OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [misc/] [wctype/] [wctype.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*  Copyright (C) 2002, 2003     Manuel Novoa III
2
 *
3
 *  This library is free software; you can redistribute it and/or
4
 *  modify it under the terms of the GNU Library General Public
5
 *  License as published by the Free Software Foundation; either
6
 *  version 2 of the License, or (at your option) any later version.
7
 *
8
 *  This library is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 *  Library General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU Library General Public
14
 *  License along with this library; if not, write to the Free
15
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
 */
17
 
18
/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
19
 *
20
 *  Besides uClibc, I'm using this code in my libc for elks, which is
21
 *  a 16-bit environment with a fairly limited compiler.  It would make
22
 *  things much easier for me if this file isn't modified unnecessarily.
23
 *  In particular, please put any new or replacement functions somewhere
24
 *  else, and modify the makefile to use your version instead.
25
 *  Thanks.  Manuel
26
 *
27
 *  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION! */
28
 
29
#define _GNU_SOURCE
30
#define __NO_CTYPE
31
 
32
#include <wctype.h>
33
#include <assert.h>
34
#include <string.h>
35
#include <errno.h>
36
#include <locale.h>
37
#include <ctype.h>
38
#include <stdint.h>
39
#include <bits/uClibc_uwchar.h>
40
 
41
#if defined(__LOCALE_C_ONLY) && defined(__UCLIBC_DO_XLOCALE)
42
#error xlocale functionality is not supported in stub locale mode.
43
#endif
44
 
45
#ifdef __UCLIBC_HAS_XLOCALE__
46
#include <xlocale.h>
47
#endif /* __UCLIBC_HAS_XLOCALE__ */
48
 
49
/* We know wide char support is enabled.  We wouldn't be here otherwise. */
50
 
51
/* Define this if you want to unify the towupper and towlower code in the
52
 * towctrans function. */
53
/* #define SMALL_UPLOW */
54
 
55
/**********************************************************************/
56
#ifdef __UCLIBC_MJN3_ONLY__
57
#ifdef L_iswspace
58
/* generates one warning */
59
#warning TODO: Fix the __CTYPE_* codes!
60
#endif
61
#endif /* __UCLIBC_MJN3_ONLY__ */
62
 
63
#if 1
64
/* Taking advantage of the C99 mutual-exclusion guarantees for the various
65
 * (w)ctype classes, including the descriptions of printing and control
66
 * (w)chars, we can place each in one of the following mutually-exlusive
67
 * subsets.  Since there are less than 16, we can store the data for
68
 * each (w)chars in a nibble. In contrast, glibc uses an unsigned int
69
 * per (w)char, with one bit flag for each is* type.  While this allows
70
 * a simple '&' operation to determine the type vs. a range test and a
71
 * little special handling for the "blank" and "xdigit" types in my
72
 * approach, it also uses 8 times the space for the tables on the typical
73
 * 32-bit archs we supported.*/
74
enum {
75
        __CTYPE_unclassified = 0,
76
        __CTYPE_alpha_nonupper_nonlower,
77
        __CTYPE_alpha_lower,
78
        __CTYPE_alpha_upper_lower,
79
        __CTYPE_alpha_upper,
80
        __CTYPE_digit,
81
        __CTYPE_punct,
82
        __CTYPE_graph,
83
        __CTYPE_print_space_nonblank,
84
        __CTYPE_print_space_blank,
85
        __CTYPE_space_nonblank_noncntrl,
86
        __CTYPE_space_blank_noncntrl,
87
        __CTYPE_cntrl_space_nonblank,
88
        __CTYPE_cntrl_space_blank,
89
        __CTYPE_cntrl_nonspace
90
};
91
#endif
92
 
93
 
94
/* The following is used to implement wctype(), but it is defined
95
 * here because the ordering must agree with that of the enumeration
96
 * below (ignoring unclassified). */
97
#define __CTYPE_TYPESTRING \
98
        "\6alnum\0\6alpha\0\6blank\0\6cntrl\0\6digit\0\6graph\0\6lower\0" \
99
        "\6print\0\6punct\0\6space\0\6upper\0\7xdigit\0\0"
100
 
101
 
102
/* The values for wctype_t. */
103
enum {
104
        _CTYPE_unclassified = 0,
105
        _CTYPE_isalnum,
106
        _CTYPE_isalpha,
107
        _CTYPE_isblank,
108
        _CTYPE_iscntrl,
109
        _CTYPE_isdigit,
110
        _CTYPE_isgraph,
111
        _CTYPE_islower,
112
        _CTYPE_isprint,
113
        _CTYPE_ispunct,
114
        _CTYPE_isspace,
115
        _CTYPE_isupper,
116
        _CTYPE_isxdigit                         /* _MUST_ be last of the standard classes! */
117
};
118
 
119
/* The following is used to implement wctrans(). */
120
 
121
#define __CTYPE_TRANSTRING      "\10tolower\0\10toupper\0\10totitle\0\0"
122
 
123
enum {
124
        _CTYPE_tolower = 1,
125
        _CTYPE_toupper,
126
        _CTYPE_totitle
127
};
128
 
129
/*--------------------------------------------------------------------*/
130
 
131
#define _CTYPE_iswxdigit (_CTYPE_isxdigit)
132
 
133
/*--------------------------------------------------------------------*/
134
 
135
#ifdef __UCLIBC_MJN3_ONLY__
136
#ifdef L_iswspace
137
/* generates one warning */
138
#warning TODO: Fix WC* defines!
139
#endif
140
#endif /* __UCLIBC_MJN3_ONLY__ */
141
 
142
#define ENCODING                ((__UCLIBC_CURLOCALE_DATA).encoding)
143
 
144
#define WCctype                 ((__UCLIBC_CURLOCALE_DATA).tblwctype)
145
#define WCuplow                 ((__UCLIBC_CURLOCALE_DATA).tblwuplow)
146
#define WCcmob                  ((__UCLIBC_CURLOCALE_DATA).tblwcomb)
147
#define WCuplow_diff    ((__UCLIBC_CURLOCALE_DATA).tblwuplow_diff)
148
 
149
 
150
#define WC_TABLE_DOMAIN_MAX   __LOCALE_DATA_WC_TABLE_DOMAIN_MAX
151
 
152
#define WCctype_II_LEN        __LOCALE_DATA_WCctype_II_LEN
153
#define WCctype_TI_LEN        __LOCALE_DATA_WCctype_TI_LEN
154
#define WCctype_UT_LEN        __LOCALE_DATA_WCctype_UT_LEN
155
#define WCctype_II_SHIFT      __LOCALE_DATA_WCctype_II_SHIFT
156
#define WCctype_TI_SHIFT      __LOCALE_DATA_WCctype_TI_SHIFT
157
 
158
#define WCuplow_II_LEN        __LOCALE_DATA_WCuplow_II_LEN
159
#define WCuplow_TI_LEN        __LOCALE_DATA_WCuplow_TI_LEN
160
#define WCuplow_UT_LEN        __LOCALE_DATA_WCuplow_UT_LEN
161
#define WCuplow_II_SHIFT      __LOCALE_DATA_WCuplow_II_SHIFT
162
#define WCuplow_TI_SHIFT      __LOCALE_DATA_WCuplow_TI_SHIFT
163
 
164
 
165
#define WCctype_TI_MASK         ((1 << (WCctype_TI_SHIFT)) - 1)
166
#define WCctype_II_MASK         ((1 << (WCctype_II_SHIFT)) - 1)
167
 
168
/**********************************************************************/
169
 
170
#undef __PASTE2
171
#undef __PASTE3
172
#define __PASTE2(X,Y)           X ## Y
173
#define __PASTE3(X,Y,Z)         X ## Y ## Z
174
 
175
#ifdef __UCLIBC_DO_XLOCALE
176
 
177
extern int __iswctype_l (wint_t __wc, wctype_t __desc, __locale_t __locale)
178
     __THROW;
179
 
180
#define ISW_FUNC_BODY(NAME) \
181
int __PASTE3(__isw,NAME,_l) (wint_t wc, __locale_t l) \
182
{ \
183
        return __iswctype_l(wc, __PASTE2(_CTYPE_is,NAME), l); \
184
} \
185
weak_alias(__PASTE3(__isw,NAME,_l), __PASTE3(isw,NAME,_l))
186
 
187
#else  /* __UCLIBC_DO_XLOCALE */
188
 
189
extern int __iswctype (wint_t __wc, wctype_t __desc) __THROW;
190
 
191
#define ISW_FUNC_BODY(NAME) \
192
int __PASTE2(isw,NAME) (wint_t wc) \
193
{ \
194
        return __iswctype(wc, __PASTE2(_CTYPE_is,NAME)); \
195
}
196
 
197
#endif /* __UCLIBC_DO_XLOCALE */
198
/**********************************************************************/
199
#if defined(L_iswalnum) || defined(L_iswalnum_l)
200
 
201
ISW_FUNC_BODY(alnum);
202
 
203
#endif
204
/**********************************************************************/
205
#if defined(L_iswalpha) || defined(L_iswalpha_l)
206
 
207
ISW_FUNC_BODY(alpha);
208
 
209
#endif
210
/**********************************************************************/
211
#if defined(L_iswblank) || defined(L_iswblank_l)
212
 
213
ISW_FUNC_BODY(blank);
214
 
215
#endif
216
/**********************************************************************/
217
#if defined(L_iswcntrl) || defined(L_iswcntrl_l)
218
 
219
ISW_FUNC_BODY(cntrl);
220
 
221
#endif
222
/**********************************************************************/
223
#if defined(L_iswdigit) || defined(L_iswdigit_l)
224
 
225
ISW_FUNC_BODY(digit);
226
 
227
#endif
228
/**********************************************************************/
229
#if defined(L_iswgraph) || defined(L_iswgraph_l)
230
 
231
ISW_FUNC_BODY(graph);
232
 
233
#endif
234
/**********************************************************************/
235
#if defined(L_iswlower) || defined(L_iswlower_l)
236
 
237
ISW_FUNC_BODY(lower);
238
 
239
#endif
240
/**********************************************************************/
241
#if defined(L_iswprint) || defined(L_iswprint_l)
242
 
243
ISW_FUNC_BODY(print);
244
 
245
#endif
246
/**********************************************************************/
247
#if defined(L_iswpunct) || defined(L_iswpunct_l)
248
 
249
ISW_FUNC_BODY(punct);
250
 
251
#endif
252
/**********************************************************************/
253
#if defined(L_iswspace) || defined(L_iswspace_l)
254
 
255
ISW_FUNC_BODY(space);
256
 
257
#endif
258
/**********************************************************************/
259
#if defined(L_iswupper) || defined(L_iswupper_l)
260
 
261
ISW_FUNC_BODY(upper);
262
 
263
#endif
264
/**********************************************************************/
265
#if defined(L_iswxdigit) || defined(L_iswxdigit_l)
266
 
267
ISW_FUNC_BODY(xdigit);
268
 
269
#endif
270
/**********************************************************************/
271
#if defined(L_towlower) || defined(L_towlower_l)
272
 
273
#ifdef L_towlower
274
#define TOWLOWER(w) towlower(w)
275
#else  /* L_towlower */
276
#define TOWLOWER(w) __towlower_l(w, __locale_t locale)
277
#undef __UCLIBC_CURLOCALE_DATA
278
#undef __UCLIBC_CURLOCALE
279
#define __UCLIBC_CURLOCALE_DATA (*locale)
280
#define __UCLIBC_CURLOCALE (locale)
281
#endif /* L_towlower */
282
 
283
#ifdef __UCLIBC_HAS_XLOCALE__
284
#define TOWCTRANS(w,d) __towctrans_l(w,d, __UCLIBC_CURLOCALE)
285
#else  /* __UCLIBC_HAS_XLOCALE__ */
286
#define TOWCTRANS(w,d) towctrans(w,d)
287
#endif /* __UCLIBC_HAS_XLOCALE__ */
288
 
289
#define __C_towlower(wc) \
290
        ((((__uwchar_t)(wc)) <= 0x7f) ? (__C_ctype_tolower)[(wc)] : (wc))
291
 
292
#ifdef __LOCALE_C_ONLY
293
 
294
wint_t towlower(wint_t wc)
295
{
296
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
297
        return __C_towlower(wc);
298
#else
299
        return (wc == ((unsigned int)(wc)))
300
                ? __C_tolower(((unsigned int)(wc)))
301
                : 0;
302
#endif
303
}
304
 
305
#else  /* __LOCALE_C_ONLY */
306
 
307
#ifdef SMALL_UPLOW
308
 
309
#if defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__)
310
 
311
wint_t towlower(wint_t wc)
312
{
313
        return __towctrans_l(wc, _CTYPE_tolower, __UCLIBC_CURLOCALE);
314
}
315
 
316
#else  /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
317
 
318
wint_t TOWLOWER(wint_t wc)
319
{
320
        return TOWCTRANS(wc, _CTYPE_tolower);
321
}
322
 
323
#endif /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
324
 
325
#else  /* SMALL_UPLOW */
326
 
327
#if defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__)
328
 
329
wint_t towlower(wint_t wc)
330
{
331
        return __towlower_l(wc, __UCLIBC_CURLOCALE);
332
}
333
 
334
#else  /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
335
 
336
wint_t TOWLOWER(wint_t wc)
337
{
338
        unsigned int sc, n, i;
339
        __uwchar_t u = wc;
340
 
341
        if (ENCODING == __ctype_encoding_7_bit) {
342
                /* We're in the C/POSIX locale, so ignore the tables. */
343
                return __C_towlower(wc);
344
        }
345
 
346
        if (u <= WC_TABLE_DOMAIN_MAX) {
347
                sc = u & ((1 << WCuplow_TI_SHIFT) - 1);
348
                u >>= WCuplow_TI_SHIFT;
349
                n = u & ((1 << WCuplow_II_SHIFT) - 1);
350
                u >>= WCuplow_II_SHIFT;
351
 
352
                i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
353
                i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
354
                        << WCuplow_TI_SHIFT;
355
                i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
356
                                                                                + i + sc]) << 1;
357
                wc += WCuplow_diff[i + 1];
358
        }
