static PyObject*
PyLocale_strxfrm(PyObject* self, PyObject* args)
{
    char *s, *buf;
    size_t n1, n2;
    PyObject *result;

    if (!PyArg_ParseTuple(args, "s:strxfrm", &s))
        return NULL;

    /* assume no change in size, first */
    n1 = strlen(s) + 1;
    buf = PyMem_Malloc(n1);
    if (!buf)
        return PyErr_NoMemory();
    n2 = strxfrm(buf, s, n1);
    if (n2 > n1) {
        /* more space needed */
        buf = PyMem_Realloc(buf, n2);
        if (!buf)
            return PyErr_NoMemory();
        strxfrm(buf, s, n2);
    }
    result = PyString_FromString(buf);
    PyMem_Free(buf);
    return result;
}
Exemple #2
0
void dbBtree::remove(dbDatabase* db, oid_t treeId, oid_t recordId, int offs)
{
    dbGetTie treeTie;
    dbBtree* tree = (dbBtree*)db->getRow(treeTie, treeId);
    dbBtreePage::item rem;
    oid_t rootId = tree->root;
    int   height = tree->height;
    dbGetTie tie;

    byte* p = (byte*)db->getRow(tie, recordId);
    if (tree->type == dbField::tpString) { 
	rem.keyLen = ((dbVarying*)(p + offs))->size;
	assert(rem.keyLen <= dbMaxKeyLen);
#ifdef USE_LOCALE_SETTINGS
	char cnvBuf[dbMaxKeyLen];
	if (tree->caseInsensitive) { 
	    rem.keyLen = strxfrm(cnvBuf, 
				 (char*)(p + ((dbVarying*)(p + offs))->offs), 
				 dbMaxKeyLen) + 1;
	    strlower(rem.keyChar, cnvBuf);
	} else { 
	    rem.keyLen = strxfrm(rem.keyChar, 
				 (char*)(p + ((dbVarying*)(p + offs))->offs), 
				 dbMaxKeyLen) + 1;
	}
#else
	if (tree->caseInsensitive) { 
	    strlower(rem.keyChar, (char*)(p + ((dbVarying*)(p + offs))->offs));
	} else { 
	    strcpy(rem.keyChar, (char*)(p + ((dbVarying*)(p + offs))->offs));
	}
#endif
    } else { 
	memcpy(rem.keyChar, p + offs, keySize[tree->type]);
    }
    rem.oid = recordId;
    
    int result = dbBtreePage::remove(db, rootId, tree->type, rem, height);
    assert(result != not_found);
    if (result == underflow && height != 1) { 
	dbBtreePage* page = (dbBtreePage*)db->get(rootId);
	if (page->nItems == 0) { 	
	    dbPutTie tie;
	    dbBtree* t = (dbBtree*)db->putRow(tie, treeId);
	    if (tree->type == dbField::tpString) { 
		t->root = page->keyStr[0].oid;
	    } else { 
		t->root = page->record[dbBtreePage::maxItems-1];
	    }
	    t->height -= 1;
	    db->freePage(rootId);
	}
	db->pool.unfix(page);
    } else if (result == dbBtree::overflow) { 
	dbPutTie tie;
	dbBtree* t = (dbBtree*)db->putRow(tie, treeId);
	t->root = dbBtreePage::allocate(db, rootId, tree->type, rem);
	t->height += 1;
    }
}
Exemple #3
0
int strcoll(const char *s1, const char *s2)
{
    char t1[1 + strxfrm(0, s1, 0)];
    strxfrm(t1, s1, sizeof(t1));
    char t2[1 + strxfrm(0, s2, 0)];
    strxfrm(t2, s2, sizeof(t2));
    return strcmp(t1, t2);
}
Exemple #4
0
CAMLprim value ml_text_strxfrm(value string)
{
  CAMLparam1(string);
  size_t length = strxfrm(NULL, String_val(string), 0);
  char buffer[length + 1];
  strxfrm(buffer, String_val(string), length + 1);
  CAMLreturn(caml_copy_string(buffer));
}
Exemple #5
0
void dbBtree::insert(dbDatabase* db, oid_t treeId, oid_t recordId, int offs)
{
    dbGetTie treeTie;
    dbBtree* tree = (dbBtree*)db->getRow(treeTie, treeId);
    oid_t rootId = tree->root;
    int   height = tree->height;
    dbBtreePage::item ins;
    dbGetTie tie;

    byte* p = (byte*)db->getRow(tie, recordId);
    if (tree->type == dbField::tpString) { 
	ins.keyLen = ((dbVarying*)(p + offs))->size;
	assert(ins.keyLen <= dbMaxKeyLen);
#ifdef USE_LOCALE_SETTINGS
	char cnvBuf[dbMaxKeyLen];
	if (tree->caseInsensitive) { 
	    ins.keyLen = strxfrm(cnvBuf, 
				 (char*)(p + ((dbVarying*)(p + offs))->offs), 
				 dbMaxKeyLen) + 1;
	    strlower(ins.keyChar, cnvBuf);
	} else { 
	    ins.keyLen = strxfrm(ins.keyChar, 
				 (char*)(p + ((dbVarying*)(p + offs))->offs), 
				 dbMaxKeyLen) + 1;
	}
#else
	if (tree->caseInsensitive) { 
	    strlower(ins.keyChar, (char*)(p + ((dbVarying*)(p + offs))->offs));
	} else { 
	    strcpy(ins.keyChar, (char*)(p + ((dbVarying*)(p + offs))->offs));
	}
#endif
    } else { 
	memcpy(ins.keyChar, p + offs, keySize[tree->type]);
    }
    ins.oid = recordId;

    if (rootId == 0) {
	dbPutTie tie;
        dbBtree* t = (dbBtree*)db->putRow(tie, treeId);
	t->root = dbBtreePage::allocate(db, 0, tree->type, ins);
	t->height = 1;
    } else { 
	int result;
	result = dbBtreePage::insert(db, rootId, tree->type, ins, height);
	assert(result != not_found);
	if (result == overflow) { 
	    dbPutTie tie;
	    dbBtree* t = (dbBtree*)db->putRow(tie, treeId);
	    t->root = dbBtreePage::allocate(db, rootId, tree->type, ins);
	    t->height += 1;
	}
    }
}
Exemple #6
0
static void
genequiv(STR *s)
{
	int i, p, pri;
	char src[2], dst[3];
	size_t clen;
	wchar_t wc;

	if (*s->str == '\\') {
		s->equiv[0] = backslash(s, NULL);
		if (*s->str != '=')
			errx(1, "misplaced equivalence equals sign");
		s->str += 2;
	} else {
		clen = mbrtowc(&wc, s->str, MB_LEN_MAX, NULL);
		if (clen == (size_t)-1 || clen == (size_t)-2 || clen == 0)
			errc(1, EILSEQ, NULL);
		s->equiv[0] = wc;
		if (s->str[clen] != '=')
			errx(1, "misplaced equivalence equals sign");
		s->str += clen + 2;
	}

	/*
	 * Calculate the set of all characters in the same equivalence class
	 * as the specified character (they will have the same primary
	 * collation weights).
	 * XXX Knows too much about how strxfrm() is implemented. Assumes
	 * it fills the string with primary collation weight bytes. Only one-
	 * to-one mappings are supported.
	 * XXX Equivalence classes not supported in multibyte locales.
	 */
	src[0] = (char)s->equiv[0];
	src[1] = '\0';
	if (MB_CUR_MAX == 1 && strxfrm(dst, src, sizeof(dst)) == 1) {
		pri = (unsigned char)*dst;
		for (p = 1, i = 1; i < NCHARS_SB; i++) {
			*src = i;
			if (strxfrm(dst, src, sizeof(dst)) == 1 && pri &&
			    pri == (unsigned char)*dst)
				s->equiv[p++] = i;
		}
		s->equiv[p] = OOBCH;
	}

	s->cnt = 0;
	s->state = SET;
	s->set = s->equiv;
}
Exemple #7
0
int main( int argc, char *argv[] )
{
    char x[300];
    char y[300];
    int  ret;

    CYG_TEST_INIT();

    CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C library "
                  "strxfrm() function");
    CYG_TEST_INFO("This testcase provides simple basic tests");

    // Check 1
    my_strcpy(x, "Nine rings for men doomed to die");
    ret = strxfrm(y, x, my_strlen(x)+1);
    if (my_strcmp(x, y) == 0)
        CYG_TEST_PASS("Simple strxfrm()");
    else
        CYG_TEST_FAIL("Simple strxfrm()");
    // Check return value
    CYG_TEST_PASS_FAIL( (my_strlen(x) == ret),
                        "Simple strxfrm() return value");

    // Check 2
    x[0] = '\0';
    my_strcpy(y, "Seven rings for the dwarves in their halls of stone");
    ret = strxfrm(y, x, my_strlen(x)+1);
    if (my_strcmp(y, "") == 0)
        CYG_TEST_PASS("strxfrm() of empty string");
    else
        CYG_TEST_FAIL("strxfrm() of empty string");
    // Check return value
    CYG_TEST_PASS_FAIL( (my_strlen(x) == ret),
                        "strxfrm() of empty string return value");

    // Check 3
    my_strcpy(y, "Seven rings for the dwarves in their halls of stone");
    ret = strxfrm(NULL, y, 0);

    // Check return value
    CYG_TEST_PASS_FAIL( (my_strlen(y) == ret),
                        "strxfrm() of NULL string for 0 bytes return value");

