diff options
author | jilles <jilles@FreeBSD.org> | 2010-10-31 12:06:02 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2010-10-31 12:06:02 +0000 |
commit | 4de067d3c296d7e292bb6b7415b78bc4a789a6b3 (patch) | |
tree | 8991552f2d74e310f587a48b7e2610fa8999dd8b /bin/sh/parser.c | |
parent | f1bdc586812e81a8dc92b036a28f8a29e0ef1914 (diff) | |
download | FreeBSD-src-4de067d3c296d7e292bb6b7415b78bc4a789a6b3.zip FreeBSD-src-4de067d3c296d7e292bb6b7415b78bc4a789a6b3.tar.gz |
sh: Use iteration instead of recursion to evaluate semicolon lists.
This reduces CPU and memory usage when executing long lists (such
as long functions).
Diffstat (limited to 'bin/sh/parser.c')
-rw-r--r-- | bin/sh/parser.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 329e2e3..23db5e7 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -227,13 +227,13 @@ parsecmd(int interact) static union node * list(int nlflag, int erflag) { - union node *n1, *n2, *n3; + union node *ntop, *n1, *n2, *n3; int tok; checkkwd = 2; if (!nlflag && !erflag && tokendlist[peektoken()]) return NULL; - n1 = NULL; + ntop = n1 = NULL; for (;;) { n2 = andor(); tok = readtoken(); @@ -250,14 +250,21 @@ list(int nlflag, int erflag) n2 = n3; } } - if (n1 == NULL) { - n1 = n2; + if (ntop == NULL) + ntop = n2; + else if (n1 == NULL) { + n1 = (union node *)stalloc(sizeof (struct nbinary)); + n1->type = NSEMI; + n1->nbinary.ch1 = ntop; + n1->nbinary.ch2 = n2; + ntop = n1; } else { n3 = (union node *)stalloc(sizeof (struct nbinary)); n3->type = NSEMI; - n3->nbinary.ch1 = n1; + n3->nbinary.ch1 = n1->nbinary.ch2; n3->nbinary.ch2 = n2; + n1->nbinary.ch2 = n3; n1 = n3; } switch (tok) { @@ -269,28 +276,28 @@ list(int nlflag, int erflag) if (tok == TNL) { parseheredoc(); if (nlflag) - return n1; + return ntop; } else if (tok == TEOF && nlflag) { parseheredoc(); - return n1; + return ntop; } else { tokpushback++; } checkkwd = 2; if (!nlflag && !erflag && tokendlist[peektoken()]) - return n1; + return ntop; break; case TEOF: if (heredoclist) parseheredoc(); else pungetc(); /* push back EOF on input */ - return n1; + return ntop; default: if (nlflag || erflag) synexpect(-1); tokpushback++; - return n1; + return ntop; } } } |