359
        return wc;
360
}
361
 
362
#endif /* defined(L_towlower) && defined(__UCLIBC_HAS_XLOCALE__) */
363
 
364
#endif /* SMALL_UPLOW */
365
 
366
#ifdef L_towlower_l
367
weak_alias(__towlower_l, towlower_l)
368
#endif /* L_towlower_l */
369
 
370
#endif /* __LOCALE_C_ONLY */
371
 
372
#endif
373
/**********************************************************************/
374
#if defined(L_towupper) || defined(L_towupper_l)
375
 
376
#ifdef L_towupper
377
#define TOWUPPER(w) towupper(w)
378
#else  /* L_towupper */
379
#define TOWUPPER(w) __towupper_l(w, __locale_t locale)
380
#undef __UCLIBC_CURLOCALE_DATA
381
#undef __UCLIBC_CURLOCALE
382
#define __UCLIBC_CURLOCALE_DATA (*locale)
383
#define __UCLIBC_CURLOCALE (locale)
384
#endif /* L_towupper */
385
 
386
#ifdef __UCLIBC_HAS_XLOCALE__
387
#define TOWCTRANS(w,d) __towctrans_l(w,d, __UCLIBC_CURLOCALE)
388
#else  /* __UCLIBC_HAS_XLOCALE__ */
389
#define TOWCTRANS(w,d) towctrans(w,d)
390
#endif /* __UCLIBC_HAS_XLOCALE__ */
391
 
