summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2007-09-26 12:46:48 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2007-09-26 12:46:48 +0000
commitc2e7adb3138cecc3609264f8359027157781e848 (patch)
tree20394828e292b40fa0f9f960f3305d21f6b94897
parent83ed08edb5781d6838fcf808045fccb2880e3871 (diff)
pull from ragge's repo:
Handle #pragma and _Pragma() correct.
-rw-r--r--usr.bin/pcc/cc/cpp/cpp.c53
-rw-r--r--usr.bin/pcc/cc/cpp/scanner.l12
2 files changed, 61 insertions, 4 deletions
diff --git a/usr.bin/pcc/cc/cpp/cpp.c b/usr.bin/pcc/cc/cpp/cpp.c
index 1f201d981eb..8c05e3eb502 100644
--- a/usr.bin/pcc/cc/cpp/cpp.c
+++ b/usr.bin/pcc/cc/cpp/cpp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpp.c,v 1.9 2007/09/24 16:04:01 otto Exp $ */
+/* $OpenBSD: cpp.c,v 1.10 2007/09/26 12:46:47 otto Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
@@ -126,6 +126,7 @@ struct incs {
static struct symtab *filloc;
static struct symtab *linloc;
+static struct symtab *pragloc;
int trulvl;
int flslvl;
int elflvl;
@@ -242,7 +243,9 @@ main(int argc, char **argv)
filloc = lookup((usch *)"__FILE__", ENTER);
linloc = lookup((usch *)"__LINE__", ENTER);
+ pragloc = lookup((usch *)"_Pragma", ENTER);
filloc->value = linloc->value = (usch *)""; /* Just something */
+ pragloc->value = (usch *)"";
if (tflag == 0) {
time_t t = time(NULL);
@@ -759,6 +762,51 @@ savch(c)
}
/*
+ * convert _Pragma to #pragma for output.
+ */
+static void
+pragoper(void)
+{
+ usch *opb;
+ int t;
+
+ slow = 1;
+ putstr((usch *)"\n#pragma ");
+ if ((t = yylex()) == WSPACE)
+ t = yylex();
+ if (t != '(')
+ goto bad;
+ if ((t = yylex()) == WSPACE)
+ t = yylex();
+ opb = stringbuf;
+ while (t != ')') {
+ savstr((usch *)yytext);
+ t = yylex();
+ }
+ savch(0);
+ cunput(WARN);
+ unpstr(opb);
+ stringbuf = opb;
+ expmac(NULL);
+ while (stringbuf > opb)
+ cunput(*--stringbuf);
+ if ((t = yylex()) != STRING)
+ goto bad;
+ opb = (usch *)yytext;
+ if (*opb++ == 'L')
+ opb++;
+ while ((t = *opb++) != '\"') {
+ if (t == '\\' && (*opb == '\"' || *opb == '\\'))
+ t = *opb++;
+ putch(t);
+ }
+ putch('\n');
+ prtline();
+ return;
+bad: error("bad pragma operator");
+}
+
+/*
* substitute namep for sp->value.
*/
int
@@ -780,6 +828,9 @@ struct recur *rp;
} else if (sp == linloc) {
(void)sheap("%d", ifiles->lineno);
return 1;
+ } else if (sp == pragloc) {
+ pragoper();
+ return 1;
}
vp = sp->value;
diff --git a/usr.bin/pcc/cc/cpp/scanner.l b/usr.bin/pcc/cc/cpp/scanner.l
index 606c0aa037b..f8c62193003 100644
--- a/usr.bin/pcc/cc/cpp/scanner.l
+++ b/usr.bin/pcc/cc/cpp/scanner.l
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: scanner.l,v 1.6 2007/09/21 08:15:36 gilles Exp $ */
+/* $OpenBSD: scanner.l,v 1.7 2007/09/26 12:46:47 otto Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson. All rights reserved.
@@ -799,10 +799,16 @@ undefstmt(void)
static void
pragmastmt(void)
{
+ int c;
+
slow = 1;
if (yylex() != WSPACE)
error("bad pragma");
- while (yylex() != '\n') /* no pragma support */
- ;
+ putstr((usch *)"#pragma ");
+ do {
+ putch(c = input()); /* Do arg expansion instead? */
+ } while (c && c != '\n');
+ ifiles->lineno++;
+ prtline();
slow = 0;
}