sh.set.c revision 195609
1195609Smp/* $Header: /p/tcsh/cvsroot/tcsh/sh.set.c,v 3.72 2007/09/28 21:02:03 christos Exp $ */ 259243Sobrien/* 359243Sobrien * sh.set.c: Setting and Clearing of variables 459243Sobrien */ 559243Sobrien/*- 659243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California. 759243Sobrien * All rights reserved. 859243Sobrien * 959243Sobrien * Redistribution and use in source and binary forms, with or without 1059243Sobrien * modification, are permitted provided that the following conditions 1159243Sobrien * are met: 1259243Sobrien * 1. Redistributions of source code must retain the above copyright 1359243Sobrien * notice, this list of conditions and the following disclaimer. 1459243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1559243Sobrien * notice, this list of conditions and the following disclaimer in the 1659243Sobrien * documentation and/or other materials provided with the distribution. 17100616Smp * 3. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien#include "sh.h" 3459243Sobrien 35195609SmpRCSID("$tcsh: sh.set.c,v 3.72 2007/09/28 21:02:03 christos Exp $") 3659243Sobrien 3759243Sobrien#include "ed.h" 3859243Sobrien#include "tw.h" 3959243Sobrien 40145479Smp#ifdef HAVE_NL_LANGINFO 41145479Smp#include <langinfo.h> 42145479Smp#endif 43145479Smp 44145479Smpextern int GotTermCaps; 45131962Smpint numeof = 0; 4659243Sobrien 47167465Smpstatic void update_vars (Char *); 48167465Smpstatic Char *getinx (Char *, int *); 49167465Smpstatic void asx (Char *, int, Char *); 50167465Smpstatic struct varent *getvx (Char *, int); 51167465Smpstatic Char *xset (Char *, Char ***); 52167465Smpstatic Char *operate (int, Char *, Char *); 53167465Smpstatic void putn1 (unsigned); 54167465Smpstatic struct varent *madrof (Char *, struct varent *); 55167465Smpstatic void unsetv1 (struct varent *); 56167465Smpstatic void exportpath (Char **); 57167465Smpstatic void balance (struct varent *, int, int); 5859243Sobrien 5959243Sobrien/* 6059243Sobrien * C Shell 6159243Sobrien */ 6259243Sobrien 6359243Sobrienstatic void 64167465Smpupdate_vars(Char *vp) 6559243Sobrien{ 6659243Sobrien if (eq(vp, STRpath)) { 67167465Smp struct varent *p = adrof(STRpath); 68167465Smp if (p == NULL) 69167465Smp stderror(ERR_NAME | ERR_UNDVAR); 70167465Smp else { 71167465Smp exportpath(p->vec); 72167465Smp dohash(NULL, NULL); 73167465Smp } 7459243Sobrien } 7559243Sobrien else if (eq(vp, STRhistchars)) { 76145479Smp Char *pn = varval(vp); 7759243Sobrien 7859243Sobrien HIST = *pn++; 7959243Sobrien HISTSUB = *pn; 8059243Sobrien } 8159243Sobrien else if (eq(vp, STRpromptchars)) { 82145479Smp Char *pn = varval(vp); 8359243Sobrien 8459243Sobrien PRCH = *pn++; 8559243Sobrien PRCHROOT = *pn; 8659243Sobrien } 8759243Sobrien else if (eq(vp, STRhistlit)) { 8859243Sobrien HistLit = 1; 8959243Sobrien } 9059243Sobrien else if (eq(vp, STRuser)) { 9159243Sobrien tsetenv(STRKUSER, varval(vp)); 9259243Sobrien tsetenv(STRLOGNAME, varval(vp)); 9359243Sobrien } 9459243Sobrien else if (eq(vp, STRgroup)) { 9559243Sobrien tsetenv(STRKGROUP, varval(vp)); 9659243Sobrien } 9759243Sobrien else if (eq(vp, STRwordchars)) { 9859243Sobrien word_chars = varval(vp); 9959243Sobrien } 10059243Sobrien else if (eq(vp, STRloginsh)) { 10159243Sobrien loginsh = 1; 10259243Sobrien } 10359243Sobrien else if (eq(vp, STRsymlinks)) { 104145479Smp Char *pn = varval(vp); 10559243Sobrien 10659243Sobrien if (eq(pn, STRignore)) 10759243Sobrien symlinks = SYM_IGNORE; 10859243Sobrien else if (eq(pn, STRexpand)) 10959243Sobrien symlinks = SYM_EXPAND; 11059243Sobrien else if (eq(pn, STRchase)) 11159243Sobrien symlinks = SYM_CHASE; 11259243Sobrien else 11359243Sobrien symlinks = 0; 11459243Sobrien } 11559243Sobrien else if (eq(vp, STRterm)) { 11659243Sobrien Char *cp = varval(vp); 11759243Sobrien tsetenv(STRKTERM, cp); 11859243Sobrien#ifdef DOESNT_WORK_RIGHT 11959243Sobrien cp = getenv("TERMCAP"); 12059243Sobrien if (cp && (*cp != '/')) /* if TERMCAP and not a path */ 12159243Sobrien Unsetenv(STRTERMCAP); 12259243Sobrien#endif /* DOESNT_WORK_RIGHT */ 12359243Sobrien GotTermCaps = 0; 12459243Sobrien if (noediting && Strcmp(cp, STRnetwork) != 0 && 12559243Sobrien Strcmp(cp, STRunknown) != 0 && Strcmp(cp, STRdumb) != 0) { 12659243Sobrien editing = 1; 12759243Sobrien noediting = 0; 128167465Smp setNS(STRedit); 12959243Sobrien } 13059243Sobrien ed_Init(); /* reset the editor */ 13159243Sobrien } 13259243Sobrien else if (eq(vp, STRhome)) { 133167465Smp Char *cp, *canon; 13459243Sobrien 13559243Sobrien cp = Strsave(varval(vp)); /* get the old value back */ 136167465Smp cleanup_push(cp, xfree); 13759243Sobrien 13859243Sobrien /* 13959243Sobrien * convert to cononical pathname (possibly resolving symlinks) 14059243Sobrien */ 141167465Smp canon = dcanon(cp, cp); 142167465Smp cleanup_ignore(cp); 143167465Smp cleanup_until(cp); 144167465Smp cleanup_push(canon, xfree); 14559243Sobrien 146167465Smp setcopy(vp, canon, VAR_READWRITE); /* have to save the new val */ 14759243Sobrien 14859243Sobrien /* and now mirror home with HOME */ 149167465Smp tsetenv(STRKHOME, canon); 15059243Sobrien /* fix directory stack for new tilde home */ 15159243Sobrien dtilde(); 152167465Smp cleanup_until(canon); 15359243Sobrien } 15459243Sobrien else if (eq(vp, STRedit)) { 15559243Sobrien editing = 1; 15659243Sobrien noediting = 0; 15759243Sobrien /* PWP: add more stuff in here later */ 15859243Sobrien } 15959243Sobrien else if (eq(vp, STRshlvl)) { 16059243Sobrien tsetenv(STRKSHLVL, varval(vp)); 16159243Sobrien } 162131962Smp else if (eq(vp, STRignoreeof)) { 163131962Smp Char *cp; 164131962Smp numeof = 0; 165131962Smp for ((cp = varval(STRignoreeof)); cp && *cp; cp++) { 166131962Smp if (!Isdigit(*cp)) { 167131962Smp numeof = 0; 168131962Smp break; 169131962Smp } 170131962Smp numeof = numeof * 10 + *cp - '0'; 171131962Smp } 172131962Smp if (numeof <= 0) numeof = 26; /* Sanity check */ 173131962Smp } 17459243Sobrien else if (eq(vp, STRbackslash_quote)) { 17559243Sobrien bslash_quote = 1; 17659243Sobrien } 177195609Smp else if (eq(vp, STRcompat_expr)) { 178195609Smp compat_expr = 1; 179195609Smp } 18059243Sobrien else if (eq(vp, STRdirstack)) { 18159243Sobrien dsetstack(); 18259243Sobrien } 18359243Sobrien else if (eq(vp, STRrecognize_only_executables)) { 18459243Sobrien tw_cmd_free(); 18559243Sobrien } 18683098Smp else if (eq(vp, STRkillring)) { 18783098Smp SetKillRing(getn(varval(vp))); 18883098Smp } 18959243Sobrien#ifndef HAVENOUTMP 19059243Sobrien else if (eq(vp, STRwatch)) { 19159243Sobrien resetwatch(); 19259243Sobrien } 19359243Sobrien#endif /* HAVENOUTMP */ 19459243Sobrien else if (eq(vp, STRimplicitcd)) { 19559243Sobrien implicit_cd = ((eq(varval(vp), STRverbose)) ? 2 : 1); 19659243Sobrien } 19759243Sobrien#ifdef COLOR_LS_F 19859243Sobrien else if (eq(vp, STRcolor)) { 19959243Sobrien set_color_context(); 20059243Sobrien } 20159243Sobrien#endif /* COLOR_LS_F */ 20259243Sobrien#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 20359243Sobrien else if(eq(vp, CHECK_MBYTEVAR) || eq(vp, STRnokanji)) { 20459243Sobrien update_dspmbyte_vars(); 20559243Sobrien } 20659243Sobrien#endif 20769408Sache#ifdef NLS_CATALOGS 20869408Sache else if (eq(vp, STRcatalog)) { 209145479Smp nlsclose(); 21069408Sache nlsinit(); 21169408Sache } 212100616Smp#if defined(FILEC) && defined(TIOCSTI) 213100616Smp else if (eq(vp, STRfilec)) 214100616Smp filec = 1; 215100616Smp#endif 21669408Sache#endif /* NLS_CATALOGS */ 21759243Sobrien} 21859243Sobrien 21959243Sobrien 22059243Sobrien/*ARGSUSED*/ 22159243Sobrienvoid 222167465Smpdoset(Char **v, struct command *c) 22359243Sobrien{ 224145479Smp Char *p; 22559243Sobrien Char *vp, op; 22659243Sobrien Char **vecp; 227145479Smp int hadsub; 22859243Sobrien int subscr; 22959243Sobrien int flags = VAR_READWRITE; 230145479Smp int first_match = 0; 231145479Smp int last_match = 0; 232145479Smp int changed = 0; 23359243Sobrien 23459243Sobrien USE(c); 23559243Sobrien v++; 23659243Sobrien do { 23759243Sobrien changed = 0; 23859243Sobrien /* 23959243Sobrien * Readonly addition From: Tim P. Starrin <noid@cyborg.larc.nasa.gov> 24059243Sobrien */ 24159243Sobrien if (*v && eq(*v, STRmr)) { 24259243Sobrien flags = VAR_READONLY; 24359243Sobrien v++; 24459243Sobrien changed = 1; 24559243Sobrien } 24659243Sobrien if (*v && eq(*v, STRmf) && !last_match) { 24759243Sobrien first_match = 1; 24859243Sobrien v++; 24959243Sobrien changed = 1; 25059243Sobrien } 25159243Sobrien if (*v && eq(*v, STRml) && !first_match) { 25259243Sobrien last_match = 1; 25359243Sobrien v++; 25459243Sobrien changed = 1; 25559243Sobrien } 25659243Sobrien } while(changed); 25759243Sobrien p = *v++; 25859243Sobrien if (p == 0) { 25959243Sobrien plist(&shvhed, flags); 26059243Sobrien return; 26159243Sobrien } 26259243Sobrien do { 26359243Sobrien hadsub = 0; 26459243Sobrien vp = p; 26559243Sobrien if (letter(*p)) 26659243Sobrien for (; alnum(*p); p++) 26759243Sobrien continue; 26859243Sobrien if (vp == p || !letter(*vp)) 26959243Sobrien stderror(ERR_NAME | ERR_VARBEGIN); 27059243Sobrien if (*p == '[') { 27159243Sobrien hadsub++; 27259243Sobrien p = getinx(p, &subscr); 27359243Sobrien } 27459243Sobrien if ((op = *p) != 0) { 27559243Sobrien *p++ = 0; 27659243Sobrien if (*p == 0 && *v && **v == '(') 27759243Sobrien p = *v++; 27859243Sobrien } 27959243Sobrien else if (*v && eq(*v, STRequal)) { 28059243Sobrien op = '=', v++; 28159243Sobrien if (*v) 28259243Sobrien p = *v++; 28359243Sobrien } 28459243Sobrien if (op && op != '=') 28559243Sobrien stderror(ERR_NAME | ERR_SYNTAX); 28659243Sobrien if (eq(p, STRLparen)) { 287145479Smp Char **e = v; 28859243Sobrien 28959243Sobrien if (hadsub) 29059243Sobrien stderror(ERR_NAME | ERR_SYNTAX); 29159243Sobrien for (;;) { 29259243Sobrien if (!*e) 29359243Sobrien stderror(ERR_NAME | ERR_MISSING, ')'); 29459243Sobrien if (**e == ')') 29559243Sobrien break; 29659243Sobrien e++; 29759243Sobrien } 29859243Sobrien p = *e; 29959243Sobrien *e = 0; 30059243Sobrien vecp = saveblk(v); 30159243Sobrien if (first_match) 30259243Sobrien flags |= VAR_FIRST; 30359243Sobrien else if (last_match) 30459243Sobrien flags |= VAR_LAST; 30559243Sobrien 30659243Sobrien set1(vp, vecp, &shvhed, flags); 30759243Sobrien *e = p; 30859243Sobrien v = e + 1; 30959243Sobrien } 310167465Smp else if (hadsub) { 311167465Smp Char *copy; 312167465Smp 313167465Smp copy = Strsave(p); 314167465Smp cleanup_push(copy, xfree); 315167465Smp asx(vp, subscr, copy); 316167465Smp cleanup_ignore(copy); 317167465Smp cleanup_until(copy); 318167465Smp } 31959243Sobrien else 320167465Smp setv(vp, Strsave(p), flags); 32159243Sobrien update_vars(vp); 32259243Sobrien } while ((p = *v++) != NULL); 32359243Sobrien} 32459243Sobrien 32559243Sobrienstatic Char * 326167465Smpgetinx(Char *cp, int *ip) 32759243Sobrien{ 32859243Sobrien *ip = 0; 32959243Sobrien *cp++ = 0; 33059243Sobrien while (*cp && Isdigit(*cp)) 33159243Sobrien *ip = *ip * 10 + *cp++ - '0'; 33259243Sobrien if (*cp++ != ']') 33359243Sobrien stderror(ERR_NAME | ERR_SUBSCRIPT); 33459243Sobrien return (cp); 33559243Sobrien} 33659243Sobrien 33759243Sobrienstatic void 338167465Smpasx(Char *vp, int subscr, Char *p) 33959243Sobrien{ 340145479Smp struct varent *v = getvx(vp, subscr); 341167465Smp Char *prev; 34259243Sobrien 34359243Sobrien if (v->v_flags & VAR_READONLY) 34459243Sobrien stderror(ERR_READONLY|ERR_NAME, v->v_name); 345167465Smp prev = v->vec[subscr - 1]; 346167465Smp cleanup_push(prev, xfree); 34759243Sobrien v->vec[subscr - 1] = globone(p, G_APPEND); 348167465Smp cleanup_until(prev); 34959243Sobrien} 35059243Sobrien 35159243Sobrienstatic struct varent * 352167465Smpgetvx(Char *vp, int subscr) 35359243Sobrien{ 354145479Smp struct varent *v = adrof(vp); 35559243Sobrien 35659243Sobrien if (v == 0) 35759243Sobrien udvar(vp); 35859243Sobrien if (subscr < 1 || subscr > blklen(v->vec)) 35959243Sobrien stderror(ERR_NAME | ERR_RANGE); 36059243Sobrien return (v); 36159243Sobrien} 36259243Sobrien 36359243Sobrien/*ARGSUSED*/ 36459243Sobrienvoid 365167465Smpdolet(Char **v, struct command *dummy) 36659243Sobrien{ 367145479Smp Char *p; 36859243Sobrien Char *vp, c, op; 369145479Smp int hadsub; 37059243Sobrien int subscr; 37159243Sobrien 37259243Sobrien USE(dummy); 37359243Sobrien v++; 37459243Sobrien p = *v++; 37559243Sobrien if (p == 0) { 37659243Sobrien prvars(); 37759243Sobrien return; 37859243Sobrien } 37959243Sobrien do { 38059243Sobrien hadsub = 0; 38159243Sobrien vp = p; 38259243Sobrien if (letter(*p)) 38359243Sobrien for (; alnum(*p); p++) 38459243Sobrien continue; 38559243Sobrien if (vp == p || !letter(*vp)) 38659243Sobrien stderror(ERR_NAME | ERR_VARBEGIN); 38759243Sobrien if (*p == '[') { 38859243Sobrien hadsub++; 38959243Sobrien p = getinx(p, &subscr); 39059243Sobrien } 39159243Sobrien if (*p == 0 && *v) 39259243Sobrien p = *v++; 39359243Sobrien if ((op = *p) != 0) 39459243Sobrien *p++ = 0; 39559243Sobrien else 39659243Sobrien stderror(ERR_NAME | ERR_ASSIGN); 39759243Sobrien 39859243Sobrien /* 39959243Sobrien * if there is no expression after the '=' then print a "Syntax Error" 40059243Sobrien * message - strike 40159243Sobrien */ 40259243Sobrien if (*p == '\0' && *v == NULL) 40359243Sobrien stderror(ERR_NAME | ERR_ASSIGN); 40459243Sobrien 40559243Sobrien vp = Strsave(vp); 406167465Smp cleanup_push(vp, xfree); 40759243Sobrien if (op == '=') { 40859243Sobrien c = '='; 40959243Sobrien p = xset(p, &v); 41059243Sobrien } 41159243Sobrien else { 41259243Sobrien c = *p++; 41359243Sobrien if (any("+-", c)) { 41459243Sobrien if (c != op || *p) 41559243Sobrien stderror(ERR_NAME | ERR_UNKNOWNOP); 41659243Sobrien p = Strsave(STR1); 41759243Sobrien } 41859243Sobrien else { 41959243Sobrien if (any("<>", op)) { 42059243Sobrien if (c != op) 42159243Sobrien stderror(ERR_NAME | ERR_UNKNOWNOP); 42259243Sobrien stderror(ERR_NAME | ERR_SYNTAX); 42359243Sobrien } 42459243Sobrien if (c != '=') 42559243Sobrien stderror(ERR_NAME | ERR_UNKNOWNOP); 42659243Sobrien p = xset(p, &v); 42759243Sobrien } 42859243Sobrien } 429167465Smp cleanup_push(p, xfree); 43059243Sobrien if (op == '=') { 43159243Sobrien if (hadsub) 43259243Sobrien asx(vp, subscr, p); 43359243Sobrien else 434167465Smp setv(vp, p, VAR_READWRITE); 435167465Smp cleanup_ignore(p); 43659243Sobrien } 43759243Sobrien else if (hadsub) { 43859243Sobrien struct varent *gv = getvx(vp, subscr); 439167465Smp Char *val; 44059243Sobrien 441167465Smp val = operate(op, gv->vec[subscr - 1], p); 442167465Smp cleanup_push(val, xfree); 443167465Smp asx(vp, subscr, val); 444167465Smp cleanup_ignore(val); 445167465Smp cleanup_until(val); 44659243Sobrien } 447167465Smp else { 448167465Smp Char *val; 449167465Smp 450167465Smp val = operate(op, varval(vp), p); 451167465Smp cleanup_push(val, xfree); 452167465Smp setv(vp, val, VAR_READWRITE); 453167465Smp cleanup_ignore(val); 454167465Smp cleanup_until(val); 455167465Smp } 45659243Sobrien update_vars(vp); 457167465Smp cleanup_until(vp); 45859243Sobrien } while ((p = *v++) != NULL); 45959243Sobrien} 46059243Sobrien 46159243Sobrienstatic Char * 462167465Smpxset(Char *cp, Char ***vp) 46359243Sobrien{ 464145479Smp Char *dp; 46559243Sobrien 46659243Sobrien if (*cp) { 46759243Sobrien dp = Strsave(cp); 46859243Sobrien --(*vp); 469167465Smp xfree(** vp); 47059243Sobrien **vp = dp; 47159243Sobrien } 47259243Sobrien return (putn(expr(vp))); 47359243Sobrien} 47459243Sobrien 47559243Sobrienstatic Char * 476167465Smpoperate(int op, Char *vp, Char *p) 47759243Sobrien{ 47859243Sobrien Char opr[2]; 47959243Sobrien Char *vec[5]; 480145479Smp Char **v = vec; 48159243Sobrien Char **vecp = v; 482145479Smp int i; 48359243Sobrien 48459243Sobrien if (op != '=') { 48559243Sobrien if (*vp) 48659243Sobrien *v++ = vp; 487167465Smp opr[0] = op; 48859243Sobrien opr[1] = 0; 48959243Sobrien *v++ = opr; 49059243Sobrien if (op == '<' || op == '>') 49159243Sobrien *v++ = opr; 49259243Sobrien } 49359243Sobrien *v++ = p; 49459243Sobrien *v++ = 0; 49559243Sobrien i = expr(&vecp); 49659243Sobrien if (*vecp) 49759243Sobrien stderror(ERR_NAME | ERR_EXPRESSION); 49859243Sobrien return (putn(i)); 49959243Sobrien} 50059243Sobrien 501167465Smpstatic Char *putp; 50259243Sobrien 50359243SobrienChar * 504167465Smpputn(int n) 50559243Sobrien{ 506167465Smp Char nbuf[(CHAR_BIT * sizeof (n) + 2) / 3 + 2]; /* Enough even for octal */ 50759243Sobrien 50859243Sobrien putp = nbuf; 50959243Sobrien if (n < 0) { 51059243Sobrien n = -n; 51159243Sobrien *putp++ = '-'; 51259243Sobrien } 51359243Sobrien putn1(n); 51459243Sobrien *putp = 0; 51559243Sobrien return (Strsave(nbuf)); 51659243Sobrien} 51759243Sobrien 51859243Sobrienstatic void 519167465Smpputn1(unsigned n) 52059243Sobrien{ 52159243Sobrien if (n > 9) 52259243Sobrien putn1(n / 10); 52359243Sobrien *putp++ = n % 10 + '0'; 52459243Sobrien} 52559243Sobrien 52659243Sobrienint 527167465Smpgetn(Char *cp) 52859243Sobrien{ 529145479Smp int n; 53059243Sobrien int sign; 531195609Smp int base; 53259243Sobrien 53359243Sobrien if (!cp) /* PWP: extra error checking */ 53459243Sobrien stderror(ERR_NAME | ERR_BADNUM); 53559243Sobrien 53659243Sobrien sign = 0; 53759243Sobrien if (cp[0] == '+' && cp[1]) 53859243Sobrien cp++; 53959243Sobrien if (*cp == '-') { 54059243Sobrien sign++; 54159243Sobrien cp++; 54259243Sobrien if (!Isdigit(*cp)) 54359243Sobrien stderror(ERR_NAME | ERR_BADNUM); 54459243Sobrien } 545195609Smp 546195609Smp if (cp[0] == '0' && cp[1]) 547195609Smp base = 8; 548195609Smp else 549195609Smp base = 10; 550195609Smp 55159243Sobrien n = 0; 55259243Sobrien while (Isdigit(*cp)) 553195609Smp { 554195609Smp if (base == 8 && *cp >= '8') 555195609Smp stderror(ERR_NAME | ERR_BADNUM); 556195609Smp n = n * base + *cp++ - '0'; 557195609Smp } 55859243Sobrien if (*cp) 55959243Sobrien stderror(ERR_NAME | ERR_BADNUM); 56059243Sobrien return (sign ? -n : n); 56159243Sobrien} 56259243Sobrien 56359243SobrienChar * 564167465Smpvalue1(Char *var, struct varent *head) 56559243Sobrien{ 566145479Smp struct varent *vp; 56759243Sobrien 56859243Sobrien if (!var || !head) /* PWP: extra error checking */ 56959243Sobrien return (STRNULL); 57059243Sobrien 57159243Sobrien vp = adrof1(var, head); 572100616Smp return ((vp == NULL || vp->vec == NULL || vp->vec[0] == NULL) ? 573100616Smp STRNULL : vp->vec[0]); 57459243Sobrien} 57559243Sobrien 57659243Sobrienstatic struct varent * 577167465Smpmadrof(Char *pat, struct varent *vp) 57859243Sobrien{ 579145479Smp struct varent *vp1; 58059243Sobrien 58159243Sobrien for (vp = vp->v_left; vp; vp = vp->v_right) { 58259243Sobrien if (vp->v_left && (vp1 = madrof(pat, vp)) != NULL) 58359243Sobrien return vp1; 58459243Sobrien if (Gmatch(vp->v_name, pat)) 58559243Sobrien return vp; 58659243Sobrien } 58759243Sobrien return vp; 58859243Sobrien} 58959243Sobrien 59059243Sobrienstruct varent * 591167465Smpadrof1(const Char *name, struct varent *v) 59259243Sobrien{ 59359243Sobrien int cmp; 59459243Sobrien 59559243Sobrien v = v->v_left; 59659243Sobrien while (v && ((cmp = *name - *v->v_name) != 0 || 59759243Sobrien (cmp = Strcmp(name, v->v_name)) != 0)) 59859243Sobrien if (cmp < 0) 59959243Sobrien v = v->v_left; 60059243Sobrien else 60159243Sobrien v = v->v_right; 60259243Sobrien return v; 60359243Sobrien} 60459243Sobrien 605167465Smpvoid 606167465Smpsetcopy(const Char *var, const Char *val, int flags) 607167465Smp{ 608167465Smp Char *copy; 609167465Smp 610167465Smp copy = Strsave(val); 611167465Smp cleanup_push(copy, xfree); 612167465Smp setv(var, copy, flags); 613167465Smp cleanup_ignore(copy); 614167465Smp cleanup_until(copy); 615167465Smp} 616167465Smp 61759243Sobrien/* 61859243Sobrien * The caller is responsible for putting value in a safe place 61959243Sobrien */ 62059243Sobrienvoid 621167465Smpsetv(const Char *var, Char *val, int flags) 62259243Sobrien{ 623167465Smp Char **vec = xmalloc(2 * sizeof(Char **)); 62459243Sobrien 62559243Sobrien vec[0] = val; 62659243Sobrien vec[1] = 0; 62759243Sobrien set1(var, vec, &shvhed, flags); 62859243Sobrien} 62959243Sobrien 63059243Sobrienvoid 631167465Smpset1(const Char *var, Char **vec, struct varent *head, int flags) 63259243Sobrien{ 633145479Smp Char **oldv = vec; 63459243Sobrien 63559243Sobrien if ((flags & VAR_NOGLOB) == 0) { 636167465Smp int gflag; 637167465Smp 638167465Smp gflag = tglob(oldv); 63959243Sobrien if (gflag) { 640167465Smp vec = globall(oldv, gflag); 64159243Sobrien if (vec == 0) { 64259243Sobrien blkfree(oldv); 64359243Sobrien stderror(ERR_NAME | ERR_NOMATCH); 64459243Sobrien } 64559243Sobrien blkfree(oldv); 64659243Sobrien } 64759243Sobrien } 64859243Sobrien /* 64959243Sobrien * Uniqueness addition from: Michael Veksler <mveksler@vnet.ibm.com> 65059243Sobrien */ 65159243Sobrien if ( flags & (VAR_FIRST | VAR_LAST) ) { 65259243Sobrien /* 65359243Sobrien * Code for -f (VAR_FIRST) and -l (VAR_LAST) options. 65459243Sobrien * Method: 65559243Sobrien * Delete all duplicate words leaving "holes" in the word array (vec). 65659243Sobrien * Then remove the "holes", keeping the order of the words unchanged. 65759243Sobrien */ 65859243Sobrien if (vec && vec[0] && vec[1]) { /* more than one word ? */ 65959243Sobrien int i, j; 66059243Sobrien int num_items; 66159243Sobrien 66259243Sobrien for (num_items = 0; vec[num_items]; num_items++) 66359243Sobrien continue; 66459243Sobrien if (flags & VAR_FIRST) { 66559243Sobrien /* delete duplications, keeping first occurance */ 66659243Sobrien for (i = 1; i < num_items; i++) 66759243Sobrien for (j = 0; j < i; j++) 66859243Sobrien /* If have earlier identical item, remove i'th item */ 66959243Sobrien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { 670167465Smp xfree(vec[i]); 67159243Sobrien vec[i] = NULL; 67259243Sobrien break; 67359243Sobrien } 67459243Sobrien } else if (flags & VAR_LAST) { 67559243Sobrien /* delete duplications, keeping last occurance */ 67659243Sobrien for (i = 0; i < num_items - 1; i++) 67759243Sobrien for (j = i + 1; j < num_items; j++) 67859243Sobrien /* If have later identical item, remove i'th item */ 67959243Sobrien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { 68059243Sobrien /* remove identical item (the first) */ 681167465Smp xfree(vec[i]); 68259243Sobrien vec[i] = NULL; 68359243Sobrien } 68459243Sobrien } 68559243Sobrien /* Compress items - remove empty items */ 68659243Sobrien for (j = i = 0; i < num_items; i++) 68759243Sobrien if (vec[i]) 68859243Sobrien vec[j++] = vec[i]; 68959243Sobrien 69059243Sobrien /* NULL-fy remaining items */ 69159243Sobrien for (; j < num_items; j++) 69259243Sobrien vec[j] = NULL; 69359243Sobrien } 69459243Sobrien /* don't let the attribute propagate */ 69559243Sobrien flags &= ~(VAR_FIRST|VAR_LAST); 69659243Sobrien } 69759243Sobrien setq(var, vec, head, flags); 69859243Sobrien} 69959243Sobrien 70059243Sobrien 70159243Sobrienvoid 702167465Smpsetq(const Char *name, Char **vec, struct varent *p, int flags) 70359243Sobrien{ 704145479Smp struct varent *c; 705145479Smp int f; 70659243Sobrien 70759243Sobrien f = 0; /* tree hangs off the header's left link */ 70859243Sobrien while ((c = p->v_link[f]) != 0) { 70959243Sobrien if ((f = *name - *c->v_name) == 0 && 71059243Sobrien (f = Strcmp(name, c->v_name)) == 0) { 71159243Sobrien if (c->v_flags & VAR_READONLY) 71259243Sobrien stderror(ERR_READONLY|ERR_NAME, c->v_name); 71359243Sobrien blkfree(c->vec); 71459243Sobrien c->v_flags = flags; 71559243Sobrien trim(c->vec = vec); 71659243Sobrien return; 71759243Sobrien } 71859243Sobrien p = c; 71959243Sobrien f = f > 0; 72059243Sobrien } 721167465Smp p->v_link[f] = c = xmalloc(sizeof(struct varent)); 72259243Sobrien c->v_name = Strsave(name); 72359243Sobrien c->v_flags = flags; 72459243Sobrien c->v_bal = 0; 72559243Sobrien c->v_left = c->v_right = 0; 72659243Sobrien c->v_parent = p; 72759243Sobrien balance(p, f, 0); 72859243Sobrien trim(c->vec = vec); 72959243Sobrien} 73059243Sobrien 73159243Sobrien/*ARGSUSED*/ 73259243Sobrienvoid 733167465Smpunset(Char **v, struct command *c) 73459243Sobrien{ 735145479Smp int did_roe, did_edit; 73659243Sobrien 73759243Sobrien USE(c); 73859243Sobrien did_roe = adrof(STRrecognize_only_executables) != NULL; 73959243Sobrien did_edit = adrof(STRedit) != NULL; 74059243Sobrien unset1(v, &shvhed); 741100616Smp 742100616Smp#if defined(FILEC) && defined(TIOCSTI) 743100616Smp if (adrof(STRfilec) == 0) 744100616Smp filec = 0; 745100616Smp#endif /* FILEC && TIOCSTI */ 746100616Smp 74759243Sobrien if (adrof(STRhistchars) == 0) { 74859243Sobrien HIST = '!'; 74959243Sobrien HISTSUB = '^'; 75059243Sobrien } 751131962Smp if (adrof(STRignoreeof) == 0) 752131962Smp numeof = 0; 75359243Sobrien if (adrof(STRpromptchars) == 0) { 75459243Sobrien PRCH = '>'; 75559243Sobrien PRCHROOT = '#'; 75659243Sobrien } 75759243Sobrien if (adrof(STRhistlit) == 0) 75859243Sobrien HistLit = 0; 75959243Sobrien if (adrof(STRloginsh) == 0) 76059243Sobrien loginsh = 0; 76159243Sobrien if (adrof(STRwordchars) == 0) 76259243Sobrien word_chars = STR_WORD_CHARS; 76359243Sobrien if (adrof(STRedit) == 0) 76459243Sobrien editing = 0; 76559243Sobrien if (adrof(STRbackslash_quote) == 0) 76659243Sobrien bslash_quote = 0; 767195609Smp if (adrof(STRcompat_expr) == 0) 768195609Smp compat_expr = 0; 76959243Sobrien if (adrof(STRsymlinks) == 0) 77059243Sobrien symlinks = 0; 77159243Sobrien if (adrof(STRimplicitcd) == 0) 77259243Sobrien implicit_cd = 0; 77383098Smp if (adrof(STRkillring) == 0) 77483098Smp SetKillRing(0); 77559243Sobrien if (did_edit && noediting && adrof(STRedit) == 0) 77659243Sobrien noediting = 0; 77759243Sobrien if (did_roe && adrof(STRrecognize_only_executables) == 0) 77859243Sobrien tw_cmd_free(); 77959243Sobrien#ifdef COLOR_LS_F 78059243Sobrien if (adrof(STRcolor) == 0) 78159243Sobrien set_color_context(); 78259243Sobrien#endif /* COLOR_LS_F */ 78359243Sobrien#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 78459243Sobrien update_dspmbyte_vars(); 78559243Sobrien#endif 78669408Sache#ifdef NLS_CATALOGS 787145479Smp nlsclose(); 78869408Sache nlsinit(); 78969408Sache#endif /* NLS_CATALOGS */ 79059243Sobrien} 79159243Sobrien 79259243Sobrienvoid 793167465Smpunset1(Char *v[], struct varent *head) 79459243Sobrien{ 795145479Smp struct varent *vp; 796145479Smp int cnt; 79759243Sobrien 79859243Sobrien while (*++v) { 79959243Sobrien cnt = 0; 80059243Sobrien while ((vp = madrof(*v, head)) != NULL) 80159243Sobrien if (vp->v_flags & VAR_READONLY) 80259243Sobrien stderror(ERR_READONLY|ERR_NAME, vp->v_name); 80359243Sobrien else 80459243Sobrien unsetv1(vp), cnt++; 80559243Sobrien if (cnt == 0) 80659243Sobrien setname(short2str(*v)); 80759243Sobrien } 80859243Sobrien} 80959243Sobrien 81059243Sobrienvoid 811167465Smpunsetv(Char *var) 81259243Sobrien{ 813145479Smp struct varent *vp; 81459243Sobrien 81559243Sobrien if ((vp = adrof1(var, &shvhed)) == 0) 81659243Sobrien udvar(var); 81759243Sobrien unsetv1(vp); 81859243Sobrien} 81959243Sobrien 82059243Sobrienstatic void 821167465Smpunsetv1(struct varent *p) 82259243Sobrien{ 823145479Smp struct varent *c, *pp; 824145479Smp int f; 82559243Sobrien 82659243Sobrien /* 82759243Sobrien * Free associated memory first to avoid complications. 82859243Sobrien */ 82959243Sobrien blkfree(p->vec); 830167465Smp xfree(p->v_name); 83159243Sobrien /* 83259243Sobrien * If p is missing one child, then we can move the other into where p is. 83359243Sobrien * Otherwise, we find the predecessor of p, which is guaranteed to have no 83459243Sobrien * right child, copy it into p, and move it's left child into it. 83559243Sobrien */ 83659243Sobrien if (p->v_right == 0) 83759243Sobrien c = p->v_left; 83859243Sobrien else if (p->v_left == 0) 83959243Sobrien c = p->v_right; 84059243Sobrien else { 84159243Sobrien for (c = p->v_left; c->v_right; c = c->v_right) 84259243Sobrien continue; 84359243Sobrien p->v_name = c->v_name; 84459243Sobrien p->v_flags = c->v_flags; 84559243Sobrien p->vec = c->vec; 84659243Sobrien p = c; 84759243Sobrien c = p->v_left; 84859243Sobrien } 84959243Sobrien 85059243Sobrien /* 85159243Sobrien * Move c into where p is. 85259243Sobrien */ 85359243Sobrien pp = p->v_parent; 85459243Sobrien f = pp->v_right == p; 85559243Sobrien if ((pp->v_link[f] = c) != 0) 85659243Sobrien c->v_parent = pp; 85759243Sobrien /* 85859243Sobrien * Free the deleted node, and rebalance. 85959243Sobrien */ 860167465Smp xfree(p); 86159243Sobrien balance(pp, f, 1); 86259243Sobrien} 86359243Sobrien 86459243Sobrienvoid 865167465SmpsetNS(Char *cp) 86659243Sobrien{ 867167465Smp setcopy(cp, STRNULL, VAR_READWRITE); 86859243Sobrien} 86959243Sobrien 87059243Sobrien/*ARGSUSED*/ 87159243Sobrienvoid 872167465Smpshift(Char **v, struct command *c) 87359243Sobrien{ 874145479Smp struct varent *argv; 875145479Smp Char *name; 87659243Sobrien 87759243Sobrien USE(c); 87859243Sobrien v++; 87959243Sobrien name = *v; 88059243Sobrien if (name == 0) 88159243Sobrien name = STRargv; 88259243Sobrien else 88359243Sobrien (void) strip(name); 88459243Sobrien argv = adrof(name); 885100616Smp if (argv == NULL || argv->vec == NULL) 88659243Sobrien udvar(name); 88759243Sobrien if (argv->vec[0] == 0) 88859243Sobrien stderror(ERR_NAME | ERR_NOMORE); 88959243Sobrien lshift(argv->vec, 1); 89059243Sobrien update_vars(name); 89159243Sobrien} 89259243Sobrien 89359243Sobrienstatic void 894167465Smpexportpath(Char **val) 89559243Sobrien{ 896167465Smp struct Strbuf buf = Strbuf_INIT; 897167465Smp Char *exppath; 89859243Sobrien 89959243Sobrien if (val) 90059243Sobrien while (*val) { 901167465Smp Strbuf_append(&buf, *val++); 902167465Smp if (*val == 0 || eq(*val, STRRparen)) 90359243Sobrien break; 904167465Smp Strbuf_append1(&buf, PATHSEP); 905167465Smp } 906167465Smp exppath = Strbuf_finish(&buf); 907167465Smp cleanup_push(exppath, xfree); 908167465Smp tsetenv(STRKPATH, exppath); 909167465Smp cleanup_until(exppath); 91059243Sobrien} 91159243Sobrien 91259243Sobrien#ifndef lint 91359243Sobrien /* 91459243Sobrien * Lint thinks these have null effect 91559243Sobrien */ 91659243Sobrien /* macros to do single rotations on node p */ 91759243Sobrien# define rright(p) (\ 91859243Sobrien t = (p)->v_left,\ 91959243Sobrien (t)->v_parent = (p)->v_parent,\ 92059243Sobrien (((p)->v_left = t->v_right) != NULL) ?\ 92159243Sobrien (t->v_right->v_parent = (p)) : 0,\ 92259243Sobrien (t->v_right = (p))->v_parent = t,\ 92359243Sobrien (p) = t) 92459243Sobrien# define rleft(p) (\ 92559243Sobrien t = (p)->v_right,\ 92659243Sobrien ((t)->v_parent = (p)->v_parent,\ 92759243Sobrien ((p)->v_right = t->v_left) != NULL) ? \ 92859243Sobrien (t->v_left->v_parent = (p)) : 0,\ 92959243Sobrien (t->v_left = (p))->v_parent = t,\ 93059243Sobrien (p) = t) 93159243Sobrien#else 93259243Sobrienstatic struct varent * 933167465Smprleft(struct varent *p) 93459243Sobrien{ 93559243Sobrien return (p); 93659243Sobrien} 93759243Sobrienstatic struct varent * 938167465Smprright(struct varent *p) 93959243Sobrien{ 94059243Sobrien return (p); 94159243Sobrien} 94259243Sobrien 94359243Sobrien#endif /* ! lint */ 94459243Sobrien 94559243Sobrien 94659243Sobrien/* 94759243Sobrien * Rebalance a tree, starting at p and up. 94859243Sobrien * F == 0 means we've come from p's left child. 94959243Sobrien * D == 1 means we've just done a delete, otherwise an insert. 95059243Sobrien */ 95159243Sobrienstatic void 952167465Smpbalance(struct varent *p, int f, int d) 95359243Sobrien{ 954145479Smp struct varent *pp; 95559243Sobrien 95659243Sobrien#ifndef lint 957145479Smp struct varent *t; /* used by the rotate macros */ 95859243Sobrien#endif /* !lint */ 959145479Smp int ff; 96059243Sobrien#ifdef lint 96159243Sobrien ff = 0; /* Sun's lint is dumb! */ 96259243Sobrien#endif 96359243Sobrien 96459243Sobrien /* 96559243Sobrien * Ok, from here on, p is the node we're operating on; pp is it's parent; f 96659243Sobrien * is the branch of p from which we have come; ff is the branch of pp which 96759243Sobrien * is p. 96859243Sobrien */ 96959243Sobrien for (; (pp = p->v_parent) != 0; p = pp, f = ff) { 97059243Sobrien ff = pp->v_right == p; 97159243Sobrien if (f ^ d) { /* right heavy */ 97259243Sobrien switch (p->v_bal) { 97359243Sobrien case -1: /* was left heavy */ 97459243Sobrien p->v_bal = 0; 97559243Sobrien break; 97659243Sobrien case 0: /* was balanced */ 97759243Sobrien p->v_bal = 1; 97859243Sobrien break; 97959243Sobrien case 1: /* was already right heavy */ 98059243Sobrien switch (p->v_right->v_bal) { 981167465Smp case 1: /* single rotate */ 98259243Sobrien pp->v_link[ff] = rleft(p); 98359243Sobrien p->v_left->v_bal = 0; 98459243Sobrien p->v_bal = 0; 98559243Sobrien break; 98659243Sobrien case 0: /* single rotate */ 98759243Sobrien pp->v_link[ff] = rleft(p); 98859243Sobrien p->v_left->v_bal = 1; 98959243Sobrien p->v_bal = -1; 99059243Sobrien break; 99159243Sobrien case -1: /* double rotate */ 99259243Sobrien (void) rright(p->v_right); 99359243Sobrien pp->v_link[ff] = rleft(p); 99459243Sobrien p->v_left->v_bal = 99559243Sobrien p->v_bal < 1 ? 0 : -1; 99659243Sobrien p->v_right->v_bal = 99759243Sobrien p->v_bal > -1 ? 0 : 1; 99859243Sobrien p->v_bal = 0; 99959243Sobrien break; 100059243Sobrien default: 100159243Sobrien break; 100259243Sobrien } 100359243Sobrien break; 100459243Sobrien default: 100559243Sobrien break; 100659243Sobrien } 100759243Sobrien } 100859243Sobrien else { /* left heavy */ 100959243Sobrien switch (p->v_bal) { 101059243Sobrien case 1: /* was right heavy */ 101159243Sobrien p->v_bal = 0; 101259243Sobrien break; 101359243Sobrien case 0: /* was balanced */ 101459243Sobrien p->v_bal = -1; 101559243Sobrien break; 101659243Sobrien case -1: /* was already left heavy */ 101759243Sobrien switch (p->v_left->v_bal) { 101859243Sobrien case -1: /* single rotate */ 101959243Sobrien pp->v_link[ff] = rright(p); 102059243Sobrien p->v_right->v_bal = 0; 102159243Sobrien p->v_bal = 0; 102259243Sobrien break; 1023167465Smp case 0: /* single rotate */ 102459243Sobrien pp->v_link[ff] = rright(p); 102559243Sobrien p->v_right->v_bal = -1; 102659243Sobrien p->v_bal = 1; 102759243Sobrien break; 102859243Sobrien case 1: /* double rotate */ 102959243Sobrien (void) rleft(p->v_left); 103059243Sobrien pp->v_link[ff] = rright(p); 103159243Sobrien p->v_left->v_bal = 103259243Sobrien p->v_bal < 1 ? 0 : -1; 103359243Sobrien p->v_right->v_bal = 103459243Sobrien p->v_bal > -1 ? 0 : 1; 103559243Sobrien p->v_bal = 0; 103659243Sobrien break; 103759243Sobrien default: 103859243Sobrien break; 103959243Sobrien } 104059243Sobrien break; 104159243Sobrien default: 104259243Sobrien break; 104359243Sobrien } 104459243Sobrien } 104559243Sobrien /* 104659243Sobrien * If from insert, then we terminate when p is balanced. If from 104759243Sobrien * delete, then we terminate when p is unbalanced. 104859243Sobrien */ 104959243Sobrien if ((p->v_bal == 0) ^ d) 105059243Sobrien break; 105159243Sobrien } 105259243Sobrien} 105359243Sobrien 105459243Sobrienvoid 1055167465Smpplist(struct varent *p, int what) 105659243Sobrien{ 1057145479Smp struct varent *c; 1058145479Smp int len; 105959243Sobrien 106059243Sobrien for (;;) { 106159243Sobrien while (p->v_left) 106259243Sobrien p = p->v_left; 106359243Sobrienx: 106459243Sobrien if (p->v_parent == 0) /* is it the header? */ 1065167465Smp break; 106659243Sobrien if ((p->v_flags & what) != 0) { 1067167465Smp if (setintr) { 1068167465Smp int old_pintr_disabled; 1069167465Smp 1070167465Smp pintr_push_enable(&old_pintr_disabled); 1071167465Smp cleanup_until(&old_pintr_disabled); 1072167465Smp } 107359243Sobrien len = blklen(p->vec); 107459243Sobrien xprintf("%S\t", p->v_name); 107559243Sobrien if (len != 1) 107659243Sobrien xputchar('('); 107759243Sobrien blkpr(p->vec); 107859243Sobrien if (len != 1) 107959243Sobrien xputchar(')'); 108059243Sobrien xputchar('\n'); 108159243Sobrien } 108259243Sobrien if (p->v_right) { 108359243Sobrien p = p->v_right; 108459243Sobrien continue; 108559243Sobrien } 108659243Sobrien do { 108759243Sobrien c = p; 108859243Sobrien p = p->v_parent; 108959243Sobrien } while (p->v_right == c); 109059243Sobrien goto x; 109159243Sobrien } 109259243Sobrien} 109359243Sobrien 109459243Sobrien#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 1095145479Smpextern int dspmbyte_ls; 109659243Sobrien 109759243Sobrienvoid 1098167465Smpupdate_dspmbyte_vars(void) 109959243Sobrien{ 110059243Sobrien int lp, iskcode; 110159243Sobrien Char *dstr1; 110259243Sobrien struct varent *vp; 110359243Sobrien 110459243Sobrien /* if variable "nokanji" is set, multi-byte display is disabled */ 110559243Sobrien if ((vp = adrof(CHECK_MBYTEVAR)) && !adrof(STRnokanji)) { 110659243Sobrien _enable_mbdisp = 1; 110759243Sobrien dstr1 = vp->vec[0]; 1108145479Smp if(eq (dstr1, STRsjis)) 110959243Sobrien iskcode = 1; 1110145479Smp else if (eq(dstr1, STReuc)) 111159243Sobrien iskcode = 2; 1112145479Smp else if (eq(dstr1, STRbig5)) 111383098Smp iskcode = 3; 1114145479Smp else if (eq(dstr1, STRutf8)) 1115100616Smp iskcode = 4; 111659243Sobrien else if ((dstr1[0] - '0') >= 0 && (dstr1[0] - '0') <= 3) { 111759243Sobrien iskcode = 0; 111859243Sobrien } 111959243Sobrien else { 112059243Sobrien xprintf(CGETS(18, 2, 112159243Sobrien "Warning: unknown multibyte display; using default(euc(JP))\n")); 112259243Sobrien iskcode = 2; 112359243Sobrien } 112459243Sobrien if (dstr1 && vp->vec[1] && eq(vp->vec[1], STRls)) 112559243Sobrien dspmbyte_ls = 1; 112659243Sobrien else 112759243Sobrien dspmbyte_ls = 0; 112859243Sobrien for (lp = 0; lp < 256 && iskcode > 0; lp++) { 112959243Sobrien switch (iskcode) { 113059243Sobrien case 1: 113159243Sobrien /* Shift-JIS */ 113259243Sobrien _cmap[lp] = _cmap_mbyte[lp]; 113359243Sobrien _mbmap[lp] = _mbmap_sjis[lp]; 113459243Sobrien break; 113559243Sobrien case 2: 113659243Sobrien /* 2 ... euc */ 113759243Sobrien _cmap[lp] = _cmap_mbyte[lp]; 113859243Sobrien _mbmap[lp] = _mbmap_euc[lp]; 113959243Sobrien break; 114083098Smp case 3: 114183098Smp /* 3 ... big5 */ 114283098Smp _cmap[lp] = _cmap_mbyte[lp]; 114383098Smp _mbmap[lp] = _mbmap_big5[lp]; 114483098Smp break; 1145100616Smp case 4: 1146100616Smp /* 4 ... utf8 */ 1147100616Smp _cmap[lp] = _cmap_mbyte[lp]; 1148100616Smp _mbmap[lp] = _mbmap_utf8[lp]; 1149100616Smp break; 115059243Sobrien default: 115159243Sobrien xprintf(CGETS(18, 3, 115259243Sobrien "Warning: unknown multibyte code %d; multibyte disabled\n"), 115359243Sobrien iskcode); 115459243Sobrien _cmap[lp] = _cmap_c[lp]; 115559243Sobrien _mbmap[lp] = 0; /* Default map all 0 */ 115659243Sobrien _enable_mbdisp = 0; 115759243Sobrien break; 115859243Sobrien } 115959243Sobrien } 116059243Sobrien if (iskcode == 0) { 116159243Sobrien /* check original table */ 116259243Sobrien if (Strlen(dstr1) != 256) { 116359243Sobrien xprintf(CGETS(18, 4, 116459243Sobrien "Warning: Invalid multibyte table length (%d); multibyte disabled\n"), 116559243Sobrien Strlen(dstr1)); 116659243Sobrien _enable_mbdisp = 0; 116759243Sobrien } 116859243Sobrien for (lp = 0; lp < 256 && _enable_mbdisp == 1; lp++) { 116959243Sobrien if (!((dstr1[lp] - '0') >= 0 && (dstr1[lp] - '0') <= 3)) { 117059243Sobrien xprintf(CGETS(18, 4, 117159243Sobrien "Warning: bad multibyte code at offset +%d; multibyte diabled\n"), 117259243Sobrien lp); 117359243Sobrien _enable_mbdisp = 0; 117459243Sobrien break; 117559243Sobrien } 117659243Sobrien } 117759243Sobrien /* set original table */ 117859243Sobrien for (lp = 0; lp < 256; lp++) { 117959243Sobrien if (_enable_mbdisp == 1) { 118059243Sobrien _cmap[lp] = _cmap_mbyte[lp]; 118159243Sobrien _mbmap[lp] = (unsigned short) ((dstr1[lp] - '0') & 0x0f); 118259243Sobrien } 118359243Sobrien else { 118459243Sobrien _cmap[lp] = _cmap_c[lp]; 118559243Sobrien _mbmap[lp] = 0; /* Default map all 0 */ 118659243Sobrien } 118759243Sobrien } 118859243Sobrien } 118959243Sobrien } 119059243Sobrien else { 119159243Sobrien for (lp = 0; lp < 256; lp++) { 119259243Sobrien _cmap[lp] = _cmap_c[lp]; 119359243Sobrien _mbmap[lp] = 0; /* Default map all 0 */ 119459243Sobrien } 119559243Sobrien _enable_mbdisp = 0; 119659243Sobrien dspmbyte_ls = 0; 119759243Sobrien } 119859243Sobrien#ifdef MBYTEDEBUG /* Sorry, use for beta testing */ 119959243Sobrien { 120059243Sobrien Char mbmapstr[300]; 1201167465Smp for (lp = 0; lp < 256; lp++) 120259243Sobrien mbmapstr[lp] = _mbmap[lp] + '0'; 1203167465Smp mbmapstr[lp] = 0; 1204167465Smp setcopy(STRmbytemap, mbmapstr, VAR_READWRITE); 120559243Sobrien } 120659243Sobrien#endif /* MBYTEMAP */ 120759243Sobrien} 120859243Sobrien 120959243Sobrien/* dspkanji/dspmbyte autosetting */ 121059243Sobrien/* PATCH IDEA FROM Issei.Suzuki VERY THANKS */ 121159243Sobrienvoid 1212167465Smpautoset_dspmbyte(const Char *pcp) 121359243Sobrien{ 121459243Sobrien int i; 1215167465Smp static const struct dspm_autoset_Table { 121659243Sobrien Char *n; 121759243Sobrien Char *v; 121859243Sobrien } dspmt[] = { 1219145479Smp { STRLANGEUCJP, STReuc }, 1220145479Smp { STRLANGEUCKR, STReuc }, 1221145479Smp { STRLANGEUCZH, STReuc }, 1222145479Smp { STRLANGEUCJPB, STReuc }, 1223145479Smp { STRLANGEUCKRB, STReuc }, 1224145479Smp { STRLANGEUCZHB, STReuc }, 1225131962Smp#ifdef linux 1226145479Smp { STRLANGEUCJPC, STReuc }, 1227131962Smp#endif 1228145479Smp { STRLANGSJIS, STRsjis }, 1229145479Smp { STRLANGSJISB, STRsjis }, 1230145479Smp { STRLANGBIG5, STRbig5 }, 1231145479Smp { STRstarutfstar8, STRutf8 }, 123259243Sobrien { NULL, NULL } 123359243Sobrien }; 1234167465Smp#if defined(HAVE_NL_LANGINFO) && defined(CODESET) 1235167465Smp static const struct dspm_autoset_Table dspmc[] = { 1236145479Smp { STRstarutfstar8, STRutf8 }, 1237145479Smp { STReuc, STReuc }, 1238145479Smp { STRGB2312, STReuc }, 1239145479Smp { STRLANGBIG5, STRbig5 }, 1240145479Smp { NULL, NULL } 1241145479Smp }; 1242145479Smp Char *codeset; 124359243Sobrien 1244145479Smp codeset = str2short(nl_langinfo(CODESET)); 1245145479Smp if (*codeset != '\0') { 1246145479Smp for (i = 0; dspmc[i].n; i++) { 1247167465Smp const Char *estr; 1248145479Smp if (dspmc[i].n[0] && t_pmatch(pcp, dspmc[i].n, &estr, 0) > 0) { 1249167465Smp setcopy(CHECK_MBYTEVAR, dspmc[i].v, VAR_READWRITE); 1250145479Smp update_dspmbyte_vars(); 1251145479Smp return; 1252145479Smp } 1253145479Smp } 1254145479Smp } 1255145479Smp#endif 1256145479Smp 125759243Sobrien if (*pcp == '\0') 125859243Sobrien return; 125959243Sobrien 126059243Sobrien for (i = 0; dspmt[i].n; i++) { 1261167465Smp const Char *estr; 1262145479Smp if (dspmt[i].n[0] && t_pmatch(pcp, dspmt[i].n, &estr, 0) > 0) { 1263167465Smp setcopy(CHECK_MBYTEVAR, dspmt[i].v, VAR_READWRITE); 126459243Sobrien update_dspmbyte_vars(); 126559243Sobrien break; 126659243Sobrien } 126759243Sobrien } 126859243Sobrien} 126959243Sobrien#endif 1270