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)
This commit is contained in:
parent
b8b6816f7b
commit
00ed36fd52
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user