summaryrefslogtreecommitdiff
path: root/editors/awk.c
diff options
context:
space:
mode:
authorGlenn L McGrath2003-10-30 13:36:39 +0000
committerGlenn L McGrath2003-10-30 13:36:39 +0000
commit00ed36fd5248de9a612d9417918c5a44406d4644 (patch)
tree7852793928a1a66af1976b251cdece1b50e87f17 /editors/awk.c
parentb8b6816f7b0aa20e1e08e0881f4a428ccd76850e (diff)
downloadbusybox-00ed36fd5248de9a612d9417918c5a44406d4644.zip
busybox-00ed36fd5248de9a612d9417918c5a44406d4644.tar.gz
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)
Diffstat (limited to 'editors/awk.c')
-rw-r--r--editors/awk.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/editors/awk.c b/editors/awk.c
index 0f8cf94..8f746b4 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -82,6 +82,7 @@ typedef struct func_s {
typedef struct rstream_s {
FILE *F;
char *buffer;
+ int adv;
int size;
int pos;
unsigned short is_pipe;
@@ -426,6 +427,7 @@ static nvblock *cb = NULL;
static char *pos;
static char *buf;
static int icase = FALSE;
+static int exiting = FALSE;
static struct {
unsigned long tclass;
@@ -464,7 +466,7 @@ static const char EMSG_NO_MATH[] = "Math support is not compiled in";
static void syntax_error(const char * const message)
{
bb_error_msg("%s:%i: %s", programname, lineno, message);
- awk_exit(1);
+ exit(1);
}
#define runtime_error(x) syntax_error(x)
@@ -1634,21 +1636,24 @@ static int awk_getline(rstream *rsm, var *v) {
char *b;
regmatch_t pmatch[2];
- int p, pp=0, size;
+ int a, p, pp=0, size;
int fd, so, eo, r, rp;
- char c, *s;
+ char c, *m, *s;
/* we're using our own buffer since we need access to accumulating
* characters
*/
fd = fileno(rsm->F);
- b = rsm->buffer;
+ m = rsm->buffer;
+ a = rsm->adv;
p = rsm->pos;
size = rsm->size;
c = (char) rsplitter.n.info;
rp = 0;
+
+ if (! m) qrealloc(&m, 256, &size);
do {
- qrealloc(&b, p+128, &size);
+ b = m + a;
so = eo = p;
r = 1;
if (p > 0) {
@@ -1680,6 +1685,14 @@ static int awk_getline(rstream *rsm, var *v) {
}
}
+ if (a > 0) {
+ memmove(m, (const void *)(m+a), p+1);
+ b = m;
+ a = 0;
+ }
+
+ qrealloc(&m, a+p+128, &size);
+ b = m + a;
pp = p;
p += safe_read(fd, b+p, size-p-1);
if (p < pp) {
@@ -1703,11 +1716,9 @@ static int awk_getline(rstream *rsm, var *v) {
b[eo] = c;
}
- p -= eo;
- if (p) memmove(b, (const void *)(b+eo), p+1);
-
- rsm->buffer = b;
- rsm->pos = p;
+ rsm->buffer = m;
+ rsm->adv = a + eo;
+ rsm->pos = p - eo;
rsm->size = size;
return r;
@@ -2534,6 +2545,12 @@ static int awk_exit(int r) {
unsigned int i;
hash_item *hi;
+ static var tv;
+
+ if (! exiting) {
+ exiting = TRUE;
+ evaluate(endseq.first, &tv);
+ }
/* waiting for children */
for (i=0; i<fdhash->csize; i++) {
@@ -2581,7 +2598,7 @@ static rstream *next_input_file(void) {
if (rsm.F) fclose(rsm.F);
rsm.F = NULL;
- rsm.pos = 0;
+ rsm.pos = rsm.adv = 0;
do {
if (getvar_i(V[ARGIND])+1 >= getvar_i(V[ARGC])) {
@@ -2733,7 +2750,6 @@ extern int awk_main(int argc, char **argv) {
}
- evaluate(endseq.first, &tv);
awk_exit(EXIT_SUCCESS);
return 0;