ref: 664e782912da639d082308433dd7dddfcf9922ce
parent: 7c3cd98f410be4dfea41213eb55c6ff88b09b280
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
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();