1 /* name.c 4.1 82/05/07 */ 2 3 # 4 /* 5 * UNIX shell 6 * 7 * S. R. Bourne 8 * Bell Telephone Laboratories 9 * 10 */ 11 12 #include "defs.h" 13 14 PROC BOOL chkid(); 15 16 17 NAMNOD ps2nod = { NIL, NIL, ps2name}, 18 fngnod = { NIL, NIL, fngname}, 19 pathnod = { NIL, NIL, pathname}, 20 ifsnod = { NIL, NIL, ifsname}, 21 ps1nod = { &pathnod, &ps2nod, ps1name}, 22 homenod = { &fngnod, &ifsnod, homename}, 23 mailnod = { &homenod, &ps1nod, mailname}; 24 25 NAMPTR namep = &mailnod; 26 27 28 /* ======== variable and string handling ======== */ 29 30 syslook(w,syswds) 31 STRING w; 32 SYSTAB syswds; 33 { 34 REG CHAR first; 35 REG STRING s; 36 REG SYSPTR syscan; 37 38 syscan=syswds; first = *w; 39 40 WHILE s=syscan->sysnam 41 DO IF first == *s 42 ANDF eq(w,s) 43 THEN return(syscan->sysval); 44 FI 45 syscan++; 46 OD 47 return(0); 48 } 49 50 setlist(arg,xp) 51 REG ARGPTR arg; 52 INT xp; 53 { 54 WHILE arg 55 DO REG STRING s=mactrim(arg->argval); 56 setname(s, xp); 57 arg=arg->argnxt; 58 IF flags&execpr 59 THEN prs(s); 60 IF arg THEN blank(); ELSE newline(); FI 61 FI 62 OD 63 } 64 65 VOID setname(argi, xp) 66 STRING argi; 67 INT xp; 68 { 69 REG STRING argscan=argi; 70 REG NAMPTR n; 71 72 IF letter(*argscan) 73 THEN WHILE alphanum(*argscan) DO argscan++ OD 74 IF *argscan=='=' 75 THEN *argscan = 0; 76 n=lookup(argi); 77 *argscan++ = '='; 78 attrib(n, xp); 79 IF xp&N_ENVNAM 80 THEN n->namenv = n->namval = argscan; 81 ELSE assign(n, argscan); 82 FI 83 return; 84 FI 85 FI 86 failed(argi,notid); 87 } 88 89 replace(a, v) 90 REG STRING *a; 91 STRING v; 92 { 93 free(*a); *a=make(v); 94 } 95 96 dfault(n,v) 97 NAMPTR n; 98 STRING v; 99 { 100 IF n->namval==0 101 THEN assign(n,v) 102 FI 103 } 104 105 assign(n,v) 106 NAMPTR n; 107 STRING v; 108 { 109 IF n->namflg&N_RDONLY 110 THEN failed(n->namid,wtfailed); 111 ELSE replace(&n->namval,v); 112 FI 113 } 114 115 INT readvar(names) 116 STRING *names; 117 { 118 FILEBLK fb; 119 REG FILE f = &fb; 120 REG CHAR c; 121 REG INT rc=0; 122 NAMPTR n=lookup(*names++); /* done now to avoid storage mess */ 123 STKPTR rel=relstak(); 124 125 push(f); initf(dup(0)); 126 IF lseek(0,0L,1)==-1 127 THEN f->fsiz=1; 128 FI 129 130 LOOP c=nextc(0); 131 IF (*names ANDF any(c, ifsnod.namval)) ORF eolchar(c) 132 THEN zerostak(); 133 assign(n,absstak(rel)); setstak(rel); 134 IF *names 135 THEN n=lookup(*names++); 136 ELSE n=0; 137 FI 138 IF eolchar(c) 139 THEN break; 140 FI 141 ELSE pushstak(c); 142 FI 143 POOL 144 WHILE n 145 DO assign(n, nullstr); 146 IF *names THEN n=lookup(*names++); ELSE n=0; FI 147 OD 148 149 IF eof THEN rc=1 FI 150 lseek(0, (long)(f->fnxt-f->fend), 1); 151 pop(); 152 return(rc); 153 } 154 155 assnum(p, i) 156 STRING *p; 157 INT i; 158 { 159 itos(i); replace(p,numbuf); 160 } 161 162 STRING make(v) 163 STRING v; 164 { 165 REG STRING p; 166 167 IF v 168 THEN movstr(v,p=alloc(length(v))); 169 return(p); 170 ELSE return(0); 171 FI 172 } 173 174 175 NAMPTR lookup(nam) 176 REG STRING nam; 177 { 178 REG NAMPTR nscan=namep; 179 REG NAMPTR *prev; 180 INT LR; 181 182 IF !chkid(nam) 183 THEN failed(nam,notid); 184 FI 185 WHILE nscan 186 DO IF (LR=cf(nam,nscan->namid))==0 187 THEN return(nscan); 188 ELIF LR<0 189 THEN prev = &(nscan->namlft); 190 ELSE prev = &(nscan->namrgt); 191 FI 192 nscan = *prev; 193 OD 194 195 /* add name node */ 196 nscan=alloc(sizeof *nscan); 197 nscan->namlft=nscan->namrgt=NIL; 198 nscan->namid=make(nam); 199 nscan->namval=0; nscan->namflg=N_DEFAULT; nscan->namenv=0; 200 return(*prev = nscan); 201 } 202 203 LOCAL BOOL chkid(nam) 204 STRING nam; 205 { 206 REG CHAR * cp=nam; 207 208 IF !letter(*cp) 209 THEN return(FALSE); 210 ELSE WHILE *++cp 211 DO IF !alphanum(*cp) 212 THEN return(FALSE); 213 FI 214 OD 215 FI 216 return(TRUE); 217 } 218 219 LOCAL VOID (*namfn)(); 220 namscan(fn) 221 VOID (*fn)(); 222 { 223 namfn=fn; 224 namwalk(namep); 225 } 226 227 LOCAL VOID namwalk(np) 228 REG NAMPTR np; 229 { 230 IF np 231 THEN namwalk(np->namlft); 232 (*namfn)(np); 233 namwalk(np->namrgt); 234 FI 235 } 236 237 VOID printnam(n) 238 NAMPTR n; 239 { 240 REG STRING s; 241 242 sigchk(); 243 IF s=n->namval 244 THEN prs(n->namid); 245 prc('='); prs(s); 246 newline(); 247 FI 248 } 249 250 LOCAL STRING staknam(n) 251 REG NAMPTR n; 252 { 253 REG STRING p; 254 255 p=movstr(n->namid,staktop); 256 p=movstr("=",p); 257 p=movstr(n->namval,p); 258 return(getstak(p+1-ADR(stakbot))); 259 } 260 261 VOID exname(n) 262 REG NAMPTR n; 263 { 264 IF n->namflg&N_EXPORT 265 THEN free(n->namenv); 266 n->namenv = make(n->namval); 267 ELSE free(n->namval); 268 n->namval = make(n->namenv); 269 FI 270 } 271 272 VOID printflg(n) 273 REG NAMPTR n; 274 { 275 IF n->namflg&N_EXPORT 276 THEN prs(export); blank(); 277 FI 278 IF n->namflg&N_RDONLY 279 THEN prs(readonly); blank(); 280 FI 281 IF n->namflg&(N_EXPORT|N_RDONLY) 282 THEN prs(n->namid); newline(); 283 FI 284 } 285 286 VOID getenv() 287 { 288 REG STRING *e=environ; 289 290 WHILE *e 291 DO setname(*e++, N_ENVNAM) OD 292 } 293 294 LOCAL INT namec; 295 296 VOID countnam(n) 297 NAMPTR n; 298 { 299 namec++; 300 } 301 302 LOCAL STRING *argnam; 303 304 VOID pushnam(n) 305 NAMPTR n; 306 { 307 IF n->namval 308 THEN *argnam++ = staknam(n); 309 FI 310 } 311 312 STRING *setenv() 313 { 314 REG STRING *er; 315 316 namec=0; 317 namscan(countnam); 318 argnam = er = getstak(namec*BYTESPERWORD+BYTESPERWORD); 319 namscan(pushnam); 320 *argnam++ = 0; 321 return(er); 322 } 323