summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2005-10-26 20:00:59 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2005-10-26 20:00:59 +1000
commitfc31133e92b1527728c4c2a4f4a2262a46a05b38 (patch)
treefc2bb1ea559132a66a805613ace5c8bc71dde510 /src
parent[INPUT] Fix NUL skipping in preadbuffer (diff)
downloaddash-fc31133e92b1527728c4c2a4f4a2262a46a05b38.tar.gz
dash-fc31133e92b1527728c4c2a4f4a2262a46a05b38.zip
[INPUT] Size optimisations in preadbuffer()
Added unlikely markers.
Reduced switch coverage.
Removed p since we now erase NULs as soon as we see them.
Use more to store parselleft.
Diffstat (limited to 'src')
-rw-r--r--src/input.c58
1 files changed, 31 insertions, 27 deletions
diff --git a/src/input.c b/src/input.c
index 8a43824..4628c2f 100644
--- a/src/input.c
+++ b/src/input.c
@@ -260,14 +260,14 @@ retry:
 int
 preadbuffer(void)
 {
-	char *p, *q;
+	char *q;
 	int more;
 #ifndef SMALL
 	int something;
 #endif
 	char savec;
 
-	while (parsefile->strpush) {
+	while (unlikely(parsefile->strpush)) {
 		if (
 			parsenleft == -1 && parsefile->strpush->ap &&
 			parsenextc[-1] != ' ' && parsenextc[-1] != '\t'
@@ -278,60 +278,64 @@ preadbuffer(void)
 		if (--parsenleft >= 0)
 			return (*parsenextc++);
 	}
-	if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
+	if (unlikely(parsenleft == EOF_NLEFT || parsefile->buf == NULL))
 		return PEOF;
 	flushout(&output);
 #ifdef FLUSHERR
 	flushout(&errout);
 #endif
 
+	more = parselleft;
+	if (more <= 0) {
 again:
-	if (parselleft <= 0) {
-		if ((parselleft = preadfd()) <= 0) {
+		if ((more = preadfd()) <= 0) {
 			parselleft = parsenleft = EOF_NLEFT;
 			return PEOF;
 		}
 	}
 
-	q = p = parsenextc;
+	q = parsenextc;
 
 	/* delete nul characters */
 #ifndef SMALL
 	something = 0;
 #endif
-	for (more = 1; more;) {
-		switch (*p++) {
-		case '\0':
-			p = memmove(q, p, parselleft);
-			goto check;
+	for (;;) {
+		int c;
 
-#ifndef SMALL
-		case '\t':
-		case ' ':
-			break;
-#endif
+		more--;
+		c = *q;
 
-		case '\n':
-			parsenleft = q - parsenextc;
-			more = 0; /* Stop processing here */
-			break;
+		if (!c)
+			memmove(q, q + 1, more);
+		else {
+			q++;
+
+			if (c == '\n') {
+				parsenleft = q - parsenextc - 1;
+				break;
+			}
 
 #ifndef SMALL
-		default:
-			something = 1;
-			break;
+			switch (c) {
+			default:
+				something = 1;
+				/* fall through */
+			case '\t':
+			case ' ':
+				break;
+			}
 #endif
 		}
 
-		q++;
-check:
-		if (--parselleft <= 0 && more) {
+		if (more <= 0) {
 			parsenleft = q - parsenextc - 1;
 			if (parsenleft < 0)
 				goto again;
-			more = 0;
+			break;
 		}
 	}
+	parselleft = more;
 
 	savec = *q;
 	*q = '\0';