392
#define __C_towupper(wc) \
393
        ((((__uwchar_t)(wc)) <= 0x7f) ? (__C_ctype_toupper)[(wc)] : (wc))
394
 
395
#ifdef __LOCALE_C_ONLY
396
 
397
wint_t towupper(wint_t wc)
398
{
399
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
400
        return __C_towupper(wc);
401
#else
402
        return (wc == ((unsigned int)(wc)))
403
                ? __C_toupper(((unsigned int)(wc)))
404
                : 0;
405
#endif
406
 
407
}
408
 
409
#else  /* __LOCALE_C_ONLY */
410
 
411
#ifdef SMALL_UPLOW
412
 
413
#if defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__)
414
 
415
wint_t towupper(wint_t wc)
416
{
417
        return __towctrans_l(wc, _CTYPE_toupper, __UCLIBC_CURLOCALE);
418
}
419
 
420
#else  /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
421
 
422
wint_t TOWUPPER(wint_t wc)
423
{
424
        return TOWCTRANS(wc, _CTYPE_toupper);
425
}
426
 
427
#endif /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
428
 
429
#else  /* SMALL_UPLOW */
430
 
431
#if defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__)
432
 
433
wint_t towupper(wint_t wc)
434
{
435
        return __towupper_l(wc, __UCLIBC_CURLOCALE);
436
}
437
 