//    CYG_TEST_NA("Testing is not applicable to this configuration");

    CYG_TEST_FINISH("Finished tests from testcase " __FILE__ " for C library "
                    "strxfrm() function");
} // main()
Exemple #8
0
static int
test (const char *locale)
{
  size_t bufsize;
  size_t r;
  size_t l;
  char *buf;
  locale_t loc;
  int result = 0;

  if (setlocale (LC_COLLATE, locale) == NULL)
    {
      printf ("cannot set locale \"%s\"\n", locale);
      return 1;
    }
  bufsize = strxfrm (NULL, string, 0) + 1;
  buf = malloc (bufsize);
  if (buf == NULL)
    {
      printf ("cannot allocate %zd bytes\n", bufsize);
      return 1;
    }
  r = strxfrm (buf, string, bufsize);
  l = strlen (buf);
  if (r != l)
    {
       printf ("locale \"%s\": strxfrm returned %zu, strlen returned %zu\n",
	       locale, r, l);
       result = 1;
    }

  loc = newlocale (1 << LC_ALL, locale, NULL);

  r = strxfrm_l (buf, string, bufsize, loc);
  l = strlen (buf);
  if (r != l)
    {
       printf ("locale \"%s\": strxfrm_l returned %zu, strlen returned %zu\n",
	       locale, r, l);
       result = 1;
    }

  freelocale (loc);

  free (buf);

  return result;
}
Exemple #9
0
void cyg_user_start(void)
#endif
{
    char x[300];
    char y[300];
    int  ret;
    int ctr;
    int fail;

    CYG_TEST_INIT();

    CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C library "
                  "strxfrm() function");
    CYG_TEST_INFO("This testcase tests robustness, and may take some time");

    fail = 0;
    for (ctr = 0; ctr < NUM_ROBUSTNESS_RUNS; ctr++) {
        my_strcpy(x, "Green plastic watering can, ");
        my_strcpy(y, "for her fake Chineese rubber plant");
        ret = strxfrm(x, y, my_strlen(y)+1);
        if ( (my_strcmp(x, "for her fake Chineese rubber plant") != 0) ||
             (my_strlen(y) != ret) ) {
            fail = 1;
            break;
        }
    }
    CYG_TEST_PASS_FAIL( (fail == 0), "Robustness test" );


