]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcsh/tc.nls.c
This commit was generated by cvs2svn to compensate for changes in r162503,
[FreeBSD/FreeBSD.git] / contrib / tcsh / tc.nls.c
1 /* $Header: /src/pub/tcsh/tc.nls.c,v 3.6 2005/02/15 21:09:02 christos Exp $ */
2 /*
3  * tc.nls.c: NLS handling
4  */
5 /*-
6  * Copyright (c) 1980, 1991 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 #include "sh.h"
34
35 RCSID("$Id: tc.nls.c,v 3.6 2005/02/15 21:09:02 christos Exp $")
36
37 #ifdef SHORT_STRINGS
38 int
39 NLSWidth(c)
40     NLSChar c;
41 {
42 # ifdef HAVE_WCWIDTH
43     int l; 
44     if (c & NLS_ILLEGAL)
45         return 1;
46     l = wcwidth(c);
47     return l >= 0 ? l : 0;
48 # else
49     return c != 0;
50 # endif
51 }
52 #endif
53
54 #if defined (WIDE_STRINGS) || !defined (SHORT_STRINGS)
55 Char *
56 NLSChangeCase(Char *p, int mode)
57 {
58     Char c, *op = p, *n, c2 = 0;
59     for (; (c = *p) != 0; p++) {
60         if (mode == 0 && Islower(c)) {
61             c2 = Toupper(c);
62             break;
63         } else if (mode && Isupper(c)) {
64             c2 = Tolower(c);
65             break;
66         }
67     }
68     if (!*p)
69         return 0;
70     n = Strsave(op);
71     n[p - op] = c2;
72     return n;
73 }
74
75 int
76 NLSExtend(Char *from, int max, int num)
77 {
78     (void)from;
79     num = abs (num);
80     if (num > max)
81         num = max;
82     return num;
83 }
84 #endif
85
86 #ifdef WIDE_STRINGS
87
88 int
89 NLSStringWidth(Char *s)
90 {
91     int w = 0;
92     while (*s)
93         w += wcwidth(*s++);
94     return w;
95 }
96
97 #elif defined (SHORT_STRINGS)
98
99 int
100 NLSFrom(const Char *p, size_t l, NLSChar *cp)
101 {
102     size_t i;
103     int len;
104     wchar_t c;
105     char b[MB_LEN_MAX];
106
107     if (l == NLSZEROT) {
108         for (i = 0; i < MB_CUR_MAX && *p; i++)
109             b[i] = p[i] & CHAR;
110     } else {
111         for (i = 0; i < MB_CUR_MAX && i < l; i++)
112             b[i] = p[i] & CHAR;
113     }
114     mbtowc(0, 0, 0);
115     len = rt_mbtowc(&c, b, i);
116     if (len <= 0) {
117         if (cp)
118           *cp = *p ? *p | NLS_ILLEGAL : 0;
119         return 1;
120     }
121     if (cp) 
122         *cp = (int)c; 
123     return len;
124 }
125
126 int
127 NLSFinished(Char *p, size_t l, eChar extra)
128 {
129     size_t i, r; 
130     wchar_t c;
131     char b[MB_LEN_MAX + 1], back[MB_LEN_MAX];
132     mbstate_t state;
133     for (i = 0; i < MB_CUR_MAX && i < l; i++)
134         b[i] = p[i]; 
135     if (extra != CHAR_ERR)
136         b[i++] = extra;
137     memset(&state, 0, sizeof(state));
138     r = mbrtowc((wchar_t *)&c, b, i, (mbstate_t *)&state);
139     if (r == (size_t)-2)
140         return 0;
141     if (r == (size_t)-1 || (size_t)wctomb(back, c) != r ||
142         memcmp(b, back, r) != 0)
143         return -1;
144     return r == i ? 1 : 2;
145 }
146
147 int
148 NLSChars(Char *s)
149 {
150     int l;
151     for (l = 0; *s; l++)
152         s += NLSSize(s, -1);
153     return l;
154 }
155
156 int
157 NLSStringWidth(Char *s)
158 {
159     int w = 0;
160     NLSChar c;
161     while (*s) {
162         s += NLSFrom(s, NLSZEROT, &c);
163         w += NLSWidth(c);
164     }
165     return w;
166 }
167
168 int
169 NLSTo(Char *p, NLSChar c)
170 {
171     char b[MB_LEN_MAX];
172     int i, j;
173
174     if (c & NLS_ILLEGAL) {
175         if (p)
176             *p = c;
177         return 1;
178     }
179     i = wctomb(b, (wchar_t)c);
180     if (i == -1)
181         return 0;
182     if (p)
183         for (j = 0; j < i; j++)
184             p[j] = b[j];
185     return i;
186 }
187
188
189 int
190 NLSExtend(Char *from, int max, int num)
191 {
192     int l, n, i;
193     Char *p;
194
195     if (num == 0)
196         return 0;
197     if (num > 0) {
198         n = 0;
199         while (num > 0 && max > 0) {
200             l = NLSSize(from, max);
201             n += l;
202             from += l;
203             max -= l;
204             num--;
205         }
206         return n;
207     }
208     from -= max;
209     p = from;
210     i = max;
211     n = 0;
212     while (i > 0) {
213         l = NLSSize(p, i);
214         p += l;
215         i -= l;
216         n++;
217     }
218     if (n >= -num)
219         n += num;
220     else
221         n = 0;
222     i = max;
223     while (n > 0) {
224         l = NLSSize(from, max);
225         from += l;
226         max -= l;
227         i -= l;
228         n--;
229     }
230     return i;
231 }
232
233 void
234 NLSQuote(Char *cp)
235 {
236     int l;
237     while (*cp) {
238         l = NLSSize(cp, -1);
239         cp++;
240         while (l-- > 1)
241             *cp++ |= QUOTE;
242     }
243 }
244
245 Char *
246 NLSChangeCase(Char *p, int mode)
247 {
248     Char *n, *op = p;
249     NLSChar c, c2 = 0;
250     int l, l2;
251
252     while (*p) {
253        l = NLSFrom(p, NLSZEROT, &c);
254        if (mode == 0 && iswlower((wint_t)c)) {
255            c2 = (int)towupper((wint_t)c);
256            break;
257        } else if (mode && iswupper((wint_t)c)) {
258            c2 = (int)towlower((wint_t)c);
259            break;
260        }
261         p += l;
262     }
263     if (!*p)
264         return 0;
265     l2 = NLSTo((Char *)0, c2);
266     n = (Char *)xmalloc((size_t)((op - p + l2 + Strlen(p + l) + 1) * sizeof(Char)));
267     if (p != op)
268         memcpy(n, op, (p - op) * sizeof(Char));
269     NLSTo(n + (p - op), c2);
270     memcpy(n + (p - op + l2), p + l, (Strlen(p + l) + 1) * sizeof(Char));
271     return n;
272 }
273 #endif
274
275 int
276 NLSClassify(c, nocomb)
277     NLSChar c;
278     int nocomb;
279 {
280     int w;
281     if (c & NLS_ILLEGAL)
282         return NLSCLASS_ILLEGAL;
283     w = NLSWidth(c);
284     if (w > 0 || (Iswprint(c) && !nocomb))
285         return w;
286     if (Iswcntrl(c) && c < 0x100) {
287         if (c == '\n')
288             return NLSCLASS_NL;
289         if (c == '\t')
290             return NLSCLASS_TAB;
291 #ifndef ASCII
292         if (!Isupper(_toebcdic[_toascii[c]|0100]) && !strchr("@[\\]^_", _toebcdic[_toascii[c]|0100]))
293             return NLSCLASS_ILLEGAL;
294 #endif
295         return NLSCLASS_CTRL;
296     }
297     if (c >= 0x1000000)
298         return NLSCLASS_ILLEGAL4;
299     if (c >= 0x10000)
300         return NLSCLASS_ILLEGAL3;
301     if (c >= 0x100)
302         return NLSCLASS_ILLEGAL2;
303     return NLSCLASS_ILLEGAL;
304 }