[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:
Bill Currie 2023-10-25 21:07:50 +09:00
parent f1f0a4a260
commit ffb2514e75
9 changed files with 480 additions and 160 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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"

View file

@ -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);
}

View file

@ -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 *

View file

@ -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);
}

View file

@ -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

View file

@ -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");
}

View file

@ -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)