int readvar(unsigned char **names) { struct fileblk fb; register struct fileblk *f = &fb; unsigned char c[MULTI_BYTE_MAX+1]; register int rc = 0; struct namnod *n; unsigned char *rel; unsigned char *oldstak; register unsigned char *pc, *rest; int d; unsigned int (*newwc)(void); extern const char badargs[]; if (eq(*names, "-r")) { if (*++names == NULL) error(badargs); newwc = readwc; } else newwc = nextwc; n = lookup(*names++); /* done now to avoid storage mess */ rel = (unsigned char *)relstak(); push(f); initf(dup(0)); /* * If stdin is a pipe then this lseek(2) will fail with ESPIPE, so * the read buffer size is set to 1 because we will not be able * lseek(2) back towards the beginning of the file, so we have * to read a byte at a time instead * */ if (lseek(0, (off_t)0, SEEK_CUR) == -1) f->fsiz = 1; #ifdef __sun /* * If stdin is a socket then this isastream(3C) will return 1, so * the read buffer size is set to 1 because we will not be able * lseek(2) back towards the beginning of the file, so we have * to read a byte at a time instead * */ if (isastream(0) == 1) f->fsiz = 1; #endif /* * strip leading IFS characters */ for (;;) { d = newwc(); if(eolchar(d)) break; rest = readw(d); pc = c; while(*pc++ = *rest++); if(!anys(c, ifsnod.namval)) break; } oldstak = curstak(); for (;;) { if ((*names && anys(c, ifsnod.namval)) || eolchar(d)) { if (staktop >= brkend) growstak(staktop); zerostak(); assign(n, absstak(rel)); setstak(rel); if (*names) n = lookup(*names++); else n = 0; if (eolchar(d)) { break; } else /* strip imbedded IFS characters */ while(1) { d = newwc(); if(eolchar(d)) break; rest = readw(d); pc = c; while(*pc++ = *rest++); if(!anys(c, ifsnod.namval)) break; } } else { if(d == '\\' && newwc == nextwc) { d = newwc(); rest = readw(d); while(d = *rest++) { if (staktop >= brkend) growstak(staktop); pushstak(d); } oldstak = staktop; } else { pc = c; while(d = *pc++) { if (staktop >= brkend) growstak(staktop); pushstak(d); } if(!anys(c, ifsnod.namval)) oldstak = staktop; } d = newwc(); if (eolchar(d)) staktop = oldstak; else { rest = readw(d); pc = c; while(*pc++ = *rest++); } } } while (n) { assign(n, nullstr); if (*names) n = lookup(*names++); else n = 0; } if (eof) rc = 1; #ifdef __sun if (isastream(0) != 1) #endif /* * If we are reading on a stream do not attempt to * lseek(2) back towards the start because this is * logically meaningless, but there is nothing in * the standards to pervent the stream implementation * from attempting it and breaking our code here * */ lseek(0, (off_t)(f->nxtoff - f->endoff), SEEK_CUR); pop(); return(rc); }
static int getch(char endch) { register char d; retry: d = readc(); if (!subchar(d)) return (d); if (d == DOLLAR) { register int c; if ((c = readc(), dolchar(c))) { NAMPTR n = (NAMPTR) NIL; int dolg = 0; BOOL bra; register const char *argp; register const char *v; CHAR idb[2]; char *id = idb; if (bra = (c == BRACE)) c = readc(); if (letter(c)) { argp = (STRING) relstak(); while (alphanum(c)) { pushstak(c); c = readc(); } zerostak(); n = lookup(absstak(argp)); setstak(argp); v = n->namval; id = (char *)n->namid; peekc = c | MARK;; } else if (digchar(c)) { *id = c; idb[1] = 0; if (astchar(c)) { dolg = 1; c = '1'; } c -= '0'; v = ((c == 0) ? (const char *)cmdadr : (c <= dolc) ? dolv[c] : (dolg = 0, NULL)); } else if (c == '$') { v = pidadr; } else if (c == '!') { v = pcsadr; } else if (c == '#') { v = dolladr; } else if (c == '?') { v = exitadr; } else if (c == '-') { v = flagadr; } else if (bra) { error(badsub); } else { goto retry; } c = readc(); if (!defchar(c) && bra) error(badsub); argp = 0; if (bra) { if (c != '}') { argp = (STRING) relstak(); if ((v == 0) ^ (setchar(c))) copyto('}'); else skipto('}'); argp = absstak(argp); } } else { peekc = c | MARK; c = 0; } if (v) { if (c != '+') { for (;;) { while (c = *v++) pushstak(c | quote); if (dolg == 0 || (++dolg > dolc)) break; else { v = dolv[dolg]; pushstak(SP | (*id == '*' ? quote : 0)); } } } } else if (argp) { if (c == '?') { failed(id, *argp ? argp : badparam); } else if (c == '=') { if (n) assign(n, argp); else error(badsub); } } else if (flags & setflg) { failed(id, badparam); } goto retry; } else { peekc = c | MARK; } } else if (d == endch) { return (d); } else if (d == SQUOTE) { comsubst(); goto retry; } else if (d == DQUOTE) { quoted++; quote ^= QUOTE; goto retry; } return d; }