shithub: scc

Download patch

ref: 664e782912da639d082308433dd7dddfcf9922ce
parent: 7c3cd98f410be4dfea41213eb55c6ff88b09b280
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu May 7 11:11:47 EDT 2015

Add addinput() lexer function

This function is thought for a first attempt to add preprocessor
capabilities to the lexer.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -262,6 +262,9 @@
 extern uint8_t next(void);
 extern void expect(uint8_t tok);
 extern void discard(void);
+extern char *filename(void);
+extern unsigned short fileline(void);
+extern void addinput(char *fname);
 #define accept(t) ((yytoken == (t)) ? next() : 0)
 
 /* code.c */
--- a/cc1/error.c
+++ b/cc1/error.c
@@ -12,14 +12,10 @@
 static void
 warn_helper(int8_t flag, char *fmt, va_list va)
 {
-	extern unsigned linenum;
-	extern unsigned columnum;
-	extern const char *filename;
-
 	if (!flag)
 		return;
 	fprintf(stderr, "%s:%s:%u: ",
-		(flag < 0) ? "error" : "warning", filename, linenum);
+		(flag < 0) ? "error" : "warning", filename(), fileline());
 	vfprintf(stderr, fmt, va);
 	putc('\n', stderr);
 }
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -10,9 +10,15 @@
 #include "../inc/cc.h"
 #include "cc1.h"
 
+typedef struct input Input;
+
+struct input {
+	char *fname;
+	unsigned short nline;
+	struct input *next;
+};
+
 uint8_t lex_ns = NS_IDEN;
-const char *filename;
-unsigned linenum;
 
 uint8_t yytoken;
 struct yystype yylval;
@@ -19,7 +25,45 @@
 char yytext[IDENTSIZ + 1];
 static uint8_t safe;
 
+static Input *input;
 
+void
+addinput(char *fname)
+{
+	Input *ip;
+
+	ip = xmalloc(sizeof(Input));
+	ip->next = input;
+	if (fname) {
+		if (!freopen(fname, "r", stdin))
+			die("file '%s' not found", fname);	
+		ip->fname = xstrdup(fname);
+		ip->nline = 1;
+	} else {
+		ip->fname = NULL;
+		ip->nline = (input) ? input->nline : 1;
+	}
+	input = ip;
+}
+
+char *
+filename(void)
+{
+	Input *ip;
+
+	for (ip = input; ip; ip = ip->next) {
+		if (ip->fname)
+			return ip->fname;
+	}
+	return "(stdin)";
+}
+
+unsigned short
+fileline(void)
+{
+	return input->nline;
+}
+
 static uint8_t
 integer(char *s, char base)
 {
@@ -137,7 +181,7 @@
 			warn("character constant out of range");
 		break;
 	case '\n':
-		 ++linenum;
+		 ++input->nline;
 		if ((c = getchar()) == '\\')
 			goto repeat;
 		break;
@@ -359,7 +403,7 @@
 
 	while (isspace(c = getchar())) {
 		if (c == '\n')
-			++linenum;
+			++input->nline;
 	}
 	return c;
 }
@@ -409,20 +453,6 @@
 	ungetc(c = skipspaces(), stdin);
 
 	return c;
-}
-
-void
-lexfile(const char *file)
-{
-
-	if (file == NULL) {
-		filename = "(stdin)";
-	} else {
-		if (!freopen(file, "r", stdin))
-			die("file '%s' not found", file);
-		filename = file;
-	}
-	linenum = 1;
 }
 
 void
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -66,7 +66,7 @@
 		usage();
 
 	ikeywords();
-	lexfile(*argv);
+	addinput(*argv);
 
 	next();