jrb@petro.UUCP (09/22/87)
I've been toying with ways to make the `HOME' directory for a pile of software a little more portable and the following sure beats the method where you effectively get -> sprintf(buf,"%s/afile","/usr/me"); fopen(buf,"r"); <- but it sure does LOOK wierd! ----- cut here ----- #define FOO "/usr/me stream = fopen(FOO/afile","r"); ----- ereh tuc ----- It works, mostly because file names are "divided" as they are, but is it stylish?! Any takers? Peter? Thanks! Jon ----- Peter and the Wolf? No! -- Peter da Wolf `-_-' Gimme a break! -- 'U` -- Jon Boede ...!{gatech,ihnp4,akgua}!petro!jrb 512/599-1847 2555 N.E. Loop 410, #1403, 78217 "People who are incapable of making decisions are the ones who hit those barrels at freeway exits."
rjchen@phoenix.UUCP (09/24/87)
In article <325@petro.UUCP> jrb@petro.UUCP (Jon Boede) writes: >I've been toying with ways to make the `HOME' directory for a pile of software >a little more portable and the following sure beats the method where you >effectively get -> sprintf(buf,"%s/afile","/usr/me"); fopen(buf,"r"); <- but >it sure does LOOK wierd! > >#define FOO "/usr/me >stream = fopen(FOO/afile","r"); The official ANSI C way of doing it is as follows: #define FOO "/usr/me" stream = fopen(FOO "/afile", "r"); This expands to stream = fopen("/usr/me" "/afile", "r"); which the preprocessor mushes together to make stream = fopen("usr/me/afile", "r") Of course, you need an ANSI-draft-conforming preprocessor first. -- Raymond Chen, BITNET: (preferably) 6101695@pucc, rjchen@pucc ARPA: rjchen@pucc.PRINCETON.EDU UUCP: {allegra}!princeton!pucc!rjchen *** DO NOT REPLACE THIS LINE ***
karl@haddock.UUCP (09/25/87)
In article <325@petro.UUCP> jrb@petro.UUCP (Jon Boede) writes: >#define FOO "/usr/me >stream = fopen(FOO/afile","r"); It isn't portable, and so it's best to avoid this. In pre-ANSI, the best you can do is paste the two pieces together at run-time (with strcat or sprintf), or #define each such path separately (#define FOO_afile "/usr/me/afile" , etc.), but in ANSI C string constants can be pasted at compile-time: #define FOO "/usr/me" stream = fopen(FOO "/afile", "r") Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
karl@haddock.ISC.COM (Karl Heuer) (09/25/87)
In article <763@phoenix.PRINCETON.EDU> rjchen@phoenix.UUCP (Raymond Juimong Chen) writes: >This expands to >stream = fopen("/usr/me" "/afile", "r"); > >which the preprocessor mushes together to make >stream = fopen("usr/me/afile", "r") A minor quibble here. (No, not the missing slash.) In compilers that maintain the traditional separation of cpp from compiler proper, the string pasting is likely to be done in the lexer, not the preprocessor. Otherwise the preprocessor has to avoid situations like ("\12" "3"), for which the naive answer ("\123") is wrong. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
chris@mimsy.UUCP (Chris Torek) (09/26/87)
In article <1237@haddock.ISC.COM> karl@haddock.ISC.COM (Karl Heuer) writes: >... In pre-ANSI [C], the best you can do is paste the two pieces >together at run-time (with strcat or sprintf), or #define each such >path separately ... but in ANSI C string constants can be pasted at >compile-time: > #define FOO "/usr/me" > stream = fopen(FOO "/afile", "r") Or use the following program, e.g., `cc -E foo.c | string > x.c && cc -c x.c && mv x.o foo.o'. I wrote the original version of string on 30 October 1982. This one has been cleaned up a bit. (This can be done as a tiny lex program, but until Van sends out his new lex, we get slow scanners.) static char rcsid[] = "$Header: string.c,v 1.2 87/09/26 01:10:41 chris Exp $"; /* string -- combine adjacent C strings */ #include <stdio.h> #define SQUOTE '\'' #define DQUOTE '"' #define BACKSLASH '\\' /*ARGSUSED*/ main(argc, argv) int argc; char **argv; { register int c; register char *p, *q; char buf[BUFSIZ]; /* process charcters, handling 'x' and "string" "s" */ while ((c = getchar()) != EOF) { switch (c) { case SQUOTE: /* char const */ (void) putchar(c); while ((c = getchar()) != EOF) { (void) putchar(c); if (c == BACKSLASH) { if ((c = getchar()) != EOF) (void) putchar(c); } else if (c == SQUOTE) break; } break; case DQUOTE: /* "string" */ (void) putchar(DQUOTE); more: while ((c = getchar()) != EOF) { if (c == BACKSLASH) { (void) putchar(c); if ((c = getchar()) != EOF) (void) putchar(c); } else if (c == DQUOTE) break; else (void) putchar(c); } /* found the close quote, but might be another str */ p = buf; while ((c = getchar()) == ' ' || c == '\t' || c == '\n') if (p < &buf[sizeof buf]) *p++ = c; if (c == DQUOTE) /* another string */ goto more; if (c != EOF) { /* close previous string and rescan later */ (void) putchar(DQUOTE); ungetc(c, stdin); } /* write buffered whitespace */ for (q = buf; q < p;) (void) putchar(*q++); break; default: /* anything else copied literally */ (void) putchar(c); } } exit(0); } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris