/* * Get a word. This routine is analogous to the routine * word() in sh.lex.c for the main lexical input. One difference * here is that we don't get a newline to terminate our expansion. * Rather, DgetC will return a DEOF when we hit the end-of-input. */ static int Dword(void) { int c, c1; Char wbuf[BUFSIZ]; Char *wp = wbuf; int i = MAXWLEN; bool dolflg; bool sofar = 0, done = 0; while (!done) { done = 1; c = DgetC(DODOL); switch (c) { case DEOF: if (sofar == 0) return (0); /* finish this word and catch the code above the next time */ unDredc(c); /* fall into ... */ case '\n': *wp = 0; Gcat(STRNULL, wbuf); return (1); case ' ': case '\t': done = 0; break; case '`': /* We preserve ` quotations which are done yet later */ *wp++ = c, --i; case '\'': case '"': /* * Note that DgetC never returns a QUOTES character from an * expansion, so only true input quotes will get us here or out. */ c1 = c; dolflg = c1 == '"' ? DODOL : 0; for (;;) { c = DgetC(dolflg); if (c == c1) break; if (c == '\n' || c == DEOF) stderror(ERR_UNMATCHED, c1); if ((c & (QUOTE | TRIM)) == ('\n' | QUOTE)) --wp, ++i; if (--i <= 0) stderror(ERR_WTOOLONG); switch (c1) { case '"': /* * Leave any `s alone for later. Other chars are all * quoted, thus `...` can tell it was within "...". */ *wp++ = c == '`' ? '`' : c | QUOTE; break; case '\'': /* Prevent all further interpretation */ *wp++ = c | QUOTE; break; case '`': /* Leave all text alone for later */ *wp++ = c; break; default: break; } } if (c1 == '`') *wp++ = '`' /* i--; eliminated */; sofar = 1; if ((wp = Dpack(wbuf, wp)) == NULL) return (1); else { i = MAXWLEN - (wp - wbuf); done = 0; } break; case '\\': c = DgetC(0); /* No $ subst! */ if (c == '\n' || c == DEOF) { done = 0; break; } c |= QUOTE; break; default: break; } if (done) { unDgetC(c); sofar = 1; if ((wp = Dpack(wbuf, wp)) == NULL) return (1); else { i = MAXWLEN - (wp - wbuf); done = 0; } } } /* Really NOTREACHED */ return (0); }
/* * Get a word. This routine is analogous to the routine * word() in sh.lex.c for the main lexical input. One difference * here is that we don't get a newline to terminate our expansion. * Rather, DgetC will return a DEOF when we hit the end-of-input. */ static int Dword(struct blk_buf *bb) { eChar c, c1; struct Strbuf *wbuf = Strbuf_alloc(); int dolflg; int sofar = 0; Char *str; cleanup_push(wbuf, Strbuf_free); for (;;) { c = DgetC(DODOL); switch (c) { case DEOF: if (sofar == 0) { cleanup_until(wbuf); return (0); } /* finish this word and catch the code above the next time */ unDredc(c); /*FALLTHROUGH*/ case '\n': goto end; case ' ': case '\t': continue; case '`': /* We preserve ` quotations which are done yet later */ Strbuf_append1(wbuf, (Char) c); /*FALLTHROUGH*/ case '\'': case '"': /* * Note that DgetC never returns a QUOTES character from an * expansion, so only true input quotes will get us here or out. */ c1 = c; dolflg = c1 == '"' ? DODOL : 0; for (;;) { c = DgetC(dolflg); if (c == c1) break; if (c == '\n' || c == DEOF) { cleanup_until(bb); stderror(ERR_UNMATCHED, (int)c1); } if ((c & (QUOTE | TRIM)) == ('\n' | QUOTE)) { if (wbuf->len != 0 && (wbuf->s[wbuf->len - 1] & TRIM) == '\\') wbuf->len--; } switch (c1) { case '"': /* * Leave any `s alone for later. Other chars are all * quoted, thus `...` can tell it was within "...". */ Strbuf_append1(wbuf, c == '`' ? '`' : c | QUOTE); break; case '\'': /* Prevent all further interpretation */ Strbuf_append1(wbuf, c | QUOTE); break; case '`': /* Leave all text alone for later */ Strbuf_append1(wbuf, (Char) c); break; default: break; } } if (c1 == '`') Strbuf_append1(wbuf, '`'); sofar = 1; if (Dpack(wbuf) != 0) goto end; continue; case '\\': c = DgetC(0); /* No $ subst! */ if (c == '\n' || c == DEOF) continue; c |= QUOTE; break; default: break; } unDgetC(c); sofar = 1; if (Dpack(wbuf) != 0) goto end; } end: cleanup_ignore(wbuf); cleanup_until(wbuf); str = Strbuf_finish(wbuf); bb_append(bb, str); xfree(wbuf); return 1; }