diff --git a/tools/qfcc/acconfig.h b/tools/qfcc/acconfig.h index 0112570d7..2e0651acb 100644 --- a/tools/qfcc/acconfig.h +++ b/tools/qfcc/acconfig.h @@ -8,5 +8,14 @@ /* Define this if you want to use the new parser */ #undef NEW_PARSER +/* Define this to your operating system's path separator character */ +#undef PATH_SEPARATOR + +/* Define this if you want to use the C preprocessor */ +#undef USE_CPP + +/* Define this to the command line for the C preprocessor */ +#undef CPP_NAME + @BOTTOM@ #endif // __config_h_ diff --git a/tools/qfcc/configure.in b/tools/qfcc/configure.in index 7ec47fcee..d8596c6ba 100644 --- a/tools/qfcc/configure.in +++ b/tools/qfcc/configure.in @@ -23,6 +23,9 @@ AC_PROG_CPP AC_PROG_YACC AM_PROG_LEX +CPP_NAME=$ac_cv_prog_CPP +AC_DEFINE_UNQUOTED(CPP_NAME, "$CPP_NAME") + dnl We want warnings, lots of warnings... if test "x$GCC" = xyes; then CFLAGS="$CFLAGS -Wall -Werror" @@ -34,7 +37,7 @@ dnl Checks for libraries. dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(unistd.h) +AC_CHECK_HEADERS(sys/types.h sys/wait.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_ARG_ENABLE(profile, @@ -51,6 +54,8 @@ if test "x$profile" = xyes; then fi fi +AC_DEFINE_UNQUOTED(PATH_SEPARATOR, '/') + dnl Checks for library functions. AC_MSG_CHECKING(for timeGetTime in -lwinmm) @@ -88,13 +93,21 @@ if test "x$HAVE_QF" != xno; then fi AC_ARG_ENABLE(new-parser, - [ --disable-new-parser disable the new parser.]) + [ --disable-new-parser disable the new parser.] +) if test "x$enable_new_parser" != "xno"; then AC_DEFINE(NEW_PARSER) fi AM_CONDITIONAL(NEW_PARSER, test "x$enable_new_parser" != "xno") +AC_ARG_ENABLE(cpp, + [ --enable-cpp Enable use of the C preprocessor.] +) +if test "x$enable_new_parser" = "xyes"; then + AC_DEFINE(USE_CPP) +fi + if test "x$HAVE_QF" = xno; then echo '***' echo '*** You seem to not have the QuakeForge libs & headers installed' diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 2dcc4b0ad..a298ce192 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -30,6 +30,17 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif + +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif + #include #include #include @@ -88,7 +99,7 @@ WriteFiles (void) int i; char filename[1024]; - sprintf (filename, "%s/files.dat", sourcedir); + sprintf (filename, "%s%cfiles.dat", sourcedir, PATH_SEPARATOR); f = fopen (filename, "w"); if (!f) Error ("Couldn't open %s", filename); @@ -1002,26 +1013,87 @@ Options: \n\ // compile all the files while ((src = COM_Parse (src))) { #ifdef NEW_PARSER +#ifdef USE_CPP + pid_t pid; + char *temp1; + char *temp2 = strrchr (argv[0], PATH_SEPARATOR); + char tempname[1024]; + int tempfd; +#endif extern FILE *yyin; int yyparse(void); extern void clear_frame_macros (void); //extern int yydebug; //yydebug = 1; - sprintf (filename, "%s/%s", sourcedir, com_token); + sprintf (filename, "%s%c%s", sourcedir, PATH_SEPARATOR, com_token); if (!options.quiet) printf ("compiling %s\n", filename); +#ifdef USE_CPP + temp1 = getenv ("TMPDIR"); + if ((!temp1) || (!temp1[0])) { + temp1 = getenv ("TEMP"); + if ((!temp1) || (!temp1[0])) { + temp1 = "/tmp"; + } + } + + snprintf (tempname, sizeof (tempname), "%s%c%sXXXXXX", temp1, PATH_SEPARATOR, temp2 ? temp2 + 1 : argv[0]); + tempfd = mkstemp (tempname); + + if ((pid = fork ()) == -1) { + perror ("fork"); + return 1; + } + + if (!pid) { // we're a child, check for abuse + execlp ("cpp", "-D__QFCC__=1", "-o", tempname, filename, NULL); + printf ("Child shouldn't reach here\n"); + exit (1); + } else { // give parental guidance (or bury it in the back yard) + int status; + pid_t rc; + +// printf ("pid = %d\n", pid); + if ((rc = waitpid (0, &status, 0 | WUNTRACED)) != pid) { + if (rc == -1) { + perror ("wait"); + exit (1); + } + printf ("*** Uhh, dude, the wrong child (%d) just died.\n*** Don't ask me, I can't figure it out either.\n", rc); + exit (1); + } + if (WIFEXITED (status)) { + if (WEXITSTATUS (status)) { + printf ("cpp returned error code %d", WEXITSTATUS (status)); + exit (1); + } + } else { + printf ("cpp returned prematurely."); + exit (1); + } + } + + yyin = fdopen (tempfd, "r+t"); +#else yyin = fopen (filename, "rt"); +#endif s_file = ReuseString (filename); pr_source_line = 1; clear_frame_macros (); if (yyparse () || pr_error_count) return 1; fclose (yyin); +#ifdef USE_CPP + if (unlink (tempname)) { + perror ("unlink"); + exit (1); + } +#endif #else char *src2; - sprintf (filename, "%s/%s", sourcedir, com_token); + sprintf (filename, "%s%c%s", sourcedir, PATH_SEPARATOR, com_token); if (!options.quiet) printf ("compiling %s\n", filename); LoadFile (filename, (void *) &src2);