:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / freetype / ctype.c
1 /* $Id$
2  *
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
7  * PROGRAMMERS:     ???
8  *                  Eric Kohl
9  * HISTORY:         ???: Created
10  *                  10/01/2000: Added missing functions and changed
11  *                              all functions to use ctype table
12  */
13
14 #undef __MSVCRT__
15 #include <ctype.h>
16 #include <string.h>
17
18 #undef _pctype
19
20 #define upalpha ('A' - 'a')
21
22
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 */
59         _PUNCT,                 /* 0x22 */
60         _PUNCT,                 /* `#', 0x23 */
61         _PUNCT,                 /* `$', 0x24 */
62         _PUNCT,                 /* `%', 0x25 */
63         _PUNCT,                 /* `&', 0x26 */
64         _PUNCT,                 /* 0x27 */
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 */
117         _PUNCT,                 /* 0x5c */
118         _PUNCT,                 /* `]', 0x5d */
119         _PUNCT,                 /* `^', 0x5e */
120         _PUNCT,                 /* `_', 0x5f */
121         _PUNCT,                 /* 0x60 */
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 */
152         _CONTROL,               /* 0x7f */
153         0,                      /* 0x80 */
154         0,                      /* 0x81 */
155         0,                      /* 0x82 */
156         0,                      /* 0x83 */
157         0,                      /* 0x84 */
158         0,                      /* 0x85 */
159         0,                      /* 0x86 */
160         0,                      /* 0x87 */
161         0,                      /* 0x88 */
162         0,                      /* 0x89 */
163         0,                      /* 0x8a */
164         0,                      /* 0x8b */
165         0,                      /* 0x8c */
166         0,                      /* 0x8d */
167         0,                      /* 0x8e */
168         0,                      /* 0x8f */
169         0,                      /* 0x90 */
170         0,                      /* 0x91 */
171         0,                      /* 0x92 */
172         0,                      /* 0x93 */
173         0,                      /* 0x94 */
174         0,                      /* 0x95 */
175         0,                      /* 0x96 */
176         0,                      /* 0x97 */
177         0,                      /* 0x98 */
178         0,                      /* 0x99 */
179         0,                      /* 0x9a */
180         0,                      /* 0x9b */
181         0,                      /* 0x9c */
182         0,                      /* 0x9d */
183         0,                      /* 0x9e */
184         0,                      /* 0x9f */
185         0,                      /* 0xa0 */
186         0,                      /* 0xa1 */
187         0,                      /* 0xa2 */
188         0,                      /* 0xa3 */
189         0,                      /* 0xa4 */
190         0,                      /* 0xa5 */
191         0,                      /* 0xa6 */
192         0,                      /* 0xa7 */
193         0,                      /* 0xa8 */
194         0,                      /* 0xa9 */
195         0,                      /* 0xaa */
196         0,                      /* 0xab */
197         0,                      /* 0xac */
198         0,                      /* 0xad */
199         0,                      /* 0xae */
200         0,                      /* 0xaf */
201         0,                      /* 0xb0 */
202         0,                      /* 0xb1 */
203         0,                      /* 0xb2 */
204         0,                      /* 0xb3 */
205         0,                      /* 0xb4 */
206         0,                      /* 0xb5 */
207         0,                      /* 0xb6 */
208         0,                      /* 0xb7 */
209         0,                      /* 0xb8 */
210         0,                      /* 0xb9 */
211         0,                      /* 0xba */
212         0,                      /* 0xbb */
213         0,                      /* 0xbc */
214         0,                      /* 0xbd */
215         0,                      /* 0xbe */
216         0,                      /* 0xbf */
217         0,                      /* 0xc0 */
218         0,                      /* 0xc1 */
219         0,                      /* 0xc2 */
220         0,                      /* 0xc3 */
221         0,                      /* 0xc4 */
222         0,                      /* 0xc5 */
223         0,                      /* 0xc6 */
224         0,                      /* 0xc7 */
225         0,                      /* 0xc8 */
226         0,                      /* 0xc9 */
227         0,                      /* 0xca */
228         0,                      /* 0xcb */
229         0,                      /* 0xcc */
230         0,                      /* 0xcd */
231         0,                      /* 0xce */
232         0,                      /* 0xcf */
233         0,                      /* 0xd0 */
234         0,                      /* 0xd1 */
235         0,                      /* 0xd2 */
236         0,                      /* 0xd3 */
237         0,                      /* 0xd4 */
238         0,                      /* 0xd5 */
239         0,                      /* 0xd6 */
240         0,                      /* 0xd7 */
241         0,                      /* 0xd8 */
242         0,                      /* 0xd9 */
243         0,                      /* 0xda */
244         0,                      /* 0xdb */
245         0,                      /* 0xdc */
246         0,                      /* 0xdd */
247         0,                      /* 0xde */
248         0,                      /* 0xdf */
249         0,                      /* 0xe0 */
250         0,                      /* 0xe1 */
251         0,                      /* 0xe2 */
252         0,                      /* 0xe3 */
253         0,                      /* 0xe4 */
254         0,                      /* 0xe5 */
255         0,                      /* 0xe6 */
256         0,                      /* 0xe7 */
257         0,                      /* 0xe8 */
258         0,                      /* 0xe9 */
259         0,                      /* 0xea */
260         0,                      /* 0xeb */
261         0,                      /* 0xec */
262         0,                      /* 0xed */
263         0,                      /* 0xee */
264         0,                      /* 0xef */
265         0,                      /* 0xf0 */
266         0,                      /* 0xf1 */
267         0,                      /* 0xf2 */
268         0,                      /* 0xf3 */
269         0,                      /* 0xf4 */
270         0,                      /* 0xf5 */
271         0,                      /* 0xf6 */
272         0,                      /* 0xf7 */
273         0,                      /* 0xf8 */
274         0,                      /* 0xf9 */
275         0,                      /* 0xfa */
276         0,                      /* 0xfb */
277         0,                      /* 0xfc */
278         0,                      /* 0xfd */
279         0,                      /* 0xfe */
280         0                       /* 0xff */
281 };
282
283 unsigned short *_pctype = _ctype + 1;
284 unsigned short *_pwctype = _ctype + 1;
285
286 int _isctype (int c, int ctypeFlags)
287 {
288   return (_pctype[(unsigned char)(c & 0xFF)] & ctypeFlags);
289 }
290
291 int iswctype(wint_t wc, wctype_t wctypeFlags)
292 {
293    return (_pwctype[(unsigned char)(wc & 0xFF)] & wctypeFlags);
294 }
295
296 int isalpha(int c)
297 {
298    return(_isctype(c, _ALPHA));
299 }
300
301 int isalnum(int c)
302 {
303    return(_isctype(c, _ALPHA | _DIGIT));
304 }
305
306 int __isascii(int c)
307 {
308    return ((unsigned char)c <= 0x7f);
309 }
310
311 int iscntrl(int c)
312 {
313    return(_isctype(c, _CONTROL));
314 }
315
316 int __iscsym(int c)
317 {
318    return(isalnum(c)||(c == '_'));
319 }
320
321 int __iscsymf(int c)
322 {
323    return(isalpha(c)||(c == '_'));
324 }
325
326
327 int isdigit(int c)
328 {
329    return(_isctype(c, _DIGIT));
330 }
331
332 /*
333 int isgraph(int c)
334 {
335    return (_isctype (c, _PUNCT | _ALPHA | _DIGIT));
336 }
337 */
338
339 int islower(int c)
340 {
341    return (_isctype (c, _LOWER));
342 }
343
344 int isprint(int c)
345 {
346    return (_isctype (c, _BLANK | _PUNCT | _ALPHA | _DIGIT));
347 }
348
349 /*
350 int ispunct(int c)
351 {
352    return (_isctype (c, _PUNCT));
353 }
354 */
355
356 int isspace(int c)
357 {
358    return (_isctype (c, _SPACE));
359 }
360
361 int isupper(int c)
362 {
363    return (_isctype (c, _UPPER));
364 }
365
366 int isxdigit(int c)
367 {
368    return (_isctype (c, _HEX));
369 }
370
371 /*
372 int iswalpha(wint_t c)
373 {
374    return (iswctype (c, _ALPHA));
375 }
376 */
377
378 int iswdigit(wint_t c)
379 {
380    return (iswctype (c, _DIGIT));
381 }
382
383 int iswlower(wint_t c)
384 {
385    return (iswctype (c, _LOWER));
386 }
387
388 int iswxdigit(wint_t c)
389 {
390    return (iswctype (c, _HEX));
391 }
392
393
394 /*
395 int __toascii(int c)
396 {
397    return((unsigned)(c) & 0x7f);
398 }
399
400 int _tolower(int c)
401 {
402    if (_isctype (c, _UPPER))
403        return (c - upalpha);
404    return(c);
405 }
406
407 int _toupper(int c)
408 {
409    if (_isctype (c, _LOWER))
410       return (c + upalpha);
411    return(c);
412 }
413 */
414
415 int tolower(int c)
416 {
417    if (_isctype (c, _UPPER))
418        return (c - upalpha);
419    return(c);
420 }
421
422 int toupper(int c)
423 {
424    if (_isctype (c, _LOWER))
425       return (c + upalpha);
426    return(c);
427 }
428
429 wchar_t towlower(wchar_t c)
430 {
431    if (iswctype (c, _UPPER))
432        return (c - upalpha);
433    return(c);
434 }
435
436 wchar_t towupper(wchar_t c)
437 {
438    if (iswctype (c, _LOWER))
439       return (c + upalpha);
440    return(c);
441 }
442
443 /* EOF */
444
445 int strcmp(const char *s1, const char *s2)
446 {
447         while (*s1 == *s2)
448         {
449                 if (*s1 == 0)
450                         return 0;
451                 s1++;
452                 s2++;
453         }
454
455         return *(unsigned const char *)s1 - *(unsigned const char *)(s2);
456 }
457
458 int strncmp(const char *s1, const char *s2, size_t n)
459 {
460         if (n == 0)
461                 return 0;
462         do
463         {
464                 if (*s1 != *s2++)
465                         return *(unsigned const char *)s1 - *(unsigned const char *)--s2;
466                 if (*s1++ == 0)
467                         break;
468         }
469         while (--n != 0);
470
471         return 0;
472 }
473
474 char *strncpy(char *dst, const char *src, size_t n)
475 {
476         if (n != 0)
477         {
478                 char *d = dst;
479                 const char *s = src;
480
481                 do
482                 {
483                         if ((*d++ = *s++) == 0)
484                         {
485                                 while (--n != 0)
486                                         *d++ = 0;
487                                 break;
488                         }
489                 }
490                 while (--n != 0);
491         }
492
493         return dst;
494 }
495
496 void * memmove(void *dest,const void *src,size_t count)
497 {
498         char *char_dest = (char *)dest;
499         char *char_src = (char *)src;
500
501         if ((char_dest <= char_src) || (char_dest >= (char_src+count)))
502         {
503                 /*  non-overlapping buffers */
504                 while(count > 0)
505                 {
506                         *char_dest = *char_src;
507                         char_dest++;
508                         char_src++;
509                         count--;
510                 }
511         }
512         else
513         {
514                 /* overlaping buffers */
515                 char_dest = (char *)dest + count - 1;
516                 char_src = (char *)src + count - 1;
517
518                 while(count > 0)
519                 {
520                         *char_dest = *char_src;
521                         char_dest--;
522                         char_src--;
523                         count--;
524                 }
525         }
526
527         return dest;
528 }
529
530 /* FIXME: these types should be from the default includes */
531
532 typedef int (*  _pfunccmp_t) (char *, char *);
533
534 #define min(a,b) ((a)<(b)?(a):(b))
535
536 /*
537  * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
538  */
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);           \
543         do {                                            \
544                 register TYPE   t = *pi;                \
545                 *pi++ = *pj;                            \
546                 *pj++ = t;                              \
547         } while (--i > 0);                              \
548 }
549
550 #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
551         es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
552
553 static inline void
554 swapfunc (
555         char    * a,
556         char    * b,
557         int     n,
558         int     swaptype
559         )
560 {
561         if(swaptype <= 1) 
562                 swapcode(long, a, b, n)
563         else
564                 swapcode(char, a, b, n)
565 }
566
567 #define swap(a, b)                                      \
568         if (swaptype == 0) {                            \
569                 long t = *(long *)(a);                  \
570                 *(long *)(a) = *(long *)(b);            \
571                 *(long *)(b) = t;                       \
572         } else                                          \
573                 swapfunc(a, b, es, swaptype)
574
575 #define vecswap(a, b, n)        if ((n) > 0) swapfunc(a, b, n, swaptype)
576
577 static inline char *
578 med3 (
579         char            * a,
580         char            * b,
581         char            * c,
582         _pfunccmp_t     cmp
583         )
584 {
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 ));
588 }
589
590
591 /* EXPORTED */
592 void
593 qsort (
594         void            * a,
595         size_t          n,
596         size_t          es,
597         _pfunccmp_t     cmp
598         )
599 {
600         char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
601         int d, r, swaptype, swap_cnt;
602
603 loop:   SWAPINIT(a, es);
604         swap_cnt = 0;
605         if (n < 7)
606         {
607                 for (   pm = (char *) a + es;
608                         pm < (char *) a + n * es;
609                         pm += es
610                         )
611                 {
612                         for (   pl = pm;
613                                 pl > (char *) a && cmp(pl - es, pl) > 0;
614                                 pl -= es
615                                 )
616                         {
617                                 swap(pl, pl - es);
618                         }
619                 }
620                 return;
621         }
622         pm = (char *) a + (n / 2) * es;
623         if (n > 7)
624         {
625                 pl = (char *) a;
626                 pn = (char *) a + (n - 1) * es;
627                 if (n > 40)
628                 {
629                         d = (n / 8) * 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);
633                 }
634                 pm = med3(pl, pm, pn, cmp);
635         }
636         swap(a, pm);
637         pa = pb = (char *) a + es;
638
639         pc = pd = (char *) a + (n - 1) * es;
640         for (;;)
641         {
642                 while (pb <= pc && (r = cmp(pb, a)) <= 0)
643                 {
644                         if (r == 0)
645                         {
646                                 swap_cnt = 1;
647                                 swap(pa, pb);
648                                 pa += es;
649                         }
650                         pb += es;
651                 }
652                 while (pb <= pc && (r = cmp(pc, a)) >= 0)
653                 {
654                         if (r == 0)
655                         {
656                                 swap_cnt = 1;
657                                 swap(pc, pd);
658                                 pd -= es;
659                         }
660                         pc -= es;
661                 }
662                 if (pb > pc)
663                 {
664                         break;
665                 }
666                 swap(pb, pc);
667                 swap_cnt = 1;
668                 pb += es;
669                 pc -= es;
670         }
671         if (swap_cnt == 0)  /* Switch to insertion sort */
672         {
673                 for (   pm = (char *) a + es;
674                         pm < (char *) a + n * es;
675                         pm += es
676                         )
677                 {
678                         for (   pl = pm;
679                                 pl > (char *) a && cmp(pl - es, pl) > 0; 
680                                 pl -= es
681                                 )
682                         {
683                                 swap(pl, pl - es);
684                         }
685                 }
686                 return;
687         }
688
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)
695         {
696                 qsort(a, r / es, es, cmp);
697         }
698         if ((r = pd - pc) > es)
699         { 
700                 /* Iterate rather than recurse to save stack space */
701                 a = pn - r;
702                 n = r / es;
703                 goto loop;
704         }
705 /*              qsort(pn - r, r / es, es, cmp);*/
706 }