home *** CD-ROM | disk | FTP | other *** search
- /* $Copyright: $
- * Copyright (c) 1991,1992,1993 by Steve Baker
- * All rights reserved
- *
- * This software is provided as is without any express or implied
- * warranties, including, without limitation, the implied warranties
- * of merchantability and fitness for a particular purpose.
- */
- #include "shell.h"
-
- char *malloc(), *strcpy();
- char numbuf[10];
- extern struct _setvar *sets[37];
- extern char **PATH, **_mbox, newmail, *_home, **_mailnotice, **_homedirs, **_cdpath;
- extern char _insert, *_prompt, *_statline, **history, _noassigns, *_term[11];
- extern char _echo, _verbose, _glob, _notypeahead, _nonomatch, _noclobber;
- extern int _maxhist, curhist, _joblimit, _failat, _mailchkint, _statint;
- extern char _nodots, _restricted, _nohup, _nobgnull, buf[1025], path[1025];
- extern struct timeval *_timeout, timeout;
- extern int a,b,c,d;
-
- char **evalw(), *getvalidenv(), *string(), *UPPER();
- struct _setvar *getvalidset(), *getset(), *find_var(), *add_var();
-
- enum {
- VAR_CDPATH, VAR_CWD, VAR_ECHO, VAR_FAILAT, VAR_HISTORY, VAR_HOME,
- VAR_HOMEDIRS, VAR_INSERT, VAR_JOBLIMIT, VAR_MAIL, VAR_MAILCHKINT,
- VAR_MAILNOTICE, VAR_NOBGNULL, VAR_NOCLOBBER, VAR_NOGLOB, VAR_NONOMATCH,
- VAR_NOTYPEAHEAD, VAR_PATH, VAR_PROMPT, VAR_STATINT, VAR_STATLINE, VAR_TERM,
- VAR_TIMEOUT, VAR_USER, VAR_VERBOSE, VAR_NOASSIGNS, VAR_RESTRICTED,
- VAR_NODOTS, VAR_NOHUP
- };
-
- #define hash(x) (isalpha(x)? (x & 31) + 10 : isdigit(x)? x - '0' : x == '_' ? 10 : -1)
-
- /*
- * Parse our shell vars here...
- */
-
- char ***parse_shellvars(arg)
- char ***arg;
- {
- int i;
- char **evalvars();
-
- for(i=0;arg[i];i++)
- arg[i] = evalvars(arg[i]);
-
- return arg;
- }
-
- char **evalvars(w)
- char **w;
- {
- char **tmp, **etmp;
- int i,j,nst,nt,wrd;
-
- tmp = (char **)calloc(nt=5,sizeof(char *));
-
- wrd = nst = 0;
- for(i=0;w[i];i++) {
- if (w[i][0] == '(' && !w[i][1]) nst++;
- if (w[i][0] == ')' && !w[i][1]) nst -= (nst?1:0);
-
- if (nst) {
- if (wrd == nt) tmp = (char **)realloc(tmp,sizeof(char *) * (nt+=5));
- tmp[wrd++] = w[i];
- } else {
- etmp = evalw(w[i]);
- for(j=0;etmp[j];j++) {
- if (wrd == nt) tmp = (char **)realloc(tmp,sizeof(char *) * (nt+=5));
- tmp[wrd++] = etmp[j];
- }
- if (w[i] != etmp[0]) free(w[i]);
- free(etmp);
- }
- }
- if (wrd == nt) tmp = (char **)realloc(tmp,sizeof(char *) * (++nt));
- tmp[wrd] = NULL;
- free(w);
- return tmp;
- }
-
- /*
- String/Numeric vars: $ Environment vars: $$
- var var[x] ?var ?var[x] #var #var[x]
- {var} {var[x]} ?{var} ?{var[x]} #{var} #{var[x]}
- */
-
- char **evalw(wrd)
- char *wrd;
- {
- struct _setvar *SET;
- char **etmp, **tmp, *w;
- int i,j,z,nt,bp,tp,pos;
-
- tp = pos = bp = 0;
-
- tmp = (char **)calloc(nt = 2,sizeof(char *));
- if (*wrd == '\'' || !index(wrd,'$')) {
- tmp[0] = wrd;
- tmp[1] = NULL;
- return tmp;
- }
- while(*wrd) {
- switch(*wrd++) {
- case '$':
- if (*wrd == '$') {
- if (*++wrd == '?') {
- ++wrd;
- w = getvalidenv(&wrd,&pos);
- if (w) buf[bp++] = '1';
- else buf[bp++] = '0';
- free(w);
- break;
- }
- if (*wrd == '#') {
- wrd++;
- i = 0;
- w = getvalidenv(&wrd,&pos);
- if (w) {
- if (pos < 0) {
- for(i=1,j=0;w[j];j++) if (w[j] == ':') i++;
- } else i = strlen(w);
- }
- sprintf(path,"%d",i);
- for(i=0;path[i];i++) buf[bp++] = path[i];
- break;
- }
- w = getvalidenv(&wrd,&pos);
- while (*w) buf[bp++] = *w++;
- free(w);
- break;
- }
- if (*wrd == '<') {
- wrd++;
- fgets(path,1024,stdin);
- for(i=0;path[i] != '\n';i++) buf[bp++] = path[i];
- break;
- }
- if (*wrd == '?') {
- wrd++;
- if (SET = getvalidset(&wrd,&pos)) buf[bp++] = SET->type + '1';
- else buf[bp++] = '0';
- break;
- }
- if (*wrd == '#') {
- wrd++;
- if (SET = getvalidset(&wrd,&pos)) {
- if (pos < 0) i = SET->nwrds;
- else i = strlen(SET->sv.wrd[pos]);
- } else i = 0;
- sprintf(path,"%d",i);
- for(i=0;path[i];i++) buf[bp++] = path[i];
- break;
- }
- SET = getvalidset(&wrd,&pos);
- if (!SET) break;
- if (SET->type == T_INTEGER) {
- sprintf(numbuf,"%d",SET->sv.val);
- for(i=0;numbuf[i];i++) buf[bp++] = numbuf[i];
- } else if (SET->type == T_STRING && pos < 0) {
- buf[bp] = 0;
- w = (char *)strcpy((char *)malloc(bp+1),buf);
- etmp = evalw(wrd);
- for(i=0;SET->sv.wrd[i];i++) {
- for(z=0;etmp[z];z++) {
- if (tp == nt) tmp = (char **)realloc(tmp,sizeof(char *) * (nt+=5));
- tmp[tp] = (char *)malloc(strlen(SET->sv.wrd[i])+bp+strlen(etmp[z])+2);
- sprintf(tmp[tp++],"%s%s%s",w,SET->sv.wrd[i],etmp[z]);
- }
- }
- free_list(etmp);
- free(w);
- if (tp == nt) tmp = (char **)realloc(tmp,sizeof(char *) * (nt+=1));
- tmp[tp] = NULL;
- return tmp;
- } else if (SET->type == T_STRING) {
- for(j=0;SET->sv.wrd[pos][j];j++) buf[bp++] = SET->sv.wrd[pos][j];
- }
- break;
- case '\\':
- buf[bp++] = *wrd++;
- break;
- default:
- buf[bp++] = *(wrd-1);
- break;
- }
- }
- buf[bp] = 0;
- if (tp >= (nt-1)) tmp = (char **)realloc(tmp,sizeof(char *) * (nt+=2));
- tmp[tp++] = (char *)strcpy((char *)malloc(bp+1),buf);
- tmp[tp] = NULL;
- return tmp;
- }
-
- struct _setvar *getvalidset(wrd,pos)
- char **wrd;
- int *pos;
- {
- struct _setvar *SET;
-
- if (**wrd == '{') {
- (*wrd)++;
- SET = getset(wrd,pos);
- if (**wrd == '}') (*wrd)++;
- } else SET = getset(wrd,pos);
- return SET;
- }
-
- char *getvalidenv(wrd,p)
- char **wrd;
- int *p;
- {
- int bp = 0, pos;
- char brac = FALSE;
- char *s,*env,nest;
-
- *p = -1;
- if (**wrd == '{') {
- brac = TRUE;
- (*wrd)++;
- }
- while(isalnum(**wrd) || **wrd == '_') path[bp++] = *(*wrd)++;
- path[bp] = 0;
- env = (char *)getenv(path);
- if (**wrd == '[') {
- nest = 0;
- (*wrd)++;
- if (!env) {
- while(**wrd && **wrd != ']') {
- if (**wrd == '[') nest++;
- (*wrd)++;
- if (nest && **wrd == ']') {
- nest--;
- (*wrd)++;
- }
- }
- if (**wrd) (*wrd)++;
- if (brac) {
- while(**wrd && **wrd != '}') (*wrd)++;
- if (**wrd) (*wrd)++;
- }
- } else {
- for(bp = 0; **wrd && **wrd != ']';) path[bp++] = *(*wrd)++;
- path[bp] = 0;
- if (**wrd) (*wrd)++;
- if (brac) {
- while(**wrd && **wrd != '}') (*wrd)++;
- if (**wrd) (*wrd)++;
- }
- *p = pos = expr(path);
- for(bp=0;bp<pos;bp++) {
- env = (char *)index(env,':');
- if (!env) return NULL;
- env++;
- }
- bp = 0;
- while(*env && *env != ':') path[bp++] = *env++;
- path[bp] = 0;
- env = (char*)malloc(bp+1);
- strcpy(env,path);
- }
- return env;
- }
- if (!env) return NULL;
- s = (char *)malloc(strlen(env)+1);
- strcpy(s,env);
- return s;
- }
-
- struct _setvar *getset(pat,pos)
- char **pat;
- int *pos;
- {
- int i=0;
- char buf[81],bp=0;
- struct _setvar *SET;
-
- *pos = -1;
-
- while((isalpha(**pat) || isdigit(**pat) || **pat == '_') && bp < 80)
- buf[bp++] = *(*pat)++;
- buf[bp] = 0;
-
- if ((SET = find_var(buf)) == NULL) return NULL;
- if (SET->type != T_STRING) return SET;
- if (**pat == '[') {
- (*pat)++;
- if (!SET) {
- while(**pat && **pat != ']') (*pat)++;
- if (**pat) (*pat)++;
- } else {
- i = 0;
- while(**pat && **pat != ']') path[i++] = *(*pat)++;
- path[i] = 0;
- if (!**pat) return NULL;
- if (**pat) (*pat)++;
- *pos = expr(path);
- if (*pos < 0 || (SET->nwrds-1 < *pos)) {
- *pos = -2;
- return NULL;
- }
- }
- }
- return SET;
- }
-
- SET(n,arg,in,out,err)
- int n;
- char **arg;
- FILE *in,*out,*err;
- {
- static char *signs[] = {
- "=","+=","-=","*=","/=","%=","&=","|=","<<=",">>=","^=","++","--",0
- };
- union setval st;
- struct _setvar *s;
- char *t, *tmp;
-
- if (n == 1) {
- for(a=0;a<37;a++) {
- s = sets[a];
- while(s) {
- fprt(out,s->var);
- fputc('\t',out);
- if (s->type == T_STRING) {
- fprt(out,t = (char *)string(s->sv.wrd));
- free(t);
- } else if (s->type == T_INTEGER) fprintf(out,"%d",s->sv.val);
- fputc('\n',out);
- s = s->nxt;
- }
- }
- return 0;
- }
- for(c=0;signs[c];c++) if (!strcmp(arg[2],signs[c])) break;
- if (arg[2] && !signs[c]) {
- fprintf(err,"%s: missing assignment operator. '=' expected.\n",arg[0]);
- return 1;
- }
- if (strlen(arg[1]) > 80) {
- fprintf(err,"set: variable name too long.\n");
- return 1;
- }
- t = strcpy(malloc(strlen(arg[1])+1),arg[1]);
- if (n == 2) {
- a = T_NULL;
- st.val = 0;
- if (!(s = add_var(t,st,a,0))) return 0;
- check_and_export(s);
- return 0;
- }
- if (strcmp("set",arg[0])) {
- a = T_INTEGER;
- if (c < 11) {
- tmp = (char *)grab(arg,3,NULL,&b);
- st.val = expr(tmp);
- } else tmp = NULL;
- if (c > 0 && (s = find_var(t))) {
- if (s->type != T_INTEGER) s->sv.val = 0;
- switch (c) {
- case 1:
- st.val += s->sv.val;
- break;
- case 2:
- st.val = s->sv.val - st.val;
- break;
- case 3:
- st.val *= s->sv.val;
- break;
- case 4:
- st.val = s->sv.val / st.val;
- break;
- case 5:
- st.val = s->sv.val % st.val;
- break;
- case 6:
- st.val = s->sv.val & st.val;
- break;
- case 7:
- st.val = s->sv.val | st.val;
- break;
- case 8:
- st.val = s->sv.val << st.val;
- break;
- case 9:
- st.val = s->sv.val >> st.val;
- break;
- case 10:
- st.val = s->sv.val ^ st.val;
- break;
- case 11:
- st.val = s->sv.val+1;
- break;
- case 12:
- st.val = s->sv.val-1;
- break;
- }
- }
- if (tmp) free(tmp);
- } else {
- if (c > 1) {
- fprintf(stderr,"set: invalid assignment operator: '%s'.\n",signs[c]);
- return 1;
- }
- if (n <= 3) {
- fprintf(stderr,"set: assignment expected.\n");
- return 1;
- }
- a = 0;
- if (c && (s = find_var(t))) {
- st.wrd = (char **)calloc((n-2)+s->nwrds,sizeof(char *));
- for(b=0;s->sv.wrd[b];b++)
- st.wrd[a++] = strcpy(malloc(strlen(s->sv.wrd[b])+1),s->sv.wrd[b]);
- } else st.wrd = (char **)calloc(n - 2,sizeof(char *));
- for(b=3;arg[b];b++) st.wrd[a++] = strcpy(malloc(strlen(arg[b])+1),arg[b]);
- st.wrd[a] = NULL;
- a = T_STRING;
- }
- if (!(s = add_var(t,st,a,0))) return 0;
- check_and_export(s);
- return 0;
- }
-
- struct _vars {
- char *name, val;
- } vars[] = {
- "cdpath",VAR_CDPATH,
- "cwd", VAR_CWD,
- "echo",VAR_ECHO,
- "failat",VAR_FAILAT,
- "history",VAR_HISTORY,
- "home",VAR_HOME,
- "homedirs",VAR_HOMEDIRS,
- "insert",VAR_INSERT,
- "joblimit",VAR_JOBLIMIT,
- "mail",VAR_MAIL,
- "mailchkint",VAR_MAILCHKINT,
- "mailnotice",VAR_MAILNOTICE,
- "noassigns",VAR_NOASSIGNS,
- "nobgnull", VAR_NOBGNULL,
- "noclobber",VAR_NOCLOBBER,
- "nodots",VAR_NODOTS,
- "noglob",VAR_NOGLOB,
- "nohup",VAR_NOHUP,
- "nonomatch",VAR_NONOMATCH,
- "notypeahead",VAR_NOTYPEAHEAD,
- "path",VAR_PATH,
- "prompt",VAR_PROMPT,
- "restricted",VAR_RESTRICTED,
- "statint",VAR_STATINT,
- "statline",VAR_STATLINE,
- "term",VAR_TERM,
- "timeout",VAR_TIMEOUT,
- "user",VAR_USER,
- "verbose",VAR_VERBOSE
- };
- #define NVARS 28
-
- check_and_export(v)
- struct _setvar *v;
- {
- int tmp;
- char s=0, e=NVARS, m=NVARS/2;
-
- while(s <= e) {
- if (!(d = strcmp(v->var,vars[m].name))) break;
- if (d < 0) e = m - 1;
- else s = m + 1;
- m = (s+e)/2;
- }
- if (d) return;
- switch(vars[m].val) {
- case VAR_CDPATH:
- if (v->type != T_STRING) return;
- _cdpath = v->sv.wrd;
- return;
- case VAR_CWD:
- if (v->type != T_STRING) return;
- export(v);
- return;
- case VAR_ECHO:
- _echo = TRUE;
- return;
- case VAR_FAILAT:
- if (v->type != T_INTEGER) return;
- _failat = (int)(v->sv.val? v->sv.val : 1);
- return;
- case VAR_HISTORY:
- if (v->type != T_INTEGER) return;
- _maxhist = tmp = (int)(v->sv.val);
- if (tmp < curhist) for(d=tmp;d<curhist;d++) free(history[d]);
- history = (char **)realloc(history,sizeof(char *)*(tmp?tmp+1:2));
- if (curhist > tmp) curhist = tmp;
- return;
- case VAR_HOME:
- if (v->type != T_STRING) return;
- export(v);
- if (_home) free(_home);
- _home = string(v->sv.wrd);
- return;
- case VAR_HOMEDIRS:
- if (v->type != T_STRING) return;
- _homedirs = v->sv.wrd;
- return;
- case VAR_INSERT:
- _insert = TRUE;
- return;
- case VAR_JOBLIMIT:
- if (v->type != T_INTEGER) return;
- _joblimit = (int)(v->sv.val);
- return;
- case VAR_MAIL:
- if (v->type != T_STRING) return;
- export(v);
- _mbox = v->sv.wrd;
- newmail = TRUE;
- check_mail(TRUE);
- return;
- case VAR_MAILCHKINT:
- if (v->type != T_INTEGER) return;
- _mailchkint = (int)(v->sv.val);
- return;
- case VAR_MAILNOTICE:
- if (v->type != T_STRING) return;
- _mailnotice = v->sv.wrd;
- return;
- case VAR_NOASSIGNS:
- _noassigns = TRUE;
- return;
- case VAR_NOBGNULL:
- _nobgnull = TRUE;
- return;
- case VAR_NOCLOBBER:
- _noclobber = TRUE;
- return;
- case VAR_NODOTS:
- _nodots = TRUE;
- return;
- case VAR_NOHUP:
- _nohup = TRUE;
- return;
- case VAR_NOGLOB:
- _glob = FALSE;
- return;
- case VAR_NONOMATCH:
- _nonomatch = TRUE;
- return;
- case VAR_NOTYPEAHEAD:
- _notypeahead = TRUE;
- return;
- case VAR_PATH:
- if (v->type != T_STRING) return;
- PATH = v->sv.wrd;
- export(v);
- return;
- case VAR_PROMPT:
- if (v->type != T_STRING) return;
- if (_prompt) free(_prompt);
- _prompt = string(v->sv.wrd);
- return;
- case VAR_RESTRICTED:
- v->protect = TRUE;
- _restricted = TRUE;
- break;
- case VAR_STATINT:
- if (v->type != T_INTEGER) return;
- _statint = (int)(v->sv.val);
- return;
- case VAR_STATLINE:
- if (v->type != T_STRING) return;
- if (_statline) free(_statline);
- _statline = string(v->sv.wrd);
- return;
- case VAR_TIMEOUT:
- if (v->type != T_INTEGER) return;
- if (v->sv.val < 1) _timeout = NULL;
- else {
- timeout.tv_sec = v->sv.val;
- _timeout = &timeout;
- }
- return;
- case VAR_TERM:
- if (v->type != T_STRING) return;
- export(v);
- if (v->sv.wrd[0]) set_term(v->sv.wrd[0]);
- return;
- case VAR_USER:
- if (v->type != T_STRING) return;
- export(v);
- return;
- case VAR_VERBOSE:
- _verbose = TRUE;
- return;
- }
- }
-
- export(v)
- struct _setvar *v;
- {
- char *name = UPPER(v->var),*val;
- int len=0;
-
- for(d=0;v->sv.wrd[d];d++) len += strlen(v->sv.wrd[d])+1;
- val = (char *)malloc(len);
- strcpy(val,v->sv.wrd[0]);
- for(d=1;v->sv.wrd[d];d++) {
- strcat(val,":");
- strcat(val,v->sv.wrd[d]);
- }
- setenv(name,val,1);
- free(name);
- free(val);
- }
-
- UNSET(n,arg,in,out,err)
- int n;
- char **arg;
- FILE *in,*out,*err;
- {
- if (n == 1) return 0;
- for(a=1;arg[a];a++)
- if (remove_var(arg[a])) unexport(arg[a]);
- else {
- fprintf(err,"unset: no such variable: %s\n",arg[a]);
- return -1;
- }
- return 0;
- }
-
- unexport(v)
- char *v;
- {
- char s=0, e=NVARS, m=NVARS/2;
-
- while(s <= e) {
- if (!(b = strcmp(v,vars[m].name))) break;
- if (b < 0) e = m - 1;
- else s = m + 1;
- m = (s+e)/2;
- }
- if (b) return;
- switch(vars[m].val) {
- case VAR_CDPATH:
- _cdpath = NULL;
- return;
- case VAR_ECHO:
- _echo = FALSE;
- return;
- case VAR_FAILAT:
- _failat = 1;
- return;
- case VAR_HISTORY:
- _maxhist = c = 1;
- if (c < curhist) for(b=c;b<curhist;b++) free(history[b]);
- history = (char **)realloc(history,sizeof(char *)*2);
- if (curhist > c) curhist = c;
- return;
- case VAR_HOME:
- free(_home);
- _home = NULL;
- return;
- case VAR_HOMEDIRS:
- _homedirs = NULL;
- return;
- case VAR_INSERT:
- _insert = FALSE;
- return;
- case VAR_JOBLIMIT:
- _joblimit = -1;
- return;
- case VAR_MAIL:
- _mbox = NULL;
- return;
- case VAR_MAILCHKINT:
- _mailchkint = 60;
- return;
- case VAR_MAILNOTICE:
- _mailnotice = NULL;
- return;
- case VAR_NOASSIGNS:
- _noassigns = FALSE;
- return;
- case VAR_NOBGNULL:
- _nobgnull = FALSE;
- return;
- case VAR_NOCLOBBER:
- _noclobber = FALSE;
- return;
- case VAR_NODOTS:
- _nodots = FALSE;
- return;
- case VAR_NOGLOB:
- _glob = TRUE;
- return;
- case VAR_NOHUP:
- _nohup = FALSE;
- return;
- case VAR_NONOMATCH:
- _nonomatch = FALSE;
- return;
- case VAR_NOTYPEAHEAD:
- _notypeahead = FALSE;
- return;
- case VAR_PATH:
- PATH = (char **) malloc(sizeof(char *) * 2);
- PATH[0] = ".";
- PATH[1] = 0;
- return;
- case VAR_PROMPT:
- free(_prompt);
- _prompt = "";
- return;
- case VAR_STATINT:
- _statint = 30;
- return;
- case VAR_STATLINE:
- printf("%s%s%s",_term[TS],_term[CE],_term[FS]);
- free(_statline);
- _statline = NULL;
- return;
- case VAR_TIMEOUT:
- _timeout = NULL;
- return;
- case VAR_VERBOSE:
- _verbose = FALSE;
- return;
- }
- }
-
- /* shift <nshifts> <var> [<var> ... <var>] - shifts words to the left.*/
- SHIFT(n,arg,ferr)
- int n;
- char **arg;
- FILE *ferr;
- {
- struct _setvar *S;
- int i, j, ns;
-
- if (n < 3) {
- fprintf(ferr,"shift: not enough arguments!\n");
- return 1;
- }
- if ((ns = atoi(arg[1])) <= 0) {
- fprintf(ferr,"shift: shift specifier should be greater than zero.\n");
- return 1;
- }
- for(i=2;i<n;i++) {
- if ((S = find_var(arg[i])) == NULL) {
- fprintf(ferr,"shift: variable '%s' not defined.\n",arg[i]);
- continue;
- }
- if (S->type) {
- fprintf(ferr,"shift: variable '%s' not a string type.\n",arg[i]);
- continue;
- }
- if (S->protect) {
- fprintf(ferr,"shift: variable '%s' is protected and not changed.\n",arg[i]);
- continue;
- }
- if (S->nwrds <= ns) {
- fprintf(ferr,"shift: too many words would be shifted for variable '%s'.\n",arg[i]);
- continue;
- }
- for(j=0;j<ns;j++) free(S->sv.wrd[j]);
- for(j=ns;j<=S->nwrds;j++) S->sv.wrd[j-ns] = S->sv.wrd[j];
- S->nwrds -= ns;
- S->sv.wrd = (char **)realloc(S->sv.wrd,sizeof(char **) * (S->nwrds+1));
- }
- return 0;
- }
-
- struct _setvar *find_var(pat)
- char *pat;
- {
- int i, hv = hash(*pat);
- struct _setvar *p = sets[hv];
-
- while (p) {
- if (!(i = strcmp(pat,p->var))) return p;
- if (i < 0) return NULL;
- p = p->nxt;
- }
- return NULL;
- }
-
- struct _setvar *add_var(var,stuff,type,pro)
- char *var;
- union setval stuff;
- BYTE type,pro;
- {
- int i, hv = hash(*var);
- struct _setvar *p = sets[hv], *s = p, *t = (struct _setvar *)malloc(sizeof(struct _setvar));
-
- while (p) {
- if (!(i = strcmp(var,p->var))) {
- if (p->protect) {
- if (type == T_STRING) free_list(stuff.wrd);
- return NULL;
- }
- if (p->type == T_STRING) free_list(p->sv.wrd);
- p->sv = stuff;
- p->type = type;
- if (type == T_STRING) {
- for(i=0;stuff.wrd[i];i++);
- p->nwrds = i;
- }
- return p;
- }
- if (i < 0) break;
- s = p;
- p = p->nxt;
- }
- t->var = (char *)strcpy((char *)malloc(strlen(var)+1),var);
- t->type = type;
- t->nwrds = 0;
- t->protect = pro?1:0;
- switch(type) {
- case T_STRING:
- t->sv.wrd = stuff.wrd;
- for(i=0;stuff.wrd[i];i++);
- t->nwrds = i;
- break;
- case T_INTEGER:
- t->sv.val = stuff.val;
- break;
- case T_NULL:
- t->sv.val = 0;
- break;
- }
- t->nxt = p;
- if (p == sets[hv] && s == sets[hv]) sets[hv] = t;
- else s->nxt = t;
- return t;
- }
-
- remove_var(var)
- char *var;
- {
- int i, hv = hash(*var);
- struct _setvar *p = sets[hv], *s = p;
-
- while (p) {
- if (!(i = strcmp(var,p->var))) {
- if (p->protect) return TRUE;
- if (p == sets[hv]) sets[hv] = p->nxt;
- else s->nxt = p->nxt;
- free(p->var);
- if (p->type == T_STRING) free_list(p->sv.wrd);
- free(p);
- return TRUE;
- }
- if (i < 0) break;
- s = p;
- p = p->nxt;
- }
- return FALSE;
- }
-
- struct _setvar *makenvar(var,num)
- char *var;
- long num;
- {
- union setval st;
- struct _setvar *s;
-
- st.val = num;
- if (!(s = add_var(var,st,T_INTEGER,0))) return NULL;
- check_and_export(s);
- return s;
- }
-
- struct _setvar *makenull(var)
- char *var;
- {
- union setval st;
- struct _setvar *s;
-
- st.val = 0;
- if (!(s = add_var(var,st,T_NULL,0))) return NULL;
- check_and_export(s);
- return s;
- }
-
- struct _setvar *makeset(var,wrd)
- char *var, *wrd;
- {
- union setval st;
- struct _setvar *s;
-
- st.wrd = (char **)calloc(2,sizeof(char *));
- st.wrd[0] = strcpy(malloc(strlen(wrd)+1),wrd);
- st.wrd[1] = NULL;
- if (!(s = add_var(var,st,T_STRING,0))) return NULL;
- check_and_export(s);
- return s;
- }
-
- struct _setvar *makewset(var,wrd)
- char *var, *wrd;
- {
- union setval st;
- struct _setvar *s;
- int i,j,k, n = 5,p = 0;
-
- st.wrd = (char **)calloc(n,sizeof(char *));
- i = 0;
- while(buf[i] == ' ' || buf[i] == '\t') i++;
- j = i;
- while(1) {
- if (buf[i] == ' ' || buf[i] == '\t' || !buf[i]) {
- if (!buf[i] && (i-j) == 0) break;
- if (p == (n-1)) st.wrd = (char **)realloc(st.wrd,(n+=2) * sizeof(char *));
- st.wrd[p] = (char *)malloc((i-j)+1);
- for(k=j;k<i;k++) st.wrd[p][k-j] = buf[k];
- st.wrd[p++][k-j] = 0;
- if (!buf[i]) break;
- while(buf[i] == ' ' || buf[i] == '\t') i++;
- j = i;
- } else i++;
- }
- st.wrd[p] = NULL;
- if (!(s = add_var(var,st,T_STRING,0))) return NULL;
- check_and_export(s);
- return s;
- }
-