changeset 307:9e342c4e4b66 ccdev

Added support for __LINE__, __FILE__, __DATE__, and __TIME__ Added support for the standard __LINE__, __FILE__, __DATE__, and __TIME "macros" and updated the readme form lwcc to reflect the current development state. Note: attempts to define these four macros will succeed but the definitions will be ignored.
author William Astle <lost@l-w.ca>
date Sat, 21 Sep 2013 12:27:48 -0600
parents b08787e5b9f3
children 670ea8f90212
files lwcc/README.txt lwcc/cpp-main.c lwcc/preproc.c
diffstat 3 files changed, 97 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/lwcc/README.txt	Wed Sep 18 20:41:41 2013 -0600
+++ b/lwcc/README.txt	Sat Sep 21 12:27:48 2013 -0600
@@ -3,32 +3,46 @@
 While none of the actual code from PCC was actually used, much of compiler
 itself served as a template for creating lwcc.
 
-This directory is arranged as follows:
 
-driver/
+LIMITATIONS AND DESIGN CHOICES
+==============================
 
-This contains the source for the front end driver program which will be
-called "lwcc" and is the public face of the compiler. The lwcc program
-itself provides various options that are largely compatible with unix C
-compilers like gcc. It should be noted that the internal interface between
-the lwcc driver and its back end programs (the preprocessor and compiler
-proper) is unspecified and subject to change without notice. The assembler
-and linker (lwasm, lwlink) do have defined public interfaces are are not
-likely to change substantially.
+The direct interface to both the compiler proper and the preprocessor is
+specifically undefined. Indeed, the preprocessor may, in fact, not be a
+separate program at all. Relying on the specific format of the output of the
+preprocessor is specifically forbidden even though it is possible to obtain
+preprocessed output from the compiler driver. This is provided for debugging
+purposes only.
+
+The preprocessor supports variadic macros. It also supports stringification,
+and token concatenation but only within a macro expansion. There are
+examples online that use the construct "#__LINE__" to get a string version
+of the current line number.
 
-
-cpp/
+The preprocessor defaults to ignoring trigraphs because they are basically a
+stupid idea on any current system. They have their place for systems where
+creating the nine characters specified by the trigraphs is very difficult or
+impossible. It is possible, however, to instruct the preprocessor to decode
+trigraph sequences.
 
-This is the actual C preprocessor. Its specific interface is deliberately
-undocumented. Do not call it directly. Ever. Just don't. Bad Things(tm) will
-happen if you do.
+The nonstandard "#pragma once" feature is not supported at all. The effect
+is easily accomplished using standard macros and conditionals. It is,
+therefore, unneeded complexity.
 
-
-liblwcc/
+The nonstandard idea of preprocessor assertions is also completely
+unsupported. It is just as easy to test predefined macros and such tests are
+much more portable.
 
-This contains any runtime libraries the compiler needs to support its
-output. This is usually assembly routines to support complex operations not
-directly supported by the CPU instruction set.
+The preprocessor supports __LINE__, __FILE__, __DATE__, and __TIME__. The
+compiler itself supports __func__ as a predefined string constant if
+encountered because there is no way for the preprocessor to determine what
+function it occurs within. The preprocessor does not define __STDC__,
+__STDC_VERSION__, or __STDC_HOSTED__. I have seen no truly useful purpose
+for these and since lwcc does not, at this time, conform to any known C
+standard, it would be incorrect to define the first two.
+
+The compiler driver may define additional macros depending on its idea of
+the context.
 
 
 RUNTIME INFORMATION
--- a/lwcc/cpp-main.c	Wed Sep 18 20:41:41 2013 -0600
+++ b/lwcc/cpp-main.c	Sat Sep 21 12:27:48 2013 -0600
@@ -173,7 +173,7 @@
 		}
 		fn++;
 	}
-	fprintf(fp, "\" %d\n", flag);
+	fprintf(fp, "\" %d", flag);
 }
 
 int process_file(const char *fn)
--- a/lwcc/preproc.c	Wed Sep 18 20:41:41 2013 -0600
+++ b/lwcc/preproc.c	Sat Sep 21 12:27:48 2013 -0600
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 
 #include <lw_alloc.h>
@@ -1334,7 +1335,67 @@
 	struct token_list *expand_list;
 	int repl;
 	struct token_list *rtl;
-			
+	
+	// check for built in macros
+	if (strcmp(mname, "__FILE__") == 0)
+	{
+		struct strbuf *sb;
+		
+		sb = strbuf_new();
+		strbuf_add(sb, '"');
+		for (tstr = (char *)(pp -> fn); *tstr; tstr++)
+		{
+			if (*tstr == 32 || (*tstr > 34 && *tstr < 127))
+			{
+				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');
+			}
+		}
+		strbuf_add(sb, '"');
+		tstr = strbuf_end(sb);
+		preproc_unget_token(pp, token_create(TOK_STR_LIT, tstr, pp -> lineno, pp -> column, pp -> fn));
+		lw_free(tstr);
+		return 1;
+	}
+	else if (strcmp(mname, "__LINE__") == 0)
+	{
+		char nbuf[25];
+		snprintf(nbuf, 25, "%d", pp -> lineno);
+		preproc_unget_token(pp, token_create(TOK_NUMBER, nbuf, pp -> lineno, pp -> column, pp -> fn));
+		return 1;
+	}
+	else if (strcmp(mname, "__DATE__") == 0)
+	{
+		char dbuf[14];
+		struct tm *tv;
+		time_t tm;
+		static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+		
+		tm = time(NULL);
+		tv = localtime(&tm);
+		snprintf(dbuf, 14, "\"%s %2d %04d\"", months[tv -> tm_mon], tv -> tm_mday, tv -> tm_year + 1900);
+		preproc_unget_token(pp, token_create(TOK_STR_LIT, dbuf, pp -> lineno, pp -> column, pp -> fn));
+		return 1;
+	}
+	else if (strcmp(mname, "__TIME__") == 0)
+	{
+		char tbuf[11];
+		struct tm *tv;
+		time_t tm;
+		
+		tm = time(NULL);
+		tv = localtime(&tm);
+		snprintf(tbuf, 11, "\"%02d:%02d:%02d\"", tv -> tm_hour, tv -> tm_min, tv -> tm_sec);
+		preproc_unget_token(pp, token_create(TOK_STR_LIT, tbuf, pp -> lineno, pp -> column, pp -> fn));
+		return 1;
+	}
+	
 	s = symtab_find(pp, mname);
 	if (!s)
 		return 0;