1 /* $Header: /p/tcsh/cvsroot/tcsh/tc.nls.c,v 3.21 2006/09/26 16:45:30 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("$tcsh: tc.nls.c,v 3.21 2006/09/26 16:45:30 christos Exp $") 36 37 #ifdef WIDE_STRINGS 38 int 39 NLSWidth(Char c) 40 { 41 # ifdef HAVE_WCWIDTH 42 int l; 43 if (c & INVALID_BYTE) 44 return 1; 45 l = wcwidth(c); 46 return l >= 0 ? l : 0; 47 # else 48 return iswprint(c) != 0; 49 # endif 50 } 51 52 int 53 NLSStringWidth(const Char *s) 54 { 55 int w = 0, l; 56 Char c; 57 58 while (*s) { 59 c = *s++; 60 #ifdef HAVE_WCWIDTH 61 if ((l = wcwidth(c)) < 0) 62 l = 2; 63 #else 64 l = iswprint(c) != 0; 65 #endif 66 w += l; 67 } 68 return w; 69 } 70 #endif 71 72 Char * 73 NLSChangeCase(const Char *p, int mode) 74 { 75 Char c, *n, c2 = 0; 76 const Char *op = p; 77 78 for (; (c = *p) != 0; p++) { 79 if (mode == 0 && Islower(c)) { 80 c2 = Toupper(c); 81 break; 82 } else if (mode && Isupper(c)) { 83 c2 = Tolower(c); 84 break; 85 } 86 } 87 if (!*p) 88 return 0; 89 n = Strsave(op); 90 n[p - op] = c2; 91 return n; 92 } 93 94 int 95 NLSClassify(Char c, int nocomb) 96 { 97 int w; 98 if (c & INVALID_BYTE) 99 return NLSCLASS_ILLEGAL; 100 w = NLSWidth(c); 101 if ((w > 0 && !(Iscntrl(c) && (c & CHAR) < 0x100)) || (Isprint(c) && !nocomb)) 102 return w; 103 if (Iscntrl(c) && (c & CHAR) < 0x100) { 104 if (c == '\n') 105 return NLSCLASS_NL; 106 if (c == '\t') 107 return NLSCLASS_TAB; 108 return NLSCLASS_CTRL; 109 } 110 #ifdef WIDE_STRINGS 111 if (c >= 0x1000000) 112 return NLSCLASS_ILLEGAL4; 113 if (c >= 0x10000) 114 return NLSCLASS_ILLEGAL3; 115 #endif 116 if (c >= 0x100) 117 return NLSCLASS_ILLEGAL2; 118 return NLSCLASS_ILLEGAL; 119 } 120