1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462 |
- #define strtok_r __strtok_r
- #define _GNU_SOURCE
- #define __CTYPE_HAS_8_BIT_LOCALES 1
- #include <string.h>
- #include <stdlib.h>
- #include <stddef.h>
- #include <limits.h>
- #include <stdint.h>
- #include <assert.h>
- #include <errno.h>
- #include <ctype.h>
- #include <stdio.h>
- #ifdef __UCLIBC_MJN3_ONLY__
- #ifdef L_setlocale
- #warning TODO: Make the link_warning()s a config option?
- #endif
- #endif
- #undef link_warning
- #define link_warning(A,B)
- #undef __LOCALE_C_ONLY
- #ifndef __UCLIBC_HAS_LOCALE__
- #define __LOCALE_C_ONLY
- #endif
- #ifdef __LOCALE_C_ONLY
- #include <locale.h>
- #else
- #ifdef __UCLIBC_MJN3_ONLY__
- #ifdef L_setlocale
- #warning TODO: Fix the __CTYPE_HAS_8_BIT_LOCALES define at the top of the file.
- #warning TODO: Fix __WCHAR_ENABLED.
- #endif
- #endif
- #include <bits/uClibc_locale.h>
- #undef CODESET_LIST
- #define CODESET_LIST (__locale_mmap->codeset_list)
- #ifdef __UCLIBC_HAS_XLOCALE__
- #include <xlocale.h>
- #include <locale.h>
- #else
- #define __UCLIBC_HAS_XLOCALE__ 1
- #include <xlocale.h>
- #include <locale.h>
- #undef __UCLIBC_HAS_XLOCALE__
- #endif
- #include <wchar.h>
- #define LOCALE_NAMES (__locale_mmap->locale_names5)
- #define LOCALES (__locale_mmap->locales)
- #define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers)
- #define CATEGORY_NAMES (__locale_mmap->lc_names)
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning REMINDER: redo the MAX_LOCALE_STR stuff...
- #endif
- #define MAX_LOCALE_STR 256
- #define MAX_LOCALE_CATEGORY_STR 32
- extern int _locale_set_l(const unsigned char *p, __locale_t base);
- extern void _locale_init_l(__locale_t base);
- #endif
- #undef LOCALE_STRING_SIZE
- #define LOCALE_SELECTOR_SIZE (2 * __LC_ALL + 2)
- #ifdef __UCLIBC_MJN3_ONLY__
- #ifdef L_setlocale
- #warning TODO: Create a C locale selector string.
- #endif
- #endif
- #define C_LOCALE_SELECTOR "\x23\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80"
- #include <langinfo.h>
- #include <nl_types.h>
- #ifdef L_setlocale
- #ifdef __LOCALE_C_ONLY
- link_warning(setlocale,"REMINDER: The 'setlocale' function supports only C|POSIX locales.")
- static const char C_string[] = "C";
- char *setlocale(int category, register const char *locale)
- {
- return ( (((unsigned int)(category)) <= LC_ALL)
- && ( (!locale)
- || (!*locale)
- || ((*locale == 'C') && !locale[1])
- || (!__strcmp(locale, "POSIX"))) )
- ? (char *) C_string
- : NULL;
- }
- #else
- #ifdef __UCLIBC_HAS_THREADS__
- link_warning(setlocale,"REMINDER: The 'setlocale' function is _not_ threadsafe except for simple queries.")
- #endif
- #if !defined(__LOCALE_DATA_NUM_LOCALES) || (__LOCALE_DATA_NUM_LOCALES <= 1)
- #error locales enabled, but not data other than for C locale!
- #endif
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Move posix and utf8 strings.
- #endif
- static const char posix[] = "POSIX";
- static const char utf8[] = "UTF-8";
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Fix dimensions of hr_locale.
- #endif
- static char hr_locale[(MAX_LOCALE_CATEGORY_STR * LC_ALL) + MAX_LOCALE_STR];
- static void update_hr_locale(const unsigned char *spec)
- {
- const unsigned char *loc;
- const unsigned char *s;
- char *n;
- int i, category, done;
- done = category = 0;
- do {
- s = spec + 1;
- n = hr_locale + category * MAX_LOCALE_CATEGORY_STR;
- if (category == LC_ALL) {
- done = 1;
- for (i = 0 ; i < LC_ALL-1 ; i += 2) {
- if ((s[i] != s[i+2]) || (s[i+1] != s[i+3])) {
- goto SKIP;
- }
- }
-
- category = LC_CTYPE;
- }
- SKIP:
- i = (category == LC_ALL) ? 0 : category;
- s += 2*i;
- do {
- if ((*s != 0xff) || (s[1] != 0xff)) {
- loc = LOCALES
- + __LOCALE_DATA_WIDTH_LOCALES * ((((int)(*s & 0x7f)) << 7)
- + (s[1] & 0x7f));
- if (category == LC_ALL) {
- n = stpcpy(n, CATEGORY_NAMES + (int) CATEGORY_NAMES[i]);
- *n++ = '=';
- }
- if (*loc == 0) {
- *n++ = 'C';
- *n = 0;
- } else {
- char at = 0;
- __memcpy(n, LOCALE_NAMES + 5*((*loc)-1), 5);
- if (n[2] != '_') {
- at = n[2];
- n[2] = '_';
- }
- n += 5;
- *n++ = '.';
- if (loc[2] == 2) {
- n = stpcpy(n, utf8);
- } else if (loc[2] >= 3) {
- n = stpcpy(n, CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3]));
- }
- if (at) {
- const char *q;
- *n++ = '@';
- q = LOCALE_AT_MODIFIERS;
- do {
- if (q[1] == at) {
- n = stpcpy(n, q+2);
- break;
- }
- q += 2 + *q;
- } while (*q);
- }
- }
- *n++ = ';';
- }
- s += 2;
- } while (++i < category);
- *--n = 0;
- ++category;
- } while (!done);
- }
- char *setlocale(int category, const char *locale)
- {
- if (((unsigned int)(category)) > LC_ALL) {
- #if 0
- __set_errno(EINVAL);
- #endif
- return NULL;
- }
- if (locale != NULL) {
- if (!__newlocale((1 << category), locale, __global_locale)) {
- return NULL;
- }
- update_hr_locale(__global_locale->cur_locale);
- }
-
- return hr_locale + (category * MAX_LOCALE_CATEGORY_STR);
- }
- #endif
- #endif
- #ifdef L_localeconv
- #ifdef __LOCALE_C_ONLY
- link_warning(localeconv,"REMINDER: The 'localeconv' function is hardwired for C/POSIX locale only.")
- static struct lconv the_lconv;
- static const char decpt[] = ".";
- struct lconv *localeconv(void)
- {
- register char *p = (char *)(&the_lconv);
- *((char **)p) = (char *) decpt;
- do {
- p += sizeof(char **);
- *((char **)p) = (char *) (decpt+1);
- } while (p < (char *) &the_lconv.negative_sign);
- p = (&the_lconv.int_frac_digits);
- do {
- *p = CHAR_MAX;
- ++p;
- } while (p <= &the_lconv.int_n_sign_posn);
- return &the_lconv;
- }
- #else
- static struct lconv the_lconv;
- struct lconv *localeconv(void)
- {
- register char *p = (char *) &the_lconv;
- register char **q = (char **) &(__UCLIBC_CURLOCALE_DATA).decimal_point;
- do {
- *((char **)p) = *q;
- p += sizeof(char **);
- ++q;
- } while (p < &the_lconv.int_frac_digits);
- do {
- *p = **q;
- ++p;
- ++q;
- } while (p <= &the_lconv.int_n_sign_posn);
- return &the_lconv;
- }
- #endif
- #endif
- #if defined(L__locale_init) && !defined(__LOCALE_C_ONLY)
- __uclibc_locale_t __global_locale_data;
- __locale_t __global_locale = &__global_locale_data;
- #ifdef __UCLIBC_HAS_XLOCALE__
- __locale_t __curlocale_var = &__global_locale_data;
- #endif
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Move utf8 and ascii strings.
- #endif
- static const char utf8[] = "UTF-8";
- static const char ascii[] = "ASCII";
- typedef struct {
- uint16_t num_base;
- uint16_t num_der;
- uint16_t MAX_WEIGHTS;
- uint16_t num_index2weight;
- #define num_index2ruleidx num_index2weight
- uint16_t num_weightstr;
- uint16_t num_multistart;
- uint16_t num_override;
- uint16_t num_ruletable;
- } coldata_header_t;
- typedef struct {
- uint16_t num_weights;
- uint16_t num_starters;
- uint16_t ii_shift;
- uint16_t ti_shift;
- uint16_t ii_len;
- uint16_t ti_len;
- uint16_t max_weight;
- uint16_t num_col_base;
- uint16_t max_col_index;
- uint16_t undefined_idx;
- uint16_t range_low;
- uint16_t range_count;
- uint16_t range_base_weight;
- uint16_t range_rule_offset;
- uint16_t index2weight_offset;
- uint16_t index2ruleidx_offset;
- uint16_t multistart_offset;
- uint16_t wcs2colidt_offset_low;
- uint16_t wcs2colidt_offset_hi;
- } coldata_base_t;
- typedef struct {
- uint16_t base_idx;
- uint16_t undefined_idx;
- uint16_t overrides_offset;
- uint16_t multistart_offset;
- } coldata_der_t;
- static int init_cur_collate(int der_num, __collate_t *cur_collate)
- {
- const uint16_t *__locale_collate_tbl = __locale_mmap->collate_data;
- coldata_header_t *cdh;
- coldata_base_t *cdb;
- coldata_der_t *cdd;
- const uint16_t *p;
- size_t n;
- uint16_t i, w;
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning kill of x86-specific asserts
- #endif
- #if 0
- assert(sizeof(coldata_base_t) == 19*2);
- assert(sizeof(coldata_der_t) == 4*2);
- assert(sizeof(coldata_header_t) == 8*2);
- #endif
- if (!der_num) {
- cur_collate->num_weights = 0;
- return 1;
- }
- --der_num;
- cdh = (coldata_header_t *) __locale_collate_tbl;
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning CONSIDER: Should we assert here?
- #endif
- #if 0
- if (der_num >= cdh->num_der) {
- return 0;
- }
- #else
- assert((der_num < cdh->num_der));
- #endif
- cdd = (coldata_der_t *)(__locale_collate_tbl
- + (sizeof(coldata_header_t)
- + cdh->num_base * sizeof(coldata_base_t)
- + der_num * sizeof(coldata_der_t)
- )/2 );
- cdb = (coldata_base_t *)(__locale_collate_tbl
- + (sizeof(coldata_header_t)
- + cdd->base_idx * sizeof(coldata_base_t)
- )/2 );
- __memcpy(cur_collate, cdb, offsetof(coldata_base_t,index2weight_offset));
- cur_collate->undefined_idx = cdd->undefined_idx;
- cur_collate->ti_mask = (1 << cur_collate->ti_shift)-1;
- cur_collate->ii_mask = (1 << cur_collate->ii_shift)-1;
- n = (sizeof(coldata_header_t) + cdh->num_base * sizeof(coldata_base_t)
- + cdh->num_der * sizeof(coldata_der_t))/2;
- cur_collate->index2weight_tbl = __locale_collate_tbl + n + cdb->index2weight_offset;
- n += cdh->num_index2weight;
- cur_collate->index2ruleidx_tbl = __locale_collate_tbl + n + cdb->index2ruleidx_offset;
- n += cdh->num_index2ruleidx;
- cur_collate->multistart_tbl = __locale_collate_tbl + n + cdd->multistart_offset;
- n += cdh->num_multistart;
- cur_collate->overrides_tbl = __locale_collate_tbl + n + cdd->overrides_offset;
- n += cdh->num_override;
- cur_collate->ruletable = __locale_collate_tbl + n;
- n += cdh->num_ruletable;
- cur_collate->weightstr = __locale_collate_tbl + n;
- n += cdh->num_weightstr;
- cur_collate->wcs2colidt_tbl = __locale_collate_tbl + n
- + (((unsigned long)(cdb->wcs2colidt_offset_hi)) << 16)
- + cdb->wcs2colidt_offset_low;
- cur_collate->MAX_WEIGHTS = cdh->MAX_WEIGHTS;
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning CONSIDER: Fix the +1 by increasing max_col_index?
- #warning CONSIDER: Since this collate info is dependent only on LC_COLLATE ll_cc and not on codeset, we could just globally allocate this for each in a table
- #endif
- cur_collate->index2weight = calloc(2*cur_collate->max_col_index+2,
- sizeof(uint16_t));
- if (!cur_collate->index2weight) {
- return 0;
- }
- cur_collate->index2ruleidx = cur_collate->index2weight
- + cur_collate->max_col_index + 1;
- __memcpy(cur_collate->index2weight, cur_collate->index2weight_tbl,
- cur_collate->num_col_base * sizeof(uint16_t));
- __memcpy(cur_collate->index2ruleidx, cur_collate->index2ruleidx_tbl,
- cur_collate->num_col_base * sizeof(uint16_t));
-
- p = cur_collate->overrides_tbl;
- while (*p > 1) {
- n = *p++;
- w = *p++;
- do {
- i = *p++;
- cur_collate->index2weight[i-1] = w++;
- cur_collate->index2ruleidx[i-1] = *p++;
- } while (--n);
- }
- assert(*p == 1);
- while (*++p) {
- i = *p;
- cur_collate->index2weight[i-1] = *++p;
- cur_collate->index2ruleidx[i-1] = *++p;
- }
- for (i=0 ; i < cur_collate->multistart_tbl[0] ; i++) {
- p = cur_collate->multistart_tbl;
- p += p[i];
- do {
- n = *p++;
- do {
- if (!*p) {
- goto FOUND;
- }
-
- do {
- } while (*p++);
- break;
- } while (1);
- } while (1);
- FOUND:
- continue;
- }
- return 1;
- }
- int _locale_set_l(const unsigned char *p, __locale_t base)
- {
- const char **x;
- unsigned char *s = base->cur_locale + 1;
- const size_t *stp;
- const unsigned char *r;
- const uint16_t *io;
- const uint16_t *ii;
- const unsigned char *d;
- int row;
- int crow;
- int len;
- int c;
- int i = 0;
- __collate_t newcol;
- ++p;
- newcol.index2weight = NULL;
- if ((p[2*LC_COLLATE] != s[2*LC_COLLATE])
- || (p[2*LC_COLLATE + 1] != s[2*LC_COLLATE + 1])
- ) {
- row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f);
- assert(row < __LOCALE_DATA_NUM_LOCALES);
- if (!init_cur_collate(__locale_mmap->locales[ __LOCALE_DATA_WIDTH_LOCALES
- * row + 3 + LC_COLLATE ],
- &newcol)
- ) {
- return 0;
- }
- free(base->collate.index2weight);
- __memcpy(&base->collate, &newcol, sizeof(__collate_t));
- }
- do {
- if ((*p != *s) || (p[1] != s[1])) {
- row = (((int)(*p & 0x7f)) << 7) + (p[1] & 0x7f);
- assert(row < __LOCALE_DATA_NUM_LOCALES);
- *s = *p;
- s[1] = p[1];
- if ((i != LC_COLLATE)
- && ((len = __locale_mmap->lc_common_item_offsets_LEN[i]) != 0)
- ) {
- crow = __locale_mmap->locales[ __LOCALE_DATA_WIDTH_LOCALES * row
- + 3 + i ]
- * len;
- x = (const char **)(((char *) base)
- + base->category_offsets[i]);
-
- stp = __locale_mmap->lc_common_tbl_offsets + 4*i;
- r = (const unsigned char *)( ((char *)__locale_mmap) + *stp );
- io = (const uint16_t *)( ((char *)__locale_mmap) + *++stp );
- ii = (const uint16_t *)( ((char *)__locale_mmap) + *++stp );
- d = (const unsigned char *)( ((char *)__locale_mmap) + *++stp );
- for (c=0 ; c < len ; c++) {
- *(x + c) = d + ii[ r[crow + c] + io[c] ];
- }
- }
- if (i == LC_CTYPE) {
- c = __locale_mmap->locales[ __LOCALE_DATA_WIDTH_LOCALES * row
- + 2 ];
- if (c <= 2) {
- if (c == 2) {
- base->codeset = utf8;
- base->encoding = __ctype_encoding_utf8;
-
- base->mb_cur_max = 6;
- } else {
- assert(c==1);
- base->codeset = ascii;
- base->encoding = __ctype_encoding_7_bit;
- base->mb_cur_max = 1;
- }
- } else {
- const __codeset_8_bit_t *c8b;
- r = CODESET_LIST;
- base->codeset = r + r[c -= 3];
- base->encoding = __ctype_encoding_8_bit;
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning REMINDER: update 8 bit mb_cur_max when translit implemented!
- #endif
-
- base->mb_cur_max = 1;
- c8b = __locale_mmap->codeset_8_bit + c;
- #ifdef __CTYPE_HAS_8_BIT_LOCALES
- base->idx8ctype = c8b->idx8ctype;
- base->idx8uplow = c8b->idx8uplow;
- #ifdef __UCLIBC_HAS_WCHAR__
- base->idx8c2wc = c8b->idx8c2wc;
- base->idx8wc2c = c8b->idx8wc2c;
-
- #endif
-
- __memcpy(base->__ctype_b_data,
- __C_ctype_b - __UCLIBC_CTYPE_B_TBL_OFFSET,
- (256 + __UCLIBC_CTYPE_B_TBL_OFFSET)
- * sizeof(__ctype_mask_t));
- __memcpy(base->__ctype_tolower_data,
- __C_ctype_tolower - __UCLIBC_CTYPE_TO_TBL_OFFSET,
- (256 + __UCLIBC_CTYPE_TO_TBL_OFFSET)
- * sizeof(__ctype_touplow_t));
- __memcpy(base->__ctype_toupper_data,
- __C_ctype_toupper - __UCLIBC_CTYPE_TO_TBL_OFFSET,
- (256 + __UCLIBC_CTYPE_TO_TBL_OFFSET)
- * sizeof(__ctype_touplow_t));
- #define Cctype_TBL_MASK ((1 << __LOCALE_DATA_Cctype_IDX_SHIFT) - 1)
- #define Cctype_IDX_OFFSET (128 >> __LOCALE_DATA_Cctype_IDX_SHIFT)
- {
- int u;
- __ctype_mask_t m;
- for (u=0 ; u < 128 ; u++) {
- #ifdef __LOCALE_DATA_Cctype_PACKED
- c = base->tbl8ctype
- [ ((int)(c8b->idx8ctype
- [(u >> __LOCALE_DATA_Cctype_IDX_SHIFT) ])
- << (__LOCALE_DATA_Cctype_IDX_SHIFT - 1))
- + ((u & Cctype_TBL_MASK) >> 1)];
- c = (u & 1) ? (c >> 4) : (c & 0xf);
- #else
- c = base->tbl8ctype
- [ ((int)(c8b->idx8ctype
- [(u >> __LOCALE_DATA_Cctype_IDX_SHIFT) ])
- << __LOCALE_DATA_Cctype_IDX_SHIFT)
- + (u & Cctype_TBL_MASK) ];
- #endif
- m = base->code2flag[c];
- base->__ctype_b_data
- [128 + __UCLIBC_CTYPE_B_TBL_OFFSET + u]
- = m;
- #ifdef __UCLIBC_HAS_CTYPE_SIGNED__
- if (((signed char)(128 + u)) != -1) {
- base->__ctype_b_data[__UCLIBC_CTYPE_B_TBL_OFFSET
- + ((signed char)(128 + u))]
- = m;
- }
- #endif
- base->__ctype_tolower_data
- [128 + __UCLIBC_CTYPE_TO_TBL_OFFSET + u]
- = 128 + u;
- base->__ctype_toupper_data
- [128 + __UCLIBC_CTYPE_TO_TBL_OFFSET + u]
- = 128 + u;
- if (m & (_ISlower|_ISupper)) {
- c = base->tbl8uplow
- [ ((int)(c8b->idx8uplow
- [u >> __LOCALE_DATA_Cuplow_IDX_SHIFT])
- << __LOCALE_DATA_Cuplow_IDX_SHIFT)
- + ((128 + u)
- & ((1 << __LOCALE_DATA_Cuplow_IDX_SHIFT)
- - 1)) ];
- if (m & _ISlower) {
- base->__ctype_toupper_data
- [128 + __UCLIBC_CTYPE_TO_TBL_OFFSET + u]
- = (unsigned char)(128 + u + c);
- #ifdef __UCLIBC_HAS_CTYPE_SIGNED__
- if (((signed char)(128 + u)) != -1) {
- base->__ctype_toupper_data
- [__UCLIBC_CTYPE_TO_TBL_OFFSET
- + ((signed char)(128 + u))]
- = (unsigned char)(128 + u + c);
- }
- #endif
- } else {
- base->__ctype_tolower_data
- [128 + __UCLIBC_CTYPE_TO_TBL_OFFSET + u]
- = (unsigned char)(128 + u - c);
- #ifdef __UCLIBC_HAS_CTYPE_SIGNED__
- if (((signed char)(128 + u)) != -1) {
- base->__ctype_tolower_data
- [__UCLIBC_CTYPE_TO_TBL_OFFSET
- + ((signed char)(128 + u))]
- = (unsigned char)(128 + u - c);
- }
- #endif
- }
- }
- }
- }
- #ifdef __UCLIBC_HAS_XLOCALE__
- base->__ctype_b = base->__ctype_b_data
- + __UCLIBC_CTYPE_B_TBL_OFFSET;
- base->__ctype_tolower = base->__ctype_tolower_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
- base->__ctype_toupper = base->__ctype_toupper_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
- #else
- __ctype_b = base->__ctype_b_data
- + __UCLIBC_CTYPE_B_TBL_OFFSET;
- __ctype_tolower = base->__ctype_tolower_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
- __ctype_toupper = base->__ctype_toupper_data
- + __UCLIBC_CTYPE_TO_TBL_OFFSET;
- #endif
- #endif
- }
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Put the outdigit string length in the locale_mmap object.
- #endif
- d = base->outdigit_length;
- x = &base->outdigit0_mb;
- for (c = 0 ; c < 10 ; c++) {
- ((unsigned char *)d)[c] = __strlen(x[c]);
- assert(d[c] > 0);
- }
- } else if (i == LC_NUMERIC) {
- assert(LC_NUMERIC > LC_CTYPE);
- base->decimal_point_len
- = __locale_mbrtowc_l(&base->decimal_point_wc,
- base->decimal_point, base);
- assert(base->decimal_point_len > 0);
- assert(base->decimal_point[base->decimal_point_len] == 0);
- if (*base->grouping) {
- base->thousands_sep_len
- = __locale_mbrtowc_l(&base->thousands_sep_wc,
- base->thousands_sep, base);
- #if 1
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Remove hack involving grouping without a thousep char (bg_BG).
- #endif
- assert(base->thousands_sep_len >= 0);
- if (base->thousands_sep_len == 0) {
- base->grouping = base->thousands_sep;
- }
- assert(base->thousands_sep[base->thousands_sep_len] == 0);
- #else
- assert(base->thousands_sep_len > 0);
- assert(base->thousands_sep[base->thousands_sep_len] == 0);
- #endif
- }
- }
- }
- ++i;
- p += 2;
- s += 2;
- } while (i < LC_ALL);
- return 1;
- }
- static const uint16_t __code2flag[16] = {
- 0,
- _ISprint|_ISgraph|_ISalnum|_ISalpha,
- _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower,
- _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower|_ISupper,
- _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper,
- _ISprint|_ISgraph|_ISalnum|_ISdigit,
- _ISprint|_ISgraph|_ISpunct,
- _ISprint|_ISgraph,
- _ISprint|_ISspace,
- _ISprint|_ISspace|_ISblank,
- _ISspace,
- _ISspace|_ISblank,
- _IScntrl|_ISspace,
- _IScntrl|_ISspace|_ISblank,
- _IScntrl
- };
- void _locale_init_l(__locale_t base)
- {
- __memset(base->cur_locale, 0, LOCALE_SELECTOR_SIZE);
- base->cur_locale[0] = '#';
- __memcpy(base->category_item_count,
- __locale_mmap->lc_common_item_offsets_LEN,
- LC_ALL);
- ++base->category_item_count[0];
- base->category_offsets[0] = offsetof(__uclibc_locale_t, outdigit0_mb);
- base->category_offsets[1] = offsetof(__uclibc_locale_t, decimal_point);
- base->category_offsets[2] = offsetof(__uclibc_locale_t, int_curr_symbol);
- base->category_offsets[3] = offsetof(__uclibc_locale_t, abday_1);
- base->category_offsets[5] = offsetof(__uclibc_locale_t, yesexpr);
- #ifdef __CTYPE_HAS_8_BIT_LOCALES
- base->tbl8ctype
- = (const unsigned char *) &__locale_mmap->tbl8ctype;
- base->tbl8uplow
- = (const unsigned char *) &__locale_mmap->tbl8uplow;
- #ifdef __UCLIBC_HAS_WCHAR__
- base->tbl8c2wc
- = (const uint16_t *) &__locale_mmap->tbl8c2wc;
- base->tbl8wc2c
- = (const unsigned char *) &__locale_mmap->tbl8wc2c;
-
- #endif
- #endif
- #ifdef __UCLIBC_HAS_WCHAR__
- base->tblwctype
- = (const unsigned char *) &__locale_mmap->tblwctype;
- base->tblwuplow
- = (const unsigned char *) &__locale_mmap->tblwuplow;
- base->tblwuplow_diff
- = (const uint16_t *) &__locale_mmap->tblwuplow_diff;
-
- #endif
-
- #ifdef __UCLIBC_HAS_XLOCALE__
- base->__ctype_b = __C_ctype_b;
- base->__ctype_tolower = __C_ctype_tolower;
- base->__ctype_toupper = __C_ctype_toupper;
- #else
- __ctype_b = __C_ctype_b;
- __ctype_tolower = __C_ctype_tolower;
- __ctype_toupper = __C_ctype_toupper;
- #endif
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Initialize code2flag correctly based on locale_mmap.
- #endif
- base->code2flag = __code2flag;
- _locale_set_l(C_LOCALE_SELECTOR, base);
- }
- void _locale_init(void)
- {
-
-
- _locale_init_l(__global_locale);
- }
- #endif
- #if defined(L_nl_langinfo) || defined(L_nl_langinfo_l)
- #ifdef __LOCALE_C_ONLY
- #define C_LC_ALL 6
- #define cat_start nl_data
- #define C_locale_data (nl_data + C_LC_ALL + 1 + 90)
- static const unsigned char nl_data[C_LC_ALL + 1 + 90 + 320] = {
- '\x00', '\x0b', '\x0e', '\x24', '\x56', '\x56', '\x5a',
- '\x00', '\x02', '\x04', '\x06', '\x08', '\x0a', '\x0c', '\x0e',
- '\x10', '\x12', '\x14', '\x1a', '\x1b', '\x1b', '\x1b', '\x1b',
- '\x1b', '\x1b', '\x1b', '\x1b', '\x1b', '\x1c', '\x1c', '\x1c',
- '\x1c', '\x1c', '\x1c', '\x1c', '\x1c', '\x1c', '\x1c', '\x1c',
- '\x1c', '\x1c', '\x1c', '\x1e', '\x20', '\x24', '\x28', '\x2c',
- '\x30', '\x34', '\x38', '\x3c', '\x43', '\x4a', '\x52', '\x5c',
- '\x65', '\x6c', '\x75', '\x79', '\x7d', '\x81', '\x85', '\x89',
- '\x8d', '\x91', '\x95', '\x99', '\x9d', '\xa1', '\xa5', '\xad',
- '\x36', '\x3c', '\x42', '\x46', '\x4b', '\x50', '\x57', '\x61',
- '\x69', '\x72', '\x7b', '\x7e', '\x81', '\x96', '\x9f', '\xa8',
- '\xb3', '\xb3', '\xb3', '\xb3', '\xb3', '\xb3', '\xb4', '\xba',
- '\xbf', '\xbf',
- '0', '\x00', '1', '\x00', '2', '\x00', '3', '\x00',
- '4', '\x00', '5', '\x00', '6', '\x00', '7', '\x00',
- '8', '\x00', '9', '\x00', 'A', 'S', 'C', 'I',
- 'I', '\x00', '.', '\x00', '\x7f', '\x00', '-', '\x00',
- 'S', 'u', 'n', '\x00', 'M', 'o', 'n', '\x00',
- 'T', 'u', 'e', '\x00', 'W', 'e', 'd', '\x00',
- 'T', 'h', 'u', '\x00', 'F', 'r', 'i', '\x00',
- 'S', 'a', 't', '\x00', 'S', 'u', 'n', 'd',
- 'a', 'y', '\x00', 'M', 'o', 'n', 'd', 'a',
- 'y', '\x00', 'T', 'u', 'e', 's', 'd', 'a',
- 'y', '\x00', 'W', 'e', 'd', 'n', 'e', 's',
- 'd', 'a', 'y', '\x00', 'T', 'h', 'u', 'r',
- 's', 'd', 'a', 'y', '\x00', 'F', 'r', 'i',
- 'd', 'a', 'y', '\x00', 'S', 'a', 't', 'u',
- 'r', 'd', 'a', 'y', '\x00', 'J', 'a', 'n',
- '\x00', 'F', 'e', 'b', '\x00', 'M', 'a', 'r',
- '\x00', 'A', 'p', 'r', '\x00', 'M', 'a', 'y',
- '\x00', 'J', 'u', 'n', '\x00', 'J', 'u', 'l',
- '\x00', 'A', 'u', 'g', '\x00', 'S', 'e', 'p',
- '\x00', 'O', 'c', 't', '\x00', 'N', 'o', 'v',
- '\x00', 'D', 'e', 'c', '\x00', 'J', 'a', 'n',
- 'u', 'a', 'r', 'y', '\x00', 'F', 'e', 'b',
- 'r', 'u', 'a', 'r', 'y', '\x00', 'M', 'a',
- 'r', 'c', 'h', '\x00', 'A', 'p', 'r', 'i',
- 'l', '\x00', 'M', 'a', 'y', '\x00', 'J', 'u',
- 'n', 'e', '\x00', 'J', 'u', 'l', 'y', '\x00',
- 'A', 'u', 'g', 'u', 's', 't', '\x00', 'S',
- 'e', 'p', 't', 'e', 'm', 'b', 'e', 'r',
- '\x00', 'O', 'c', 't', 'o', 'b', 'e', 'r',
- '\x00', 'N', 'o', 'v', 'e', 'm', 'b', 'e',
- 'r', '\x00', 'D', 'e', 'c', 'e', 'm', 'b',
- 'e', 'r', '\x00', 'A', 'M', '\x00', 'P', 'M',
- '\x00', '%', 'a', ' ', '%', 'b', ' ', '%',
- 'e', ' ', '%', 'H', ':', '%', 'M', ':',
- '%', 'S', ' ', '%', 'Y', '\x00', '%', 'm',
- '/', '%', 'd', '/', '%', 'y', '\x00', '%',
- 'H', ':', '%', 'M', ':', '%', 'S', '\x00',
- '%', 'I', ':', '%', 'M', ':', '%', 'S',
- ' ', '%', 'p', '\x00', '^', '[', 'y', 'Y',
- ']', '\x00', '^', '[', 'n', 'N', ']', '\x00',
- };
- char *nl_langinfo(nl_item item)
- {
- unsigned int c;
- unsigned int i;
- if ((c = _NL_ITEM_CATEGORY(item)) < C_LC_ALL) {
- if ((i = cat_start[c] + _NL_ITEM_INDEX(item)) < cat_start[c+1]) {
- return (char *) C_locale_data + nl_data[C_LC_ALL+1+i] + 2*(i & 64);
- }
- }
- return (char *) cat_start;
- }
- #else
- #if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
- char *nl_langinfo(nl_item item)
- {
- return __nl_langinfo_l(item, __UCLIBC_CURLOCALE);
- }
- #else
- static const char empty[] = "";
- char *__XL(nl_langinfo)(nl_item item __LOCALE_PARAM )
- {
- unsigned int c = _NL_ITEM_CATEGORY(item);
- unsigned int i = _NL_ITEM_INDEX(item);
- if ((c < LC_ALL) && (i < __LOCALE_PTR->category_item_count[c])) {
- return ((char **)(((char *) __LOCALE_PTR)
- + __LOCALE_PTR->category_offsets[c]))[i];
- }
- return (char *) empty;
- }
- #endif
- #endif
- #endif
- #ifdef L_newlocale
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Move posix and utf8 strings.
- #endif
- static const char posix[] = "POSIX";
- static const char utf8[] = "UTF-8";
- static int find_locale(int category_mask, const char *p,
- unsigned char *new_locale)
- {
- int i;
- const unsigned char *s;
- uint16_t n;
- unsigned char lang_cult, codeset;
- #if defined(__LOCALE_DATA_AT_MODIFIERS_LENGTH) && 1
-
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning REMINDER: Fix buf size in find_locale.
- #endif
- char buf[18];
- const char *q;
- if ((q = __strchr(p,'@')) != NULL) {
- if ((((size_t)((q-p)-5)) > (sizeof(buf) - 5)) || (p[2] != '_')) {
- return 0;
- }
-
- s = LOCALE_AT_MODIFIERS;
- do {
- if (!__strcmp(s+2, q+1)) {
- break;
- }
- s += 2 + *s;
- } while (*s);
- if (!*s) {
- return 0;
- }
- assert(q - p < sizeof(buf));
- __memcpy(buf, p, q-p);
- buf[q-p] = 0;
- buf[2] = s[1];
- p = buf;
- }
- #endif
- lang_cult = codeset = 0;
- if (((*p == 'C') && !p[1]) || !__strcmp(p, posix)) {
- goto FIND_LOCALE;
- }
- if ((__strlen(p) > 5) && (p[5] == '.')) {
-
-
- codeset = 2;
- if (__strcmp(utf8,p+6) != 0) {
- s = CODESET_LIST;
- do {
- ++codeset;
- if (!__strcmp(CODESET_LIST+*s, p+6)) {
- goto FIND_LANG_CULT;
- }
- } while (*++s);
- return 0;
- }
- }
- FIND_LANG_CULT:
- s = LOCALE_NAMES;
- do {
-
- ++lang_cult;
- if (!__strncmp(s,p,5)) {
- goto FIND_LOCALE;
- }
- s += 5;
- } while (lang_cult < __LOCALE_DATA_NUM_LOCALE_NAMES);
- return 0;
- FIND_LOCALE:
- s = LOCALES;
- n = 0;
- do {
- if ((lang_cult == *s) && ((codeset == s[1]) || (codeset == s[2]))) {
- i = 1;
- s = new_locale + 1;
- do {
- if (category_mask & i) {
-
- ((unsigned char *) s)[0] = (n >> 7) | 0x80;
- ((unsigned char *) s)[1] = (n & 0x7f) | 0x80;
- }
- s += 2;
- i += i;
- } while (i < (1 << LC_ALL));
- return i;
- }
- s += __LOCALE_DATA_WIDTH_LOCALES;
- ++n;
- } while (n <= __LOCALE_DATA_NUM_LOCALES);
- return 0;
- }
- static unsigned char *composite_locale(int category_mask, const char *locale,
- unsigned char *new_locale)
- {
- char buf[MAX_LOCALE_STR];
- char *t;
- char *e;
- int c;
- int component_mask;
- if (!__strchr(locale,'=')) {
- if (!find_locale(category_mask, locale, new_locale)) {
- return NULL;
- }
- return new_locale;
- }
- if (__strlen(locale) >= sizeof(buf)) {
- return NULL;
- }
- stpcpy(buf, locale);
- component_mask = 0;
- t = strtok_r(buf, "=", &e);
- do {
- c = 0;
- while (__strcmp(CATEGORY_NAMES + (int) CATEGORY_NAMES[c], t)) {
- if (++c == LC_ALL) {
- return NULL;
- }
- }
- t = strtok_r(NULL, ";", &e);
- c = (1 << c);
- if (component_mask & c) {
- return NULL;
- }
- component_mask |= c;
- if ((category_mask & c) && (!t || !find_locale(c, t, new_locale))) {
- return NULL;
- }
- } while ((t = strtok_r(NULL, "=", &e)) != NULL);
- if (category_mask & ~component_mask) {
- return NULL;
- }
- return new_locale;
- }
- __locale_t __newlocale(int category_mask, const char *locale, __locale_t base)
- {
- const unsigned char *p;
- int i, j, k;
- unsigned char new_selector[LOCALE_SELECTOR_SIZE];
- if (category_mask == (1 << LC_ALL)) {
- category_mask = LC_ALL_MASK;
- }
- if (!locale || (((unsigned int)(category_mask)) > LC_ALL_MASK)) {
- INVALID:
- __set_errno(EINVAL);
- return NULL;
- }
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Rename cur_locale to locale_selector.
- #endif
- __strcpy((char *) new_selector,
- (base ? (char *) base->cur_locale : C_LOCALE_SELECTOR));
- if (!*locale) {
- #ifndef __UCLIBC_HAS_THREADS__
- static
- #endif
- const char *envstr[4] = { "LC_ALL", NULL, "LANG", posix };
- i = 1;
- k = 0;
- do {
- if (category_mask & i) {
-
- envstr[1] = CATEGORY_NAMES + CATEGORY_NAMES[k];
- j = 0;
- do {
- p = envstr[j];
- } while ((++j < 4) && (!(p = getenv(p)) || !*p));
-
-
- if (!find_locale(i, p, new_selector)) {
- goto INVALID;
- }
- }
- i += i;
- } while (++k < LC_ALL);
- } else if (!composite_locale(category_mask, locale, new_selector)) {
- goto INVALID;
- }
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning TODO: Do a compatible codeset check!
- #endif
-
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning CONSIDER: Probably want a _locale_new func to allow for caching of locales.
- #endif
- #if 0
- if (base) {
- _locale_set_l(new_selector, base);
- } else {
- base = _locale_new(new_selector);
- }
- #else
- if (!base) {
- if ((base = malloc(sizeof(__uclibc_locale_t))) == NULL) {
- return base;
- }
- _locale_init_l(base);
- }
- _locale_set_l(new_selector, base);
- #endif
- return base;
- }
- weak_alias(__newlocale, newlocale)
- #endif
- #ifdef L_duplocale
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning REMINDER: When we allocate ctype tables, remember to dup them.
- #endif
- __locale_t __duplocale(__locale_t dataset)
- {
- __locale_t r;
- uint16_t * i2w;
- size_t n;
- assert(dataset != LC_GLOBAL_LOCALE);
- if ((r = malloc(sizeof(__uclibc_locale_t))) != NULL) {
- n = 2*dataset->collate.max_col_index+2;
- if ((i2w = calloc(n, sizeof(uint16_t)))
- != NULL
- ) {
- __memcpy(r, dataset, sizeof(__uclibc_locale_t));
- r->collate.index2weight = i2w;
- __memcpy(i2w, dataset->collate.index2weight, n * sizeof(uint16_t));
- } else {
- free(r);
- r = NULL;
- }
- }
- return r;
- }
- weak_alias(__duplocale, duplocale)
- #endif
- #ifdef L_freelocale
- #ifdef __UCLIBC_MJN3_ONLY__
- #warning REMINDER: When we allocate ctype tables, remember to free them.
- #endif
- void __freelocale(__locale_t dataset)
- {
- assert(dataset != __global_locale);
- assert(dataset != LC_GLOBAL_LOCALE);
- free(dataset->collate.index2weight);
- free(dataset);
- }
- weak_alias(__freelocale, freelocale)
- #endif
- #ifdef L_uselocale
- __locale_t __uselocale(__locale_t dataset)
- {
- __locale_t old;
- if (!dataset) {
- old = __UCLIBC_CURLOCALE;
- } else {
- if (dataset == LC_GLOBAL_LOCALE) {
- dataset = __global_locale;
- }
- #ifdef __UCLIBC_HAS_THREADS__
- old = __curlocale_set(dataset);
- #else
- old = __curlocale_var;
- __curlocale_var = dataset;
- #endif
- }
- if (old == __global_locale) {
- return LC_GLOBAL_LOCALE;
- }
- return old;
- }
- weak_alias(__uselocale, uselocale)
- #endif
- #ifdef L___curlocale
- #ifdef __UCLIBC_HAS_THREADS__
- __locale_t weak_const_function __curlocale(void)
- {
- return __curlocale_var;
- }
- __locale_t weak_function __curlocale_set(__locale_t newloc)
- {
- __locale_t oldloc = __curlocale_var;
- assert(newloc != LC_GLOBAL_LOCALE);
- __curlocale_var = newloc;
- return oldloc;
- }
- #endif
- #endif
- #ifdef L___locale_mbrtowc_l
- #ifndef __CTYPE_HAS_UTF_8_LOCALES
- #warning __CTYPE_HAS_UTF_8_LOCALES not set!
- #endif
- #ifndef __CTYPE_HAS_8_BIT_LOCALES
- #warning __CTYPE_HAS_8_BIT_LOCALES not set!
- #endif
- #define Cc2wc_IDX_SHIFT __LOCALE_DATA_Cc2wc_IDX_SHIFT
- #define Cc2wc_ROW_LEN __LOCALE_DATA_Cc2wc_ROW_LEN
- extern size_t _wchar_utf8sntowcs(wchar_t *__restrict pwc, size_t wn,
- const char **__restrict src, size_t n,
- mbstate_t *ps, int allow_continuation) attribute_hidden;
- int __locale_mbrtowc_l(wchar_t *__restrict dst,
- const char *__restrict src,
- __locale_t loc )
- {
- #ifdef __CTYPE_HAS_UTF_8_LOCALES
- if (loc->encoding == __ctype_encoding_utf8) {
- mbstate_t ps;
- const char *p = src;
- size_t r;
- ps.__mask = 0;
- r = _wchar_utf8sntowcs(dst, 1, &p, SIZE_MAX, &ps, 1);
- return (r == 1) ? (p-src) : r;
- }
- #endif
- #ifdef __CTYPE_HAS_8_BIT_LOCALES
- assert((loc->encoding == __ctype_encoding_7_bit) || (loc->encoding == __ctype_encoding_8_bit));
- #else
- assert(loc->encoding == __ctype_encoding_7_bit);
- #endif
- if ((*dst = ((unsigned char)(*src))) < 0x80) {
- return (*src != 0);
- }
- #ifdef __CTYPE_HAS_8_BIT_LOCALES
- if (loc->encoding == __ctype_encoding_8_bit) {
- wchar_t wc = *dst - 0x80;
- *dst = loc->tbl8c2wc[
- (loc->idx8c2wc[wc >> Cc2wc_IDX_SHIFT]
- << Cc2wc_IDX_SHIFT) + (wc & (Cc2wc_ROW_LEN - 1))];
- if (*dst) {
- return 1;
- }
- }
- #endif
- return -1;
- }
- #endif
|