mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-19 07:51:08 +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;
|
||||
|
||||
void parse_cpp_name (void);
|
||||
void add_cpp_sysinc (const char *arg);
|
||||
void add_cpp_undef (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,
|
||||
const char *ext, int local);
|
||||
FILE *preprocess_file (const char *filename, const char *ext);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
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,
|
||||
const expr_t *flags_epxr);
|
||||
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);
|
||||
bool rua_defined (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"
|
||||
|
||||
|
|
|
@ -53,27 +53,44 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "tools/qfcc/include/cpp.h"
|
||||
#include "tools/qfcc/include/debug.h"
|
||||
#include "tools/qfcc/include/diagnostic.h"
|
||||
#include "tools/qfcc/include/options.h"
|
||||
#include "tools/qfcc/include/qfcc.h"
|
||||
#include "tools/qfcc/include/strpool.h"
|
||||
|
||||
typedef struct cpp_arg_s {
|
||||
struct cpp_arg_s *next;
|
||||
const char *arg;
|
||||
} cpp_arg_t;
|
||||
|
||||
cpp_arg_t *cpp_arg_list;
|
||||
cpp_arg_t **cpp_arg_tail = &cpp_arg_list;
|
||||
cpp_arg_t *cpp_def_list;
|
||||
cpp_arg_t **cpp_def_tail = &cpp_def_list;
|
||||
cpp_arg_t *cpp_undef_list;
|
||||
cpp_arg_t **cpp_undef_tail = &cpp_undef_list;
|
||||
cpp_arg_t *cpp_sysinc_list;
|
||||
cpp_arg_t **cpp_sysinc_tail = &cpp_sysinc_list;
|
||||
const char **cpp_argv;
|
||||
const char *cpp_name = CPP_NAME;
|
||||
typedef struct cpp_func_s {
|
||||
const char *name;
|
||||
int (*func) (const char *opt, const char *arg);
|
||||
} cpp_func_t;
|
||||
|
||||
static cpp_arg_t *cpp_quote_list, **cpp_quote_tail = &cpp_quote_list;
|
||||
static cpp_arg_t *cpp_include_list,**cpp_include_tail= &cpp_include_list;
|
||||
static cpp_arg_t *cpp_system_list, **cpp_system_tail = &cpp_system_list;
|
||||
static cpp_arg_t *cpp_after_list, **cpp_after_tail = &cpp_after_list;
|
||||
|
||||
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;
|
||||
|
||||
const char *cpp_name = CPP_NAME;
|
||||
dstring_t *tempname;
|
||||
|
||||
static const char **
|
||||
|
@ -86,66 +103,200 @@ append_cpp_args (const char **arg, cpp_arg_t *arg_list)
|
|||
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
|
||||
add_cpp_arg (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
||||
cpp_arg->next = 0;
|
||||
cpp_arg->arg = arg;
|
||||
*cpp_arg_tail = cpp_arg;
|
||||
cpp_arg_tail = &(*cpp_arg_tail)->next;
|
||||
CPP_ADD (arg, arg);
|
||||
cpp_argc++;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
add_cpp_sysinc (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
||||
cpp_arg->next = 0;
|
||||
cpp_arg->arg = arg;
|
||||
*cpp_sysinc_tail = cpp_arg;
|
||||
cpp_sysinc_tail = &(*cpp_sysinc_tail)->next;
|
||||
CPP_ADD (sysinc, arg);
|
||||
cpp_argc++;
|
||||
}
|
||||
|
||||
void
|
||||
add_cpp_undef (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_arg = malloc (sizeof (cpp_arg_t));
|
||||
cpp_arg->next = 0;
|
||||
cpp_arg->arg = arg;
|
||||
*cpp_undef_tail = cpp_arg;
|
||||
cpp_undef_tail = &(*cpp_undef_tail)->next;
|
||||
CPP_ADD (undef, arg);
|
||||
cpp_argc++;
|
||||
}
|
||||
|
||||
void
|
||||
add_cpp_def (const char *arg)
|
||||
{
|
||||
cpp_arg_t *cpp_def = malloc (sizeof (cpp_arg_t));
|
||||
cpp_def->next = 0;
|
||||
cpp_def->arg = arg;
|
||||
*cpp_def_tail = cpp_def;
|
||||
cpp_def_tail = &(*cpp_def_tail)->next;
|
||||
CPP_ADD (def, arg);
|
||||
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
|
||||
parse_cpp_name (void)
|
||||
{
|
||||
char *n;
|
||||
char *n, *e;
|
||||
|
||||
if (!cpp_name)
|
||||
if (!cpp_name || !*cpp_name) {
|
||||
return;
|
||||
n = strdup (cpp_name);
|
||||
while (*n) {
|
||||
while (*n && *n == ' ')
|
||||
n++;
|
||||
}
|
||||
|
||||
for (n = strdup (cpp_name); *n; n = e) {
|
||||
for (; *n && *n == ' '; n++) continue;
|
||||
for (e = n; *e && *e != ' '; e++) continue;
|
||||
*e++ = 0;
|
||||
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 *
|
||||
preprocess_file (const char *filename, const char *ext)
|
||||
static FILE *
|
||||
run_cpp (const char *filename, const char *ext)
|
||||
{
|
||||
add_cpp_sysinc ("-isystem");
|
||||
add_cpp_sysinc (QFCC_INCLUDE_PATH);
|
||||
|
||||
#ifndef _WIN32
|
||||
pid_t pid;
|
||||
int tempfd = 0;
|
||||
#endif
|
||||
|
||||
if (cpp_name) {
|
||||
intermediate_file (tempname, filename, ext ? ext : "p", 0);
|
||||
build_cpp_args (filename, tempname->str);
|
||||
if (!cpp_argv[0]) {
|
||||
internal_error(0, "cpp_argv[0] is null");
|
||||
}
|
||||
intermediate_file (tempname, filename, ext ? ext : "p", 0);
|
||||
build_cpp_args (filename, tempname->str);
|
||||
if (!cpp_argv[0]) {
|
||||
internal_error(0, "cpp_argv[0] is null");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!options.save_temps && !options.preprocess_only)
|
||||
mktemp (tempname->str);
|
||||
if (!options.save_temps && !options.preprocess_only)
|
||||
mktemp (tempname->str);
|
||||
}
|
||||
|
||||
{
|
||||
FILE *tmp = fopen (tempname->str, "wb");
|
||||
if (tmp == NULL) {
|
||||
fprintf (stderr, "%s: qfcc was unable to open\n",
|
||||
tempname->str);
|
||||
return 0;
|
||||
}
|
||||
fclose (tmp);
|
||||
}
|
||||
FILE *tmp = fopen (tempname->str, "wb");
|
||||
if (tmp == NULL) {
|
||||
fprintf (stderr, "%s: qfcc was unable to open\n",
|
||||
tempname->str);
|
||||
return 0;
|
||||
}
|
||||
fclose (tmp);
|
||||
|
||||
{
|
||||
int status;
|
||||
int status;
|
||||
|
||||
if (options.verbosity > 1) {
|
||||
const char **a;
|
||||
for (a = cpp_argv; *a; a++)
|
||||
printf ("%s ", *a);
|
||||
puts("");
|
||||
}
|
||||
if (options.verbosity > 1) {
|
||||
const char **a;
|
||||
for (a = cpp_argv; *a; a++)
|
||||
printf ("%s ", *a);
|
||||
puts("");
|
||||
}
|
||||
|
||||
#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
|
||||
status = spawnvp (_P_WAIT, cpp_argv[0], cpp_argv);
|
||||
status = spawnvp (_P_WAIT, cpp_argv[0], cpp_argv);
|
||||
#endif
|
||||
|
||||
if (status) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
status);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (status) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (options.preprocess_only)
|
||||
return 0;
|
||||
return fopen (tempname->str, "rb");
|
||||
if (options.preprocess_only)
|
||||
return 0;
|
||||
return fopen (tempname->str, "rb");
|
||||
#else
|
||||
if (!options.save_temps && !options.preprocess_only)
|
||||
tempfd = mkstemp (tempname->str);
|
||||
if (!options.save_temps && !options.preprocess_only)
|
||||
tempfd = mkstemp (tempname->str);
|
||||
|
||||
if ((pid = fork ()) == -1) {
|
||||
perror ("fork");
|
||||
return 0;
|
||||
if ((pid = fork ()) == -1) {
|
||||
perror ("fork");
|
||||
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
|
||||
execvp (cpp_argv[0], (char **)cpp_argv);
|
||||
execvp (cpp_argv[0], (char **)cpp_argv);
|
||||
#else
|
||||
execve (cpp_argv[0], (char **)cpp_argv, environ);
|
||||
execve (cpp_argv[0], (char **)cpp_argv, environ);
|
||||
#endif
|
||||
perror (cpp_argv[0]);
|
||||
exit (1);
|
||||
} else {
|
||||
// give parental guidance (or bury it in the back yard)
|
||||
int status;
|
||||
pid_t rc;
|
||||
perror (cpp_argv[0]);
|
||||
exit (1);
|
||||
} else {
|
||||
// give parental guidance (or bury it in the back yard)
|
||||
int status;
|
||||
pid_t rc;
|
||||
|
||||
// printf ("pid = %d\n", pid);
|
||||
#ifdef HAVE_WAITPID
|
||||
rc = waitpid (0, &status, 0 | WUNTRACED);
|
||||
rc = waitpid (0, &status, 0 | WUNTRACED);
|
||||
#else
|
||||
rc = wait (&status);
|
||||
rc = wait (&status);
|
||||
#endif
|
||||
if ((rc) != pid) {
|
||||
if (rc == -1) {
|
||||
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);
|
||||
if ((rc) != pid) {
|
||||
if (rc == -1) {
|
||||
perror ("wait");
|
||||
return 0;
|
||||
}
|
||||
if (WIFEXITED (status)) {
|
||||
if (WEXITSTATUS (status)) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
WEXITSTATUS (status));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "%s: cpp returned prematurely.\n", filename);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (options.preprocess_only)
|
||||
fprintf (stderr, "%s: The wrong child (%ld) died. Don't ask me, I don't know either.\n",
|
||||
this_program,
|
||||
(long) rc);
|
||||
return 0;
|
||||
}
|
||||
if (WIFEXITED (status)) {
|
||||
if (WEXITSTATUS (status)) {
|
||||
fprintf (stderr, "%s: cpp returned error code %d\n",
|
||||
filename,
|
||||
WEXITSTATUS (status));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "%s: cpp returned prematurely.\n", filename);
|
||||
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/progs/pr_comp.h"
|
||||
|
||||
#include "tools/qfcc/include/cpp.h"
|
||||
#include "tools/qfcc/include/debug.h"
|
||||
#include "tools/qfcc/include/def.h"
|
||||
#include "tools/qfcc/include/defspace.h"
|
||||
|
@ -81,6 +82,8 @@ pop_source_file (void)
|
|||
return;
|
||||
}
|
||||
tmp = pr.srcline_stack;
|
||||
pr.source_file = tmp->source_file;
|
||||
pr.source_line = tmp->source_line;
|
||||
pr.srcline_stack = tmp->next;
|
||||
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
|
||||
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);
|
||||
}
|
||||
switch (flags & 3) {
|
||||
case 1:
|
||||
push_source_file ();
|
||||
break;
|
||||
case 2:
|
||||
pop_source_file ();
|
||||
break;
|
||||
}
|
||||
pr.source_line = line;
|
||||
if (file) {
|
||||
add_source_file (file);
|
||||
}
|
||||
set_line_file (line, file, flags);
|
||||
}
|
||||
|
||||
pr_lineno_t *
|
||||
|
|
|
@ -140,6 +140,7 @@ static const char *short_options =
|
|||
"F" // generate files.dat
|
||||
"g" // debug
|
||||
"h" // help
|
||||
"i::" // set includes
|
||||
"I:" // set includes
|
||||
"L:" // lib path
|
||||
"l:" // lib file
|
||||
|
@ -607,8 +608,9 @@ DecodeArgs (int argc, char **argv)
|
|||
add_cpp_undef ("-undef");
|
||||
add_cpp_undef ("-nostdinc");
|
||||
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 = "";
|
||||
progs_src = "progs.src";
|
||||
|
@ -740,7 +742,7 @@ DecodeArgs (int argc, char **argv)
|
|||
options.save_temps = true;
|
||||
break;
|
||||
case 'D': // defines for cpp
|
||||
add_cpp_def (nva ("%s%s", "-D", optarg));
|
||||
cpp_define (optarg);
|
||||
break;
|
||||
case 'E': // defines for cpp
|
||||
saw_E = 1;
|
||||
|
@ -751,11 +753,21 @@ DecodeArgs (int argc, char **argv)
|
|||
add_cpp_def (nva ("%s", "-include"));
|
||||
add_cpp_def (nva ("%s", optarg));
|
||||
break;
|
||||
case 'i': // includes
|
||||
{
|
||||
int o = cpp_include (optarg, argv[optind]);
|
||||
if (o < 0) {
|
||||
usage (1);
|
||||
} else {
|
||||
optind += o;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'I': // includes
|
||||
add_cpp_def (nva ("%s%s", "-I", optarg));
|
||||
cpp_include ("I", optarg);
|
||||
break;
|
||||
case 'U': // undefines
|
||||
add_cpp_def (nva ("%s%s", "-U", optarg));
|
||||
cpp_undefine (optarg);
|
||||
break;
|
||||
case 'M':
|
||||
options.preprocess_only = 1;
|
||||
|
@ -857,8 +869,6 @@ DecodeArgs (int argc, char **argv)
|
|||
|
||||
// add the default paths
|
||||
if (!options.no_default_paths) {
|
||||
add_cpp_sysinc ("-isystem");
|
||||
add_cpp_sysinc (QFCC_INCLUDE_PATH);
|
||||
linker_add_path (QFCC_LIB_PATH);
|
||||
}
|
||||
|
||||
|
|
|
@ -173,38 +173,53 @@ start
|
|||
|
||||
directive_list
|
||||
: /*empty*/
|
||||
| directive EOD { rua_end_directive (scanner); } directive_list
|
||||
| directive directive_list
|
||||
;
|
||||
|
||||
eod : EOD { rua_end_directive (scanner); } ;
|
||||
|
||||
directive
|
||||
: INCLUDE expand string extra_warn
|
||||
| EMBED expand string extra_ignore
|
||||
: INCLUDE expand string extra_warn eod { rua_include_file ($3, scanner); }
|
||||
| EMBED expand string extra_ignore eod { rua_embed_file ($3, scanner); }
|
||||
| DEFINE ID <macro> { $$ = rua_start_macro ($2, false, scanner); }
|
||||
body { rua_macro_finish ($body, scanner); }
|
||||
eod
|
||||
| DEFINE IDp <macro> { $$ = rua_start_macro ($2, true, scanner); }
|
||||
params ')' <macro> { $$ = rua_end_params ($3, scanner); }
|
||||
body { rua_macro_finish ($body, scanner); }
|
||||
eod
|
||||
| UNDEF ID extra_warn { rua_undefine ($2, scanner); }
|
||||
eod
|
||||
| ERROR text { error (0, "%s", $text->str); dstring_delete ($text); }
|
||||
eod
|
||||
| WARNING text { warning (0, "%s", $text->str); dstring_delete ($text); }
|
||||
eod
|
||||
| PRAGMA expand { rua_start_pragma (scanner); }
|
||||
pragma_params { pragma_process (); }
|
||||
eod
|
||||
| LINE expand expr extra_warn { line_info ($3, 0, 0); }
|
||||
eod
|
||||
| LINE expand expr string line_expr extra_warn { line_info ($3, $4, $5); }
|
||||
eod
|
||||
| IF expand expr { rua_if (expr_long ($3), scanner); }
|
||||
eod
|
||||
| IFDEF ID extra_warn { rua_if (rua_defined ($2, scanner), scanner); }
|
||||
eod
|
||||
| IFNDEF ID extra_warn { rua_if (!rua_defined ($2, scanner), scanner); }
|
||||
eod
|
||||
| ELSE extra_warn { rua_else (true, "else", scanner); }
|
||||
eod
|
||||
| ELIF expand expr { rua_else (expr_long ($3), "elif", scanner); }
|
||||
eod
|
||||
| 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
|
||||
{
|
||||
rua_else (!rua_defined ($2, scanner), "elifndef", scanner);
|
||||
}
|
||||
| ENDIF extra_warn { rua_endif (scanner); }
|
||||
{ rua_else (!rua_defined ($2, scanner), "elifndef", scanner); }
|
||||
eod
|
||||
| ENDIF extra_warn
|
||||
{ rua_endif (scanner); }
|
||||
eod
|
||||
;
|
||||
|
||||
extra_warn
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <QF/va.h>
|
||||
|
||||
#include "tools/qfcc/include/class.h"
|
||||
#include "tools/qfcc/include/cpp.h"
|
||||
#include "tools/qfcc/include/debug.h"
|
||||
#include "tools/qfcc/include/diagnostic.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_expr_t) rua_expr_stack_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 {
|
||||
int start_state;
|
||||
|
@ -108,6 +110,7 @@ typedef struct rua_extra_s {
|
|||
rua_cond_stack_t cond_stack;
|
||||
rua_expr_stack_t expr_stack;
|
||||
rua_macro_list_t arg_list;
|
||||
rua_include_stack_t include_stack;
|
||||
dstring_t *dstr;
|
||||
symtab_t *macro_tab;
|
||||
yyscan_t subscanner;
|
||||
|
@ -1403,6 +1406,7 @@ qc_yyparse (FILE *in)
|
|||
.cond_stack = DARRAY_STATIC_INIT (8),
|
||||
.expr_stack = DARRAY_STATIC_INIT (32),
|
||||
.arg_list = DARRAY_STATIC_INIT (8),
|
||||
.include_stack = DARRAY_STATIC_INIT (8),
|
||||
.dstr = dstring_new (),
|
||||
.macro_tab = new_symtab (0, stab_global),
|
||||
};
|
||||
|
@ -1412,6 +1416,14 @@ qc_yyparse (FILE *in)
|
|||
yyset_in (in, scanner);
|
||||
do {
|
||||
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) {
|
||||
status = qc_process (&extra, token, &tok, scanner);
|
||||
if (status != YYPUSH_MORE || !extra.expr_stack.size) {
|
||||
|
@ -1435,6 +1447,7 @@ qc_yyparse (FILE *in)
|
|||
free (extra.cond_stack.a);
|
||||
free (extra.expr_stack.a);
|
||||
free (extra.arg_list.a);
|
||||
free (extra.include_stack.a);
|
||||
dstring_delete (extra.dstr);
|
||||
return status;
|
||||
}
|
||||
|
@ -1732,3 +1745,30 @@ rua_undefine (const char *name, void *scanner)
|
|||
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;
|
||||
|
||||
quote = *token++;
|
||||
if (quote == '<') {
|
||||
quote = '>'; // #include <file>
|
||||
}
|
||||
do {
|
||||
c = *token++;
|
||||
if (!c)
|
||||
|
|
Loading…
Reference in a new issue