13340d773SGleb Smirnoff /*
23340d773SGleb Smirnoff * Copyright (c) 1987 Regents of the University of California.
33340d773SGleb Smirnoff * All rights reserved.
43340d773SGleb Smirnoff *
53340d773SGleb Smirnoff * Redistribution and use in source and binary forms are permitted
63340d773SGleb Smirnoff * provided that this notice is preserved and that due credit is given
73340d773SGleb Smirnoff * to the University of California at Berkeley. The name of the University
83340d773SGleb Smirnoff * may not be used to endorse or promote products derived from this
93340d773SGleb Smirnoff * software without specific written prior permission. This software
103340d773SGleb Smirnoff * is provided ``as is'' without express or implied warranty.
113340d773SGleb Smirnoff */
123340d773SGleb Smirnoff
133340d773SGleb Smirnoff #include "ascii_strcasecmp.h"
143340d773SGleb Smirnoff
153340d773SGleb Smirnoff /*
163340d773SGleb Smirnoff * This array maps upper-case ASCII letters to their lower-case
173340d773SGleb Smirnoff * equivalents; all other byte values are mapped to themselves,
183340d773SGleb Smirnoff * so this is locale-independent and intended to be locale-independent,
193340d773SGleb Smirnoff * to avoid issues with, for example, "i" and "I" not being lower-case
203340d773SGleb Smirnoff * and upper-case versions of the same letter in Turkish, where
213340d773SGleb Smirnoff * there are separate "i with dot" and "i without dot" letters.
223340d773SGleb Smirnoff */
233340d773SGleb Smirnoff static const unsigned char charmap[] = {
243340d773SGleb Smirnoff 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
253340d773SGleb Smirnoff 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
263340d773SGleb Smirnoff 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
273340d773SGleb Smirnoff 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
283340d773SGleb Smirnoff 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
293340d773SGleb Smirnoff 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
303340d773SGleb Smirnoff 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
313340d773SGleb Smirnoff 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
323340d773SGleb Smirnoff 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
333340d773SGleb Smirnoff 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
343340d773SGleb Smirnoff 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
353340d773SGleb Smirnoff 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
363340d773SGleb Smirnoff 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
373340d773SGleb Smirnoff 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
383340d773SGleb Smirnoff 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
393340d773SGleb Smirnoff 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
403340d773SGleb Smirnoff 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
413340d773SGleb Smirnoff 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
423340d773SGleb Smirnoff 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
433340d773SGleb Smirnoff 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
443340d773SGleb Smirnoff 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
453340d773SGleb Smirnoff 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
463340d773SGleb Smirnoff 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
473340d773SGleb Smirnoff 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
483340d773SGleb Smirnoff 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
493340d773SGleb Smirnoff 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
503340d773SGleb Smirnoff 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
513340d773SGleb Smirnoff 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
523340d773SGleb Smirnoff 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
533340d773SGleb Smirnoff 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
543340d773SGleb Smirnoff 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
553340d773SGleb Smirnoff 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
563340d773SGleb Smirnoff };
573340d773SGleb Smirnoff
583340d773SGleb Smirnoff int
ascii_strcasecmp(const char * s1,const char * s2)593340d773SGleb Smirnoff ascii_strcasecmp(const char *s1, const char *s2)
603340d773SGleb Smirnoff {
61*ee67461eSJoseph Mingrone const unsigned char *cm = charmap,
623340d773SGleb Smirnoff *us1 = (const unsigned char *)s1,
633340d773SGleb Smirnoff *us2 = (const unsigned char *)s2;
643340d773SGleb Smirnoff
653340d773SGleb Smirnoff while (cm[*us1] == cm[*us2++])
663340d773SGleb Smirnoff if (*us1++ == '\0')
673340d773SGleb Smirnoff return(0);
683340d773SGleb Smirnoff return(cm[*us1] - cm[*--us2]);
693340d773SGleb Smirnoff }
703340d773SGleb Smirnoff
713340d773SGleb Smirnoff int
ascii_strncasecmp(const char * s1,const char * s2,size_t n)72*ee67461eSJoseph Mingrone ascii_strncasecmp(const char *s1, const char *s2, size_t n)
733340d773SGleb Smirnoff {
74*ee67461eSJoseph Mingrone const unsigned char *cm = charmap,
753340d773SGleb Smirnoff *us1 = (const unsigned char *)s1,
763340d773SGleb Smirnoff *us2 = (const unsigned char *)s2;
773340d773SGleb Smirnoff
783340d773SGleb Smirnoff for (;;) {
793340d773SGleb Smirnoff if (n == 0) {
803340d773SGleb Smirnoff /*
813340d773SGleb Smirnoff * We've run out of characters that we should
823340d773SGleb Smirnoff * compare, and they've all been equal; return
833340d773SGleb Smirnoff * 0, to indicate that the prefixes are the
843340d773SGleb Smirnoff * same.
853340d773SGleb Smirnoff */
863340d773SGleb Smirnoff return(0);
873340d773SGleb Smirnoff }
883340d773SGleb Smirnoff if (cm[*us1] != cm[*us2++]) {
893340d773SGleb Smirnoff /*
903340d773SGleb Smirnoff * We've found a mismatch.
913340d773SGleb Smirnoff */
923340d773SGleb Smirnoff break;
933340d773SGleb Smirnoff }
943340d773SGleb Smirnoff if (*us1++ == '\0') {
953340d773SGleb Smirnoff /*
963340d773SGleb Smirnoff * We've run out of characters *to* compare,
973340d773SGleb Smirnoff * and they've all been equal; return 0, to
983340d773SGleb Smirnoff * indicate that the strings are the same.
993340d773SGleb Smirnoff */
1003340d773SGleb Smirnoff return(0);
1013340d773SGleb Smirnoff }
1023340d773SGleb Smirnoff n--;
1033340d773SGleb Smirnoff }
1043340d773SGleb Smirnoff return(cm[*us1] - cm[*--us2]);
1053340d773SGleb Smirnoff }
106