438
#else  /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
439
 
440
wint_t TOWUPPER(wint_t wc)
441
{
442
        unsigned int sc, n, i;
443
        __uwchar_t u = wc;
444
 
445
        if (ENCODING == __ctype_encoding_7_bit) {
446
                /* We're in the C/POSIX locale, so ignore the tables. */
447
                return __C_towupper(wc);
448
        }
449
 
450
        if (u <= WC_TABLE_DOMAIN_MAX) {
451
                sc = u & ((1 << WCuplow_TI_SHIFT) - 1);
452
                u >>= WCuplow_TI_SHIFT;
453
                n = u & ((1 << WCuplow_II_SHIFT) - 1);
454
                u >>= WCuplow_II_SHIFT;
455
 
456
                i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
457
                i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
458
                        << WCuplow_TI_SHIFT;
459
                i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
460
                                                                                + i + sc]) << 1;
461
                wc += WCuplow_diff[i];
462
        }
463
        return wc;
464
}
465
 
466
#endif /* defined(L_towupper) && defined(__UCLIBC_HAS_XLOCALE__) */
467
 
468
#endif /* SMALL_UPLOW */
469
 
470
#ifdef L_towupper_l
471
weak_alias(__towupper_l, towupper_l)
472
#endif /* L_towupper_l */
473
 
474
#endif /* __LOCALE_C_ONLY */
475
 
476
#endif
477
/**********************************************************************/
478
#ifdef L_wctype
479
 
