diff options
Diffstat (limited to 'contrib/tcsh/tc.nls.c')
-rw-r--r-- | contrib/tcsh/tc.nls.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/contrib/tcsh/tc.nls.c b/contrib/tcsh/tc.nls.c new file mode 100644 index 0000000..7cc6e42 --- /dev/null +++ b/contrib/tcsh/tc.nls.c @@ -0,0 +1,143 @@ +/* $Header: /p/tcsh/cvsroot/tcsh/tc.nls.c,v 3.23 2010/02/12 22:17:20 christos Exp $ */ +/* + * tc.nls.c: NLS handling + */ +/*- + * Copyright (c) 1980, 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "sh.h" + +RCSID("$tcsh: tc.nls.c,v 3.23 2010/02/12 22:17:20 christos Exp $") + + +#ifdef WIDE_STRINGS +# ifdef HAVE_WCWIDTH +# ifdef UTF16_STRINGS +int +xwcwidth (wint_t wchar) +{ + wchar_t ws[2]; + + if (wchar <= 0xffff) + return wcwidth ((wchar_t) wchar); + /* UTF-16 systems can't handle these values directly in calls to wcwidth. + However, they can handle them as surrogate pairs in calls to wcswidth. + What we do here is to convert UTF-32 values >= 0x10000 into surrogate + pairs and compute the width by calling wcswidth. */ + wchar -= 0x10000; + ws[0] = 0xd800 | (wchar >> 10); + ws[1] = 0xdc00 | (wchar & 0x3ff); + return wcswidth (ws, 2); +} +# else +#define xwcwidth wcwidth +# endif /* !UTF16_STRINGS */ +# endif /* HAVE_WCWIDTH */ + +int +NLSWidth(Char c) +{ +# ifdef HAVE_WCWIDTH + int l; + if (c & INVALID_BYTE) + return 1; + l = xwcwidth((wchar_t) c); + return l >= 0 ? l : 0; +# else + return iswprint(c) != 0; +# endif +} + +int +NLSStringWidth(const Char *s) +{ + int w = 0, l; + Char c; + + while (*s) { + c = *s++; +#ifdef HAVE_WCWIDTH + if ((l = xwcwidth((wchar_t) c)) < 0) + l = 2; +#else + l = iswprint(c) != 0; +#endif + w += l; + } + return w; +} +#endif + +Char * +NLSChangeCase(const Char *p, int mode) +{ + Char c, *n, c2 = 0; + const Char *op = p; + + for (; (c = *p) != 0; p++) { + if (mode == 0 && Islower(c)) { + c2 = Toupper(c); + break; + } else if (mode && Isupper(c)) { + c2 = Tolower(c); + break; + } + } + if (!*p) + return 0; + n = Strsave(op); + n[p - op] = c2; + return n; +} + +int +NLSClassify(Char c, int nocomb) +{ + int w; + if (c & INVALID_BYTE) + return NLSCLASS_ILLEGAL; + w = NLSWidth(c); + if ((w > 0 && !(Iscntrl(c) && (c & CHAR) < 0x100)) || (Isprint(c) && !nocomb)) + return w; + if (Iscntrl(c) && (c & CHAR) < 0x100) { + if (c == '\n') + return NLSCLASS_NL; + if (c == '\t') + return NLSCLASS_TAB; + return NLSCLASS_CTRL; + } +#ifdef WIDE_STRINGS + if (c >= 0x1000000) + return NLSCLASS_ILLEGAL4; + if (c >= 0x10000) + return NLSCLASS_ILLEGAL3; +#endif + if (c >= 0x100) + return NLSCLASS_ILLEGAL2; + return NLSCLASS_ILLEGAL; +} |