//    CYG_TEST_NA("Testing is not applicable to this configuration");

    CYG_TEST_FINISH("Finished tests from testcase " __FILE__ " for C library "
                    "strxfrm() function");
} // main()
Exemple #10
0
int main()
{
    size_t s = 0;
    void* vp = 0;
    const void* vpc = 0;
    char* cp = 0;
    const char* cpc = 0;
    static_assert((std::is_same<decltype(memcpy(vp, vpc, s)), void*>::value), "");
    static_assert((std::is_same<decltype(memmove(vp, vpc, s)), void*>::value), "");
    static_assert((std::is_same<decltype(strcpy(cp, cpc)), char*>::value), "");
    static_assert((std::is_same<decltype(strncpy(cp, cpc, s)), char*>::value), "");
    static_assert((std::is_same<decltype(strcat(cp, cpc)), char*>::value), "");
    static_assert((std::is_same<decltype(strncat(cp, cpc, s)), char*>::value), "");
    static_assert((std::is_same<decltype(memcmp(vpc, vpc, s)), int>::value), "");
    static_assert((std::is_same<decltype(strcmp(cpc, cpc)), int>::value), "");
    static_assert((std::is_same<decltype(strncmp(cpc, cpc, s)), int>::value), "");
    static_assert((std::is_same<decltype(strcoll(cpc, cpc)), int>::value), "");
    static_assert((std::is_same<decltype(strxfrm(cp, cpc, s)), size_t>::value), "");
    static_assert((std::is_same<decltype(memchr(vp, 0, s)), void*>::value), "");
    static_assert((std::is_same<decltype(strchr(cp, 0)), char*>::value), "");
    static_assert((std::is_same<decltype(strcspn(cpc, cpc)), size_t>::value), "");
    static_assert((std::is_same<decltype(strpbrk(cp, cpc)), char*>::value), "");
    static_assert((std::is_same<decltype(strrchr(cp, 0)), char*>::value), "");
    static_assert((std::is_same<decltype(strspn(cpc, cpc)), size_t>::value), "");
    static_assert((std::is_same<decltype(strstr(cp, cpc)), char*>::value), "");
#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
    static_assert((std::is_same<decltype(strtok(cp, cpc)), char*>::value), "");
#endif
    static_assert((std::is_same<decltype(memset(vp, 0, s)), void*>::value), "");
    static_assert((std::is_same<decltype(strerror(0)), char*>::value), "");
    static_assert((std::is_same<decltype(strlen(cpc)), size_t>::value), "");
}
Exemple #11
0
val_t eic_strxfrm(void)
{
    val_t v;
    v.szval = strxfrm(arg(0,getargs(),ptr_t).p,
		     arg(1,getargs(),ptr_t).p,
		     arg(2,getargs(),size_t));
    return v;
}
int main()
{
    char dst[9];
    char *source = "This is a string";
    setlocale(LC_ALL, "C");
    size_t sz;
    sz = strxfrm(dst, source, 10);
    return 0;
}
Exemple #13
0
/*
 * Detect aging strxfrm() implementations that, in a subset of locales, write
 * past the specified buffer length.  Affected users must update OS packages
 * before using PostgreSQL 9.5 or later.
 *
 * Assume that the bug can come and go from one postmaster startup to another
 * due to physical replication among diverse machines.  Assume that the bug's
 * presence will not change during the life of a particular postmaster.  Given
 * those assumptions, call this no less than once per postmaster startup per
 * LC_COLLATE setting used.  No known-affected system offers strxfrm_l(), so
 * there is no need to consider pg_collation locales.
 */