480
static const unsigned char typestring[] = __CTYPE_TYPESTRING;
481
/*  extern const unsigned char typestring[]; */
482
 
483
wctype_t wctype(const char *property)
484
{
485
        const unsigned char *p;
486
        int i;
487
 
488
        p = typestring;
489
        i = 1;
490
        do {
491
                if (!strcmp(property, ++p)) {
492
                        return i;
493
                }
494
                ++i;
495
                p += p[-1];
496
        } while (*p);
497
 
498
        /* TODO - Add locale-specific classifications. */
499
        return 0;
500
}
501
 
502
#endif
503
/**********************************************************************/
504
#ifdef L_wctype_l
505
 
506
#ifdef __UCLIBC_MJN3_ONLY__
507
#warning REMINDER: Currently wctype_l simply calls wctype.
508
#endif /* __UCLIBC_MJN3_ONLY__ */
509
 
510
wctype_t __wctype_l (const char *property, __locale_t locale)
511
{
512
        return wctype(property);
513
}
514
 
515
weak_alias(__wctype_l, wctype_l)
516
 
517
#endif
518
/**********************************************************************/
519
#if defined(L_iswctype) || defined(L_iswctype_l)
520
 
521
#define __C_iswdigit(c) \
522
        ((sizeof(c) == sizeof(char)) \
523
         ? (((unsigned char)((c) - '0')) < 10) \
524
         : (((__uwchar_t)((c) - '0')) < 10))
525
#define __C_iswxdigit(c) \
526
        (__C_iswdigit(c) \
527
         || ((sizeof(c) == sizeof(char)) \
528
                 ? (((unsigned char)((((c)) | 0x20) - 'a')) < 6) \
529
                 : (((__uwchar_t)((((c)) | 0x20) - 'a')) < 6)))
530
 
531
#ifdef __UCLIBC_MJN3_ONLY__
532
#ifdef L_iswctype
533
#warning CONSIDER: Change to bit shift?  would need to sync with wctype.h
534
#endif
535
#endif /* __UCLIBC_MJN3_ONLY__ */
536
 
537
 
538
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
539
#if !defined(__UCLIBC_HAS_XLOCALE__) || defined(L_iswctype_l)
540
 
541
static const unsigned short int desc2flag[] = {
542
        [_CTYPE_unclassified] = 0,
543
        [_CTYPE_isalnum] = (unsigned short int) _ISwalnum,
544
        [_CTYPE_isalpha] = (unsigned short int) _ISwalpha,
545
        [_CTYPE_isblank] = (unsigned short int) _ISwblank,
546
        [_CTYPE_iscntrl] = (unsigned short int) _ISwcntrl,
547
        [_CTYPE_isdigit] = (unsigned short int) _ISwdigit,
548
        [_CTYPE_isgraph] = (unsigned short int) _ISwgraph,
549
        [_CTYPE_islower] = (unsigned short int) _ISwlower,
550
        [_CTYPE_isprint] = (unsigned short int) _ISwprint,
551
        [_CTYPE_ispunct] = (unsigned short int) _ISwpunct,
552
        [_CTYPE_isspace] = (unsigned short int) _ISwspace,
553
        [_CTYPE_isupper] = (unsigned short int) _ISwupper,
554
        [_CTYPE_isxdigit] = (unsigned short int) _ISwxdigit,
555
};
556
 
557
#endif /* defined(L_iswctype_L) || defined(__LOCALE_C_ONLY) */
558
#endif /* __UCLIBC_HAS_CTYPE_TABLES__ */
559
 
560
#ifdef __LOCALE_C_ONLY
561
 
562
#ifdef __UCLIBC_HAS_CTYPE_TABLES__
563
 
564
int __iswctype(wint_t wc, wctype_t desc)
565
{
566
        /* Note... wctype_t is unsigned. */
567
 
568
        if ((((__uwchar_t) wc) <= 0x7f)
569
                && (desc < (sizeof(desc2flag)/sizeof(desc2flag[0])))
570
                ) {
571
                return __isctype(wc, desc2flag[desc]);
572
        }
573
        return 0;
574
}
575
 
576
#else  /* __UCLIBC_HAS_CTYPE_TABLES__ */
577
 
