diff options
author | Ron Yorston <rmy@pobox.com> | 2019-02-12 08:43:06 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-02-12 08:43:06 +0000 |
commit | 7a8bd5ae33d8c390763f0787afe6b8c495e2d978 (patch) | |
tree | 29b0abb320d73b37f4fa4d9b355b3b32db42e836 /editors | |
parent | 0eda390d68c456975289471e68b615ae096ab33b (diff) | |
parent | f81e0120f4478c58e126bcadb19b9954ed184e8f (diff) | |
download | busybox-w32-7a8bd5ae33d8c390763f0787afe6b8c495e2d978.tar.gz busybox-w32-7a8bd5ae33d8c390763f0787afe6b8c495e2d978.tar.bz2 busybox-w32-7a8bd5ae33d8c390763f0787afe6b8c495e2d978.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'editors')
-rw-r--r-- | editors/awk.c | 41 | ||||
-rw-r--r-- | editors/sed.c | 30 | ||||
-rw-r--r-- | editors/vi.c | 78 |
3 files changed, 77 insertions, 72 deletions
diff --git a/editors/awk.c b/editors/awk.c index 86cd9a289..dbb26068d 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -275,18 +275,21 @@ typedef struct tsplitter_s { | |||
275 | | TC_STRING | TC_NUMBER | TC_UOPPOST) | 275 | | TC_STRING | TC_NUMBER | TC_UOPPOST) |
276 | #define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) | 276 | #define TC_CONCAT2 (TC_OPERAND | TC_UOPPRE) |
277 | 277 | ||
278 | #define OF_RES1 0x010000 | 278 | #define OF_RES1 0x010000 |
279 | #define OF_RES2 0x020000 | 279 | #define OF_RES2 0x020000 |
280 | #define OF_STR1 0x040000 | 280 | #define OF_STR1 0x040000 |
281 | #define OF_STR2 0x080000 | 281 | #define OF_STR2 0x080000 |
282 | #define OF_NUM1 0x100000 | 282 | #define OF_NUM1 0x100000 |
283 | #define OF_CHECKED 0x200000 | 283 | #define OF_CHECKED 0x200000 |
284 | #define OF_REQUIRED 0x400000 | ||
285 | |||
284 | 286 | ||
285 | /* combined operator flags */ | 287 | /* combined operator flags */ |
286 | #define xx 0 | 288 | #define xx 0 |
287 | #define xV OF_RES2 | 289 | #define xV OF_RES2 |
288 | #define xS (OF_RES2 | OF_STR2) | 290 | #define xS (OF_RES2 | OF_STR2) |
289 | #define Vx OF_RES1 | 291 | #define Vx OF_RES1 |
292 | #define Rx (OF_RES1 | OF_NUM1 | OF_REQUIRED) | ||
290 | #define VV (OF_RES1 | OF_RES2) | 293 | #define VV (OF_RES1 | OF_RES2) |
291 | #define Nx (OF_RES1 | OF_NUM1) | 294 | #define Nx (OF_RES1 | OF_NUM1) |
292 | #define NV (OF_RES1 | OF_NUM1 | OF_RES2) | 295 | #define NV (OF_RES1 | OF_NUM1 | OF_RES2) |
@@ -425,7 +428,7 @@ static const uint32_t tokeninfo[] = { | |||
425 | 0, | 428 | 0, |
426 | 0, /* \n */ | 429 | 0, /* \n */ |
427 | ST_IF, ST_DO, ST_FOR, OC_BREAK, | 430 | ST_IF, ST_DO, ST_FOR, OC_BREAK, |
428 | OC_CONTINUE, OC_DELETE|Vx, OC_PRINT, | 431 | OC_CONTINUE, OC_DELETE|Rx, OC_PRINT, |
429 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, | 432 | OC_PRINTF, OC_NEXT, OC_NEXTFILE, |
430 | OC_RETURN|Vx, OC_EXIT|Nx, | 433 | OC_RETURN|Vx, OC_EXIT|Nx, |
431 | ST_WHILE, | 434 | ST_WHILE, |
@@ -593,7 +596,7 @@ static const char EMSG_UNEXP_EOS[] ALIGN1 = "Unexpected end of string"; | |||
593 | static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected token"; | 596 | static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected token"; |
594 | static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero"; | 597 | static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero"; |
595 | static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier"; | 598 | static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier"; |
596 | static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments for builtin"; | 599 | static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments"; |
597 | static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; | 600 | static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array"; |
598 | static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; | 601 | static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error"; |
599 | static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; | 602 | static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function"; |
@@ -1269,7 +1272,7 @@ static node *parse_expr(uint32_t iexp) | |||
1269 | debug_printf_parse("%s(%x)\n", __func__, iexp); | 1272 | debug_printf_parse("%s(%x)\n", __func__, iexp); |
1270 | 1273 | ||
1271 | sn.info = PRIMASK; | 1274 | sn.info = PRIMASK; |
1272 | sn.r.n = glptr = NULL; | 1275 | sn.r.n = sn.a.n = glptr = NULL; |
1273 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; | 1276 | xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; |
1274 | 1277 | ||
1275 | while (!((tc = next_token(xtc)) & iexp)) { | 1278 | while (!((tc = next_token(xtc)) & iexp)) { |
@@ -1291,6 +1294,7 @@ static node *parse_expr(uint32_t iexp) | |||
1291 | || ((t_info == vn->info) && ((t_info & OPCLSMASK) == OC_COLON)) | 1294 | || ((t_info == vn->info) && ((t_info & OPCLSMASK) == OC_COLON)) |
1292 | ) { | 1295 | ) { |
1293 | vn = vn->a.n; | 1296 | vn = vn->a.n; |
1297 | if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN); | ||
1294 | } | 1298 | } |
1295 | if ((t_info & OPCLSMASK) == OC_TERNARY) | 1299 | if ((t_info & OPCLSMASK) == OC_TERNARY) |
1296 | t_info += P(6); | 1300 | t_info += P(6); |
@@ -1429,7 +1433,11 @@ static void chain_expr(uint32_t info) | |||
1429 | node *n; | 1433 | node *n; |
1430 | 1434 | ||
1431 | n = chain_node(info); | 1435 | n = chain_node(info); |
1436 | |||
1432 | n->l.n = parse_expr(TC_OPTERM | TC_GRPTERM); | 1437 | n->l.n = parse_expr(TC_OPTERM | TC_GRPTERM); |
1438 | if ((info & OF_REQUIRED) && !n->l.n) | ||
1439 | syntax_error(EMSG_TOO_FEW_ARGS); | ||
1440 | |||
1433 | if (t_tclass & TC_GRPTERM) | 1441 | if (t_tclass & TC_GRPTERM) |
1434 | rollback_token(); | 1442 | rollback_token(); |
1435 | } | 1443 | } |
@@ -1609,12 +1617,25 @@ static void parse_program(char *p) | |||
1609 | f = newfunc(t_string); | 1617 | f = newfunc(t_string); |
1610 | f->body.first = NULL; | 1618 | f->body.first = NULL; |
1611 | f->nargs = 0; | 1619 | f->nargs = 0; |
1612 | while (next_token(TC_VARIABLE | TC_SEQTERM) & TC_VARIABLE) { | 1620 | /* Match func arg list: a comma sep list of >= 0 args, and a close paren */ |
1621 | while (next_token(TC_VARIABLE | TC_SEQTERM | TC_COMMA)) { | ||
1622 | /* Either an empty arg list, or trailing comma from prev iter | ||
1623 | * must be followed by an arg */ | ||
1624 | if (f->nargs == 0 && t_tclass == TC_SEQTERM) | ||
1625 | break; | ||
1626 | |||
1627 | /* TC_SEQSTART/TC_COMMA must be followed by TC_VARIABLE */ | ||
1628 | if (t_tclass != TC_VARIABLE) | ||
1629 | syntax_error(EMSG_UNEXP_TOKEN); | ||
1630 | |||
1613 | v = findvar(ahash, t_string); | 1631 | v = findvar(ahash, t_string); |
1614 | v->x.aidx = f->nargs++; | 1632 | v->x.aidx = f->nargs++; |
1615 | 1633 | ||
1634 | /* Arg followed either by end of arg list or 1 comma */ | ||
1616 | if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) | 1635 | if (next_token(TC_COMMA | TC_SEQTERM) & TC_SEQTERM) |
1617 | break; | 1636 | break; |
1637 | if (t_tclass != TC_COMMA) | ||
1638 | syntax_error(EMSG_UNEXP_TOKEN); | ||
1618 | } | 1639 | } |
1619 | seq = &f->body; | 1640 | seq = &f->body; |
1620 | chain_group(); | 1641 | chain_group(); |
diff --git a/editors/sed.c b/editors/sed.c index fd56e0e7f..a5cedbd8d 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -377,25 +377,25 @@ static int get_address(const char *my_str, int *linenum, regex_t ** regex) | |||
377 | /* Grab a filename. Whitespace at start is skipped, then goes to EOL. */ | 377 | /* Grab a filename. Whitespace at start is skipped, then goes to EOL. */ |
378 | static int parse_file_cmd(/*sed_cmd_t *sed_cmd,*/ const char *filecmdstr, char **retval) | 378 | static int parse_file_cmd(/*sed_cmd_t *sed_cmd,*/ const char *filecmdstr, char **retval) |
379 | { | 379 | { |
380 | int start = 0, idx, hack = 0; | 380 | const char *start; |
381 | const char *eol; | ||
381 | 382 | ||
382 | /* Skip whitespace, then grab filename to end of line */ | 383 | /* Skip whitespace, then grab filename to end of line */ |
383 | while (isspace(filecmdstr[start])) | 384 | start = skip_whitespace(filecmdstr); |
384 | start++; | 385 | eol = strchrnul(start, '\n'); |
385 | idx = start; | 386 | if (eol == start) |
386 | while (filecmdstr[idx] && filecmdstr[idx] != '\n') | ||
387 | idx++; | ||
388 | |||
389 | /* If lines glued together, put backslash back. */ | ||
390 | if (filecmdstr[idx] == '\n') | ||
391 | hack = 1; | ||
392 | if (idx == start) | ||
393 | bb_error_msg_and_die("empty filename"); | 387 | bb_error_msg_and_die("empty filename"); |
394 | *retval = xstrndup(filecmdstr+start, idx-start+hack+1); | ||
395 | if (hack) | ||
396 | (*retval)[idx] = '\\'; | ||
397 | 388 | ||
398 | return idx; | 389 | if (*eol) { |
390 | /* If lines glued together, put backslash back. */ | ||
391 | *retval = xstrndup(start, eol-start + 1); | ||
392 | (*retval)[eol-start] = '\\'; | ||
393 | } else { | ||
394 | /* eol is NUL */ | ||
395 | *retval = xstrdup(start); | ||
396 | } | ||
397 | |||
398 | return eol - filecmdstr; | ||
399 | } | 399 | } |
400 | 400 | ||
401 | static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) | 401 | static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) |
diff --git a/editors/vi.c b/editors/vi.c index 3c758cca0..a46339813 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -600,6 +600,7 @@ static void check_context(char); // remember context for '' command | |||
600 | #if ENABLE_FEATURE_VI_UNDO | 600 | #if ENABLE_FEATURE_VI_UNDO |
601 | static void flush_undo_data(void); | 601 | static void flush_undo_data(void); |
602 | static void undo_push(char *, unsigned int, unsigned char); // Push an operation on the undo stack | 602 | static void undo_push(char *, unsigned int, unsigned char); // Push an operation on the undo stack |
603 | static void undo_push_insert(char *, int, int); // convenience function | ||
603 | static void undo_pop(void); // Undo the last operation | 604 | static void undo_pop(void); // Undo the last operation |
604 | # if ENABLE_FEATURE_VI_UNDO_QUEUE | 605 | # if ENABLE_FEATURE_VI_UNDO_QUEUE |
605 | static void undo_queue_commit(void); // Flush any queued objects to the undo stack | 606 | static void undo_queue_commit(void); // Flush any queued objects to the undo stack |
@@ -2013,19 +2014,7 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
2013 | c = get_one_char(); | 2014 | c = get_one_char(); |
2014 | *p = c; | 2015 | *p = c; |
2015 | #if ENABLE_FEATURE_VI_UNDO | 2016 | #if ENABLE_FEATURE_VI_UNDO |
2016 | switch (undo) { | 2017 | undo_push_insert(p, 1, undo); |
2017 | case ALLOW_UNDO: | ||
2018 | undo_push(p, 1, UNDO_INS); | ||
2019 | break; | ||
2020 | case ALLOW_UNDO_CHAIN: | ||
2021 | undo_push(p, 1, UNDO_INS_CHAIN); | ||
2022 | break; | ||
2023 | # if ENABLE_FEATURE_VI_UNDO_QUEUE | ||
2024 | case ALLOW_UNDO_QUEUED: | ||
2025 | undo_push(p, 1, UNDO_INS_QUEUED); | ||
2026 | break; | ||
2027 | # endif | ||
2028 | } | ||
2029 | #else | 2018 | #else |
2030 | modified_count++; | 2019 | modified_count++; |
2031 | #endif /* ENABLE_FEATURE_VI_UNDO */ | 2020 | #endif /* ENABLE_FEATURE_VI_UNDO */ |
@@ -2053,19 +2042,7 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
2053 | if (c == '\n') | 2042 | if (c == '\n') |
2054 | undo_queue_commit(); | 2043 | undo_queue_commit(); |
2055 | # endif | 2044 | # endif |
2056 | switch (undo) { | 2045 | undo_push_insert(p, 1, undo); |
2057 | case ALLOW_UNDO: | ||
2058 | undo_push(p, 1, UNDO_INS); | ||
2059 | break; | ||
2060 | case ALLOW_UNDO_CHAIN: | ||
2061 | undo_push(p, 1, UNDO_INS_CHAIN); | ||
2062 | break; | ||
2063 | # if ENABLE_FEATURE_VI_UNDO_QUEUE | ||
2064 | case ALLOW_UNDO_QUEUED: | ||
2065 | undo_push(p, 1, UNDO_INS_QUEUED); | ||
2066 | break; | ||
2067 | # endif | ||
2068 | } | ||
2069 | #else | 2046 | #else |
2070 | modified_count++; | 2047 | modified_count++; |
2071 | #endif /* ENABLE_FEATURE_VI_UNDO */ | 2048 | #endif /* ENABLE_FEATURE_VI_UNDO */ |
@@ -2085,7 +2062,7 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
2085 | p += bias; | 2062 | p += bias; |
2086 | q += bias; | 2063 | q += bias; |
2087 | #if ENABLE_FEATURE_VI_UNDO | 2064 | #if ENABLE_FEATURE_VI_UNDO |
2088 | undo_push(p, len, UNDO_INS); | 2065 | undo_push_insert(p, len, undo); |
2089 | #endif | 2066 | #endif |
2090 | memcpy(p, q, len); | 2067 | memcpy(p, q, len); |
2091 | p += len; | 2068 | p += len; |
@@ -2339,16 +2316,18 @@ static void undo_push(char *src, unsigned int length, uint8_t u_type) // Add to | |||
2339 | } | 2316 | } |
2340 | break; | 2317 | break; |
2341 | case UNDO_INS_QUEUED: | 2318 | case UNDO_INS_QUEUED: |
2342 | if (length != 1) | 2319 | if (length < 1) |
2343 | return; | 2320 | return; |
2344 | switch (undo_queue_state) { | 2321 | switch (undo_queue_state) { |
2345 | case UNDO_EMPTY: | 2322 | case UNDO_EMPTY: |
2346 | undo_queue_state = UNDO_INS; | 2323 | undo_queue_state = UNDO_INS; |
2347 | undo_queue_spos = src; | 2324 | undo_queue_spos = src; |
2348 | case UNDO_INS: | 2325 | case UNDO_INS: |
2349 | undo_q++; // Don't need to save any data for insertions | 2326 | while (length--) { |
2350 | if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX) | 2327 | undo_q++; // Don't need to save any data for insertions |
2351 | undo_queue_commit(); | 2328 | if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX) |
2329 | undo_queue_commit(); | ||
2330 | } | ||
2352 | return; | 2331 | return; |
2353 | case UNDO_DEL: | 2332 | case UNDO_DEL: |
2354 | // Switch from storing deleted text to inserted text | 2333 | // Switch from storing deleted text to inserted text |
@@ -2394,6 +2373,23 @@ static void undo_push(char *src, unsigned int length, uint8_t u_type) // Add to | |||
2394 | modified_count++; | 2373 | modified_count++; |
2395 | } | 2374 | } |
2396 | 2375 | ||
2376 | static void undo_push_insert(char *p, int len, int undo) | ||
2377 | { | ||
2378 | switch (undo) { | ||
2379 | case ALLOW_UNDO: | ||
2380 | undo_push(p, len, UNDO_INS); | ||
2381 | break; | ||
2382 | case ALLOW_UNDO_CHAIN: | ||
2383 | undo_push(p, len, UNDO_INS_CHAIN); | ||
2384 | break; | ||
2385 | # if ENABLE_FEATURE_VI_UNDO_QUEUE | ||
2386 | case ALLOW_UNDO_QUEUED: | ||
2387 | undo_push(p, len, UNDO_INS_QUEUED); | ||
2388 | break; | ||
2389 | # endif | ||
2390 | } | ||
2391 | } | ||
2392 | |||
2397 | static void undo_pop(void) // Undo the last operation | 2393 | static void undo_pop(void) // Undo the last operation |
2398 | { | 2394 | { |
2399 | int repeat; | 2395 | int repeat; |
@@ -2667,14 +2663,7 @@ static uintptr_t string_insert(char *p, const char *s, int undo) // insert the s | |||
2667 | 2663 | ||
2668 | i = strlen(s); | 2664 | i = strlen(s); |
2669 | #if ENABLE_FEATURE_VI_UNDO | 2665 | #if ENABLE_FEATURE_VI_UNDO |
2670 | switch (undo) { | 2666 | undo_push_insert(p, i, undo); |
2671 | case ALLOW_UNDO: | ||
2672 | undo_push(p, i, UNDO_INS); | ||
2673 | break; | ||
2674 | case ALLOW_UNDO_CHAIN: | ||
2675 | undo_push(p, i, UNDO_INS_CHAIN); | ||
2676 | break; | ||
2677 | } | ||
2678 | #endif | 2667 | #endif |
2679 | bias = text_hole_make(p, i); | 2668 | bias = text_hole_make(p, i); |
2680 | p += bias; | 2669 | p += bias; |
@@ -4263,14 +4252,9 @@ static void do_cmd(int c) | |||
4263 | case 'r': // r- replace the current char with user input | 4252 | case 'r': // r- replace the current char with user input |
4264 | c1 = get_one_char(); // get the replacement char | 4253 | c1 = get_one_char(); // get the replacement char |
4265 | if (*dot != '\n') { | 4254 | if (*dot != '\n') { |
4266 | #if ENABLE_FEATURE_VI_UNDO | 4255 | dot = text_hole_delete(dot, dot, ALLOW_UNDO); |
4267 | undo_push(dot, 1, UNDO_DEL); | 4256 | dot = char_insert(dot, c1, ALLOW_UNDO_CHAIN); |
4268 | *dot = c1; | 4257 | dot_left(); |
4269 | undo_push(dot, 1, UNDO_INS_CHAIN); | ||
4270 | #else | ||
4271 | *dot = c1; | ||
4272 | modified_count++; | ||
4273 | #endif | ||
4274 | } | 4258 | } |
4275 | end_cmd_q(); // stop adding to q | 4259 | end_cmd_q(); // stop adding to q |
4276 | break; | 4260 | break; |