1411677aeSAaron LI /*
2411677aeSAaron LI * Copyright (c) 1987 Regents of the University of California.
3411677aeSAaron LI * All rights reserved.
4411677aeSAaron LI *
5411677aeSAaron LI * Redistribution and use in source and binary forms are permitted
6411677aeSAaron LI * provided that this notice is preserved and that due credit is given
7411677aeSAaron LI * to the University of California at Berkeley. The name of the University
8411677aeSAaron LI * may not be used to endorse or promote products derived from this
9411677aeSAaron LI * software without specific written prior permission. This software
10411677aeSAaron LI * is provided ``as is'' without express or implied warranty.
11411677aeSAaron LI */
12411677aeSAaron LI
13411677aeSAaron LI #include "ascii_strcasecmp.h"
14411677aeSAaron LI
15411677aeSAaron LI /*
16411677aeSAaron LI * This array maps upper-case ASCII letters to their lower-case
17411677aeSAaron LI * equivalents; all other byte values are mapped to themselves,
18411677aeSAaron LI * so this is locale-independent and intended to be locale-independent,
19411677aeSAaron LI * to avoid issues with, for example, "i" and "I" not being lower-case
20411677aeSAaron LI * and upper-case versions of the same letter in Turkish, where
21411677aeSAaron LI * there are separate "i with dot" and "i without dot" letters.
22411677aeSAaron LI */
23411677aeSAaron LI static const unsigned char charmap[] = {
24411677aeSAaron LI 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
25411677aeSAaron LI 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
26411677aeSAaron LI 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
27411677aeSAaron LI 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
28411677aeSAaron LI 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
29411677aeSAaron LI 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
30411677aeSAaron LI 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
31411677aeSAaron LI 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32411677aeSAaron LI 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
33411677aeSAaron LI 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
34411677aeSAaron LI 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
35411677aeSAaron LI 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
36411677aeSAaron LI 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
37411677aeSAaron LI 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
38411677aeSAaron LI 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
39411677aeSAaron LI 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
40411677aeSAaron LI 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
41411677aeSAaron LI 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
42411677aeSAaron LI 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
43411677aeSAaron LI 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
44411677aeSAaron LI 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
45411677aeSAaron LI 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
46411677aeSAaron LI 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
47411677aeSAaron LI 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
48411677aeSAaron LI 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
49411677aeSAaron LI 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
50411677aeSAaron LI 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
51411677aeSAaron LI 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
52411677aeSAaron LI 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
53411677aeSAaron LI 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
54411677aeSAaron LI 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
55411677aeSAaron LI 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
56411677aeSAaron LI };
57411677aeSAaron LI
58411677aeSAaron LI int
ascii_strcasecmp(const char * s1,const char * s2)59411677aeSAaron LI ascii_strcasecmp(const char *s1, const char *s2)
60411677aeSAaron LI {
61*ed775ee7SAntonio Huete Jimenez const unsigned char *cm = charmap,
62411677aeSAaron LI *us1 = (const unsigned char *)s1,
63411677aeSAaron LI *us2 = (const unsigned char *)s2;
64411677aeSAaron LI
65411677aeSAaron LI while (cm[*us1] == cm[*us2++])
66411677aeSAaron LI if (*us1++ == '\0')
67411677aeSAaron LI return(0);
68411677aeSAaron LI return(cm[*us1] - cm[*--us2]);
69411677aeSAaron LI }
70411677aeSAaron LI
71411677aeSAaron LI int
ascii_strncasecmp(const char * s1,const char * s2,size_t n)72*ed775ee7SAntonio Huete Jimenez ascii_strncasecmp(const char *s1, const char *s2, size_t n)
73411677aeSAaron LI {
74*ed775ee7SAntonio Huete Jimenez const unsigned char *cm = charmap,
75411677aeSAaron LI *us1 = (const unsigned char *)s1,
76411677aeSAaron LI *us2 = (const unsigned char *)s2;
77411677aeSAaron LI
78411677aeSAaron LI for (;;) {
79411677aeSAaron LI if (n == 0) {
80411677aeSAaron LI /*
81411677aeSAaron LI * We've run out of characters that we should
82411677aeSAaron LI * compare, and they've all been equal; return
83411677aeSAaron LI * 0, to indicate that the prefixes are the
84411677aeSAaron LI * same.
85411677aeSAaron LI */
86411677aeSAaron LI return(0);
87411677aeSAaron LI }
88411677aeSAaron LI if (cm[*us1] != cm[*us2++]) {
89411677aeSAaron LI /*
90411677aeSAaron LI * We've found a mismatch.
91411677aeSAaron LI */
92411677aeSAaron LI break;
93411677aeSAaron LI }
94411677aeSAaron LI if (*us1++ == '\0') {
95411677aeSAaron LI /*
96411677aeSAaron LI * We've run out of characters *to* compare,
97411677aeSAaron LI * and they've all been equal; return 0, to
98411677aeSAaron LI * indicate that the strings are the same.
99411677aeSAaron LI */
100411677aeSAaron LI return(0);
101411677aeSAaron LI }
102411677aeSAaron LI n--;
103411677aeSAaron LI }
104411677aeSAaron LI return(cm[*us1] - cm[*--us2]);
105411677aeSAaron LI }
106