shithub: scc

Download patch

ref: 669e2ebc23002ffab0e05b1e9c97bf54a7ad9f4d
parent: 2edbdb8b2a7914d14f1b080179a057879144378e
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu May 7 11:50:39 EDT 2015

Add FILE* to input

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -265,6 +265,7 @@
 extern char *filename(void);
 extern unsigned short fileline(void);
 extern void addinput(char *fname);
+extern void delinput(void);
 #define accept(t) ((yytoken == (t)) ? next() : 0)
 
 /* code.c */
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -501,7 +501,8 @@
 	extern jmp_buf recover;
 
 	setsafe(END_DECL);
-	setjmp(recover);
+	if (setjmp(recover))
+		return;
 
 	switch (yytoken) {
 	case IDEN: case TYPE: case TYPEIDEN: case SCLASS: case TQUALIFIER:
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -15,6 +15,7 @@
 struct input {
 	char *fname;
 	unsigned short nline;
+	FILE *fp;
 	struct input *next;
 };
 
@@ -34,30 +35,48 @@
 
 	ip = xmalloc(sizeof(Input));
 	ip->next = input;
+
 	if (fname) {
-		if (!freopen(fname, "r", stdin))
-			die("file '%s' not found", fname);	
+		if ((ip->fp = fopen(fname, "r")) == NULL)
+			die("file '%s' not found", fname);
 		ip->fname = xstrdup(fname);
-		ip->nline = 1;
+	} else if (!input) {
+		ip->fp = stdin;
+		ip->fname = "(stdin)";
 	} else {
-		ip->fname = NULL;
-		ip->nline = (input) ? input->nline : 1;
+		ip->fname = input->fname;
+		ip->fp = NULL;
+		ip->nline = input->nline;
+		return;
 	}
+
+	ip->nline = 1;
 	input = ip;
+	next();
 }
 
