mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-19 16:01:15 +00:00
[qfcc] Update line directive handling
In addition to cleaning up the old flex line rules, this improves handling of the '# num "file" flags' from cpp to at least parse the additional flags (support for the system header flag might come later, but I doubt the extern-c flag will have much meaning). QuakePascal has lost its line directive handling (no errors, but dead rules) for now. Eventually the lexers will be merged.
This commit is contained in:
parent
717be4a12d
commit
f1f0a4a260
5 changed files with 68 additions and 55 deletions
|
@ -33,7 +33,10 @@
|
|||
|
||||
#include "QF/progs/pr_debug.h"
|
||||
|
||||
void line_info (const char *text);
|
||||
typedef struct expr_s expr_t;
|
||||
|
||||
void line_info (const expr_t *line_expr, const char *text,
|
||||
const expr_t *flags_epxr);
|
||||
pr_lineno_t *new_lineno (void);
|
||||
void add_source_file (const char *file);
|
||||
void debug_finish_module (const char *modname);
|
||||
|
|
|
@ -97,27 +97,19 @@ add_source_file (const char *file)
|
|||
}
|
||||
|
||||
void
|
||||
line_info (const char *text)
|
||||
line_info (const expr_t *line_expr, const char *file, const expr_t *flags_expr)
|
||||
{
|
||||
const char *p;
|
||||
char *s;
|
||||
const char *str;
|
||||
int line;
|
||||
int flags;
|
||||
int line = expr_long (line_expr);
|
||||
int flags = flags_expr ? expr_long (flags_expr) : 0;
|
||||
|
||||
p = text;
|
||||
line = strtol (p, &s, 10);
|
||||
p = s;
|
||||
while (isspace ((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
error (0, "Unexpected end of file");
|
||||
str = make_string (p, &s); // grab the filename
|
||||
p = s;
|
||||
while (isspace ((unsigned char) *p))
|
||||
p++;
|
||||
flags = strtol (p, &s, 10);
|
||||
switch (flags) {
|
||||
if (file) {
|
||||
if (*file != '"') {
|
||||
error (0, "\"%s\" is not a valid filename", file);
|
||||
return;
|
||||
}
|
||||
file = make_string (file, 0);
|
||||
}
|
||||
switch (flags & 3) {
|
||||
case 1:
|
||||
push_source_file ();
|
||||
break;
|
||||
|
@ -125,10 +117,10 @@ line_info (const char *text)
|
|||
pop_source_file ();
|
||||
break;
|
||||
}
|
||||
while (*p && *p != '\n') // ignore rest
|
||||
p++;
|
||||
pr.source_line = line - 1;
|
||||
add_source_file (str);
|
||||
pr.source_line = line;
|
||||
if (file) {
|
||||
add_source_file (file);
|
||||
}
|
||||
}
|
||||
|
||||
pr_lineno_t *
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
#include "QF/dstring.h"
|
||||
|
||||
#include "tools/qfcc/include/debug.h"
|
||||
#include "tools/qfcc/include/diagnostic.h"
|
||||
#include "tools/qfcc/include/expr.h"
|
||||
#include "tools/qfcc/include/pragma.h"
|
||||
|
@ -119,7 +120,7 @@ parse_error (void *scanner)
|
|||
%token TOKEN
|
||||
// end of tokens comment between qc and preprocessor
|
||||
|
||||
%token QSTRING HSTRING
|
||||
%token <text> QSTRING HSTRING
|
||||
|
||||
%token INCLUDE EMBED
|
||||
%token DEFINE UNDEF
|
||||
|
@ -130,13 +131,32 @@ parse_error (void *scanner)
|
|||
%token DEFINED EOD
|
||||
%token CONCAT ARGS
|
||||
|
||||
%type <text> string
|
||||
%type <macro> params body arg arg_list
|
||||
%type <dstr> text text_text
|
||||
%type <value.expr> unary_expr expr id defined defined_id
|
||||
%type <value.expr> unary_expr expr id defined defined_id line_expr
|
||||
|
||||
%{
|
||||
#define BEXPR(a,op,b) new_long_expr (expr_long (a) op expr_long (b), false)
|
||||
#define UEXPR(op,a) new_long_expr (op expr_long (a), false)
|
||||
|
||||
static const expr_t *
|
||||
get_long (const expr_t *expr, const char *text, int defl)
|
||||
{
|
||||
auto type = expr ? get_type (expr) : 0;
|
||||
if (!type || !is_long (type)) {
|
||||
if (type && is_double (type)) {
|
||||
error (0, "floating constant in preprocessor expression");
|
||||
expr = new_long_expr (expr_double (expr), false);
|
||||
} else {
|
||||
error (0, "token \"%s\" is not valid in preprocessor"
|
||||
" expressions", text);
|
||||
expr= new_long_expr (defl, false);
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%%
|
||||
|
@ -169,7 +189,8 @@ directive
|
|||
| WARNING text { warning (0, "%s", $text->str); dstring_delete ($text); }
|
||||
| PRAGMA expand { rua_start_pragma (scanner); }
|
||||
pragma_params { pragma_process (); }
|
||||
| LINE expand expr QSTRING extra_warn
|
||||
| LINE expand expr extra_warn { line_info ($3, 0, 0); }
|
||||
| LINE expand expr string line_expr extra_warn { line_info ($3, $4, $5); }
|
||||
| IF expand expr { rua_if (expr_long ($3), scanner); }
|
||||
| IFDEF ID extra_warn { rua_if (rua_defined ($2, scanner), scanner); }
|
||||
| IFNDEF ID extra_warn { rua_if (!rua_defined ($2, scanner), scanner); }
|
||||
|
@ -218,8 +239,8 @@ pragma_params
|
|||
;
|
||||
|
||||
string
|
||||
: HSTRING
|
||||
| QSTRING
|
||||
: HSTRING { $$ = save_string ($1); }
|
||||
| QSTRING { $$ = save_string ($1); }
|
||||
;
|
||||
|
||||
params
|
||||
|
@ -263,27 +284,8 @@ defined_id
|
|||
|
||||
unary_expr
|
||||
: id
|
||||
| VALUE
|
||||
{
|
||||
auto type = get_type ($1);
|
||||
if (!is_long (type)) {
|
||||
if (is_double (type)) {
|
||||
error (0, "floating constant in preprocessor expression");
|
||||
$1 = new_long_expr (expr_double ($1), false);
|
||||
} else {
|
||||
error (0, "token \"%s\" is not valid in preprocessor"
|
||||
" expressions", $<text>1);
|
||||
$1 = new_long_expr (1, false);
|
||||
}
|
||||
}
|
||||
$$ = $1;
|
||||
}
|
||||
| QSTRING
|
||||
{
|
||||
error (0, "token \"%s\" is not valid in preprocessor"
|
||||
" expressions", $<text>1);
|
||||
$$ = new_long_expr (1, false);
|
||||
}
|
||||
| VALUE { $$ = get_long ($1, $<text>1, 1); }
|
||||
| QSTRING { $$ = get_long (0, $<text>1, 1); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| DEFINED { rua_expand_off (scanner); }
|
||||
defined { rua_expand_on (scanner); $$ = $3; }
|
||||
|
@ -315,4 +317,18 @@ expr
|
|||
| expr '%' expr { $$ = BEXPR ($1, % , $3); }
|
||||
;
|
||||
|
||||
line_expr
|
||||
: /* empty */ { $$ = new_long_expr (0, false); }
|
||||
| line_expr VALUE
|
||||
{
|
||||
pr_long_t flags = expr_long ($1);
|
||||
pr_long_t bit = expr_long (get_long ($2, $<text>2, 0)) - 1;
|
||||
if (bit >= 0) {
|
||||
flags |= 1 << bit;
|
||||
$1 = new_long_expr (flags, false);
|
||||
}
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
|
@ -198,6 +198,11 @@ pp_vnumber '({s}*{m}?{pp_number}){2,4}{s}*'{ULFD}?
|
|||
<LCOMMENT>[\\]* /* consume \ */
|
||||
|
||||
<ARGS>^# { return '#'; }
|
||||
^#{s}+/{D} {
|
||||
yy_push_state (PREPROC, yyscanner);
|
||||
extra->preprocessor = true;
|
||||
return PRE_LINE;
|
||||
}
|
||||
<*>^# {
|
||||
yy_push_state (DIRECTIVE, yyscanner);
|
||||
extra->preprocessor = true;
|
||||
|
@ -243,9 +248,6 @@ pp_vnumber '({s}*{m}?{pp_number}){2,4}{s}*'{ULFD}?
|
|||
<PREEXPR>defined { return PRE_DEFINED; }
|
||||
<PREEXPR>{ID} { return PRE_ID; }
|
||||
|
||||
^#{s}+{D}+{s}+\"(\.|[^"\n])*\".*$ { line_info (yytext + 1); }
|
||||
^#line{s}+{D}+{s}+\"(\.|[^"\n])*\".*$ { line_info (yytext + 5); }
|
||||
|
||||
<INITIAL,ARGS>{
|
||||
{ID} |
|
||||
@{ID} { return -rua_id; }
|
||||
|
|
|
@ -135,8 +135,8 @@ FRAMEID {ID}(\.{ID})*
|
|||
<COMMENT><<EOF>> { error (0, "EOF in comment"); return 0; }
|
||||
"//".* /* nothing to do, with people like you */
|
||||
|
||||
^#{s}+{D}+{s}+\"(\.|[^"\n])*\".*$ { line_info (yytext + 1); }
|
||||
^#line{s}+{D}+{s}+\"(\.|[^"\n])*\".*$ { line_info (yytext + 1); }
|
||||
^#{s}+{D}+{s}+\"(\.|[^"\n])*\".*$ { /*line_info (yytext + 1);FIXME*/ }
|
||||
^#line{s}+{D}+{s}+\"(\.|[^"\n])*\".*$ { /*line_info (yytext + 1);FIXME*/ }
|
||||
|
||||
{INTEGER} {
|
||||
int i;
|
||||
|
|
Loading…
Reference in a new issue