scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 38e6f6b3509088e152f21f77b97f75ba5a4309ed
parent 454cbc4039b4f3c7efb737b04259c0e4ab73ba40
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 11 Aug 2015 22:02:15 +0200

Add cpperror()

This function is like printerr(), but it also discards the
rest of the line, and calls to next() to obtain a EOF in yytoken.

Diffstat:
Mcc1/cc1.h | 1+
Mcc1/cpp.c | 27+++++++++++++--------------
Mcc1/error.c | 21+++++++++++++++++----
3 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -291,6 +291,7 @@ extern void error(char *fmt, ...); extern void warn(char *fmt, ...); extern void unexpected(void); extern void printerr(char *fmt, ...); +extern void cpperror(char *fmt, ...); /* types.c */ extern bool eqtype(Type *tp1, Type *tp2); diff --git a/cc1/cpp.c b/cc1/cpp.c @@ -244,11 +244,11 @@ getpars(Symbol *args[NR_MACROARG]) do { if (n == NR_MACROARG) { - printerr("too much parameters in macro"); + cpperror("too much parameters in macro"); return NR_MACROARG; } if (yytoken != IDEN) { - printerr("macro arguments must be identifiers"); + cpperror("macro arguments must be identifiers"); return NR_MACROARG; } args[n++] = yylval.sym; @@ -279,14 +279,14 @@ getdefs(Symbol *args[NR_MACROARG], int nargs, char *bp, size_t bufsiz) } } if (prevc == '#' && !ispar) { - printerr("'#' is not followed by a macro parameter"); + cpperror("'#' is not followed by a macro parameter"); return 0; } if (yytoken == EOFTOK) break; if ((len = strlen(yytext)) >= bufsiz) { - printerr("too long macro"); + cpperror("too long macro"); return 0; } memcpy(bp, yytext, len); @@ -391,15 +391,15 @@ include(void) } if (*bp) - printerr("included file '%s' not found", file); + cpperror("included file '%s' not found", file); return; bad_include: - printerr("#include expects \"FILENAME\" or <FILENAME>"); + cpperror("#include expects \"FILENAME\" or <FILENAME>"); return; too_long: - printerr("#include FILENAME too long"); + cpperror("#include FILENAME too long"); return; } @@ -412,11 +412,10 @@ line(void) if (cppoff) return; - setnamespace(NS_IDEN); next(); n = strtol(yytext, &endp, 10); if (n <= 0 || n > USHRT_MAX || *endp != '\0') { - printerr("first parameter of #line is not a positive integer"); + cpperror("first parameter of #line is not a positive integer"); return; } @@ -425,7 +424,7 @@ line(void) goto set_line; if (*yytext != '\"' || yylen == 1) { - printerr("second parameter of #line is not a valid filename"); + cpperror("second parameter of #line is not a valid filename"); return; } @@ -434,7 +433,7 @@ line(void) next(); set_line: - input->nline = yylval.sym->u.i; + input->nline = n; } static void @@ -451,7 +450,7 @@ usererr(void) { if (cppoff) return; - printerr("#error %s", input->p); + cpperror("#error %s", input->p); *input->p = '\0'; next(); } @@ -470,7 +469,7 @@ ifclause(int negate, int isifdef) if (isifdef) { if (yytoken != IDEN) { - printerr("no macro name given in #%s directive", + cpperror("no macro name given in #%s directive", (negate) ? "ifndef" : "ifdef"); return; } @@ -482,7 +481,7 @@ ifclause(int negate, int isifdef) } else { /* TODO: catch recovery here */ if ((expr = iconstexpr()) == NULL) { - printerr("parameter of #if is not an integer constant expression"); + cpperror("parameter of #if is not an integer constant expression"); return; } status = expr->sym->u.i != 0; diff --git a/cc1/error.c b/cc1/error.c @@ -13,7 +13,7 @@ extern int failure; static unsigned nerrors; static void -warn_helper(int flag, char *fmt, va_list va) +warn_error(int flag, char *fmt, va_list va) { if (flag == 0) return; @@ -39,7 +39,7 @@ warn(char *fmt, ...) va_list va; va_start(va, fmt); - warn_helper(warnings, fmt, va); + warn_error(warnings, fmt, va); va_end(va); } @@ -49,7 +49,7 @@ error(char *fmt, ...) va_list va; va_start(va, fmt); - warn_helper(-1, fmt, va); + warn_error(-1, fmt, va); va_end(va); exit(1); discard(); @@ -60,11 +60,24 @@ printerr(char *fmt, ...) { va_list va; va_start(va, fmt); - warn_helper(-1, fmt, va); + warn_error(-1, fmt, va); va_end(va); } void +cpperror(char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + warn_error(-1, fmt, va); + va_end(va); + + /* discard input until the end of the line */ + *input->p = '\0'; + next(); +} + +void unexpected(void) { error("unexpected '%s'", yytext);