# HG changeset patch # User William Astle # Date 1379558501 21600 # Node ID b08787e5b9f3edd229f5ea2857697564b01f1bd0 # Parent 54f213c8fb81ade22f569c635da0c53712634645 Add include search paths and command line macro definitions Added command line macro definitions. Also implemented include paths. There is no default include path; that will be supplied by the driver program. diff -r 54f213c8fb81 -r b08787e5b9f3 lwcc/cpp-main.c --- a/lwcc/cpp-main.c Wed Sep 18 19:17:52 2013 -0600 +++ b/lwcc/cpp-main.c Wed Sep 18 20:41:41 2013 -0600 @@ -40,6 +40,9 @@ /* input files */ lw_stringlist_t input_files; +lw_stringlist_t includedirs; +lw_stringlist_t sysincludedirs; +lw_stringlist_t macrolist; /* various flags */ int trigraphs = 0; @@ -70,6 +73,18 @@ case 0x100: trigraphs = 1; break; + + case 'I': + lw_stringlist_addstring(includedirs, arg); + break; + + case 'S': + lw_stringlist_addstring(sysincludedirs, arg); + break; + + case 'D': + lw_stringlist_addstring(macrolist, arg); + break; case lw_cmdline_key_end: break; @@ -99,7 +114,10 @@ int retval = 0; input_files = lw_stringlist_create(); - + includedirs = lw_stringlist_create(); + sysincludedirs = lw_stringlist_create(); + macrolist = lw_stringlist_create(); + /* parse command line arguments */ lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, NULL); @@ -134,7 +152,9 @@ } } lw_stringlist_destroy(input_files); - + lw_stringlist_destroy(includedirs); + lw_stringlist_destroy(sysincludedirs); + lw_stringlist_destroy(macrolist); exit(retval); } @@ -162,11 +182,32 @@ struct token *tok = NULL; int last_line = 0; char *last_fn = NULL; + char *tstr; pp = preproc_init(fn); if (!pp) return -1; + /* set up the include paths */ + lw_stringlist_reset(includedirs); + for (tstr = lw_stringlist_current(includedirs); tstr; tstr = lw_stringlist_next(includedirs)) + { + preproc_add_include(pp, tstr, 0); + } + + lw_stringlist_reset(sysincludedirs); + for (tstr = lw_stringlist_current(sysincludedirs); tstr; tstr = lw_stringlist_next(sysincludedirs)) + { + preproc_add_include(pp, tstr, 1); + } + + /* set up pre-defined macros */ + lw_stringlist_reset(macrolist); + for (tstr = lw_stringlist_current(macrolist); tstr; tstr = lw_stringlist_next(macrolist)) + { + preproc_add_macro(pp, tstr); + } + print_line_marker(output_fp, 1, fn, 1); last_fn = lw_strdup(fn); for (;;) diff -r 54f213c8fb81 -r b08787e5b9f3 lwcc/cpp.c --- a/lwcc/cpp.c Wed Sep 18 19:17:52 2013 -0600 +++ b/lwcc/cpp.c Wed Sep 18 20:41:41 2013 -0600 @@ -26,6 +26,7 @@ #include #include +#include #include "cpp.h" #include "strpool.h" @@ -58,9 +59,19 @@ pp -> ppeolseen = 1; pp -> lineno = 1; pp -> n = NULL; + pp -> quotelist = lw_stringlist_create(); + pp -> inclist = lw_stringlist_create(); return pp; } +void preproc_add_include(struct preproc_info *pp, char *dir, int sys) +{ + if (sys) + lw_stringlist_addstring(pp -> inclist, dir); + else + lw_stringlist_addstring(pp -> quotelist, dir); +} + struct token *preproc_next_token(struct preproc_info *pp) { struct token *t; @@ -118,6 +129,8 @@ void preproc_finish(struct preproc_info *pp) { fclose(pp -> fp); + lw_stringlist_destroy(pp -> inclist); + lw_stringlist_destroy(pp -> quotelist); if (pp -> curtok) token_free(pp -> curtok); while (pp -> tokqueue) diff -r 54f213c8fb81 -r b08787e5b9f3 lwcc/cpp.h --- a/lwcc/cpp.h Wed Sep 18 19:17:52 2013 -0600 +++ b/lwcc/cpp.h Wed Sep 18 20:41:41 2013 -0600 @@ -24,6 +24,8 @@ #include +#include + //#include "symbol.h" #include "token.h" @@ -68,6 +70,8 @@ struct preproc_info *n; // next in file stack struct preproc_info *filestack; // stack of saved files during include struct strpool *strpool; + lw_stringlist_t quotelist; + lw_stringlist_t inclist; }; extern struct preproc_info *preproc_init(const char *); @@ -79,6 +83,8 @@ extern void preproc_throw_error(struct preproc_info *, const char *, ...); extern void preproc_throw_warning(struct preproc_info *, const char *, ...); extern void preproc_unget_token(struct preproc_info *, struct token *); +extern void preproc_add_include(struct preproc_info *, char *, int); +extern void preproc_add_macro(struct preproc_info *, char *); extern struct token *preproc_next(struct preproc_info *); #endif // cpp_h_seen___ diff -r 54f213c8fb81 -r b08787e5b9f3 lwcc/lex.c --- a/lwcc/lex.c Wed Sep 18 19:17:52 2013 -0600 +++ b/lwcc/lex.c Wed Sep 18 20:41:41 2013 -0600 @@ -193,6 +193,17 @@ characters cross a token boundary. */ void preproc_lex_unfetch_byte(struct preproc_info *pp, int c) { + if (pp -> lexstr) + { + if (c == CPP_EOL) + return; + if (pp -> lexstrloc > 0) + { + pp -> lexstrloc--; + return; + } + } + if (pp -> ungetbufl >= pp -> ungetbufs) { pp -> ungetbufs += 100; diff -r 54f213c8fb81 -r b08787e5b9f3 lwcc/preproc.c --- a/lwcc/preproc.c Wed Sep 18 19:17:52 2013 -0600 +++ b/lwcc/preproc.c Wed Sep 18 20:41:41 2013 -0600 @@ -22,12 +22,14 @@ #include #include #include +#include #include #include #include "cpp.h" #include "strbuf.h" +#include "strpool.h" #include "symbol.h" #include "token.h" @@ -280,7 +282,6 @@ mname = lw_strdup(ct -> strval); ct = preproc_next_token(pp); - if (ct -> ttype == TOK_WSPACE) { /* object like macro */ @@ -338,7 +339,7 @@ else { baddefine: - preproc_throw_error(pp, "bad #define"); + preproc_throw_error(pp, "bad #define", ct -> ttype); baddefine2: token_list_destroy(tl); skip_eol(pp); @@ -353,6 +354,7 @@ for (;;) { ct = preproc_next_token(pp); + if (ct -> ttype == TOK_EOL) break; token_list_append(tl, token_dup(ct)); @@ -378,6 +380,23 @@ /* no need to check for EOL here */ } +void preproc_add_macro(struct preproc_info *pp, char *str) +{ + char *s; + + pp -> lexstr = lw_strdup(str); + pp -> lexstrloc = 0; + s = strchr(pp -> lexstr, '='); + if (s) + *s = ' '; + + dir_define(pp); + + lw_free(pp -> lexstr); + pp -> lexstr = NULL; + pp -> lexstrloc = 0; +} + static void dir_undef(struct preproc_info *pp) { struct token *ct; @@ -453,6 +472,71 @@ lw_free(s); } +static char *preproc_file_exists_in_dir(char *dir, char *fn) +{ + int l; + char *f; + + l = snprintf(NULL, 0, "%s/%s", dir, fn); + f = lw_alloc(l + 1); + snprintf(f, l + 1, "%s/%s", dir, fn); + + if (access(f, R_OK) == 0) + return f; + lw_free(f); + return NULL; +} + +static char *preproc_find_file(struct preproc_info *pp, char *fn, int sys) +{ + char *tstr; + char *pref; + char *rfn; + + /* pass through absolute paths, dumb as they are */ + if (fn[0] == '/') + return lw_strdup(fn); + + if (!sys) + { + /* look in the directory with the current file */ + tstr = strchr(pp -> fn, '/'); + if (!tstr) + pref = lw_strdup("."); + else + { + pref = lw_alloc(tstr - pp -> fn + 1); + memcpy(pref, pp -> fn, tstr - pp -> fn); + pref[tstr - pp -> fn] = 0; + } + rfn = preproc_file_exists_in_dir(pref, fn); + lw_free(pref); + if (rfn) + return rfn; + + /* look in the "quote" dir list */ + lw_stringlist_reset(pp -> quotelist); + for (pref = lw_stringlist_current(pp -> quotelist); pref; pref = lw_stringlist_next(pp -> quotelist)) + { + rfn = preproc_file_exists_in_dir(pref, fn); + if (rfn) + return rfn; + } + } + + /* look in the "include" dir list */ + lw_stringlist_reset(pp -> inclist); + for (pref = lw_stringlist_current(pp -> inclist); pref; pref = lw_stringlist_next(pp -> inclist)) + { + rfn = preproc_file_exists_in_dir(pref, fn); + if (rfn) + return rfn; + } + + /* the default search list is provided by the driver program */ + return NULL; +} + static void dir_include(struct preproc_info *pp) { FILE *fp; @@ -550,10 +634,14 @@ } } doinc: -// fn = preproc_find_file(pp, fn, sys); + fn = preproc_find_file(pp, fn, sys); + if (!fn) + goto badfile; fp = fopen(fn, "rb"); if (!fp) { + lw_free(fn); +badfile: preproc_throw_error(pp, "Cannot open #include file %s - this is fatal", fn); exit(1); } @@ -564,7 +652,8 @@ fs -> n = pp -> filestack; pp -> curtok = NULL; pp -> filestack = fs; - pp -> fn = fn; + pp -> fn = strpool_strdup(pp -> strpool, fn); + lw_free(fn); pp -> fp = fp; pp -> ra = CPP_NOUNG; pp -> ppeolseen = 1; diff -r 54f213c8fb81 -r b08787e5b9f3 lwcc/token.h --- a/lwcc/token.h Wed Sep 18 19:17:52 2013 -0600 +++ b/lwcc/token.h Wed Sep 18 20:41:41 2013 -0600 @@ -31,71 +31,66 @@ CPP_EOF = -1, }; -enum -{ - TOK_NONE = 0, - TOK_EOF, - TOK_EOL, - TOK_WSPACE, - TOK_IDENT, - TOK_NUMBER, -// TOK_STRING, - TOK_CHAR, - TOK_DIV, - TOK_ADD, - TOK_SUB, - TOK_OPAREN, - TOK_CPAREN, - TOK_NE, - TOK_EQ, - TOK_LE, - TOK_LT, - TOK_GE, - TOK_GT, - TOK_BAND, - TOK_BOR, - TOK_BNOT, - TOK_MOD, - TOK_COMMA, - TOK_ELLIPSIS, - TOK_QMARK, - TOK_COLON, - TOK_OBRACE, - TOK_CBRACE, - TOK_OSQUARE, - TOK_CSQUARE, - TOK_COM, - TOK_EOS, - TOK_HASH, - TOK_DBLHASH, - TOK_XOR, - TOK_XORASS, - TOK_STAR, - TOK_MULASS, - TOK_DIVASS, - TOK_ASS, - TOK_MODASS, - TOK_SUBASS, - TOK_DBLSUB, - TOK_ADDASS, - TOK_DBLADD, - TOK_BWAND, - TOK_BWANDASS, - TOK_BWOR, - TOK_BWORASS, - TOK_LSH, - TOK_LSHASS, - TOK_RSH, - TOK_RSHASS, - TOK_DOT, - TOK_CHR_LIT, - TOK_STR_LIT, - TOK_ARROW, - TOK_ENDEXPAND, - TOK_STARTEXPAND, - TOK_ERROR, - TOK_MAX -}; +#define TOK_NONE 0 +#define TOK_EOF 1 +#define TOK_EOL 2 +#define TOK_WSPACE 3 +#define TOK_IDENT 4 +#define TOK_NUMBER 5 +#define TOK_CHAR 6 +#define TOK_ADD 8 +#define TOK_SUB 9 +#define TOK_OPAREN 10 +#define TOK_CPAREN 11 +#define TOK_NE 12 +#define TOK_EQ 13 +#define TOK_LE 14 +#define TOK_LT 15 +#define TOK_GE 16 +#define TOK_GT 17 +#define TOK_BAND 18 +#define TOK_BOR 19 +#define TOK_BNOT 20 +#define TOK_MOD 21 +#define TOK_COMMA 22 +#define TOK_ELLIPSIS 23 +#define TOK_QMARK 24 +#define TOK_COLON 25 +#define TOK_OBRACE 26 +#define TOK_CBRACE 27 +#define TOK_OSQUARE 28 +#define TOK_CSQUARE 29 +#define TOK_COM 30 +#define TOK_EOS 31 +#define TOK_HASH 32 +#define TOK_DBLHASH 33 +#define TOK_XOR 34 +#define TOK_XORASS 35 +#define TOK_STAR 36 +#define TOK_MULASS 37 +#define TOK_DIV 38 +#define TOK_DIVASS 39 +#define TOK_ASS 40 +#define TOK_MODASS 41 +#define TOK_SUBASS 42 +#define TOK_DBLSUB 43 +#define TOK_ADDASS 44 +#define TOK_DBLADD 45 +#define TOK_BWAND 46 +#define TOK_BWANDASS 47 +#define TOK_BWOR 48 +#define TOK_BWORASS 49 +#define TOK_LSH 50 +#define TOK_LSHASS 51 +#define TOK_RSH 52 +#define TOK_RSHASS 53 +#define TOK_DOT 54 +#define TOK_CHR_LIT 55 +#define TOK_STR_LIT 56 +#define TOK_ARROW 57 +#define TOK_ENDEXPAND 58 +#define TOK_ERROR 59 +#define TOK_MAX 60 struct token {