Research V7 development
[unix-history] / usr / src / cmd / sh / name.c
#
/*
* UNIX shell
*
* S. R. Bourne
* Bell Telephone Laboratories
*
*/
#include "defs.h"
PROC BOOL chkid();
NAMNOD ps2nod = { NIL, NIL, ps2name},
fngnod = { NIL, NIL, fngname},
pathnod = { NIL, NIL, pathname},
ifsnod = { NIL, NIL, ifsname},
ps1nod = { &pathnod, &ps2nod, ps1name},
homenod = { &fngnod, &ifsnod, homename},
mailnod = { &homenod, &ps1nod, mailname};
NAMPTR namep = &mailnod;
/* ======== variable and string handling ======== */
syslook(w,syswds)
STRING w;
SYSTAB syswds;
{
REG CHAR first;
REG STRING s;
REG SYSPTR syscan;
syscan=syswds; first = *w;
WHILE s=syscan->sysnam
DO IF first == *s
ANDF eq(w,s)
THEN return(syscan->sysval);
FI
syscan++;
OD
return(0);
}
setlist(arg,xp)
REG ARGPTR arg;
INT xp;
{
WHILE arg
DO REG STRING s=mactrim(arg->argval);
setname(s, xp);
arg=arg->argnxt;
IF flags&execpr
THEN prs(s);
IF arg THEN blank(); ELSE newline(); FI
FI
OD
}
VOID setname(argi, xp)
STRING argi;
INT xp;
{
REG STRING argscan=argi;
REG NAMPTR n;
IF letter(*argscan)
THEN WHILE alphanum(*argscan) DO argscan++ OD
IF *argscan=='='
THEN *argscan = 0;
n=lookup(argi);
*argscan++ = '=';
attrib(n, xp);
IF xp&N_ENVNAM
THEN n->namenv = n->namval = argscan;
ELSE assign(n, argscan);
FI
return;
FI
FI
failed(argi,notid);
}
replace(a, v)
REG STRING *a;
STRING v;
{
free(*a); *a=make(v);
}
dfault(n,v)
NAMPTR n;
STRING v;
{
IF n->namval==0
THEN assign(n,v)
FI
}
assign(n,v)
NAMPTR n;
STRING v;
{
IF n->namflg&N_RDONLY
THEN failed(n->namid,wtfailed);
ELSE replace(&n->namval,v);
FI
}
INT readvar(names)
STRING *names;
{
FILEBLK fb;
REG FILE f = &fb;
REG CHAR c;
REG INT rc=0;
NAMPTR n=lookup(*names++); /* done now to avoid storage mess */
STKPTR rel=relstak();
push(f); initf(dup(0));
IF lseek(0,0L,1)==-1
THEN f->fsiz=1;
FI
LOOP c=nextc(0);
IF (*names ANDF any(c, ifsnod.namval)) ORF eolchar(c)
THEN zerostak();
assign(n,absstak(rel)); setstak(rel);
IF *names
THEN n=lookup(*names++);
ELSE n=0;
FI
IF eolchar(c)
THEN break;
FI
ELSE pushstak(c);
FI
POOL
WHILE n
DO assign(n, nullstr);
IF *names THEN n=lookup(*names++); ELSE n=0; FI
OD
IF eof THEN rc=1 FI
lseek(0, (long)(f->fnxt-f->fend), 1);
pop();
return(rc);
}
assnum(p, i)
STRING *p;
INT i;
{
itos(i); replace(p,numbuf);
}
STRING make(v)
STRING v;
{
REG STRING p;
IF v
THEN movstr(v,p=alloc(length(v)));
return(p);
ELSE return(0);
FI
}
NAMPTR lookup(nam)
REG STRING nam;
{
REG NAMPTR nscan=namep;
REG NAMPTR *prev;
INT LR;
IF !chkid(nam)
THEN failed(nam,notid);
FI
WHILE nscan
DO IF (LR=cf(nam,nscan->namid))==0
THEN return(nscan);
ELIF LR<0
THEN prev = &(nscan->namlft);
ELSE prev = &(nscan->namrgt);
FI
nscan = *prev;
OD
/* add name node */
nscan=alloc(sizeof *nscan);
nscan->namlft=nscan->namrgt=NIL;
nscan->namid=make(nam);
nscan->namval=0; nscan->namflg=N_DEFAULT; nscan->namenv=0;
return(*prev = nscan);
}
LOCAL BOOL chkid(nam)
STRING nam;
{
REG CHAR * cp=nam;
IF !letter(*cp)
THEN return(FALSE);
ELSE WHILE *++cp
DO IF !alphanum(*cp)
THEN return(FALSE);
FI
OD
FI
return(TRUE);
}
LOCAL VOID (*namfn)();
namscan(fn)
VOID (*fn)();
{
namfn=fn;
namwalk(namep);
}
LOCAL VOID namwalk(np)
REG NAMPTR np;
{
IF np
THEN namwalk(np->namlft);
(*namfn)(np);
namwalk(np->namrgt);
FI
}
VOID printnam(n)
NAMPTR n;
{
REG STRING s;
sigchk();
IF s=n->namval
THEN prs(n->namid);
prc('='); prs(s);
newline();
FI
}
LOCAL STRING staknam(n)
REG NAMPTR n;
{
REG STRING p;
p=movstr(n->namid,staktop);
p=movstr("=",p);
p=movstr(n->namval,p);
return(getstak(p+1-ADR(stakbot)));
}
VOID exname(n)
REG NAMPTR n;
{
IF n->namflg&N_EXPORT
THEN free(n->namenv);
n->namenv = make(n->namval);
ELSE free(n->namval);
n->namval = make(n->namenv);
FI
}
VOID printflg(n)
REG NAMPTR n;
{
IF n->namflg&N_EXPORT
THEN prs(export); blank();
FI
IF n->namflg&N_RDONLY
THEN prs(readonly); blank();
FI
IF n->namflg&(N_EXPORT|N_RDONLY)
THEN prs(n->namid); newline();
FI
}
VOID getenv()
{
REG STRING *e=environ;
WHILE *e
DO setname(*e++, N_ENVNAM) OD
}
LOCAL INT namec;
VOID countnam(n)
NAMPTR n;
{
namec++;
}
LOCAL STRING *argnam;
VOID pushnam(n)
NAMPTR n;
{
IF n->namval
THEN *argnam++ = staknam(n);
FI
}
STRING *setenv()
{
REG STRING *er;
namec=0;
namscan(countnam);
argnam = er = getstak(namec*BYTESPERWORD+BYTESPERWORD);
namscan(pushnam);
*argnam++ = 0;
return(er);
}