aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc.h1
-rwxr-xr-xconfigure2
-rw-r--r--pp.c23
-rw-r--r--scan.c6
4 files changed, 28 insertions, 4 deletions
diff --git a/cc.h b/cc.h
index a996541..3b33e8c 100644
--- a/cc.h
+++ b/cc.h
@@ -383,6 +383,7 @@ _Noreturn void error(const struct location *, const char *, ...);
void scanfrom(const char *, FILE *);
void scanopen(void);
+void scansetloc(struct location loc);
void scan(struct token *);
/* preprocessor */
diff --git a/configure b/configure
index 1d8a0f2..7b8555d 100755
--- a/configure
+++ b/configure
@@ -139,7 +139,7 @@ static const char target[] = "$target";
static const char *const startfiles[] = {$startfiles};
static const char *const endfiles[] = {$endfiles};
static const char *const preprocesscmd[] = {
- "$DEFAULT_PREPROCESSOR", "-P",
+ "$DEFAULT_PREPROCESSOR", "-E",
/* clear preprocessor GNU C version */
"-U", "__GNUC__",
diff --git a/pp.c b/pp.c
index 9f0c74d..96f76fc 100644
--- a/pp.c
+++ b/pp.c
@@ -302,15 +302,18 @@ undef(void)
static void
directive(void)
{
+ struct location newloc;
enum ppflags oldflags;
- char *name;
+ char *name = NULL;
scan(&tok);
if (tok.kind == TNEWLINE)
return; /* empty directive */
oldflags = ppflags;
ppflags |= PPNEWLINE;
- name = tokencheck(&tok, TIDENT, "or newline after '#'");
+ if (tok.kind == TNUMBER)
+ goto line; /* gcc line markers */
+ name = tokencheck(&tok, TIDENT, "newline, or number after '#'");
if (strcmp(name, "if") == 0) {
error(&tok.loc, "#if directive is not implemented");
} else if (strcmp(name, "ifdef") == 0) {
@@ -330,7 +333,21 @@ directive(void)
scan(&tok);
undef();
} else if (strcmp(name, "line") == 0) {
- error(&tok.loc, "#line directive is not implemented");
+ scan(&tok);
+ tokencheck(&tok, TNUMBER, "after #line");
+line:
+ newloc.line = strtoull(tok.lit, NULL, 0);
+ scan(&tok);
+ newloc.file = tok.loc.file;
+ if (tok.kind == TSTRINGLIT) {
+ /* XXX: handle escape sequences (reuse string decoding from expr.c) */
+ newloc.file = strchr(tok.lit, '"') + 1;
+ *strchr(newloc.file, '"') = '\0';
+ scan(&tok);
+ }
+ while (tok.kind == TNUMBER)
+ scan(&tok);
+ scansetloc(newloc);
} else if (strcmp(name, "error") == 0) {
error(&tok.loc, "#error directive is not implemented");
} else if (strcmp(name, "pragma") == 0) {
diff --git a/scan.c b/scan.c
index 34e003e..a8327bf 100644
--- a/scan.c
+++ b/scan.c
@@ -444,6 +444,12 @@ scanopen(void)
}
}
+void
+scansetloc(struct location loc)
+{
+ scanner->loc = loc;
+}
+
static void
scanclose(void)
{