578
int __iswctype(wint_t wc, wctype_t desc)
579
{
580
        /* This is lame, but it is here just to get it working for now. */
581
 
582
        if (wc == ((unsigned int)(wc))) {
583
                switch(desc) {
584
                        case _CTYPE_isupper:
585
                                return __C_isupper((unsigned int)(wc));
586
                        case _CTYPE_islower:
587
                                return __C_islower((unsigned int)(wc));
588
                        case _CTYPE_isalpha:
589
                                return __C_isalpha((unsigned int)(wc));
590
                        case _CTYPE_isdigit:
591
                                return __C_isdigit((unsigned int)(wc));
592
                        case _CTYPE_isxdigit:
593
                                return __C_isxdigit((unsigned int)(wc));
594
                        case _CTYPE_isspace:
595
                                return __C_isspace((unsigned int)(wc));
596
                        case _CTYPE_isprint:
597
                                return __C_isprint((unsigned int)(wc));
598
                        case _CTYPE_isgraph:
599
                                return __C_isgraph((unsigned int)(wc));
600
                        case _CTYPE_isblank:
601
                                return __C_isblank((unsigned int)(wc));
602
                        case _CTYPE_iscntrl:
603
                                return __C_iscntrl((unsigned int)(wc));
604
                        case _CTYPE_ispunct:
605
                                return __C_ispunct((unsigned int)(wc));
606
                        case _CTYPE_isalnum:
607
                                return __C_isalnum((unsigned int)(wc));
608
                        default:
609
                                break;
610
                }
611
        }
612
        return 0;
613
}
614
 
615
#endif /* __UCLIBC_HAS_CTYPE_TABLES__ */
616
 
617
#else  /* __LOCALE_C_ONLY */
618
 
619
#ifdef __UCLIBC_MJN3_ONLY__
620
#ifdef L_iswctype
621
#warning CONSIDER: Handle combining class?
622
#endif
623
#endif /* __UCLIBC_MJN3_ONLY__ */
624
 
625
#ifdef L_iswctype
626
#define ISWCTYPE(w,d) __iswctype(w,d)
627
#else  /* L_iswctype */
628
#define ISWCTYPE(w,d) __iswctype_l(w,d, __locale_t locale)
629
#undef __UCLIBC_CURLOCALE_DATA
630
#undef __UCLIBC_CURLOCALE
631
#define __UCLIBC_CURLOCALE_DATA (*locale)
632
#define __UCLIBC_CURLOCALE (locale)
633
#endif /* L_iswctype */
634
 
635
#if defined(L_iswctype) && defined(__UCLIBC_HAS_XLOCALE__)
636
 
637
int __iswctype(wint_t wc, wctype_t desc)
638
{
639
        return __iswctype_l(wc, desc, __UCLIBC_CURLOCALE);
640
}
641
 
642
#else  /* defined(L_iswctype) && defined(__UCLIBC_HAS_XLOCALE__) */
643
 
644
int ISWCTYPE(wint_t wc, wctype_t desc)
645
{
646
        unsigned int sc, n, i0, i1;
647
        unsigned char d = __CTYPE_unclassified;
648
 
649
        if ((ENCODING != __ctype_encoding_7_bit) || (((__uwchar_t) wc) <= 0x7f)){
650
                if (desc < _CTYPE_iswxdigit) {
651
                        if (((__uwchar_t) wc) <= WC_TABLE_DOMAIN_MAX) {
652
                                /* From here on, we know wc > 0. */
653
                                sc = wc & WCctype_TI_MASK;
654
                                wc >>= WCctype_TI_SHIFT;
655
                                n = wc & WCctype_II_MASK;
656
                                wc >>= WCctype_II_SHIFT;
657
 
658
                                i0 = WCctype[wc];
659
                                i0 <<= WCctype_II_SHIFT;
660
                                i1 = WCctype[WCctype_II_LEN + i0 + n];
661
                                i1 <<= (WCctype_TI_SHIFT-1);
662
                                d = WCctype[WCctype_II_LEN + WCctype_TI_LEN + i1 + (sc >> 1)];
663
 
664
                                d = (sc & 1) ? (d >> 4) : (d & 0xf);
665
                        } else if ( ((((__uwchar_t)(wc - 0xe0020UL)) <= 0x5f)
666
                                                 || (wc == 0xe0001UL))
667
                                                || ( (((__uwchar_t)(wc - 0xf0000UL)) < 0x20000UL)
668
                                                         && ((wc & 0xffffU) <= 0xfffdU))
669
                                                ) {
670
                                d = __CTYPE_punct;
671
                        }
672
 
673
#if 0
674
                        return ( ((unsigned char)(d - ctype_range[2*desc]))
675
                                         <= ctype_range[2*desc + 1] )
676
                                && ((desc != _CTYPE_iswblank) || (d & 1));
677
#else
678
                        return (__UCLIBC_CURLOCALE_DATA).code2flag[d] & desc2flag[desc];
679
#endif
680
                }
681
 
682
#ifdef __UCLIBC_MJN3_ONLY__
683
#warning TODO: xdigit really needs to be handled better.  Remember only for ascii!
684
#endif /* __UCLIBC_MJN3_ONLY__ */
685
                /* TODO - Add locale-specific classifications. */
686
                return (desc == _CTYPE_iswxdigit) ? __C_iswxdigit(wc) : 0;
687
        }
688
        return 0;
689
}
690
 
