diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-10-30 13:36:39 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-10-30 13:36:39 +0000 |
commit | 00ed36fd5248de9a612d9417918c5a44406d4644 (patch) | |
tree | 7852793928a1a66af1976b251cdece1b50e87f17 | |
parent | b8b6816f7b0aa20e1e08e0881f4a428ccd76850e (diff) | |
download | busybox-w32-00ed36fd5248de9a612d9417918c5a44406d4644.tar.gz busybox-w32-00ed36fd5248de9a612d9417918c5a44406d4644.tar.bz2 busybox-w32-00ed36fd5248de9a612d9417918c5a44406d4644.zip |
Patch from Dmitry Zakharov,
Fixes two bugs:
- END block didn't execute after an exit() call
- huge memory consumption and performance degradation on large input
(now performance is comparable to gawk)
-rw-r--r-- | editors/awk.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/editors/awk.c b/editors/awk.c index 0f8cf94f4..8f746b48c 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -82,6 +82,7 @@ typedef struct func_s { | |||
82 | typedef struct rstream_s { | 82 | typedef struct rstream_s { |
83 | FILE *F; | 83 | FILE *F; |
84 | char *buffer; | 84 | char *buffer; |
85 | int adv; | ||
85 | int size; | 86 | int size; |
86 | int pos; | 87 | int pos; |
87 | unsigned short is_pipe; | 88 | unsigned short is_pipe; |
@@ -426,6 +427,7 @@ static nvblock *cb = NULL; | |||
426 | static char *pos; | 427 | static char *pos; |
427 | static char *buf; | 428 | static char *buf; |
428 | static int icase = FALSE; | 429 | static int icase = FALSE; |
430 | static int exiting = FALSE; | ||
429 | 431 | ||
430 | static struct { | 432 | static struct { |
431 | unsigned long tclass; | 433 | unsigned long tclass; |
@@ -464,7 +466,7 @@ static const char EMSG_NO_MATH[] = "Math support is not compiled in"; | |||
464 | static void syntax_error(const char * const message) | 466 | static void syntax_error(const char * const message) |
465 | { | 467 | { |
466 | bb_error_msg("%s:%i: %s", programname, lineno, message); | 468 | bb_error_msg("%s:%i: %s", programname, lineno, message); |
467 | awk_exit(1); | 469 | exit(1); |
468 | } | 470 | } |
469 | 471 | ||
470 | #define runtime_error(x) syntax_error(x) | 472 | #define runtime_error(x) syntax_error(x) |
@@ -1634,21 +1636,24 @@ static int awk_getline(rstream *rsm, var *v) { | |||
1634 | 1636 | ||
1635 | char *b; | 1637 | char *b; |
1636 | regmatch_t pmatch[2]; | 1638 | regmatch_t pmatch[2]; |
1637 | int p, pp=0, size; | 1639 | int a, p, pp=0, size; |
1638 | int fd, so, eo, r, rp; | 1640 | int fd, so, eo, r, rp; |
1639 | char c, *s; | 1641 | char c, *m, *s; |
1640 | 1642 | ||
1641 | /* we're using our own buffer since we need access to accumulating | 1643 | /* we're using our own buffer since we need access to accumulating |
1642 | * characters | 1644 | * characters |
1643 | */ | 1645 | */ |
1644 | fd = fileno(rsm->F); | 1646 | fd = fileno(rsm->F); |
1645 | b = rsm->buffer; | 1647 | m = rsm->buffer; |
1648 | a = rsm->adv; | ||
1646 | p = rsm->pos; | 1649 | p = rsm->pos; |
1647 | size = rsm->size; | 1650 | size = rsm->size; |
1648 | c = (char) rsplitter.n.info; | 1651 | c = (char) rsplitter.n.info; |
1649 | rp = 0; | 1652 | rp = 0; |
1653 | |||
1654 | if (! m) qrealloc(&m, 256, &size); | ||
1650 | do { | 1655 | do { |
1651 | qrealloc(&b, p+128, &size); | 1656 | b = m + a; |
1652 | so = eo = p; | 1657 | so = eo = p; |
1653 | r = 1; | 1658 | r = 1; |
1654 | if (p > 0) { | 1659 | if (p > 0) { |
@@ -1680,6 +1685,14 @@ static int awk_getline(rstream *rsm, var *v) { | |||
1680 | } | 1685 | } |
1681 | } | 1686 | } |
1682 | 1687 | ||
1688 | if (a > 0) { | ||
1689 | memmove(m, (const void *)(m+a), p+1); | ||
1690 | b = m; | ||
1691 | a = 0; | ||
1692 | } | ||
1693 | |||
1694 | qrealloc(&m, a+p+128, &size); | ||
1695 | b = m + a; | ||
1683 | pp = p; | 1696 | pp = p; |
1684 | p += safe_read(fd, b+p, size-p-1); | 1697 | p += safe_read(fd, b+p, size-p-1); |
1685 | if (p < pp) { | 1698 | if (p < pp) { |
@@ -1703,11 +1716,9 @@ static int awk_getline(rstream *rsm, var *v) { | |||
1703 | b[eo] = c; | 1716 | b[eo] = c; |
1704 | } | 1717 | } |
1705 | 1718 | ||
1706 | p -= eo; | 1719 | rsm->buffer = m; |
1707 | if (p) memmove(b, (const void *)(b+eo), p+1); | 1720 | rsm->adv = a + eo; |
1708 | 1721 | rsm->pos = p - eo; | |
1709 | rsm->buffer = b; | ||
1710 | rsm->pos = p; | ||
1711 | rsm->size = size; | 1722 | rsm->size = size; |
1712 | 1723 | ||
1713 | return r; | 1724 | return r; |
@@ -2534,6 +2545,12 @@ static int awk_exit(int r) { | |||
2534 | 2545 | ||
2535 | unsigned int i; | 2546 | unsigned int i; |
2536 | hash_item *hi; | 2547 | hash_item *hi; |
2548 | static var tv; | ||
2549 | |||
2550 | if (! exiting) { | ||
2551 | exiting = TRUE; | ||
2552 | evaluate(endseq.first, &tv); | ||
2553 | } | ||
2537 | 2554 | ||
2538 | /* waiting for children */ | 2555 | /* waiting for children */ |
2539 | for (i=0; i<fdhash->csize; i++) { | 2556 | for (i=0; i<fdhash->csize; i++) { |
@@ -2581,7 +2598,7 @@ static rstream *next_input_file(void) { | |||
2581 | 2598 | ||
2582 | if (rsm.F) fclose(rsm.F); | 2599 | if (rsm.F) fclose(rsm.F); |
2583 | rsm.F = NULL; | 2600 | rsm.F = NULL; |
2584 | rsm.pos = 0; | 2601 | rsm.pos = rsm.adv = 0; |
2585 | 2602 | ||
2586 | do { | 2603 | do { |
2587 | if (getvar_i(V[ARGIND])+1 >= getvar_i(V[ARGC])) { | 2604 | if (getvar_i(V[ARGIND])+1 >= getvar_i(V[ARGC])) { |
@@ -2733,7 +2750,6 @@ extern int awk_main(int argc, char **argv) { | |||
2733 | 2750 | ||
2734 | } | 2751 | } |
2735 | 2752 | ||
2736 | evaluate(endseq.first, &tv); | ||
2737 | awk_exit(EXIT_SUCCESS); | 2753 | awk_exit(EXIT_SUCCESS); |
2738 | 2754 | ||
2739 | return 0; | 2755 | return 0; |