diff options
-rw-r--r-- | toys/posix/sed.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/toys/posix/sed.c b/toys/posix/sed.c index 979a6eb8..d958ab70 100644 --- a/toys/posix/sed.c +++ b/toys/posix/sed.c @@ -461,11 +461,14 @@ static void sed_line(char **pline, long plen) char *l = (c=='P') ? strchr(line, '\n') : 0; if (emit(line, l ? l-line : len, eol)) break; - } else if (c=='q') { + } else if (c=='q' || c=='Q') { if (pline) *pline = (void *)1; free(TT.nextline); + if (!toys.exitval && command->arg1) + toys.exitval = atoi(command->arg1+(char *)command); TT.nextline = 0; TT.nextlen = 0; + if (c=='Q') line = 0; break; } else if (c=='s') { @@ -826,7 +829,7 @@ static void parse_pattern(char **pline, long len) c = command->c = *(line++); if (strchr("}:", c) && i) break; - if (strchr("aiqr=", c) && i>1) break; + if (strchr("aiqQr=", c) && i>1) break; // Allocate memory and copy out of toybuf now that we know how big it is command = xmemdup(toybuf, reg-toybuf); @@ -953,7 +956,7 @@ writenow: if (len != strlen(s)) goto error; reg = extend_string((void *)&command, s, reg-(char*)command, len); free(s); - } else if (strchr("abcirtTw:", c)) { + } else if (strchr("abcirtTqQw:", c)) { int end; // trim leading spaces @@ -964,12 +967,20 @@ writenow: resume_a: command->hit = 0; - // btT: end with space or semicolon, aicrw continue to newline. - if (!(end = strcspn(line, strchr(":btT", c) ? "}; \t\r\n\v\f" : "\n"))) { - // Argument's optional for btT + // btTqQ: end with space or semicolon, aicrw continue to newline. + if (!(end = strcspn(line, strchr(":btTqQ", c) ? "}; \t\r\n\v\f" : "\n"))){ + // Argument's optional for btTqQ if (strchr("btT", c)) continue; else if (!command->arg1) break; } + // Error checking: qQ can only have digits after them + if (c=='q' || c=='Q') { + for (i = 0; i<end && isdigit(line[i]); i++); + if (i != end) { + line += i; + break; + } + } // Extend allocation to include new string. We use offsets instead of // pointers so realloc() moving stuff doesn't break things. Ok to write @@ -1007,7 +1018,7 @@ resume_a: } else line += end; // Commands that take no arguments - } else if (!strchr("{dDgGhHlnNpPqx=", c)) break; + } else if (!strchr("{dDgGhHlnNpPx=", c)) break; } error: |