-char *
-filename(void)
+void
+delinput(void)
 {
-	Input *ip;
+	Input *ip = input;
+	FILE *fp = ip->fp;
 
-	for (ip = input; ip; ip = ip->next) {
-		if (ip->fname)
-			return ip->fname;
+	if (fp) {
+		if (fclose(fp))
+			die("error reading from input file '%s'", ip->fname);
+		if (strcmp("(stdin)", input->fname))
+			free(ip->fname);
 	}
-	return "(stdin)";
+	input = ip->next;
+	free(ip);
 }
 
+char *
+filename(void)
+{
+	return input->fname;
+}
+
 unsigned short
 fileline(void)
 {
@@ -81,7 +100,7 @@
 
 	size = sign = 0;
 type:
-	switch (ch = toupper(getchar())) {
+	switch (ch = toupper(getc(input->fp))) {
 	case 'L':
 		if (size == LLONG)
 			goto wrong_type;
@@ -92,7 +111,7 @@
 			goto wrong_type;
 		goto type;
 	default:
-		ungetc(ch, stdin);
+		ungetc(ch, input->fp);
 		tp = ctype(INT, sign, size);
 		break;
 	wrong_type:
@@ -114,7 +133,7 @@
 	char ch, *bp;
 
 	for (bp = yytext ; bp < &yytext[IDENTSIZ]; *bp++ = ch) {
-		ch = getchar();
+		ch = getc(input->fp);
 		switch (base) {
 		case 8:
 			if (ch >= '7')
@@ -134,7 +153,7 @@
 	if (bp == &yytext[IDENTSIZ])
 		error("number too long %s", yytext);
 	*bp = '\0';
-	ungetc(ch, stdin);
+	ungetc(ch, input->fp);
 	return yytext;
 }
 
@@ -144,16 +163,16 @@
 	char ch;
 	static char base;
 
-	if ((ch = getchar()) == '0') {
-		if (toupper(ch = getchar()) == 'X') {
+	if ((ch = getc(input->fp)) == '0') {
+		if (toupper(ch = getc(input->fp)) == 'X') {
 			base = 16;
 		} else {
 			base = 8;
-			ungetc(ch, stdin);
+			ungetc(ch, input->fp);
 		}
 	} else {
 		base = 10;
-		ungetc(ch, stdin);
+		ungetc(ch, input->fp);
 	}
 
 	return integer(digits(base), base);
@@ -166,7 +185,7 @@
 	int c;
 
 repeat:
-	switch (getchar()) {
+	switch (getc(input->fp)) {
 	case '\\': c = '\''; break;
 	case 'a':  c = '\a'; break;
 	case 'f':  c = '\f'; break;
@@ -189,7 +208,7 @@
 		break;
 	case '\n':
 		newline();
-		if ((c = getchar()) == '\\')
+		if ((c = getc(input->fp)) == '\\')
 			goto repeat;
 		break;
 	default:
@@ -207,11 +226,11 @@
 	static char c;
 	Symbol *sym;
 
-	getchar();   /* discard the initial ' */
-	c = getchar();
+	getc(input->fp);   /* discard the initial ' */
+	c = getc(input->fp);
 	if (c == '\\')
 		escape(&c);
-	if (getchar() != '\'')
+	if (getc(input->fp) != '\'')
 		error("invalid character constant");
 	sym = install("", NS_IDEN);
 	sym->u.i = c;
@@ -228,10 +247,10 @@
 	int c;
 	static Symbol *sym;
 
-	getchar(); /* discard the initial " */
+	getc(input->fp); /* discard the initial " */
 
 	for (bp = buf; bp < &buf[STRINGSIZ]; ) {
-		switch (c = getchar()) {
+		switch (c = getc(input->fp)) {
 		case EOF:
 			error("found EOF while parsing");
 		case '"':
@@ -263,13 +282,13 @@
 	Symbol *sym;
 
 	for (bp = yytext; bp < &yytext[IDENTSIZ]; *bp++ = c) {
-		if (!isalnum(c = getchar()) && c != '_')
+		if (!isalnum(c = getc(input->fp)) && c != '_')
 			break;
 	}
 	if (bp == &yytext[IDENTSIZ])
 		error("identifier too long %s", yytext);
 	*bp = '\0';
-	ungetc(c, stdin);
+	ungetc(c, input->fp);
 
 	sym = yylval.sym = lookup(yytext, lex_ns);
 	if (!sym || sym->token == IDEN)
@@ -281,7 +300,7 @@
 static uint8_t
 follow(int expect, int ifyes, int ifno)
 {
-	int c = getchar();
+	int c = getc(input->fp);
 
 	if (c == expect) {
 		yytext[1] = c;
@@ -288,7 +307,7 @@
 		yytext[2] = 0;
 		return ifyes;
 	}
-	ungetc(c, stdin);
+	ungetc(c, input->fp);
 	return ifno;
 }
 
@@ -295,7 +314,7 @@
 static uint8_t
 minus(void)
 {
-	int c = getchar();
+	int c = getc(input->fp);
 
 	yytext[1] = c;
 	yytext[2] = '\0';
@@ -305,7 +324,7 @@
 	case '=': return SUB_EQ;
 	default:
 		yytext[1] = '\0';
-		ungetc(c, stdin);
+		ungetc(c, input->fp);
 		return '-';
 	}
 }
@@ -313,7 +332,7 @@
 static uint8_t
 plus(void)
 {
-	int c = getchar();
+	int c = getc(input->fp);
 
 	yytext[1] = c;
 	yytext[2] = '\0';
@@ -322,7 +341,7 @@
 	case '=': return ADD_EQ;
 	default:
 		yytext[1] = '\0';
-		ungetc(c, stdin);
+		ungetc(c, input->fp);
 		return '+';
 	}
 }
@@ -330,7 +349,7 @@
 static uint8_t
 relational(uint8_t op, uint8_t equal, uint8_t shift, uint8_t assig)
 {
-	int c = getchar();
+	int c = getc(input->fp);
 
 	yytext[1] = c;
 	yytext[2] = '\0';
@@ -339,7 +358,7 @@
 		return equal;
 	if (c == op)
 		return follow('=', assig, shift);
-	ungetc(c, stdin);
+	ungetc(c, input->fp);
 	yytext[1] = '\0';
 	return op;
 }
@@ -347,7 +366,7 @@
 static uint8_t
 logic(uint8_t op, uint8_t equal, uint8_t logic)
 {
-	int c = getchar();
+	int c = getc(input->fp);
 
 	yytext[1] = c;
 	yytext[2] = '\0';
@@ -356,7 +375,7 @@
 		return equal;
 	if (c == op)
 		return logic;
-	ungetc(c, stdin);
+	ungetc(c, input->fp);
 	yytext[1] = '\0';
 	return op;
 }
@@ -366,10 +385,10 @@
 {
 	int c;
 
-	if ((c = getchar()) != '.') {
-		ungetc(c, stdin);
+	if ((c = getc(input->fp)) != '.') {
+		ungetc(c, input->fp);
 		return '.';
-	} else if ((c = getchar()) != '.') {
+	} else if ((c = getc(input->fp)) != '.') {
 		error("incorrect token '%s'", yytext);
 	} else {
 		yytext[2] = yytext[1] = '.';
@@ -381,7 +400,7 @@
 static uint8_t
 operator(void)
 {
-	uint8_t c = getchar();
+	uint8_t c = getc(input->fp);
 
 	yytext[0] = c;
 	yytext[1] = '\0';
@@ -408,7 +427,7 @@
 
 	int c;
 
-	while (isspace(c = getchar())) {
+	while (isspace(c = getc(input->fp))) {
 		if (c == '\n')
 			newline();
 	}
@@ -420,7 +439,7 @@
 {
 	int c;
 
-	ungetc(c = skipspaces(), stdin);
+	ungetc(c = skipspaces(), input->fp);
 
 	if (isalpha(c) || c == '_') {
 		yytoken = iden();
@@ -457,7 +476,7 @@
 {
 	int c;
 	
-	ungetc(c = skipspaces(), stdin);
+	ungetc(c = skipspaces(), input->fp);
 
 	return c;
 }
@@ -494,8 +513,9 @@
 				goto jump;
 			break;
 		}
-	} while ((c = getchar()) != EOF);
+	} while ((c = getc(input->fp)) != EOF);
 
+	c = EOFTOK;
 jump:
 	yytoken = c;
 	longjmp(recover, 1);
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -66,15 +66,12 @@
 		usage();
 
 	ikeywords();
-	addinput(*argv);
 
-	next();
-
+	addinput(*argv);
 	while (yytoken != EOFTOK)
 		extdecl();
+	delinput();
 
-	if (fclose(stdin))
-		die("error reading from input:%s", strerror(errno));
 	if (fclose(stdout))
 		die("error writing in output:%s", strerror(errno));
 	return 0;