char * appstak(char *x) { while (*x) pushstak(*x++); zerostak(); return x; }
static void comsubst(void) { /* command substn */ FILEBLK cb; register char d; register STKPTR savptr = fixstak(); usestak(); while ((d = readc()) != SQUOTE && d) pushstak(d); { register char *argc; trim(argc = fixstak()); push(&cb); estabf(argc); } { register TREPTR t = makefork(FPOU, cmd(EOFSYM, MTFLG | NLFLG)); int pv[2]; /* this is done like this so that the pipe * is open only when needed */ chkpipe(pv); initf(pv[INPIPE]); execute(t, 0, 0, pv); close(pv[OTPIPE]); } tdystak(savptr); staktop = movstr(savptr, stakbot); while (d = readc()) pushstak(d | quote); await(0); while (stakbot != staktop) { if ((*--staktop & STRIP) != NL) { ++staktop; break; } } pop(); }
static char *copyto(char endch) { register CHAR c; while ((c = getch(endch)) != endch && c) pushstak(c | quote); zerostak(); if (c != endch) error(badsub); }
void subst(int in, int ot) { register char c; FILEBLK fb; register int count = CPYSIZ; push(&fb); initf(in); /* DQUOTE used to stop it from quoting */ while (c = (getch(DQUOTE) & STRIP)) { pushstak(c); if (--count == 0) { flush(ot); count = CPYSIZ; } } flush(ot); pop(); }
char *macro(char *as) { /* Strip "" and do $ substitution * Leaves result on top of stack */ register BOOL savqu = quoted; register CHAR savq = quote; FILEHDR fb; push((void *)&fb);/*FIXME*/ estabf(as); usestak(); quote = 0; quoted = 0; copyto(0); pop(); if (quoted && (stakbot == staktop)) { pushstak(QUOTE); } quote = savq; quoted = savqu; return (fixstak()); }
char * endstak () { pushstak(0); return getstak(staktop-stakbot); }
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 void copyto(unsigned char endch, int trimflag) /* trimflag - flag to check if argument will be trimmed */ { unsigned int c; unsigned int d; unsigned char *pc; while ((c = getch(endch, trimflag)) != endch && c) if (quote) { if(c == '\\') { /* don't interpret next character */ if (staktop >= brkend) growstak(staktop); pushstak(c); d = readwc(); if(!escchar(d)) { /* both \ and following character are quoted if next character is not $, `, ", or \*/ if (staktop >= brkend) growstak(staktop); pushstak('\\'); if (staktop >= brkend) growstak(staktop); pushstak('\\'); pc = readw(d); /* push entire multibyte char */ while(*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } else { pc = readw(d); /* d might be NULL */ /* Evenif d is NULL, we have to save it */ if (*pc) { while (*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } else { if (staktop >= brkend) growstak(staktop); pushstak(*pc); } } } else { /* push escapes onto stack to quote characters */ pc = readw(c); if (staktop >= brkend) growstak(staktop); pushstak('\\'); while(*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } } else if(c == '\\') { c = readwc(); /* get character to be escaped */ if (staktop >= brkend) growstak(staktop); pushstak('\\'); pc = readw(c); /* c might be NULL */ /* Evenif c is NULL, we have to save it */ if (*pc) { while (*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } else { if (staktop >= brkend) growstak(staktop); pushstak(*pc); } } else { pc = readw(c); while (*pc) { if (staktop >= brkend) growstak(staktop); pushstak(*pc++); } } if (staktop >= brkend) growstak(staktop); zerostak(); if (c != endch) error(badsub); }
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; }
void addblok(unsigned int reqd) { if (stakbot == 0) { brkbegin = setbrk(3 * BRKINCR); /* * setbrk() returns 8 byte aligned address * but we could need larger align in future */ brkbegin = (unsigned char *)round(brkbegin, ALIGNSIZ); bloktop = (struct blk *)brkbegin; } if (stakbas != staktop) { unsigned char *rndstak; struct blk *blokstak; if (staktop >= brkend) growstak(staktop); pushstak(0); rndstak = (unsigned char *)round(staktop, ALIGNSIZ); blokstak = (struct blk *)(stakbas) - 1; blokstak->word = stakbsy; stakbsy = blokstak; bloktop->word = (struct blk *)(Rcheat(rndstak) | BUSY); bloktop = (struct blk *)(rndstak); } reqd += brkincr; reqd &= ~(brkincr - 1); blokp = bloktop; /* * brkend points to the first invalid address. * make sure bloktop is valid. */ if ((unsigned char *)&bloktop->word >= brkend) { if (setbrk((unsigned)((unsigned char *) (&bloktop->word) - brkend + sizeof (struct blk))) == (unsigned char *)-1) error(nospace); } bloktop = bloktop->word = (struct blk *)(Rcheat(bloktop) + reqd); if ((unsigned char *)&bloktop->word >= brkend) { if (setbrk((unsigned)((unsigned char *) (&bloktop->word) - brkend + sizeof (struct blk))) == (unsigned char *)-1) error(nospace); } bloktop->word = (struct blk *)(brkbegin + 1); { unsigned char *stakadr = (unsigned char *) (bloktop + 2); unsigned char *sp = stakadr; if (reqd = (staktop-stakbot)) { if (stakadr + reqd >= brkend) growstak(stakadr + reqd); while (reqd-- > 0) *sp++ = *stakbot++; sp--; } staktop = sp; if (staktop >= brkend) growstak(staktop); stakbas = stakbot = stakadr; } }