1c80476e4SDavid E. O'Brien /*
2c80476e4SDavid E. O'Brien * sh.set.c: Setting and Clearing of variables
3c80476e4SDavid E. O'Brien */
4c80476e4SDavid E. O'Brien /*-
5c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California.
6c80476e4SDavid E. O'Brien * All rights reserved.
7c80476e4SDavid E. O'Brien *
8c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without
9c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions
10c80476e4SDavid E. O'Brien * are met:
11c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright
12c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer.
13c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright
14c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the
15c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution.
1629301572SMark Peek * 3. Neither the name of the University nor the names of its contributors
17c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software
18c80476e4SDavid E. O'Brien * without specific prior written permission.
19c80476e4SDavid E. O'Brien *
20c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30c80476e4SDavid E. O'Brien * SUCH DAMAGE.
31c80476e4SDavid E. O'Brien */
32c80476e4SDavid E. O'Brien #include "sh.h"
33c80476e4SDavid E. O'Brien #include "ed.h"
34c80476e4SDavid E. O'Brien #include "tw.h"
35c80476e4SDavid E. O'Brien
3623338178SMark Peek #ifdef HAVE_NL_LANGINFO
3723338178SMark Peek #include <langinfo.h>
3823338178SMark Peek #endif
3923338178SMark Peek
4023338178SMark Peek extern int GotTermCaps;
41b2d5d167SMark Peek int numeof = 0;
42c80476e4SDavid E. O'Brien
4345e5710bSMark Peek static void update_vars (Char *);
4445e5710bSMark Peek static Char *getinx (Char *, int *);
4545e5710bSMark Peek static void asx (Char *, int, Char *);
4645e5710bSMark Peek static struct varent *getvx (Char *, int);
4745e5710bSMark Peek static Char *xset (Char *, Char ***);
4845e5710bSMark Peek static Char *operate (int, Char *, Char *);
499ccc37e3SMark Peek static void putn1 (tcsh_number_t);
5045e5710bSMark Peek static struct varent *madrof (Char *, struct varent *);
5145e5710bSMark Peek static void unsetv1 (struct varent *);
5245e5710bSMark Peek static void exportpath (Char **);
5345e5710bSMark Peek static void balance (struct varent *, int, int);
5419d2e3deSDmitry Chagin static int set_noclobber (Char **);
55c80476e4SDavid E. O'Brien
56c80476e4SDavid E. O'Brien /*
57c80476e4SDavid E. O'Brien * C Shell
58c80476e4SDavid E. O'Brien */
59c80476e4SDavid E. O'Brien
60c80476e4SDavid E. O'Brien static void
update_vars(Char * vp)6145e5710bSMark Peek update_vars(Char *vp)
62c80476e4SDavid E. O'Brien {
63c80476e4SDavid E. O'Brien if (eq(vp, STRpath)) {
6445e5710bSMark Peek struct varent *p = adrof(STRpath);
6545e5710bSMark Peek if (p == NULL)
6645e5710bSMark Peek stderror(ERR_NAME | ERR_UNDVAR);
6745e5710bSMark Peek else {
6845e5710bSMark Peek exportpath(p->vec);
69c80476e4SDavid E. O'Brien dohash(NULL, NULL);
70c80476e4SDavid E. O'Brien }
7145e5710bSMark Peek }
7219d2e3deSDmitry Chagin else if (eq(vp, STRnoclobber)) {
7319d2e3deSDmitry Chagin struct varent *p = adrof(STRnoclobber);
7419d2e3deSDmitry Chagin if (p == NULL)
7519d2e3deSDmitry Chagin stderror(ERR_NAME | ERR_UNDVAR);
7619d2e3deSDmitry Chagin else
7719d2e3deSDmitry Chagin no_clobber = set_noclobber(p->vec);
7819d2e3deSDmitry Chagin }
79c80476e4SDavid E. O'Brien else if (eq(vp, STRhistchars)) {
8023338178SMark Peek Char *pn = varval(vp);
81c80476e4SDavid E. O'Brien
82c80476e4SDavid E. O'Brien HIST = *pn++;
839ccc37e3SMark Peek if (HIST)
84c80476e4SDavid E. O'Brien HISTSUB = *pn;
859ccc37e3SMark Peek else
869ccc37e3SMark Peek HISTSUB = HIST;
87c80476e4SDavid E. O'Brien }
88c80476e4SDavid E. O'Brien else if (eq(vp, STRpromptchars)) {
8923338178SMark Peek Char *pn = varval(vp);
90c80476e4SDavid E. O'Brien
91c80476e4SDavid E. O'Brien PRCH = *pn++;
929ccc37e3SMark Peek if (PRCH)
93c80476e4SDavid E. O'Brien PRCHROOT = *pn;
949ccc37e3SMark Peek else
959ccc37e3SMark Peek PRCHROOT = PRCH;
96c80476e4SDavid E. O'Brien }
97c80476e4SDavid E. O'Brien else if (eq(vp, STRhistlit)) {
98c80476e4SDavid E. O'Brien HistLit = 1;
99c80476e4SDavid E. O'Brien }
100c80476e4SDavid E. O'Brien else if (eq(vp, STRuser)) {
101c80476e4SDavid E. O'Brien tsetenv(STRKUSER, varval(vp));
102c80476e4SDavid E. O'Brien tsetenv(STRLOGNAME, varval(vp));
103c80476e4SDavid E. O'Brien }
104c80476e4SDavid E. O'Brien else if (eq(vp, STRgroup)) {
105c80476e4SDavid E. O'Brien tsetenv(STRKGROUP, varval(vp));
106c80476e4SDavid E. O'Brien }
107c80476e4SDavid E. O'Brien else if (eq(vp, STRwordchars)) {
108c80476e4SDavid E. O'Brien word_chars = varval(vp);
109c80476e4SDavid E. O'Brien }
110c80476e4SDavid E. O'Brien else if (eq(vp, STRloginsh)) {
111c80476e4SDavid E. O'Brien loginsh = 1;
112c80476e4SDavid E. O'Brien }
1139ccc37e3SMark Peek else if (eq(vp, STRanyerror)) {
1149ccc37e3SMark Peek anyerror = 1;
1159ccc37e3SMark Peek }
116c80476e4SDavid E. O'Brien else if (eq(vp, STRsymlinks)) {
11723338178SMark Peek Char *pn = varval(vp);
118c80476e4SDavid E. O'Brien
119c80476e4SDavid E. O'Brien if (eq(pn, STRignore))
120c80476e4SDavid E. O'Brien symlinks = SYM_IGNORE;
121c80476e4SDavid E. O'Brien else if (eq(pn, STRexpand))
122c80476e4SDavid E. O'Brien symlinks = SYM_EXPAND;
123c80476e4SDavid E. O'Brien else if (eq(pn, STRchase))
124c80476e4SDavid E. O'Brien symlinks = SYM_CHASE;
125c80476e4SDavid E. O'Brien else
126c80476e4SDavid E. O'Brien symlinks = 0;
127c80476e4SDavid E. O'Brien }
128c80476e4SDavid E. O'Brien else if (eq(vp, STRterm)) {
129c80476e4SDavid E. O'Brien Char *cp = varval(vp);
130c80476e4SDavid E. O'Brien tsetenv(STRKTERM, cp);
131c80476e4SDavid E. O'Brien #ifdef DOESNT_WORK_RIGHT
132c80476e4SDavid E. O'Brien cp = getenv("TERMCAP");
133c80476e4SDavid E. O'Brien if (cp && (*cp != '/')) /* if TERMCAP and not a path */
134c80476e4SDavid E. O'Brien Unsetenv(STRTERMCAP);
135c80476e4SDavid E. O'Brien #endif /* DOESNT_WORK_RIGHT */
136c80476e4SDavid E. O'Brien GotTermCaps = 0;
137c80476e4SDavid E. O'Brien if (noediting && Strcmp(cp, STRnetwork) != 0 &&
138c80476e4SDavid E. O'Brien Strcmp(cp, STRunknown) != 0 && Strcmp(cp, STRdumb) != 0) {
139c80476e4SDavid E. O'Brien editing = 1;
140c80476e4SDavid E. O'Brien noediting = 0;
14145e5710bSMark Peek setNS(STRedit);
142c80476e4SDavid E. O'Brien }
143c80476e4SDavid E. O'Brien ed_Init(); /* reset the editor */
144c80476e4SDavid E. O'Brien }
145c80476e4SDavid E. O'Brien else if (eq(vp, STRhome)) {
14645e5710bSMark Peek Char *cp, *canon;
147c80476e4SDavid E. O'Brien
148c80476e4SDavid E. O'Brien cp = Strsave(varval(vp)); /* get the old value back */
149c80476e4SDavid E. O'Brien /*
150c80476e4SDavid E. O'Brien * convert to cononical pathname (possibly resolving symlinks)
151c80476e4SDavid E. O'Brien */
15245e5710bSMark Peek canon = dcanon(cp, cp);
15345e5710bSMark Peek cleanup_push(canon, xfree);
154c80476e4SDavid E. O'Brien
15545e5710bSMark Peek setcopy(vp, canon, VAR_READWRITE); /* have to save the new val */
156c80476e4SDavid E. O'Brien
157c80476e4SDavid E. O'Brien /* and now mirror home with HOME */
15845e5710bSMark Peek tsetenv(STRKHOME, canon);
159c80476e4SDavid E. O'Brien /* fix directory stack for new tilde home */
160c80476e4SDavid E. O'Brien dtilde();
16145e5710bSMark Peek cleanup_until(canon);
162c80476e4SDavid E. O'Brien }
163c80476e4SDavid E. O'Brien else if (eq(vp, STRedit)) {
164c80476e4SDavid E. O'Brien editing = 1;
165c80476e4SDavid E. O'Brien noediting = 0;
166c80476e4SDavid E. O'Brien /* PWP: add more stuff in here later */
167c80476e4SDavid E. O'Brien }
16819d2e3deSDmitry Chagin else if (eq(vp, STRvimode)) {
16919d2e3deSDmitry Chagin VImode = 1;
17019d2e3deSDmitry Chagin update_wordchars();
17119d2e3deSDmitry Chagin }
172c80476e4SDavid E. O'Brien else if (eq(vp, STRshlvl)) {
173c80476e4SDavid E. O'Brien tsetenv(STRKSHLVL, varval(vp));
174c80476e4SDavid E. O'Brien }
175b2d5d167SMark Peek else if (eq(vp, STRignoreeof)) {
176b2d5d167SMark Peek Char *cp;
177b2d5d167SMark Peek numeof = 0;
178b2d5d167SMark Peek for ((cp = varval(STRignoreeof)); cp && *cp; cp++) {
179b2d5d167SMark Peek if (!Isdigit(*cp)) {
180b2d5d167SMark Peek numeof = 0;
181b2d5d167SMark Peek break;
182b2d5d167SMark Peek }
183b2d5d167SMark Peek numeof = numeof * 10 + *cp - '0';
184b2d5d167SMark Peek }
185b2d5d167SMark Peek if (numeof <= 0) numeof = 26; /* Sanity check */
186b2d5d167SMark Peek }
187c80476e4SDavid E. O'Brien else if (eq(vp, STRbackslash_quote)) {
188c80476e4SDavid E. O'Brien bslash_quote = 1;
189c80476e4SDavid E. O'Brien }
190a15e6f9aSMark Peek else if (eq(vp, STRcompat_expr)) {
191a15e6f9aSMark Peek compat_expr = 1;
192a15e6f9aSMark Peek }
193c80476e4SDavid E. O'Brien else if (eq(vp, STRdirstack)) {
194c80476e4SDavid E. O'Brien dsetstack();
195c80476e4SDavid E. O'Brien }
196c80476e4SDavid E. O'Brien else if (eq(vp, STRrecognize_only_executables)) {
197c80476e4SDavid E. O'Brien tw_cmd_free();
198c80476e4SDavid E. O'Brien }
1996767bd61SMark Peek else if (eq(vp, STRkillring)) {
2009ccc37e3SMark Peek SetKillRing((int)getn(varval(vp)));
2016767bd61SMark Peek }
20219d2e3deSDmitry Chagin else if (eq(vp, STRhistory)) {
20319d2e3deSDmitry Chagin sethistory((int)getn(varval(vp)));
20419d2e3deSDmitry Chagin }
205c80476e4SDavid E. O'Brien #ifndef HAVENOUTMP
206c80476e4SDavid E. O'Brien else if (eq(vp, STRwatch)) {
207c80476e4SDavid E. O'Brien resetwatch();
208c80476e4SDavid E. O'Brien }
209c80476e4SDavid E. O'Brien #endif /* HAVENOUTMP */
210c80476e4SDavid E. O'Brien else if (eq(vp, STRimplicitcd)) {
211c80476e4SDavid E. O'Brien implicit_cd = ((eq(varval(vp), STRverbose)) ? 2 : 1);
212c80476e4SDavid E. O'Brien }
21319d2e3deSDmitry Chagin else if (eq(vp, STRcdtohome)) {
21419d2e3deSDmitry Chagin cdtohome = 1;
21519d2e3deSDmitry Chagin }
216c80476e4SDavid E. O'Brien #ifdef COLOR_LS_F
217c80476e4SDavid E. O'Brien else if (eq(vp, STRcolor)) {
218c80476e4SDavid E. O'Brien set_color_context();
219c80476e4SDavid E. O'Brien }
220c80476e4SDavid E. O'Brien #endif /* COLOR_LS_F */
221c80476e4SDavid E. O'Brien #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE)
222c80476e4SDavid E. O'Brien else if (eq(vp, CHECK_MBYTEVAR) || eq(vp, STRnokanji)) {
223c80476e4SDavid E. O'Brien update_dspmbyte_vars();
224c80476e4SDavid E. O'Brien }
225c80476e4SDavid E. O'Brien #endif
2263b6eaa7bSAndrey A. Chernov #ifdef NLS_CATALOGS
2273b6eaa7bSAndrey A. Chernov else if (eq(vp, STRcatalog)) {
22823338178SMark Peek nlsclose();
2293b6eaa7bSAndrey A. Chernov nlsinit();
2303b6eaa7bSAndrey A. Chernov }
23129301572SMark Peek #if defined(FILEC) && defined(TIOCSTI)
23229301572SMark Peek else if (eq(vp, STRfilec))
23329301572SMark Peek filec = 1;
23429301572SMark Peek #endif
2353b6eaa7bSAndrey A. Chernov #endif /* NLS_CATALOGS */
236c80476e4SDavid E. O'Brien }
237c80476e4SDavid E. O'Brien
238c80476e4SDavid E. O'Brien
239c80476e4SDavid E. O'Brien /*ARGSUSED*/
240c80476e4SDavid E. O'Brien void
doset(Char ** v,struct command * c)24145e5710bSMark Peek doset(Char **v, struct command *c)
242c80476e4SDavid E. O'Brien {
24323338178SMark Peek Char *p;
2449ccc37e3SMark Peek Char *vp;
245c80476e4SDavid E. O'Brien Char **vecp;
24623338178SMark Peek int hadsub;
247c80476e4SDavid E. O'Brien int subscr;
248c80476e4SDavid E. O'Brien int flags = VAR_READWRITE;
24923338178SMark Peek int first_match = 0;
25023338178SMark Peek int last_match = 0;
25123338178SMark Peek int changed = 0;
252c80476e4SDavid E. O'Brien
253c80476e4SDavid E. O'Brien USE(c);
254c80476e4SDavid E. O'Brien v++;
255c80476e4SDavid E. O'Brien do {
256c80476e4SDavid E. O'Brien changed = 0;
257c80476e4SDavid E. O'Brien /*
258c80476e4SDavid E. O'Brien * Readonly addition From: Tim P. Starrin <noid@cyborg.larc.nasa.gov>
259c80476e4SDavid E. O'Brien */
260c80476e4SDavid E. O'Brien if (*v && eq(*v, STRmr)) {
261c80476e4SDavid E. O'Brien flags = VAR_READONLY;
262c80476e4SDavid E. O'Brien v++;
263c80476e4SDavid E. O'Brien changed = 1;
264c80476e4SDavid E. O'Brien }
265c80476e4SDavid E. O'Brien if (*v && eq(*v, STRmf) && !last_match) {
266c80476e4SDavid E. O'Brien first_match = 1;
267c80476e4SDavid E. O'Brien v++;
268c80476e4SDavid E. O'Brien changed = 1;
269c80476e4SDavid E. O'Brien }
270c80476e4SDavid E. O'Brien if (*v && eq(*v, STRml) && !first_match) {
271c80476e4SDavid E. O'Brien last_match = 1;
272c80476e4SDavid E. O'Brien v++;
273c80476e4SDavid E. O'Brien changed = 1;
274c80476e4SDavid E. O'Brien }
275c80476e4SDavid E. O'Brien } while (changed);
276c80476e4SDavid E. O'Brien p = *v++;
277c80476e4SDavid E. O'Brien if (p == 0) {
278c80476e4SDavid E. O'Brien plist(&shvhed, flags);
279c80476e4SDavid E. O'Brien return;
280c80476e4SDavid E. O'Brien }
281c80476e4SDavid E. O'Brien do {
282c80476e4SDavid E. O'Brien hadsub = 0;
283c80476e4SDavid E. O'Brien vp = p;
2849ccc37e3SMark Peek if (!letter(*p))
285c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_VARBEGIN);
2869ccc37e3SMark Peek do {
2879ccc37e3SMark Peek p++;
2889ccc37e3SMark Peek } while (alnum(*p));
289c80476e4SDavid E. O'Brien if (*p == '[') {
290c80476e4SDavid E. O'Brien hadsub++;
291c80476e4SDavid E. O'Brien p = getinx(p, &subscr);
292c80476e4SDavid E. O'Brien }
2939ccc37e3SMark Peek if (*p != '\0' && *p != '=')
2949ccc37e3SMark Peek stderror(ERR_NAME | ERR_VARALNUM);
2959ccc37e3SMark Peek if (*p == '=') {
2969ccc37e3SMark Peek *p++ = '\0';
2979ccc37e3SMark Peek if (*p == '\0' && *v != NULL && **v == '(')
298c80476e4SDavid E. O'Brien p = *v++;
299c80476e4SDavid E. O'Brien }
300c80476e4SDavid E. O'Brien else if (*v && eq(*v, STRequal)) {
3019ccc37e3SMark Peek if (*++v != NULL)
302c80476e4SDavid E. O'Brien p = *v++;
303c80476e4SDavid E. O'Brien }
304c80476e4SDavid E. O'Brien if (eq(p, STRLparen)) {
30523338178SMark Peek Char **e = v;
306c80476e4SDavid E. O'Brien
307c80476e4SDavid E. O'Brien if (hadsub)
308c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_SYNTAX);
309c80476e4SDavid E. O'Brien for (;;) {
310c80476e4SDavid E. O'Brien if (!*e)
311c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_MISSING, ')');
312c80476e4SDavid E. O'Brien if (**e == ')')
313c80476e4SDavid E. O'Brien break;
314c80476e4SDavid E. O'Brien e++;
315c80476e4SDavid E. O'Brien }
316c80476e4SDavid E. O'Brien p = *e;
317c80476e4SDavid E. O'Brien *e = 0;
318c80476e4SDavid E. O'Brien vecp = saveblk(v);
319c80476e4SDavid E. O'Brien if (first_match)
320c80476e4SDavid E. O'Brien flags |= VAR_FIRST;
321c80476e4SDavid E. O'Brien else if (last_match)
322c80476e4SDavid E. O'Brien flags |= VAR_LAST;
323c80476e4SDavid E. O'Brien
324c80476e4SDavid E. O'Brien set1(vp, vecp, &shvhed, flags);
325c80476e4SDavid E. O'Brien *e = p;
326c80476e4SDavid E. O'Brien v = e + 1;
327c80476e4SDavid E. O'Brien }
32845e5710bSMark Peek else if (hadsub) {
32945e5710bSMark Peek Char *copy;
33045e5710bSMark Peek
33145e5710bSMark Peek copy = Strsave(p);
33245e5710bSMark Peek cleanup_push(copy, xfree);
33345e5710bSMark Peek asx(vp, subscr, copy);
33445e5710bSMark Peek cleanup_ignore(copy);
33545e5710bSMark Peek cleanup_until(copy);
33645e5710bSMark Peek }
337c80476e4SDavid E. O'Brien else
33845e5710bSMark Peek setv(vp, Strsave(p), flags);
339c80476e4SDavid E. O'Brien update_vars(vp);
340c80476e4SDavid E. O'Brien } while ((p = *v++) != NULL);
341c80476e4SDavid E. O'Brien }
342c80476e4SDavid E. O'Brien
343c80476e4SDavid E. O'Brien static Char *
getinx(Char * cp,int * ip)34445e5710bSMark Peek getinx(Char *cp, int *ip)
345c80476e4SDavid E. O'Brien {
346c80476e4SDavid E. O'Brien *ip = 0;
347c80476e4SDavid E. O'Brien *cp++ = 0;
348c80476e4SDavid E. O'Brien while (*cp && Isdigit(*cp))
349c80476e4SDavid E. O'Brien *ip = *ip * 10 + *cp++ - '0';
350c80476e4SDavid E. O'Brien if (*cp++ != ']')
351c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_SUBSCRIPT);
352c80476e4SDavid E. O'Brien return (cp);
353c80476e4SDavid E. O'Brien }
354c80476e4SDavid E. O'Brien
355c80476e4SDavid E. O'Brien static void
asx(Char * vp,int subscr,Char * p)35645e5710bSMark Peek asx(Char *vp, int subscr, Char *p)
357c80476e4SDavid E. O'Brien {
35823338178SMark Peek struct varent *v = getvx(vp, subscr);
35945e5710bSMark Peek Char *prev;
360c80476e4SDavid E. O'Brien
361c80476e4SDavid E. O'Brien if (v->v_flags & VAR_READONLY)
362c80476e4SDavid E. O'Brien stderror(ERR_READONLY|ERR_NAME, v->v_name);
36345e5710bSMark Peek prev = v->vec[subscr - 1];
36445e5710bSMark Peek cleanup_push(prev, xfree);
365c80476e4SDavid E. O'Brien v->vec[subscr - 1] = globone(p, G_APPEND);
36645e5710bSMark Peek cleanup_until(prev);
367c80476e4SDavid E. O'Brien }
368c80476e4SDavid E. O'Brien
369c80476e4SDavid E. O'Brien static struct varent *
getvx(Char * vp,int subscr)37045e5710bSMark Peek getvx(Char *vp, int subscr)
371c80476e4SDavid E. O'Brien {
37223338178SMark Peek struct varent *v = adrof(vp);
373c80476e4SDavid E. O'Brien
374c80476e4SDavid E. O'Brien if (v == 0)
375c80476e4SDavid E. O'Brien udvar(vp);
376c80476e4SDavid E. O'Brien if (subscr < 1 || subscr > blklen(v->vec))
377c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_RANGE);
378c80476e4SDavid E. O'Brien return (v);
379c80476e4SDavid E. O'Brien }
380c80476e4SDavid E. O'Brien
381c80476e4SDavid E. O'Brien /*ARGSUSED*/
382c80476e4SDavid E. O'Brien void
dolet(Char ** v,struct command * dummy)38345e5710bSMark Peek dolet(Char **v, struct command *dummy)
384c80476e4SDavid E. O'Brien {
38523338178SMark Peek Char *p;
386c80476e4SDavid E. O'Brien Char *vp, c, op;
38723338178SMark Peek int hadsub;
388c80476e4SDavid E. O'Brien int subscr;
389c80476e4SDavid E. O'Brien
390c80476e4SDavid E. O'Brien USE(dummy);
391c80476e4SDavid E. O'Brien v++;
392c80476e4SDavid E. O'Brien p = *v++;
393c80476e4SDavid E. O'Brien if (p == 0) {
394c80476e4SDavid E. O'Brien prvars();
395c80476e4SDavid E. O'Brien return;
396c80476e4SDavid E. O'Brien }
397c80476e4SDavid E. O'Brien do {
398c80476e4SDavid E. O'Brien hadsub = 0;
399c80476e4SDavid E. O'Brien vp = p;
400c80476e4SDavid E. O'Brien if (letter(*p))
401c80476e4SDavid E. O'Brien for (; alnum(*p); p++)
402c80476e4SDavid E. O'Brien continue;
403c80476e4SDavid E. O'Brien if (vp == p || !letter(*vp))
404c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_VARBEGIN);
405c80476e4SDavid E. O'Brien if (*p == '[') {
406c80476e4SDavid E. O'Brien hadsub++;
407c80476e4SDavid E. O'Brien p = getinx(p, &subscr);
408c80476e4SDavid E. O'Brien }
409c80476e4SDavid E. O'Brien if (*p == 0 && *v)
410c80476e4SDavid E. O'Brien p = *v++;
411c80476e4SDavid E. O'Brien if ((op = *p) != 0)
412c80476e4SDavid E. O'Brien *p++ = 0;
413c80476e4SDavid E. O'Brien else
414c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_ASSIGN);
415c80476e4SDavid E. O'Brien
416c80476e4SDavid E. O'Brien /*
417c80476e4SDavid E. O'Brien * if there is no expression after the '=' then print a "Syntax Error"
418c80476e4SDavid E. O'Brien * message - strike
419c80476e4SDavid E. O'Brien */
420c80476e4SDavid E. O'Brien if (*p == '\0' && *v == NULL)
421c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_ASSIGN);
422c80476e4SDavid E. O'Brien
423c80476e4SDavid E. O'Brien vp = Strsave(vp);
42445e5710bSMark Peek cleanup_push(vp, xfree);
425c80476e4SDavid E. O'Brien if (op == '=') {
426c80476e4SDavid E. O'Brien c = '=';
427c80476e4SDavid E. O'Brien p = xset(p, &v);
428c80476e4SDavid E. O'Brien }
429c80476e4SDavid E. O'Brien else {
430c80476e4SDavid E. O'Brien c = *p++;
431c80476e4SDavid E. O'Brien if (any("+-", c)) {
432c80476e4SDavid E. O'Brien if (c != op || *p)
433c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_UNKNOWNOP);
434c80476e4SDavid E. O'Brien p = Strsave(STR1);
435c80476e4SDavid E. O'Brien }
436c80476e4SDavid E. O'Brien else {
437c80476e4SDavid E. O'Brien if (any("<>", op)) {
438c80476e4SDavid E. O'Brien if (c != op)
439c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_UNKNOWNOP);
440c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_SYNTAX);
441c80476e4SDavid E. O'Brien }
442c80476e4SDavid E. O'Brien if (c != '=')
443c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_UNKNOWNOP);
444c80476e4SDavid E. O'Brien p = xset(p, &v);
445c80476e4SDavid E. O'Brien }
446c80476e4SDavid E. O'Brien }
44745e5710bSMark Peek cleanup_push(p, xfree);
448c80476e4SDavid E. O'Brien if (op == '=') {
449c80476e4SDavid E. O'Brien if (hadsub)
450c80476e4SDavid E. O'Brien asx(vp, subscr, p);
451c80476e4SDavid E. O'Brien else
45245e5710bSMark Peek setv(vp, p, VAR_READWRITE);
45345e5710bSMark Peek cleanup_ignore(p);
454c80476e4SDavid E. O'Brien }
455c80476e4SDavid E. O'Brien else if (hadsub) {
456c80476e4SDavid E. O'Brien struct varent *gv = getvx(vp, subscr);
45745e5710bSMark Peek Char *val;
458c80476e4SDavid E. O'Brien
45945e5710bSMark Peek val = operate(op, gv->vec[subscr - 1], p);
46045e5710bSMark Peek cleanup_push(val, xfree);
46145e5710bSMark Peek asx(vp, subscr, val);
46245e5710bSMark Peek cleanup_ignore(val);
46345e5710bSMark Peek cleanup_until(val);
464c80476e4SDavid E. O'Brien }
46545e5710bSMark Peek else {
46645e5710bSMark Peek Char *val;
46745e5710bSMark Peek
46845e5710bSMark Peek val = operate(op, varval(vp), p);
46945e5710bSMark Peek cleanup_push(val, xfree);
47045e5710bSMark Peek setv(vp, val, VAR_READWRITE);
47145e5710bSMark Peek cleanup_ignore(val);
47245e5710bSMark Peek cleanup_until(val);
47345e5710bSMark Peek }
474c80476e4SDavid E. O'Brien update_vars(vp);
47545e5710bSMark Peek cleanup_until(vp);
476c80476e4SDavid E. O'Brien } while ((p = *v++) != NULL);
477c80476e4SDavid E. O'Brien }
478c80476e4SDavid E. O'Brien
479c80476e4SDavid E. O'Brien static Char *
xset(Char * cp,Char *** vp)48045e5710bSMark Peek xset(Char *cp, Char ***vp)
481c80476e4SDavid E. O'Brien {
48223338178SMark Peek Char *dp;
483c80476e4SDavid E. O'Brien
484c80476e4SDavid E. O'Brien if (*cp) {
485c80476e4SDavid E. O'Brien dp = Strsave(cp);
486c80476e4SDavid E. O'Brien --(*vp);
48745e5710bSMark Peek xfree(** vp);
488c80476e4SDavid E. O'Brien **vp = dp;
489c80476e4SDavid E. O'Brien }
490c80476e4SDavid E. O'Brien return (putn(expr(vp)));
491c80476e4SDavid E. O'Brien }
492c80476e4SDavid E. O'Brien
493c80476e4SDavid E. O'Brien static Char *
operate(int op,Char * vp,Char * p)49445e5710bSMark Peek operate(int op, Char *vp, Char *p)
495c80476e4SDavid E. O'Brien {
496c80476e4SDavid E. O'Brien Char opr[2];
497c80476e4SDavid E. O'Brien Char *vec[5];
49823338178SMark Peek Char **v = vec;
499c80476e4SDavid E. O'Brien Char **vecp = v;
5009ccc37e3SMark Peek tcsh_number_t i;
501c80476e4SDavid E. O'Brien
502c80476e4SDavid E. O'Brien if (op != '=') {
503c80476e4SDavid E. O'Brien if (*vp)
504c80476e4SDavid E. O'Brien *v++ = vp;
50545e5710bSMark Peek opr[0] = op;
506c80476e4SDavid E. O'Brien opr[1] = 0;
507c80476e4SDavid E. O'Brien *v++ = opr;
508c80476e4SDavid E. O'Brien if (op == '<' || op == '>')
509c80476e4SDavid E. O'Brien *v++ = opr;
510c80476e4SDavid E. O'Brien }
511c80476e4SDavid E. O'Brien *v++ = p;
512c80476e4SDavid E. O'Brien *v++ = 0;
513c80476e4SDavid E. O'Brien i = expr(&vecp);
514c80476e4SDavid E. O'Brien if (*vecp)
515c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_EXPRESSION);
516c80476e4SDavid E. O'Brien return (putn(i));
517c80476e4SDavid E. O'Brien }
518c80476e4SDavid E. O'Brien
51945e5710bSMark Peek static Char *putp;
520c80476e4SDavid E. O'Brien
521c80476e4SDavid E. O'Brien Char *
putn(tcsh_number_t n)5229ccc37e3SMark Peek putn(tcsh_number_t n)
523c80476e4SDavid E. O'Brien {
5249ccc37e3SMark Peek Char nbuf[1024]; /* Enough even for octal */
525c80476e4SDavid E. O'Brien
526c80476e4SDavid E. O'Brien putp = nbuf;
527c80476e4SDavid E. O'Brien if (n < 0) {
528c80476e4SDavid E. O'Brien n = -n;
529c80476e4SDavid E. O'Brien *putp++ = '-';
530c80476e4SDavid E. O'Brien }
531c80476e4SDavid E. O'Brien putn1(n);
532c80476e4SDavid E. O'Brien *putp = 0;
533c80476e4SDavid E. O'Brien return (Strsave(nbuf));
534c80476e4SDavid E. O'Brien }
535c80476e4SDavid E. O'Brien
536c80476e4SDavid E. O'Brien static void
putn1(tcsh_number_t n)5379ccc37e3SMark Peek putn1(tcsh_number_t n)
538c80476e4SDavid E. O'Brien {
539c80476e4SDavid E. O'Brien if (n > 9)
540c80476e4SDavid E. O'Brien putn1(n / 10);
5419ccc37e3SMark Peek *putp++ = (Char)(n % 10 + '0');
542c80476e4SDavid E. O'Brien }
543c80476e4SDavid E. O'Brien
5449ccc37e3SMark Peek tcsh_number_t
getn(const Char * cp)5459ccc37e3SMark Peek getn(const Char *cp)
546c80476e4SDavid E. O'Brien {
5479ccc37e3SMark Peek tcsh_number_t n;
548c80476e4SDavid E. O'Brien int sign;
549a15e6f9aSMark Peek int base;
550c80476e4SDavid E. O'Brien
551c80476e4SDavid E. O'Brien if (!cp) /* PWP: extra error checking */
552c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_BADNUM);
553c80476e4SDavid E. O'Brien
554c80476e4SDavid E. O'Brien sign = 0;
555c80476e4SDavid E. O'Brien if (cp[0] == '+' && cp[1])
556c80476e4SDavid E. O'Brien cp++;
557c80476e4SDavid E. O'Brien if (*cp == '-') {
558c80476e4SDavid E. O'Brien sign++;
559c80476e4SDavid E. O'Brien cp++;
560c80476e4SDavid E. O'Brien if (!Isdigit(*cp))
561c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_BADNUM);
562c80476e4SDavid E. O'Brien }
563a15e6f9aSMark Peek
5649ccc37e3SMark Peek if (cp[0] == '0' && cp[1] && is_set(STRparseoctal))
565a15e6f9aSMark Peek base = 8;
566a15e6f9aSMark Peek else
567a15e6f9aSMark Peek base = 10;
568a15e6f9aSMark Peek
569c80476e4SDavid E. O'Brien n = 0;
570c80476e4SDavid E. O'Brien while (Isdigit(*cp))
571a15e6f9aSMark Peek {
572a15e6f9aSMark Peek if (base == 8 && *cp >= '8')
573a15e6f9aSMark Peek stderror(ERR_NAME | ERR_BADNUM);
574a15e6f9aSMark Peek n = n * base + *cp++ - '0';
575a15e6f9aSMark Peek }
576c80476e4SDavid E. O'Brien if (*cp)
577c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_BADNUM);
578c80476e4SDavid E. O'Brien return (sign ? -n : n);
579c80476e4SDavid E. O'Brien }
580c80476e4SDavid E. O'Brien
581c80476e4SDavid E. O'Brien Char *
value1(Char * var,struct varent * head)58245e5710bSMark Peek value1(Char *var, struct varent *head)
583c80476e4SDavid E. O'Brien {
58423338178SMark Peek struct varent *vp;
585c80476e4SDavid E. O'Brien
586c80476e4SDavid E. O'Brien if (!var || !head) /* PWP: extra error checking */
587c80476e4SDavid E. O'Brien return (STRNULL);
588c80476e4SDavid E. O'Brien
589c80476e4SDavid E. O'Brien vp = adrof1(var, head);
59029301572SMark Peek return ((vp == NULL || vp->vec == NULL || vp->vec[0] == NULL) ?
59129301572SMark Peek STRNULL : vp->vec[0]);
592c80476e4SDavid E. O'Brien }
593c80476e4SDavid E. O'Brien
594c80476e4SDavid E. O'Brien static struct varent *
madrof(Char * pat,struct varent * vp)59545e5710bSMark Peek madrof(Char *pat, struct varent *vp)
596c80476e4SDavid E. O'Brien {
59723338178SMark Peek struct varent *vp1;
598c80476e4SDavid E. O'Brien
599c80476e4SDavid E. O'Brien for (vp = vp->v_left; vp; vp = vp->v_right) {
600c80476e4SDavid E. O'Brien if (vp->v_left && (vp1 = madrof(pat, vp)) != NULL)
601c80476e4SDavid E. O'Brien return vp1;
602c80476e4SDavid E. O'Brien if (Gmatch(vp->v_name, pat))
603c80476e4SDavid E. O'Brien return vp;
604c80476e4SDavid E. O'Brien }
605c80476e4SDavid E. O'Brien return vp;
606c80476e4SDavid E. O'Brien }
607c80476e4SDavid E. O'Brien
608c80476e4SDavid E. O'Brien struct varent *
adrof1(const Char * name,struct varent * v)60945e5710bSMark Peek adrof1(const Char *name, struct varent *v)
610c80476e4SDavid E. O'Brien {
611c80476e4SDavid E. O'Brien int cmp;
612c80476e4SDavid E. O'Brien
613c80476e4SDavid E. O'Brien v = v->v_left;
614c80476e4SDavid E. O'Brien while (v && ((cmp = *name - *v->v_name) != 0 ||
615c80476e4SDavid E. O'Brien (cmp = Strcmp(name, v->v_name)) != 0))
616c80476e4SDavid E. O'Brien if (cmp < 0)
617c80476e4SDavid E. O'Brien v = v->v_left;
618c80476e4SDavid E. O'Brien else
619c80476e4SDavid E. O'Brien v = v->v_right;
620c80476e4SDavid E. O'Brien return v;
621c80476e4SDavid E. O'Brien }
622c80476e4SDavid E. O'Brien
62345e5710bSMark Peek void
setcopy(const Char * var,const Char * val,int flags)62445e5710bSMark Peek setcopy(const Char *var, const Char *val, int flags)
62545e5710bSMark Peek {
62645e5710bSMark Peek Char *copy;
62745e5710bSMark Peek
62845e5710bSMark Peek copy = Strsave(val);
62945e5710bSMark Peek cleanup_push(copy, xfree);
63045e5710bSMark Peek setv(var, copy, flags);
63145e5710bSMark Peek cleanup_ignore(copy);
63245e5710bSMark Peek cleanup_until(copy);
63345e5710bSMark Peek }
63445e5710bSMark Peek
635c80476e4SDavid E. O'Brien /*
636c80476e4SDavid E. O'Brien * The caller is responsible for putting value in a safe place
637c80476e4SDavid E. O'Brien */
638c80476e4SDavid E. O'Brien void
setv(const Char * var,Char * val,int flags)63945e5710bSMark Peek setv(const Char *var, Char *val, int flags)
640c80476e4SDavid E. O'Brien {
64145e5710bSMark Peek Char **vec = xmalloc(2 * sizeof(Char **));
642c80476e4SDavid E. O'Brien
643c80476e4SDavid E. O'Brien vec[0] = val;
644c80476e4SDavid E. O'Brien vec[1] = 0;
645c80476e4SDavid E. O'Brien set1(var, vec, &shvhed, flags);
646c80476e4SDavid E. O'Brien }
647c80476e4SDavid E. O'Brien
648c80476e4SDavid E. O'Brien void
set1(const Char * var,Char ** vec,struct varent * head,int flags)64945e5710bSMark Peek set1(const Char *var, Char **vec, struct varent *head, int flags)
650c80476e4SDavid E. O'Brien {
65123338178SMark Peek Char **oldv = vec;
652c80476e4SDavid E. O'Brien
653c80476e4SDavid E. O'Brien if ((flags & VAR_NOGLOB) == 0) {
65445e5710bSMark Peek int gflag;
65545e5710bSMark Peek
65645e5710bSMark Peek gflag = tglob(oldv);
657c80476e4SDavid E. O'Brien if (gflag) {
65845e5710bSMark Peek vec = globall(oldv, gflag);
659*5224c2a3SDmitry Chagin if (vec == NULL) {
660c80476e4SDavid E. O'Brien blkfree(oldv);
661c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_NOMATCH);
662c80476e4SDavid E. O'Brien }
663c80476e4SDavid E. O'Brien blkfree(oldv);
664c80476e4SDavid E. O'Brien }
665c80476e4SDavid E. O'Brien }
666c80476e4SDavid E. O'Brien /*
667c80476e4SDavid E. O'Brien * Uniqueness addition from: Michael Veksler <mveksler@vnet.ibm.com>
668c80476e4SDavid E. O'Brien */
669c80476e4SDavid E. O'Brien if ( flags & (VAR_FIRST | VAR_LAST) ) {
670c80476e4SDavid E. O'Brien /*
671c80476e4SDavid E. O'Brien * Code for -f (VAR_FIRST) and -l (VAR_LAST) options.
672c80476e4SDavid E. O'Brien * Method:
673c80476e4SDavid E. O'Brien * Delete all duplicate words leaving "holes" in the word array (vec).
674c80476e4SDavid E. O'Brien * Then remove the "holes", keeping the order of the words unchanged.
675c80476e4SDavid E. O'Brien */
676*5224c2a3SDmitry Chagin if (vec[0] && vec[1]) { /* more than one word ? */
677c80476e4SDavid E. O'Brien int i, j;
678c80476e4SDavid E. O'Brien int num_items;
679c80476e4SDavid E. O'Brien
680c80476e4SDavid E. O'Brien for (num_items = 0; vec[num_items]; num_items++)
681c80476e4SDavid E. O'Brien continue;
682c80476e4SDavid E. O'Brien if (flags & VAR_FIRST) {
683c80476e4SDavid E. O'Brien /* delete duplications, keeping first occurance */
684c80476e4SDavid E. O'Brien for (i = 1; i < num_items; i++)
685c80476e4SDavid E. O'Brien for (j = 0; j < i; j++)
686c80476e4SDavid E. O'Brien /* If have earlier identical item, remove i'th item */
687c80476e4SDavid E. O'Brien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) {
68845e5710bSMark Peek xfree(vec[i]);
689c80476e4SDavid E. O'Brien vec[i] = NULL;
690c80476e4SDavid E. O'Brien break;
691c80476e4SDavid E. O'Brien }
692c80476e4SDavid E. O'Brien } else if (flags & VAR_LAST) {
693c80476e4SDavid E. O'Brien /* delete duplications, keeping last occurance */
694c80476e4SDavid E. O'Brien for (i = 0; i < num_items - 1; i++)
695c80476e4SDavid E. O'Brien for (j = i + 1; j < num_items; j++)
696c80476e4SDavid E. O'Brien /* If have later identical item, remove i'th item */
697c80476e4SDavid E. O'Brien if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) {
698c80476e4SDavid E. O'Brien /* remove identical item (the first) */
69945e5710bSMark Peek xfree(vec[i]);
700c80476e4SDavid E. O'Brien vec[i] = NULL;
701c80476e4SDavid E. O'Brien }
702c80476e4SDavid E. O'Brien }
703c80476e4SDavid E. O'Brien /* Compress items - remove empty items */
704c80476e4SDavid E. O'Brien for (j = i = 0; i < num_items; i++)
705c80476e4SDavid E. O'Brien if (vec[i])
706c80476e4SDavid E. O'Brien vec[j++] = vec[i];
707c80476e4SDavid E. O'Brien
708c80476e4SDavid E. O'Brien /* NULL-fy remaining items */
709c80476e4SDavid E. O'Brien for (; j < num_items; j++)
710c80476e4SDavid E. O'Brien vec[j] = NULL;
711c80476e4SDavid E. O'Brien }
712c80476e4SDavid E. O'Brien /* don't let the attribute propagate */
713c80476e4SDavid E. O'Brien flags &= ~(VAR_FIRST|VAR_LAST);
714c80476e4SDavid E. O'Brien }
715c80476e4SDavid E. O'Brien setq(var, vec, head, flags);
716c80476e4SDavid E. O'Brien }
717c80476e4SDavid E. O'Brien
718c80476e4SDavid E. O'Brien
719c80476e4SDavid E. O'Brien void
setq(const Char * name,Char ** vec,struct varent * p,int flags)72045e5710bSMark Peek setq(const Char *name, Char **vec, struct varent *p, int flags)
721c80476e4SDavid E. O'Brien {
72223338178SMark Peek struct varent *c;
72323338178SMark Peek int f;
724c80476e4SDavid E. O'Brien
725c80476e4SDavid E. O'Brien f = 0; /* tree hangs off the header's left link */
726c80476e4SDavid E. O'Brien while ((c = p->v_link[f]) != 0) {
727c80476e4SDavid E. O'Brien if ((f = *name - *c->v_name) == 0 &&
728c80476e4SDavid E. O'Brien (f = Strcmp(name, c->v_name)) == 0) {
729c80476e4SDavid E. O'Brien if (c->v_flags & VAR_READONLY)
730c80476e4SDavid E. O'Brien stderror(ERR_READONLY|ERR_NAME, c->v_name);
731c80476e4SDavid E. O'Brien blkfree(c->vec);
732c80476e4SDavid E. O'Brien c->v_flags = flags;
733c80476e4SDavid E. O'Brien trim(c->vec = vec);
734c80476e4SDavid E. O'Brien return;
735c80476e4SDavid E. O'Brien }
736c80476e4SDavid E. O'Brien p = c;
737c80476e4SDavid E. O'Brien f = f > 0;
738c80476e4SDavid E. O'Brien }
73945e5710bSMark Peek p->v_link[f] = c = xmalloc(sizeof(struct varent));
740c80476e4SDavid E. O'Brien c->v_name = Strsave(name);
741c80476e4SDavid E. O'Brien c->v_flags = flags;
742c80476e4SDavid E. O'Brien c->v_bal = 0;
743c80476e4SDavid E. O'Brien c->v_left = c->v_right = 0;
744c80476e4SDavid E. O'Brien c->v_parent = p;
745c80476e4SDavid E. O'Brien balance(p, f, 0);
746c80476e4SDavid E. O'Brien trim(c->vec = vec);
747c80476e4SDavid E. O'Brien }
748c80476e4SDavid E. O'Brien
749c80476e4SDavid E. O'Brien /*ARGSUSED*/
750c80476e4SDavid E. O'Brien void
unset(Char ** v,struct command * c)75145e5710bSMark Peek unset(Char **v, struct command *c)
752c80476e4SDavid E. O'Brien {
75323338178SMark Peek int did_roe, did_edit;
754c80476e4SDavid E. O'Brien
755c80476e4SDavid E. O'Brien USE(c);
756c80476e4SDavid E. O'Brien did_roe = adrof(STRrecognize_only_executables) != NULL;
757c80476e4SDavid E. O'Brien did_edit = adrof(STRedit) != NULL;
758c80476e4SDavid E. O'Brien unset1(v, &shvhed);
75929301572SMark Peek
76029301572SMark Peek #if defined(FILEC) && defined(TIOCSTI)
76129301572SMark Peek if (adrof(STRfilec) == 0)
76229301572SMark Peek filec = 0;
76329301572SMark Peek #endif /* FILEC && TIOCSTI */
76429301572SMark Peek
765c80476e4SDavid E. O'Brien if (adrof(STRhistchars) == 0) {
766c80476e4SDavid E. O'Brien HIST = '!';
767c80476e4SDavid E. O'Brien HISTSUB = '^';
768c80476e4SDavid E. O'Brien }
769b2d5d167SMark Peek if (adrof(STRignoreeof) == 0)
770b2d5d167SMark Peek numeof = 0;
771c80476e4SDavid E. O'Brien if (adrof(STRpromptchars) == 0) {
7729ccc37e3SMark Peek PRCH = tcsh ? '>' : '%';
773c80476e4SDavid E. O'Brien PRCHROOT = '#';
774c80476e4SDavid E. O'Brien }
77519d2e3deSDmitry Chagin if (adrof(STRnoclobber) == 0)
77619d2e3deSDmitry Chagin no_clobber = 0;
777c80476e4SDavid E. O'Brien if (adrof(STRhistlit) == 0)
778c80476e4SDavid E. O'Brien HistLit = 0;
779c80476e4SDavid E. O'Brien if (adrof(STRloginsh) == 0)
780c80476e4SDavid E. O'Brien loginsh = 0;
7819ccc37e3SMark Peek if (adrof(STRanyerror) == 0)
7829ccc37e3SMark Peek anyerror = 0;
783c80476e4SDavid E. O'Brien if (adrof(STRwordchars) == 0)
784c80476e4SDavid E. O'Brien word_chars = STR_WORD_CHARS;
785c80476e4SDavid E. O'Brien if (adrof(STRedit) == 0)
786c80476e4SDavid E. O'Brien editing = 0;
787c80476e4SDavid E. O'Brien if (adrof(STRbackslash_quote) == 0)
788c80476e4SDavid E. O'Brien bslash_quote = 0;
789a15e6f9aSMark Peek if (adrof(STRcompat_expr) == 0)
790a15e6f9aSMark Peek compat_expr = 0;
791c80476e4SDavid E. O'Brien if (adrof(STRsymlinks) == 0)
792c80476e4SDavid E. O'Brien symlinks = 0;
793c80476e4SDavid E. O'Brien if (adrof(STRimplicitcd) == 0)
794c80476e4SDavid E. O'Brien implicit_cd = 0;
79519d2e3deSDmitry Chagin if (adrof(STRcdtohome) == 0)
79619d2e3deSDmitry Chagin cdtohome = 0;
7976767bd61SMark Peek if (adrof(STRkillring) == 0)
7986767bd61SMark Peek SetKillRing(0);
799c80476e4SDavid E. O'Brien if (did_edit && noediting && adrof(STRedit) == 0)
800c80476e4SDavid E. O'Brien noediting = 0;
80119d2e3deSDmitry Chagin if (adrof(STRvimode) == 0)
80219d2e3deSDmitry Chagin VImode = 0;
803c80476e4SDavid E. O'Brien if (did_roe && adrof(STRrecognize_only_executables) == 0)
804c80476e4SDavid E. O'Brien tw_cmd_free();
80519d2e3deSDmitry Chagin if (adrof(STRhistory) == 0)
80619d2e3deSDmitry Chagin sethistory(0);
807c80476e4SDavid E. O'Brien #ifdef COLOR_LS_F
808c80476e4SDavid E. O'Brien if (adrof(STRcolor) == 0)
809c80476e4SDavid E. O'Brien set_color_context();
810c80476e4SDavid E. O'Brien #endif /* COLOR_LS_F */
811c80476e4SDavid E. O'Brien #if defined(KANJI) && defined(SHORT_STRINGS) && defined(DSPMBYTE)
812c80476e4SDavid E. O'Brien update_dspmbyte_vars();
813c80476e4SDavid E. O'Brien #endif
81419d2e3deSDmitry Chagin update_wordchars();
8153b6eaa7bSAndrey A. Chernov #ifdef NLS_CATALOGS
81623338178SMark Peek nlsclose();
8173b6eaa7bSAndrey A. Chernov nlsinit();
8183b6eaa7bSAndrey A. Chernov #endif /* NLS_CATALOGS */
819c80476e4SDavid E. O'Brien }
820c80476e4SDavid E. O'Brien
821c80476e4SDavid E. O'Brien void
unset1(Char * v[],struct varent * head)82245e5710bSMark Peek unset1(Char *v[], struct varent *head)
823c80476e4SDavid E. O'Brien {
82423338178SMark Peek struct varent *vp;
82523338178SMark Peek int cnt;
826c80476e4SDavid E. O'Brien
827c80476e4SDavid E. O'Brien while (*++v) {
828c80476e4SDavid E. O'Brien cnt = 0;
829c80476e4SDavid E. O'Brien while ((vp = madrof(*v, head)) != NULL)
830c80476e4SDavid E. O'Brien if (vp->v_flags & VAR_READONLY)
831c80476e4SDavid E. O'Brien stderror(ERR_READONLY|ERR_NAME, vp->v_name);
832c80476e4SDavid E. O'Brien else
833c80476e4SDavid E. O'Brien unsetv1(vp), cnt++;
834c80476e4SDavid E. O'Brien if (cnt == 0)
835c80476e4SDavid E. O'Brien setname(short2str(*v));
836c80476e4SDavid E. O'Brien }
837c80476e4SDavid E. O'Brien }
838c80476e4SDavid E. O'Brien
839c80476e4SDavid E. O'Brien void
unsetv(Char * var)84045e5710bSMark Peek unsetv(Char *var)
841c80476e4SDavid E. O'Brien {
84223338178SMark Peek struct varent *vp;
843c80476e4SDavid E. O'Brien
844c80476e4SDavid E. O'Brien if ((vp = adrof1(var, &shvhed)) == 0)
845c80476e4SDavid E. O'Brien udvar(var);
846c80476e4SDavid E. O'Brien unsetv1(vp);
847c80476e4SDavid E. O'Brien }
848c80476e4SDavid E. O'Brien
849c80476e4SDavid E. O'Brien static void
unsetv1(struct varent * p)85045e5710bSMark Peek unsetv1(struct varent *p)
851c80476e4SDavid E. O'Brien {
85223338178SMark Peek struct varent *c, *pp;
85323338178SMark Peek int f;
854c80476e4SDavid E. O'Brien
855c80476e4SDavid E. O'Brien /*
856c80476e4SDavid E. O'Brien * Free associated memory first to avoid complications.
857c80476e4SDavid E. O'Brien */
858c80476e4SDavid E. O'Brien blkfree(p->vec);
85945e5710bSMark Peek xfree(p->v_name);
860c80476e4SDavid E. O'Brien /*
861c80476e4SDavid E. O'Brien * If p is missing one child, then we can move the other into where p is.
862c80476e4SDavid E. O'Brien * Otherwise, we find the predecessor of p, which is guaranteed to have no
863c80476e4SDavid E. O'Brien * right child, copy it into p, and move it's left child into it.
864c80476e4SDavid E. O'Brien */
865c80476e4SDavid E. O'Brien if (p->v_right == 0)
866c80476e4SDavid E. O'Brien c = p->v_left;
867c80476e4SDavid E. O'Brien else if (p->v_left == 0)
868c80476e4SDavid E. O'Brien c = p->v_right;
869c80476e4SDavid E. O'Brien else {
870c80476e4SDavid E. O'Brien for (c = p->v_left; c->v_right; c = c->v_right)
871c80476e4SDavid E. O'Brien continue;
872c80476e4SDavid E. O'Brien p->v_name = c->v_name;
873c80476e4SDavid E. O'Brien p->v_flags = c->v_flags;
874c80476e4SDavid E. O'Brien p->vec = c->vec;
875c80476e4SDavid E. O'Brien p = c;
876c80476e4SDavid E. O'Brien c = p->v_left;
877c80476e4SDavid E. O'Brien }
878c80476e4SDavid E. O'Brien
879c80476e4SDavid E. O'Brien /*
880c80476e4SDavid E. O'Brien * Move c into where p is.
881c80476e4SDavid E. O'Brien */
882c80476e4SDavid E. O'Brien pp = p->v_parent;
883c80476e4SDavid E. O'Brien f = pp->v_right == p;
884c80476e4SDavid E. O'Brien if ((pp->v_link[f] = c) != 0)
885c80476e4SDavid E. O'Brien c->v_parent = pp;
886c80476e4SDavid E. O'Brien /*
887c80476e4SDavid E. O'Brien * Free the deleted node, and rebalance.
888c80476e4SDavid E. O'Brien */
88945e5710bSMark Peek xfree(p);
890c80476e4SDavid E. O'Brien balance(pp, f, 1);
891c80476e4SDavid E. O'Brien }
892c80476e4SDavid E. O'Brien
8939ccc37e3SMark Peek /* Set variable name to NULL. */
894c80476e4SDavid E. O'Brien void
setNS(const Char * varName)8959ccc37e3SMark Peek setNS(const Char *varName)
896c80476e4SDavid E. O'Brien {
8979ccc37e3SMark Peek setcopy(varName, STRNULL, VAR_READWRITE);
898c80476e4SDavid E. O'Brien }
899c80476e4SDavid E. O'Brien
900c80476e4SDavid E. O'Brien /*ARGSUSED*/
901c80476e4SDavid E. O'Brien void
shift(Char ** v,struct command * c)90245e5710bSMark Peek shift(Char **v, struct command *c)
903c80476e4SDavid E. O'Brien {
90423338178SMark Peek struct varent *argv;
90523338178SMark Peek Char *name;
906c80476e4SDavid E. O'Brien
907c80476e4SDavid E. O'Brien USE(c);
908c80476e4SDavid E. O'Brien v++;
909c80476e4SDavid E. O'Brien name = *v;
910c80476e4SDavid E. O'Brien if (name == 0)
911c80476e4SDavid E. O'Brien name = STRargv;
912c80476e4SDavid E. O'Brien else
913c80476e4SDavid E. O'Brien (void) strip(name);
914c80476e4SDavid E. O'Brien argv = adrof(name);
91529301572SMark Peek if (argv == NULL || argv->vec == NULL)
916c80476e4SDavid E. O'Brien udvar(name);
917c80476e4SDavid E. O'Brien if (argv->vec[0] == 0)
918c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_NOMORE);
919c80476e4SDavid E. O'Brien lshift(argv->vec, 1);
920c80476e4SDavid E. O'Brien update_vars(name);
921c80476e4SDavid E. O'Brien }
922c80476e4SDavid E. O'Brien
923c80476e4SDavid E. O'Brien static void
exportpath(Char ** val)92445e5710bSMark Peek exportpath(Char **val)
925c80476e4SDavid E. O'Brien {
92645e5710bSMark Peek struct Strbuf buf = Strbuf_INIT;
927c80476e4SDavid E. O'Brien Char *exppath;
928c80476e4SDavid E. O'Brien
929c80476e4SDavid E. O'Brien if (val)
930c80476e4SDavid E. O'Brien while (*val) {
93145e5710bSMark Peek Strbuf_append(&buf, *val++);
932c80476e4SDavid E. O'Brien if (*val == 0 || eq(*val, STRRparen))
933c80476e4SDavid E. O'Brien break;
93445e5710bSMark Peek Strbuf_append1(&buf, PATHSEP);
935c80476e4SDavid E. O'Brien }
93645e5710bSMark Peek exppath = Strbuf_finish(&buf);
93745e5710bSMark Peek cleanup_push(exppath, xfree);
938c80476e4SDavid E. O'Brien tsetenv(STRKPATH, exppath);
93945e5710bSMark Peek cleanup_until(exppath);
940c80476e4SDavid E. O'Brien }
941c80476e4SDavid E. O'Brien
94219d2e3deSDmitry Chagin static int
set_noclobber(Char ** val)94319d2e3deSDmitry Chagin set_noclobber(Char **val)
94419d2e3deSDmitry Chagin {
94519d2e3deSDmitry Chagin Char *option;
94619d2e3deSDmitry Chagin int nc = NOCLOBBER_DEFAULT;
94719d2e3deSDmitry Chagin
94819d2e3deSDmitry Chagin if (val == NULL)
94919d2e3deSDmitry Chagin return nc;
95019d2e3deSDmitry Chagin while (*val) {
95119d2e3deSDmitry Chagin if (*val == 0 || eq(*val, STRRparen))
95219d2e3deSDmitry Chagin return nc;
95319d2e3deSDmitry Chagin
95419d2e3deSDmitry Chagin option = *val++;
95519d2e3deSDmitry Chagin
95619d2e3deSDmitry Chagin if (eq(option, STRnotempty))
95719d2e3deSDmitry Chagin nc |= NOCLOBBER_NOTEMPTY;
95819d2e3deSDmitry Chagin else if (eq(option, STRask))
95919d2e3deSDmitry Chagin nc |= NOCLOBBER_ASK;
96019d2e3deSDmitry Chagin }
96119d2e3deSDmitry Chagin return nc;
96219d2e3deSDmitry Chagin }
96319d2e3deSDmitry Chagin
964c80476e4SDavid E. O'Brien #ifndef lint
965c80476e4SDavid E. O'Brien /*
966c80476e4SDavid E. O'Brien * Lint thinks these have null effect
967c80476e4SDavid E. O'Brien */
968c80476e4SDavid E. O'Brien /* macros to do single rotations on node p */
969c80476e4SDavid E. O'Brien # define rright(p) (\
970c80476e4SDavid E. O'Brien t = (p)->v_left,\
971c80476e4SDavid E. O'Brien (t)->v_parent = (p)->v_parent,\
972c80476e4SDavid E. O'Brien (((p)->v_left = t->v_right) != NULL) ?\
973c80476e4SDavid E. O'Brien (t->v_right->v_parent = (p)) : 0,\
974c80476e4SDavid E. O'Brien (t->v_right = (p))->v_parent = t,\
975c80476e4SDavid E. O'Brien (p) = t)
976c80476e4SDavid E. O'Brien # define rleft(p) (\
977c80476e4SDavid E. O'Brien t = (p)->v_right,\
978c80476e4SDavid E. O'Brien ((t)->v_parent = (p)->v_parent,\
979c80476e4SDavid E. O'Brien ((p)->v_right = t->v_left) != NULL) ? \
980c80476e4SDavid E. O'Brien (t->v_left->v_parent = (p)) : 0,\
981c80476e4SDavid E. O'Brien (t->v_left = (p))->v_parent = t,\
982c80476e4SDavid E. O'Brien (p) = t)
983c80476e4SDavid E. O'Brien #else
984c80476e4SDavid E. O'Brien static struct varent *
rleft(struct varent * p)98545e5710bSMark Peek rleft(struct varent *p)
986c80476e4SDavid E. O'Brien {
987c80476e4SDavid E. O'Brien return (p);
988c80476e4SDavid E. O'Brien }
989c80476e4SDavid E. O'Brien static struct varent *
rright(struct varent * p)99045e5710bSMark Peek rright(struct varent *p)
991c80476e4SDavid E. O'Brien {
992c80476e4SDavid E. O'Brien return (p);
993c80476e4SDavid E. O'Brien }
994c80476e4SDavid E. O'Brien
995c80476e4SDavid E. O'Brien #endif /* ! lint */
996c80476e4SDavid E. O'Brien
997c80476e4SDavid E. O'Brien
998c80476e4SDavid E. O'Brien /*
999c80476e4SDavid E. O'Brien * Rebalance a tree, starting at p and up.
1000c80476e4SDavid E. O'Brien * F == 0 means we've come from p's left child.
1001c80476e4SDavid E. O'Brien * D == 1 means we've just done a delete, otherwise an insert.
1002c80476e4SDavid E. O'Brien */
1003c80476e4SDavid E. O'Brien static void
balance(struct varent * p,int f,int d)100445e5710bSMark Peek balance(struct varent *p, int f, int d)
1005c80476e4SDavid E. O'Brien {
100623338178SMark Peek struct varent *pp;
1007c80476e4SDavid E. O'Brien
1008c80476e4SDavid E. O'Brien #ifndef lint
100923338178SMark Peek struct varent *t; /* used by the rotate macros */
1010c80476e4SDavid E. O'Brien #endif /* !lint */
101123338178SMark Peek int ff;
1012c80476e4SDavid E. O'Brien #ifdef lint
1013c80476e4SDavid E. O'Brien ff = 0; /* Sun's lint is dumb! */
1014c80476e4SDavid E. O'Brien #endif
1015c80476e4SDavid E. O'Brien
1016c80476e4SDavid E. O'Brien /*
1017c80476e4SDavid E. O'Brien * Ok, from here on, p is the node we're operating on; pp is it's parent; f
1018c80476e4SDavid E. O'Brien * is the branch of p from which we have come; ff is the branch of pp which
1019c80476e4SDavid E. O'Brien * is p.
1020c80476e4SDavid E. O'Brien */
1021c80476e4SDavid E. O'Brien for (; (pp = p->v_parent) != 0; p = pp, f = ff) {
1022c80476e4SDavid E. O'Brien ff = pp->v_right == p;
1023c80476e4SDavid E. O'Brien if (f ^ d) { /* right heavy */
1024c80476e4SDavid E. O'Brien switch (p->v_bal) {
1025c80476e4SDavid E. O'Brien case -1: /* was left heavy */
1026c80476e4SDavid E. O'Brien p->v_bal = 0;
1027c80476e4SDavid E. O'Brien break;
1028c80476e4SDavid E. O'Brien case 0: /* was balanced */
1029c80476e4SDavid E. O'Brien p->v_bal = 1;
1030c80476e4SDavid E. O'Brien break;
1031c80476e4SDavid E. O'Brien case 1: /* was already right heavy */
1032c80476e4SDavid E. O'Brien switch (p->v_right->v_bal) {
103345e5710bSMark Peek case 1: /* single rotate */
1034c80476e4SDavid E. O'Brien pp->v_link[ff] = rleft(p);
1035c80476e4SDavid E. O'Brien p->v_left->v_bal = 0;
1036c80476e4SDavid E. O'Brien p->v_bal = 0;
1037c80476e4SDavid E. O'Brien break;
1038c80476e4SDavid E. O'Brien case 0: /* single rotate */
1039c80476e4SDavid E. O'Brien pp->v_link[ff] = rleft(p);
1040c80476e4SDavid E. O'Brien p->v_left->v_bal = 1;
1041c80476e4SDavid E. O'Brien p->v_bal = -1;
1042c80476e4SDavid E. O'Brien break;
1043c80476e4SDavid E. O'Brien case -1: /* double rotate */
1044c80476e4SDavid E. O'Brien (void) rright(p->v_right);
1045c80476e4SDavid E. O'Brien pp->v_link[ff] = rleft(p);
1046c80476e4SDavid E. O'Brien p->v_left->v_bal =
1047c80476e4SDavid E. O'Brien p->v_bal < 1 ? 0 : -1;
1048c80476e4SDavid E. O'Brien p->v_right->v_bal =
1049c80476e4SDavid E. O'Brien p->v_bal > -1 ? 0 : 1;
1050c80476e4SDavid E. O'Brien p->v_bal = 0;
1051c80476e4SDavid E. O'Brien break;
1052c80476e4SDavid E. O'Brien default:
1053c80476e4SDavid E. O'Brien break;
1054c80476e4SDavid E. O'Brien }
1055c80476e4SDavid E. O'Brien break;
1056c80476e4SDavid E. O'Brien default:
1057c80476e4SDavid E. O'Brien break;
1058c80476e4SDavid E. O'Brien }
1059c80476e4SDavid E. O'Brien }
1060c80476e4SDavid E. O'Brien else { /* left heavy */
1061c80476e4SDavid E. O'Brien switch (p->v_bal) {
1062c80476e4SDavid E. O'Brien case 1: /* was right heavy */
1063c80476e4SDavid E. O'Brien p->v_bal = 0;
1064c80476e4SDavid E. O'Brien break;
1065c80476e4SDavid E. O'Brien case 0: /* was balanced */
1066c80476e4SDavid E. O'Brien p->v_bal = -1;
1067c80476e4SDavid E. O'Brien break;
1068c80476e4SDavid E. O'Brien case -1: /* was already left heavy */
1069c80476e4SDavid E. O'Brien switch (p->v_left->v_bal) {
1070c80476e4SDavid E. O'Brien case -1: /* single rotate */
1071c80476e4SDavid E. O'Brien pp->v_link[ff] = rright(p);
1072c80476e4SDavid E. O'Brien p->v_right->v_bal = 0;
1073c80476e4SDavid E. O'Brien p->v_bal = 0;
1074c80476e4SDavid E. O'Brien break;
107545e5710bSMark Peek case 0: /* single rotate */
1076c80476e4SDavid E. O'Brien pp->v_link[ff] = rright(p);
1077c80476e4SDavid E. O'Brien p->v_right->v_bal = -1;
1078c80476e4SDavid E. O'Brien p->v_bal = 1;
1079c80476e4SDavid E. O'Brien break;
1080c80476e4SDavid E. O'Brien case 1: /* double rotate */
1081c80476e4SDavid E. O'Brien (void) rleft(p->v_left);
1082c80476e4SDavid E. O'Brien pp->v_link[ff] = rright(p);
1083c80476e4SDavid E. O'Brien p->v_left->v_bal =
1084c80476e4SDavid E. O'Brien p->v_bal < 1 ? 0 : -1;
1085c80476e4SDavid E. O'Brien p->v_right->v_bal =
1086c80476e4SDavid E. O'Brien p->v_bal > -1 ? 0 : 1;
1087c80476e4SDavid E. O'Brien p->v_bal = 0;
1088c80476e4SDavid E. O'Brien break;
1089c80476e4SDavid E. O'Brien default:
1090c80476e4SDavid E. O'Brien break;
1091c80476e4SDavid E. O'Brien }
1092c80476e4SDavid E. O'Brien break;
1093c80476e4SDavid E. O'Brien default:
1094c80476e4SDavid E. O'Brien break;
1095c80476e4SDavid E. O'Brien }
1096c80476e4SDavid E. O'Brien }
1097c80476e4SDavid E. O'Brien /*
1098c80476e4SDavid E. O'Brien * If from insert, then we terminate when p is balanced. If from
1099c80476e4SDavid E. O'Brien * delete, then we terminate when p is unbalanced.
1100c80476e4SDavid E. O'Brien */
1101c80476e4SDavid E. O'Brien if ((p->v_bal == 0) ^ d)
1102c80476e4SDavid E. O'Brien break;
1103c80476e4SDavid E. O'Brien }
1104c80476e4SDavid E. O'Brien }
1105c80476e4SDavid E. O'Brien
1106c80476e4SDavid E. O'Brien void
plist(struct varent * p,int what)110745e5710bSMark Peek plist(struct varent *p, int what)
1108c80476e4SDavid E. O'Brien {
110923338178SMark Peek struct varent *c;
111023338178SMark Peek int len;
1111c80476e4SDavid E. O'Brien
1112c80476e4SDavid E. O'Brien for (;;) {
1113c80476e4SDavid E. O'Brien while (p->v_left)
1114c80476e4SDavid E. O'Brien p = p->v_left;
1115c80476e4SDavid E. O'Brien x:
1116c80476e4SDavid E. O'Brien if (p->v_parent == 0) /* is it the header? */
111745e5710bSMark Peek break;
1118c80476e4SDavid E. O'Brien if ((p->v_flags & what) != 0) {
111945e5710bSMark Peek if (setintr) {
112045e5710bSMark Peek int old_pintr_disabled;
112145e5710bSMark Peek
112245e5710bSMark Peek pintr_push_enable(&old_pintr_disabled);
112345e5710bSMark Peek cleanup_until(&old_pintr_disabled);
112445e5710bSMark Peek }
1125c80476e4SDavid E. O'Brien len = blklen(p->vec);
1126c80476e4SDavid E. O'Brien xprintf("%S\t", p->v_name);
1127c80476e4SDavid E. O'Brien if (len != 1)
1128c80476e4SDavid E. O'Brien xputchar('(');
1129c80476e4SDavid E. O'Brien blkpr(p->vec);
1130c80476e4SDavid E. O'Brien if (len != 1)
1131c80476e4SDavid E. O'Brien xputchar(')');
1132c80476e4SDavid E. O'Brien xputchar('\n');
1133c80476e4SDavid E. O'Brien }
1134c80476e4SDavid E. O'Brien if (p->v_right) {
1135c80476e4SDavid E. O'Brien p = p->v_right;
1136c80476e4SDavid E. O'Brien continue;
1137c80476e4SDavid E. O'Brien }
1138c80476e4SDavid E. O'Brien do {
1139c80476e4SDavid E. O'Brien c = p;
1140c80476e4SDavid E. O'Brien p = p->v_parent;
1141c80476e4SDavid E. O'Brien } while (p->v_right == c);
1142c80476e4SDavid E. O'Brien goto x;
1143c80476e4SDavid E. O'Brien }
1144c80476e4SDavid E. O'Brien }
1145c80476e4SDavid E. O'Brien
11469ccc37e3SMark Peek #if defined(KANJI)
11479ccc37e3SMark Peek # if defined(SHORT_STRINGS) && defined(DSPMBYTE)
114823338178SMark Peek extern int dspmbyte_ls;
1149c80476e4SDavid E. O'Brien
1150c80476e4SDavid E. O'Brien void
update_dspmbyte_vars(void)115145e5710bSMark Peek update_dspmbyte_vars(void)
1152c80476e4SDavid E. O'Brien {
1153c80476e4SDavid E. O'Brien int lp, iskcode;
1154c80476e4SDavid E. O'Brien Char *dstr1;
1155c80476e4SDavid E. O'Brien struct varent *vp;
1156c80476e4SDavid E. O'Brien
1157c80476e4SDavid E. O'Brien /* if variable "nokanji" is set, multi-byte display is disabled */
1158c80476e4SDavid E. O'Brien if ((vp = adrof(CHECK_MBYTEVAR)) && !adrof(STRnokanji)) {
1159c80476e4SDavid E. O'Brien _enable_mbdisp = 1;
1160c80476e4SDavid E. O'Brien dstr1 = vp->vec[0];
116123338178SMark Peek if (eq (dstr1, STRsjis))
1162c80476e4SDavid E. O'Brien iskcode = 1;
116323338178SMark Peek else if (eq(dstr1, STReuc))
1164c80476e4SDavid E. O'Brien iskcode = 2;
116523338178SMark Peek else if (eq(dstr1, STRbig5))
11666767bd61SMark Peek iskcode = 3;
116723338178SMark Peek else if (eq(dstr1, STRutf8))
116829301572SMark Peek iskcode = 4;
1169c80476e4SDavid E. O'Brien else if ((dstr1[0] - '0') >= 0 && (dstr1[0] - '0') <= 3) {
1170c80476e4SDavid E. O'Brien iskcode = 0;
1171c80476e4SDavid E. O'Brien }
1172c80476e4SDavid E. O'Brien else {
1173c80476e4SDavid E. O'Brien xprintf(CGETS(18, 2,
1174c80476e4SDavid E. O'Brien "Warning: unknown multibyte display; using default(euc(JP))\n"));
1175c80476e4SDavid E. O'Brien iskcode = 2;
1176c80476e4SDavid E. O'Brien }
1177c80476e4SDavid E. O'Brien if (dstr1 && vp->vec[1] && eq(vp->vec[1], STRls))
1178c80476e4SDavid E. O'Brien dspmbyte_ls = 1;
1179c80476e4SDavid E. O'Brien else
1180c80476e4SDavid E. O'Brien dspmbyte_ls = 0;
1181c80476e4SDavid E. O'Brien for (lp = 0; lp < 256 && iskcode > 0; lp++) {
1182c80476e4SDavid E. O'Brien switch (iskcode) {
1183c80476e4SDavid E. O'Brien case 1:
1184c80476e4SDavid E. O'Brien /* Shift-JIS */
1185c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_mbyte[lp];
1186c80476e4SDavid E. O'Brien _mbmap[lp] = _mbmap_sjis[lp];
1187c80476e4SDavid E. O'Brien break;
1188c80476e4SDavid E. O'Brien case 2:
1189c80476e4SDavid E. O'Brien /* 2 ... euc */
1190c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_mbyte[lp];
1191c80476e4SDavid E. O'Brien _mbmap[lp] = _mbmap_euc[lp];
1192c80476e4SDavid E. O'Brien break;
11936767bd61SMark Peek case 3:
11946767bd61SMark Peek /* 3 ... big5 */
11956767bd61SMark Peek _cmap[lp] = _cmap_mbyte[lp];
11966767bd61SMark Peek _mbmap[lp] = _mbmap_big5[lp];
11976767bd61SMark Peek break;
119829301572SMark Peek case 4:
119929301572SMark Peek /* 4 ... utf8 */
120029301572SMark Peek _cmap[lp] = _cmap_mbyte[lp];
120129301572SMark Peek _mbmap[lp] = _mbmap_utf8[lp];
120229301572SMark Peek break;
1203c80476e4SDavid E. O'Brien default:
1204c80476e4SDavid E. O'Brien xprintf(CGETS(18, 3,
1205c80476e4SDavid E. O'Brien "Warning: unknown multibyte code %d; multibyte disabled\n"),
1206c80476e4SDavid E. O'Brien iskcode);
1207c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_c[lp];
1208c80476e4SDavid E. O'Brien _mbmap[lp] = 0; /* Default map all 0 */
1209c80476e4SDavid E. O'Brien _enable_mbdisp = 0;
1210c80476e4SDavid E. O'Brien break;
1211c80476e4SDavid E. O'Brien }
1212c80476e4SDavid E. O'Brien }
1213c80476e4SDavid E. O'Brien if (iskcode == 0) {
1214c80476e4SDavid E. O'Brien /* check original table */
1215c80476e4SDavid E. O'Brien if (Strlen(dstr1) != 256) {
1216c80476e4SDavid E. O'Brien xprintf(CGETS(18, 4,
1217c80476e4SDavid E. O'Brien "Warning: Invalid multibyte table length (%d); multibyte disabled\n"),
1218c80476e4SDavid E. O'Brien Strlen(dstr1));
1219c80476e4SDavid E. O'Brien _enable_mbdisp = 0;
1220c80476e4SDavid E. O'Brien }
1221c80476e4SDavid E. O'Brien for (lp = 0; lp < 256 && _enable_mbdisp == 1; lp++) {
1222c80476e4SDavid E. O'Brien if (!((dstr1[lp] - '0') >= 0 && (dstr1[lp] - '0') <= 3)) {
1223c80476e4SDavid E. O'Brien xprintf(CGETS(18, 4,
1224c80476e4SDavid E. O'Brien "Warning: bad multibyte code at offset +%d; multibyte diabled\n"),
1225c80476e4SDavid E. O'Brien lp);
1226c80476e4SDavid E. O'Brien _enable_mbdisp = 0;
1227c80476e4SDavid E. O'Brien break;
1228c80476e4SDavid E. O'Brien }
1229c80476e4SDavid E. O'Brien }
1230c80476e4SDavid E. O'Brien /* set original table */
1231c80476e4SDavid E. O'Brien for (lp = 0; lp < 256; lp++) {
1232c80476e4SDavid E. O'Brien if (_enable_mbdisp == 1) {
1233c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_mbyte[lp];
1234c80476e4SDavid E. O'Brien _mbmap[lp] = (unsigned short) ((dstr1[lp] - '0') & 0x0f);
1235c80476e4SDavid E. O'Brien }
1236c80476e4SDavid E. O'Brien else {
1237c80476e4SDavid E. O'Brien _cmap[lp] = _cmap_c[lp];
1238c80476e4SDavid E. O'Brien _mbmap[lp] = 0; /* Default map all 0 */
1239c80476e4SDavid E. O'Brien }
1240c80476e4SDavid E. O'Brien }
1241c80476e4SDavid E. O'Brien }
1242c80476e4SDavid E. O'Brien }
1243c80476e4SDavid E. O'Brien else {
1244c80476e4SDavid E. O'Brien for (lp = 0; lp < 256; lp++) {
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 _enable_mbdisp = 0;
1249c80476e4SDavid E. O'Brien dspmbyte_ls = 0;
1250c80476e4SDavid E. O'Brien }
1251c80476e4SDavid E. O'Brien #ifdef MBYTEDEBUG /* Sorry, use for beta testing */
1252c80476e4SDavid E. O'Brien {
1253c80476e4SDavid E. O'Brien Char mbmapstr[300];
125445e5710bSMark Peek for (lp = 0; lp < 256; lp++)
1255c80476e4SDavid E. O'Brien mbmapstr[lp] = _mbmap[lp] + '0';
125645e5710bSMark Peek mbmapstr[lp] = 0;
125745e5710bSMark Peek setcopy(STRmbytemap, mbmapstr, VAR_READWRITE);
1258c80476e4SDavid E. O'Brien }
1259c80476e4SDavid E. O'Brien #endif /* MBYTEMAP */
1260c80476e4SDavid E. O'Brien }
1261c80476e4SDavid E. O'Brien
1262c80476e4SDavid E. O'Brien /* dspkanji/dspmbyte autosetting */
1263c80476e4SDavid E. O'Brien /* PATCH IDEA FROM Issei.Suzuki VERY THANKS */
1264c80476e4SDavid E. O'Brien void
autoset_dspmbyte(const Char * pcp)126545e5710bSMark Peek autoset_dspmbyte(const Char *pcp)
1266c80476e4SDavid E. O'Brien {
1267c80476e4SDavid E. O'Brien int i;
126845e5710bSMark Peek static const struct dspm_autoset_Table {
1269c80476e4SDavid E. O'Brien Char *n;
1270c80476e4SDavid E. O'Brien Char *v;
1271c80476e4SDavid E. O'Brien } dspmt[] = {
127223338178SMark Peek { STRLANGEUCJP, STReuc },
127323338178SMark Peek { STRLANGEUCKR, STReuc },
127423338178SMark Peek { STRLANGEUCZH, STReuc },
127523338178SMark Peek { STRLANGEUCJPB, STReuc },
127623338178SMark Peek { STRLANGEUCKRB, STReuc },
127723338178SMark Peek { STRLANGEUCZHB, STReuc },
12789ccc37e3SMark Peek #ifdef __linux__
127923338178SMark Peek { STRLANGEUCJPC, STReuc },
1280b2d5d167SMark Peek #endif
128123338178SMark Peek { STRLANGSJIS, STRsjis },
128223338178SMark Peek { STRLANGSJISB, STRsjis },
128323338178SMark Peek { STRLANGBIG5, STRbig5 },
128423338178SMark Peek { STRstarutfstar8, STRutf8 },
1285c80476e4SDavid E. O'Brien { NULL, NULL }
1286c80476e4SDavid E. O'Brien };
128745e5710bSMark Peek #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
128845e5710bSMark Peek static const struct dspm_autoset_Table dspmc[] = {
128923338178SMark Peek { STRstarutfstar8, STRutf8 },
129023338178SMark Peek { STReuc, STReuc },
129123338178SMark Peek { STRGB2312, STReuc },
129223338178SMark Peek { STRLANGBIG5, STRbig5 },
129323338178SMark Peek { NULL, NULL }
129423338178SMark Peek };
129523338178SMark Peek Char *codeset;
129623338178SMark Peek
129723338178SMark Peek codeset = str2short(nl_langinfo(CODESET));
129823338178SMark Peek if (*codeset != '\0') {
129923338178SMark Peek for (i = 0; dspmc[i].n; i++) {
130045e5710bSMark Peek const Char *estr;
130123338178SMark Peek if (dspmc[i].n[0] && t_pmatch(pcp, dspmc[i].n, &estr, 0) > 0) {
130245e5710bSMark Peek setcopy(CHECK_MBYTEVAR, dspmc[i].v, VAR_READWRITE);
130323338178SMark Peek update_dspmbyte_vars();
130423338178SMark Peek return;
130523338178SMark Peek }
130623338178SMark Peek }
130723338178SMark Peek }
130823338178SMark Peek #endif
1309c80476e4SDavid E. O'Brien
1310c80476e4SDavid E. O'Brien if (*pcp == '\0')
1311c80476e4SDavid E. O'Brien return;
1312c80476e4SDavid E. O'Brien
1313c80476e4SDavid E. O'Brien for (i = 0; dspmt[i].n; i++) {
131445e5710bSMark Peek const Char *estr;
131523338178SMark Peek if (dspmt[i].n[0] && t_pmatch(pcp, dspmt[i].n, &estr, 0) > 0) {
131645e5710bSMark Peek setcopy(CHECK_MBYTEVAR, dspmt[i].v, VAR_READWRITE);
1317c80476e4SDavid E. O'Brien update_dspmbyte_vars();
1318c80476e4SDavid E. O'Brien break;
1319c80476e4SDavid E. O'Brien }
1320c80476e4SDavid E. O'Brien }
1321c80476e4SDavid E. O'Brien }
13229ccc37e3SMark Peek # elif defined(AUTOSET_KANJI)
13239ccc37e3SMark Peek void
autoset_kanji(void)13249ccc37e3SMark Peek autoset_kanji(void)
13259ccc37e3SMark Peek {
13269ccc37e3SMark Peek char *codeset = nl_langinfo(CODESET);
13279ccc37e3SMark Peek
13289ccc37e3SMark Peek if (*codeset == '\0') {
13299ccc37e3SMark Peek if (adrof(STRnokanji) == NULL)
13309ccc37e3SMark Peek setNS(STRnokanji);
13319ccc37e3SMark Peek return;
13329ccc37e3SMark Peek }
13339ccc37e3SMark Peek
13349ccc37e3SMark Peek if (strcasestr(codeset, "SHIFT_JIS") == (char*)0) {
13359ccc37e3SMark Peek if (adrof(STRnokanji) == NULL)
13369ccc37e3SMark Peek setNS(STRnokanji);
13379ccc37e3SMark Peek return;
13389ccc37e3SMark Peek }
13399ccc37e3SMark Peek
13409ccc37e3SMark Peek if (adrof(STRnokanji) != NULL)
13419ccc37e3SMark Peek unsetv(STRnokanji);
13429ccc37e3SMark Peek }
13439ccc37e3SMark Peek #endif
1344c80476e4SDavid E. O'Brien #endif
134519d2e3deSDmitry Chagin
134619d2e3deSDmitry Chagin void
update_wordchars(void)134719d2e3deSDmitry Chagin update_wordchars(void)
134819d2e3deSDmitry Chagin {
134919d2e3deSDmitry Chagin if ((word_chars == STR_WORD_CHARS) || (word_chars == STR_WORD_CHARS_VI)) {
135019d2e3deSDmitry Chagin word_chars = (VImode ? STR_WORD_CHARS_VI : STR_WORD_CHARS);
135119d2e3deSDmitry Chagin }
135219d2e3deSDmitry Chagin }
1353