diff lwcc/preproc.c @ 308:670ea8f90212 ccdev

Converted preproc logic to library and moved some utility stuff to lwlib The strbuf and strpool stuff is generally useful so move it to lwlib where other such things live. Also, package the preprocessor logic into a library for easy use in multiple places.
author William Astle <lost@l-w.ca>
date Sat, 21 Sep 2013 13:33:54 -0600
parents 9e342c4e4b66
children 73b2bfa17ab0
line wrap: on
line diff
--- a/lwcc/preproc.c	Sat Sep 21 12:27:48 2013 -0600
+++ b/lwcc/preproc.c	Sat Sep 21 13:33:54 2013 -0600
@@ -27,10 +27,10 @@
 
 #include <lw_alloc.h>
 #include <lw_string.h>
+#include <lw_strbuf.h>
+#include <lw_strpool.h>
 
 #include "cpp.h"
-#include "strbuf.h"
-#include "strpool.h"
 #include "symbol.h"
 #include "token.h"
 
@@ -38,6 +38,8 @@
 static void process_directive(struct preproc_info *);
 static long eval_expr(struct preproc_info *);
 extern struct token *preproc_lex_next_token(struct preproc_info *);
+static long preproc_numval(struct preproc_info *, struct token *);
+static int eval_escape(char **);
 
 
 struct token *preproc_next_processed_token(struct preproc_info *pp)
@@ -424,11 +426,11 @@
 
 char *streol(struct preproc_info *pp)
 {
-	struct strbuf *s;
+	struct lw_strbuf *s;
 	struct token *ct;
 	int i;
 		
-	s = strbuf_new();
+	s = lw_strbuf_new();
 	do
 	{
 		ct = preproc_next_token(pp);
@@ -437,10 +439,10 @@
 	while (ct -> ttype != TOK_EOL)
 	{
 		for (i = 0; ct -> strval[i]; i++)
-			strbuf_add(s, ct -> strval[i]);
+			lw_strbuf_add(s, ct -> strval[i]);
 		ct = preproc_next_token(pp);
 	}
-	return strbuf_end(s);
+	return lw_strbuf_end(s);
 }
 
 static void dir_error(struct preproc_info *pp)
@@ -544,7 +546,7 @@
 	struct token *ct;
 	int sys = 0;
 	char *fn;
-	struct strbuf *strbuf;
+	struct lw_strbuf *strbuf;
 	int i;
 	struct preproc_info *fs;
 	
@@ -561,7 +563,7 @@
 	}
 	else if (ct -> ttype == TOK_LT)
 	{
-		strbuf = strbuf_new();
+		strbuf = lw_strbuf_new();
 		for (;;)
 		{
 			int c;
@@ -570,23 +572,23 @@
 			{
 				preproc_lex_unfetch_byte(pp, c);
 				preproc_throw_error(pp, "Bad #include");
-				lw_free(strbuf_end(strbuf));
+				lw_free(lw_strbuf_end(strbuf));
 				break;
 			}
 			if (c == '>')
 				break;
-			strbuf_add(strbuf, c);
+			lw_strbuf_add(strbuf, c);
 		}
 		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));
+			lw_free(lw_strbuf_end(strbuf));
 			return;
 		}
 		sys = 1;
-		fn = strbuf_end(strbuf);
+		fn = lw_strbuf_end(strbuf);
 		goto doinc;
 	}
 	else
@@ -598,7 +600,7 @@
 			goto usrinc;
 		else if (ct -> ttype == TOK_LT)
 		{
-			strbuf = strbuf_new();
+			strbuf = lw_strbuf_new();
 			for (;;)
 			{
 				ct = preproc_next_processed_token(pp);
@@ -607,12 +609,12 @@
 				if (ct -> ttype == TOK_EOL)
 				{
 					preproc_throw_error(pp, "Bad #include");
-					lw_free(strbuf_end(strbuf));
+					lw_free(lw_strbuf_end(strbuf));
 					return;
 				}
 				for (i = 0; ct -> strval[i]; ct++)
 				{
-					strbuf_add(strbuf, ct -> strval[i]);
+					lw_strbuf_add(strbuf, ct -> strval[i]);
 				}
 			}
 			ct = preproc_next_processed_token_nws(pp);
@@ -620,11 +622,11 @@
 			{
 				preproc_throw_error(pp, "Bad #include");
 				skip_eol(pp);
-				lw_free(strbuf_end(strbuf));
+				lw_free(lw_strbuf_end(strbuf));
 				return;
 			}
 			sys = 1;
-			fn = strbuf_end(strbuf);
+			fn = lw_strbuf_end(strbuf);
 			goto doinc;
 		}
 		else