void
check_strxfrm_bug(void)
{
	char		buf[32];
	const int	canary = 0x7F;
	bool		ok = true;

	/*
	 * Given a two-byte ASCII string and length limit 7, 8 or 9, Solaris 10
	 * 05/08 returns 18 and modifies 10 bytes.  It respects limits above or
	 * below that range.
	 *
	 * The bug is present in Solaris 8 as well; it is absent in Solaris 10
	 * 01/13 and Solaris 11.2.  Affected locales include is_IS.ISO8859-1,
	 * en_US.UTF-8, en_US.ISO8859-1, and ru_RU.KOI8-R.  Unaffected locales
	 * include de_DE.UTF-8, de_DE.ISO8859-1, zh_TW.UTF-8, and C.
	 */
	buf[7] = canary;
	(void) strxfrm(buf, "ab", 7);
	if (buf[7] != canary)
		ok = false;

	/*
	 * illumos bug #1594 was present in the source tree from 2010-10-11 to
	 * 2012-02-01.  Given an ASCII string of any length and length limit 1,
	 * affected systems ignore the length limit and modify a number of bytes
	 * one less than the return value.  The problem inputs for this bug do not
	 * overlap those for the Solaris bug, hence a distinct test.
	 *
	 * Affected systems include smartos-20110926T021612Z.  Affected locales
	 * include en_US.ISO8859-1 and en_US.UTF-8.  Unaffected locales include C.
	 */
	buf[1] = canary;
	(void) strxfrm(buf, "a", 1);
	if (buf[1] != canary)
		ok = false;

	if (!ok)
		ereport(ERROR,
				(errcode(ERRCODE_SYSTEM_ERROR),
				 errmsg_internal("strxfrm(), in locale \"%s\", writes past the specified array length",
								 setlocale(LC_COLLATE, NULL)),
				 errhint("Apply system library package updates.")));
}
void test_pointer (const char *s, const char *t)
{
  q[0] = strcmp (s, t);
  q[1] = strncmp (s, t, 7);
  q[2] = strlen (s);
  q[3] = strnlen (s, 7);
  q[4] = strcspn (s, t);
  q[5] = strspn (s, t);
  q[6] = strxfrm (s, s, 7);
}
Exemple #15
0
static void
genequiv(STR *s)
{
	int i, p, pri;
	char src[2], dst[3];

	if (*s->str == '\\') {
		s->equiv[0] = backslash(s);
		if (*s->str != '=')
			errx(1, "misplaced equivalence equals sign");
		s->str += 2;
	} else {
		s->equiv[0] = s->str[0];
		if (s->str[1] != '=')
			errx(1, "misplaced equivalence equals sign");
		s->str += 3;
	}

	/*
	 * Calculate the set of all characters in the same equivalence class
	 * as the specified character (they will have the same primary
	 * collation weights).
	 * XXX Knows too much about how strxfrm() is implemented. Assumes
	 * it fills the string with primary collation weight bytes. Only one-
	 * to-one mappings are supported.
	 */
	src[0] = s->equiv[0];
	src[1] = '\0';
	if (strxfrm(dst, src, sizeof(dst)) == 1) {
		pri = (unsigned char)*dst;
		for (p = 1, i = 1; i < NCHARS; i++) {
			*src = i;
			if (strxfrm(dst, src, sizeof(dst)) == 1 && pri &&
			    pri == (unsigned char)*dst)
				s->equiv[p++] = i;
		}
		s->equiv[p] = OOBCH;
	}

	s->cnt = 0;
	s->state = SET;
	s->set = s->equiv;
}
Exemple #16
0
/*
 * Set up for a new collation locale.
 */
void
Perl_new_collate(pTHX_ const char *newcoll)
{
#ifdef USE_LOCALE_COLLATE
    dVAR;

    if (! newcoll) {
	if (PL_collation_name) {
	    ++PL_collation_ix;
	    Safefree(PL_collation_name);
	    PL_collation_name = NULL;
	}
	PL_collation_standard = TRUE;
	PL_collxfrm_base = 0;
	PL_collxfrm_mult = 2;
	return;
    }

    if (! PL_collation_name || strNE(PL_collation_name, newcoll)) {
	++PL_collation_ix;
	Safefree(PL_collation_name);
	PL_collation_name = stdize_locale(savepv(newcoll));
	PL_collation_standard = ((*newcoll == 'C' && newcoll[1] == '\0')
				 || strEQ(newcoll, "POSIX"));

	{
	  /*  2: at most so many chars ('a', 'b'). */
	  /* 50: surely no system expands a char more. */
#define XFRMBUFSIZE  (2 * 50)
	  char xbuf[XFRMBUFSIZE];
	  const Size_t fa = strxfrm(xbuf, "a",  XFRMBUFSIZE);
	  const Size_t fb = strxfrm(xbuf, "ab", XFRMBUFSIZE);
	  const SSize_t mult = fb - fa;
	  if (mult < 1 && !(fa == 0 && fb == 0))
	      Perl_croak(aTHX_ "panic: strxfrm() gets absurd - a => %"UVuf", ab => %"UVuf,
			 (UV) fa, (UV) fb);
	  PL_collxfrm_base = (fa > (Size_t)mult) ? (fa - mult) : 0;
	  PL_collxfrm_mult = mult;
	}
    }

#endif /* USE_LOCALE_COLLATE */
}
size_t _Locale_strxfrm(struct _Locale_collate* lcollate,
		       char* dest, size_t destN, const char* src, size_t srcN)
{
  size_t n;
  n = strxfrm(dest, src, destN);
  if (n > destN)
    return (size_t)-1;
  dest[n] = 0;
  return n;
}
Exemple #18
0
void dbBtree::find(dbDatabase* db, oid_t treeId, dbSearchContext& sc)
{
    dbGetTie tie;
    dbBtree* tree = (dbBtree*)db->getRow(tie, treeId);
    oid_t rootId = tree->root;
    int   height = tree->height;
    char  firstKeyBuf[dbMaxKeyLen];
    char  lastKeyBuf[dbMaxKeyLen];
#ifdef USE_LOCALE_SETTINGS
    char cnvBuf[dbMaxKeyLen];
#endif
    if (tree->type == dbField::tpString) { 
	if (sc.firstKey != NULL) { 
	    if (tree->caseInsensitive) { 
		strlower(firstKeyBuf, sc.firstKey);
		sc.firstKey = firstKeyBuf;
	    }
#ifdef USE_LOCALE_SETTINGS
	    strxfrm(cnvBuf, sc.firstKey, dbMaxKeyLen);
	    sc.firstKey = cnvBuf;
#endif
	}
	if (sc.lastKey != NULL) { 
	    if (tree->caseInsensitive) { 
		strlower(lastKeyBuf, sc.lastKey);
		sc.lastKey = lastKeyBuf;
	    }
#ifdef USE_LOCALE_SETTINGS
	    // Hack!!! firstKeyBuf is free at rthis moment and cnvBuf is used.
	    // So use firstKeyBuf for convertsion of last key.
	    strxfrm(firstKeyBuf, sc.lastKey, dbMaxKeyLen);
	    sc.lastKey = firstKeyBuf;
#endif
	}

    }
    if (rootId != 0) { 
	dbBtreePage* page = (dbBtreePage*)db->get(rootId);
	page->find(db, sc, tree->type, height);
	db->pool.unfix(page);
    }
}
Exemple #19
0
void main(void)
 {
   char buffer[64] = "Jamsa\'s C/C++ Programmer\'s Bible";
   char target[64];

   int length;

   length = strxfrm(target, buffer, sizeof(buffer));

   printf("Length %d Target %s Buffer %s\n", length,
     target, buffer);
 }
