ref: 8fb3ee51e2eacdf956288a5434dbd2cd57a161ec
parent: 7a32845fcd3b08eb599634ef26bfd963944d630c
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri May 8 14:15:43 EDT 2015
Add include handler It is the first version of the preprocessor handler, and it does the correct work for include of local files.
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -40,6 +40,7 @@
int i;
char *s;
uint8_t token;
+ void (*fun)(char *);
} u;
struct symbol *next;
struct symbol *hash;
@@ -96,6 +97,7 @@
NS_IDEN,
NS_TAG,
NS_LABEL,
+ NS_CPP,
NS_STRUCTS,
NR_NAMESPACES
};
@@ -264,7 +266,7 @@
extern void discard(void);
extern char *filename(void);
extern unsigned short fileline(void);
-extern void addinput(char *fname);
+extern bool addinput(char *fname);
extern void delinput(void);
#define accept(t) ((yytoken == (t)) ? next() : 0)
--- a/cc1/lex.c
+++ b/cc1/lex.c
@@ -1,4 +1,5 @@
+#include <assert.h>
#include <inttypes.h>
#include <setjmp.h>
#include <stdio.h>
@@ -10,7 +11,7 @@
#include "../inc/cc.h"
#include "cc1.h"
-#define INPUTSIZ 128
+#define INPUTSIZ 120
typedef struct input Input;
@@ -17,7 +18,7 @@
struct input {char *fname;
unsigned short nline;
- int8_t cnt;
+ int cnt;
FILE *fp;
char *line, *ptr;
struct input *next;
@@ -35,32 +36,35 @@
static Input *input;
-void
+bool
addinput(char *fname)
{- Input *ip, *oip = input;
+ Input *ip;
+ FILE *fp;
+ unsigned short nline = 1;
+ if (fname) {+ if ((fp = fopen(fname, "r")) == NULL)
+ return 0;
+ fname = xstrdup(fname);
+ } else if (!input) {+ fp = stdin;
+ fname = "(stdin)";
+ } else {+ fname = input->fname;
+ nline = input->nline;
+ fp = NULL;
+ }
+
ip = xmalloc(sizeof(Input));
+ ip->fname = fname;
ip->next = input;
ip->line = NULL;
ip->cnt = 0;
- ip->nline = 1;
+ ip->nline = nline;
+ ip->fp = fp;
input = ip;
-
- if (fname) {- if ((ip->fp = fopen(fname, "r")) == NULL)
- die("file '%s' not found", fname);- ip->fname = xstrdup(fname);
- next();
- } else if (!oip) {- ip->fp = stdin;
- ip->fname = "(stdin)";
- next();
- } else {- ip->fname = oip->fname;
- ip->fp = NULL;
- ip->nline = input->nline;
- }
+ return 1;
}
void
@@ -99,6 +103,110 @@
die("input file '%s' too long", input->fname);}
+/* TODO: preprocessor error must not rise recover */
+static void
+preprocessor(void)
+{+ char str[IDENTSIZ+1], *p, *q;
+ unsigned short cnt, n;
+ Symbol *sym;
+
+ p = input->ptr;
+ q = &p[input->cnt-1];
+ while (q > p && isspace(*q))
+ ++q;
+ while (isspace(*p))
+ ++p;
+ for (q = p; isalpha(*q); ++q)
+ /* nothing */;
+ if ((n = q - p) > IDENTSIZ)
+ goto bad_directive;
+ strncpy(str, p, n);
+ str[n] = '\0';
+
+ /* discard this line for the lexer */
+ input->cnt = 0;
+ if ((sym = lookup(str, NS_CPP)) == NULL)
+ goto bad_directive;
+ (*sym->u.fun)(q);
+ return;
+
+bad_directive:
+ error("incorrect preprocessor directive");+}
+
+void
+include(char *s)
+{+ char fname[FILENAME_MAX], delim, c, *p;
+ size_t len;
+
+ while (isspace(*s))
+ ++s;
+ if ((c = *s++) == '>')
+ delim = '>';
+ else if (c == '"')
+ delim = '"';
+ else
+ goto bad_include;
+
+ for (p = s; (c = *p) && c != delim; ++p)
+ /* nothing */;
+ if (c == '\0')
+ goto bad_include;
+
+ len = p - s;
+ if (delim == '"') {+ if (len >= FILENAME_MAX)
+ goto too_long;
+ strncpy(fname, s, len);
+ fname[len] = '\0';
+ if (!addinput(fname))
+ goto not_found;
+ return;
+ }
+ abort();
+
+ return;
+
+not_found:
+ error("included file '%s' not found", fname);+too_long:
+ error("file name in include too long");+bad_include:
+ error("#include expects \"FILENAME\" or <FILENAME>");+}
+
+void
+define(char *str)
+{+
+}
+
+void
+undef(char *str)
+{+ fprintf(stderr, "Esto en un undef\n");
+}
+
+void
+ifdef(char *str)
+{+ fprintf(stderr, "Esto en un ifdef\n");
+}
+
+void
+ifndef(char *str)
+{+ fprintf(stderr, "Esto en un ifndef\n");
+}
+
+void
+endif(char *str)
+{+ fprintf(stderr, "Esto en un endif\n");
+}
+
static int
readline(void)
{@@ -105,8 +213,12 @@
char *bp, *ptr;
uint8_t n;
int c;
- FILE *fp = input->fp;
+ FILE *fp;
+repeat:
+ if (!input)
+ return EOF;
+ fp = input->fp;
if (!input->line)
input->line = xmalloc(INPUTSIZ);
ptr = input->line;
@@ -115,8 +227,10 @@
if (c == '\n')
newline();
}
- if (c == EOF)
- return EOF;
+ if (c == EOF) {+ delinput();
+ goto repeat;
+ }
ungetc(c, fp);
for (bp = ptr; (c = getc(fp)) != EOF && c != '\n'; ) {@@ -134,12 +248,22 @@
*bp = ' ';
input->cnt = bp - ptr;
input->ptr = ptr;
- return *input->ptr++;
+
+ if ((c = *input->ptr++) == '#') {+ *bp = '\0';
+ preprocessor();
+ goto repeat;
+ }
+ return c;
}
static int
backchar(int c)
{+ if (!input) {+ assert(c == EOF);
+ return c;
+ }
++input->cnt;
return *--input->ptr = c;
}
--- a/cc1/main.c
+++ b/cc1/main.c
@@ -67,12 +67,10 @@
ikeywords();
- addinput(*argv);
- while (yytoken != EOFTOK)
- extdecl();
- delinput();
+ if (!addinput(*argv))
+ die("error opening input file '%s'", *argv);+ for (next(); yytoken != EOFTOK; extdecl())
+ /* nothing */;
- if (fclose(stdout))
- die("error writing in output:%s", strerror(errno));return 0;
}
--- a/cc1/symbol.c
+++ b/cc1/symbol.c
@@ -107,10 +107,13 @@
void
ikeywords(void)
{- static struct {+ extern void include(char *), define(char *), undef(char *);
+ extern void ifdef(char *), ifndef(char *), endif(char *);
+ static struct words {char *str;
uint8_t token, value;
- } *bp, buff[] = {+ void (*fun)(char *);
+ } ccwords[] = { {"auto", SCLASS, AUTO}, {"break", BREAK, BREAK}, {"_Bool", TYPE, BOOL},@@ -146,13 +149,36 @@
{"volatile", TQUALIFIER, VOLATILE}, {"while", WHILE, WHILE}, {NULL, 0, 0},+ }, cppwords[] = {+ {"include", 0, 0, include},+ {"define", 0, 0, define},+ {"undef", 0, 0, undef},+ {"ifdef", 0, 0, ifdef},+ {"ifndef", 0, 0, ifndef},+ {"endif", 0, 0, endif},+ {NULL, 0, 0}};
+ static struct wordlist {+ struct words *words;
+ uint8_t ns;
+ } wordlist [] = {+ {ccwords, NS_IDEN},+ {cppwords, NS_CPP},+ {NULL, 0}+ };
+ struct wordlist *lp;
+ struct words *bp;
Symbol *sym;
- for (bp = buff; bp->str; ++bp) {- sym = install(bp->str, NS_IDEN);
- sym->token = bp->token;
- sym->u.token = bp->value;
+ for (lp = wordlist; lp->words; ++lp) {+ for (bp = lp->words; bp->str; ++bp) {+ sym = install(bp->str, lp->ns);
+ sym->token = bp->token;
+ if (bp->fun)
+ sym->u.fun = bp->fun;
+ else
+ sym->u.token = bp->value;
+ }
}
globalcnt = 0;
}
--
⑨