sh.set.c revision 167465
1167465Smp/* $Header: /p/tcsh/cvsroot/tcsh/sh.set.c,v 3.70 2006/08/24 20:56:31 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 35167465SmpRCSID("$tcsh: sh.set.c,v 3.70 2006/08/24 20:56:31 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 } 17759243Sobrien else if (eq(vp, STRdirstack)) { 17859243Sobrien dsetstack(); 17959243Sobrien } 18059243Sobrien else if (eq(vp, STRrecognize_only_executables)) { 18159243Sobrien tw_cmd_free(); 18259243Sobrien } 18383098Smp else if (eq(vp, STRkillring)) { 18483098Smp SetKillRing(getn(varval(vp))); 18583098Smp } 18659243Sobrien#ifndef HAVENOUTMP 18759243Sobrien else if (eq(vp, STRwatch)) { 18859243Sobrien resetwatch(); 18959243Sobrien } 19059243Sobrien#endif /* HAVENOUTMP */ 19159243Sobrien else if (eq(vp, STRimplicitcd)) { 19259243Sobrien implicit_cd = ((eq(varval(vp), STRverbose)) ? 2 : 1); 19359243Sobrien } 19459243Sobrien#ifdef COLOR_LS_F 19559243Sobrien else if (eq(vp, STRcolor)) { 19659243Sobrien set_color_context(); 19759243Sobrien } 19859243Sobrien#endif /* COLOR_LS_F */ 19959243Sobrien#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 20059243Sobrien else if(eq(vp, CHECK_MBYTEVAR) || eq(vp, STRnokanji)) { 20159243Sobrien update_dspmbyte_vars(); 20259243Sobrien } 20359243Sobrien#endif 20469408Sache#ifdef NLS_CATALOGS 20569408Sache else if (eq(vp, STRcatalog)) { 206145479Smp nlsclose(); 20769408Sache nlsinit(); 20869408Sache } 209100616Smp#if defined(FILEC) && defined(TIOCSTI) 210100616Smp else if (eq(vp, STRfilec)) 211100616Smp filec = 1; 212100616Smp#endif 21369408Sache#endif /* NLS_CATALOGS */ 21459243Sobrien} 21559243Sobrien 21659243Sobrien 21759243Sobrien/*ARGSUSED*/ 21859243Sobrienvoid 219167465Smpdoset(Char **v, struct command *c) 22059243Sobrien{ 221145479Smp Char *p; 22259243Sobrien Char *vp, op; 22359243Sobrien Char **vecp; 224145479Smp int hadsub; 22559243Sobrien int subscr; 22659243Sobrien int flags = VAR_READWRITE; 227145479Smp int first_match = 0; 228145479Smp int last_match = 0; 229145479Smp int changed = 0; 23059243Sobrien 23159243Sobrien USE(c); 23259243Sobrien v++; 23359243Sobrien do { 23459243Sobrien changed = 0; 23559243Sobrien /* 23659243Sobrien * Readonly addition From: Tim P. Starrin <noid@cyborg.larc.nasa.gov> 23759243Sobrien */ 23859243Sobrien if (*v && eq(*v, STRmr)) { 23959243Sobrien flags = VAR_READONLY; 24059243Sobrien v++; 24159243Sobrien changed = 1; 24259243Sobrien } 24359243Sobrien if (*v && eq(*v, STRmf) && !last_match) { 24459243Sobrien first_match = 1; 24559243Sobrien v++; 24659243Sobrien changed = 1; 24759243Sobrien } 24859243Sobrien if (*v && eq(*v, STRml) && !first_match) { 24959243Sobrien last_match = 1; 25059243Sobrien v++; 25159243Sobrien changed = 1; 25259243Sobrien } 25359243Sobrien } while(changed); 25459243Sobrien p = *v++; 25559243Sobrien if (p == 0) { 25659243Sobrien plist(&shvhed, flags); 25759243Sobrien return; 25859243Sobrien } 25959243Sobrien do { 26059243Sobrien hadsub = 0; 26159243Sobrien vp = p; 26259243Sobrien if (letter(*p)) 26359243Sobrien for (; alnum(*p); p++) 26459243Sobrien continue; 26559243Sobrien if (vp == p || !letter(*vp)) 26659243Sobrien stderror(ERR_NAME | ERR_VARBEGIN); 26759243Sobrien if (*p == '[') { 26859243Sobrien hadsub++; 26959243Sobrien p = getinx(p, &subscr); 27059243Sobrien } 27159243Sobrien if ((op = *p) != 0) { 27259243Sobrien *p++ = 0; 27359243Sobrien if (*p == 0 && *v && **v == '(') 27459243Sobrien p = *v++; 27559243Sobrien } 27659243Sobrien else if (*v && eq(*v, STRequal)) { 27759243Sobrien op = '=', v++; 27859243Sobrien if (*v) 27959243Sobrien p = *v++; 28059243Sobrien } 28159243Sobrien if (op && op != '=') 28259243Sobrien stderror(ERR_NAME | ERR_SYNTAX); 28359243Sobrien if (eq(p, STRLparen)) { 284145479Smp Char **e = v; 28559243Sobrien 28659243Sobrien if (hadsub) 28759243Sobrien stderror(ERR_NAME | ERR_SYNTAX); 28859243Sobrien for (;;) { 28959243Sobrien if (!*e) 29059243Sobrien stderror(ERR_NAME | ERR_MISSING, ')'); 29159243Sobrien if (**e == ')') 29259243Sobrien break; 29359243Sobrien e++; 29459243Sobrien } 29559243Sobrien p = *e; 29659243Sobrien *e = 0; 29759243Sobrien vecp = saveblk(v); 29859243Sobrien if (first_match) 29959243Sobrien flags |= VAR_FIRST; 30059243Sobrien else if (last_match) 30159243Sobrien flags |= VAR_LAST; 30259243Sobrien 30359243Sobrien set1(vp, vecp, &shvhed, flags); 30459243Sobrien *e = p; 30559243Sobrien v = e + 1; 30659243Sobrien } 307167465Smp else if (hadsub) { 308167465Smp Char *copy; 309167465Smp 310167465Smp copy = Strsave(p); 311167465Smp cleanup_push(copy, xfree); 312167465Smp asx(vp, subscr, copy); 313167465Smp cleanup_ignore(copy); 314167465Smp cleanup_until(copy); 315167465Smp } 31659243Sobrien else 317167465Smp setv(vp, Strsave(p), flags); 31859243Sobrien update_vars(vp); 31959243Sobrien } while ((p = *v++) != NULL); 32059243Sobrien} 32159243Sobrien 32259243Sobrienstatic Char * 323167465Smpgetinx(Char *cp, int *ip) 32459243Sobrien{ 32559243Sobrien *ip = 0; 32659243Sobrien *cp++ = 0; 32759243Sobrien while (*cp && Isdigit(*cp)) 32859243Sobrien *ip = *ip * 10 + *cp++ - '0'; 32959243Sobrien if (*cp++ != ']') 33059243Sobrien stderror(ERR_NAME | ERR_SUBSCRIPT); 33159243Sobrien return (cp); 33259243Sobrien} 33359243Sobrien 33459243Sobrienstatic void 335167465Smpasx(Char *vp, int subscr, Char *p) 33659243Sobrien{ 337145479Smp struct varent *v = getvx(vp, subscr); 338167465Smp Char *prev; 33959243Sobrien 34059243Sobrien if (v->v_flags & VAR_READONLY) 34159243Sobrien stderror(ERR_READONLY|ERR_NAME, v->v_name); 342167465Smp prev = v->vec[subscr - 1]; 343167465Smp cleanup_push(prev, xfree); 34459243Sobrien v->vec[subscr - 1] = globone(p, G_APPEND); 345167465Smp cleanup_until(prev); 34659243Sobrien} 34759243Sobrien 34859243Sobrienstatic struct varent * 349167465Smpgetvx(Char *vp, int subscr) 35059243Sobrien{ 351145479Smp struct varent *v = adrof(vp); 35259243Sobrien 35359243Sobrien if (v == 0) 35459243Sobrien udvar(vp); 35559243Sobrien if (subscr < 1 || subscr > blklen(v->vec)) 35659243Sobrien stderror(ERR_NAME | ERR_RANGE); 35759243Sobrien return (v); 35859243Sobrien} 35959243Sobrien 36059243Sobrien/*ARGSUSED*/ 36159243Sobrienvoid 362167465Smpdolet(Char **v, struct command *dummy) 36359243Sobrien{ 364145479Smp Char *p; 36559243Sobrien Char *vp, c, op; 366145479Smp int hadsub; 36759243Sobrien int subscr; 36859243Sobrien 36959243Sobrien USE(dummy); 37059243Sobrien v++; 37159243Sobrien p = *v++; 37259243Sobrien if (p == 0) { 37359243Sobrien prvars(); 37459243Sobrien return; 37559243Sobrien } 37659243Sobrien do { 37759243Sobrien hadsub = 0; 37859243Sobrien vp = p; 37959243Sobrien if (letter(*p)) 38059243Sobrien for (; alnum(*p); p++) 38159243Sobrien continue; 38259243Sobrien if (vp == p || !letter(*vp)) 38359243Sobrien stderror(ERR_NAME | ERR_VARBEGIN); 38459243Sobrien if (*p == '[') { 38559243Sobrien hadsub++; 38659243Sobrien p = getinx(p, &subscr); 38759243Sobrien } 38859243Sobrien if (*p == 0 && *v) 38959243Sobrien p = *v++; 39059243Sobrien if ((op = *p) != 0) 39159243Sobrien *p++ = 0; 39259243Sobrien else 39359243Sobrien stderror(ERR_NAME | ERR_ASSIGN); 39459243Sobrien 39559243Sobrien /* 39659243Sobrien * if there is no expression after the '=' then print a "Syntax Error" 39759243Sobrien * message - strike 39859243Sobrien */ 39959243Sobrien if (*p == '\0' && *v == NULL) 40059243Sobrien stderror(ERR_NAME | ERR_ASSIGN); 40159243Sobrien 40259243Sobrien vp = Strsave(vp); 403167465Smp cleanup_push(vp, xfree); 40459243Sobrien if (op == '=') { 40559243Sobrien c = '='; 40659243Sobrien p = xset(p, &v); 40759243Sobrien } 40859243Sobrien else { 40959243Sobrien c = *p++; 41059243Sobrien if (any("+-", c)) { 41159243Sobrien if (c != op || *p) 41259243Sobrien stderror(ERR_NAME | ERR_UNKNOWNOP); 41359243Sobrien p = Strsave(STR1); 41459243Sobrien } 41559243Sobrien else { 41659243Sobrien if (any("<>", op)) { 41759243Sobrien if (c != op) 41859243Sobrien stderror(ERR_NAME | ERR_UNKNOWNOP); 41959243Sobrien stderror(ERR_NAME | ERR_SYNTAX); 42059243Sobrien } 42159243Sobrien if (c != '=') 42259243Sobrien stderror(ERR_NAME | ERR_UNKNOWNOP); 42359243Sobrien p = xset(p, &v); 42459243Sobrien } 42559243Sobrien } 426167465Smp cleanup_push(p, xfree); 42759243Sobrien if (op == '=') { 42859243Sobrien if (hadsub) 42959243Sobrien asx(vp, subscr, p); 43059243Sobrien else 431167465Smp setv(vp, p, VAR_READWRITE); 432167465Smp cleanup_ignore(p); 43359243Sobrien } 43459243Sobrien else if (hadsub) { 43559243Sobrien struct varent *gv = getvx(vp, subscr); 436167465Smp Char *val; 43759243Sobrien 438167465Smp val = operate(op, gv->vec[subscr - 1], p); 439167465Smp cleanup_push(val, xfree); 440167465Smp asx(vp, subscr, val); 441167465Smp cleanup_ignore(val); 442167465Smp cleanup_until(val); 44359243Sobrien } 444167465Smp else { 445167465Smp Char *val; 446167465Smp 447167465Smp val = operate(op, varval(vp), p); 448167465Smp cleanup_push(val, xfree); 449167465Smp setv(vp, val, VAR_READWRITE); 450167465Smp cleanup_ignore(val); 451167465Smp cleanup_until(val); 452167465Smp } 45359243Sobrien update_vars(vp); 454167465Smp cleanup_until(vp); 45559243Sobrien } while ((p = *v++) != NULL); 45659243Sobrien} 45759243Sobrien 45859243Sobrienstatic Char * 459167465Smpxset(Char *cp, Char ***vp) 46059243Sobrien{ 461145479Smp Char *dp; 46259243Sobrien 46359243Sobrien if (*cp) { 46459243Sobrien dp = Strsave(cp); 46559243Sobrien --(*vp); 466167465Smp xfree(** vp); 46759243Sobrien **vp = dp; 46859243Sobrien } 46959243Sobrien return (putn(expr(vp))); 47059243Sobrien} 47159243Sobrien 47259243Sobrienstatic Char * 473167465Smpoperate(int op, Char *vp, Char *p) 47459243Sobrien{ 47559243Sobrien Char opr[2]; 47659243Sobrien Char *vec[5]; 477145479Smp Char **v = vec; 47859243Sobrien Char **vecp = v; 479145479Smp int i; 48059243Sobrien 48159243Sobrien if (op != '=') { 48259243Sobrien if (*vp) 48359243Sobrien *v++ = vp; 484167465Smp opr[0] = op; 48559243Sobrien opr[1] = 0; 48659243Sobrien *v++ = opr; 48759243Sobrien if (op == '<' || op == '>') 48859243Sobrien *v++ = opr; 48959243Sobrien } 49059243Sobrien *v++ = p; 49159243Sobrien *v++ = 0; 49259243Sobrien i = expr(&vecp); 49359243Sobrien if (*vecp) 49459243Sobrien stderror(ERR_NAME | ERR_EXPRESSION); 49559243Sobrien return (putn(i)); 49659243Sobrien} 49759243Sobrien 498167465Smpstatic Char *putp; 49959243Sobrien 50059243SobrienChar * 501167465Smpputn(int n) 50259243Sobrien{ 503167465Smp Char nbuf[(CHAR_BIT * sizeof (n) + 2) / 3 + 2]; /* Enough even for octal */ 50459243Sobrien 50559243Sobrien putp = nbuf; 50659243Sobrien if (n < 0) { 50759243Sobrien n = -n; 50859243Sobrien *putp++ = '-'; 50959243Sobrien } 51059243Sobrien putn1(n); 51159243Sobrien *putp = 0; 51259243Sobrien return (Strsave(nbuf)); 51359243Sobrien} 51459243Sobrien 51559243Sobrienstatic void 516167465Smpputn1(unsigned n) 51759243Sobrien{ 51859243Sobrien if (n > 9) 51959243Sobrien putn1(n / 10); 52059243Sobrien *putp++ = n % 10 + '0'; 52159243Sobrien} 52259243Sobrien 52359243Sobrienint 524167465Smpgetn(Char *cp) 52559243Sobrien{ 526145479Smp int n; 52759243Sobrien int sign; 52859243Sobrien 52959243Sobrien if (!cp) /* PWP: extra error checking */ 53059243Sobrien stderror(ERR_NAME | ERR_BADNUM); 53159243Sobrien 53259243Sobrien sign = 0; 53359243Sobrien if (cp[0] == '+' && cp[1]) 53459243Sobrien cp++; 53559243Sobrien if (*cp == '-') { 53659243Sobrien sign++; 53759243Sobrien cp++; 53859243Sobrien if (!Isdigit(*cp)) 53959243Sobrien stderror(ERR_NAME | ERR_BADNUM); 54059243Sobrien } 54159243Sobrien n = 0; 54259243Sobrien while (Isdigit(*cp)) 54359243Sobrien n = n * 10 + *cp++ - '0'; 54459243Sobrien if (*cp) 54559243Sobrien stderror(ERR_NAME | ERR_BADNUM); 54659243Sobrien return (sign ? -n : n); 54759243Sobrien} 54859243Sobrien 54959243SobrienChar * 550167465Smpvalue1(Char *var, struct varent *head) 55159243Sobrien{ 552145479Smp struct varent *vp; 55359243Sobrien 55459243Sobrien if (!var || !head) /* PWP: extra error checking */ 55559243Sobrien return (STRNULL); 55659243Sobrien 55759243Sobrien vp = adrof1(var, head); 558100616Smp return ((vp == NULL || vp->vec == NULL || vp->vec[0] == NULL) ? 559100616Smp STRNULL : vp->vec[0]); 56059243Sobrien} 56159243Sobrien 56259243Sobrienstatic struct varent * 563167465Smpmadrof(Char *pat, struct varent *vp) 56459243Sobrien{ 565145479Smp struct varent *vp1; 56659243Sobrien 56759243Sobrien for (vp = vp->v_left; vp; vp = vp->v_right) { 56859243Sobrien if (vp->v_left && (vp1 = madrof(pat, vp)) != NULL) 56959243Sobrien return vp1; 57059243Sobrien if (Gmatch(vp->v_name, pat)) 57159243Sobrien return vp; 57259243Sobrien } 57359243Sobrien return vp; 57459243Sobrien} 57559243Sobrien 57659243Sobrienstruct varent * 577167465Smpadrof1(const Char *name, struct varent *v) 57859243Sobrien{ 57959243Sobrien int cmp; 58059243Sobrien 58159243Sobrien v = v->v_left; 58259243Sobrien while (v && ((cmp = *name - *v->v_name) != 0 || 58359243Sobrien (cmp = Strcmp(name, v->v_name)) != 0)) 58459243Sobrien if (cmp < 0) 58559243Sobrien v = v->v_left; 58659243Sobrien else 58759243Sobrien v = v->v_right; 58859243Sobrien return v; 58959243Sobrien} 59059243Sobrien 591167465Smpvoid 592167465Smpsetcopy(const Char *var, const Char *val, int flags) 593167465Smp{ 594167465Smp Char *copy; 595167465Smp 596167465Smp copy = Strsave(val); 597167465Smp cleanup_push(copy, xfree); 598167465Smp setv(var, copy, flags); 599167465Smp cleanup_ignore(copy); 600167465Smp cleanup_until(copy); 601167465Smp} 602167465Smp 60359243Sobrien/* 60459243Sobrien * The caller is responsible for putting value in a safe place 60559243Sobrien */ 60659243Sobrienvoid 607167465Smpsetv(const Char *var, Char *val, int flags) 60859243Sobrien{ 609167465Smp Char **vec = xmalloc(2 * sizeof(Char **)); 61059243Sobrien 61159243Sobrien vec[0] = val; 61259243Sobrien vec[1] = 0; 61359243Sobrien set1(var, vec, &shvhed, flags); 61459243Sobrien} 61559243Sobrien 61659243Sobrienvoid 617167465Smpset1(const Char *var, Char **vec, struct varent *head, int flags) 61859243Sobrien{ 619145479Smp Char **oldv = vec; 62059243Sobrien 62159243Sobrien if ((flags & VAR_NOGLOB) == 0) { 622167465Smp int gflag; 623167465Smp 624167465Smp gflag = tglob(oldv); 62559243Sobrien if (gflag) { 626167465Smp vec = globall(oldv, gflag); 62759243Sobrien if (vec == 0) { 62859243Sobrien blkfree(oldv); 62959243Sobrien stderror(ERR_NAME | ERR_NOMATCH); 63059243Sobrien } 63159243Sobrien blkfree(oldv); 63259243Sobrien } 63359243Sobrien } 63459243Sobrien /* 63559243Sobrien * Uniqueness addition from: Michael Veksler <mveksler@vnet.ibm.com> 63659243Sobrien */ 63759243Sobrien if ( flags & (VAR_FIRST | VAR_LAST) ) { 63859243Sobrien /* 63959243Sobrien * Code for -f (VAR_FIRST) and -l (VAR_LAST) options. 64059243Sobrien * Method: 64159243Sobrien * Delete all duplicate words leaving "holes" in the word array (vec). 64259243Sobrien * Then remove the "holes", keeping the order of the words unchanged. 64359243Sobrien */ 64459243Sobrien if (vec && vec[0] && vec[1]) { /* more than one word ? */ 64559243Sobrien int i, j; 64659243Sobrien int num_items; 64759243Sobrien 64859243Sobrien for (num_items = 0; vec[num_items]; num_items++) 64959243Sobrien continue; 65059243Sobrien if (flags & VAR_FIRST) { 65159243Sobrien /* delete duplications, keeping first occurance */ 65259243Sobrien for (i = 1; i < num_items; i++) 65359243Sobrien for (j = 0; j < i; j++) 65459243Sobrien /* If have earlier identical item, remove i'th item */ 65559243Sobrien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { 656167465Smp xfree(vec[i]); 65759243Sobrien vec[i] = NULL; 65859243Sobrien break; 65959243Sobrien } 66059243Sobrien } else if (flags & VAR_LAST) { 66159243Sobrien /* delete duplications, keeping last occurance */ 66259243Sobrien for (i = 0; i < num_items - 1; i++) 66359243Sobrien for (j = i + 1; j < num_items; j++) 66459243Sobrien /* If have later identical item, remove i'th item */ 66559243Sobrien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { 66659243Sobrien /* remove identical item (the first) */ 667167465Smp xfree(vec[i]); 66859243Sobrien vec[i] = NULL; 66959243Sobrien } 67059243Sobrien } 67159243Sobrien /* Compress items - remove empty items */ 67259243Sobrien for (j = i = 0; i < num_items; i++) 67359243Sobrien if (vec[i]) 67459243Sobrien vec[j++] = vec[i]; 67559243Sobrien 67659243Sobrien /* NULL-fy remaining items */ 67759243Sobrien for (; j < num_items; j++) 67859243Sobrien vec[j] = NULL; 67959243Sobrien } 68059243Sobrien /* don't let the attribute propagate */ 68159243Sobrien flags &= ~(VAR_FIRST|VAR_LAST); 68259243Sobrien } 68359243Sobrien setq(var, vec, head, flags); 68459243Sobrien} 68559243Sobrien 68659243Sobrien 68759243Sobrienvoid 688167465Smpsetq(const Char *name, Char **vec, struct varent *p, int flags) 68959243Sobrien{ 690145479Smp struct varent *c; 691145479Smp int f; 69259243Sobrien 69359243Sobrien f = 0; /* tree hangs off the header's left link */ 69459243Sobrien while ((c = p->v_link[f]) != 0) { 69559243Sobrien if ((f = *name - *c->v_name) == 0 && 69659243Sobrien (f = Strcmp(name, c->v_name)) == 0) { 69759243Sobrien if (c->v_flags & VAR_READONLY) 69859243Sobrien stderror(ERR_READONLY|ERR_NAME, c->v_name); 69959243Sobrien blkfree(c->vec); 70059243Sobrien c->v_flags = flags; 70159243Sobrien trim(c->vec = vec); 70259243Sobrien return; 70359243Sobrien } 70459243Sobrien p = c; 70559243Sobrien f = f > 0; 70659243Sobrien } 707167465Smp p->v_link[f] = c = xmalloc(sizeof(struct varent)); 70859243Sobrien c->v_name = Strsave(name); 70959243Sobrien c->v_flags = flags; 71059243Sobrien c->v_bal = 0; 71159243Sobrien c->v_left = c->v_right = 0; 71259243Sobrien c->v_parent = p; 71359243Sobrien balance(p, f, 0); 71459243Sobrien trim(c->vec = vec); 71559243Sobrien} 71659243Sobrien 71759243Sobrien/*ARGSUSED*/ 71859243Sobrienvoid 719167465Smpunset(Char **v, struct command *c) 72059243Sobrien{ 721145479Smp int did_roe, did_edit; 72259243Sobrien 72359243Sobrien USE(c); 72459243Sobrien did_roe = adrof(STRrecognize_only_executables) != NULL; 72559243Sobrien did_edit = adrof(STRedit) != NULL; 72659243Sobrien unset1(v, &shvhed); 727100616Smp 728100616Smp#if defined(FILEC) && defined(TIOCSTI) 729100616Smp if (adrof(STRfilec) == 0) 730100616Smp filec = 0; 731100616Smp#endif /* FILEC && TIOCSTI */ 732100616Smp 73359243Sobrien if (adrof(STRhistchars) == 0) { 73459243Sobrien HIST = '!'; 73559243Sobrien HISTSUB = '^'; 73659243Sobrien } 737131962Smp if (adrof(STRignoreeof) == 0) 738131962Smp numeof = 0; 73959243Sobrien if (adrof(STRpromptchars) == 0) { 74059243Sobrien PRCH = '>'; 74159243Sobrien PRCHROOT = '#'; 74259243Sobrien } 74359243Sobrien if (adrof(STRhistlit) == 0) 74459243Sobrien HistLit = 0; 74559243Sobrien if (adrof(STRloginsh) == 0) 74659243Sobrien loginsh = 0; 74759243Sobrien if (adrof(STRwordchars) == 0) 74859243Sobrien word_chars = STR_WORD_CHARS; 74959243Sobrien if (adrof(STRedit) == 0) 75059243Sobrien editing = 0; 75159243Sobrien if (adrof(STRbackslash_quote) == 0) 75259243Sobrien bslash_quote = 0; 75359243Sobrien if (adrof(STRsymlinks) == 0) 75459243Sobrien symlinks = 0; 75559243Sobrien if (adrof(STRimplicitcd) == 0) 75659243Sobrien implicit_cd = 0; 75783098Smp if (adrof(STRkillring) == 0) 75883098Smp SetKillRing(0); 75959243Sobrien if (did_edit && noediting && adrof(STRedit) == 0) 76059243Sobrien noediting = 0; 76159243Sobrien if (did_roe && adrof(STRrecognize_only_executables) == 0) 76259243Sobrien tw_cmd_free(); 76359243Sobrien#ifdef COLOR_LS_F 76459243Sobrien if (adrof(STRcolor) == 0) 76559243Sobrien set_color_context(); 76659243Sobrien#endif /* COLOR_LS_F */ 76759243Sobrien#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 76859243Sobrien update_dspmbyte_vars(); 76959243Sobrien#endif 77069408Sache#ifdef NLS_CATALOGS 771145479Smp nlsclose(); 77269408Sache nlsinit(); 77369408Sache#endif /* NLS_CATALOGS */ 77459243Sobrien} 77559243Sobrien 77659243Sobrienvoid 777167465Smpunset1(Char *v[], struct varent *head) 77859243Sobrien{ 779145479Smp struct varent *vp; 780145479Smp int cnt; 78159243Sobrien 78259243Sobrien while (*++v) { 78359243Sobrien cnt = 0; 78459243Sobrien while ((vp = madrof(*v, head)) != NULL) 78559243Sobrien if (vp->v_flags & VAR_READONLY) 78659243Sobrien stderror(ERR_READONLY|ERR_NAME, vp->v_name); 78759243Sobrien else 78859243Sobrien unsetv1(vp), cnt++; 78959243Sobrien if (cnt == 0) 79059243Sobrien setname(short2str(*v)); 79159243Sobrien } 79259243Sobrien} 79359243Sobrien 79459243Sobrienvoid 795167465Smpunsetv(Char *var) 79659243Sobrien{ 797145479Smp struct varent *vp; 79859243Sobrien 79959243Sobrien if ((vp = adrof1(var, &shvhed)) == 0) 80059243Sobrien udvar(var); 80159243Sobrien unsetv1(vp); 80259243Sobrien} 80359243Sobrien 80459243Sobrienstatic void 805167465Smpunsetv1(struct varent *p) 80659243Sobrien{ 807145479Smp struct varent *c, *pp; 808145479Smp int f; 80959243Sobrien 81059243Sobrien /* 81159243Sobrien * Free associated memory first to avoid complications. 81259243Sobrien */ 81359243Sobrien blkfree(p->vec); 814167465Smp xfree(p->v_name); 81559243Sobrien /* 81659243Sobrien * If p is missing one child, then we can move the other into where p is. 81759243Sobrien * Otherwise, we find the predecessor of p, which is guaranteed to have no 81859243Sobrien * right child, copy it into p, and move it's left child into it. 81959243Sobrien */ 82059243Sobrien if (p->v_right == 0) 82159243Sobrien c = p->v_left; 82259243Sobrien else if (p->v_left == 0) 82359243Sobrien c = p->v_right; 82459243Sobrien else { 82559243Sobrien for (c = p->v_left; c->v_right; c = c->v_right) 82659243Sobrien continue; 82759243Sobrien p->v_name = c->v_name; 82859243Sobrien p->v_flags = c->v_flags; 82959243Sobrien p->vec = c->vec; 83059243Sobrien p = c; 83159243Sobrien c = p->v_left; 83259243Sobrien } 83359243Sobrien 83459243Sobrien /* 83559243Sobrien * Move c into where p is. 83659243Sobrien */ 83759243Sobrien pp = p->v_parent; 83859243Sobrien f = pp->v_right == p; 83959243Sobrien if ((pp->v_link[f] = c) != 0) 84059243Sobrien c->v_parent = pp; 84159243Sobrien /* 84259243Sobrien * Free the deleted node, and rebalance. 84359243Sobrien */ 844167465Smp xfree(p); 84559243Sobrien balance(pp, f, 1); 84659243Sobrien} 84759243Sobrien 84859243Sobrienvoid 849167465SmpsetNS(Char *cp) 85059243Sobrien{ 851167465Smp setcopy(cp, STRNULL, VAR_READWRITE); 85259243Sobrien} 85359243Sobrien 85459243Sobrien/*ARGSUSED*/ 85559243Sobrienvoid 856167465Smpshift(Char **v, struct command *c) 85759243Sobrien{ 858145479Smp struct varent *argv; 859145479Smp Char *name; 86059243Sobrien 86159243Sobrien USE(c); 86259243Sobrien v++; 86359243Sobrien name = *v; 86459243Sobrien if (name == 0) 86559243Sobrien name = STRargv; 86659243Sobrien else 86759243Sobrien (void) strip(name); 86859243Sobrien argv = adrof(name); 869100616Smp if (argv == NULL || argv->vec == NULL) 87059243Sobrien udvar(name); 87159243Sobrien if (argv->vec[0] == 0) 87259243Sobrien stderror(ERR_NAME | ERR_NOMORE); 87359243Sobrien lshift(argv->vec, 1); 87459243Sobrien update_vars(name); 87559243Sobrien} 87659243Sobrien 87759243Sobrienstatic void 878167465Smpexportpath(Char **val) 87959243Sobrien{ 880167465Smp struct Strbuf buf = Strbuf_INIT; 881167465Smp Char *exppath; 88259243Sobrien 88359243Sobrien if (val) 88459243Sobrien while (*val) { 885167465Smp Strbuf_append(&buf, *val++); 886167465Smp if (*val == 0 || eq(*val, STRRparen)) 88759243Sobrien break; 888167465Smp Strbuf_append1(&buf, PATHSEP); 889167465Smp } 890167465Smp exppath = Strbuf_finish(&buf); 891167465Smp cleanup_push(exppath, xfree); 892167465Smp tsetenv(STRKPATH, exppath); 893167465Smp cleanup_until(exppath); 89459243Sobrien} 89559243Sobrien 89659243Sobrien#ifndef lint 89759243Sobrien /* 89859243Sobrien * Lint thinks these have null effect 89959243Sobrien */ 90059243Sobrien /* macros to do single rotations on node p */ 90159243Sobrien# define rright(p) (\ 90259243Sobrien t = (p)->v_left,\ 90359243Sobrien (t)->v_parent = (p)->v_parent,\ 90459243Sobrien (((p)->v_left = t->v_right) != NULL) ?\ 90559243Sobrien (t->v_right->v_parent = (p)) : 0,\ 90659243Sobrien (t->v_right = (p))->v_parent = t,\ 90759243Sobrien (p) = t) 90859243Sobrien# define rleft(p) (\ 90959243Sobrien t = (p)->v_right,\ 91059243Sobrien ((t)->v_parent = (p)->v_parent,\ 91159243Sobrien ((p)->v_right = t->v_left) != NULL) ? \ 91259243Sobrien (t->v_left->v_parent = (p)) : 0,\ 91359243Sobrien (t->v_left = (p))->v_parent = t,\ 91459243Sobrien (p) = t) 91559243Sobrien#else 91659243Sobrienstatic struct varent * 917167465Smprleft(struct varent *p) 91859243Sobrien{ 91959243Sobrien return (p); 92059243Sobrien} 92159243Sobrienstatic struct varent * 922167465Smprright(struct varent *p) 92359243Sobrien{ 92459243Sobrien return (p); 92559243Sobrien} 92659243Sobrien 92759243Sobrien#endif /* ! lint */ 92859243Sobrien 92959243Sobrien 93059243Sobrien/* 93159243Sobrien * Rebalance a tree, starting at p and up. 93259243Sobrien * F == 0 means we've come from p's left child. 93359243Sobrien * D == 1 means we've just done a delete, otherwise an insert. 93459243Sobrien */ 93559243Sobrienstatic void 936167465Smpbalance(struct varent *p, int f, int d) 93759243Sobrien{ 938145479Smp struct varent *pp; 93959243Sobrien 94059243Sobrien#ifndef lint 941145479Smp struct varent *t; /* used by the rotate macros */ 94259243Sobrien#endif /* !lint */ 943145479Smp int ff; 94459243Sobrien#ifdef lint 94559243Sobrien ff = 0; /* Sun's lint is dumb! */ 94659243Sobrien#endif 94759243Sobrien 94859243Sobrien /* 94959243Sobrien * Ok, from here on, p is the node we're operating on; pp is it's parent; f 95059243Sobrien * is the branch of p from which we have come; ff is the branch of pp which 95159243Sobrien * is p. 95259243Sobrien */ 95359243Sobrien for (; (pp = p->v_parent) != 0; p = pp, f = ff) { 95459243Sobrien ff = pp->v_right == p; 95559243Sobrien if (f ^ d) { /* right heavy */ 95659243Sobrien switch (p->v_bal) { 95759243Sobrien case -1: /* was left heavy */ 95859243Sobrien p->v_bal = 0; 95959243Sobrien break; 96059243Sobrien case 0: /* was balanced */ 96159243Sobrien p->v_bal = 1; 96259243Sobrien break; 96359243Sobrien case 1: /* was already right heavy */ 96459243Sobrien switch (p->v_right->v_bal) { 965167465Smp case 1: /* single rotate */ 96659243Sobrien pp->v_link[ff] = rleft(p); 96759243Sobrien p->v_left->v_bal = 0; 96859243Sobrien p->v_bal = 0; 96959243Sobrien break; 97059243Sobrien case 0: /* single rotate */ 97159243Sobrien pp->v_link[ff] = rleft(p); 97259243Sobrien p->v_left->v_bal = 1; 97359243Sobrien p->v_bal = -1; 97459243Sobrien break; 97559243Sobrien case -1: /* double rotate */ 97659243Sobrien (void) rright(p->v_right); 97759243Sobrien pp->v_link[ff] = rleft(p); 97859243Sobrien p->v_left->v_bal = 97959243Sobrien p->v_bal < 1 ? 0 : -1; 98059243Sobrien p->v_right->v_bal = 98159243Sobrien p->v_bal > -1 ? 0 : 1; 98259243Sobrien p->v_bal = 0; 98359243Sobrien break; 98459243Sobrien default: 98559243Sobrien break; 98659243Sobrien } 98759243Sobrien break; 98859243Sobrien default: 98959243Sobrien break; 99059243Sobrien } 99159243Sobrien } 99259243Sobrien else { /* left heavy */ 99359243Sobrien switch (p->v_bal) { 99459243Sobrien case 1: /* was right heavy */ 99559243Sobrien p->v_bal = 0; 99659243Sobrien break; 99759243Sobrien case 0: /* was balanced */ 99859243Sobrien p->v_bal = -1; 99959243Sobrien break; 100059243Sobrien case -1: /* was already left heavy */ 100159243Sobrien switch (p->v_left->v_bal) { 100259243Sobrien case -1: /* single rotate */ 100359243Sobrien pp->v_link[ff] = rright(p); 100459243Sobrien p->v_right->v_bal = 0; 100559243Sobrien p->v_bal = 0; 100659243Sobrien break; 1007167465Smp case 0: /* single rotate */ 100859243Sobrien pp->v_link[ff] = rright(p); 100959243Sobrien p->v_right->v_bal = -1; 101059243Sobrien p->v_bal = 1; 101159243Sobrien break; 101259243Sobrien case 1: /* double rotate */ 101359243Sobrien (void) rleft(p->v_left); 101459243Sobrien pp->v_link[ff] = rright(p); 101559243Sobrien p->v_left->v_bal = 101659243Sobrien p->v_bal < 1 ? 0 : -1; 101759243Sobrien p->v_right->v_bal = 101859243Sobrien p->v_bal > -1 ? 0 : 1; 101959243Sobrien p->v_bal = 0; 102059243Sobrien break; 102159243Sobrien default: 102259243Sobrien break; 102359243Sobrien } 102459243Sobrien break; 102559243Sobrien default: 102659243Sobrien break; 102759243Sobrien } 102859243Sobrien } 102959243Sobrien /* 103059243Sobrien * If from insert, then we terminate when p is balanced. If from 103159243Sobrien * delete, then we terminate when p is unbalanced. 103259243Sobrien */ 103359243Sobrien if ((p->v_bal == 0) ^ d) 103459243Sobrien break; 103559243Sobrien } 103659243Sobrien} 103759243Sobrien 103859243Sobrienvoid 1039167465Smpplist(struct varent *p, int what) 104059243Sobrien{ 1041145479Smp struct varent *c; 1042145479Smp int len; 104359243Sobrien 104459243Sobrien for (;;) { 104559243Sobrien while (p->v_left) 104659243Sobrien p = p->v_left; 104759243Sobrienx: 104859243Sobrien if (p->v_parent == 0) /* is it the header? */ 1049167465Smp break; 105059243Sobrien if ((p->v_flags & what) != 0) { 1051167465Smp if (setintr) { 1052167465Smp int old_pintr_disabled; 1053167465Smp 1054167465Smp pintr_push_enable(&old_pintr_disabled); 1055167465Smp cleanup_until(&old_pintr_disabled); 1056167465Smp } 105759243Sobrien len = blklen(p->vec); 105859243Sobrien xprintf("%S\t", p->v_name); 105959243Sobrien if (len != 1) 106059243Sobrien xputchar('('); 106159243Sobrien blkpr(p->vec); 106259243Sobrien if (len != 1) 106359243Sobrien xputchar(')'); 106459243Sobrien xputchar('\n'); 106559243Sobrien } 106659243Sobrien if (p->v_right) { 106759243Sobrien p = p->v_right; 106859243Sobrien continue; 106959243Sobrien } 107059243Sobrien do { 107159243Sobrien c = p; 107259243Sobrien p = p->v_parent; 107359243Sobrien } while (p->v_right == c); 107459243Sobrien goto x; 107559243Sobrien } 107659243Sobrien} 107759243Sobrien 107859243Sobrien#if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 1079145479Smpextern int dspmbyte_ls; 108059243Sobrien 108159243Sobrienvoid 1082167465Smpupdate_dspmbyte_vars(void) 108359243Sobrien{ 108459243Sobrien int lp, iskcode; 108559243Sobrien Char *dstr1; 108659243Sobrien struct varent *vp; 108759243Sobrien 108859243Sobrien /* if variable "nokanji" is set, multi-byte display is disabled */ 108959243Sobrien if ((vp = adrof(CHECK_MBYTEVAR)) && !adrof(STRnokanji)) { 109059243Sobrien _enable_mbdisp = 1; 109159243Sobrien dstr1 = vp->vec[0]; 1092145479Smp if(eq (dstr1, STRsjis)) 109359243Sobrien iskcode = 1; 1094145479Smp else if (eq(dstr1, STReuc)) 109559243Sobrien iskcode = 2; 1096145479Smp else if (eq(dstr1, STRbig5)) 109783098Smp iskcode = 3; 1098145479Smp else if (eq(dstr1, STRutf8)) 1099100616Smp iskcode = 4; 110059243Sobrien else if ((dstr1[0] - '0') >= 0 && (dstr1[0] - '0') <= 3) { 110159243Sobrien iskcode = 0; 110259243Sobrien } 110359243Sobrien else { 110459243Sobrien xprintf(CGETS(18, 2, 110559243Sobrien "Warning: unknown multibyte display; using default(euc(JP))\n")); 110659243Sobrien iskcode = 2; 110759243Sobrien } 110859243Sobrien if (dstr1 && vp->vec[1] && eq(vp->vec[1], STRls)) 110959243Sobrien dspmbyte_ls = 1; 111059243Sobrien else 111159243Sobrien dspmbyte_ls = 0; 111259243Sobrien for (lp = 0; lp < 256 && iskcode > 0; lp++) { 111359243Sobrien switch (iskcode) { 111459243Sobrien case 1: 111559243Sobrien /* Shift-JIS */ 111659243Sobrien _cmap[lp] = _cmap_mbyte[lp]; 111759243Sobrien _mbmap[lp] = _mbmap_sjis[lp]; 111859243Sobrien break; 111959243Sobrien case 2: 112059243Sobrien /* 2 ... euc */ 112159243Sobrien _cmap[lp] = _cmap_mbyte[lp]; 112259243Sobrien _mbmap[lp] = _mbmap_euc[lp]; 112359243Sobrien break; 112483098Smp case 3: 112583098Smp /* 3 ... big5 */ 112683098Smp _cmap[lp] = _cmap_mbyte[lp]; 112783098Smp _mbmap[lp] = _mbmap_big5[lp]; 112883098Smp break; 1129100616Smp case 4: 1130100616Smp /* 4 ... utf8 */ 1131100616Smp _cmap[lp] = _cmap_mbyte[lp]; 1132100616Smp _mbmap[lp] = _mbmap_utf8[lp]; 1133100616Smp break; 113459243Sobrien default: 113559243Sobrien xprintf(CGETS(18, 3, 113659243Sobrien "Warning: unknown multibyte code %d; multibyte disabled\n"), 113759243Sobrien iskcode); 113859243Sobrien _cmap[lp] = _cmap_c[lp]; 113959243Sobrien _mbmap[lp] = 0; /* Default map all 0 */ 114059243Sobrien _enable_mbdisp = 0; 114159243Sobrien break; 114259243Sobrien } 114359243Sobrien } 114459243Sobrien if (iskcode == 0) { 114559243Sobrien /* check original table */ 114659243Sobrien if (Strlen(dstr1) != 256) { 114759243Sobrien xprintf(CGETS(18, 4, 114859243Sobrien "Warning: Invalid multibyte table length (%d); multibyte disabled\n"), 114959243Sobrien Strlen(dstr1)); 115059243Sobrien _enable_mbdisp = 0; 115159243Sobrien } 115259243Sobrien for (lp = 0; lp < 256 && _enable_mbdisp == 1; lp++) { 115359243Sobrien if (!((dstr1[lp] - '0') >= 0 && (dstr1[lp] - '0') <= 3)) { 115459243Sobrien xprintf(CGETS(18, 4, 115559243Sobrien "Warning: bad multibyte code at offset +%d; multibyte diabled\n"), 115659243Sobrien lp); 115759243Sobrien _enable_mbdisp = 0; 115859243Sobrien break; 115959243Sobrien } 116059243Sobrien } 116159243Sobrien /* set original table */ 116259243Sobrien for (lp = 0; lp < 256; lp++) { 116359243Sobrien if (_enable_mbdisp == 1) { 116459243Sobrien _cmap[lp] = _cmap_mbyte[lp]; 116559243Sobrien _mbmap[lp] = (unsigned short) ((dstr1[lp] - '0') & 0x0f); 116659243Sobrien } 116759243Sobrien else { 116859243Sobrien _cmap[lp] = _cmap_c[lp]; 116959243Sobrien _mbmap[lp] = 0; /* Default map all 0 */ 117059243Sobrien } 117159243Sobrien } 117259243Sobrien } 117359243Sobrien } 117459243Sobrien else { 117559243Sobrien for (lp = 0; lp < 256; lp++) { 117659243Sobrien _cmap[lp] = _cmap_c[lp]; 117759243Sobrien _mbmap[lp] = 0; /* Default map all 0 */ 117859243Sobrien } 117959243Sobrien _enable_mbdisp = 0; 118059243Sobrien dspmbyte_ls = 0; 118159243Sobrien } 118259243Sobrien#ifdef MBYTEDEBUG /* Sorry, use for beta testing */ 118359243Sobrien { 118459243Sobrien Char mbmapstr[300]; 1185167465Smp for (lp = 0; lp < 256; lp++) 118659243Sobrien mbmapstr[lp] = _mbmap[lp] + '0'; 1187167465Smp mbmapstr[lp] = 0; 1188167465Smp setcopy(STRmbytemap, mbmapstr, VAR_READWRITE); 118959243Sobrien } 119059243Sobrien#endif /* MBYTEMAP */ 119159243Sobrien} 119259243Sobrien 119359243Sobrien/* dspkanji/dspmbyte autosetting */ 119459243Sobrien/* PATCH IDEA FROM Issei.Suzuki VERY THANKS */ 119559243Sobrienvoid 1196167465Smpautoset_dspmbyte(const Char *pcp) 119759243Sobrien{ 119859243Sobrien int i; 1199167465Smp static const struct dspm_autoset_Table { 120059243Sobrien Char *n; 120159243Sobrien Char *v; 120259243Sobrien } dspmt[] = { 1203145479Smp { STRLANGEUCJP, STReuc }, 1204145479Smp { STRLANGEUCKR, STReuc }, 1205145479Smp { STRLANGEUCZH, STReuc }, 1206145479Smp { STRLANGEUCJPB, STReuc }, 1207145479Smp { STRLANGEUCKRB, STReuc }, 1208145479Smp { STRLANGEUCZHB, STReuc }, 1209131962Smp#ifdef linux 1210145479Smp { STRLANGEUCJPC, STReuc }, 1211131962Smp#endif 1212145479Smp { STRLANGSJIS, STRsjis }, 1213145479Smp { STRLANGSJISB, STRsjis }, 1214145479Smp { STRLANGBIG5, STRbig5 }, 1215145479Smp { STRstarutfstar8, STRutf8 }, 121659243Sobrien { NULL, NULL } 121759243Sobrien }; 1218167465Smp#if defined(HAVE_NL_LANGINFO) && defined(CODESET) 1219167465Smp static const struct dspm_autoset_Table dspmc[] = { 1220145479Smp { STRstarutfstar8, STRutf8 }, 1221145479Smp { STReuc, STReuc }, 1222145479Smp { STRGB2312, STReuc }, 1223145479Smp { STRLANGBIG5, STRbig5 }, 1224145479Smp { NULL, NULL } 1225145479Smp }; 1226145479Smp Char *codeset; 122759243Sobrien 1228145479Smp codeset = str2short(nl_langinfo(CODESET)); 1229145479Smp if (*codeset != '\0') { 1230145479Smp for (i = 0; dspmc[i].n; i++) { 1231167465Smp const Char *estr; 1232145479Smp if (dspmc[i].n[0] && t_pmatch(pcp, dspmc[i].n, &estr, 0) > 0) { 1233167465Smp setcopy(CHECK_MBYTEVAR, dspmc[i].v, VAR_READWRITE); 1234145479Smp update_dspmbyte_vars(); 1235145479Smp return; 1236145479Smp } 1237145479Smp } 1238145479Smp } 1239145479Smp#endif 1240145479Smp 124159243Sobrien if (*pcp == '\0') 124259243Sobrien return; 124359243Sobrien 124459243Sobrien for (i = 0; dspmt[i].n; i++) { 1245167465Smp const Char *estr; 1246145479Smp if (dspmt[i].n[0] && t_pmatch(pcp, dspmt[i].n, &estr, 0) > 0) { 1247167465Smp setcopy(CHECK_MBYTEVAR, dspmt[i].v, VAR_READWRITE); 124859243Sobrien update_dspmbyte_vars(); 124959243Sobrien break; 125059243Sobrien } 125159243Sobrien } 125259243Sobrien} 125359243Sobrien#endif 1254