xref: /netbsd-src/external/bsd/tcpdump/dist/ascii_strcasecmp.c (revision c74ad2514f801c840bd3203347d1246afccaa98b)
1784088dfSchristos /*
2784088dfSchristos  * Copyright (c) 1987 Regents of the University of California.
3784088dfSchristos  * All rights reserved.
4784088dfSchristos  *
5784088dfSchristos  * Redistribution and use in source and binary forms are permitted
6784088dfSchristos  * provided that this notice is preserved and that due credit is given
7784088dfSchristos  * to the University of California at Berkeley. The name of the University
8784088dfSchristos  * may not be used to endorse or promote products derived from this
9784088dfSchristos  * software without specific written prior permission. This software
10784088dfSchristos  * is provided ``as is'' without express or implied warranty.
11784088dfSchristos  */
12784088dfSchristos 
13fdccd7e4Schristos #include <sys/cdefs.h>
14fdccd7e4Schristos #ifndef lint
15*c74ad251Schristos __RCSID("$NetBSD: ascii_strcasecmp.c,v 1.3 2023/08/17 20:19:39 christos Exp $");
16fdccd7e4Schristos #endif
17fdccd7e4Schristos 
18784088dfSchristos #include "ascii_strcasecmp.h"
19784088dfSchristos 
20784088dfSchristos /*
21784088dfSchristos  * This array maps upper-case ASCII letters to their lower-case
22784088dfSchristos  * equivalents; all other byte values are mapped to themselves,
23784088dfSchristos  * so this is locale-independent and intended to be locale-independent,
24784088dfSchristos  * to avoid issues with, for example, "i" and "I" not being lower-case
25784088dfSchristos  * and upper-case versions of the same letter in Turkish, where
26784088dfSchristos  * there are separate "i with dot" and "i without dot" letters.
27784088dfSchristos  */
28784088dfSchristos static const unsigned char charmap[] = {
29784088dfSchristos 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
30784088dfSchristos 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
31784088dfSchristos 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
32784088dfSchristos 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
33784088dfSchristos 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
34784088dfSchristos 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
35784088dfSchristos 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
36784088dfSchristos 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
37784088dfSchristos 	0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
38784088dfSchristos 	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
39784088dfSchristos 	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
40784088dfSchristos 	0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
41784088dfSchristos 	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
42784088dfSchristos 	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
43784088dfSchristos 	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
44784088dfSchristos 	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
45784088dfSchristos 	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
46784088dfSchristos 	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
47784088dfSchristos 	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
48784088dfSchristos 	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
49784088dfSchristos 	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
50784088dfSchristos 	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
51784088dfSchristos 	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
52784088dfSchristos 	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
53784088dfSchristos 	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
54784088dfSchristos 	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
55784088dfSchristos 	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
56784088dfSchristos 	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
57784088dfSchristos 	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
58784088dfSchristos 	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
59784088dfSchristos 	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
60784088dfSchristos 	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
61784088dfSchristos };
62784088dfSchristos 
63784088dfSchristos int
ascii_strcasecmp(const char * s1,const char * s2)64784088dfSchristos ascii_strcasecmp(const char *s1, const char *s2)
65784088dfSchristos {
66*c74ad251Schristos 	const unsigned char *cm = charmap,
67784088dfSchristos 			*us1 = (const unsigned char *)s1,
68784088dfSchristos 			*us2 = (const unsigned char *)s2;
69784088dfSchristos 
70784088dfSchristos 	while (cm[*us1] == cm[*us2++])
71784088dfSchristos 		if (*us1++ == '\0')
72784088dfSchristos 			return(0);
73784088dfSchristos 	return(cm[*us1] - cm[*--us2]);
74784088dfSchristos }
75784088dfSchristos 
76784088dfSchristos int
ascii_strncasecmp(const char * s1,const char * s2,size_t n)77*c74ad251Schristos ascii_strncasecmp(const char *s1, const char *s2, size_t n)
78784088dfSchristos {
79*c74ad251Schristos 	const unsigned char *cm = charmap,
80784088dfSchristos 			*us1 = (const unsigned char *)s1,
81784088dfSchristos 			*us2 = (const unsigned char *)s2;
82784088dfSchristos 
83784088dfSchristos 	for (;;) {
84784088dfSchristos 		if (n == 0) {
85784088dfSchristos 			/*
86784088dfSchristos 			 * We've run out of characters that we should
87784088dfSchristos 			 * compare, and they've all been equal; return
88784088dfSchristos 			 * 0, to indicate that the prefixes are the
89784088dfSchristos 			 * same.
90784088dfSchristos 			 */
91784088dfSchristos 			return(0);
92784088dfSchristos 		}
93784088dfSchristos 		if (cm[*us1] != cm[*us2++]) {
94784088dfSchristos 			/*
95784088dfSchristos 			 * We've found a mismatch.
96784088dfSchristos 			 */
97784088dfSchristos 			break;
98784088dfSchristos 		}
99784088dfSchristos 		if (*us1++ == '\0') {
100784088dfSchristos 			/*
101784088dfSchristos 			 * We've run out of characters *to* compare,
102784088dfSchristos 			 * and they've all been equal; return 0, to
103784088dfSchristos 			 * indicate that the strings are the same.
104784088dfSchristos 			 */
105784088dfSchristos 			return(0);
106784088dfSchristos 		}
107784088dfSchristos 		n--;
108784088dfSchristos 	}
109784088dfSchristos 	return(cm[*us1] - cm[*--us2]);
110784088dfSchristos }
111