1 /* $Header: /src/pub/tcsh/tc.nls.c,v 3.6 2005/02/15 21:09:02 christos Exp $ */
3 * tc.nls.c: NLS handling
6 * Copyright (c) 1980, 1991 The Regents of the University of California.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
35 RCSID("$Id: tc.nls.c,v 3.6 2005/02/15 21:09:02 christos Exp $")
47 return l >= 0 ? l : 0;
54 #if defined (WIDE_STRINGS) || !defined (SHORT_STRINGS)
56 NLSChangeCase(Char *p, int mode)
58 Char c, *op = p, *n, c2 = 0;
59 for (; (c = *p) != 0; p++) {
60 if (mode == 0 && Islower(c)) {
63 } else if (mode && Isupper(c)) {
76 NLSExtend(Char *from, int max, int num)
89 NLSStringWidth(Char *s)
97 #elif defined (SHORT_STRINGS)
100 NLSFrom(const Char *p, size_t l, NLSChar *cp)
108 for (i = 0; i < MB_CUR_MAX && *p; i++)
111 for (i = 0; i < MB_CUR_MAX && i < l; i++)
115 len = rt_mbtowc(&c, b, i);
118 *cp = *p ? *p | NLS_ILLEGAL : 0;
127 NLSFinished(Char *p, size_t l, eChar extra)
131 char b[MB_LEN_MAX + 1], back[MB_LEN_MAX];
133 for (i = 0; i < MB_CUR_MAX && i < l; i++)
135 if (extra != CHAR_ERR)
137 memset(&state, 0, sizeof(state));
138 r = mbrtowc((wchar_t *)&c, b, i, (mbstate_t *)&state);
141 if (r == (size_t)-1 || (size_t)wctomb(back, c) != r ||
142 memcmp(b, back, r) != 0)
144 return r == i ? 1 : 2;
157 NLSStringWidth(Char *s)
162 s += NLSFrom(s, NLSZEROT, &c);
169 NLSTo(Char *p, NLSChar c)
174 if (c & NLS_ILLEGAL) {
179 i = wctomb(b, (wchar_t)c);
183 for (j = 0; j < i; j++)
190 NLSExtend(Char *from, int max, int num)
199 while (num > 0 && max > 0) {
200 l = NLSSize(from, max);
224 l = NLSSize(from, max);
246 NLSChangeCase(Char *p, int mode)
253 l = NLSFrom(p, NLSZEROT, &c);
254 if (mode == 0 && iswlower((wint_t)c)) {
255 c2 = (int)towupper((wint_t)c);
257 } else if (mode && iswupper((wint_t)c)) {
258 c2 = (int)towlower((wint_t)c);
265 l2 = NLSTo((Char *)0, c2);
266 n = (Char *)xmalloc((size_t)((op - p + l2 + Strlen(p + l) + 1) * sizeof(Char)));
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));
276 NLSClassify(c, nocomb)
282 return NLSCLASS_ILLEGAL;
284 if (w > 0 || (Iswprint(c) && !nocomb))
286 if (Iswcntrl(c) && c < 0x100) {
292 if (!Isupper(_toebcdic[_toascii[c]|0100]) && !strchr("@[\\]^_", _toebcdic[_toascii[c]|0100]))
293 return NLSCLASS_ILLEGAL;
295 return NLSCLASS_CTRL;
298 return NLSCLASS_ILLEGAL4;
300 return NLSCLASS_ILLEGAL3;
302 return NLSCLASS_ILLEGAL2;
303 return NLSCLASS_ILLEGAL;