1 /* Functions for multi-byte support.
2 Created for gawk multi-byte extension May, 1993 by t^2 (Takahiro Tanimoto)
3 Last change: May 21, 1997 by K.Okabe */
4 #include "awk.h"
5
6 int
7 #ifdef __STDC__
mbstrncasecmp(const char * s1,const char * s2,size_t n)8 mbstrncasecmp(const char *s1, const char *s2, size_t n)
9 #else
10 mbstrncasecmp(s1, s2, n)
11 const char *s1, *s2;
12 size_t n;
13 #endif
14 {
15 int c1;
16
17 while (n--) {
18 if ((c1 = (unsigned char)*s1++) == 0)
19 return -(unsigned char)*s2;
20 if (!ismbchar(c1)) {
21 if ((c1 = ((unsigned char)casetable[c1]
22 - (unsigned char)casetable[(unsigned char)*s2++])) != 0)
23 return c1;
24 }
25 else {
26 size_t len = mbclen(c1) - 1;
27
28 if ((c1 -= (unsigned char)*s2++) != 0)
29 return c1;
30
31 while (len--) {
32 if (!n--)
33 return 0;
34 if ((c1 = (unsigned char)*s1++) == 0)
35 return -(unsigned char)*s2;
36 if ((c1 -= (unsigned char)*s2++) != 0)
37 return c1;
38 }
39 }
40 }
41 return 0;
42 }
43
44 int
45 #ifdef __STDC__
mbmemcmp(const void * p1,size_t n1,const void * p2,size_t n2)46 mbmemcmp(const void *p1, size_t n1, const void *p2, size_t n2)
47 #else
48 mbmemcmp(p1, n1, p2, n2)
49 const void *p1, *p2;
50 size_t n1, n2;
51 #endif
52 {
53 const unsigned char *s1 = p1, *s2 = p2;
54 unsigned char c1;
55 size_t n;
56
57 for (;;) {
58 if (!n1--)
59 return n2 ? -1 : 0;
60 if (!n2--)
61 return 1;
62 if ((c1 = *s1++) != *s2++) {
63 s2--;
64 return ismbchar(c1) ? (ismbchar(*s2) ? (int)c1 - *s2 : 1):
65 (ismbchar(*s2) ? -1 : (int)c1 - *s2);
66 }
67
68 if (!ismbchar(c1))
69 continue;
70 for (n = mbclen(c1) - 1; n > 0; n--) {
71 if (!n1--)
72 return n2 ? -1 : 0;
73 if (!n2--)
74 return 1;
75 if (*s1++ != *s2++)
76 return (int)*--s1 - *--s2;
77 }
78 }
79 }
80
81 size_t
82 #ifdef __STDC__
mblength(const char * s,size_t len)83 mblength(const char *s, size_t len)
84 #else
85 mblength(s, len)
86 const char *s;
87 size_t len;
88 #endif
89 {
90 const char *send;
91
92 send = s + len;
93 len = 0;
94 while ((s += mbclen(*s)) <= send)
95 len++;
96 return len;
97 }
98
99 size_t
100 #ifdef __STDC__
mbbyte(const char * s,size_t len)101 mbbyte(const char *s, size_t len)
102 #else
103 mbbyte(s, len)
104 const char *s;
105 size_t len;
106 #endif
107 {
108 const char *s0, *s1;
109
110 if (current_mbctype == MBCTYPE_UTF8) {
111 if (len == 0)
112 return 0;
113
114 s0 = s;
115 s1 = s + len;
116 s = s1 - 1;
117 while (s > s0 && ! ismbchar (*s) && ! ((unsigned char) *s < 0x80))
118 s--;
119 return (s + mbclen(*s) == s1) ? len : s - s0 ;
120 } else {
121 s0 = s;
122 s1 = s + len;
123 for (s = s1; s-- > s0 && ismbchar (*s);)
124 ;
125 if (! ((s1 - s) & 1))
126 len--;
127 return len;
128 }
129 }
130