# HG changeset patch # User William Astle # Date 1379788068 21600 # Node ID 9e342c4e4b66a944c657500a2e74b9cd0d44975e # Parent b08787e5b9f3edd229f5ea2857697564b01f1bd0 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. diff -r b08787e5b9f3 -r 9e342c4e4b66 lwcc/README.txt --- 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 diff -r b08787e5b9f3 -r 9e342c4e4b66 lwcc/cpp-main.c --- 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) diff -r b08787e5b9f3 -r 9e342c4e4b66 lwcc/preproc.c --- 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 #include #include +#include #include #include @@ -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;