mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-06-04 02:20:53 +00:00
[qfcc] Implement #include and search paths
Other than some trouble with line comments and continuation lines, it seems to work nicely.
This commit is contained in:
parent
f1f0a4a260
commit
ffb2514e75
9 changed files with 480 additions and 160 deletions
|
@ -34,9 +34,15 @@
|
||||||
struct dstring_s;
|
struct dstring_s;
|
||||||
|
|
||||||
void parse_cpp_name (void);
|
void parse_cpp_name (void);
|
||||||
void add_cpp_sysinc (const char *arg);
|
|
||||||
void add_cpp_undef (const char *arg);
|
void add_cpp_undef (const char *arg);
|
||||||
void add_cpp_def (const char *arg);
|
void add_cpp_def (const char *arg);
|
||||||
|
|
||||||
|
int cpp_include (const char *opt, const char *arg);
|
||||||
|
void cpp_define (const char *arg);
|
||||||
|
void cpp_undefine (const char *arg);
|
||||||
|
const char *cpp_find_file (const char *name, int quote, bool *is_system);
|
||||||
|
void cpp_set_quote_file (const char *path);
|
||||||
|
|
||||||
void intermediate_file (struct dstring_s *ifile, const char *filename,
|
void intermediate_file (struct dstring_s *ifile, const char *filename,
|
||||||
const char *ext, int local);
|
const char *ext, int local);
|
||||||
FILE *preprocess_file (const char *filename, const char *ext);
|
FILE *preprocess_file (const char *filename, const char *ext);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
typedef struct expr_s expr_t;
|
typedef struct expr_s expr_t;
|
||||||
|
|
||||||
|
void set_line_file (int line, const char *file, int flags);
|
||||||
void line_info (const expr_t *line_expr, const char *text,
|
void line_info (const expr_t *line_expr, const char *text,
|
||||||
const expr_t *flags_epxr);
|
const expr_t *flags_epxr);
|
||||||
pr_lineno_t *new_lineno (void);
|
pr_lineno_t *new_lineno (void);
|
||||||
|
|
|
@ -91,6 +91,8 @@ void rua_else (bool pass, const char *tok, void *scanner);
|
||||||
void rua_endif (void *scanner);
|
void rua_endif (void *scanner);
|
||||||
bool rua_defined (const char *sym, void *scanner);
|
bool rua_defined (const char *sym, void *scanner);
|
||||||
void rua_undefine (const char *sym, void *scanner);
|
void rua_undefine (const char *sym, void *scanner);
|
||||||
|
void rua_include_file (const char *name, void *scanner);
|
||||||
|
void rua_embed_file (const char *name, void *scanner);
|
||||||
|
|
||||||
#include "tools/qfcc/source/pre-parse.h"
|
#include "tools/qfcc/source/pre-parse.h"
|
||||||
|
|
||||||
|
|
|
@ -53,27 +53,44 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
|
#include "QF/sys.h"
|
||||||
|
#include "QF/va.h"
|
||||||
|
|
||||||
#include "tools/qfcc/include/cpp.h"
|
#include "tools/qfcc/include/cpp.h"
|
||||||
|
#include "tools/qfcc/include/debug.h"
|
||||||
#include "tools/qfcc/include/diagnostic.h"
|
#include "tools/qfcc/include/diagnostic.h"
|
||||||
#include "tools/qfcc/include/options.h"
|
#include "tools/qfcc/include/options.h"
|
||||||
|
#include "tools/qfcc/include/qfcc.h"
|
||||||
|
#include "tools/qfcc/include/strpool.h"
|
||||||
|
|
||||||
typedef struct cpp_arg_s {
|
typedef struct cpp_arg_s {
|
||||||
struct cpp_arg_s *next;
|
struct cpp_arg_s *next;
|
||||||
const char *arg;
|
const char *arg;
|
||||||
} cpp_arg_t;
|
} cpp_arg_t;
|
||||||
|
|
||||||
cpp_arg_t *cpp_arg_list;
|
typedef struct cpp_func_s {
|
||||||
cpp_arg_t **cpp_arg_tail = &cpp_arg_list;
|
const char *name;
|
||||||
cpp_arg_t *cpp_def_list;
|
int (*func) (const char *opt, const char *arg);
|
||||||
cpp_arg_t **cpp_def_tail = &cpp_def_list;
|
} cpp_func_t;
|
||||||
cpp_arg_t *cpp_undef_list;
|
|
||||||
cpp_arg_t **cpp_undef_tail = &cpp_undef_list;
|
static cpp_arg_t *cpp_quote_list, **cpp_quote_tail = &cpp_quote_list;
|
||||||
cpp_arg_t *cpp_sysinc_list;
|
static cpp_arg_t *cpp_include_list,**cpp_include_tail= &cpp_include_list;
|
||||||
cpp_arg_t **cpp_sysinc_tail = &cpp_sysinc_list;
|
static cpp_arg_t *cpp_system_list, **cpp_system_tail = &cpp_system_list;
|
||||||
const char **cpp_argv;
|
static cpp_arg_t *cpp_after_list, **cpp_after_tail = &cpp_after_list;
|
||||||
const char *cpp_name = CPP_NAME;
|
|
||||||
|
static const char *cpp_prefix = "";
|
||||||
|
static const char *cpp_sysroot = QFCC_INCLUDE_PATH;
|
||||||
|
static const char *cpp_quote_start = 0;
|
||||||
|
|
||||||
|
static cpp_arg_t *cpp_arg_list, **cpp_arg_tail = &cpp_arg_list;
|
||||||
|
static cpp_arg_t *cpp_def_list, **cpp_def_tail = &cpp_def_list;
|
||||||
|
static cpp_arg_t *cpp_undef_list, **cpp_undef_tail = &cpp_undef_list;
|
||||||
|
static cpp_arg_t *cpp_sysinc_list, **cpp_sysinc_tail = &cpp_sysinc_list;
|
||||||
|
|
||||||
|
static const char **cpp_argv;
|
||||||
static int cpp_argc = 0;
|
static int cpp_argc = 0;
|
||||||
|
|
||||||
|
const char *cpp_name = CPP_NAME;
|
||||||
dstring_t *tempname;
|
dstring_t *tempname;
|
||||||
|
|
||||||
static const char **
|
static const char **
|
||||||
|
@ -86,66 +103,200 @@ append_cpp_args (const char **arg, cpp_arg_t *arg_list)
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CPP_ADD(list, a) \
|
||||||
|
do { \
|
||||||
|
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t)); \
|
||||||
|
*(cpp_arg) = (cpp_arg_t) { .arg = save_string (a) }; \
|
||||||
|
*cpp_##list##_tail = cpp_arg; \
|
||||||
|
cpp_##list##_tail = &cpp_arg->next; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_cpp_arg (const char *arg)
|
add_cpp_arg (const char *arg)
|
||||||
{
|
{
|
||||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
CPP_ADD (arg, arg);
|
||||||
cpp_arg->next = 0;
|
|
||||||
cpp_arg->arg = arg;
|
|
||||||
*cpp_arg_tail = cpp_arg;
|
|
||||||
cpp_arg_tail = &(*cpp_arg_tail)->next;
|
|
||||||
cpp_argc++;
|
cpp_argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
add_cpp_sysinc (const char *arg)
|
add_cpp_sysinc (const char *arg)
|
||||||
{
|
{
|
||||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
CPP_ADD (sysinc, arg);
|
||||||
cpp_arg->next = 0;
|
|
||||||
cpp_arg->arg = arg;
|
|
||||||
*cpp_sysinc_tail = cpp_arg;
|
|
||||||
cpp_sysinc_tail = &(*cpp_sysinc_tail)->next;
|
|
||||||
cpp_argc++;
|
cpp_argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
add_cpp_undef (const char *arg)
|
add_cpp_undef (const char *arg)
|
||||||
{
|
{
|
||||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
CPP_ADD (undef, arg);
|
||||||
cpp_arg->next = 0;
|
|
||||||
cpp_arg->arg = arg;
|
|
||||||
*cpp_undef_tail = cpp_arg;
|
|
||||||
cpp_undef_tail = &(*cpp_undef_tail)->next;
|
|
||||||
cpp_argc++;
|
cpp_argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
add_cpp_def (const char *arg)
|
add_cpp_def (const char *arg)
|
||||||
{
|
{
|
||||||
cpp_arg_t *cpp_def = malloc (sizeof (cpp_arg_t));
|
CPP_ADD (def, arg);
|
||||||
cpp_def->next = 0;
|
|
||||||
cpp_def->arg = arg;
|
|
||||||
*cpp_def_tail = cpp_def;
|
|
||||||
cpp_def_tail = &(*cpp_def_tail)->next;
|
|
||||||
cpp_argc++;
|
cpp_argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_I (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!arg) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!strcmp (arg, "-")) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
CPP_ADD (include, arg);
|
||||||
|
add_cpp_def (save_string ("-I"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_dirafter (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!arg) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
CPP_ADD (quote, arg);
|
||||||
|
add_cpp_def (save_string ("-idirafter"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_prefix (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
cpp_prefix = save_string (arg);
|
||||||
|
add_cpp_def (save_string ("-iprefix"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_quote (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!arg) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
CPP_ADD (quote, arg);
|
||||||
|
add_cpp_def (save_string ("-iquote"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_sysroot (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
cpp_sysroot = save_string (arg);
|
||||||
|
add_cpp_def (save_string ("-isysroot"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_system (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!arg) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
CPP_ADD (system, arg);
|
||||||
|
add_cpp_def (save_string ("-isystem"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_withprefix (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!arg) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
arg = va (0, "%s%s", cpp_prefix, arg);
|
||||||
|
CPP_ADD (after, arg);
|
||||||
|
add_cpp_def (save_string ("-iwithprefix"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cpp_include_withprefixbefore (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
if (!arg) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
arg = va (0, "%s%s", cpp_prefix, arg);
|
||||||
|
CPP_ADD (include, arg);
|
||||||
|
add_cpp_def (save_string ("-iwithprefixbefore"));
|
||||||
|
add_cpp_def (save_string (arg));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CPP_INCLUDE(name) {#name, cpp_include_##name}
|
||||||
|
int
|
||||||
|
cpp_include (const char *opt, const char *arg)
|
||||||
|
{
|
||||||
|
static cpp_func_t include_funcs[] = {
|
||||||
|
CPP_INCLUDE (I),
|
||||||
|
CPP_INCLUDE (prefix),
|
||||||
|
CPP_INCLUDE (dirafter),
|
||||||
|
CPP_INCLUDE (quote),
|
||||||
|
CPP_INCLUDE (sysroot),
|
||||||
|
CPP_INCLUDE (system),
|
||||||
|
CPP_INCLUDE (withprefix),
|
||||||
|
CPP_INCLUDE (withprefixbefore),
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
for (int i = 0; include_funcs[i].name; i++) {
|
||||||
|
if (!strcmp (opt, include_funcs[i].name)) {
|
||||||
|
return include_funcs[i].func (opt, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#undef CPP_INCLUDE
|
||||||
|
|
||||||
|
void cpp_define (const char *arg)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (!cpp_macros) {
|
||||||
|
cpp_macros = new_symtab (stab_global);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
arg = va (0, "-D%s", arg);
|
||||||
|
CPP_ADD (def, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpp_undefine (const char *arg)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (cpp_macros) {
|
||||||
|
auto sym = symtab_lookup (cpp_macros, arg);
|
||||||
|
if (sym) {
|
||||||
|
symtab_removesymbol (cpp_macros, sym);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
arg = va (0, "-D%s", arg);
|
||||||
|
CPP_ADD (undef, arg);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
parse_cpp_name (void)
|
parse_cpp_name (void)
|
||||||
{
|
{
|
||||||
char *n;
|
char *n, *e;
|
||||||
|
|
||||||
if (!cpp_name)
|
if (!cpp_name || !*cpp_name) {
|
||||||
return;
|
return;
|
||||||
n = strdup (cpp_name);
|
}
|
||||||
while (*n) {
|
|
||||||
while (*n && *n == ' ')
|
for (n = strdup (cpp_name); *n; n = e) {
|
||||||
n++;
|
for (; *n && *n == ' '; n++) continue;
|
||||||
|
for (e = n; *e && *e != ' '; e++) continue;
|
||||||
|
*e++ = 0;
|
||||||
add_cpp_arg (n);
|
add_cpp_arg (n);
|
||||||
while (*n && *n != ' ')
|
|
||||||
n++;
|
|
||||||
if (*n)
|
|
||||||
*n++ = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,126 +381,206 @@ intermediate_file (dstring_t *ifile, const char *filename, const char *ext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *
|
static FILE *
|
||||||
preprocess_file (const char *filename, const char *ext)
|
run_cpp (const char *filename, const char *ext)
|
||||||
{
|
{
|
||||||
|
add_cpp_sysinc ("-isystem");
|
||||||
|
add_cpp_sysinc (QFCC_INCLUDE_PATH);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int tempfd = 0;
|
int tempfd = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cpp_name) {
|
intermediate_file (tempname, filename, ext ? ext : "p", 0);
|
||||||
intermediate_file (tempname, filename, ext ? ext : "p", 0);
|
build_cpp_args (filename, tempname->str);
|
||||||
build_cpp_args (filename, tempname->str);
|
if (!cpp_argv[0]) {
|
||||||
if (!cpp_argv[0]) {
|
internal_error(0, "cpp_argv[0] is null");
|
||||||
internal_error(0, "cpp_argv[0] is null");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (!options.save_temps && !options.preprocess_only)
|
if (!options.save_temps && !options.preprocess_only)
|
||||||
mktemp (tempname->str);
|
mktemp (tempname->str);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
FILE *tmp = fopen (tempname->str, "wb");
|
||||||
FILE *tmp = fopen (tempname->str, "wb");
|
if (tmp == NULL) {
|
||||||
if (tmp == NULL) {
|
fprintf (stderr, "%s: qfcc was unable to open\n",
|
||||||
fprintf (stderr, "%s: qfcc was unable to open\n",
|
tempname->str);
|
||||||
tempname->str);
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
fclose (tmp);
|
||||||
fclose (tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
int status;
|
||||||
int status;
|
|
||||||
|
|
||||||
if (options.verbosity > 1) {
|
if (options.verbosity > 1) {
|
||||||
const char **a;
|
const char **a;
|
||||||
for (a = cpp_argv; *a; a++)
|
for (a = cpp_argv; *a; a++)
|
||||||
printf ("%s ", *a);
|
printf ("%s ", *a);
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
status = spawnvp (_P_WAIT, cpp_argv[0], (char **) cpp_argv);
|
status = spawnvp (_P_WAIT, cpp_argv[0], (char **) cpp_argv);
|
||||||
#else
|
#else
|
||||||
status = spawnvp (_P_WAIT, cpp_argv[0], cpp_argv);
|
status = spawnvp (_P_WAIT, cpp_argv[0], cpp_argv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||||
filename,
|
filename,
|
||||||
status);
|
status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (options.preprocess_only)
|
if (options.preprocess_only)
|
||||||
return 0;
|
return 0;
|
||||||
return fopen (tempname->str, "rb");
|
return fopen (tempname->str, "rb");
|
||||||
#else
|
#else
|
||||||
if (!options.save_temps && !options.preprocess_only)
|
if (!options.save_temps && !options.preprocess_only)
|
||||||
tempfd = mkstemp (tempname->str);
|
tempfd = mkstemp (tempname->str);
|
||||||
|
|
||||||
if ((pid = fork ()) == -1) {
|
if ((pid = fork ()) == -1) {
|
||||||
perror ("fork");
|
perror ("fork");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
if (!pid) {
|
||||||
|
// we're a child, check for abuse
|
||||||
|
if (options.verbosity > 1) {
|
||||||
|
const char **a;
|
||||||
|
for (a = cpp_argv; *a; a++)
|
||||||
|
printf ("%s ", *a);
|
||||||
|
puts("");
|
||||||
}
|
}
|
||||||
if (!pid) {
|
|
||||||
// we're a child, check for abuse
|
|
||||||
if (options.verbosity > 1) {
|
|
||||||
const char **a;
|
|
||||||
for (a = cpp_argv; *a; a++)
|
|
||||||
printf ("%s ", *a);
|
|
||||||
puts("");
|
|
||||||
}
|
|
||||||
#ifdef HAVE_EXECVP
|
#ifdef HAVE_EXECVP
|
||||||
execvp (cpp_argv[0], (char **)cpp_argv);
|
execvp (cpp_argv[0], (char **)cpp_argv);
|
||||||
#else
|
#else
|
||||||
execve (cpp_argv[0], (char **)cpp_argv, environ);
|
execve (cpp_argv[0], (char **)cpp_argv, environ);
|
||||||
#endif
|
#endif
|
||||||
perror (cpp_argv[0]);
|
perror (cpp_argv[0]);
|
||||||
exit (1);
|
exit (1);
|
||||||
} else {
|
} else {
|
||||||
// give parental guidance (or bury it in the back yard)
|
// give parental guidance (or bury it in the back yard)
|
||||||
int status;
|
int status;
|
||||||
pid_t rc;
|
pid_t rc;
|
||||||
|
|
||||||
// printf ("pid = %d\n", pid);
|
// printf ("pid = %d\n", pid);
|
||||||
#ifdef HAVE_WAITPID
|
#ifdef HAVE_WAITPID
|
||||||
rc = waitpid (0, &status, 0 | WUNTRACED);
|
rc = waitpid (0, &status, 0 | WUNTRACED);
|
||||||
#else
|
#else
|
||||||
rc = wait (&status);
|
rc = wait (&status);
|
||||||
#endif
|
#endif
|
||||||
if ((rc) != pid) {
|
if ((rc) != pid) {
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
perror ("wait");
|
perror ("wait");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fprintf (stderr, "%s: The wrong child (%ld) died. Don't ask me, I don't know either.\n",
|
|
||||||
this_program,
|
|
||||||
(long) rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (WIFEXITED (status)) {
|
fprintf (stderr, "%s: The wrong child (%ld) died. Don't ask me, I don't know either.\n",
|
||||||
if (WEXITSTATUS (status)) {
|
this_program,
|
||||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
(long) rc);
|
||||||
filename,
|
return 0;
|
||||||
WEXITSTATUS (status));
|
}
|
||||||
return 0;
|
if (WIFEXITED (status)) {
|
||||||
}
|
if (WEXITSTATUS (status)) {
|
||||||
} else {
|
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||||
fprintf (stderr, "%s: cpp returned prematurely.\n", filename);
|
filename,
|
||||||
return 0;
|
WEXITSTATUS (status));
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
if (options.preprocess_only)
|
} else {
|
||||||
|
fprintf (stderr, "%s: cpp returned prematurely.\n", filename);
|
||||||
return 0;
|
return 0;
|
||||||
else if (options.save_temps)
|
|
||||||
return fopen (tempname->str, "rb");
|
|
||||||
else {
|
|
||||||
return fdopen (tempfd, "rb");
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return fopen (filename, "rb");
|
if (options.preprocess_only) {
|
||||||
|
return 0;
|
||||||
|
} else if (options.save_temps) {
|
||||||
|
set_line_file (1, tempname->str, 0);
|
||||||
|
return fopen (tempname->str, "rb");
|
||||||
|
} else {
|
||||||
|
set_line_file (1, "1", 0);
|
||||||
|
return fdopen (tempfd, "rb");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *
|
||||||
|
preprocess_file (const char *filename, const char *ext)
|
||||||
|
{
|
||||||
|
if (cpp_name) {
|
||||||
|
return run_cpp (filename, ext);
|
||||||
|
} else {
|
||||||
|
set_line_file (1, filename, 0);
|
||||||
|
return fopen (filename, "rb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
test_path (const char *path, const char *name)
|
||||||
|
{
|
||||||
|
static dstring_t *fullpath;
|
||||||
|
if (!fullpath) {
|
||||||
|
fullpath = dstring_new ();
|
||||||
|
}
|
||||||
|
dstring_copystr (fullpath, path);
|
||||||
|
if (fullpath->size > 1 && fullpath->str[fullpath->size - 2] != '/') {
|
||||||
|
dstring_appendstr (fullpath, "/");
|
||||||
|
}
|
||||||
|
dstring_appendstr (fullpath, name);
|
||||||
|
if (Sys_FileExists (fullpath->str) == 0) {
|
||||||
|
return fullpath->str;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
cpp_find_file (const char *name, int quote, bool *is_system)
|
||||||
|
{
|
||||||
|
*is_system = false;
|
||||||
|
if (*name == '/') {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
const char *path;
|
||||||
|
if (quote == '"') {
|
||||||
|
if (cpp_quote_start && (path = test_path (cpp_quote_start, name))) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
for (auto dir = cpp_quote_list; dir; dir = dir->next) {
|
||||||
|
if ((path = test_path (cpp_quote_start, dir->arg))) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto dir = cpp_include_list; dir; dir = dir->next) {
|
||||||
|
if ((path = test_path (dir->arg, name))) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*is_system = true;
|
||||||
|
for (auto dir = cpp_system_list; dir; dir = dir->next) {
|
||||||
|
if ((path = test_path (dir->arg, name))) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto dir = cpp_after_list; dir; dir = dir->next) {
|
||||||
|
if ((path = test_path (dir->arg, name))) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cpp_set_quote_file (const char *path)
|
||||||
|
{
|
||||||
|
if (!path) {
|
||||||
|
cpp_quote_start = pr.comp_dir;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const char *e = strrchr (path, '/');
|
||||||
|
if (!e) {
|
||||||
|
cpp_quote_start = pr.comp_dir;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cpp_quote_start = save_substring (path, e - path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "QF/alloc.h"
|
#include "QF/alloc.h"
|
||||||
#include "QF/progs/pr_comp.h"
|
#include "QF/progs/pr_comp.h"
|
||||||
|
|
||||||
|
#include "tools/qfcc/include/cpp.h"
|
||||||
#include "tools/qfcc/include/debug.h"
|
#include "tools/qfcc/include/debug.h"
|
||||||
#include "tools/qfcc/include/def.h"
|
#include "tools/qfcc/include/def.h"
|
||||||
#include "tools/qfcc/include/defspace.h"
|
#include "tools/qfcc/include/defspace.h"
|
||||||
|
@ -81,6 +82,8 @@ pop_source_file (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tmp = pr.srcline_stack;
|
tmp = pr.srcline_stack;
|
||||||
|
pr.source_file = tmp->source_file;
|
||||||
|
pr.source_line = tmp->source_line;
|
||||||
pr.srcline_stack = tmp->next;
|
pr.srcline_stack = tmp->next;
|
||||||
FREE (srclines, tmp);
|
FREE (srclines, tmp);
|
||||||
}
|
}
|
||||||
|
@ -96,6 +99,26 @@ add_source_file (const char *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_line_file (int line, const char *file, int flags)
|
||||||
|
{
|
||||||
|
switch (flags & 3) {
|
||||||
|
case 1:
|
||||||
|
push_source_file ();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pop_source_file ();
|
||||||
|
file = GETSTR (pr.source_file);
|
||||||
|
line = pr.source_line;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pr.source_line = line;
|
||||||
|
if (file) {
|
||||||
|
add_source_file (file);
|
||||||
|
cpp_set_quote_file (file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
line_info (const expr_t *line_expr, const char *file, const expr_t *flags_expr)
|
line_info (const expr_t *line_expr, const char *file, const expr_t *flags_expr)
|
||||||
{
|
{
|
||||||
|
@ -109,18 +132,7 @@ line_info (const expr_t *line_expr, const char *file, const expr_t *flags_expr)
|
||||||
}
|
}
|
||||||
file = make_string (file, 0);
|
file = make_string (file, 0);
|
||||||
}
|
}
|
||||||
switch (flags & 3) {
|
set_line_file (line, file, flags);
|
||||||
case 1:
|
|
||||||
push_source_file ();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
pop_source_file ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pr.source_line = line;
|
|
||||||
if (file) {
|
|
||||||
add_source_file (file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_lineno_t *
|
pr_lineno_t *
|
||||||
|
|
|
@ -140,6 +140,7 @@ static const char *short_options =
|
||||||
"F" // generate files.dat
|
"F" // generate files.dat
|
||||||
"g" // debug
|
"g" // debug
|
||||||
"h" // help
|
"h" // help
|
||||||
|
"i::" // set includes
|
||||||
"I:" // set includes
|
"I:" // set includes
|
||||||
"L:" // lib path
|
"L:" // lib path
|
||||||
"l:" // lib file
|
"l:" // lib file
|
||||||
|
@ -607,8 +608,9 @@ DecodeArgs (int argc, char **argv)
|
||||||
add_cpp_undef ("-undef");
|
add_cpp_undef ("-undef");
|
||||||
add_cpp_undef ("-nostdinc");
|
add_cpp_undef ("-nostdinc");
|
||||||
add_cpp_undef ("-fno-extended-identifiers");
|
add_cpp_undef ("-fno-extended-identifiers");
|
||||||
add_cpp_def ("-D__QFCC__=1");
|
|
||||||
add_cpp_def ("-D__QUAKEC__=1");
|
cpp_define ("__QFCC__");
|
||||||
|
cpp_define ("__QUAKEC__");
|
||||||
|
|
||||||
sourcedir = "";
|
sourcedir = "";
|
||||||
progs_src = "progs.src";
|
progs_src = "progs.src";
|
||||||
|
@ -740,7 +742,7 @@ DecodeArgs (int argc, char **argv)
|
||||||
options.save_temps = true;
|
options.save_temps = true;
|
||||||
break;
|
break;
|
||||||
case 'D': // defines for cpp
|
case 'D': // defines for cpp
|
||||||
add_cpp_def (nva ("%s%s", "-D", optarg));
|
cpp_define (optarg);
|
||||||
break;
|
break;
|
||||||
case 'E': // defines for cpp
|
case 'E': // defines for cpp
|
||||||
saw_E = 1;
|
saw_E = 1;
|
||||||
|
@ -751,11 +753,21 @@ DecodeArgs (int argc, char **argv)
|
||||||
add_cpp_def (nva ("%s", "-include"));
|
add_cpp_def (nva ("%s", "-include"));
|
||||||
add_cpp_def (nva ("%s", optarg));
|
add_cpp_def (nva ("%s", optarg));
|
||||||
break;
|
break;
|
||||||
|
case 'i': // includes
|
||||||
|
{
|
||||||
|
int o = cpp_include (optarg, argv[optind]);
|
||||||
|
if (o < 0) {
|
||||||
|
usage (1);
|
||||||
|
} else {
|
||||||
|
optind += o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'I': // includes
|
case 'I': // includes
|
||||||
add_cpp_def (nva ("%s%s", "-I", optarg));
|
cpp_include ("I", optarg);
|
||||||
break;
|
break;
|
||||||
case 'U': // undefines
|
case 'U': // undefines
|
||||||
add_cpp_def (nva ("%s%s", "-U", optarg));
|
cpp_undefine (optarg);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
options.preprocess_only = 1;
|
options.preprocess_only = 1;
|
||||||
|
@ -857,8 +869,6 @@ DecodeArgs (int argc, char **argv)
|
||||||
|
|
||||||
// add the default paths
|
// add the default paths
|
||||||
if (!options.no_default_paths) {
|
if (!options.no_default_paths) {
|
||||||
add_cpp_sysinc ("-isystem");
|
|
||||||
add_cpp_sysinc (QFCC_INCLUDE_PATH);
|
|
||||||
linker_add_path (QFCC_LIB_PATH);
|
linker_add_path (QFCC_LIB_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,38 +173,53 @@ start
|
||||||
|
|
||||||
directive_list
|
directive_list
|
||||||
: /*empty*/
|
: /*empty*/
|
||||||
| directive EOD { rua_end_directive (scanner); } directive_list
|
| directive directive_list
|
||||||
;
|
;
|
||||||
|
|
||||||
|
eod : EOD { rua_end_directive (scanner); } ;
|
||||||
|
|
||||||
directive
|
directive
|
||||||
: INCLUDE expand string extra_warn
|
: INCLUDE expand string extra_warn eod { rua_include_file ($3, scanner); }
|
||||||
| EMBED expand string extra_ignore
|
| EMBED expand string extra_ignore eod { rua_embed_file ($3, scanner); }
|
||||||
| DEFINE ID <macro> { $$ = rua_start_macro ($2, false, scanner); }
|
| DEFINE ID <macro> { $$ = rua_start_macro ($2, false, scanner); }
|
||||||
body { rua_macro_finish ($body, scanner); }
|
body { rua_macro_finish ($body, scanner); }
|
||||||
|
eod
|
||||||
| DEFINE IDp <macro> { $$ = rua_start_macro ($2, true, scanner); }
|
| DEFINE IDp <macro> { $$ = rua_start_macro ($2, true, scanner); }
|
||||||
params ')' <macro> { $$ = rua_end_params ($3, scanner); }
|
params ')' <macro> { $$ = rua_end_params ($3, scanner); }
|
||||||
body { rua_macro_finish ($body, scanner); }
|
body { rua_macro_finish ($body, scanner); }
|
||||||
|
eod
|
||||||
| UNDEF ID extra_warn { rua_undefine ($2, scanner); }
|
| UNDEF ID extra_warn { rua_undefine ($2, scanner); }
|
||||||
|
eod
|
||||||
| ERROR text { error (0, "%s", $text->str); dstring_delete ($text); }
|
| ERROR text { error (0, "%s", $text->str); dstring_delete ($text); }
|
||||||
|
eod
|
||||||
| WARNING text { warning (0, "%s", $text->str); dstring_delete ($text); }
|
| WARNING text { warning (0, "%s", $text->str); dstring_delete ($text); }
|
||||||
|
eod
|
||||||
| PRAGMA expand { rua_start_pragma (scanner); }
|
| PRAGMA expand { rua_start_pragma (scanner); }
|
||||||
pragma_params { pragma_process (); }
|
pragma_params { pragma_process (); }
|
||||||
|
eod
|
||||||
| LINE expand expr extra_warn { line_info ($3, 0, 0); }
|
| LINE expand expr extra_warn { line_info ($3, 0, 0); }
|
||||||
|
eod
|
||||||
| LINE expand expr string line_expr extra_warn { line_info ($3, $4, $5); }
|
| LINE expand expr string line_expr extra_warn { line_info ($3, $4, $5); }
|
||||||
|
eod
|
||||||
| IF expand expr { rua_if (expr_long ($3), scanner); }
|
| IF expand expr { rua_if (expr_long ($3), scanner); }
|
||||||
|
eod
|
||||||
| IFDEF ID extra_warn { rua_if (rua_defined ($2, scanner), scanner); }
|
| IFDEF ID extra_warn { rua_if (rua_defined ($2, scanner), scanner); }
|
||||||
|
eod
|
||||||
| IFNDEF ID extra_warn { rua_if (!rua_defined ($2, scanner), scanner); }
|
| IFNDEF ID extra_warn { rua_if (!rua_defined ($2, scanner), scanner); }
|
||||||
|
eod
|
||||||
| ELSE extra_warn { rua_else (true, "else", scanner); }
|
| ELSE extra_warn { rua_else (true, "else", scanner); }
|
||||||
|
eod
|
||||||
| ELIF expand expr { rua_else (expr_long ($3), "elif", scanner); }
|
| ELIF expand expr { rua_else (expr_long ($3), "elif", scanner); }
|
||||||
|
eod
|
||||||
| ELIFDEF ID extra_warn
|
| ELIFDEF ID extra_warn
|
||||||
{
|
{ rua_else (rua_defined ($2, scanner), "elifdef", scanner); }
|
||||||
rua_else (rua_defined ($2, scanner), "elifdef", scanner);
|
eod
|
||||||
}
|
|
||||||
| ELIFNDEF ID extra_warn
|
| ELIFNDEF ID extra_warn
|
||||||
{
|
{ rua_else (!rua_defined ($2, scanner), "elifndef", scanner); }
|
||||||
rua_else (!rua_defined ($2, scanner), "elifndef", scanner);
|
eod
|
||||||
}
|
| ENDIF extra_warn
|
||||||
| ENDIF extra_warn { rua_endif (scanner); }
|
{ rua_endif (scanner); }
|
||||||
|
eod
|
||||||
;
|
;
|
||||||
|
|
||||||
extra_warn
|
extra_warn
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
#include <QF/va.h>
|
#include <QF/va.h>
|
||||||
|
|
||||||
#include "tools/qfcc/include/class.h"
|
#include "tools/qfcc/include/class.h"
|
||||||
|
#include "tools/qfcc/include/cpp.h"
|
||||||
#include "tools/qfcc/include/debug.h"
|
#include "tools/qfcc/include/debug.h"
|
||||||
#include "tools/qfcc/include/diagnostic.h"
|
#include "tools/qfcc/include/diagnostic.h"
|
||||||
#include "tools/qfcc/include/expr.h"
|
#include "tools/qfcc/include/expr.h"
|
||||||
|
@ -96,6 +97,7 @@ typedef struct {
|
||||||
typedef struct DARRAY_TYPE (rua_cond_t) rua_cond_stack_t;
|
typedef struct DARRAY_TYPE (rua_cond_t) rua_cond_stack_t;
|
||||||
typedef struct DARRAY_TYPE (rua_expr_t) rua_expr_stack_t;
|
typedef struct DARRAY_TYPE (rua_expr_t) rua_expr_stack_t;
|
||||||
typedef struct DARRAY_TYPE (rua_macro_t *) rua_macro_list_t;
|
typedef struct DARRAY_TYPE (rua_macro_t *) rua_macro_list_t;
|
||||||
|
typedef struct DARRAY_TYPE (YY_BUFFER_STATE) rua_include_stack_t;
|
||||||
|
|
||||||
typedef struct rua_extra_s {
|
typedef struct rua_extra_s {
|
||||||
int start_state;
|
int start_state;
|
||||||
|
@ -108,6 +110,7 @@ typedef struct rua_extra_s {
|
||||||
rua_cond_stack_t cond_stack;
|
rua_cond_stack_t cond_stack;
|
||||||
rua_expr_stack_t expr_stack;
|
rua_expr_stack_t expr_stack;
|
||||||
rua_macro_list_t arg_list;
|
rua_macro_list_t arg_list;
|
||||||
|
rua_include_stack_t include_stack;
|
||||||
dstring_t *dstr;
|
dstring_t *dstr;
|
||||||
symtab_t *macro_tab;
|
symtab_t *macro_tab;
|
||||||
yyscan_t subscanner;
|
yyscan_t subscanner;
|
||||||
|
@ -1403,6 +1406,7 @@ qc_yyparse (FILE *in)
|
||||||
.cond_stack = DARRAY_STATIC_INIT (8),
|
.cond_stack = DARRAY_STATIC_INIT (8),
|
||||||
.expr_stack = DARRAY_STATIC_INIT (32),
|
.expr_stack = DARRAY_STATIC_INIT (32),
|
||||||
.arg_list = DARRAY_STATIC_INIT (8),
|
.arg_list = DARRAY_STATIC_INIT (8),
|
||||||
|
.include_stack = DARRAY_STATIC_INIT (8),
|
||||||
.dstr = dstring_new (),
|
.dstr = dstring_new (),
|
||||||
.macro_tab = new_symtab (0, stab_global),
|
.macro_tab = new_symtab (0, stab_global),
|
||||||
};
|
};
|
||||||
|
@ -1412,6 +1416,14 @@ qc_yyparse (FILE *in)
|
||||||
yyset_in (in, scanner);
|
yyset_in (in, scanner);
|
||||||
do {
|
do {
|
||||||
int token = yylex (&tok, &tok.location, scanner);
|
int token = yylex (&tok, &tok.location, scanner);
|
||||||
|
if (!token && extra.include_stack.size) {
|
||||||
|
struct yyguts_t * yyg = (struct yyguts_t*)scanner;//FIXME
|
||||||
|
yy_delete_buffer (YY_CURRENT_BUFFER, scanner);
|
||||||
|
auto buffer = DARRAY_REMOVE (&extra.include_stack);
|
||||||
|
set_line_file (-1, 0, 2);
|
||||||
|
yy_switch_to_buffer (buffer, scanner);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
status = qc_process (&extra, token, &tok, scanner);
|
status = qc_process (&extra, token, &tok, scanner);
|
||||||
if (status != YYPUSH_MORE || !extra.expr_stack.size) {
|
if (status != YYPUSH_MORE || !extra.expr_stack.size) {
|
||||||
|
@ -1435,6 +1447,7 @@ qc_yyparse (FILE *in)
|
||||||
free (extra.cond_stack.a);
|
free (extra.cond_stack.a);
|
||||||
free (extra.expr_stack.a);
|
free (extra.expr_stack.a);
|
||||||
free (extra.arg_list.a);
|
free (extra.arg_list.a);
|
||||||
|
free (extra.include_stack.a);
|
||||||
dstring_delete (extra.dstr);
|
dstring_delete (extra.dstr);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -1732,3 +1745,30 @@ rua_undefine (const char *name, void *scanner)
|
||||||
symtab_removesymbol (macro_tab, sym);
|
symtab_removesymbol (macro_tab, sym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rua_include_file (const char *name, void *scanner)
|
||||||
|
{
|
||||||
|
auto extra = qc_yyget_extra (scanner);
|
||||||
|
struct yyguts_t * yyg = (struct yyguts_t*)scanner;//FIXME
|
||||||
|
int quote = *name;
|
||||||
|
name = make_string (name, 0);
|
||||||
|
bool is_system;
|
||||||
|
auto found = cpp_find_file (name, quote, &is_system);
|
||||||
|
if (!found || !(yyin = fopen (found, "rb"))) {
|
||||||
|
error (0, "fatal error: %s: %s", name, strerror (errno));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
set_line_file (1, found, 1);
|
||||||
|
DARRAY_APPEND (&extra->include_stack, YY_CURRENT_BUFFER);
|
||||||
|
yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE, scanner), scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rua_embed_file (const char *name, void *scanner)
|
||||||
|
{
|
||||||
|
if (scanner) {
|
||||||
|
internal_error (0, "not implemented");
|
||||||
|
}
|
||||||
|
printf ("eh?\n");
|
||||||
|
}
|
||||||
|
|
|
@ -195,6 +195,9 @@ make_string (const char *token, char **end)
|
||||||
unicount = 0;
|
unicount = 0;
|
||||||
|
|
||||||
quote = *token++;
|
quote = *token++;
|
||||||
|
if (quote == '<') {
|
||||||
|
quote = '>'; // #include <file>
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
c = *token++;
|
c = *token++;
|
||||||
if (!c)
|
if (!c)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue