changeset 306:b08787e5b9f3 ccdev

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.
author William Astle <lost@l-w.ca>
date Wed, 18 Sep 2013 20:41:41 -0600
parents 54f213c8fb81
children 9e342c4e4b66
files lwcc/cpp-main.c lwcc/cpp.c lwcc/cpp.h lwcc/lex.c lwcc/preproc.c lwcc/token.h
diffstat 6 files changed, 226 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- 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 (;;)
--- 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 <lw_alloc.h>
 #include <lw_string.h>
+#include <lw_stringlist.h>
 
 #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)
--- 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 <stdio.h>
 
+#include <lw_stringlist.h>
+
 //#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___
--- 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;
--- 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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <lw_alloc.h>
 #include <lw_string.h>
 
 #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;
--- 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
 {