1*19d2e3deSDmitry Chagin /* $Header: /p/tcsh/cvsroot/tcsh/sh.set.c,v 3.89 2015/09/08 15:49:53 christos Exp $ */ 2c80476e4SDavid E. O'Brien /* 3c80476e4SDavid E. O'Brien * sh.set.c: Setting and Clearing of variables 4c80476e4SDavid E. O'Brien */ 5c80476e4SDavid E. O'Brien /*- 6c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California. 7c80476e4SDavid E. O'Brien * All rights reserved. 8c80476e4SDavid E. O'Brien * 9c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 10c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions 11c80476e4SDavid E. O'Brien * are met: 12c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 13c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 14c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 15c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 16c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 1729301572SMark Peek * 3. Neither the name of the University nor the names of its contributors 18c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software 19c80476e4SDavid E. O'Brien * without specific prior written permission. 20c80476e4SDavid E. O'Brien * 21c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31c80476e4SDavid E. O'Brien * SUCH DAMAGE. 32c80476e4SDavid E. O'Brien */ 33c80476e4SDavid E. O'Brien #include "sh.h" 34c80476e4SDavid E. O'Brien 35*19d2e3deSDmitry Chagin RCSID("$tcsh: sh.set.c,v 3.89 2015/09/08 15:49:53 christos Exp $") 36c80476e4SDavid E. O'Brien 37c80476e4SDavid E. O'Brien #include "ed.h" 38c80476e4SDavid E. O'Brien #include "tw.h" 39c80476e4SDavid E. O'Brien 4023338178SMark Peek #ifdef HAVE_NL_LANGINFO 4123338178SMark Peek #include <langinfo.h> 4223338178SMark Peek #endif 4323338178SMark Peek 4423338178SMark Peek extern int GotTermCaps; 45b2d5d167SMark Peek int numeof = 0; 46c80476e4SDavid E. O'Brien 4745e5710bSMark Peek static void update_vars (Char *); 4845e5710bSMark Peek static Char *getinx (Char *, int *); 4945e5710bSMark Peek static void asx (Char *, int, Char *); 5045e5710bSMark Peek static struct varent *getvx (Char *, int); 5145e5710bSMark Peek static Char *xset (Char *, Char ***); 5245e5710bSMark Peek static Char *operate (int, Char *, Char *); 539ccc37e3SMark Peek static void putn1 (tcsh_number_t); 5445e5710bSMark Peek static struct varent *madrof (Char *, struct varent *); 5545e5710bSMark Peek static void unsetv1 (struct varent *); 5645e5710bSMark Peek static void exportpath (Char **); 5745e5710bSMark Peek static void balance (struct varent *, int, int); 58*19d2e3deSDmitry Chagin static int set_noclobber (Char **); 59c80476e4SDavid E. O'Brien 60c80476e4SDavid E. O'Brien /* 61c80476e4SDavid E. O'Brien * C Shell 62c80476e4SDavid E. O'Brien */ 63c80476e4SDavid E. O'Brien 64c80476e4SDavid E. O'Brien static void 6545e5710bSMark Peek update_vars(Char *vp) 66c80476e4SDavid E. O'Brien { 67c80476e4SDavid E. O'Brien if (eq(vp, STRpath)) { 6845e5710bSMark Peek struct varent *p = adrof(STRpath); 6945e5710bSMark Peek if (p == NULL) 7045e5710bSMark Peek stderror(ERR_NAME | ERR_UNDVAR); 7145e5710bSMark Peek else { 7245e5710bSMark Peek exportpath(p->vec); 73c80476e4SDavid E. O'Brien dohash(NULL, NULL); 74c80476e4SDavid E. O'Brien } 7545e5710bSMark Peek } 76*19d2e3deSDmitry Chagin else if (eq(vp, STRnoclobber)) { 77*19d2e3deSDmitry Chagin struct varent *p = adrof(STRnoclobber); 78*19d2e3deSDmitry Chagin if (p == NULL) 79*19d2e3deSDmitry Chagin stderror(ERR_NAME | ERR_UNDVAR); 80*19d2e3deSDmitry Chagin else 81*19d2e3deSDmitry Chagin no_clobber = set_noclobber(p->vec); 82*19d2e3deSDmitry Chagin } 83c80476e4SDavid E. O'Brien else if (eq(vp, STRhistchars)) { 8423338178SMark Peek Char *pn = varval(vp); 85c80476e4SDavid E. O'Brien 86c80476e4SDavid E. O'Brien HIST = *pn++; 879ccc37e3SMark Peek if (HIST) 88c80476e4SDavid E. O'Brien HISTSUB = *pn; 899ccc37e3SMark Peek else 909ccc37e3SMark Peek HISTSUB = HIST; 91c80476e4SDavid E. O'Brien } 92c80476e4SDavid E. O'Brien else if (eq(vp, STRpromptchars)) { 9323338178SMark Peek Char *pn = varval(vp); 94c80476e4SDavid E. O'Brien 95c80476e4SDavid E. O'Brien PRCH = *pn++; 969ccc37e3SMark Peek if (PRCH) 97c80476e4SDavid E. O'Brien PRCHROOT = *pn; 989ccc37e3SMark Peek else 999ccc37e3SMark Peek PRCHROOT = PRCH; 100c80476e4SDavid E. O'Brien } 101c80476e4SDavid E. O'Brien else if (eq(vp, STRhistlit)) { 102c80476e4SDavid E. O'Brien HistLit = 1; 103c80476e4SDavid E. O'Brien } 104c80476e4SDavid E. O'Brien else if (eq(vp, STRuser)) { 105c80476e4SDavid E. O'Brien tsetenv(STRKUSER, varval(vp)); 106c80476e4SDavid E. O'Brien tsetenv(STRLOGNAME, varval(vp)); 107c80476e4SDavid E. O'Brien } 108c80476e4SDavid E. O'Brien else if (eq(vp, STRgroup)) { 109c80476e4SDavid E. O'Brien tsetenv(STRKGROUP, varval(vp)); 110c80476e4SDavid E. O'Brien } 111c80476e4SDavid E. O'Brien else if (eq(vp, STRwordchars)) { 112c80476e4SDavid E. O'Brien word_chars = varval(vp); 113c80476e4SDavid E. O'Brien } 114c80476e4SDavid E. O'Brien else if (eq(vp, STRloginsh)) { 115c80476e4SDavid E. O'Brien loginsh = 1; 116c80476e4SDavid E. O'Brien } 1179ccc37e3SMark Peek else if (eq(vp, STRanyerror)) { 1189ccc37e3SMark Peek anyerror = 1; 1199ccc37e3SMark Peek } 120c80476e4SDavid E. O'Brien else if (eq(vp, STRsymlinks)) { 12123338178SMark Peek Char *pn = varval(vp); 122c80476e4SDavid E. O'Brien 123c80476e4SDavid E. O'Brien if (eq(pn, STRignore)) 124c80476e4SDavid E. O'Brien symlinks = SYM_IGNORE; 125c80476e4SDavid E. O'Brien else if (eq(pn, STRexpand)) 126c80476e4SDavid E. O'Brien symlinks = SYM_EXPAND; 127c80476e4SDavid E. O'Brien else if (eq(pn, STRchase)) 128c80476e4SDavid E. O'Brien symlinks = SYM_CHASE; 129c80476e4SDavid E. O'Brien else 130c80476e4SDavid E. O'Brien symlinks = 0; 131c80476e4SDavid E. O'Brien } 132c80476e4SDavid E. O'Brien else if (eq(vp, STRterm)) { 133c80476e4SDavid E. O'Brien Char *cp = varval(vp); 134c80476e4SDavid E. O'Brien tsetenv(STRKTERM, cp); 135c80476e4SDavid E. O'Brien #ifdef DOESNT_WORK_RIGHT 136c80476e4SDavid E. O'Brien cp = getenv("TERMCAP"); 137c80476e4SDavid E. O'Brien if (cp && (*cp != '/')) /* if TERMCAP and not a path */ 138c80476e4SDavid E. O'Brien Unsetenv(STRTERMCAP); 139c80476e4SDavid E. O'Brien #endif /* DOESNT_WORK_RIGHT */ 140c80476e4SDavid E. O'Brien GotTermCaps = 0; 141c80476e4SDavid E. O'Brien if (noediting && Strcmp(cp, STRnetwork) != 0 && 142c80476e4SDavid E. O'Brien Strcmp(cp, STRunknown) != 0 && Strcmp(cp, STRdumb) != 0) { 143c80476e4SDavid E. O'Brien editing = 1; 144c80476e4SDavid E. O'Brien noediting = 0; 14545e5710bSMark Peek setNS(STRedit); 146c80476e4SDavid E. O'Brien } 147c80476e4SDavid E. O'Brien ed_Init(); /* reset the editor */ 148c80476e4SDavid E. O'Brien } 149c80476e4SDavid E. O'Brien else if (eq(vp, STRhome)) { 15045e5710bSMark Peek Char *cp, *canon; 151c80476e4SDavid E. O'Brien 152c80476e4SDavid E. O'Brien cp = Strsave(varval(vp)); /* get the old value back */ 15345e5710bSMark Peek cleanup_push(cp, xfree); 154c80476e4SDavid E. O'Brien 155c80476e4SDavid E. O'Brien /* 156c80476e4SDavid E. O'Brien * convert to cononical pathname (possibly resolving symlinks) 157c80476e4SDavid E. O'Brien */ 15845e5710bSMark Peek canon = dcanon(cp, cp); 15945e5710bSMark Peek cleanup_ignore(cp); 16045e5710bSMark Peek cleanup_until(cp); 16145e5710bSMark Peek cleanup_push(canon, xfree); 162c80476e4SDavid E. O'Brien 16345e5710bSMark Peek setcopy(vp, canon, VAR_READWRITE); /* have to save the new val */ 164c80476e4SDavid E. O'Brien 165c80476e4SDavid E. O'Brien /* and now mirror home with HOME */ 16645e5710bSMark Peek tsetenv(STRKHOME, canon); 167c80476e4SDavid E. O'Brien /* fix directory stack for new tilde home */ 168c80476e4SDavid E. O'Brien dtilde(); 16945e5710bSMark Peek cleanup_until(canon); 170c80476e4SDavid E. O'Brien } 171c80476e4SDavid E. O'Brien else if (eq(vp, STRedit)) { 172c80476e4SDavid E. O'Brien editing = 1; 173c80476e4SDavid E. O'Brien noediting = 0; 174c80476e4SDavid E. O'Brien /* PWP: add more stuff in here later */ 175c80476e4SDavid E. O'Brien } 176*19d2e3deSDmitry Chagin else if (eq(vp, STRvimode)) { 177*19d2e3deSDmitry Chagin VImode = 1; 178*19d2e3deSDmitry Chagin update_wordchars(); 179*19d2e3deSDmitry Chagin } 180c80476e4SDavid E. O'Brien else if (eq(vp, STRshlvl)) { 181c80476e4SDavid E. O'Brien tsetenv(STRKSHLVL, varval(vp)); 182c80476e4SDavid E. O'Brien } 183b2d5d167SMark Peek else if (eq(vp, STRignoreeof)) { 184b2d5d167SMark Peek Char *cp; 185b2d5d167SMark Peek numeof = 0; 186b2d5d167SMark Peek for ((cp = varval(STRignoreeof)); cp && *cp; cp++) { 187b2d5d167SMark Peek if (!Isdigit(*cp)) { 188b2d5d167SMark Peek numeof = 0; 189b2d5d167SMark Peek break; 190b2d5d167SMark Peek } 191b2d5d167SMark Peek numeof = numeof * 10 + *cp - '0'; 192b2d5d167SMark Peek } 193b2d5d167SMark Peek if (numeof <= 0) numeof = 26; /* Sanity check */ 194b2d5d167SMark Peek } 195c80476e4SDavid E. O'Brien else if (eq(vp, STRbackslash_quote)) { 196c80476e4SDavid E. O'Brien bslash_quote = 1; 197c80476e4SDavid E. O'Brien } 198a15e6f9aSMark Peek else if (eq(vp, STRcompat_expr)) { 199a15e6f9aSMark Peek compat_expr = 1; 200a15e6f9aSMark Peek } 201c80476e4SDavid E. O'Brien else if (eq(vp, STRdirstack)) { 202c80476e4SDavid E. O'Brien dsetstack(); 203c80476e4SDavid E. O'Brien } 204c80476e4SDavid E. O'Brien else if (eq(vp, STRrecognize_only_executables)) { 205c80476e4SDavid E. O'Brien tw_cmd_free(); 206c80476e4SDavid E. O'Brien } 2076767bd61SMark Peek else if (eq(vp, STRkillring)) { 2089ccc37e3SMark Peek SetKillRing((int)getn(varval(vp))); 2096767bd61SMark Peek } 210*19d2e3deSDmitry Chagin else if (eq(vp, STRhistory)) { 211*19d2e3deSDmitry Chagin sethistory((int)getn(varval(vp))); 212*19d2e3deSDmitry Chagin } 213c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP 214c80476e4SDavid E. O'Brien else if (eq(vp, STRwatch)) { 215c80476e4SDavid E. O'Brien resetwatch(); 216c80476e4SDavid E. O'Brien } 217c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */ 218c80476e4SDavid E. O'Brien else if (eq(vp, STRimplicitcd)) { 219c80476e4SDavid E. O'Brien implicit_cd = ((eq(varval(vp), STRverbose)) ? 2 : 1); 220c80476e4SDavid E. O'Brien } 221*19d2e3deSDmitry Chagin else if (eq(vp, STRcdtohome)) { 222*19d2e3deSDmitry Chagin cdtohome = 1; 223*19d2e3deSDmitry Chagin } 224c80476e4SDavid E. O'Brien #ifdef COLOR_LS_F 225c80476e4SDavid E. O'Brien else if (eq(vp, STRcolor)) { 226c80476e4SDavid E. O'Brien set_color_context(); 227c80476e4SDavid E. O'Brien } 228c80476e4SDavid E. O'Brien #endif /* COLOR_LS_F */ 229c80476e4SDavid E. O'Brien #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 230c80476e4SDavid E. O'Brien else if(eq(vp, CHECK_MBYTEVAR) || eq(vp, STRnokanji)) { 231c80476e4SDavid E. O'Brien update_dspmbyte_vars(); 232c80476e4SDavid E. O'Brien } 233c80476e4SDavid E. O'Brien #endif 2343b6eaa7bSAndrey A. Chernov #ifdef NLS_CATALOGS 2353b6eaa7bSAndrey A. Chernov else if (eq(vp, STRcatalog)) { 23623338178SMark Peek nlsclose(); 2373b6eaa7bSAndrey A. Chernov nlsinit(); 2383b6eaa7bSAndrey A. Chernov } 23929301572SMark Peek #if defined(FILEC) && defined(TIOCSTI) 24029301572SMark Peek else if (eq(vp, STRfilec)) 24129301572SMark Peek filec = 1; 24229301572SMark Peek #endif 2433b6eaa7bSAndrey A. Chernov #endif /* NLS_CATALOGS */ 244c80476e4SDavid E. O'Brien } 245c80476e4SDavid E. O'Brien 246c80476e4SDavid E. O'Brien 247c80476e4SDavid E. O'Brien /*ARGSUSED*/ 248c80476e4SDavid E. O'Brien void 24945e5710bSMark Peek doset(Char **v, struct command *c) 250c80476e4SDavid E. O'Brien { 25123338178SMark Peek Char *p; 2529ccc37e3SMark Peek Char *vp; 253c80476e4SDavid E. O'Brien Char **vecp; 25423338178SMark Peek int hadsub; 255c80476e4SDavid E. O'Brien int subscr; 256c80476e4SDavid E. O'Brien int flags = VAR_READWRITE; 25723338178SMark Peek int first_match = 0; 25823338178SMark Peek int last_match = 0; 25923338178SMark Peek int changed = 0; 260c80476e4SDavid E. O'Brien 261c80476e4SDavid E. O'Brien USE(c); 262c80476e4SDavid E. O'Brien v++; 263c80476e4SDavid E. O'Brien do { 264c80476e4SDavid E. O'Brien changed = 0; 265c80476e4SDavid E. O'Brien /* 266c80476e4SDavid E. O'Brien * Readonly addition From: Tim P. Starrin <noid@cyborg.larc.nasa.gov> 267c80476e4SDavid E. O'Brien */ 268c80476e4SDavid E. O'Brien if (*v && eq(*v, STRmr)) { 269c80476e4SDavid E. O'Brien flags = VAR_READONLY; 270c80476e4SDavid E. O'Brien v++; 271c80476e4SDavid E. O'Brien changed = 1; 272c80476e4SDavid E. O'Brien } 273c80476e4SDavid E. O'Brien if (*v && eq(*v, STRmf) && !last_match) { 274c80476e4SDavid E. O'Brien first_match = 1; 275c80476e4SDavid E. O'Brien v++; 276c80476e4SDavid E. O'Brien changed = 1; 277c80476e4SDavid E. O'Brien } 278c80476e4SDavid E. O'Brien if (*v && eq(*v, STRml) && !first_match) { 279c80476e4SDavid E. O'Brien last_match = 1; 280c80476e4SDavid E. O'Brien v++; 281c80476e4SDavid E. O'Brien changed = 1; 282c80476e4SDavid E. O'Brien } 283c80476e4SDavid E. O'Brien } while(changed); 284c80476e4SDavid E. O'Brien p = *v++; 285c80476e4SDavid E. O'Brien if (p == 0) { 286c80476e4SDavid E. O'Brien plist(&shvhed, flags); 287c80476e4SDavid E. O'Brien return; 288c80476e4SDavid E. O'Brien } 289c80476e4SDavid E. O'Brien do { 290c80476e4SDavid E. O'Brien hadsub = 0; 291c80476e4SDavid E. O'Brien vp = p; 2929ccc37e3SMark Peek if (!letter(*p)) 293c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_VARBEGIN); 2949ccc37e3SMark Peek do { 2959ccc37e3SMark Peek p++; 2969ccc37e3SMark Peek } while (alnum(*p)); 297c80476e4SDavid E. O'Brien if (*p == '[') { 298c80476e4SDavid E. O'Brien hadsub++; 299c80476e4SDavid E. O'Brien p = getinx(p, &subscr); 300c80476e4SDavid E. O'Brien } 3019ccc37e3SMark Peek if (*p != '\0' && *p != '=') 3029ccc37e3SMark Peek stderror(ERR_NAME | ERR_VARALNUM); 3039ccc37e3SMark Peek if (*p == '=') { 3049ccc37e3SMark Peek *p++ = '\0'; 3059ccc37e3SMark Peek if (*p == '\0' && *v != NULL && **v == '(') 306c80476e4SDavid E. O'Brien p = *v++; 307c80476e4SDavid E. O'Brien } 308c80476e4SDavid E. O'Brien else if (*v && eq(*v, STRequal)) { 3099ccc37e3SMark Peek if (*++v != NULL) 310c80476e4SDavid E. O'Brien p = *v++; 311c80476e4SDavid E. O'Brien } 312c80476e4SDavid E. O'Brien if (eq(p, STRLparen)) { 31323338178SMark Peek Char **e = v; 314c80476e4SDavid E. O'Brien 315c80476e4SDavid E. O'Brien if (hadsub) 316c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_SYNTAX); 317c80476e4SDavid E. O'Brien for (;;) { 318c80476e4SDavid E. O'Brien if (!*e) 319c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_MISSING, ')'); 320c80476e4SDavid E. O'Brien if (**e == ')') 321c80476e4SDavid E. O'Brien break; 322c80476e4SDavid E. O'Brien e++; 323c80476e4SDavid E. O'Brien } 324c80476e4SDavid E. O'Brien p = *e; 325c80476e4SDavid E. O'Brien *e = 0; 326c80476e4SDavid E. O'Brien vecp = saveblk(v); 327c80476e4SDavid E. O'Brien if (first_match) 328c80476e4SDavid E. O'Brien flags |= VAR_FIRST; 329c80476e4SDavid E. O'Brien else if (last_match) 330c80476e4SDavid E. O'Brien flags |= VAR_LAST; 331c80476e4SDavid E. O'Brien 332c80476e4SDavid E. O'Brien set1(vp, vecp, &shvhed, flags); 333c80476e4SDavid E. O'Brien *e = p; 334c80476e4SDavid E. O'Brien v = e + 1; 335c80476e4SDavid E. O'Brien } 33645e5710bSMark Peek else if (hadsub) { 33745e5710bSMark Peek Char *copy; 33845e5710bSMark Peek 33945e5710bSMark Peek copy = Strsave(p); 34045e5710bSMark Peek cleanup_push(copy, xfree); 34145e5710bSMark Peek asx(vp, subscr, copy); 34245e5710bSMark Peek cleanup_ignore(copy); 34345e5710bSMark Peek cleanup_until(copy); 34445e5710bSMark Peek } 345c80476e4SDavid E. O'Brien else 34645e5710bSMark Peek setv(vp, Strsave(p), flags); 347c80476e4SDavid E. O'Brien update_vars(vp); 348c80476e4SDavid E. O'Brien } while ((p = *v++) != NULL); 349c80476e4SDavid E. O'Brien } 350c80476e4SDavid E. O'Brien 351c80476e4SDavid E. O'Brien static Char * 35245e5710bSMark Peek getinx(Char *cp, int *ip) 353c80476e4SDavid E. O'Brien { 354c80476e4SDavid E. O'Brien *ip = 0; 355c80476e4SDavid E. O'Brien *cp++ = 0; 356c80476e4SDavid E. O'Brien while (*cp && Isdigit(*cp)) 357c80476e4SDavid E. O'Brien *ip = *ip * 10 + *cp++ - '0'; 358c80476e4SDavid E. O'Brien if (*cp++ != ']') 359c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_SUBSCRIPT); 360c80476e4SDavid E. O'Brien return (cp); 361c80476e4SDavid E. O'Brien } 362c80476e4SDavid E. O'Brien 363c80476e4SDavid E. O'Brien static void 36445e5710bSMark Peek asx(Char *vp, int subscr, Char *p) 365c80476e4SDavid E. O'Brien { 36623338178SMark Peek struct varent *v = getvx(vp, subscr); 36745e5710bSMark Peek Char *prev; 368c80476e4SDavid E. O'Brien 369c80476e4SDavid E. O'Brien if (v->v_flags & VAR_READONLY) 370c80476e4SDavid E. O'Brien stderror(ERR_READONLY|ERR_NAME, v->v_name); 37145e5710bSMark Peek prev = v->vec[subscr - 1]; 37245e5710bSMark Peek cleanup_push(prev, xfree); 373c80476e4SDavid E. O'Brien v->vec[subscr - 1] = globone(p, G_APPEND); 37445e5710bSMark Peek cleanup_until(prev); 375c80476e4SDavid E. O'Brien } 376c80476e4SDavid E. O'Brien 377c80476e4SDavid E. O'Brien static struct varent * 37845e5710bSMark Peek getvx(Char *vp, int subscr) 379c80476e4SDavid E. O'Brien { 38023338178SMark Peek struct varent *v = adrof(vp); 381c80476e4SDavid E. O'Brien 382c80476e4SDavid E. O'Brien if (v == 0) 383c80476e4SDavid E. O'Brien udvar(vp); 384c80476e4SDavid E. O'Brien if (subscr < 1 || subscr > blklen(v->vec)) 385c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_RANGE); 386c80476e4SDavid E. O'Brien return (v); 387c80476e4SDavid E. O'Brien } 388c80476e4SDavid E. O'Brien 389c80476e4SDavid E. O'Brien /*ARGSUSED*/ 390c80476e4SDavid E. O'Brien void 39145e5710bSMark Peek dolet(Char **v, struct command *dummy) 392c80476e4SDavid E. O'Brien { 39323338178SMark Peek Char *p; 394c80476e4SDavid E. O'Brien Char *vp, c, op; 39523338178SMark Peek int hadsub; 396c80476e4SDavid E. O'Brien int subscr; 397c80476e4SDavid E. O'Brien 398c80476e4SDavid E. O'Brien USE(dummy); 399c80476e4SDavid E. O'Brien v++; 400c80476e4SDavid E. O'Brien p = *v++; 401c80476e4SDavid E. O'Brien if (p == 0) { 402c80476e4SDavid E. O'Brien prvars(); 403c80476e4SDavid E. O'Brien return; 404c80476e4SDavid E. O'Brien } 405c80476e4SDavid E. O'Brien do { 406c80476e4SDavid E. O'Brien hadsub = 0; 407c80476e4SDavid E. O'Brien vp = p; 408c80476e4SDavid E. O'Brien if (letter(*p)) 409c80476e4SDavid E. O'Brien for (; alnum(*p); p++) 410c80476e4SDavid E. O'Brien continue; 411c80476e4SDavid E. O'Brien if (vp == p || !letter(*vp)) 412c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_VARBEGIN); 413c80476e4SDavid E. O'Brien if (*p == '[') { 414c80476e4SDavid E. O'Brien hadsub++; 415c80476e4SDavid E. O'Brien p = getinx(p, &subscr); 416c80476e4SDavid E. O'Brien } 417c80476e4SDavid E. O'Brien if (*p == 0 && *v) 418c80476e4SDavid E. O'Brien p = *v++; 419c80476e4SDavid E. O'Brien if ((op = *p) != 0) 420c80476e4SDavid E. O'Brien *p++ = 0; 421c80476e4SDavid E. O'Brien else 422c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_ASSIGN); 423c80476e4SDavid E. O'Brien 424c80476e4SDavid E. O'Brien /* 425c80476e4SDavid E. O'Brien * if there is no expression after the '=' then print a "Syntax Error" 426c80476e4SDavid E. O'Brien * message - strike 427c80476e4SDavid E. O'Brien */ 428c80476e4SDavid E. O'Brien if (*p == '\0' && *v == NULL) 429c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_ASSIGN); 430c80476e4SDavid E. O'Brien 431c80476e4SDavid E. O'Brien vp = Strsave(vp); 43245e5710bSMark Peek cleanup_push(vp, xfree); 433c80476e4SDavid E. O'Brien if (op == '=') { 434c80476e4SDavid E. O'Brien c = '='; 435c80476e4SDavid E. O'Brien p = xset(p, &v); 436c80476e4SDavid E. O'Brien } 437c80476e4SDavid E. O'Brien else { 438c80476e4SDavid E. O'Brien c = *p++; 439c80476e4SDavid E. O'Brien if (any("+-", c)) { 440c80476e4SDavid E. O'Brien if (c != op || *p) 441c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_UNKNOWNOP); 442c80476e4SDavid E. O'Brien p = Strsave(STR1); 443c80476e4SDavid E. O'Brien } 444c80476e4SDavid E. O'Brien else { 445c80476e4SDavid E. O'Brien if (any("<>", op)) { 446c80476e4SDavid E. O'Brien if (c != op) 447c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_UNKNOWNOP); 448c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_SYNTAX); 449c80476e4SDavid E. O'Brien } 450c80476e4SDavid E. O'Brien if (c != '=') 451c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_UNKNOWNOP); 452c80476e4SDavid E. O'Brien p = xset(p, &v); 453c80476e4SDavid E. O'Brien } 454c80476e4SDavid E. O'Brien } 45545e5710bSMark Peek cleanup_push(p, xfree); 456c80476e4SDavid E. O'Brien if (op == '=') { 457c80476e4SDavid E. O'Brien if (hadsub) 458c80476e4SDavid E. O'Brien asx(vp, subscr, p); 459c80476e4SDavid E. O'Brien else 46045e5710bSMark Peek setv(vp, p, VAR_READWRITE); 46145e5710bSMark Peek cleanup_ignore(p); 462c80476e4SDavid E. O'Brien } 463c80476e4SDavid E. O'Brien else if (hadsub) { 464c80476e4SDavid E. O'Brien struct varent *gv = getvx(vp, subscr); 46545e5710bSMark Peek Char *val; 466c80476e4SDavid E. O'Brien 46745e5710bSMark Peek val = operate(op, gv->vec[subscr - 1], p); 46845e5710bSMark Peek cleanup_push(val, xfree); 46945e5710bSMark Peek asx(vp, subscr, val); 47045e5710bSMark Peek cleanup_ignore(val); 47145e5710bSMark Peek cleanup_until(val); 472c80476e4SDavid E. O'Brien } 47345e5710bSMark Peek else { 47445e5710bSMark Peek Char *val; 47545e5710bSMark Peek 47645e5710bSMark Peek val = operate(op, varval(vp), p); 47745e5710bSMark Peek cleanup_push(val, xfree); 47845e5710bSMark Peek setv(vp, val, VAR_READWRITE); 47945e5710bSMark Peek cleanup_ignore(val); 48045e5710bSMark Peek cleanup_until(val); 48145e5710bSMark Peek } 482c80476e4SDavid E. O'Brien update_vars(vp); 48345e5710bSMark Peek cleanup_until(vp); 484c80476e4SDavid E. O'Brien } while ((p = *v++) != NULL); 485c80476e4SDavid E. O'Brien } 486c80476e4SDavid E. O'Brien 487c80476e4SDavid E. O'Brien static Char * 48845e5710bSMark Peek xset(Char *cp, Char ***vp) 489c80476e4SDavid E. O'Brien { 49023338178SMark Peek Char *dp; 491c80476e4SDavid E. O'Brien 492c80476e4SDavid E. O'Brien if (*cp) { 493c80476e4SDavid E. O'Brien dp = Strsave(cp); 494c80476e4SDavid E. O'Brien --(*vp); 49545e5710bSMark Peek xfree(** vp); 496c80476e4SDavid E. O'Brien **vp = dp; 497c80476e4SDavid E. O'Brien } 498c80476e4SDavid E. O'Brien return (putn(expr(vp))); 499c80476e4SDavid E. O'Brien } 500c80476e4SDavid E. O'Brien 501c80476e4SDavid E. O'Brien static Char * 50245e5710bSMark Peek operate(int op, Char *vp, Char *p) 503c80476e4SDavid E. O'Brien { 504c80476e4SDavid E. O'Brien Char opr[2]; 505c80476e4SDavid E. O'Brien Char *vec[5]; 50623338178SMark Peek Char **v = vec; 507c80476e4SDavid E. O'Brien Char **vecp = v; 5089ccc37e3SMark Peek tcsh_number_t i; 509c80476e4SDavid E. O'Brien 510c80476e4SDavid E. O'Brien if (op != '=') { 511c80476e4SDavid E. O'Brien if (*vp) 512c80476e4SDavid E. O'Brien *v++ = vp; 51345e5710bSMark Peek opr[0] = op; 514c80476e4SDavid E. O'Brien opr[1] = 0; 515c80476e4SDavid E. O'Brien *v++ = opr; 516c80476e4SDavid E. O'Brien if (op == '<' || op == '>') 517c80476e4SDavid E. O'Brien *v++ = opr; 518c80476e4SDavid E. O'Brien } 519c80476e4SDavid E. O'Brien *v++ = p; 520c80476e4SDavid E. O'Brien *v++ = 0; 521c80476e4SDavid E. O'Brien i = expr(&vecp); 522c80476e4SDavid E. O'Brien if (*vecp) 523c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_EXPRESSION); 524c80476e4SDavid E. O'Brien return (putn(i)); 525c80476e4SDavid E. O'Brien } 526c80476e4SDavid E. O'Brien 52745e5710bSMark Peek static Char *putp; 528c80476e4SDavid E. O'Brien 529c80476e4SDavid E. O'Brien Char * 5309ccc37e3SMark Peek putn(tcsh_number_t n) 531c80476e4SDavid E. O'Brien { 5329ccc37e3SMark Peek Char nbuf[1024]; /* Enough even for octal */ 533c80476e4SDavid E. O'Brien 534c80476e4SDavid E. O'Brien putp = nbuf; 535c80476e4SDavid E. O'Brien if (n < 0) { 536c80476e4SDavid E. O'Brien n = -n; 537c80476e4SDavid E. O'Brien *putp++ = '-'; 538c80476e4SDavid E. O'Brien } 539c80476e4SDavid E. O'Brien putn1(n); 540c80476e4SDavid E. O'Brien *putp = 0; 541c80476e4SDavid E. O'Brien return (Strsave(nbuf)); 542c80476e4SDavid E. O'Brien } 543c80476e4SDavid E. O'Brien 544c80476e4SDavid E. O'Brien static void 5459ccc37e3SMark Peek putn1(tcsh_number_t n) 546c80476e4SDavid E. O'Brien { 547c80476e4SDavid E. O'Brien if (n > 9) 548c80476e4SDavid E. O'Brien putn1(n / 10); 5499ccc37e3SMark Peek *putp++ = (Char)(n % 10 + '0'); 550c80476e4SDavid E. O'Brien } 551c80476e4SDavid E. O'Brien 5529ccc37e3SMark Peek tcsh_number_t 5539ccc37e3SMark Peek getn(const Char *cp) 554c80476e4SDavid E. O'Brien { 5559ccc37e3SMark Peek tcsh_number_t n; 556c80476e4SDavid E. O'Brien int sign; 557a15e6f9aSMark Peek int base; 558c80476e4SDavid E. O'Brien 559c80476e4SDavid E. O'Brien if (!cp) /* PWP: extra error checking */ 560c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_BADNUM); 561c80476e4SDavid E. O'Brien 562c80476e4SDavid E. O'Brien sign = 0; 563c80476e4SDavid E. O'Brien if (cp[0] == '+' && cp[1]) 564c80476e4SDavid E. O'Brien cp++; 565c80476e4SDavid E. O'Brien if (*cp == '-') { 566c80476e4SDavid E. O'Brien sign++; 567c80476e4SDavid E. O'Brien cp++; 568c80476e4SDavid E. O'Brien if (!Isdigit(*cp)) 569c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_BADNUM); 570c80476e4SDavid E. O'Brien } 571a15e6f9aSMark Peek 5729ccc37e3SMark Peek if (cp[0] == '0' && cp[1] && is_set(STRparseoctal)) 573a15e6f9aSMark Peek base = 8; 574a15e6f9aSMark Peek else 575a15e6f9aSMark Peek base = 10; 576a15e6f9aSMark Peek 577c80476e4SDavid E. O'Brien n = 0; 578c80476e4SDavid E. O'Brien while (Isdigit(*cp)) 579a15e6f9aSMark Peek { 580a15e6f9aSMark Peek if (base == 8 && *cp >= '8') 581a15e6f9aSMark Peek stderror(ERR_NAME | ERR_BADNUM); 582a15e6f9aSMark Peek n = n * base + *cp++ - '0'; 583a15e6f9aSMark Peek } 584c80476e4SDavid E. O'Brien if (*cp) 585c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_BADNUM); 586c80476e4SDavid E. O'Brien return (sign ? -n : n); 587c80476e4SDavid E. O'Brien } 588c80476e4SDavid E. O'Brien 589c80476e4SDavid E. O'Brien Char * 59045e5710bSMark Peek value1(Char *var, struct varent *head) 591c80476e4SDavid E. O'Brien { 59223338178SMark Peek struct varent *vp; 593c80476e4SDavid E. O'Brien 594c80476e4SDavid E. O'Brien if (!var || !head) /* PWP: extra error checking */ 595c80476e4SDavid E. O'Brien return (STRNULL); 596c80476e4SDavid E. O'Brien 597c80476e4SDavid E. O'Brien vp = adrof1(var, head); 59829301572SMark Peek return ((vp == NULL || vp->vec == NULL || vp->vec[0] == NULL) ? 59929301572SMark Peek STRNULL : vp->vec[0]); 600c80476e4SDavid E. O'Brien } 601c80476e4SDavid E. O'Brien 602c80476e4SDavid E. O'Brien static struct varent * 60345e5710bSMark Peek madrof(Char *pat, struct varent *vp) 604c80476e4SDavid E. O'Brien { 60523338178SMark Peek struct varent *vp1; 606c80476e4SDavid E. O'Brien 607c80476e4SDavid E. O'Brien for (vp = vp->v_left; vp; vp = vp->v_right) { 608c80476e4SDavid E. O'Brien if (vp->v_left && (vp1 = madrof(pat, vp)) != NULL) 609c80476e4SDavid E. O'Brien return vp1; 610c80476e4SDavid E. O'Brien if (Gmatch(vp->v_name, pat)) 611c80476e4SDavid E. O'Brien return vp; 612c80476e4SDavid E. O'Brien } 613c80476e4SDavid E. O'Brien return vp; 614c80476e4SDavid E. O'Brien } 615c80476e4SDavid E. O'Brien 616c80476e4SDavid E. O'Brien struct varent * 61745e5710bSMark Peek adrof1(const Char *name, struct varent *v) 618c80476e4SDavid E. O'Brien { 619c80476e4SDavid E. O'Brien int cmp; 620c80476e4SDavid E. O'Brien 621c80476e4SDavid E. O'Brien v = v->v_left; 622c80476e4SDavid E. O'Brien while (v && ((cmp = *name - *v->v_name) != 0 || 623c80476e4SDavid E. O'Brien (cmp = Strcmp(name, v->v_name)) != 0)) 624c80476e4SDavid E. O'Brien if (cmp < 0) 625c80476e4SDavid E. O'Brien v = v->v_left; 626c80476e4SDavid E. O'Brien else 627c80476e4SDavid E. O'Brien v = v->v_right; 628c80476e4SDavid E. O'Brien return v; 629c80476e4SDavid E. O'Brien } 630c80476e4SDavid E. O'Brien 63145e5710bSMark Peek void 63245e5710bSMark Peek setcopy(const Char *var, const Char *val, int flags) 63345e5710bSMark Peek { 63445e5710bSMark Peek Char *copy; 63545e5710bSMark Peek 63645e5710bSMark Peek copy = Strsave(val); 63745e5710bSMark Peek cleanup_push(copy, xfree); 63845e5710bSMark Peek setv(var, copy, flags); 63945e5710bSMark Peek cleanup_ignore(copy); 64045e5710bSMark Peek cleanup_until(copy); 64145e5710bSMark Peek } 64245e5710bSMark Peek 643c80476e4SDavid E. O'Brien /* 644c80476e4SDavid E. O'Brien * The caller is responsible for putting value in a safe place 645c80476e4SDavid E. O'Brien */ 646c80476e4SDavid E. O'Brien void 64745e5710bSMark Peek setv(const Char *var, Char *val, int flags) 648c80476e4SDavid E. O'Brien { 64945e5710bSMark Peek Char **vec = xmalloc(2 * sizeof(Char **)); 650c80476e4SDavid E. O'Brien 651c80476e4SDavid E. O'Brien vec[0] = val; 652c80476e4SDavid E. O'Brien vec[1] = 0; 653c80476e4SDavid E. O'Brien set1(var, vec, &shvhed, flags); 654c80476e4SDavid E. O'Brien } 655c80476e4SDavid E. O'Brien 656c80476e4SDavid E. O'Brien void 65745e5710bSMark Peek set1(const Char *var, Char **vec, struct varent *head, int flags) 658c80476e4SDavid E. O'Brien { 65923338178SMark Peek Char **oldv = vec; 660c80476e4SDavid E. O'Brien 661c80476e4SDavid E. O'Brien if ((flags & VAR_NOGLOB) == 0) { 66245e5710bSMark Peek int gflag; 66345e5710bSMark Peek 66445e5710bSMark Peek gflag = tglob(oldv); 665c80476e4SDavid E. O'Brien if (gflag) { 66645e5710bSMark Peek vec = globall(oldv, gflag); 667c80476e4SDavid E. O'Brien if (vec == 0) { 668c80476e4SDavid E. O'Brien blkfree(oldv); 669c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_NOMATCH); 670c80476e4SDavid E. O'Brien } 671c80476e4SDavid E. O'Brien blkfree(oldv); 672c80476e4SDavid E. O'Brien } 673c80476e4SDavid E. O'Brien } 674c80476e4SDavid E. O'Brien /* 675c80476e4SDavid E. O'Brien * Uniqueness addition from: Michael Veksler <mveksler@vnet.ibm.com> 676c80476e4SDavid E. O'Brien */ 677c80476e4SDavid E. O'Brien if ( flags & (VAR_FIRST | VAR_LAST) ) { 678c80476e4SDavid E. O'Brien /* 679c80476e4SDavid E. O'Brien * Code for -f (VAR_FIRST) and -l (VAR_LAST) options. 680c80476e4SDavid E. O'Brien * Method: 681c80476e4SDavid E. O'Brien * Delete all duplicate words leaving "holes" in the word array (vec). 682c80476e4SDavid E. O'Brien * Then remove the "holes", keeping the order of the words unchanged. 683c80476e4SDavid E. O'Brien */ 684c80476e4SDavid E. O'Brien if (vec && vec[0] && vec[1]) { /* more than one word ? */ 685c80476e4SDavid E. O'Brien int i, j; 686c80476e4SDavid E. O'Brien int num_items; 687c80476e4SDavid E. O'Brien 688c80476e4SDavid E. O'Brien for (num_items = 0; vec[num_items]; num_items++) 689c80476e4SDavid E. O'Brien continue; 690c80476e4SDavid E. O'Brien if (flags & VAR_FIRST) { 691c80476e4SDavid E. O'Brien /* delete duplications, keeping first occurance */ 692c80476e4SDavid E. O'Brien for (i = 1; i < num_items; i++) 693c80476e4SDavid E. O'Brien for (j = 0; j < i; j++) 694c80476e4SDavid E. O'Brien /* If have earlier identical item, remove i'th item */ 695c80476e4SDavid E. O'Brien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { 69645e5710bSMark Peek xfree(vec[i]); 697c80476e4SDavid E. O'Brien vec[i] = NULL; 698c80476e4SDavid E. O'Brien break; 699c80476e4SDavid E. O'Brien } 700c80476e4SDavid E. O'Brien } else if (flags & VAR_LAST) { 701c80476e4SDavid E. O'Brien /* delete duplications, keeping last occurance */ 702c80476e4SDavid E. O'Brien for (i = 0; i < num_items - 1; i++) 703c80476e4SDavid E. O'Brien for (j = i + 1; j < num_items; j++) 704c80476e4SDavid E. O'Brien /* If have later identical item, remove i'th item */ 705c80476e4SDavid E. O'Brien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { 706c80476e4SDavid E. O'Brien /* remove identical item (the first) */ 70745e5710bSMark Peek xfree(vec[i]); 708c80476e4SDavid E. O'Brien vec[i] = NULL; 709c80476e4SDavid E. O'Brien } 710c80476e4SDavid E. O'Brien } 711c80476e4SDavid E. O'Brien /* Compress items - remove empty items */ 712c80476e4SDavid E. O'Brien for (j = i = 0; i < num_items; i++) 713c80476e4SDavid E. O'Brien if (vec[i]) 714c80476e4SDavid E. O'Brien vec[j++] = vec[i]; 715c80476e4SDavid E. O'Brien 716c80476e4SDavid E. O'Brien /* NULL-fy remaining items */ 717c80476e4SDavid E. O'Brien for (; j < num_items; j++) 718c80476e4SDavid E. O'Brien vec[j] = NULL; 719c80476e4SDavid E. O'Brien } 720c80476e4SDavid E. O'Brien /* don't let the attribute propagate */ 721c80476e4SDavid E. O'Brien flags &= ~(VAR_FIRST|VAR_LAST); 722c80476e4SDavid E. O'Brien } 723c80476e4SDavid E. O'Brien setq(var, vec, head, flags); 724c80476e4SDavid E. O'Brien } 725c80476e4SDavid E. O'Brien 726c80476e4SDavid E. O'Brien 727c80476e4SDavid E. O'Brien void 72845e5710bSMark Peek setq(const Char *name, Char **vec, struct varent *p, int flags) 729c80476e4SDavid E. O'Brien { 73023338178SMark Peek struct varent *c; 73123338178SMark Peek int f; 732c80476e4SDavid E. O'Brien 733c80476e4SDavid E. O'Brien f = 0; /* tree hangs off the header's left link */ 734c80476e4SDavid E. O'Brien while ((c = p->v_link[f]) != 0) { 735c80476e4SDavid E. O'Brien if ((f = *name - *c->v_name) == 0 && 736c80476e4SDavid E. O'Brien (f = Strcmp(name, c->v_name)) == 0) { 737c80476e4SDavid E. O'Brien if (c->v_flags & VAR_READONLY) 738c80476e4SDavid E. O'Brien stderror(ERR_READONLY|ERR_NAME, c->v_name); 739c80476e4SDavid E. O'Brien blkfree(c->vec); 740c80476e4SDavid E. O'Brien c->v_flags = flags; 741c80476e4SDavid E. O'Brien trim(c->vec = vec); 742c80476e4SDavid E. O'Brien return; 743c80476e4SDavid E. O'Brien } 744c80476e4SDavid E. O'Brien p = c; 745c80476e4SDavid E. O'Brien f = f > 0; 746c80476e4SDavid E. O'Brien } 74745e5710bSMark Peek p->v_link[f] = c = xmalloc(sizeof(struct varent)); 748c80476e4SDavid E. O'Brien c->v_name = Strsave(name); 749c80476e4SDavid E. O'Brien c->v_flags = flags; 750c80476e4SDavid E. O'Brien c->v_bal = 0; 751c80476e4SDavid E. O'Brien c->v_left = c->v_right = 0; 752c80476e4SDavid E. O'Brien c->v_parent = p; 753c80476e4SDavid E. O'Brien balance(p, f, 0); 754c80476e4SDavid E. O'Brien trim(c->vec = vec); 755c80476e4SDavid E. O'Brien } 756c80476e4SDavid E. O'Brien 757c80476e4SDavid E. O'Brien /*ARGSUSED*/ 758c80476e4SDavid E. O'Brien void 75945e5710bSMark Peek unset(Char **v, struct command *c) 760c80476e4SDavid E. O'Brien { 76123338178SMark Peek int did_roe, did_edit; 762c80476e4SDavid E. O'Brien 763c80476e4SDavid E. O'Brien USE(c); 764c80476e4SDavid E. O'Brien did_roe = adrof(STRrecognize_only_executables) != NULL; 765c80476e4SDavid E. O'Brien did_edit = adrof(STRedit) != NULL; 766c80476e4SDavid E. O'Brien unset1(v, &shvhed); 76729301572SMark Peek 76829301572SMark Peek #if defined(FILEC) && defined(TIOCSTI) 76929301572SMark Peek if (adrof(STRfilec) == 0) 77029301572SMark Peek filec = 0; 77129301572SMark Peek #endif /* FILEC && TIOCSTI */ 77229301572SMark Peek 773c80476e4SDavid E. O'Brien if (adrof(STRhistchars) == 0) { 774c80476e4SDavid E. O'Brien HIST = '!'; 775c80476e4SDavid E. O'Brien HISTSUB = '^'; 776c80476e4SDavid E. O'Brien } 777b2d5d167SMark Peek if (adrof(STRignoreeof) == 0) 778b2d5d167SMark Peek numeof = 0; 779c80476e4SDavid E. O'Brien if (adrof(STRpromptchars) == 0) { 7809ccc37e3SMark Peek PRCH = tcsh ? '>' : '%'; 781c80476e4SDavid E. O'Brien PRCHROOT = '#'; 782c80476e4SDavid E. O'Brien } 783*19d2e3deSDmitry Chagin if (adrof(STRnoclobber) == 0) 784*19d2e3deSDmitry Chagin no_clobber = 0; 785c80476e4SDavid E. O'Brien if (adrof(STRhistlit) == 0) 786c80476e4SDavid E. O'Brien HistLit = 0; 787c80476e4SDavid E. O'Brien if (adrof(STRloginsh) == 0) 788c80476e4SDavid E. O'Brien loginsh = 0; 7899ccc37e3SMark Peek if (adrof(STRanyerror) == 0) 7909ccc37e3SMark Peek anyerror = 0; 791c80476e4SDavid E. O'Brien if (adrof(STRwordchars) == 0) 792c80476e4SDavid E. O'Brien word_chars = STR_WORD_CHARS; 793c80476e4SDavid E. O'Brien if (adrof(STRedit) == 0) 794c80476e4SDavid E. O'Brien editing = 0; 795c80476e4SDavid E. O'Brien if (adrof(STRbackslash_quote) == 0) 796c80476e4SDavid E. O'Brien bslash_quote = 0; 797a15e6f9aSMark Peek if (adrof(STRcompat_expr) == 0) 798a15e6f9aSMark Peek compat_expr = 0; 799c80476e4SDavid E. O'Brien if (adrof(STRsymlinks) == 0) 800c80476e4SDavid E. O'Brien symlinks = 0; 801c80476e4SDavid E. O'Brien if (adrof(STRimplicitcd) == 0) 802c80476e4SDavid E. O'Brien implicit_cd = 0; 803*19d2e3deSDmitry Chagin if (adrof(STRcdtohome) == 0) 804*19d2e3deSDmitry Chagin cdtohome = 0; 8056767bd61SMark Peek if (adrof(STRkillring) == 0) 8066767bd61SMark Peek SetKillRing(0); 807c80476e4SDavid E. O'Brien if (did_edit && noediting && adrof(STRedit) == 0) 808c80476e4SDavid E. O'Brien noediting = 0; 809*19d2e3deSDmitry Chagin if (adrof(STRvimode) == 0) 810*19d2e3deSDmitry Chagin VImode = 0; 811c80476e4SDavid E. O'Brien if (did_roe && adrof(STRrecognize_only_executables) == 0) 812c80476e4SDavid E. O'Brien tw_cmd_free(); 813*19d2e3deSDmitry Chagin if (adrof(STRhistory) == 0) 814*19d2e3deSDmitry Chagin sethistory(0); 815c80476e4SDavid E. O'Brien #ifdef COLOR_LS_F 816c80476e4SDavid E. O'Brien if (adrof(STRcolor) == 0) 817c80476e4SDavid E. O'Brien set_color_context(); 818c80476e4SDavid E. O'Brien #endif /* COLOR_LS_F */ 819c80476e4SDavid E. O'Brien #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE) 820c80476e4SDavid E. O'Brien update_dspmbyte_vars(); 821c80476e4SDavid E. O'Brien #endif 822*19d2e3deSDmitry Chagin update_wordchars(); 8233b6eaa7bSAndrey A. Chernov #ifdef NLS_CATALOGS 82423338178SMark Peek nlsclose(); 8253b6eaa7bSAndrey A. Chernov nlsinit(); 8263b6eaa7bSAndrey A. Chernov #endif /* NLS_CATALOGS */ 827c80476e4SDavid E. O'Brien } 828c80476e4SDavid E. O'Brien 829c80476e4SDavid E. O'Brien void 83045e5710bSMark Peek unset1(Char *v[], struct varent *head) 831c80476e4SDavid E. O'Brien { 83223338178SMark Peek struct varent *vp; 83323338178SMark Peek int cnt; 834c80476e4SDavid E. O'Brien 835c80476e4SDavid E. O'Brien while (*++v) { 836c80476e4SDavid E. O'Brien cnt = 0; 837c80476e4SDavid E. O'Brien while ((vp = madrof(*v, head)) != NULL) 838c80476e4SDavid E. O'Brien if (vp->v_flags & VAR_READONLY) 839c80476e4SDavid E. O'Brien stderror(ERR_READONLY|ERR_NAME, vp->v_name); 840c80476e4SDavid E. O'Brien else 841c80476e4SDavid E. O'Brien unsetv1(vp), cnt++; 842c80476e4SDavid E. O'Brien if (cnt == 0) 843c80476e4SDavid E. O'Brien setname(short2str(*v)); 844c80476e4SDavid E. O'Brien } 845c80476e4SDavid E. O'Brien } 846c80476e4SDavid E. O'Brien 847c80476e4SDavid E. O'Brien void 84845e5710bSMark Peek unsetv(Char *var) 849c80476e4SDavid E. O'Brien { 85023338178SMark Peek struct varent *vp; 851c80476e4SDavid E. O'Brien 852c80476e4SDavid E. O'Brien if ((vp = adrof1(var, &shvhed)) == 0) 853c80476e4SDavid E. O'Brien udvar(var); 854c80476e4SDavid E. O'Brien unsetv1(vp); 855c80476e4SDavid E. O'Brien } 856c80476e4SDavid E. O'Brien 857c80476e4SDavid E. O'Brien static void 85845e5710bSMark Peek unsetv1(struct varent *p) 859c80476e4SDavid E. O'Brien { 86023338178SMark Peek struct varent *c, *pp; 86123338178SMark Peek int f; 862c80476e4SDavid E. O'Brien 863c80476e4SDavid E. O'Brien /* 864c80476e4SDavid E. O'Brien * Free associated memory first to avoid complications. 865c80476e4SDavid E. O'Brien */ 866c80476e4SDavid E. O'Brien blkfree(p->vec); 86745e5710bSMark Peek xfree(p->v_name); 868c80476e4SDavid E. O'Brien /* 869c80476e4SDavid E. O'Brien * If p is missing one child, then we can move the other into where p is. 870c80476e4SDavid E. O'Brien * Otherwise, we find the predecessor of p, which is guaranteed to have no 871c80476e4SDavid E. O'Brien * right child, copy it into p, and move it's left child into it. 872c80476e4SDavid E. O'Brien */ 873c80476e4SDavid E. O'Brien if (p->v_right == 0) 874c80476e4SDavid E. O'Brien c = p->v_left; 875c80476e4SDavid E. O'Brien else if (p->v_left == 0) 876c80476e4SDavid E. O'Brien c = p->v_right; 877c80476e4SDavid E. O'Brien else { 878c80476e4SDavid E. O'Brien for (c = p->v_left; c->v_right; c = c->v_right) 879c80476e4SDavid E. O'Brien continue; 880c80476e4SDavid E. O'Brien p->v_name = c->v_name; 881c80476e4SDavid E. O'Brien p->v_flags = c->v_flags; 882c80476e4SDavid E. O'Brien p->vec = c->vec; 883c80476e4SDavid E. O'Brien p = c; 884c80476e4SDavid E. O'Brien c = p->v_left; 885c80476e4SDavid E. O'Brien } 886c80476e4SDavid E. O'Brien 887c80476e4SDavid E. O'Brien /* 888c80476e4SDavid E. O'Brien * Move c into where p is. 889c80476e4SDavid E. O'Brien */ 890c80476e4SDavid E. O'Brien pp = p->v_parent; 891c80476e4SDavid E. O'Brien f = pp->v_right == p; 892c80476e4SDavid E. O'Brien if ((pp->v_link[f] = c) != 0) 893c80476e4SDavid E. O'Brien c->v_parent = pp; 894c80476e4SDavid E. O'Brien /* 895c80476e4SDavid E. O'Brien * Free the deleted node, and rebalance. 896c80476e4SDavid E. O'Brien */ 89745e5710bSMark Peek xfree(p); 898c80476e4SDavid E. O'Brien balance(pp, f, 1); 899c80476e4SDavid E. O'Brien } 900c80476e4SDavid E. O'Brien 9019ccc37e3SMark Peek /* Set variable name to NULL. */ 902c80476e4SDavid E. O'Brien void 9039ccc37e3SMark Peek setNS(const Char *varName) 904c80476e4SDavid E. O'Brien { 9059ccc37e3SMark Peek setcopy(varName, STRNULL, VAR_READWRITE); 906c80476e4SDavid E. O'Brien } 907c80476e4SDavid E. O'Brien 908c80476e4SDavid E. O'Brien /*ARGSUSED*/ 909c80476e4SDavid E. O'Brien void 91045e5710bSMark Peek shift(Char **v, struct command *c) 911c80476e4SDavid E. O'Brien { 91223338178SMark Peek struct varent *argv; 91323338178SMark Peek Char *name; 914c80476e4SDavid E. O'Brien 915c80476e4SDavid E. O'Brien USE(c); 916c80476e4SDavid E. O'Brien v++; 917c80476e4SDavid E. O'Brien name = *v; 918c80476e4SDavid E. O'Brien if (name == 0) 919c80476e4SDavid E. O'Brien name = STRargv; 920c80476e4SDavid E. O'Brien else 921c80476e4SDavid E. O'Brien (void) strip(name); 922c80476e4SDavid E. O'Brien argv = adrof(name); 92329301572SMark Peek if (argv == NULL || argv->vec == NULL) 924c80476e4SDavid E. O'Brien udvar(name); 925c80476e4SDavid E. O'Brien if (argv->vec[0] == 0) 926c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_NOMORE); 927c80476e4SDavid E. O'Brien lshift(argv->vec, 1); 928c80476e4SDavid E. O'Brien update_vars(name); 929c80476e4SDavid E. O'Brien } 930c80476e4SDavid E. O'Brien 931c80476e4SDavid E. O'Brien static void 93245e5710bSMark Peek exportpath(Char **val) 933c80476e4SDavid E. O'Brien { 93445e5710bSMark Peek struct Strbuf buf = Strbuf_INIT; 935c80476e4SDavid E. O'Brien Char *exppath; 936c80476e4SDavid E. O'Brien 937c80476e4SDavid E. O'Brien if (val) 938c80476e4SDavid E. O'Brien while (*val) { 93945e5710bSMark Peek Strbuf_append(&buf, *val++); 940c80476e4SDavid E. O'Brien if (*val == 0 || eq(*val, STRRparen)) 941c80476e4SDavid E. O'Brien break; 94245e5710bSMark Peek Strbuf_append1(&buf, PATHSEP); 943c80476e4SDavid E. O'Brien } 94445e5710bSMark Peek exppath = Strbuf_finish(&buf); 94545e5710bSMark Peek cleanup_push(exppath, xfree); 946c80476e4SDavid E. O'Brien tsetenv(STRKPATH, exppath); 94745e5710bSMark Peek cleanup_until(exppath); 948c80476e4SDavid E. O'Brien } 949c80476e4SDavid E. O'Brien 950*19d2e3deSDmitry Chagin static int 951*19d2e3deSDmitry Chagin set_noclobber(Char **val) 952*19d2e3deSDmitry Chagin { 953*19d2e3deSDmitry Chagin Char *option; 954*19d2e3deSDmitry Chagin int nc = NOCLOBBER_DEFAULT; 955*19d2e3deSDmitry Chagin 956*19d2e3deSDmitry Chagin if (val == NULL) 957*19d2e3deSDmitry Chagin return nc; 958*19d2e3deSDmitry Chagin while (*val) { 959*19d2e3deSDmitry Chagin if (*val == 0 || eq(*val, STRRparen)) 960*19d2e3deSDmitry Chagin return nc; 961*19d2e3deSDmitry Chagin 962*19d2e3deSDmitry Chagin option = *val++; 963*19d2e3deSDmitry Chagin 964*19d2e3deSDmitry Chagin if (eq(option, STRnotempty)) 965*19d2e3deSDmitry Chagin nc |= NOCLOBBER_NOTEMPTY; 966*19d2e3deSDmitry Chagin else if (eq(option, STRask)) 967*19d2e3deSDmitry Chagin nc |= NOCLOBBER_ASK; 968*19d2e3deSDmitry Chagin } 969*19d2e3deSDmitry Chagin return nc; 970*19d2e3deSDmitry Chagin } 971*19d2e3deSDmitry Chagin 972c80476e4SDavid E. O'Brien #ifndef lint 973c80476e4SDavid E. O'Brien /* 974c80476e4SDavid E. O'Brien * Lint thinks these have null effect 975c80476e4SDavid E. O'Brien */ 976c80476e4SDavid E. O'Brien /* macros to do single rotations on node p */ 977c80476e4SDavid E. O'Brien # define rright(p) (\ 978c80476e4SDavid E. O'Brien t = (p)->v_left,\ 979c80476e4SDavid E. O'Brien (t)->v_parent = (p)->v_parent,\ 980c80476e4SDavid E. O'Brien (((p)->v_left = t->v_right) != NULL) ?\ 981c80476e4SDavid E. O'Brien (t->v_right->v_parent = (p)) : 0,\ 982c80476e4SDavid E. O'Brien (t->v_right = (p))->v_parent = t,\ 983c80476e4SDavid E. O'Brien (p) = t) 984c80476e4SDavid E. O'Brien # define rleft(p) (\ 985c80476e4SDavid E. O'Brien t = (p)->v_right,\ 986c80476e4SDavid E. O'Brien ((t)->v_parent = (p)->v_parent,\ 987c80476e4SDavid E. O'Brien ((p)->v_right = t->v_left) != NULL) ? \ 988c80476e4SDavid E. O'Brien (t->v_left->v_parent = (p)) : 0,\ 989c80476e4SDavid E. O'Brien (t->v_left = (p))->v_parent = t,\ 990c80476e4SDavid E. O'Brien (p) = t) 991c80476e4SDavid E. O'Brien #else 992c80476e4SDavid E. O'Brien static struct varent * 99345e5710bSMark Peek rleft(struct varent *p) 994c80476e4SDavid E. O'Brien { 995c80476e4SDavid E. O'Brien return (p); 996c80476e4SDavid E. O'Brien } 997c80476e4SDavid E. O'Brien static struct varent * 99845e5710bSMark Peek rright(struct varent *p) 999c80476e4SDavid E. O'Brien { 1000c80476e4SDavid E. O'Brien return (p); 1001c80476e4SDavid E. O'Brien } 1002c80476e4SDavid E. O'Brien 1003c80476e4SDavid E. O'Brien #endif /* ! lint */ 1004c80476e4SDavid E. O'Brien 1005c80476e4SDavid E. O'Brien 1006c80476e4SDavid E. O'Brien /* 1007c80476e4SDavid E. O'Brien * Rebalance a tree, starting at p and up. 1008c80476e4SDavid E. O'Brien * F == 0 means we've come from p's left child. 1009c80476e4SDavid E. O'Brien * D == 1 means we've just done a delete, otherwise an insert. 1010c80476e4SDavid E. O'Brien */ 1011c80476e4SDavid E. O'Brien static void 101245e5710bSMark Peek balance(struct varent *p, int f, int d) 1013c80476e4SDavid E. O'Brien { 101423338178SMark Peek struct varent *pp; 1015c80476e4SDavid E. O'Brien 1016c80476e4SDavid E. O'Brien #ifndef lint 101723338178SMark Peek struct varent *t; /* used by the rotate macros */ 1018c80476e4SDavid E. O'Brien #endif /* !lint */ 101923338178SMark Peek int ff; 1020c80476e4SDavid E. O'Brien #ifdef lint 1021c80476e4SDavid E. O'Brien ff = 0; /* Sun's lint is dumb! */ 1022c80476e4SDavid E. O'Brien #endif 1023c80476e4SDavid E. O'Brien 1024c80476e4SDavid E. O'Brien /* 1025c80476e4SDavid E. O'Brien * Ok, from here on, p is the node we're operating on; pp is it's parent; f 1026c80476e4SDavid E. O'Brien * is the branch of p from which we have come; ff is the branch of pp which 1027c80476e4SDavid E. O'Brien * is p. 1028c80476e4SDavid E. O'Brien */ 1029c80476e4SDavid E. O'Brien for (; (pp = p->v_parent) != 0; p = pp, f = ff) { 1030c80476e4SDavid E. O'Brien ff = pp->v_right == p; 1031c80476e4SDavid E. O'Brien if (f ^ d) { /* right heavy */ 1032c80476e4SDavid E. O'Brien switch (p->v_bal) { 1033c80476e4SDavid E. O'Brien case -1: /* was left heavy */ 1034c80476e4SDavid E. O'Brien p->v_bal = 0; 1035c80476e4SDavid E. O'Brien break; 1036c80476e4SDavid E. O'Brien case 0: /* was balanced */ 1037c80476e4SDavid E. O'Brien p->v_bal = 1; 1038c80476e4SDavid E. O'Brien break; 1039c80476e4SDavid E. O'Brien case 1: /* was already right heavy */ 1040c80476e4SDavid E. O'Brien switch (p->v_right->v_bal) { 104145e5710bSMark Peek case 1: /* single rotate */ 1042c80476e4SDavid E. O'Brien pp->v_link[ff] = rleft(p); 1043c80476e4SDavid E. O'Brien p->v_left->v_bal = 0; 1044c80476e4SDavid E. O'Brien p->v_bal = 0; 1045c80476e4SDavid E. O'Brien break; 1046c80476e4SDavid E. O'Brien case 0: /* single rotate */ 1047c80476e4SDavid E. O'Brien pp->v_link[ff] = rleft(p); 1048c80476e4SDavid E. O'Brien p->v_left->v_bal = 1; 1049c80476e4SDavid E. O'Brien p->v_bal = -1; 1050c80476e4SDavid E. O'Brien break; 1051c80476e4SDavid E. O'Brien case -1: /* double rotate */ 1052c80476e4SDavid E. O'Brien (void) rright(p->v_right); 1053c80476e4SDavid E. O'Brien pp->v_link[ff] = rleft(p); 1054c80476e4SDavid E. O'Brien p->v_left->v_bal = 1055c80476e4SDavid E. O'Brien p->v_bal < 1 ? 0 : -1; 1056c80476e4SDavid E. O'Brien p->v_right->v_bal = 1057c80476e4SDavid E. O'Brien p->v_bal > -1 ? 0 : 1; 1058c80476e4SDavid E. O'Brien p->v_bal = 0; 1059c80476e4SDavid E. O'Brien break; 1060c80476e4SDavid E. O'Brien default: 1061c80476e4SDavid E. O'Brien break; 1062c80476e4SDavid E. O'Brien } 1063c80476e4SDavid E. O'Brien break; 1064c80476e4SDavid E. O'Brien default: 1065c80476e4SDavid E. O'Brien break; 1066c80476e4SDavid E. O'Brien } 1067c80476e4SDavid E. O'Brien } 1068c80476e4SDavid E. O'Brien else { /* left heavy */ 1069c80476e4SDavid E. O'Brien switch (p->v_bal) { 1070c80476e4SDavid E. O'Brien case 1: /* was right heavy */ 1071c80476e4SDavid E. O'Brien p->v_bal = 0; 1072c80476e4SDavid E. O'Brien break; 1073c80476e4SDavid E. O'Brien case 0: /* was balanced */ 1074c80476e4SDavid E. O'Brien p->v_bal = -1; 1075c80476e4SDavid E. O'Brien break; 1076c80476e4SDavid E. O'Brien case -1: /* was already left heavy */ 1077c80476e4SDavid E. O'Brien switch (p->v_left->v_bal) { 1078c80476e4SDavid E. O'Brien case -1: /* single rotate */ 1079c80476e4SDavid E. O'Brien pp->v_link[ff] = rright(p); 1080c80476e4SDavid E. O'Brien p->v_right->v_bal = 0; 1081c80476e4SDavid E. O'Brien p->v_bal = 0; 1082c80476e4SDavid E. O'Brien break; 108345e5710bSMark Peek case 0: /* single rotate */ 1084c80476e4SDavid E. O'Brien pp->v_link[ff] = rright(p); 1085c80476e4SDavid E. O'Brien p->v_right->v_bal = -1; 1086c80476e4SDavid E. O'Brien p->v_bal = 1; 1087c80476e4SDavid E. O'Brien break; 1088c80476e4SDavid E. O'Brien case 1: /* double rotate */ 1089c80476e4SDavid E. O'Brien (void) rleft(p->v_left); 1090c80476e4SDavid E. O'Brien pp->v_link[ff] = rright(p); 1091c80476e4SDavid E. O'Brien p->v_left->v_bal = 1092c80476e4SDavid E. O'Brien p->v_bal < 1 ? 0 : -1; 1093c80476e4SDavid E. O'Brien p->v_right->v_bal = 1094c80476e4SDavid E. O'Brien p->v_bal > -1 ? 0 : 1; 1095c80476e4SDavid E. O'Brien p->v_bal = 0; 1096c80476e4SDavid E. O'Brien break; 1097c80476e4SDavid E. O'Brien default: 1098c80476e4SDavid E. O'Brien break; 1099c80476e4SDavid E. O'Brien } 1100c80476e4SDavid E. O'Brien break; 1101c80476e4SDavid E. O'Brien default: 1102c80476e4SDavid E. O'Brien break; 1103c80476e4SDavid E. O'Brien } 1104c80476e4SDavid E. O'Brien } 1105c80476e4SDavid E. O'Brien /* 1106c80476e4SDavid E. O'Brien * If from insert, then we terminate when p is balanced. If from 1107c80476e4SDavid E. O'Brien * delete, then we terminate when p is unbalanced. 1108c80476e4SDavid E. O'Brien */ 1109c80476e4SDavid E. O'Brien if ((p->v_bal == 0) ^ d) 1110c80476e4SDavid E. O'Brien break; 1111c80476e4SDavid E. O'Brien } 1112c80476e4SDavid E. O'Brien } 1113c80476e4SDavid E. O'Brien 1114c80476e4SDavid E. O'Brien void 111545e5710bSMark Peek plist(struct varent *p, int what) 1116c80476e4SDavid E. O'Brien { 111723338178SMark Peek struct varent *c; 111823338178SMark Peek int len; 1119c80476e4SDavid E. O'Brien 1120c80476e4SDavid E. O'Brien for (;;) { 1121c80476e4SDavid E. O'Brien while (p->v_left) 1122c80476e4SDavid E. O'Brien p = p->v_left; 1123c80476e4SDavid E. O'Brien x: 1124c80476e4SDavid E. O'Brien if (p->v_parent == 0) /* is it the header? */ 112545e5710bSMark Peek break; 1126c80476e4SDavid E. O'Brien if ((p->v_flags & what) != 0) { 112745e5710bSMark Peek if (setintr) { 112845e5710bSMark Peek int old_pintr_disabled; 112945e5710bSMark Peek 113045e5710bSMark Peek pintr_push_enable(&old_pintr_disabled); 113145e5710bSMark Peek cleanup_until(&old_pintr_disabled); 113245e5710bSMark Peek } 1133c80476e4SDavid E. O'Brien len = blklen(p->vec); 1134c80476e4SDavid E. O'Brien xprintf("%S\t", p->v_name); 1135c80476e4SDavid E. O'Brien if (len != 1) 1136c80476e4SDavid E. O'Brien xputchar('('); 1137c80476e4SDavid E. O'Brien blkpr(p->vec); 1138c80476e4SDavid E. O'Brien if (len != 1) 1139c80476e4SDavid E. O'Brien xputchar(')'); 1140c80476e4SDavid E. O'Brien xputchar('\n'); 1141c80476e4SDavid E. O'Brien } 1142c80476e4SDavid E. O'Brien if (p->v_right) { 1143c80476e4SDavid E. O'Brien p = p->v_right; 1144c80476e4SDavid E. O'Brien continue; 1145c80476e4SDavid E. O'Brien } 1146c80476e4SDavid E. O'Brien do { 1147c80476e4SDavid E. O'Brien c = p; 1148c80476e4SDavid E. O'Brien p = p->v_parent; 1149c80476e4SDavid E. O'Brien } while (p->v_right == c); 1150c80476e4SDavid E. O'Brien goto x; 1151c80476e4SDavid E. O'Brien } 1152c80476e4SDavid E. O'Brien } 1153c80476e4SDavid E. O'Brien 11549ccc37e3SMark Peek #if defined(KANJI) 11559ccc37e3SMark Peek # if defined(SHORT_STRINGS) && defined(DSPMBYTE) 115623338178SMark Peek extern int dspmbyte_ls; 1157c80476e4SDavid E. O'Brien 1158c80476e4SDavid E. O'Brien void 115945e5710bSMark Peek update_dspmbyte_vars(void) 1160c80476e4SDavid E. O'Brien { 1161c80476e4SDavid E. O'Brien int lp, iskcode; 1162c80476e4SDavid E. O'Brien Char *dstr1; 1163c80476e4SDavid E. O'Brien struct varent *vp; 1164c80476e4SDavid E. O'Brien 1165c80476e4SDavid E. O'Brien /* if variable "nokanji" is set, multi-byte display is disabled */ 1166c80476e4SDavid E. O'Brien if ((vp = adrof(CHECK_MBYTEVAR)) && !adrof(STRnokanji)) { 1167c80476e4SDavid E. O'Brien _enable_mbdisp = 1; 1168c80476e4SDavid E. O'Brien dstr1 = vp->vec[0]; 116923338178SMark Peek if(eq (dstr1, STRsjis)) 1170c80476e4SDavid E. O'Brien iskcode = 1; 117123338178SMark Peek else if (eq(dstr1, STReuc)) 1172c80476e4SDavid E. O'Brien iskcode = 2; 117323338178SMark Peek else if (eq(dstr1, STRbig5)) 11746767bd61SMark Peek iskcode = 3; 117523338178SMark Peek else if (eq(dstr1, STRutf8)) 117629301572SMark Peek iskcode = 4; 1177c80476e4SDavid E. O'Brien else if ((dstr1[0] - '0') >= 0 && (dstr1[0] - '0') <= 3) { 1178c80476e4SDavid E. O'Brien iskcode = 0; 1179c80476e4SDavid E. O'Brien } 1180c80476e4SDavid E. O'Brien else { 1181c80476e4SDavid E. O'Brien xprintf(CGETS(18, 2, 1182c80476e4SDavid E. O'Brien "Warning: unknown multibyte display; using default(euc(JP))\n")); 1183c80476e4SDavid E. O'Brien iskcode = 2; 1184c80476e4SDavid E. O'Brien } 1185c80476e4SDavid E. O'Brien if (dstr1 && vp->vec[1] && eq(vp->vec[1], STRls)) 1186c80476e4SDavid E. O'Brien dspmbyte_ls = 1; 1187c80476e4SDavid E. O'Brien else 1188c80476e4SDavid E. O'Brien dspmbyte_ls = 0; 1189c80476e4SDavid E. O'Brien for (lp = 0; lp < 256 && iskcode > 0; lp++) { 1190c80476e4SDavid E. O'Brien switch (iskcode) { 1191c80476e4SDavid E. O'Brien case 1: 1192c80476e4SDavid E. O'Brien /* Shift-JIS */ 1193c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_mbyte[lp]; 1194c80476e4SDavid E. O'Brien _mbmap[lp] = _mbmap_sjis[lp]; 1195c80476e4SDavid E. O'Brien break; 1196c80476e4SDavid E. O'Brien case 2: 1197c80476e4SDavid E. O'Brien /* 2 ... euc */ 1198c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_mbyte[lp]; 1199c80476e4SDavid E. O'Brien _mbmap[lp] = _mbmap_euc[lp]; 1200c80476e4SDavid E. O'Brien break; 12016767bd61SMark Peek case 3: 12026767bd61SMark Peek /* 3 ... big5 */ 12036767bd61SMark Peek _cmap[lp] = _cmap_mbyte[lp]; 12046767bd61SMark Peek _mbmap[lp] = _mbmap_big5[lp]; 12056767bd61SMark Peek break; 120629301572SMark Peek case 4: 120729301572SMark Peek /* 4 ... utf8 */ 120829301572SMark Peek _cmap[lp] = _cmap_mbyte[lp]; 120929301572SMark Peek _mbmap[lp] = _mbmap_utf8[lp]; 121029301572SMark Peek break; 1211c80476e4SDavid E. O'Brien default: 1212c80476e4SDavid E. O'Brien xprintf(CGETS(18, 3, 1213c80476e4SDavid E. O'Brien "Warning: unknown multibyte code %d; multibyte disabled\n"), 1214c80476e4SDavid E. O'Brien iskcode); 1215c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_c[lp]; 1216c80476e4SDavid E. O'Brien _mbmap[lp] = 0; /* Default map all 0 */ 1217c80476e4SDavid E. O'Brien _enable_mbdisp = 0; 1218c80476e4SDavid E. O'Brien break; 1219c80476e4SDavid E. O'Brien } 1220c80476e4SDavid E. O'Brien } 1221c80476e4SDavid E. O'Brien if (iskcode == 0) { 1222c80476e4SDavid E. O'Brien /* check original table */ 1223c80476e4SDavid E. O'Brien if (Strlen(dstr1) != 256) { 1224c80476e4SDavid E. O'Brien xprintf(CGETS(18, 4, 1225c80476e4SDavid E. O'Brien "Warning: Invalid multibyte table length (%d); multibyte disabled\n"), 1226c80476e4SDavid E. O'Brien Strlen(dstr1)); 1227c80476e4SDavid E. O'Brien _enable_mbdisp = 0; 1228c80476e4SDavid E. O'Brien } 1229c80476e4SDavid E. O'Brien for (lp = 0; lp < 256 && _enable_mbdisp == 1; lp++) { 1230c80476e4SDavid E. O'Brien if (!((dstr1[lp] - '0') >= 0 && (dstr1[lp] - '0') <= 3)) { 1231c80476e4SDavid E. O'Brien xprintf(CGETS(18, 4, 1232c80476e4SDavid E. O'Brien "Warning: bad multibyte code at offset +%d; multibyte diabled\n"), 1233c80476e4SDavid E. O'Brien lp); 1234c80476e4SDavid E. O'Brien _enable_mbdisp = 0; 1235c80476e4SDavid E. O'Brien break; 1236c80476e4SDavid E. O'Brien } 1237c80476e4SDavid E. O'Brien } 1238c80476e4SDavid E. O'Brien /* set original table */ 1239c80476e4SDavid E. O'Brien for (lp = 0; lp < 256; lp++) { 1240c80476e4SDavid E. O'Brien if (_enable_mbdisp == 1) { 1241c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_mbyte[lp]; 1242c80476e4SDavid E. O'Brien _mbmap[lp] = (unsigned short) ((dstr1[lp] - '0') & 0x0f); 1243c80476e4SDavid E. O'Brien } 1244c80476e4SDavid E. O'Brien else { 1245c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_c[lp]; 1246c80476e4SDavid E. O'Brien _mbmap[lp] = 0; /* Default map all 0 */ 1247c80476e4SDavid E. O'Brien } 1248c80476e4SDavid E. O'Brien } 1249c80476e4SDavid E. O'Brien } 1250c80476e4SDavid E. O'Brien } 1251c80476e4SDavid E. O'Brien else { 1252c80476e4SDavid E. O'Brien for (lp = 0; lp < 256; lp++) { 1253c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_c[lp]; 1254c80476e4SDavid E. O'Brien _mbmap[lp] = 0; /* Default map all 0 */ 1255c80476e4SDavid E. O'Brien } 1256c80476e4SDavid E. O'Brien _enable_mbdisp = 0; 1257c80476e4SDavid E. O'Brien dspmbyte_ls = 0; 1258c80476e4SDavid E. O'Brien } 1259c80476e4SDavid E. O'Brien #ifdef MBYTEDEBUG /* Sorry, use for beta testing */ 1260c80476e4SDavid E. O'Brien { 1261c80476e4SDavid E. O'Brien Char mbmapstr[300]; 126245e5710bSMark Peek for (lp = 0; lp < 256; lp++) 1263c80476e4SDavid E. O'Brien mbmapstr[lp] = _mbmap[lp] + '0'; 126445e5710bSMark Peek mbmapstr[lp] = 0; 126545e5710bSMark Peek setcopy(STRmbytemap, mbmapstr, VAR_READWRITE); 1266c80476e4SDavid E. O'Brien } 1267c80476e4SDavid E. O'Brien #endif /* MBYTEMAP */ 1268c80476e4SDavid E. O'Brien } 1269c80476e4SDavid E. O'Brien 1270c80476e4SDavid E. O'Brien /* dspkanji/dspmbyte autosetting */ 1271c80476e4SDavid E. O'Brien /* PATCH IDEA FROM Issei.Suzuki VERY THANKS */ 1272c80476e4SDavid E. O'Brien void 127345e5710bSMark Peek autoset_dspmbyte(const Char *pcp) 1274c80476e4SDavid E. O'Brien { 1275c80476e4SDavid E. O'Brien int i; 127645e5710bSMark Peek static const struct dspm_autoset_Table { 1277c80476e4SDavid E. O'Brien Char *n; 1278c80476e4SDavid E. O'Brien Char *v; 1279c80476e4SDavid E. O'Brien } dspmt[] = { 128023338178SMark Peek { STRLANGEUCJP, STReuc }, 128123338178SMark Peek { STRLANGEUCKR, STReuc }, 128223338178SMark Peek { STRLANGEUCZH, STReuc }, 128323338178SMark Peek { STRLANGEUCJPB, STReuc }, 128423338178SMark Peek { STRLANGEUCKRB, STReuc }, 128523338178SMark Peek { STRLANGEUCZHB, STReuc }, 12869ccc37e3SMark Peek #ifdef __linux__ 128723338178SMark Peek { STRLANGEUCJPC, STReuc }, 1288b2d5d167SMark Peek #endif 128923338178SMark Peek { STRLANGSJIS, STRsjis }, 129023338178SMark Peek { STRLANGSJISB, STRsjis }, 129123338178SMark Peek { STRLANGBIG5, STRbig5 }, 129223338178SMark Peek { STRstarutfstar8, STRutf8 }, 1293c80476e4SDavid E. O'Brien { NULL, NULL } 1294c80476e4SDavid E. O'Brien }; 129545e5710bSMark Peek #if defined(HAVE_NL_LANGINFO) && defined(CODESET) 129645e5710bSMark Peek static const struct dspm_autoset_Table dspmc[] = { 129723338178SMark Peek { STRstarutfstar8, STRutf8 }, 129823338178SMark Peek { STReuc, STReuc }, 129923338178SMark Peek { STRGB2312, STReuc }, 130023338178SMark Peek { STRLANGBIG5, STRbig5 }, 130123338178SMark Peek { NULL, NULL } 130223338178SMark Peek }; 130323338178SMark Peek Char *codeset; 130423338178SMark Peek 130523338178SMark Peek codeset = str2short(nl_langinfo(CODESET)); 130623338178SMark Peek if (*codeset != '\0') { 130723338178SMark Peek for (i = 0; dspmc[i].n; i++) { 130845e5710bSMark Peek const Char *estr; 130923338178SMark Peek if (dspmc[i].n[0] && t_pmatch(pcp, dspmc[i].n, &estr, 0) > 0) { 131045e5710bSMark Peek setcopy(CHECK_MBYTEVAR, dspmc[i].v, VAR_READWRITE); 131123338178SMark Peek update_dspmbyte_vars(); 131223338178SMark Peek return; 131323338178SMark Peek } 131423338178SMark Peek } 131523338178SMark Peek } 131623338178SMark Peek #endif 1317c80476e4SDavid E. O'Brien 1318c80476e4SDavid E. O'Brien if (*pcp == '\0') 1319c80476e4SDavid E. O'Brien return; 1320c80476e4SDavid E. O'Brien 1321c80476e4SDavid E. O'Brien for (i = 0; dspmt[i].n; i++) { 132245e5710bSMark Peek const Char *estr; 132323338178SMark Peek if (dspmt[i].n[0] && t_pmatch(pcp, dspmt[i].n, &estr, 0) > 0) { 132445e5710bSMark Peek setcopy(CHECK_MBYTEVAR, dspmt[i].v, VAR_READWRITE); 1325c80476e4SDavid E. O'Brien update_dspmbyte_vars(); 1326c80476e4SDavid E. O'Brien break; 1327c80476e4SDavid E. O'Brien } 1328c80476e4SDavid E. O'Brien } 1329c80476e4SDavid E. O'Brien } 13309ccc37e3SMark Peek # elif defined(AUTOSET_KANJI) 13319ccc37e3SMark Peek void 13329ccc37e3SMark Peek autoset_kanji(void) 13339ccc37e3SMark Peek { 13349ccc37e3SMark Peek char *codeset = nl_langinfo(CODESET); 13359ccc37e3SMark Peek 13369ccc37e3SMark Peek if (*codeset == '\0') { 13379ccc37e3SMark Peek if (adrof(STRnokanji) == NULL) 13389ccc37e3SMark Peek setNS(STRnokanji); 13399ccc37e3SMark Peek return; 13409ccc37e3SMark Peek } 13419ccc37e3SMark Peek 13429ccc37e3SMark Peek if (strcasestr(codeset, "SHIFT_JIS") == (char*)0) { 13439ccc37e3SMark Peek if (adrof(STRnokanji) == NULL) 13449ccc37e3SMark Peek setNS(STRnokanji); 13459ccc37e3SMark Peek return; 13469ccc37e3SMark Peek } 13479ccc37e3SMark Peek 13489ccc37e3SMark Peek if (adrof(STRnokanji) != NULL) 13499ccc37e3SMark Peek unsetv(STRnokanji); 13509ccc37e3SMark Peek } 13519ccc37e3SMark Peek #endif 1352c80476e4SDavid E. O'Brien #endif 1353*19d2e3deSDmitry Chagin 1354*19d2e3deSDmitry Chagin void 1355*19d2e3deSDmitry Chagin update_wordchars(void) 1356*19d2e3deSDmitry Chagin { 1357*19d2e3deSDmitry Chagin if ((word_chars == STR_WORD_CHARS) || (word_chars == STR_WORD_CHARS_VI)) { 1358*19d2e3deSDmitry Chagin word_chars = (VImode ? STR_WORD_CHARS_VI : STR_WORD_CHARS); 1359*19d2e3deSDmitry Chagin } 1360*19d2e3deSDmitry Chagin } 1361