3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/rtl/ctype.c
6 * PURPOSE: Character type and conversion functions
9 * HISTORY: ???: Created
10 * 10/01/2000: Added missing functions and changed
11 * all functions to use ctype table
20 #define upalpha ('A' - 'a')
23 unsigned short _ctype[] = {
24 0, /* <EOF>, 0xFFFF */
25 _CONTROL, /* CTRL+@, 0x00 */
26 _CONTROL, /* CTRL+A, 0x01 */
27 _CONTROL, /* CTRL+B, 0x02 */
28 _CONTROL, /* CTRL+C, 0x03 */
29 _CONTROL, /* CTRL+D, 0x04 */
30 _CONTROL, /* CTRL+E, 0x05 */
31 _CONTROL, /* CTRL+F, 0x06 */
32 _CONTROL, /* CTRL+G, 0x07 */
33 _CONTROL, /* CTRL+H, 0x08 */
34 _CONTROL | _SPACE, /* CTRL+I, 0x09 */
35 _CONTROL | _SPACE, /* CTRL+J, 0x0a */
36 _CONTROL | _SPACE, /* CTRL+K, 0x0b */
37 _CONTROL | _SPACE, /* CTRL+L, 0x0c */
38 _CONTROL | _SPACE, /* CTRL+M, 0x0d */
39 _CONTROL, /* CTRL+N, 0x0e */
40 _CONTROL, /* CTRL+O, 0x0f */
41 _CONTROL, /* CTRL+P, 0x10 */
42 _CONTROL, /* CTRL+Q, 0x11 */
43 _CONTROL, /* CTRL+R, 0x12 */
44 _CONTROL, /* CTRL+S, 0x13 */
45 _CONTROL, /* CTRL+T, 0x14 */
46 _CONTROL, /* CTRL+U, 0x15 */
47 _CONTROL, /* CTRL+V, 0x16 */
48 _CONTROL, /* CTRL+W, 0x17 */
49 _CONTROL, /* CTRL+X, 0x18 */
50 _CONTROL, /* CTRL+Y, 0x19 */
51 _CONTROL, /* CTRL+Z, 0x1a */
52 _CONTROL, /* CTRL+[, 0x1b */
53 _CONTROL, /* CTRL+\, 0x1c */
54 _CONTROL, /* CTRL+], 0x1d */
55 _CONTROL, /* CTRL+^, 0x1e */
56 _CONTROL, /* CTRL+_, 0x1f */
57 _SPACE | _BLANK, /* ` ', 0x20 */
58 _PUNCT, /* `!', 0x21 */
60 _PUNCT, /* `#', 0x23 */
61 _PUNCT, /* `$', 0x24 */
62 _PUNCT, /* `%', 0x25 */
63 _PUNCT, /* `&', 0x26 */
65 _PUNCT, /* `(', 0x28 */
66 _PUNCT, /* `)', 0x29 */
67 _PUNCT, /* `*', 0x2a */
68 _PUNCT, /* `+', 0x2b */
69 _PUNCT, /* `,', 0x2c */
70 _PUNCT, /* `-', 0x2d */
71 _PUNCT, /* `.', 0x2e */
72 _PUNCT, /* `/', 0x2f */
73 _DIGIT | _HEX, /* `0', 0x30 */
74 _DIGIT | _HEX, /* `1', 0x31 */
75 _DIGIT | _HEX, /* `2', 0x32 */
76 _DIGIT | _HEX, /* `3', 0x33 */
77 _DIGIT | _HEX, /* `4', 0x34 */
78 _DIGIT | _HEX, /* `5', 0x35 */
79 _DIGIT | _HEX, /* `6', 0x36 */
80 _DIGIT | _HEX, /* `7', 0x37 */
81 _DIGIT | _HEX, /* `8', 0x38 */
82 _DIGIT | _HEX, /* `9', 0x39 */
83 _PUNCT, /* `:', 0x3a */
84 _PUNCT, /* `;', 0x3b */
85 _PUNCT, /* `<', 0x3c */
86 _PUNCT, /* `=', 0x3d */
87 _PUNCT, /* `>', 0x3e */
88 _PUNCT, /* `?', 0x3f */
89 _PUNCT, /* `@', 0x40 */
90 _UPPER | _HEX, /* `A', 0x41 */
91 _UPPER | _HEX, /* `B', 0x42 */
92 _UPPER | _HEX, /* `C', 0x43 */
93 _UPPER | _HEX, /* `D', 0x44 */
94 _UPPER | _HEX, /* `E', 0x45 */
95 _UPPER | _HEX, /* `F', 0x46 */
96 _UPPER, /* `G', 0x47 */
97 _UPPER, /* `H', 0x48 */
98 _UPPER, /* `I', 0x49 */
99 _UPPER, /* `J', 0x4a */
100 _UPPER, /* `K', 0x4b */
101 _UPPER, /* `L', 0x4c */
102 _UPPER, /* `M', 0x4d */
103 _UPPER, /* `N', 0x4e */
104 _UPPER, /* `O', 0x4f */
105 _UPPER, /* `P', 0x50 */
106 _UPPER, /* `Q', 0x51 */
107 _UPPER, /* `R', 0x52 */
108 _UPPER, /* `S', 0x53 */
109 _UPPER, /* `T', 0x54 */
110 _UPPER, /* `U', 0x55 */
111 _UPPER, /* `V', 0x56 */
112 _UPPER, /* `W', 0x57 */
113 _UPPER, /* `X', 0x58 */
114 _UPPER, /* `Y', 0x59 */
115 _UPPER, /* `Z', 0x5a */
116 _PUNCT, /* `[', 0x5b */
118 _PUNCT, /* `]', 0x5d */
119 _PUNCT, /* `^', 0x5e */
120 _PUNCT, /* `_', 0x5f */
122 _LOWER | _HEX, /* `a', 0x61 */
123 _LOWER | _HEX, /* `b', 0x62 */
124 _LOWER | _HEX, /* `c', 0x63 */
125 _LOWER | _HEX, /* `d', 0x64 */
126 _LOWER | _HEX, /* `e', 0x65 */
127 _LOWER | _HEX, /* `f', 0x66 */
128 _LOWER, /* `g', 0x67 */
129 _LOWER, /* `h', 0x68 */
130 _LOWER, /* `i', 0x69 */
131 _LOWER, /* `j', 0x6a */
132 _LOWER, /* `k', 0x6b */
133 _LOWER, /* `l', 0x6c */
134 _LOWER, /* `m', 0x6d */
135 _LOWER, /* `n', 0x6e */
136 _LOWER, /* `o', 0x6f */
137 _LOWER, /* `p', 0x70 */
138 _LOWER, /* `q', 0x71 */
139 _LOWER, /* `r', 0x72 */
140 _LOWER, /* `s', 0x73 */
141 _LOWER, /* `t', 0x74 */
142 _LOWER, /* `u', 0x75 */
143 _LOWER, /* `v', 0x76 */
144 _LOWER, /* `w', 0x77 */
145 _LOWER, /* `x', 0x78 */
146 _LOWER, /* `y', 0x79 */
147 _LOWER, /* `z', 0x7a */
148 _PUNCT, /* `{', 0x7b */
149 _PUNCT, /* `|', 0x7c */
150 _PUNCT, /* `}', 0x7d */
151 _PUNCT, /* `~', 0x7e */
283 unsigned short *_pctype = _ctype + 1;
284 unsigned short *_pwctype = _ctype + 1;
286 int _isctype (int c, int ctypeFlags)
288 return (_pctype[(unsigned char)(c & 0xFF)] & ctypeFlags);
291 int iswctype(wint_t wc, wctype_t wctypeFlags)
293 return (_pwctype[(unsigned char)(wc & 0xFF)] & wctypeFlags);
298 return(_isctype(c, _ALPHA));
303 return(_isctype(c, _ALPHA | _DIGIT));
308 return ((unsigned char)c <= 0x7f);
313 return(_isctype(c, _CONTROL));
318 return(isalnum(c)||(c == '_'));
323 return(isalpha(c)||(c == '_'));
329 return(_isctype(c, _DIGIT));
335 return (_isctype (c, _PUNCT | _ALPHA | _DIGIT));
341 return (_isctype (c, _LOWER));
346 return (_isctype (c, _BLANK | _PUNCT | _ALPHA | _DIGIT));
352 return (_isctype (c, _PUNCT));
358 return (_isctype (c, _SPACE));
363 return (_isctype (c, _UPPER));
368 return (_isctype (c, _HEX));
372 int iswalpha(wint_t c)
374 return (iswctype (c, _ALPHA));
378 int iswdigit(wint_t c)
380 return (iswctype (c, _DIGIT));
383 int iswlower(wint_t c)
385 return (iswctype (c, _LOWER));
388 int iswxdigit(wint_t c)
390 return (iswctype (c, _HEX));
397 return((unsigned)(c) & 0x7f);
402 if (_isctype (c, _UPPER))
403 return (c - upalpha);
409 if (_isctype (c, _LOWER))
410 return (c + upalpha);
417 if (_isctype (c, _UPPER))
418 return (c - upalpha);
424 if (_isctype (c, _LOWER))
425 return (c + upalpha);
429 wchar_t towlower(wchar_t c)
431 if (iswctype (c, _UPPER))
432 return (c - upalpha);
436 wchar_t towupper(wchar_t c)
438 if (iswctype (c, _LOWER))
439 return (c + upalpha);
445 int strcmp(const char *s1, const char *s2)
455 return *(unsigned const char *)s1 - *(unsigned const char *)(s2);
458 int strncmp(const char *s1, const char *s2, size_t n)
465 return *(unsigned const char *)s1 - *(unsigned const char *)--s2;
474 char *strncpy(char *dst, const char *src, size_t n)
483 if ((*d++ = *s++) == 0)
496 void * memmove(void *dest,const void *src,size_t count)
498 char *char_dest = (char *)dest;
499 char *char_src = (char *)src;
501 if ((char_dest <= char_src) || (char_dest >= (char_src+count)))
503 /* non-overlapping buffers */
506 *char_dest = *char_src;
514 /* overlaping buffers */
515 char_dest = (char *)dest + count - 1;
516 char_src = (char *)src + count - 1;
520 *char_dest = *char_src;
530 /* FIXME: these types should be from the default includes */
532 typedef int (* _pfunccmp_t) (char *, char *);
534 #define min(a,b) ((a)<(b)?(a):(b))
537 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
539 #define swapcode(TYPE, parmi, parmj, n) { \
540 long i = (n) / sizeof (TYPE); \
541 register TYPE *pi = (TYPE *) (parmi); \
542 register TYPE *pj = (TYPE *) (parmj); \
544 register TYPE t = *pi; \
550 #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
551 es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
562 swapcode(long, a, b, n)
564 swapcode(char, a, b, n)
568 if (swaptype == 0) { \
569 long t = *(long *)(a); \
570 *(long *)(a) = *(long *)(b); \
573 swapfunc(a, b, es, swaptype)
575 #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
585 return cmp(a, b) < 0 ?
586 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
587 :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
600 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
601 int d, r, swaptype, swap_cnt;
603 loop: SWAPINIT(a, es);
607 for ( pm = (char *) a + es;
608 pm < (char *) a + n * es;
613 pl > (char *) a && cmp(pl - es, pl) > 0;
622 pm = (char *) a + (n / 2) * es;
626 pn = (char *) a + (n - 1) * es;
630 pl = med3(pl, pl + d, pl + 2 * d, cmp);
631 pm = med3(pm - d, pm, pm + d, cmp);
632 pn = med3(pn - 2 * d, pn - d, pn, cmp);
634 pm = med3(pl, pm, pn, cmp);
637 pa = pb = (char *) a + es;
639 pc = pd = (char *) a + (n - 1) * es;
642 while (pb <= pc && (r = cmp(pb, a)) <= 0)
652 while (pb <= pc && (r = cmp(pc, a)) >= 0)
671 if (swap_cnt == 0) /* Switch to insertion sort */
673 for ( pm = (char *) a + es;
674 pm < (char *) a + n * es;
679 pl > (char *) a && cmp(pl - es, pl) > 0;
689 pn = (char *) a + n * es;
690 r = min(pa - (char *)a, pb - pa);
691 vecswap(a, pb - r, r);
692 r = min(pd - pc, pn - pd - es);
693 vecswap(pb, pn - r, r);
694 if ((r = pb - pa) > es)
696 qsort(a, r / es, es, cmp);
698 if ((r = pd - pc) > es)
700 /* Iterate rather than recurse to save stack space */
705 /* qsort(pn - r, r / es, es, cmp);*/