shithub: scc

Download patch

ref: 954fbccea045ef32df7eb4b38908661d0354cdcb
parent: 81e3671bc0195954d80cb3a212009b94f33cf49f
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Jan 26 08:25:01 EST 2018

[as] Don't use fgets()

We have to use is*() functions, and since we cannot check
if the input is correct or not with fgets (without running
again over the string) is better to use a hand written get
string, which makes easier to implement multiline comments

--- a/as/parser.c
+++ b/as/parser.c
@@ -1,5 +1,6 @@
 static char sccsid[] = "@(#) ./as/parser.c";
 #include <ctype.h>
+#include <limits.h>
 #include <setjmp.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -124,27 +125,58 @@
 	return r;
 }
 
+static void
+comment(FILE *fp)
+{
+	int c;
+
+	while ((c = getc(fp)) != EOF) {
+		if (c != '*')
+			continue;
+		if ((c = getc(fp)) == '/')
+			return;
+		ungetc(c, fp);
+	}
+}
+
+static size_t
+getline(FILE *fp, char buff[MAXLINE])
+{
+	int c;
+	char *bp;
+
+	for (bp = buff; (c = getc(fp)) != EOF; *bp++ = c) {
+		if (c == '\n')
+			break;
+		if (c == '/') {
+			if ((c = getc(fp)) != '*') {
+				ungetc(c, fp);
+			} else {
+				comment(fp);
+				c = ' ';
+			}
+		} else if (c > UCHAR_MAX) {
+			error("invalid character '%x'", c);
+		}
+		if (bp == &buff[MAXLINE])
+			error("line too long");
+	}
+	return bp - buff;
+}
+
 int
 nextline(FILE *fp, struct line *lp)
 {
 	size_t n;
-	char *p;
 	static char buff[MAXLINE];
 
 repeat:
-	if (!fgets(buff, sizeof(buff), fp))
+	if (feof(fp))
 		return 0;
-
+	if ((n = getline(fp, buff)) == 0)
+		goto repeat;
 	if (++lineno == 0)
 		die("as: file too long");
-
-	n = strlen(buff);
-	if (n == 0)
-		goto repeat;
-	if (buff[n-1] != '\n')
-		error("line too long");
-	buff[n-1] = '\0';
-
 	if (extract(buff, n, lp) == 0)
 		goto repeat;
 	return 1;