aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
Diffstat (limited to 'toys')
-rw-r--r--toys/posix/sed.c25
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: