aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-10-30 13:36:39 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-10-30 13:36:39 +0000
commit00ed36fd5248de9a612d9417918c5a44406d4644 (patch)
tree7852793928a1a66af1976b251cdece1b50e87f17
parentb8b6816f7b0aa20e1e08e0881f4a428ccd76850e (diff)
downloadbusybox-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.c40
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 {
82typedef struct rstream_s { 82typedef 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;
426static char *pos; 427static char *pos;
427static char *buf; 428static char *buf;
428static int icase = FALSE; 429static int icase = FALSE;
430static int exiting = FALSE;
429 431
430static struct { 432static 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";
464static void syntax_error(const char * const message) 466static 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;