void test_array (const char *s)
{
  extern char a[8];

  q[0] = strcmp (a, s);
  q[1] = strncmp (a, s, 7);
  q[2] = strlen (a);
  q[3] = strnlen (a, 7);
  q[4] = strcspn (a, s);
  q[5] = strspn (a, s);
  q[6] = strxfrm (a, s, 7);
}
Exemple #21
0
int main(int argc, char **argv) {
  char q[10];
  size_t n = strxfrm(q, "abcdef", sizeof(q));
  assert(n < sizeof(q));

  char q2[10];
  locale_t loc = newlocale(LC_ALL_MASK, "", (locale_t)0);
  n = strxfrm_l(q2, L"qwerty", sizeof(q), loc);
  assert(n < sizeof(q2));

  freelocale(loc);
  return 0;
}
nsresult nsCollationUnix::AllocateRawSortKey(int32_t strength, 
                                             const nsAString& stringIn,
                                             uint8_t** key, uint32_t* outLen)
{
  nsresult res = NS_OK;

  nsAutoString stringNormalized;
  if (strength != kCollationCaseSensitive) {
    res = mCollation->NormalizeString(stringIn, stringNormalized);
    if (NS_FAILED(res))
      return res;
  } else {
    stringNormalized = stringIn;
  }
  // convert unicode to charset
  char *str;

  res = mCollation->UnicodeToChar(stringNormalized, &str);
  if (NS_SUCCEEDED(res) && str) {
    DoSetLocale();
    // call strxfrm to generate a key 
    size_t len = strxfrm(nullptr, str, 0) + 1;
    void *buffer = PR_Malloc(len);
    if (!buffer) {
      res = NS_ERROR_OUT_OF_MEMORY;
    } else if (strxfrm((char *)buffer, str, len) >= len) {
      PR_Free(buffer);
      res = NS_ERROR_FAILURE;
    } else {
      *key = (uint8_t *)buffer;
      *outLen = len;
    }
    DoRestoreLocale();
    PR_Free(str);
  }

  return res;
}
Exemple #23
0
char *
Perl_mem_collxfrm(pTHX_ const char *s, STRLEN len, STRLEN *xlen)
{
    dVAR;
    char *xbuf;
    STRLEN xAlloc, xin, xout; /* xalloc is a reserved word in VC */

    PERL_ARGS_ASSERT_MEM_COLLXFRM;

    /* the first sizeof(collationix) bytes are used by sv_collxfrm(). */
    /* the +1 is for the terminating NUL. */

    xAlloc = sizeof(PL_collation_ix) + PL_collxfrm_base + (PL_collxfrm_mult * len) + 1;
    Newx(xbuf, xAlloc, char);
    if (! xbuf)
	goto bad;

    *(U32*)xbuf = PL_collation_ix;
    xout = sizeof(PL_collation_ix);
    for (xin = 0; xin < len; ) {
	Size_t xused;

	for (;;) {
	    xused = strxfrm(xbuf + xout, s + xin, xAlloc - xout);
	    if (xused >= PERL_INT_MAX)
		goto bad;
	    if ((STRLEN)xused < xAlloc - xout)
		break;
	    xAlloc = (2 * xAlloc) + 1;
	    Renew(xbuf, xAlloc, char);
	    if (! xbuf)
		goto bad;
	}

	xin += strlen(s + xin) + 1;
	xout += xused;

	/* Embedded NULs are understood but silently skipped
	 * because they make no sense in locale collation. */
    }

    xbuf[xout] = '\0';
    *xlen = xout - sizeof(PL_collation_ix);
    return xbuf;

  bad:
    Safefree(xbuf);
    *xlen = 0;
    return NULL;
}
Exemple #24
0
inline int8 packStrKey(byte* p) 
{
#ifdef USE_LOCALE_SETTINGS
    char buf[8];
    strxfrm(buf, (char*)p, sizeof buf);
    p = (byte*)buf;
#endif
    int8 pkey = 0;
    for (int i = 0; i < 8 && p[i] != 0; i++) { 
        pkey |= int8(p[i]) << ((7-i)*8);
    }
    // As far as signed comparison is used for packed key, 
    // and strcmp compares characters as unsign, we should make this 
    // correction
    return pkey - (int8(-1) << 63);
}
Exemple #25
0
void TestLocale( void )
{
    char            bufA[80] = "FoO baR gOoBeR bLaH";
    char            bufB[80];
    int             status;

    setlocale( LC_ALL, "C" );                   /* set locale to "C" */

    status = strxfrm( bufB, bufA, 20 );         /* transform the string */
    VERIFY( status == 19 );

    status = strcoll( bufB, bufA );             /* compare with "C" locale */
    VERIFY( status == 0 );

    status = strcoll( bufB, "Bar" );            /* compare with "C" locale */
    VERIFY( status != 0 );
}
Exemple #26
0
size_t _Locale_strxfrm(struct _Locale_collate *lcollate,
                       char *dest, size_t dest_n,
                       const char *src, size_t src_n )
{
  if (src_n == 0)
  {
    if (dest != NULL) dest[0] = 0;
    return 0;
  }
  const char *real_src;
  char *buf = NULL;
  if (src[src_n] != 0) {
    buf = malloc(src_n + 1);
    strncpy(buf, src, src_n);
    buf[src_n] = 0;
    real_src = buf;
  }
  else
    real_src = src;
  size_t result = strxfrm(dest, real_src, dest_n);
  if (buf != NULL) free(buf);
  return result;
}
Exemple #27
0
/*
 *  stress_strxfrm()
 *	stress on strxfrm
 */
