diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index d94a781dc..db45bab21 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -66,6 +66,10 @@ typedef struct pr_info_s { struct defspace_s *far_data; struct defspace_s *entity_data; struct scope_s *scope; + + string_t source_file; + int source_line; + int error_count; } pr_info_t; extern pr_info_t pr; @@ -73,10 +77,8 @@ extern pr_info_t pr; //============================================================================ extern char destfile[]; -extern int pr_source_line; extern struct scope_s *current_scope; -extern int pr_error_count; #define G_var(t, o) (pr.near_data->data[o].t##_var) #define G_FLOAT(o) G_var (float, o) @@ -89,8 +91,6 @@ extern int pr_error_count; #define POINTER_OFS(p) ((pr_type_t *) (p) - pr.near_data->data) -extern string_t s_file; // filename for function definition - const char *strip_path (const char *filename); const char *save_string (const char *str); diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index 78f3edf28..d9270498d 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -272,8 +272,8 @@ new_def (type_t *type, const char *name, scope_t *scope) def->scope = scope; def->space = scope->space; - def->file = s_file; - def->line = pr_source_line; + def->file = pr.source_file; + def->line = pr.source_line; return def; } diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index 7a939a2f4..3c64526fc 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -84,7 +84,7 @@ emit_statement (int sline, opcode_t *op, def_t *var_a, def_t *var_b, expr_t e; e.line = sline; - e.file = s_file; + e.file = pr.source_file; error (&e, "ice ice baby\n"); abort (); } @@ -107,7 +107,7 @@ emit_statement (int sline, opcode_t *op, def_t *var_a, def_t *var_b, } statement = &pr.statements[pr.num_statements]; pr.num_statements++; - pr.statement_linenums[statement - pr.statements] = pr_source_line; + pr.statement_linenums[statement - pr.statements] = pr.source_line; statement->op = op->opcode; statement->a = var_a ? var_a->ofs : 0; statement->b = var_b ? var_b->ofs : 0; diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index d08ad17aa..0e0465002 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -224,8 +224,8 @@ expr_t * error (expr_t *e, const char *fmt, ...) { va_list args; - string_t file = s_file; - int line = pr_source_line; + string_t file = pr.source_file; + int line = pr.source_line; va_start (args, fmt); if (e) { @@ -236,7 +236,7 @@ error (expr_t *e, const char *fmt, ...) vfprintf (stderr, fmt, args); fputs ("\n", stderr); va_end (args); - pr_error_count++; + pr.error_count++; if (e) { e->type = ex_error; @@ -247,13 +247,13 @@ error (expr_t *e, const char *fmt, ...) void _warning (expr_t *e, const char *fmt, va_list args) { - string_t file = s_file; - int line = pr_source_line; + string_t file = pr.source_file; + int line = pr.source_line; if (options.warnings.promote) { options.warnings.promote = 0; // only want to do this once fprintf (stderr, "%s: warnings treated as errors\n", "qfcc"); - pr_error_count++; + pr.error_count++; } if (e) { @@ -287,8 +287,8 @@ notice (expr_t *e, const char *fmt, ...) if (options.notices.promote) { _warning (e, fmt, args); } else { - string_t file = s_file; - int line = pr_source_line; + string_t file = pr.source_file; + int line = pr.source_line; if (e) { file = e->file; @@ -386,8 +386,8 @@ new_expr (void) ALLOC (16384, expr_t, exprs, e); - e->line = pr_source_line; - e->file = s_file; + e->line = pr.source_line; + e->file = pr.source_file; return e; } diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 07be4d205..b85d38ea6 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -179,7 +179,7 @@ new_function (const char *name) pr.func_tail = &f->next; f->function_num = pr.num_functions++; f->s_name = ReuseString (name); - f->s_file = s_file; + f->s_file = pr.source_file; return f; } @@ -246,14 +246,14 @@ emit_function (function_t *f, expr_t *e) current_scope = f->scope; while (e) { - //printf ("%d ", pr_source_line); + //printf ("%d ", pr.source_line); //print_expr (e); //puts(""); emit_expr (e); e = e->next; } - emit_statement (pr_source_line, op_done, 0, 0, 0); + emit_statement (pr.source_line, op_done, 0, 0, 0); flush_scope (current_scope, 0); current_scope = pr.scope; reset_tempdefs (); diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index b5fff788e..3c5dcef28 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -33,6 +33,12 @@ static const char rcsid[] = #ifdef HAVE_CONFIG_H # include "config.h" #endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif #include #include "QF/hash.h" @@ -84,6 +90,8 @@ add_defs (qfo_t *qfo) } else { if (def->flags & QFOD_GLOBAL) { if ((d = Hash_Find (defined_defs, pr.strings + def->name))) { + pr.source_file = (*def)->file; + pr.source_line = (*def)->line; error (0, "%s redefined", pr.strings + def->name); } } @@ -99,6 +107,8 @@ add_defs (qfo_t *qfo) while ((d = Hash_Find (extern_defs, pr.strings + def->name))) { Hash_Del (extern_defs, pr.strings + d->name); if (d->full_type != def->full_type) { + pr.source_file = (*def)->file; + pr.source_line = (*def)->line; error (0, "type mismatch %s %s", pr.strings + def->full_type, pr.strings + d->full_type); @@ -162,4 +172,11 @@ linker_add_object_file (const char *filename) void linker_finish (void) { + qfo_def_t **undef_defs, **def; + undef_defs = (qfo_def_t **) Hash_GetList (extern_defs); + for (def = undef_defs; *def; def++) { + pr.source_file = (*def)->file; + pr.source_line = (*def)->line; + error (0, "undefined symbol %s", pr.strings + (*def)->name); + } } diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 5d9607994..bd2aa2f1b 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -93,7 +93,7 @@ m ([\-+]?) if (c == EOF) error (0, "EOF in comment"); if (c == '\n') - pr_source_line++; + pr.source_line++; } while (c != '/' && c != EOF); } @@ -162,8 +162,8 @@ m ([\-+]?) str = make_string (p); // grab the filename while (*p && *p != '\n') // ignore flags p++; - pr_source_line = line - 1; - s_file = ReuseString (strip_path (str)); + pr.source_line = line - 1; + pr.source_file = ReuseString (strip_path (str)); } [+\-*/&|^%]= { @@ -226,7 +226,7 @@ m ([\-+]?) [^\r\n]* /* skip */ <*>\r*\n { - pr_source_line++; + pr.source_line++; BEGIN (INITIAL); } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 44ff8ad0d..031ae8e17 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -63,7 +63,6 @@ static const char rcsid[] = #define YYERROR_VERBOSE 1 extern char *yytext; -extern int pr_source_line; void yyerror (const char *s) @@ -181,8 +180,6 @@ type_t *current_ivars; scope_t *current_scope; storage_class_t current_storage; -string_t s_file; // filename for function definition - int element_flag; %} @@ -493,7 +490,7 @@ begin_function if (options.code.debug) { pr_lineno_t *lineno = new_lineno (); $$->aux = new_auxfunction (); - $$->aux->source_line = pr_source_line; + $$->aux->source_line = pr.source_line; $$->aux->line_info = lineno - linenos; $$->aux->local_defs = num_locals; diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index f06052053..55394dde2 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -89,9 +89,6 @@ char debugfile[1024]; pr_info_t pr; -int pr_source_line; -int pr_error_count; - ddef_t *globals; int numglobaldefs; @@ -133,8 +130,8 @@ InitData (void) memset (&pr, 0, sizeof (pr)); } chain_initial_types (); - pr_source_line = 1; - pr_error_count = 0; + pr.source_line = 1; + pr.error_count = 0; pr.num_statements = 1; pr.statements_size = 16384; pr.statements = calloc (pr.statements_size, sizeof (dstatement_t)); @@ -340,7 +337,7 @@ begin_compilation (void) pr.near_data->size = RESERVED_OFS; pr.func_tail = &pr.func_head; - pr_error_count = 0; + pr.error_count = 0; } qboolean @@ -482,8 +479,8 @@ compile_to_obj (const char *file, const char *obj) clear_structs (); clear_enums (); clear_typedefs (); - s_file = ReuseString (strip_path (file)); - err = yyparse () || pr_error_count; + pr.source_file = ReuseString (strip_path (file)); + err = yyparse () || pr.error_count; fclose (yyin); if (cpp_name && (!options.save_temps)) { if (unlink (tempname->str)) { @@ -602,10 +599,10 @@ progs_src_compile (void) yyin = preprocess_file (filename->str); - s_file = ReuseString (strip_path (filename->str)); - pr_source_line = 1; + pr.source_file = ReuseString (strip_path (filename->str)); + pr.source_line = 1; clear_frame_macros (); - err = yyparse () || pr_error_count; + err = yyparse () || pr.error_count; fclose (yyin); if (cpp_name && (!options.save_temps)) { if (unlink (tempname->str)) { diff --git a/tools/qfcc/source/switch.c b/tools/qfcc/source/switch.c index 78dc49f33..3f0e2bc8e 100644 --- a/tools/qfcc/source/switch.c +++ b/tools/qfcc/source/switch.c @@ -342,11 +342,11 @@ switch_expr (switch_block_t *switch_block, expr_t *break_label, expr_t *sw_val = new_temp_def_expr (type); expr_t *default_expr; int num_labels = 0; - int saved_line = pr_source_line; - string_t saved_file = s_file; + int saved_line = pr.source_line; + string_t saved_file = pr.source_file; - pr_source_line = sw_val->line = switch_block->test->line; - s_file = sw_val->file = switch_block->test->file; + pr.source_line = sw_val->line = switch_block->test->line; + pr.source_file = sw_val->file = switch_block->test->file; default_label->value = 0; default_label = Hash_DelElement (switch_block->labels, default_label); @@ -401,8 +401,8 @@ switch_expr (switch_block_t *switch_block, expr_t *break_label, } build_switch (sw, case_tree, op, sw_val, temp, default_label->label); } - pr_source_line = saved_line; - s_file = saved_file; + pr.source_line = saved_line; + pr.source_file = saved_file; append_expr (sw, statements); append_expr (sw, break_label); return sw;