691
#endif /* defined(L_iswctype) && defined(__UCLIBC_HAS_XLOCALE__) */
692
 
693
#ifdef L_iswctype_l
694
weak_alias(__iswctype_l, iswctype_l)
695
#endif /* L_iswctype_l */
696
 
697
#endif /* __LOCALE_C_ONLY */
698
 
699
#ifdef L_iswctype
700
weak_alias(__iswctype, iswctype)
701
#endif /* L_iswctype */
702
 
703
#endif
704
/**********************************************************************/
705
#if defined(L_towctrans) || defined(L_towctrans_l)
706
 
707
#ifdef __LOCALE_C_ONLY
708
 
709
/* Minimal support for C/POSIX locale. */
710
 
711
#ifndef _tolower
712
#warning _tolower is undefined!
713
#define _tolower(c)    tolower(c)
714
#endif
715
#ifndef _toupper
716
#warning _toupper is undefined!
717
#define _toupper(c)    toupper(c)
718
#endif
719
 
720
wint_t towctrans(wint_t wc, wctrans_t desc)
721
{
722
        if (((unsigned int)(desc - _CTYPE_tolower))
723
                <= (_CTYPE_toupper - _CTYPE_tolower)
724
                ) {
725
                /* Transliteration is either tolower or toupper. */
726
                if (((__uwchar_t) wc) <= 0x7f) {
727
                        return (desc == _CTYPE_tolower) ? _tolower(wc) : _toupper(wc);
728
                }
729
        } else {
730
                __set_errno(EINVAL);    /* Invalid transliteration. */
731
        }
732
        return wc;
733
}
734
 
735
#else  /* __LOCALE_C_ONLY */
736
 
737
#ifdef L_towctrans
738
#define TOWCTRANS(w,d) towctrans(w,d)
739
#else  /* L_towctrans */
740
#define TOWCTRANS(w,d) __towctrans_l(w,d, __locale_t locale)
741
#undef __UCLIBC_CURLOCALE_DATA
742
#undef __UCLIBC_CURLOCALE
743
#define __UCLIBC_CURLOCALE_DATA (*locale)
744
#define __UCLIBC_CURLOCALE (locale)
745
#endif /* L_towctrans */
746
 
747
#ifdef __UCLIBC_HAS_XLOCALE__
748
#define TOWLOWER(w,l) __towlower_l(w,l)
749
#define TOWUPPER(w,l) __towupper_l(w,l)
750
#else  /* __UCLIBC_HAS_XLOCALE__ */
751
#define TOWLOWER(w,l) towlower(w)
752
#define TOWUPPER(w,l) towupper(w)
753
#endif /* __UCLIBC_HAS_XLOCALE__ */
754
 
755
#if defined(L_towctrans) && defined(__UCLIBC_HAS_XLOCALE__)
756
 
757
wint_t towctrans(wint_t wc, wctrans_t desc)
758
{
759
        return __towctrans_l(wc, desc, __UCLIBC_CURLOCALE);
760
}
761
 
762
#else  /* defined(L_towctrans) && defined(__UCLIBC_HAS_XLOCALE__) */
763
 
764
#ifdef SMALL_UPLOW
765
 
