aboutsummaryrefslogtreecommitdiff
path: root/util/romcc
diff options
context:
space:
mode:
Diffstat (limited to 'util/romcc')
-rw-r--r--util/romcc/romcc.c1416
1 files changed, 773 insertions, 643 deletions
diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c
index 4b65357cb8..69121e2b83 100644
--- a/util/romcc/romcc.c
+++ b/util/romcc/romcc.c
@@ -3,8 +3,8 @@
#undef RELEASE_DATE
#undef VERSION
#define VERSION_MAJOR "0"
-#define VERSION_MINOR "67"
-#define RELEASE_DATE "9 November 2004"
+#define VERSION_MINOR "68"
+#define RELEASE_DATE "15 November 2004"
#define VERSION VERSION_MAJOR "." VERSION_MINOR
#include <stdarg.h>
@@ -328,7 +328,7 @@ struct file_state {
struct file_state *prev;
const char *basename;
char *dirname;
- char *buf;
+ const char *buf;
off_t size;
const char *pos;
int line;
@@ -336,12 +336,15 @@ struct file_state {
int report_line;
const char *report_name;
const char *report_dir;
- int macro : 1;
+ int macro : 1;
+ int trigraphs : 1;
+ int join_lines : 1;
};
struct hash_entry;
struct token {
int tok;
struct hash_entry *ident;
+ const char *pos;
int str_len;
union {
ulong_t integer;
@@ -1003,9 +1006,8 @@ struct macro_arg {
};
struct macro {
struct hash_entry *ident;
- char *buf;
+ const char *buf;
int buf_len;
- int buf_off;
struct macro_arg *args;
int argc;
};
@@ -1048,7 +1050,7 @@ struct basic_blocks {
struct block *first_block, *last_block;
int last_vertex;
};
-#define MAX_CPP_IF_DEPTH 63
+#define MAX_PP_IF_DEPTH 63
struct compile_state {
struct compiler_state *compiler;
struct arch_state *arch;
@@ -1078,10 +1080,9 @@ struct compile_state {
struct hash_entry *i_noinline;
struct hash_entry *i_always_inline;
int scope_depth;
- unsigned char if_bytes[(MAX_CPP_IF_DEPTH + CHAR_BIT -1)/CHAR_BIT];
+ unsigned char if_bytes[(MAX_PP_IF_DEPTH + CHAR_BIT -1)/CHAR_BIT];
int if_depth;
int eat_depth, eat_targ;
- int macro_line;
struct file_state *macro_file;
struct triple *functions;
struct triple *main_function;
@@ -1376,9 +1377,11 @@ static struct triple *flatten(
#define COMPILER_SIMPLIFY_LOGICAL 0x00004000
#define COMPILER_SIMPLIFY_BITFIELD 0x00008000
-#define COMPILER_CPP_ONLY 0x80000000
+#define COMPILER_TRIGRAPHS 0x40000000
+#define COMPILER_PP_ONLY 0x80000000
#define COMPILER_DEFAULT_FLAGS ( \
+ COMPILER_TRIGRAPHS | \
COMPILER_ELIMINATE_INEFECTUAL_CODE | \
COMPILER_INLINE_DEFAULTON | \
COMPILER_SIMPLIFY_OP | \
@@ -1558,7 +1561,8 @@ static int append_undef(struct compiler_state *compiler, const char *str)
}
static const struct compiler_flag romcc_flags[] = {
- { "cpp-only", COMPILER_CPP_ONLY },
+ { "trigraphs", COMPILER_TRIGRAPHS },
+ { "pp-only", COMPILER_PP_ONLY },
{ "eliminate-inefectual-code", COMPILER_ELIMINATE_INEFECTUAL_CODE },
{ "simplify", COMPILER_SIMPLIFY },
{ "scc-transform", COMPILER_SCC_TRANSFORM },
@@ -1590,7 +1594,7 @@ static const struct compiler_arg romcc_args[] = {
static const struct compiler_flag romcc_opt_flags[] = {
{ "-O", COMPILER_SIMPLIFY },
{ "-O2", COMPILER_SIMPLIFY | COMPILER_SCC_TRANSFORM },
- { "-E", COMPILER_CPP_ONLY },
+ { "-E", COMPILER_PP_ONLY },
{ 0, 0, },
};
static const struct compiler_flag romcc_debug_flags[] = {
@@ -1863,66 +1867,6 @@ static void valid_param_count(struct compile_state *state, struct triple *ins)
}
}
-static void process_trigraphs(struct compile_state *state)
-{
- char *src, *dest, *end;
- struct file_state *file;
- file = state->file;
- src = dest = file->buf;
- end = file->buf + file->size;
- while((end - src) >= 3) {
- if ((src[0] == '?') && (src[1] == '?')) {
- int c = -1;
- switch(src[2]) {
- case '=': c = '#'; break;
- case '/': c = '\\'; break;
- case '\'': c = '^'; break;
- case '(': c = '['; break;
- case ')': c = ']'; break;
- case '!': c = '!'; break;
- case '<': c = '{'; break;
- case '>': c = '}'; break;
- case '-': c = '~'; break;
- }
- if (c != -1) {
- *dest++ = c;
- src += 3;
- }
- else {
- *dest++ = *src++;
- }
- }
- else {
- *dest++ = *src++;
- }
- }
- while(src != end) {
- *dest++ = *src++;
- }
- file->size = dest - file->buf;
-}
-
-static void splice_lines(struct compile_state *state)
-{
- char *src, *dest, *end;
- struct file_state *file;
- file = state->file;
- src = dest = file->buf;
- end = file->buf + file->size;
- while((end - src) >= 2) {
- if ((src[0] == '\\') && (src[1] == '\n')) {
- src += 2;
- }
- else {
- *dest++ = *src++;
- }
- }
- while(src != end) {
- *dest++ = *src++;
- }
- file->size = dest - file->buf;
-}
-
static struct type void_type;
static struct type unknown_type;
static void use_triple(struct triple *used, struct triple *user)
@@ -3087,128 +3031,128 @@ static void release_triple(struct compile_state *state, struct triple *ptr)
static void print_triples(struct compile_state *state);
static void print_blocks(struct compile_state *state, const char *func, FILE *fp);
-#define TOK_UNKNOWN 0
-#define TOK_SPACE 1
-#define TOK_SEMI 2
-#define TOK_LBRACE 3
-#define TOK_RBRACE 4
-#define TOK_COMMA 5
-#define TOK_EQ 6
-#define TOK_COLON 7
-#define TOK_LBRACKET 8
-#define TOK_RBRACKET 9
-#define TOK_LPAREN 10
-#define TOK_RPAREN 11
-#define TOK_STAR 12
-#define TOK_DOTS 13
-#define TOK_MORE 14
-#define TOK_LESS 15
-#define TOK_TIMESEQ 16
-#define TOK_DIVEQ 17
-#define TOK_MODEQ 18
-#define TOK_PLUSEQ 19
-#define TOK_MINUSEQ 20
-#define TOK_SLEQ 21
-#define TOK_SREQ 22
-#define TOK_ANDEQ 23
-#define TOK_XOREQ 24
-#define TOK_OREQ 25
-#define TOK_EQEQ 26
-#define TOK_NOTEQ 27
-#define TOK_QUEST 28
-#define TOK_LOGOR 29
-#define TOK_LOGAND 30
-#define TOK_OR 31
-#define TOK_AND 32
-#define TOK_XOR 33
-#define TOK_LESSEQ 34
-#define TOK_MOREEQ 35
-#define TOK_SL 36
-#define TOK_SR 37
-#define TOK_PLUS 38
-#define TOK_MINUS 39
-#define TOK_DIV 40
-#define TOK_MOD 41
-#define TOK_PLUSPLUS 42
-#define TOK_MINUSMINUS 43
-#define TOK_BANG 44
-#define TOK_ARROW 45
-#define TOK_DOT 46
-#define TOK_TILDE 47
-#define TOK_LIT_STRING 48
-#define TOK_LIT_CHAR 49
-#define TOK_LIT_INT 50
-#define TOK_LIT_FLOAT 51
-#define TOK_MACRO 52
-#define TOK_CONCATENATE 53
-
-#define TOK_IDENT 54
-#define TOK_STRUCT_NAME 55
-#define TOK_ENUM_CONST 56
-#define TOK_TYPE_NAME 57
-
-#define TOK_AUTO 58
-#define TOK_BREAK 59
-#define TOK_CASE 60
-#define TOK_CHAR 61
-#define TOK_CONST 62
-#define TOK_CONTINUE 63
-#define TOK_DEFAULT 64
-#define TOK_DO 65
-#define TOK_DOUBLE 66
-#define TOK_ELSE 67
-#define TOK_ENUM 68
-#define TOK_EXTERN 69
-#define TOK_FLOAT 70
-#define TOK_FOR 71
-#define TOK_GOTO 72
-#define TOK_IF 73
-#define TOK_INLINE 74
-#define TOK_INT 75
-#define TOK_LONG 76
-#define TOK_REGISTER 77
-#define TOK_RESTRICT 78
-#define TOK_RETURN 79
-#define TOK_SHORT 80
-#define TOK_SIGNED 81
-#define TOK_SIZEOF 82
-#define TOK_STATIC 83
-#define TOK_STRUCT 84
-#define TOK_SWITCH 85
-#define TOK_TYPEDEF 86
-#define TOK_UNION 87
-#define TOK_UNSIGNED 88
-#define TOK_VOID 89
-#define TOK_VOLATILE 90
-#define TOK_WHILE 91
-#define TOK_ASM 92
-#define TOK_ATTRIBUTE 93
-#define TOK_ALIGNOF 94
+#define TOK_UNKNOWN 0
+#define TOK_SPACE 1
+#define TOK_SEMI 2
+#define TOK_LBRACE 3
+#define TOK_RBRACE 4
+#define TOK_COMMA 5
+#define TOK_EQ 6
+#define TOK_COLON 7
+#define TOK_LBRACKET 8
+#define TOK_RBRACKET 9
+#define TOK_LPAREN 10
+#define TOK_RPAREN 11
+#define TOK_STAR 12
+#define TOK_DOTS 13
+#define TOK_MORE 14
+#define TOK_LESS 15
+#define TOK_TIMESEQ 16
+#define TOK_DIVEQ 17
+#define TOK_MODEQ 18
+#define TOK_PLUSEQ 19
+#define TOK_MINUSEQ 20
+#define TOK_SLEQ 21
+#define TOK_SREQ 22
+#define TOK_ANDEQ 23
+#define TOK_XOREQ 24
+#define TOK_OREQ 25
+#define TOK_EQEQ 26
+#define TOK_NOTEQ 27
+#define TOK_QUEST 28
+#define TOK_LOGOR 29
+#define TOK_LOGAND 30
+#define TOK_OR 31
+#define TOK_AND 32
+#define TOK_XOR 33
+#define TOK_LESSEQ 34
+#define TOK_MOREEQ 35
+#define TOK_SL 36
+#define TOK_SR 37
+#define TOK_PLUS 38
+#define TOK_MINUS 39
+#define TOK_DIV 40
+#define TOK_MOD 41
+#define TOK_PLUSPLUS 42
+#define TOK_MINUSMINUS 43
+#define TOK_BANG 44
+#define TOK_ARROW 45
+#define TOK_DOT 46
+#define TOK_TILDE 47
+#define TOK_LIT_STRING 48
+#define TOK_LIT_CHAR 49
+#define TOK_LIT_INT 50
+#define TOK_LIT_FLOAT 51
+#define TOK_MACRO 52
+#define TOK_CONCATENATE 53
+
+#define TOK_IDENT 54
+#define TOK_STRUCT_NAME 55
+#define TOK_ENUM_CONST 56
+#define TOK_TYPE_NAME 57
+
+#define TOK_AUTO 58
+#define TOK_BREAK 59
+#define TOK_CASE 60
+#define TOK_CHAR 61
+#define TOK_CONST 62
+#define TOK_CONTINUE 63
+#define TOK_DEFAULT 64
+#define TOK_DO 65
+#define TOK_DOUBLE 66
+#define TOK_ELSE 67
+#define TOK_ENUM 68
+#define TOK_EXTERN 69
+#define TOK_FLOAT 70
+#define TOK_FOR 71
+#define TOK_GOTO 72
+#define TOK_IF 73
+#define TOK_INLINE 74
+#define TOK_INT 75
+#define TOK_LONG 76
+#define TOK_REGISTER 77
+#define TOK_RESTRICT 78
+#define TOK_RETURN 79
+#define TOK_SHORT 80
+#define TOK_SIGNED 81
+#define TOK_SIZEOF 82
+#define TOK_STATIC 83
+#define TOK_STRUCT 84
+#define TOK_SWITCH 85
+#define TOK_TYPEDEF 86
+#define TOK_UNION 87
+#define TOK_UNSIGNED 88
+#define TOK_VOID 89
+#define TOK_VOLATILE 90
+#define TOK_WHILE 91
+#define TOK_ASM 92
+#define TOK_ATTRIBUTE 93
+#define TOK_ALIGNOF 94
#define TOK_FIRST_KEYWORD TOK_AUTO
#define TOK_LAST_KEYWORD TOK_ALIGNOF
-#define TOK_MDEFINE 100
-#define TOK_MDEFINED 101
-#define TOK_MUNDEF 102
-#define TOK_MINCLUDE 103
-#define TOK_MLINE 104
-#define TOK_MERROR 105
-#define TOK_MWARNING 106
-#define TOK_MPRAGMA 107
-#define TOK_MIFDEF 108
-#define TOK_MIFNDEF 109
-#define TOK_MELIF 110
-#define TOK_MENDIF 111
-
-#define TOK_FIRST_MACRO TOK_MDEFINE
-#define TOK_LAST_MACRO TOK_MENDIF
+#define TOK_MDEFINE 100
+#define TOK_MDEFINED 101
+#define TOK_MUNDEF 102
+#define TOK_MINCLUDE 103
+#define TOK_MLINE 104
+#define TOK_MERROR 105
+#define TOK_MWARNING 106
+#define TOK_MPRAGMA 107
+#define TOK_MIFDEF 108
+#define TOK_MIFNDEF 109
+#define TOK_MELIF 110
+#define TOK_MENDIF 111
+
+#define TOK_FIRST_MACRO TOK_MDEFINE
+#define TOK_LAST_MACRO TOK_MENDIF
-#define TOK_MIF 112
-#define TOK_MELSE 113
-#define TOK_MIDENT 114
+#define TOK_MIF 112
+#define TOK_MELSE 113
+#define TOK_MIDENT 114
-#define TOK_EOL 115
-#define TOK_EOF 116
+#define TOK_EOL 115
+#define TOK_EOF 116
static const char *tokens[] = {
[TOK_UNKNOWN ] = ":unknown:",
@@ -3575,47 +3519,64 @@ static void undef_macro(struct compile_state *state, struct hash_entry *ident)
}
}
-static void define_macro(
- struct compile_state *state,
- struct hash_entry *ident,
- const char *value, int value_len, int value_off,
- struct macro_arg *args)
+static void do_define_macro(struct compile_state *state,
+ struct hash_entry *ident, const char *body,
+ int argc, struct macro_arg *args)
{
struct macro *macro;
struct macro_arg *arg;
+ size_t body_len;
+
+ /* Find the length of the body */
+ body_len = strlen(body);
macro = ident->sym_define;
if (macro != 0) {
- /* Explicitly allow identical redefinitions of the same macro */
- if ((macro->buf_len == value_len) &&
- (memcmp(macro->buf, value, value_len) == 0)) {
+ int identical_bodies, identical_args;
+ struct macro_arg *oarg;
+ /* Explicitly allow identical redfinitions of the same macro */
+ identical_bodies =
+ (macro->buf_len == body_len) &&
+ (memcmp(macro->buf, body, body_len) == 0);
+ identical_args = macro->argc == argc;
+ oarg = macro->args;
+ arg = args;
+ while(identical_args && arg) {
+ identical_args = oarg->ident == arg->ident;
+ arg = arg->next;
+ oarg = oarg->next;
+ }
+ if (identical_bodies && identical_args) {
+ xfree(body);
return;
}
error(state, 0, "macro %s already defined\n", ident->name);
}
#if 0
- fprintf(state->errout, "%s: `%*.*s'\n",
- ident->name,
- value_len - value_off,
- value_len - value_off,
- value + value_off);
+ fprintf(state->errout, "#define %s: `%*.*s'\n",
+ ident->name, body_len, body_len, body);
#endif
macro = xmalloc(sizeof(*macro), "macro");
- macro->ident = ident;
- macro->buf_len = value_len;
- macro->buf_off = value_off;
+ macro->ident = ident;
+ macro->buf = body;
+ macro->buf_len = body_len;
macro->args = args;
- macro->buf = xmalloc(macro->buf_len + 1, "macro buf");
-
- macro->argc = 0;
- for(arg = args; arg; arg = arg->next) {
- macro->argc += 1;
- }
-
- memcpy(macro->buf, value, macro->buf_len);
- macro->buf[macro->buf_len] = '\0';
+ macro->argc = argc;
ident->sym_define = macro;
}
+
+static void define_macro(
+ struct compile_state *state,
+ struct hash_entry *ident,
+ const char *body, int body_len,
+ int argc, struct macro_arg *args)
+{
+ char *buf;
+ buf = xmalloc(body_len + 1, "macro buf");
+ memcpy(buf, body, body_len);
+ buf[body_len] = '\0';
+ do_define_macro(state, ident, buf, argc, args);
+}
static void register_builtin_macro(struct compile_state *state,
const char *name, const char *value)
@@ -3626,7 +3587,7 @@ static void register_builtin_macro(struct compile_state *state,
internal_error(state, 0, "Builtin macros with arguments not supported");
}
ident = lookup(state, name, strlen(name));
- define_macro(state, ident, value, strlen(value), 0, 0);
+ define_macro(state, ident, value, strlen(value), -1, 0);
}
static void register_builtin_macros(struct compile_state *state)
@@ -3675,7 +3636,7 @@ static void process_cmdline_macros(struct compile_state *state)
body++;
}
ident = lookup(state, name, name_len);
- define_macro(state, ident, body, strlen(body), 0, 0);
+ define_macro(state, ident, body, strlen(body), -1, 0);
}
for(macro = state->compiler->undefs; (name = *macro); macro++) {
ident = lookup(state, name, strlen(name));
@@ -3698,17 +3659,6 @@ static int spacep(int c)
return ret;
}
-static int eolp(int c)
-{
- int ret = 0;
- switch(c) {
- case '\n':
- ret = 1;
- break;
- }
- return ret;
-}
-
static int digitp(int c)
{
int ret = 0;
@@ -3861,56 +3811,182 @@ static int char_value(struct compile_state *state,
return c;
}
-static const char *after_digits(const char *ptr, const char *end)
+static const char *next_char(struct file_state *file, const char *pos, int index)
{
- while((ptr < end) && digitp(*ptr)) {
- ptr++;
+ const char *end = file->buf + file->size;
+ while(pos < end) {
+ /* Lookup the character */
+ int size = 1;
+ int c = *pos;
+ /* Is this a trigraph? */
+ if (file->trigraphs &&
+ (c == '?') && ((end - pos) >= 3) && (pos[1] == '?'))
+ {
+ switch(pos[2]) {
+ case '=': c = '#'; break;
+ case '/': c = '\\'; break;
+ case '\'': c = '^'; break;
+ case '(': c = '['; break;
+ case ')': c = ']'; break;
+ case '!': c = '!'; break;
+ case '<': c = '{'; break;
+ case '>': c = '}'; break;
+ case '-': c = '~'; break;
+ }
+ if (c != '?') {
+ size = 3;
+ }
+ }
+ /* Is this an escaped newline? */
+ if (file->join_lines &&
+ (c == '\\') && (pos + size < end) && (pos[1] == '\n'))
+ {
+ /* At the start of a line just eat it */
+ if (pos == file->pos) {
+ file->line++;
+ file->report_line++;
+ file->line_start = pos + size + 1;
+ }
+ pos += size + 1;
+ }
+ /* Do I need to ga any farther? */
+ else if (index == 0) {
+ break;
+ }
+ /* Process a normal character */
+ else {
+ pos += size;
+ index -= 1;
+ }
+ }
+ return pos;
+}
+
+static int get_char(struct file_state *file, const char *pos)
+{
+ const char *end = file->buf + file->size;
+ int c;
+ c = -1;
+ pos = next_char(file, pos, 0);
+ if (pos < end) {
+ /* Lookup the character */
+ c = *pos;
+ /* If it is a trigraph get the trigraph value */
+ if (file->trigraphs &&
+ (c == '?') && ((end - pos) >= 3) && (pos[1] == '?'))
+ {
+ switch(pos[2]) {
+ case '=': c = '#'; break;
+ case '/': c = '\\'; break;
+ case '\'': c = '^'; break;
+ case '(': c = '['; break;
+ case ')': c = ']'; break;
+ case '!': c = '!'; break;
+ case '<': c = '{'; break;
+ case '>': c = '}'; break;
+ case '-': c = '~'; break;
+ }
+ }
+ }
+ return c;
+}
+
+static void eat_chars(struct file_state *file, const char *targ)
+{
+ const char *pos = file->pos;
+ while(pos < targ) {
+ /* Do we have a newline? */
+ if (pos[0] == '\n') {
+ file->line++;
+ file->report_line++;
+ file->line_start = pos + 1;
+ }
+ pos++;
+ }
+ file->pos = pos;
+}
+
+
+static size_t char_strlen(struct file_state *file, const char *src, const char *end)
+{
+ size_t len;
+ len = 0;
+ while(src < end) {
+ src = next_char(file, src, 1);
+ len++;
+ }
+ return len;
+}
+
+static void char_strcpy(char *dest,
+ struct file_state *file, const char *src, const char *end)
+{
+ while(src < end) {
+ int c;
+ c = get_char(file, src);
+ src = next_char(file, src, 1);
+ *dest++ = c;
+ }
+}
+
+static char *char_strdup(struct file_state *file,
+ const char *start, const char *end, const char *id)
+{
+ char *str;
+ size_t str_len;
+ str_len = char_strlen(file, start, end);
+ str = xcmalloc(str_len + 1, id);
+ char_strcpy(str, file, start, end);
+ str[str_len] = '\0';
+ return str;
+}
+
+static const char *after_digits(struct file_state *file, const char *ptr)
+{
+ while(digitp(get_char(file, ptr))) {
+ ptr = next_char(file, ptr, 1);
}
return ptr;
}
-static const char *after_octdigits(const char *ptr, const char *end)
+static const char *after_octdigits(struct file_state *file, const char *ptr)
{
- while((ptr < end) && octdigitp(*ptr)) {
- ptr++;
+ while(octdigitp(get_char(file, ptr))) {
+ ptr = next_char(file, ptr, 1);
}
return ptr;
}
-static const char *after_hexdigits(const char *ptr, const char *end)
+static const char *after_hexdigits(struct file_state *file, const char *ptr)
{
- while((ptr < end) && hexdigitp(*ptr)) {
- ptr++;
+ while(hexdigitp(get_char(file, ptr))) {
+ ptr = next_char(file, ptr, 1);
+ }
+ return ptr;
+}
+
+static const char *after_alnums(struct file_state *file, const char *ptr)
+{
+ int c;
+ c = get_char(file, ptr);
+ while(letterp(c) || digitp(c)) {
+ ptr = next_char(file, ptr, 1);
+ c = get_char(file, ptr);
}
return ptr;
}
-static void save_string(struct compile_state *state,
+static void save_string(struct file_state *file,
struct token *tk, const char *start, const char *end, const char *id)
{
char *str;
- int str_len;
+
/* Create a private copy of the string */
- str_len = end - start + 1;
- str = xmalloc(str_len + 1, id);
- memcpy(str, start, str_len);
- str[str_len] = '\0';
+ str = char_strdup(file, start, end, id);
/* Store the copy in the token */
tk->val.str = str;
- tk->str_len = str_len;
-}
-
-static int lparen_peek(struct compile_state *state, struct file_state *file)
-{
- const char *tokp, *end;
- /* Is the next token going to be an lparen?
- * Whitespace tokens are significant for seeing if a macro
- * should be expanded.
- */
- tokp = file->pos;
- end = file->buf + file->size;
- return (tokp < end) && (*tokp == '(');
+ tk->str_len = strlen(str);
}
static void raw_next_token(struct compile_state *state,
@@ -3918,108 +3994,76 @@ static void raw_next_token(struct compile_state *state,
{
const char *token;
int c, c1, c2, c3;
- const char *tokp, *end;
+ const char *tokp;
+ int eat;
int tok;
tk->str_len = 0;
tk->ident = 0;
- token = tokp = file->pos;
- end = file->buf + file->size;
+ token = tokp = next_char(file, file->pos, 0);
tok = TOK_UNKNOWN;
- c = -1;
- if (tokp < end) {
- c = *tokp;
- }
- c1 = -1;
- if ((tokp + 1) < end) {
- c1 = tokp[1];
- }
- c2 = -1;
- if ((tokp + 2) < end) {
- c2 = tokp[2];
- }
- c3 = -1;
- if ((tokp + 3) < end) {
- c3 = tokp[3];
- }
- if (tokp >= end) {
+ c = get_char(file, tokp);
+ tokp = next_char(file, tokp, 1);
+ eat = 0;
+ c1 = get_char(file, tokp);
+ c2 = get_char(file, next_char(file, tokp, 1));
+ c3 = get_char(file, next_char(file, tokp, 2));
+
+ /* The end of the file */
+ if (c == -1) {
tok = TOK_EOF;
- tokp = end;
- }
- /* End of Line */
- else if (eolp(c)) {
- tok = TOK_EOL;
- file->line++;
- file->report_line++;
- file->line_start = tokp + 1;
}
/* Whitespace */
else if (spacep(c)) {
tok = TOK_SPACE;
- while ((tokp < end) && spacep(c)) {
- c = *(++tokp);
- }
- if (!spacep(c)) {
- tokp--;
+ while (spacep(get_char(file, tokp))) {
+ tokp = next_char(file, tokp, 1);
}
}
/* EOL Comments */
else if ((c == '/') && (c1 == '/')) {
tok = TOK_SPACE;
- for(tokp += 2; tokp < end; tokp++) {
- c = *tokp;
+ tokp = next_char(file, tokp, 1);
+ while((c = get_char(file, tokp)) != -1) {
+ tokp = next_char(file, tokp, 1);
if (c == '\n') {
- tokp--;
break;
}
}
}
/* Comments */
else if ((c == '/') && (c1 == '*')) {
- int line;
- const char *line_start;
- line = file->line;
- line_start = file->line_start;
- for(tokp += 2; (end - tokp) >= 2; tokp++) {
- c = *tokp;
- if (c == '\n') {
- line++;
- line_start = tokp +1;
- }
- else if ((c == '*') && (tokp[1] == '/')) {
+ tokp = next_char(file, tokp, 2);
+ c = c2;
+ while((c1 = get_char(file, tokp)) != -1) {
+ tokp = next_char(file, tokp, 1);
+ if ((c == '*') && (c1 == '/')) {
tok = TOK_SPACE;
- tokp += 1;
break;
}
+ c = c1;
}
if (tok == TOK_UNKNOWN) {
error(state, 0, "unterminated comment");
}
- file->report_line += line - file->line;
- file->line = line;
- file->line_start = line_start;
}
/* string constants */
- else if ((c == '"') ||
- ((c == 'L') && (c1 == '"'))) {
- int line;
- const char *line_start;
- int wchar;
- line = file->line;
- line_start = file->line_start;
+ else if ((c == '"') || ((c == 'L') && (c1 == '"'))) {
+ int wchar, multiline;
+
wchar = 0;
+ multiline = 0;
if (c == 'L') {
wchar = 1;
- tokp++;
+ tokp = next_char(file, tokp, 1);
}
- for(tokp += 1; tokp < end; tokp++) {
- c = *tokp;
+ while((c = get_char(file, tokp)) != -1) {
+ tokp = next_char(file, tokp, 1);
if (c == '\n') {
- line++;
- line_start = tokp + 1;
+ multiline = 1;
}
- else if ((c == '\\') && (tokp +1 < end)) {
- tokp++;
+ else if (c == '\\') {
+ tokp = next_char(file, tokp, 1);
}
else if (c == '"') {
tok = TOK_LIT_STRING;
@@ -4029,37 +4073,30 @@ static void raw_next_token(struct compile_state *state,
if (tok == TOK_UNKNOWN) {
error(state, 0, "unterminated string constant");
}
- if (line != file->line) {
+ if (multiline) {
warning(state, 0, "multiline string constant");
}
- file->report_line += line - file->line;
- file->line = line;
- file->line_start = line_start;
/* Save the string value */
- save_string(state, tk, token, tokp, "literal string");
+ save_string(file, tk, token, tokp, "literal string");
}
/* character constants */
- else if ((c == '\'') ||
- ((c == 'L') && (c1 == '\''))) {
- int line;
- const char *line_start;
- int wchar;
- line = file->line;
- line_start = file->line_start;
+ else if ((c == '\'') || ((c == 'L') && (c1 == '\''))) {
+ int wchar, multiline;
+
wchar = 0;
+ multiline = 0;
if (c == 'L') {
wchar = 1;
- tokp++;
+ tokp = next_char(file, tokp, 1);
}
- for(tokp += 1; tokp < end; tokp++) {
- c = *tokp;
+ while((c = get_char(file, tokp)) != -1) {
+ tokp = next_char(file, tokp, 1);
if (c == '\n') {
- line++;
- line_start = tokp + 1;
+ multiline = 1;
}
- else if ((c == '\\') && (tokp +1 < end)) {
- tokp++;
+ else if (c == '\\') {
+ tokp = next_char(file, tokp, 1);
}
else if (c == '\'') {
tok = TOK_LIT_CHAR;
@@ -4069,15 +4106,12 @@ static void raw_next_token(struct compile_state *state,
if (tok == TOK_UNKNOWN) {
error(state, 0, "unterminated character constant");
}
- if (line != file->line) {
+ if (multiline) {
warning(state, 0, "multiline character constant");
}
- file->report_line += line - file->line;
- file->line = line;
- file->line_start = line_start;
/* Save the character value */
- save_string(state, tk, token, tokp, "literal character");
+ save_string(file, tk, token, tokp, "literal character");
}
/* integer and floating constants
* Integer Constants
@@ -4092,122 +4126,140 @@ static void raw_next_token(struct compile_state *state,
* .{digits}[Ee][+-]?{digits}
* .{digits}
*/
-
else if (digitp(c) || ((c == '.') && (digitp(c1)))) {
- const char *next, *new;
+ const char *next;
int is_float;
+ int cn;
is_float = 0;
if (c != '.') {
- next = after_digits(tokp, end);
+ next = after_digits(file, tokp);
}
else {
- next = tokp;
- }
- if (next[0] == '.') {
- new = after_digits(next, end);
- is_float = (new != next);
- next = new;
- }
- if ((next[0] == 'e') || (next[0] == 'E')) {
- if (((next + 1) < end) &&
- ((next[1] == '+') || (next[1] == '-'))) {
- next++;
- }
- new = after_digits(next, end);
- is_float = (new != next);
+ next = token;
+ }
+ cn = get_char(file, next);
+ if (cn == '.') {
+ next = next_char(file, next, 1);
+ next = after_digits(file, next);
+ is_float = 1;
+ }
+ cn = get_char(file, next);
+ if ((cn == 'e') || (cn == 'E')) {
+ const char *new;
+ next = next_char(file, next, 1);
+ cn = get_char(file, next);
+ if ((cn == '+') || (cn == '-')) {
+ next = next_char(file, next, 1);
+ }
+ new = after_digits(file, next);
+ is_float |= (new != next);
next = new;
}
if (is_float) {
tok = TOK_LIT_FLOAT;
- if ((next < end) && (
- (next[0] == 'f') ||
- (next[0] == 'F') ||
- (next[0] == 'l') ||
- (next[0] == 'L'))
- ) {
- next++;
+ cn = get_char(file, next);
+ if ((cn == 'f') || (cn == 'F') || (cn == 'l') || (cn == 'L')) {
+ next = next_char(file, next, 1);
}
}
if (!is_float && digitp(c)) {
tok = TOK_LIT_INT;
if ((c == '0') && ((c1 == 'x') || (c1 == 'X'))) {
- next = after_hexdigits(tokp + 2, end);
+ next = next_char(file, tokp, 1);
+ next = after_hexdigits(file, next);
}
else if (c == '0') {
- next = after_octdigits(tokp, end);
+ next = after_octdigits(file, tokp);
}
else {
- next = after_digits(tokp, end);
+ next = after_digits(file, tokp);
}
/* crazy integer suffixes */
- if ((next < end) &&
- ((next[0] == 'u') || (next[0] == 'U'))) {
- next++;
- if ((next < end) &&
- ((next[0] == 'l') || (next[0] == 'L'))) {
- next++;
+ cn = get_char(file, next);
+ if ((cn == 'u') || (cn == 'U')) {
+ next = next_char(file, next, 1);
+ cn = get_char(file, next);
+ if ((cn == 'l') || (cn == 'L')) {
+ next = next_char(file, next, 1);
+ cn = get_char(file, next);
+ }
+ if ((cn == 'l') || (cn == 'L')) {
+ next = next_char(file, next, 1);
}
}
- else if ((next < end) &&
- ((next[0] == 'l') || (next[0] == 'L'))) {
- next++;
- if ((next < end) &&
- ((next[0] == 'u') || (next[0] == 'U'))) {
- next++;
+ else if ((cn == 'l') || (cn == 'L')) {
+ next = next_char(file, next, 1);
+ cn = get_char(file, next);
+ if ((cn == 'l') || (cn == 'L')) {
+ next = next_char(file, next, 1);
+ cn = get_char(file, next);
+ }
+ if ((cn == 'u') || (cn == 'U')) {
+ next = next_char(file, next, 1);
}
}
}
- tokp = next - 1;
+ tokp = next;
/* Save the integer/floating point value */
- save_string(state, tk, token, tokp, "literal number");
+ save_string(file, tk, token, tokp, "literal number");
}
/* identifiers */
else if (letterp(c)) {
tok = TOK_IDENT;
- tokp = identifier(tokp, end);
- tokp -= 1;
- tk->ident = lookup(state, token, tokp +1 - token);
+
+ /* Find and save the identifier string */
+ tokp = after_alnums(file, tokp);
+ save_string(file, tk, token, tokp, "identifier");
+
+ /* Look up to see which identifier it is */
+ tk->ident = lookup(state, tk->val.str, tk->str_len);
+
+ /* Free the identifier string */
+ tk->str_len = 0;
+ xfree(tk->val.str);
+
/* See if this identifier can be macro expanded */
tk->val.notmacro = 0;
- if ((tokp < end) && (tokp[1] == '$')) {
- tokp++;
+ c = get_char(file, tokp);
+ if (c == '$') {
+ tokp = next_char(file, tokp, 1);
tk->val.notmacro = 1;
}
}
/* C99 alternate macro characters */
else if ((c == '%') && (c1 == ':') && (c2 == '%') && (c3 == ':')) {
- tokp += 3;
+ eat += 3;
tok = TOK_CONCATENATE;
}
- else if ((c == '.') && (c1 == '.') && (c2 == '.')) { tokp += 2; tok = TOK_DOTS; }
- else if ((c == '<') && (c1 == '<') && (c2 == '=')) { tokp += 2; tok = TOK_SLEQ; }
- else if ((c == '>') && (c1 == '>') && (c2 == '=')) { tokp += 2; tok = TOK_SREQ; }
- else if ((c == '*') && (c1 == '=')) { tokp += 1; tok = TOK_TIMESEQ; }
- else if ((c == '/') && (c1 == '=')) { tokp += 1; tok = TOK_DIVEQ; }
- else if ((c == '%') && (c1 == '=')) { tokp += 1; tok = TOK_MODEQ; }
- else if ((c == '+') && (c1 == '=')) { tokp += 1; tok = TOK_PLUSEQ; }
- else if ((c == '-') && (c1 == '=')) { tokp += 1; tok = TOK_MINUSEQ; }
- else if ((c == '&') && (c1 == '=')) { tokp += 1; tok = TOK_ANDEQ; }
- else if ((c == '^') && (c1 == '=')) { tokp += 1; tok = TOK_XOREQ; }
- else if ((c == '|') && (c1 == '=')) { tokp += 1; tok = TOK_OREQ; }
- else if ((c == '=') && (c1 == '=')) { tokp += 1; tok = TOK_EQEQ; }
- else if ((c == '!') && (c1 == '=')) { tokp += 1; tok = TOK_NOTEQ; }
- else if ((c == '|') && (c1 == '|')) { tokp += 1; tok = TOK_LOGOR; }
- else if ((c == '&') && (c1 == '&')) { tokp += 1; tok = TOK_LOGAND; }
- else if ((c == '<') && (c1 == '=')) { tokp += 1; tok = TOK_LESSEQ; }
- else if ((c == '>') && (c1 == '=')) { tokp += 1; tok = TOK_MOREEQ; }
- else if ((c == '<') && (c1 == '<')) { tokp += 1; tok = TOK_SL; }
- else if ((c == '>') && (c1 == '>')) { tokp += 1; tok = TOK_SR; }
- else if ((c == '+') && (c1 == '+')) { tokp += 1; tok = TOK_PLUSPLUS; }
- else if ((c == '-') && (c1 == '-')) { tokp += 1; tok = TOK_MINUSMINUS; }
- else if ((c == '-') && (c1 == '>')) { tokp += 1; tok = TOK_ARROW; }
- else if ((c == '<') && (c1 == ':')) { tokp += 1; tok = TOK_LBRACKET; }
- else if ((c == ':') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACKET; }
- else if ((c == '<') && (c1 == '%')) { tokp += 1; tok = TOK_LBRACE; }
- else if ((c == '%') && (c1 == '>')) { tokp += 1; tok = TOK_RBRACE; }
- else if ((c == '%') && (c1 == ':')) { tokp += 1; tok = TOK_MACRO; }
- else if ((c == '#') && (c1 == '#')) { tokp += 1; tok = TOK_CONCATENATE; }
+ else if ((c == '.') && (c1 == '.') && (c2 == '.')) { eat += 2; tok = TOK_DOTS; }
+ else if ((c == '<') && (c1 == '<') && (c2 == '=')) { eat += 2; tok = TOK_SLEQ; }
+ else if ((c == '>') && (c1 == '>') && (c2 == '=')) { eat += 2; tok = TOK_SREQ; }
+ else if ((c == '*') && (c1 == '=')) { eat += 1; tok = TOK_TIMESEQ; }
+ else if ((c == '/') && (c1 == '=')) { eat += 1; tok = TOK_DIVEQ; }
+ else if ((c == '%') && (c1 == '=')) { eat += 1; tok = TOK_MODEQ; }
+ else if ((c == '+') && (c1 == '=')) { eat += 1; tok = TOK_PLUSEQ; }
+ else if ((c == '-') && (c1 == '=')) { eat += 1; tok = TOK_MINUSEQ; }
+ else if ((c == '&') && (c1 == '=')) { eat += 1; tok = TOK_ANDEQ; }
+ else if ((c == '^') && (c1 == '=')) { eat += 1; tok = TOK_XOREQ; }
+ else if ((c == '|') && (c1 == '=')) { eat += 1; tok = TOK_OREQ; }
+ else if ((c == '=') && (c1 == '=')) { eat += 1; tok = TOK_EQEQ; }
+ else if ((c == '!') && (c1 == '=')) { eat += 1; tok = TOK_NOTEQ; }
+ else if ((c == '|') && (c1 == '|')) { eat += 1; tok = TOK_LOGOR; }
+ else if ((c == '&') && (c1 == '&')) { eat += 1; tok = TOK_LOGAND; }
+ else if ((c == '<') && (c1 == '=')) { eat += 1; tok = TOK_LESSEQ; }
+ else if ((c == '>') && (c1 == '=')) { eat += 1; tok = TOK_MOREEQ; }
+ else if ((c == '<') && (c1 == '<')) { eat += 1; tok = TOK_SL; }
+ else if ((c == '>') && (c1 == '>')) { eat += 1; tok = TOK_SR; }
+ else if ((c == '+') && (c1 == '+')) { eat += 1; tok = TOK_PLUSPLUS; }
+ else if ((c == '-') && (c1 == '-')) { eat += 1; tok = TOK_MINUSMINUS; }
+ else if ((c == '-') && (c1 == '>')) { eat += 1; tok = TOK_ARROW; }
+ else if ((c == '<') && (c1 == ':')) { eat += 1; tok = TOK_LBRACKET; }
+ else if ((c == ':') && (c1 == '>')) { eat += 1; tok = TOK_RBRACKET; }
+ else if ((c == '<') && (c1 == '%')) { eat += 1; tok = TOK_LBRACE; }
+ else if ((c == '%') && (c1 == '>')) { eat += 1; tok = TOK_RBRACE; }
+ else if ((c == '%') && (c1 == ':')) { eat += 1; tok = TOK_MACRO; }
+ else if ((c == '#') && (c1 == '#')) { eat += 1; tok = TOK_CONCATENATE; }
else if (c == ';') { tok = TOK_SEMI; }
else if (c == '{') { tok = TOK_LBRACE; }
else if (c == '}') { tok = TOK_RBRACE; }
@@ -4233,38 +4285,12 @@ static void raw_next_token(struct compile_state *state,
else if (c == '.') { tok = TOK_DOT; }
else if (c == '~') { tok = TOK_TILDE; }
else if (c == '#') { tok = TOK_MACRO; }
+ else if (c == '\n') { tok = TOK_EOL; }
- file->pos = tokp + 1;
+ tokp = next_char(file, tokp, eat);
+ eat_chars(file, tokp);
tk->tok = tok;
- if (tok == TOK_IDENT) {
- if (state->token_base == 0) {
- ident_to_keyword(state, tk);
- } else {
- ident_to_macro(state, tk);
- }
- }
-}
-
-static void next_token(struct compile_state *state, struct token *tk)
-{
- struct file_state *file;
- file = state->file;
- /* Don't return space tokens. */
- do {
- raw_next_token(state, file, tk);
- if (tk->tok == TOK_MACRO) {
- /* Only match preprocessor directives at the start of a line */
- const char *ptr;
- for(ptr = file->line_start; spacep(*ptr); ptr++)
- ;
- if (ptr != file->pos - 1) {
- tk->tok = TOK_UNKNOWN;
- }
- }
- if (tk->tok == TOK_UNKNOWN) {
- error(state, 0, "unknown token");
- }
- } while(tk->tok == TOK_SPACE);
+ tk->pos = token;
}
static void check_tok(struct compile_state *state, struct token *tk, int tok)
@@ -4299,7 +4325,7 @@ static struct macro_arg_value *read_macro_args(
do {
raw_next_token(state, file, tk);
} while(tk->tok == TOK_SPACE);
- return 0;
+ return NULL;
}
argv = xcmalloc(sizeof(*argv) * macro->argc, "macro args");
for(i = 0, arg = macro->args; arg; arg = arg->next, i++) {
@@ -4340,11 +4366,11 @@ static struct macro_arg_value *read_macro_args(
if (tk->tok == TOK_EOF) {
error(state, 0, "End of file encountered while parsing macro arguments");
}
-
- len = file->pos - start;
+
+ len = char_strlen(file, start, file->pos);
argv[i].value = xrealloc(
argv[i].value, argv[i].len + len, "macro args");
- memcpy(argv[i].value + argv[i].len, start, len);
+ char_strcpy(argv[i].value + argv[i].len, file, start, file->pos);
argv[i].len += len;
}
if (i != macro->argc -1) {
@@ -4369,22 +4395,44 @@ struct macro_buf {
size_t len, pos;
};
+static void grow_macro_buf(struct compile_state *state,
+ const char *id, struct macro_buf *buf,
+ size_t grow)
+{
+ if ((buf->pos + grow) >= buf->len) {
+ buf->str = xrealloc(buf->str, buf->len + grow, id);
+ buf->len += grow;
+ }
+}
+
static void append_macro_text(struct compile_state *state,
- struct macro *macro, struct macro_buf *buf,
+ const char *id, struct macro_buf *buf,
const char *fstart, size_t flen)
{
+ grow_macro_buf(state, id, buf, flen);
+ memcpy(buf->str + buf->pos, fstart, flen);
#if 0
fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
buf->pos, buf->pos, buf->str,
- flen, flen, fstart);
+ flen, flen, buf->str + buf->pos);
+#endif
+ buf->pos += flen;
+}
+
+
+static void append_macro_chars(struct compile_state *state,
+ const char *id, struct macro_buf *buf,
+ struct file_state *file, const char *start, const char *end)
+{
+ size_t flen;
+ flen = char_strlen(file, start, end);
+ grow_macro_buf(state, id, buf, flen);
+ char_strcpy(buf->str + buf->pos, file, start, end);
+#if 0
+ fprintf(state->errout, "append: `%*.*s' `%*.*s'\n",
+ buf->pos, buf->pos, buf->str,
+ flen, flen, buf->str + buf->pos);
#endif
- if ((buf->pos + flen) < buf->len) {
- memcpy(buf->str + buf->pos, fstart, flen);
- } else {
- buf->str = xrealloc(buf->str, buf->len + flen, macro->ident->name);
- memcpy(buf->str + buf->pos, fstart, flen);
- buf->len += flen;
- }
buf->pos += flen;
}
@@ -4394,25 +4442,26 @@ static int compile_macro(struct compile_state *state,
static void macro_expand_args(struct compile_state *state,
struct macro *macro, struct macro_arg_value *argv, struct token *tk)
{
- size_t i;
+ int i;
for(i = 0; i < macro->argc; i++) {
struct file_state fmacro, *file;
struct macro_buf buf;
- const char *fstart;
- size_t flen;
+ fmacro.prev = 0;
fmacro.basename = argv[i].ident->name;
fmacro.dirname = "";
- fmacro.size = argv[i].len;
fmacro.buf = argv[i].value;
+ fmacro.size = argv[i].len;
fmacro.pos = fmacro.buf;
- fmacro.line_start = fmacro.buf;
fmacro.line = 1;
+ fmacro.line_start = fmacro.buf;
fmacro.report_line = 1;
fmacro.report_name = fmacro.basename;
fmacro.report_dir = fmacro.dirname;
- fmacro.prev = 0;
+ fmacro.macro = 1;
+ fmacro.trigraphs = 0;
+ fmacro.join_lines = 0;
buf.len = argv[i].len;
buf.str = xmalloc(buf.len, argv[i].ident->name);
@@ -4420,10 +4469,11 @@ static void macro_expand_args(struct compile_state *state,
file = &fmacro;
for(;;) {
- fstart = file->pos;
raw_next_token(state, file, tk);
- flen = file->pos - fstart;
+ /* If we have recursed into another macro body
+ * get out of it.
+ */
if (tk->tok == TOK_EOF) {
struct file_state *old;
old = file;
@@ -4443,8 +4493,8 @@ static void macro_expand_args(struct compile_state *state,
}
}
- append_macro_text(state, macro, &buf,
- fstart, flen);
+ append_macro_chars(state, macro->ident->name, &buf,
+ file, tk->pos, file->pos);
}
xfree(argv[i].value);
@@ -4462,19 +4512,25 @@ static void expand_macro(struct compile_state *state,
const char space[] = " ";
const char *fstart;
size_t flen;
- size_t i, j;
- fmacro.basename = macro->ident->name;
- fmacro.dirname = "";
- fmacro.size = macro->buf_len - macro->buf_off;;
- fmacro.buf = macro->buf + macro->buf_off;
- fmacro.pos = fmacro.buf;
- fmacro.line_start = fmacro.buf;
- fmacro.line = 1;
+ int i, j;
+
+ /* Place the macro body in a dummy file */
+ fmacro.prev = 0;
+ fmacro.basename = macro->ident->name;
+ fmacro.dirname = "";
+ fmacro.buf = macro->buf;
+ fmacro.size = macro->buf_len;
+ fmacro.pos = fmacro.buf;
+ fmacro.line = 1;
+ fmacro.line_start = fmacro.buf;
fmacro.report_line = 1;
fmacro.report_name = fmacro.basename;
fmacro.report_dir = fmacro.dirname;
- fmacro.prev = 0;
+ fmacro.macro = 1;
+ fmacro.trigraphs = 0;
+ fmacro.join_lines = 0;
+ /* Allocate a buffer to hold the macro expansion */
buf->len = macro->buf_len + 3;
buf->str = xmalloc(buf->len, macro->ident->name);
buf->pos = 0;
@@ -4498,7 +4554,7 @@ static void expand_macro(struct compile_state *state,
flen = argv[i].len;
break;
case TOK_MACRO:
- if (!macro->buf_off) {
+ if (macro->argc < 0) {
break;
}
do {
@@ -4515,7 +4571,7 @@ static void expand_macro(struct compile_state *state,
tk->ident->name);
}
/* Stringize token */
- append_macro_text(state, macro, buf, "\"", 1);
+ append_macro_text(state, macro->ident->name, buf, "\"", 1);
for(j = 0; j < argv[i].len; j++) {
char *str = argv[i].value + j;
size_t len = 1;
@@ -4527,9 +4583,9 @@ static void expand_macro(struct compile_state *state,
str = "\\\"";
len = 2;
}
- append_macro_text(state, macro, buf, str, len);
+ append_macro_text(state, macro->ident->name, buf, str, len);
}
- append_macro_text(state, macro, buf, "\"", 1);
+ append_macro_text(state, macro->ident->name, buf, "\"", 1);
fstart = 0;
flen = 0;
break;
@@ -4563,7 +4619,7 @@ static void expand_macro(struct compile_state *state,
break;
}
- append_macro_text(state, macro, buf, fstart, flen);
+ append_macro_text(state, macro->ident->name, buf, fstart, flen);
fstart = fmacro.pos;
raw_next_token(state, &fmacro, tk);
@@ -4580,18 +4636,24 @@ static void tag_macro_name(struct compile_state *state,
struct file_state fmacro;
const char *fstart;
size_t flen;
- fmacro.basename = macro->ident->name;
- fmacro.dirname = "";
- fmacro.size = buf->pos;
- fmacro.buf = buf->str;
- fmacro.pos = fmacro.buf;
- fmacro.line_start = fmacro.buf;
- fmacro.line = 1;
+
+ /* Put the old macro expansion buffer in a file */
+ fmacro.prev = 0;
+ fmacro.basename = macro->ident->name;
+ fmacro.dirname = "";
+ fmacro.buf = buf->str;
+ fmacro.size = buf->pos;
+ fmacro.pos = fmacro.buf;
+ fmacro.line = 1;
+ fmacro.line_start = fmacro.buf;
fmacro.report_line = 1;
fmacro.report_name = fmacro.basename;
fmacro.report_dir = fmacro.dirname;
- fmacro.prev = 0;
+ fmacro.macro = 1;
+ fmacro.trigraphs = 0;
+ fmacro.join_lines = 0;
+ /* Allocate a new macro expansion buffer */
buf->len = macro->buf_len + 3;
buf->str = xmalloc(buf->len, macro->ident->name);
buf->pos = 0;
@@ -4602,20 +4664,21 @@ static void tag_macro_name(struct compile_state *state,
flen = fmacro.pos - fstart;
if ((tk->tok == TOK_IDENT) &&
(tk->ident == macro->ident) &&
- (tk->val.notmacro == 0)) {
- append_macro_text(state, macro, buf, fstart, flen);
+ (tk->val.notmacro == 0))
+ {
+ append_macro_text(state, macro->ident->name, buf, fstart, flen);
fstart = "$";
flen = 1;
}
- append_macro_text(state, macro, buf, fstart, flen);
+ append_macro_text(state, macro->ident->name, buf, fstart, flen);
fstart = fmacro.pos;
raw_next_token(state, &fmacro, tk);
}
xfree(fmacro.buf);
}
-
+
static int compile_macro(struct compile_state *state,
struct file_state **filep, struct token *tk)
{
@@ -4638,13 +4701,13 @@ static int compile_macro(struct compile_state *state,
/* If I am a function like macro and the identifier is not followed
* by a left parenthesis, do nothing.
*/
- if ((macro->buf_off != 0) && !lparen_peek(state, *filep)) {
+ if ((macro->argc >= 0) && (get_char(*filep, (*filep)->pos) != '(')) {
return 0;
}
/* Read in the macro arguments */
argv = 0;
- if (macro->buf_off) {
+ if (macro->argc >= 0) {
raw_next_token(state, *filep, tk);
check_tok(state, tk, TOK_LPAREN);
@@ -4677,7 +4740,6 @@ static int compile_macro(struct compile_state *state,
* be regonized as a canidate for macro expansion.
*/
tag_macro_name(state, macro, &buf, tk);
- append_macro_text(state, macro, &buf, "\n\0", 2);
#if 0
fprintf(state->errout, "%s: %d -> `%*.*s'\n",
@@ -4687,18 +4749,20 @@ static int compile_macro(struct compile_state *state,
free_macro_args(macro, argv);
file = xmalloc(sizeof(*file), "file_state");
- file->basename = xstrdup(ident->name);
- file->dirname = xstrdup("");
- file->buf = buf.str;
- file->size = buf.pos - 2;
- file->pos = file->buf;
- file->line_start = file->pos;
- file->line = 1;
+ file->prev = *filep;
+ file->basename = xstrdup(ident->name);
+ file->dirname = xstrdup("");
+ file->buf = buf.str;
+ file->size = buf.pos;
+ file->pos = file->buf;
+ file->line = 1;
+ file->line_start = file->pos;
file->report_line = 1;
file->report_name = file->basename;
file->report_dir = file->dirname;
file->macro = 1;
- file->prev = *filep;
+ file->trigraphs = 0;
+ file->join_lines = 0;
*filep = file;
return 1;
}
@@ -4742,7 +4806,7 @@ static void in_if(struct compile_state *state, const char *name)
static void enter_if(struct compile_state *state)
{
state->if_depth += 1;
- if (state->if_depth > MAX_CPP_IF_DEPTH) {
+ if (state->if_depth > MAX_PP_IF_DEPTH) {
error(state, 0, "#if depth too great");
}
}
@@ -4774,28 +4838,52 @@ static void exit_if(struct compile_state *state, const char *name)
state->if_depth -= 1;
}
-static void cpp_token(struct compile_state *state, struct token *tk)
+static void raw_token(struct compile_state *state, struct token *tk)
{
struct file_state *file;
int rescan;
- next_token(state, tk);
+ file = state->file;
+ raw_next_token(state, file, tk);
do {
rescan = 0;
file = state->file;
/* Exit out of an include directive or macro call */
if ((tk->tok == TOK_EOF) &&
- (state->file && state->macro_file) &&
- file->prev)
+ (file != state->macro_file) && file->prev)
{
state->file = file->prev;
/* file->basename is used keep it */
xfree(file->dirname);
xfree(file->buf);
xfree(file);
- next_token(state, tk);
+ file = 0;
+ raw_next_token(state, state->file, tk);
+ rescan = 1;
+ }
+ } while(rescan);
+}
+
+static void pp_token(struct compile_state *state, struct token *tk)
+{
+ struct file_state *file;
+ int rescan;
+
+ raw_token(state, tk);
+ do {
+ rescan = 0;
+ file = state->file;
+ if (tk->tok == TOK_SPACE) {
+ raw_token(state, tk);
rescan = 1;
}
+ else if (tk->tok == TOK_IDENT) {
+ if (state->token_base == 0) {
+ ident_to_keyword(state, tk);
+ } else {
+ ident_to_macro(state, tk);
+ }
+ }
} while(rescan);
}
@@ -4804,31 +4892,47 @@ static void preprocess(struct compile_state *state, struct token *tk);
static void token(struct compile_state *state, struct token *tk)
{
int rescan;
- cpp_token(state, tk);
+ pp_token(state, tk);
do {
rescan = 0;
/* Process a macro directive */
if (tk->tok == TOK_MACRO) {
- preprocess(state, tk);
- rescan = 1;
+ /* Only match preprocessor directives at the start of a line */
+ const char *ptr;
+ ptr = state->file->line_start;
+ while((ptr < tk->pos)
+ && spacep(get_char(state->file, ptr)))
+ {
+ ptr = next_char(state->file, ptr, 1);
+ }
+ if (ptr == tk->pos) {
+ preprocess(state, tk);
+ rescan = 1;
+ }
}
/* Expand a macro call */
else if (tk->ident && tk->ident->sym_define) {
rescan = compile_macro(state, &state->file, tk);
if (rescan) {
- cpp_token(state, tk);
+ pp_token(state, tk);
}
}
- /* Eat tokens disabled by the preprocessor (Unless we are parsing a preprocessor directive */
+ /* Eat tokens disabled by the preprocessor
+ * (Unless we are parsing a preprocessor directive
+ */
else if (if_eat(state) && (state->token_base == 0)) {
- cpp_token(state, tk);
+ pp_token(state, tk);
rescan = 1;
}
/* Make certain EOL only shows up in preprocessor directives */
else if ((tk->tok == TOK_EOL) && (state->token_base == 0)) {
- cpp_token(state, tk);
+ pp_token(state, tk);
rescan = 1;
}
+ /* Error on unknown tokens */
+ else if (tk->tok == TOK_UNKNOWN) {
+ error(state, 0, "unknown token");
+ }
} while(rescan);
}
@@ -4867,19 +4971,35 @@ static struct token *do_eat_token(struct compile_state *state, int tok)
return tk;
}
-static int cpp_peek(struct compile_state *state)
+static int raw_peek(struct compile_state *state)
+{
+ struct token *tk1;
+ tk1 = get_token(state, 1);
+ if (tk1->tok == -1) {
+ raw_token(state, tk1);
+ }
+ return tk1->tok;
+}
+
+static struct token *raw_eat(struct compile_state *state, int tok)
+{
+ raw_peek(state);
+ return do_eat_token(state, tok);
+}
+
+static int pp_peek(struct compile_state *state)
{
struct token *tk1;
tk1 = get_token(state, 1);
if (tk1->tok == -1) {
- cpp_token(state, tk1);
+ pp_token(state, tk1);
}
return tk1->tok;
}
-static struct token *cpp_eat(struct compile_state *state, int tok)
+static struct token *pp_eat(struct compile_state *state, int tok)
{
- cpp_peek(state);
+ pp_peek(state);
return do_eat_token(state, tok);
}
@@ -4962,7 +5082,7 @@ static void compile_file(struct compile_state *state, const char *filename, int
}
}
if (!dir) {
- error(state, 0, "Cannot find `%s'\n", filename);
+ error(state, 0, "Cannot open `%s'\n", filename);
}
dirlen = strlen(dir);
file->dirname = xmalloc(dirlen + 1 + subdir_len + 1, "dirname");
@@ -4981,12 +5101,11 @@ static void compile_file(struct compile_state *state, const char *filename, int
file->report_name = file->basename;
file->report_dir = file->dirname;
file->macro = 0;
+ file->trigraphs = (state->compiler->flags & COMPILER_TRIGRAPHS)? 1: 0;
+ file->join_lines = 1;
file->prev = state->file;
state->file = file;
-
- process_trigraphs(state);
- splice_lines(state);
}
static struct triple *constant_expr(struct compile_state *state);
@@ -5009,32 +5128,28 @@ static void preprocess(struct compile_state *state, struct token *current_token)
* a parser and a major restructuring.
* Postpone that for later.
*/
- struct file_state *file;
int old_token_base;
- int line;
int tok;
- file = state->file;
- state->macro_line = line = file->line;
- state->macro_file = file;
+ state->macro_file = state->file;
old_token_base = state->token_base;
state->token_base = current_token - state->token;
- tok = cpp_peek(state);
- switch(tok) {
+ tok = pp_peek(state);
+ switch(tok) {
case TOK_LIT_INT:
{
struct token *tk;
int override_line;
- tk = cpp_eat(state, TOK_LIT_INT);
+ tk = pp_eat(state, TOK_LIT_INT);
override_line = strtoul(tk->val.str, 0, 10);
- /* I have a cpp line marker parse it */
- if (cpp_peek(state) == TOK_LIT_STRING) {
+ /* I have a preprocessor line marker parse it */
+ if (pp_peek(state) == TOK_LIT_STRING) {
const char *token, *base;
char *name, *dir;
int name_len, dir_len;
- tk = cpp_eat(state, TOK_LIT_STRING);
+ tk = pp_eat(state, TOK_LIT_STRING);
name = xmalloc(tk->str_len, "report_name");
token = tk->val.str + 1;
base = strrchr(token, '/');
@@ -5052,24 +5167,24 @@ static void preprocess(struct compile_state *state, struct token *current_token)
dir = xmalloc(dir_len + 1, "report_dir");
memcpy(dir, token, dir_len);
dir[dir_len] = '\0';
- file->report_line = override_line - 1;
- file->report_name = name;
- file->report_dir = dir;
- file->macro = 0;
+ state->file->report_line = override_line - 1;
+ state->file->report_name = name;
+ state->file->report_dir = dir;
+ state->file->macro = 0;
}
break;
}
case TOK_MLINE:
{
struct token *tk;
- cpp_eat(state, TOK_MLINE);
+ pp_eat(state, TOK_MLINE);
tk = eat(state, TOK_LIT_INT);
- file->report_line = strtoul(tk->val.str, 0, 10) -1;
- if (cpp_peek(state) == TOK_LIT_STRING) {
+ state->file->report_line = strtoul(tk->val.str, 0, 10) -1;
+ if (pp_peek(state) == TOK_LIT_STRING) {
const char *token, *base;
char *name, *dir;
int name_len, dir_len;
- tk = cpp_eat(state, TOK_LIT_STRING);
+ tk = pp_eat(state, TOK_LIT_STRING);
name = xmalloc(tk->str_len, "report_name");
token = tk->val.str + 1;
base = strrchr(token, '/');
@@ -5087,32 +5202,32 @@ static void preprocess(struct compile_state *state, struct token *current_token)
dir = xmalloc(dir_len + 1, "report_dir");
memcpy(dir, token, dir_len);
dir[dir_len] = '\0';
- file->report_name = name;
- file->report_dir = dir;
- file->macro = 0;
+ state->file->report_name = name;
+ state->file->report_dir = dir;
+ state->file->macro = 0;
}
break;
}
case TOK_MUNDEF:
{
struct hash_entry *ident;
- cpp_eat(state, TOK_MUNDEF);
+ pp_eat(state, TOK_MUNDEF);
if (if_eat(state)) /* quit early when #if'd out */
break;
- ident = cpp_eat(state, TOK_MIDENT)->ident;
+ ident = pp_eat(state, TOK_MIDENT)->ident;
undef_macro(state, ident);
break;
}
case TOK_MPRAGMA:
- cpp_eat(state, TOK_MPRAGMA);
+ pp_eat(state, TOK_MPRAGMA);
if (if_eat(state)) /* quit early when #if'd out */
break;
warning(state, 0, "Ignoring pragma");
break;
case TOK_MELIF:
- cpp_eat(state, TOK_MELIF);
+ pp_eat(state, TOK_MELIF);
reenter_if(state, "#elif");
if (if_eat(state)) /* quit early when #if'd out */
break;
@@ -5131,7 +5246,7 @@ static void preprocess(struct compile_state *state, struct token *current_token)
}
break;
case TOK_MIF:
- cpp_eat(state, TOK_MIF);
+ pp_eat(state, TOK_MIF);
enter_if(state);
if (if_eat(state)) /* quit early when #if'd out */
break;
@@ -5144,11 +5259,11 @@ static void preprocess(struct compile_state *state, struct token *current_token)
{
struct hash_entry *ident;
- cpp_eat(state, TOK_MIFNDEF);
+ pp_eat(state, TOK_MIFNDEF);
enter_if(state);
if (if_eat(state)) /* quit early when #if'd out */
break;
- ident = cpp_eat(state, TOK_MIDENT)->ident;
+ ident = pp_eat(state, TOK_MIDENT)->ident;
set_if_value(state, ident->sym_define == 0);
if (!if_value(state)) {
eat_tokens(state, TOK_MELSE);
@@ -5158,11 +5273,11 @@ static void preprocess(struct compile_state *state, struct token *current_token)
case TOK_MIFDEF:
{
struct hash_entry *ident;
- cpp_eat(state, TOK_MIFDEF);
+ pp_eat(state, TOK_MIFDEF);
enter_if(state);
if (if_eat(state)) /* quit early when #if'd out */
break;
- ident = cpp_eat(state, TOK_MIDENT)->ident;
+ ident = pp_eat(state, TOK_MIDENT)->ident;
set_if_value(state, ident->sym_define != 0);
if (!if_value(state)) {
eat_tokens(state, TOK_MELSE);
@@ -5170,69 +5285,51 @@ static void preprocess(struct compile_state *state, struct token *current_token)
break;
}
case TOK_MELSE:
- cpp_eat(state, TOK_MELSE);
+ pp_eat(state, TOK_MELSE);
enter_else(state, "#else");
if (!if_eat(state) && if_value(state)) {
eat_tokens(state, TOK_MENDIF);
}
break;
case TOK_MENDIF:
- cpp_eat(state, TOK_MENDIF);
+ pp_eat(state, TOK_MENDIF);
exit_if(state, "#endif");
break;
case TOK_MDEFINE:
{
struct hash_entry *ident;
struct macro_arg *args, **larg;
- const char *start, *mstart, *ptr;
+ const char *mstart, *mend;
+ int argc;
- cpp_eat(state, TOK_MDEFINE);
+ pp_eat(state, TOK_MDEFINE);
if (if_eat(state)) /* quit early when #if'd out */
break;
-
- ident = cpp_eat(state, TOK_MIDENT)->ident;
+ ident = pp_eat(state, TOK_MIDENT)->ident;
+ argc = -1;
args = 0;
larg = &args;
- /* Remember the start of the macro */
- start = file->pos;
-
- /* Find the end of the line. */
- for(ptr = start; *ptr != '\n'; ptr++)
- ;
-
- /* remove the trailing whitespace */
- ptr-=1;
- while(spacep(*ptr)) {
- ptr--;
- }
-
- /* Remove leading whitespace */
- while(spacep(*start) && (start < ptr)) {
- start++;
- }
- /* Remember where the macro starts */
- mstart = start;
-
/* Parse macro parameters */
- if (lparen_peek(state, state->file)) {
- cpp_eat(state, TOK_LPAREN);
-
+ if (raw_peek(state) == TOK_LPAREN) {
+ raw_eat(state, TOK_LPAREN);
+ argc += 1;
+
for(;;) {
struct macro_arg *narg, *arg;
struct hash_entry *aident;
int tok;
- tok = cpp_peek(state);
+ tok = pp_peek(state);
if (!args && (tok == TOK_RPAREN)) {
break;
}
else if (tok == TOK_DOTS) {
- cpp_eat(state, TOK_DOTS);
+ pp_eat(state, TOK_DOTS);
aident = state->i___VA_ARGS__;
}
else {
- aident = cpp_eat(state, TOK_MIDENT)->ident;
+ aident = pp_eat(state, TOK_MIDENT)->ident;
}
narg = xcmalloc(sizeof(*arg), "macro arg");
@@ -5248,57 +5345,82 @@ static void preprocess(struct compile_state *state, struct token *current_token)
/* Add the new argument to the end of the list */
*larg = narg;
larg = &narg->next;
+ argc += 1;
if ((aident == state->i___VA_ARGS__) ||
- (cpp_peek(state) != TOK_COMMA)) {
+ (pp_peek(state) != TOK_COMMA)) {
break;
}
- cpp_eat(state, TOK_COMMA);
+ pp_eat(state, TOK_COMMA);
}
- cpp_eat(state, TOK_RPAREN);
+ pp_eat(state, TOK_RPAREN);
+ }
+ /* Remove leading whitespace */
+ while(raw_peek(state) == TOK_SPACE) {
+ raw_eat(state, TOK_SPACE);
+ }
- /* Get the start of the macro body */
- mstart = file->pos;
+ /* Remember the start of the macro body */
+ tok = raw_peek(state);
+ mend = mstart = get_token(state, 1)->pos;
- /* Remove leading whitespace */
- while(spacep(*mstart) && (mstart < ptr)) {
- mstart++;
+ /* Find the end of the macro */
+ for(tok = raw_peek(state); tok != TOK_EOL; tok = raw_peek(state)) {
+ raw_eat(state, tok);
+ /* Remember the end of the last non space token */
+ raw_peek(state);
+ if (tok != TOK_SPACE) {
+ mend = get_token(state, 1)->pos;
}
}
- define_macro(state, ident, start, ptr - start + 1,
- mstart - start, args);
+
+ /* Now that I have found the body defined the token */
+ do_define_macro(state, ident,
+ char_strdup(state->file, mstart, mend, "macro buf"),
+ argc, args);
break;
}
case TOK_MERROR:
{
- const char *end;
+ const char *start, *end;
int len;
- cpp_eat(state, TOK_MERROR);
+ pp_eat(state, TOK_MERROR);
+ /* Find the start of the line */
+ raw_peek(state);
+ start = get_token(state, 1)->pos;
+
/* Find the end of the line */
- for(end = file->pos; *end != '\n'; end++)
- ;
- len = (end - file->pos);
+ while((tok = raw_peek(state)) != TOK_EOL) {
+ raw_eat(state, tok);
+ }
+ end = get_token(state, 1)->pos;
+ len = end - start;
if (!if_eat(state)) {
- error(state, 0, "%*.*s", len, len, file->pos);
+ error(state, 0, "%*.*s", len, len, start);
}
- file->pos = end;
break;
}
case TOK_MWARNING:
{
- const char *end;
+ const char *start, *end;
int len;
- cpp_eat(state, TOK_MWARNING);
+ pp_eat(state, TOK_MWARNING);
+
+ /* Find the start of the line */
+ raw_peek(state);
+ start = get_token(state, 1)->pos;
+
/* Find the end of the line */
- for(end = file->pos; *end != '\n'; end++)
- ;
- len = (end - file->pos);
+ while((tok = raw_peek(state)) != TOK_EOL) {
+ raw_eat(state, tok);
+ }
+ end = get_token(state, 1)->pos;
+ len = end - start;
if (!if_eat(state)) {
- warning(state, 0, "%*.*s", len, len, file->pos);
+ warning(state, 0, "%*.*s", len, len, start);
}
- file->pos = end;
break;
}
case TOK_MINCLUDE:
@@ -5308,7 +5430,7 @@ static void preprocess(struct compile_state *state, struct token *current_token)
local = 0;
name = 0;
- cpp_eat(state, TOK_MINCLUDE);
+ pp_eat(state, TOK_MINCLUDE);
tok = peek(state);
if (tok == TOK_LIT_STRING) {
struct token *tk;
@@ -5327,29 +5449,36 @@ static void preprocess(struct compile_state *state, struct token *current_token)
local = 1;
}
else if (tok == TOK_LESS) {
- const char *start, *end;
+ struct macro_buf buf;
eat(state, TOK_LESS);
- start = file->pos;
- for(end = start; *end != '\n'; end++) {
- if (*end == '>') {
- break;
- }
- }
- if (*end == '\n') {
+
+ buf.len = 40;
+ buf.str = xmalloc(buf.len, "include");
+ buf.pos = 0;
+
+ tok = peek(state);
+ while((tok != TOK_MORE) &&
+ (tok != TOK_EOL) && (tok != TOK_EOF))
+ {
+ struct token *tk;
+ tk = eat(state, tok);
+ append_macro_chars(state, "include", &buf,
+ state->file, tk->pos, state->file->pos);
+ tok = peek(state);
+ }
+ append_macro_text(state, "include", &buf, "\0", 1);
+ if (peek(state) != TOK_MORE) {
error(state, 0, "Unterminated include directive");
}
- name = xmalloc(end - start + 1, "include");
- memcpy(name, start, end - start);
- name[end - start] = '\0';
- file->pos = end;
- local = 0;
eat(state, TOK_MORE);
+ local = 0;
+ name = buf.str;
}
else {
error(state, 0, "Invalid include directive");
}
/* Error if there are any tokens after the include */
- if (cpp_peek(state) != TOK_EOL) {
+ if (pp_peek(state) != TOK_EOL) {
error(state, 0, "garbage after include directive");
}
if (!if_eat(state)) {
@@ -5376,10 +5505,11 @@ static void preprocess(struct compile_state *state, struct token *current_token)
}
/* Consume the rest of the macro line */
do {
- tok = cpp_peek(state);
- cpp_eat(state, tok);
+ tok = pp_peek(state);
+ pp_eat(state, tok);
} while((tok != TOK_EOF) && (tok != TOK_EOL));
state->token_base = old_token_base;
+ state->macro_file = NULL;
return;
}
@@ -8255,14 +8385,14 @@ static long_t bsf(ulong_t value)
return -1;
}
-static long_t log2(ulong_t value)
+static long_t ilog2(ulong_t value)
{
return bsr(value);
}
static long_t tlog2(struct triple *ins)
{
- return log2(ins->u.cval);
+ return ilog2(ins->u.cval);
}
static int is_pow2(struct triple *ins)
@@ -8273,7 +8403,7 @@ static int is_pow2(struct triple *ins)
return 0;
}
value = ins->u.cval;
- log = log2(value);
+ log = ilog2(value);
if (log == -1) {
return 0;
}
@@ -10897,11 +11027,11 @@ static struct triple *unary_expr(struct compile_state *state)
int parens;
eat(state, TOK_MDEFINED);
parens = 0;
- if (cpp_peek(state) == TOK_LPAREN) {
- cpp_eat(state, TOK_LPAREN);
+ if (pp_peek(state) == TOK_LPAREN) {
+ pp_eat(state, TOK_LPAREN);
parens = 1;
}
- ident = cpp_eat(state, TOK_MIDENT)->ident;
+ ident = pp_eat(state, TOK_MIDENT)->ident;
if (parens) {
eat(state, TOK_RPAREN);
}
@@ -10944,7 +11074,8 @@ static struct triple *mult_expr(struct compile_state *state)
struct type *result_type;
int tok, op, sign;
done = 0;
- switch(tok = (peek(state))) {
+ tok = peek(state);
+ switch(tok) {
case TOK_STAR:
case TOK_DIV:
case TOK_MOD:
@@ -24660,7 +24791,6 @@ static void print_preprocessed_tokens(struct compile_state *state)
tk->ident ? tk->ident->name :
tk->str_len ? tk->val.str :
tokens[tk->tok];
-
file = state->file;
while(file->macro && file->prev) {
@@ -24775,7 +24905,7 @@ static void compile(const char *filename,
compile_file(&state, filename, 1);
/* Stop if all we want is preprocessor output */
- if (state.compiler->flags & COMPILER_CPP_ONLY) {
+ if (state.compiler->flags & COMPILER_PP_ONLY) {
print_preprocessed_tokens(&state);
return;
}