C pre-processor - strings

Lee Naish lee at munnari.OZ
Wed Sep 19 07:19:57 AEST 1984


I have another problem which the C pre-processor should be able to solve but
cannot (I think).  Suppose you have a Makefile containing the following line
(which may be changed when ported):

LIB=/usr/lib/yourlib

In your program, you want to use the strings "/usr/lib/yourlib/startup",
"...../lib", "...../db" etc.  The nice way to do this would to define one
macro, LIB, and create all the strings using cpp:

CFLAGS= -DLIB=$(LIB) ....

I dont think cpp is powerful enough for this.  Some possibilities:

#define STARTUP "LIB/startup"	/* LIB doesnt get expanded in #define	*/
... STARTUP			/* or later, because of the quotes	*/

#define STARTUP(l) "l/startup"	/* STARTUP is expanded first, then the	*/
... STARTUP(LIB)		/* quotes prevent expansion of LIB	*/

#define Q(dummy) "
... Q(d)LIB/startup"		/* Q is expanded first - same problem	*/

The problem would be solvable if the macros were expanded
	1) inside #defines,
	2) bottom up instead of top down,
	3) right to left instead of left to right or
	4) simultaneously (Q(d) and LIB expanded at the same time) instead
	   of sequentially.
I prefer 4) - it is reasonably natural and increases efficiency.

Another solution would be to have some reasonable escape convention (essential
in any real macro-processor):

..... \"LIB/startup"		/* \ is gobbled by cpp, but LIB is expanded*/

This could also work with commas and parentheses, which cause problems similar
to quotes.  It is also guaranteed not to break any existing programs.  Maybe
``\ '' could be used instead of your favourite /**/ hack for concatenate too.

N/Troff devotees should love this solution - to get a backslash into
an escaped string you need four backslashes - or is it eight?  We could even
make it depend on the context (in-line or #define) or the number of passes the
processor needes for that line . . . .

	P.S.	Please only send follow-ups relevant to cpp.  Send comments
		about strcat(), Makefiles with heaps of -D's, -D's with
		unmatched quotes (this is not general enough if you want a
		macro in the middle of a string) or echo ... >> paths.h, etc,
		to /dev/null.

						Lee Naish

					ACSNET:  lee:mulga
					UUCP:    {decvax,vax135}!mulga!lee
					ARPANET: decvax!mulga!lee at Berkeley



More information about the Comp.lang.c mailing list