766
wint_t TOWCTRANS(wint_t wc, wctrans_t desc)
767
{
768
        unsigned int sc, n, i;
769
        __uwchar_t u = wc;
770
 
771
        /* TODO - clean up */
772
        if (ENCODING == __ctype_encoding_7_bit) {
773
                if ((((__uwchar_t) wc) > 0x7f)
774
                        || (((unsigned int)(desc - _CTYPE_tolower))
775
                                > (_CTYPE_toupper - _CTYPE_tolower))
776
                        ){
777
                        /* We're in the C/POSIX locale, so ignore non-ASCII values
778
                         * as well an any mappings other than toupper or tolower. */
779
                        return wc;
780
                }
781
        }
782
 
783
        if (((unsigned int)(desc - _CTYPE_tolower))
784
                <= (_CTYPE_totitle - _CTYPE_tolower)
785
                ) {
786
                if (u <= WC_TABLE_DOMAIN_MAX) {
787
                        sc = u & ((1 << WCuplow_TI_SHIFT) - 1);
788
                        u >>= WCuplow_TI_SHIFT;
789
                        n = u & ((1 << WCuplow_II_SHIFT) - 1);
790
                        u >>= WCuplow_II_SHIFT;
791
 
792
                        i = ((unsigned int) WCuplow[u]) << WCuplow_II_SHIFT;
793
                        i = ((unsigned int) WCuplow[WCuplow_II_LEN + i + n])
794
                                << WCuplow_TI_SHIFT;
795
                        i = ((unsigned int) WCuplow[WCuplow_II_LEN + WCuplow_TI_LEN
796
                                                                                        + i + sc]) << 1;
797
                        if (desc == _CTYPE_tolower) {
798
                                ++i;
799
                        }
800
                        wc += WCuplow_diff[i];
801
                        if (desc == _CTYPE_totitle) {
802
#ifdef __UCLIBC_MJN3_ONLY__
803
#warning TODO: Verify totitle special cases!
804
#endif /* __UCLIBC_MJN3_ONLY__ */
805
                                /* WARNING! These special cases work for glibc 2.2.4.  Changes
806
                                 * may be needed if the glibc locale tables are updated. */
807
                                if ( (((__uwchar_t)(wc - 0x1c4)) <= (0x1cc - 0x1c4))
808
                                         || (wc == 0x1f1)
809
                                         ) {
810
                                        ++wc;
811
                                }
812
                        }
813
                }
814
        } else {
815
                /* TODO - Deal with other transliterations. */
816
                __set_errno(EINVAL);
817
        }
818
 
819
        return wc;
820
}
821
 
822
#else  /* SMALL_UPLOW */
823
 
824
wint_t TOWCTRANS(wint_t wc, wctrans_t desc)
825
{
826
        if (ENCODING == __ctype_encoding_7_bit) {
827
                if ((((__uwchar_t) wc) > 0x7f)
828
                        || (((unsigned int)(desc - _CTYPE_tolower))
829
                                > (_CTYPE_toupper - _CTYPE_tolower))
830
                        ){
831
                        /* We're in the C/POSIX locale, so ignore non-ASCII values
832
                         * as well an any mappings other than toupper or tolower. */
833
                        return wc;
834
                }
835
        }
836
 
837
        if (desc == _CTYPE_tolower) {
838
                return TOWLOWER(wc, __UCLIBC_CURLOCALE);
839
        } else if (((unsigned int)(desc - _CTYPE_toupper))
840
                <= (_CTYPE_totitle - _CTYPE_toupper)
841
                ) {
842
                wc = TOWUPPER(wc, __UCLIBC_CURLOCALE);
843
                if (desc == _CTYPE_totitle) {
844
#ifdef __UCLIBC_MJN3_ONLY__
845
#warning TODO: Verify totitle special cases!
846
#endif /* __UCLIBC_MJN3_ONLY__ */
847
                        /* WARNING! These special cases work for glibc 2.2.4.  Changes
848
                         * may be needed if the glibc locale tables are updated. */
849
                        if ( (((__uwchar_t)(wc - 0x1c4)) <= (0x1cc - 0x1c4))
850
                                 || (wc == 0x1f1)
851
                                 ) {
852
                                ++wc;
853
                        }
854
                }
855
        } else {
856
                /* TODO - Deal with other transliterations. */
857
                __set_errno(EINVAL);
858
        }
859
        return wc;
860
}
861
 
862
#endif /* SMALL_UPLOW */
863
 
864
#endif /* defined(L_towctrans) && defined(__UCLIBC_HAS_XLOCALE__) */
865
 
866
#ifdef L_towctrans_l
867
weak_alias(__towctrans_l, towctrans_l)
868
#endif /* L_towctrans_l */
869
 
870
#endif /* __LOCALE_C_ONLY */
871
 
872
#endif
873
/**********************************************************************/
874
#ifdef L_wctrans
875
 
876
static const char transstring[] = __CTYPE_TRANSTRING;
877
 
878
wctrans_t wctrans(const char *property)
879
{
880
        const unsigned char *p;
881
        int i;
882
 
883
        p = transstring;
884
        i = 1;
885
        do {
886
                if (!strcmp(property, ++p)) {
887
                        return i;
888
                }
889
                ++i;
890
                p += p[-1];
891
        } while (*p);
892
 
893
        /* TODO - Add locale-specific translations. */
894
        return 0;
895
}
896
 
897
#endif
898
/**********************************************************************/
899
#ifdef L_wctrans_l
900
 
901
#ifdef __UCLIBC_MJN3_ONLY__
902
#warning REMINDER: Currently wctrans_l simply calls wctrans.
903
#endif /* __UCLIBC_MJN3_ONLY__ */
904
 
905
wctrans_t __wctrans_l(const char *property, __locale_t locale)
906
{
907
        return wctrans(property);
908
}
909
 
910
weak_alias(__wctrans_l, wctrans_l)
911
 
912
#endif
913
/**********************************************************************/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.