diff options
Diffstat (limited to '')
-rw-r--r-- | src/miscbltin.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/src/miscbltin.c b/src/miscbltin.c index 800cbbb..f507381 100644 --- a/src/miscbltin.c +++ b/src/miscbltin.c @@ -71,21 +71,22 @@ * @param len length of line including trailing '\0' */ static void -readcmd_handle_line(char *line, char **ap, size_t len) +readcmd_handle_line(char *s, char **ap) { struct arglist arglist; struct strlist *sl; - char *s, *backup; + char *backup; + char *line; /* ifsbreakup will fiddle with stack region... */ - s = grabstackstr(line + len); + line = stackblock(); + s = grabstackstr(s); /* need a copy, so that delimiters aren't lost * in case there are more fields than variables */ backup = sstrdup(line); arglist.lastp = &arglist.list; - recordregion(0, len - 1, 0); ifsbreakup(s, &arglist); *arglist.lastp = NULL; @@ -137,11 +138,12 @@ int readcmd(int argc, char **argv) { char **ap; - int backslash; char c; int rflag; char *prompt; char *p; + int startloc; + int newloc; int status; int i; @@ -161,9 +163,12 @@ readcmd(int argc, char **argv) } if (*(ap = argptr) == NULL) sh_error("arg count"); + status = 0; - backslash = 0; STARTSTACKSTR(p); + + goto start; + for (;;) { switch (read(0, &c, 1)) { case 1: @@ -178,26 +183,35 @@ readcmd(int argc, char **argv) } if (c == '\0') continue; - if (backslash || c == CTLESC) { + if (newloc >= startloc) { if (c == '\n') goto resetbs; - STPUTC(CTLESC, p); goto put; } if (!rflag && c == '\\') { - backslash++; + newloc = p - (char *)stackblock(); continue; } if (c == '\n') break; put: - STPUTC(c, p); + CHECKSTRSPACE(2, p); + if (strchr(qchars, c)) + USTPUTC(CTLESC, p); + USTPUTC(c, p); + + if (newloc >= startloc) { resetbs: - backslash = 0; + recordregion(startloc, newloc, 0); +start: + startloc = p - (char *)stackblock(); + newloc = startloc - 1; + } } out: + recordregion(startloc, p - (char *)stackblock(), 0); STACKSTRNUL(p); - readcmd_handle_line(stackblock(), ap, p + 1 - (char *)stackblock()); + readcmd_handle_line(p + 1, ap); return status; } |