@@ -653,7 +655,7 @@
 	fs -> n = pp -> filestack;
 	pp -> curtok = NULL;
 	pp -> filestack = fs;
-	pp -> fn = strpool_strdup(pp -> strpool, fn);
+	pp -> fn = lw_strpool_strdup(pp -> strpool, fn);
 	lw_free(fn);
 	pp -> fp = fp;
 	pp -> ra = CPP_NOUNG;
@@ -770,6 +772,36 @@
 	if (ct -> ttype == TOK_EOL)
 		return;
 	
+	if (ct -> ttype == TOK_NUMBER)
+	{
+		// this is probably a file marker from a previous run of the preprocessor
+		char *fn;
+		struct lw_strbuf *sb;
+		
+		i = preproc_numval(pp, ct);
+		ct  = preproc_next_token_nws(pp);
+		if (ct -> ttype != TOK_STR_LIT)
+			goto baddir;
+		pp -> lineno = i;
+		sb = lw_strbuf_new();
+		for (fn = ct -> strval; *fn && *fn != '"'; )
+		{
+			if (*fn == '\\')
+			{
+				lw_strbuf_add(sb, eval_escape(&fn));
+			}
+			else
+			{
+				lw_strbuf_add(sb, *fn++);
+			}
+		}
+		fn = lw_strbuf_end(sb);
+		pp -> fn = lw_strpool_strdup(pp -> strpool, fn);
+		lw_free(fn);
+		skip_eol(pp);
+		return;
+	}
+	
 	if (ct -> ttype != TOK_IDENT)
 		goto baddir;
 	
@@ -800,7 +832,6 @@
 }
 
 static long eval_expr_real(struct preproc_info *, int);
-static long preproc_numval(struct preproc_info *, struct token *);
 
 static long eval_term_real(struct preproc_info *pp)
 {
@@ -1165,12 +1196,12 @@
 */
 static char *stringify(struct token_list *tli)
 {
-	struct strbuf *s;
+	struct lw_strbuf *s;
 	int ws = 0;
 	struct token *tl = tli -> head;
 	
-	s = strbuf_new();
-	strbuf_add(s, '"');
+	s = lw_strbuf_new();
+	lw_strbuf_add(s, '"');
 
 	while (tl && tl -> ttype == TOK_WSPACE)
 		tl = tl -> next;
@@ -1184,21 +1215,21 @@
 		}
 		if (ws)
 		{
-			strbuf_add(s, ' ');
+			lw_strbuf_add(s, ' ');
 		}
 		for (ws = 0; tl -> strval[ws]; ws++)
 		{
 			if (tl -> ttype == TOK_STR_LIT || tl -> ttype == TOK_CHR_LIT)
 			{
 				if (tl -> strval[ws] == '"' || tl -> strval[ws] == '\\')
-					strbuf_add(s, '\\');
+					lw_strbuf_add(s, '\\');
 			}
 		}
 		ws = 0;
 	}
 	
-	strbuf_add(s, '"');
-	return strbuf_end(s);
+	lw_strbuf_add(s, '"');
+	return lw_strbuf_end(s);
 }
 
 static int macro_arg(struct symtab_e *s, char *str)
@@ -1339,26 +1370,26 @@
 	// check for built in macros
 	if (strcmp(mname, "__FILE__") == 0)
 	{
-		struct strbuf *sb;
+		struct lw_strbuf *sb;
 		
-		sb = strbuf_new();
-		strbuf_add(sb, '"');
+		sb = lw_strbuf_new();
+		lw_strbuf_add(sb, '"');
 		for (tstr = (char *)(pp -> fn); *tstr; tstr++)
 		{
 			if (*tstr == 32 || (*tstr > 34 && *tstr < 127))
 			{
-				strbuf_add(sb, *tstr);
+				lw_strbuf_add(sb, *tstr);
 			}
 			else
 			{
-				strbuf_add(sb, '\\');
-				strbuf_add(sb, (*tstr >> 6) + '0');
-				strbuf_add(sb, ((*tstr >> 3) & 7) + '0');
-				strbuf_add(sb, (*tstr & 7) + '0');
+				lw_strbuf_add(sb, '\\');
+				lw_strbuf_add(sb, (*tstr >> 6) + '0');
+				lw_strbuf_add(sb, ((*tstr >> 3) & 7) + '0');
+				lw_strbuf_add(sb, (*tstr & 7) + '0');
 			}
 		}
-		strbuf_add(sb, '"');
-		tstr = strbuf_end(sb);
+		lw_strbuf_add(sb, '"');
+		tstr = lw_strbuf_end(sb);
 		preproc_unget_token(pp, token_create(TOK_STR_LIT, tstr, pp -> lineno, pp -> column, pp -> fn));
 		lw_free(tstr);
 		return 1;