# HG changeset patch # User William Astle # Date 1379274540 21600 # Node ID 8d6c473956532ee3f241433bdab3004ef541c11c # Parent 856caf91ffaa929b9898e958428992f5f0c13723 Implemented #include and #line Theoretically, directives are now implemented. diff -r 856caf91ffaa -r 8d6c47395653 lwcc/cpp.h --- a/lwcc/cpp.h Sun Sep 15 13:06:00 2013 -0600 +++ b/lwcc/cpp.h Sun Sep 15 13:49:00 2013 -0600 @@ -65,6 +65,8 @@ struct expand_e *expand_list; // record of which macros are currently being expanded char *lexstr; // for lexing a string (token pasting) int lexstrloc; // ditto + struct preproc_info *n; // next in file stack + struct preproc_info *filestack; // stack of saved files during include }; extern struct preproc_info *preproc_init(const char *); diff -r 856caf91ffaa -r 8d6c47395653 lwcc/lex.c --- a/lwcc/lex.c Sun Sep 15 13:06:00 2013 -0600 +++ b/lwcc/lex.c Sun Sep 15 13:49:00 2013 -0600 @@ -291,7 +291,7 @@ pp -> eolseen = 1; return c; } - + pp -> eolseen = 0; /* convert comments to a single space here */ @@ -351,7 +351,9 @@ int cl; struct strbuf *strbuf; struct token *t; - + struct preproc_info *fs; + +fileagain: c = preproc_lex_fetch_byte(pp); if (c == CPP_EOF) { @@ -363,8 +365,24 @@ if (c == CPP_EOF) { - ttype = TOK_EOF; - goto out; + /* check if we fell off the end of an include file */ + if (pp -> filestack) + { + if (pp -> skip_level || pp -> found_level) + { + preproc_throw_error(pp, "Unbalanced conditionals in include file"); + } + fclose(pp -> fp); + fs = pp -> filestack; + *pp = *fs; + pp -> filestack = fs -> n; + goto fileagain; + } + else + { + ttype = TOK_EOF; + goto out; + } } if (c == CPP_EOL) { diff -r 856caf91ffaa -r 8d6c47395653 lwcc/preproc.c --- a/lwcc/preproc.c Sun Sep 15 13:06:00 2013 -0600 +++ b/lwcc/preproc.c Sun Sep 15 13:49:00 2013 -0600 @@ -19,6 +19,8 @@ this program. If not, see . */ +#include +#include #include #include @@ -448,10 +450,185 @@ static void dir_include(struct preproc_info *pp) { + FILE *fp; + struct token *ct; + int sys = 0; + char *fn; + struct strbuf *strbuf; + int i; + struct preproc_info *fs; + + ct = preproc_next_token_nws(pp); + if (ct -> ttype == TOK_STRING) + { +usrinc: + sys = strlen(ct -> strval); + fn = lw_alloc(sys - 1); + memcpy(fn, ct -> strval + 1, sys - 2); + fn[sys - 1] = 0; + sys = 0; + goto doinc; + } + else if (ct -> ttype == TOK_LT) + { + strbuf = strbuf_new(); + for (;;) + { + ct = preproc_next_token(pp); + if (ct -> ttype == TOK_GT) + break; + if (ct -> ttype == TOK_EOL) + { + preproc_throw_error(pp, "Bad #include"); + lw_free(strbuf_end(strbuf)); + return; + } + for (i = 0; ct -> strval[i]; ct++) + { + strbuf_add(strbuf, ct -> strval[i]); + } + } + ct = preproc_next_token_nws(pp); + if (ct -> ttype != TOK_EOL) + { + preproc_throw_error(pp, "Bad #include"); + skip_eol(pp); + lw_free(strbuf_end(strbuf)); + return; + } + sys = 1; + fn = strbuf_end(strbuf); + goto doinc; + } + else + { + preproc_unget_token(pp, ct); + // computed include + ct = preproc_next_processed_token_nws(pp); + if (ct -> ttype == TOK_STRING) + goto usrinc; + else if (ct -> ttype == TOK_LT) + { + strbuf = strbuf_new(); + for (;;) + { + ct = preproc_next_processed_token(pp); + if (ct -> ttype == TOK_GT) + break; + if (ct -> ttype == TOK_EOL) + { + preproc_throw_error(pp, "Bad #include"); + lw_free(strbuf_end(strbuf)); + return; + } + for (i = 0; ct -> strval[i]; ct++) + { + strbuf_add(strbuf, ct -> strval[i]); + } + } + ct = preproc_next_processed_token_nws(pp); + if (ct -> ttype != TOK_EOL) + { + preproc_throw_error(pp, "Bad #include"); + skip_eol(pp); + lw_free(strbuf_end(strbuf)); + return; + } + sys = 1; + fn = strbuf_end(strbuf); + goto doinc; + } + else + { + skip_eol(pp); + preproc_throw_error(pp, "Bad #include"); + return; + } + } +doinc: +// fn = preproc_find_file(pp, fn, sys); + fp = fopen(fn, "rb"); + if (!fp) + { + preproc_throw_error(pp, "Cannot open #include file - this is fatal"); + exit(1); + } + + /* save the current include file state, etc. */ + fs = lw_alloc(sizeof(struct preproc_info)); + *fs = *pp; + fs -> n = pp -> filestack; + pp -> filestack = fs; + pp -> fn = fn; + pp -> fp = fp; + pp -> ra = CPP_NOUNG; + pp -> ppeolseen = 1; + pp -> eolstate = 0; + pp -> lineno = 0; + pp -> column = 0; + pp -> qseen = 0; + pp -> ungetbufl = 0; + pp -> ungetbufs = 0; + pp -> ungetbuf = NULL; + pp -> unget = 0; + pp -> eolseen = 0; + pp -> nlseen = 0; + pp -> skip_level = 0; + pp -> found_level = 0; + pp -> else_level = 0; + pp -> else_skip_level = 0; + + // now get on with processing } static void dir_line(struct preproc_info *pp) { + struct token *ct; + long lineno; + char *estr; + + lineno = -1; + + ct = preproc_next_processed_token_nws(pp); + if (ct -> ttype == TOK_NUMBER) + { + lineno = strtoul(ct -> strval, &estr, 10); + if (*estr) + { + preproc_throw_error(pp, "Bad #line"); + skip_eol(pp); + return; + } + } + else + { + preproc_throw_error(pp, "Bad #line"); + skip_eol(pp); + return; + } + ct = preproc_next_processed_token_nws(pp); + if (ct -> ttype == TOK_EOL) + { + pp -> lineno = lineno; + return; + } + if (ct -> ttype != TOK_STRING) + { + preproc_throw_error(pp, "Bad #line"); + skip_eol(pp); + return; + } + estr = lw_strdup(ct -> strval); + ct = preproc_next_processed_token_nws(pp); + if (ct -> ttype != TOK_EOL) + { + preproc_throw_error(pp, "Bad #line"); + skip_eol(pp); + lw_free(estr); + return; + } + pp -> fn = estr; + pp -> lineno = lineno; } static void dir_pragma(struct preproc_info *pp)