static void stress_strxfrm(
	const char *name,
	char *str1,
	const size_t len1,
	char *str2,
	const size_t len2)
{
	register size_t i;
	char buf[len1 + len2];

	for (i = 0; i < len1 - 1; i++) {
		*buf = '\0';
		STRCHK(name, 0 != strxfrm(buf, str1, sizeof(buf)));
		*buf = '\0';
		STRCHK(name, 0 != strxfrm(buf, str2, sizeof(buf)));
		*buf = '\0';
		STRCHK(name, 0 != strxfrm(buf, str1, sizeof(buf)));
		STRCHK(name, 0 != strxfrm(buf, str2, sizeof(buf)));
		*buf = '\0';
		STRCHK(name, 0 != strxfrm(buf, str2, sizeof(buf)));
		STRCHK(name, 0 != strxfrm(buf, str1, sizeof(buf)));
	}
}
Exemple #28
0
char *
astrxfrm (const char *s, char *resultbuf, size_t *lengthp)
{
  char tmpbuf[4000];
  char *result;      /* either == resultbuf or == tmpbuf or freshly allocated
                        or NULL.  */
  size_t allocated;  /* number of bytes allocated at result */
  size_t length;

  if (resultbuf != NULL)
    {
      result = resultbuf;
      allocated = *lengthp;
    }
  else
    {
      result = NULL;
      allocated = 0;
    }

  {
    size_t l = strlen (s);
    size_t k;

    /* A call to strxfrm costs about 20 times more than a call to strdup of
       the result.  Therefore it is worth to try to avoid calling strxfrm
       more than once on a given string, by making enough room before calling
       strxfrm.  The size of the strxfrm result, k, is likely to be between
       l and 3 * l.  */
    if (3 * l + 1 > allocated)
      {
        /* Grow the result buffer.  */
        if (3 * l + 1 <= sizeof (tmpbuf))
          {
            result = tmpbuf;
            allocated = sizeof (tmpbuf);
          }
        else
          {
            size_t new_allocated;
            char *new_result;

            new_allocated = 3 * l + 1;
            if (new_allocated < 2 * allocated)
              new_allocated = 2 * allocated;
            new_result = (char *) malloc (new_allocated);
            if (new_result != NULL)
              {
                allocated = new_allocated;
                result = new_result;
              }
          }
      }

    errno = 0;
    k = strxfrm (result, s, allocated);
    if (errno != 0)
      goto fail;
    if (k >= allocated)
      {
        /* Grow the result buffer.  */
        if (result != resultbuf && result != tmpbuf)
          free (result);
        if (k + 1 <= sizeof (tmpbuf))
          {
            result = tmpbuf;
            allocated = sizeof (tmpbuf);
          }
        else
          {
            size_t new_allocated;
            char *new_result;

            new_allocated = k + 1;
            new_result = (char *) malloc (new_allocated);
            if (new_result == NULL)
              goto out_of_memory;
            allocated = new_allocated;
            result = new_result;
          }
        /* Here k < allocated.  */

        /* Try again.  */
        errno = 0;
        if (strxfrm (result, s, allocated) != k)
          /* strxfrm() is not producing reproducible results.  */
          abort ();
        if (errno != 0)
          goto fail;
      }

    /* Verify that strxfrm() has NUL-terminated the result.  */
    if (result[k] != '\0')
      abort ();
    length = k + 1;
  }

  /* Here length > 0.  */

  if (result == tmpbuf)
    {
      if (resultbuf != NULL && length <= *lengthp)
        {
          memcpy (resultbuf, result, length);
          result = resultbuf;
        }
      else
        {
          char *memory = (char *) malloc (length);

          if (memory == NULL)
            goto out_of_memory;
          memcpy (memory, result, length);
          result = memory;
        }
    }
  else
    {
      /* Shrink the allocated memory if possible.  */
      if (result != resultbuf && length < allocated)
        {
          if (length <= *lengthp)
            {
              memcpy (resultbuf, result, length);
              free (result);
              result = resultbuf;
            }
          else
            {
              char *memory = (char *) realloc (result, length);
              if (memory != NULL)
                {
                  memcpy (memory, result, length);
                  result = memory;
                }
            }
        }
    }

  *lengthp = length;
  return result;

 fail:
  {
    int saved_errno = errno;
    if (result != resultbuf && result != tmpbuf)
      free (result);
    errno = saved_errno;
    return NULL;
  }

 out_of_memory:
  errno = ENOMEM;
  return NULL;
}
Exemple #29
0
int
main (int argc, char *argv[])
{
  int result = 0;
  bool nocache = false;
  size_t nstrings, nstrings_max;
  struct lines *strings;
  char *line = NULL;
  size_t len = 0;
  size_t n;

  if (argc < 2)
    error (1, 0, "usage: %s <random seed> [-nocache]", argv[0]);

  if (argc == 3)
    {
      if (strcmp (argv[2], "-nocache") == 0)
	nocache = true;
      else
	{
	  printf ("Unknown option %s!\n", argv[2]);
	  exit (1);
	}
    }

  setlocale (LC_ALL, "");

  nstrings_max = 100;
  nstrings = 0;
  strings = (struct lines *) malloc (nstrings_max * sizeof (struct lines));
  if (strings == NULL)
    {
      perror (argv[0]);
      exit (1);
    }

  while (1)
    {
      char saved, *word, *newp;
      size_t l, line_len, needed;

      if (getline (&line, &len, stdin) < 0)
	break;

      if (nstrings == nstrings_max)
	{
	  strings = (struct lines *) realloc (strings,
					      (nstrings_max *= 2)
					       * sizeof (*strings));
	  if (strings == NULL)
	    {
	      perror (argv[0]);
	      exit (1);
	    }
	}
      strings[nstrings].line = strdup (line);
      l = strcspn (line, ":(;");
      while (l > 0 && isspace (line[l - 1]))
	--l;

      saved = line[l];
      line[l] = '\0';

      if (nocache)
	{
	  line_len = strlen (line);
	  word = malloc (line_len + SMALL_STR_SIZE + 1);
	  if (word == NULL)
	    {
	      printf ("malloc failed: %m\n");
	      exit (1);
	    }
	  memset (word, ' ', SMALL_STR_SIZE);
	  memcpy (word + SMALL_STR_SIZE, line, line_len);
	  word[line_len + SMALL_STR_SIZE] = '\0';
	}
      else
        word = line;

      needed = strxfrm (NULL, word, 0);
      newp = malloc (needed + 1);
      if (newp == NULL)
	{
	  printf ("malloc failed: %m\n");
	  exit (1);
	}
      strxfrm (newp, word, needed + 1);
      strings[nstrings].xfrm = newp;

      if (nocache)
	free (word);
      line[l] = saved;
      ++nstrings;
    }
  free (line);

  /* First shuffle.  */
  srandom (atoi (argv[1]));
  for (n = 0; n < 10 * nstrings; ++n)
    {
      int r1, r2, r;
      size_t idx1 = random () % nstrings;
      size_t idx2 = random () % nstrings;
      struct lines tmp = strings[idx1];
      strings[idx1] = strings[idx2];
      strings[idx2] = tmp;

      /* While we are at it a first little test.  */
      r1 = strcmp (strings[idx1].xfrm, strings[idx2].xfrm);
      r2 = strcmp (strings[idx2].xfrm, strings[idx1].xfrm);
      r = -(r1 ^ r2);
      if (r)
	r /= abs (r1 ^ r2);

      if (r < 0 || (r == 0 && (r1 != 0 || r2 != 0))
	  || (r > 0 && (r1 ^ r2) >= 0))
	printf ("collate wrong: %d vs. %d\n", r1, r2);
    }

  /* Now sort.  */
  qsort (strings, nstrings, sizeof (struct lines), xstrcmp);

  /* Print the result.  */
  for (n = 0; n < nstrings; ++n)
    {
      fputs (strings[n].line, stdout);
      free (strings[n].line);
      free (strings[n].xfrm);
    }
  free (strings);

  return result;
}
Exemple #30
0
KServiceGroup::List
KServiceGroup::entries(bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName)
{
    KServiceGroup *group = this;

    // If the entries haven't been loaded yet, we have to reload ourselves
    // together with the entries. We can't only load the entries afterwards
    // since the offsets could have been changed if the database has changed.

    if (!m_bDeep) {

        group =
            KServiceGroupFactory::self()->findGroupByDesktopPath(relPath(), true);

        if (0 == group) // No guarantee that we still exist!
            return List();
    }

    if (!sort)
        return group->m_serviceList;

    // Sort the list alphabetically, according to locale.
    // Groups come first, then services.

    KSortableValueList<SPtr,QCString> slist;
    KSortableValueList<SPtr,QCString> glist;
    for (List::ConstIterator it(group->m_serviceList.begin()); it != group->m_serviceList.end(); ++it)
    {
        KSycocaEntry *p = (*it);
	bool noDisplay = p->isType(KST_KServiceGroup) ?
                                   static_cast<KServiceGroup *>(p)->noDisplay() :
                                   static_cast<KService *>(p)->noDisplay();
        if (excludeNoDisplay && noDisplay)
           continue;
        // Choose the right list
        KSortableValueList<SPtr,QCString> & list = p->isType(KST_KServiceGroup) ? glist : slist;
        QString name;
        if (p->isType(KST_KServiceGroup))
          name = static_cast<KServiceGroup *>(p)->caption();
        else if (sortByGenericName)
          name = static_cast<KService *>(p)->genericName() + " " + p->name();
        else
          name = p->name() + " " + static_cast<KService *>(p)->genericName();

        QCString key( name.length() * 4 + 1 );
        // strxfrm() crashes on Solaris
#ifndef USE_SOLARIS
        // maybe it'd be better to use wcsxfrm() where available
        size_t ln = strxfrm( key.data(), name.local8Bit().data(), key.size());
        if( ln != size_t( -1 ))
        {
            if( ln >= key.size())
            { // didn't fit?
                key.resize( ln + 1 );
                if( strxfrm( key.data(), name.local8Bit().data(), key.size()) == size_t( -1 ))
                    key = name.local8Bit();
            }
        }
        else
#endif
        {
            key = name.local8Bit();
        }
        list.insert(key,SPtr(*it));
    }
    // Now sort
    slist.sort();
    glist.sort();

    if (d->sortOrder.isEmpty())
    {
       d->sortOrder << ":M";
       d->sortOrder << ":F";
       d->sortOrder << ":OIH IL[4]"; //just inline header
    }

    QString rp = relPath();
    if(rp == "/") rp = QString::null;

    // Iterate through the sort spec list.
    // If an entry gets mentioned explicitly, we remove it from the sorted list
    for (QStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it)
    {
        const QString &item = *it;
        if (item.isEmpty()) continue;
        if (item[0] == '/')
        {
          QString groupPath = rp + item.mid(1) + "/";
           // Remove entry from sorted list of services.
          for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
          {
             KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)((*it2).value()));
             if (group->relPath() == groupPath)
             {
                glist.remove(it2);
                break;
             }
          }
        }
        else if (item[0] != ':')
        {
           // Remove entry from sorted list of services.
           // TODO: Remove item from sortOrder-list if not found
           // TODO: This prevents duplicates
          for(KSortableValueList<SPtr,QCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2)
          {
             KService *service = (KService *)((KSycocaEntry *)((*it2).value()));
             if (service->menuId() == item)
             {
                slist.remove(it2);
                break;
             }
          }
        }
    }

    List sorted;

    bool needSeparator = false;
    // Iterate through the sort spec list.
    // Add the entries to the list according to the sort spec.
    for (QStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it)
    {
        const QString &item = *it;
        if (item.isEmpty()) continue;
        if (item[0] == ':')
        {
          // Special condition...
          if (item == ":S")
          {
             if (allowSeparators)
                needSeparator = true;
          }
          else if ( item.contains( ":O" ) )
          {
              //todo parse attribute:
              QString tmp(  item );
              tmp = tmp.remove(":O");
              QStringList optionAttribute = QStringList::split(" ",tmp);
              if( optionAttribute.count()==0)
                  optionAttribute.append(tmp);
              bool showEmptyMenu = false;
              bool showInline = false;
              bool showInlineHeader = false;
              bool showInlineAlias = false;
              int inlineValue = -1;

              for ( QStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 )
              {
                  parseAttribute( *it3,  showEmptyMenu, showInline, showInlineHeader, showInlineAlias, inlineValue );
              }
              for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
              {
                  KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2).value());
                  group->setShowEmptyMenu(  showEmptyMenu  );
                  group->setAllowInline( showInline );
                  group->setShowInlineHeader( showInlineHeader );
                  group->setInlineAlias( showInlineAlias );
                  group->setInlineValue( inlineValue );
              }

          }
          else if (item == ":M")
          {
            // Add sorted list of sub-menus
            for(KSortableValueList<SPtr,QCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2)
            {
              addItem(sorted, (*it2).value(), needSeparator);
            }
          }
          else if (item == ":F")
          {
            // Add sorted list of services
            for(KSortableValueList<SPtr,QCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2)
            {
              addItem(sorted, (*it2).value(), needSeparator);
            }
          }
          else if (item == ":A")
          {
            // Add sorted lists of services and submenus
            KSortableValueList<SPtr,QCString>::Iterator it_s = slist.begin();
            KSortableValueList<SPtr,QCString>::Iterator it_g = glist.begin();

            while(true)
            {
               if (it_s == slist.end())
               {
                  if (it_g == glist.end())
                     break; // Done

                  // Insert remaining sub-menu
                  addItem(sorted, (*it_g).value(), needSeparator);
                  it_g++;
               }
               else if (it_g == glist.end())
               {
                  // Insert remaining service
                  addItem(sorted, (*it_s).value(), needSeparator);
                  it_s++;
               }
               else if ((*it_g).index() < (*it_s).index())
               {
                  // Insert sub-menu first
                  addItem(sorted, (*it_g).value(), needSeparator);
                  it_g++;
               }
               else
               {
                  // Insert service first
                  addItem(sorted, (*it_s).value(), needSeparator);
                  it_s++;
               }
            }
          }
        }
        else if (item[0] == '/')
        {
            QString groupPath = rp + item.mid(1) + "/";

            for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2)
            {
                if (!(*it2)->isType(KST_KServiceGroup))
                    continue;
                KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2));
                if (group->relPath() == groupPath)
                {
                    if (!excludeNoDisplay || !group->noDisplay())
                    {
                        const QString &nextItem = *( ++it );
                        if ( nextItem.startsWith( ":O" ) )
                        {
                            QString tmp(  nextItem );
                            tmp = tmp.remove(":O");
                            QStringList optionAttribute = QStringList::split(" ",tmp);
                            if( optionAttribute.count()==0)
                                optionAttribute.append(tmp);
                            bool bShowEmptyMenu = false;
                            bool bShowInline = false;
                            bool bShowInlineHeader = false;
                            bool bShowInlineAlias = false;
                            int inlineValue = -1;
                            for ( QStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 )
                            {
                                parseAttribute( *it3 , bShowEmptyMenu, bShowInline, bShowInlineHeader, bShowInlineAlias , inlineValue );
                                group->setShowEmptyMenu( bShowEmptyMenu );
                                group->setAllowInline( bShowInline );
                                group->setShowInlineHeader( bShowInlineHeader );
                                group->setInlineAlias( bShowInlineAlias );
                                group->setInlineValue( inlineValue );
                            }
                        }
                        else
                            it--;

                        addItem(sorted, (group), needSeparator);
                    }
                    break;
                }
            }
        }
        else
        {
            for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2)
            {
                if (!(*it2)->isType(KST_KService))
                    continue;
                KService *service = (KService *)((KSycocaEntry *)(*it2));
                if (service->menuId() == item)
                {
                    if (!excludeNoDisplay || !service->noDisplay())
                        addItem(sorted, (*it2), needSeparator);
                    break;
                }
            }
        }
    }

    return sorted;
}