diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index 093ab888c..f5289a3e9 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -595,6 +595,13 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum) pr->pr_argc = st->op - OP_CALL0; if (!OPA.func_var) PR_RunError (pr, "NULL function"); + if (OPA.func_var < 0) { // dynamic builtin + int i = -OPA.func_var; + if (i >= pr->numbuiltins || !pr->builtins[i].proc) + PR_RunError (pr, "Bad builtin call number"); + pr->builtins[i].proc (pr); + break; + } newf = &pr->pr_functions[OPA.func_var]; if (newf->first_statement < 0) { // negative statements are built in functions diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index 9be53acce..c0b87070a 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -2006,7 +2006,7 @@ PF_checkfunction (progs_t *pr) for (i = 0; i < pr->numbuiltins; i++) { if (pr->builtins[i].name && strequal (pr->builtins[i].name, name)) { - G_FUNCTION (pr, OFS_RETURN) = i; + G_FUNCTION (pr, OFS_RETURN) = -i; return; } } diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 07e6ef120..909437c8b 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -549,6 +549,7 @@ typedef struct { int warn_error; // treat warnings as errors int quiet; // not so much chatter int debug; // produce debug info + int undefined_function_warning; // print a warning when a function isn't defined } options_t; extern options_t options; diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index abfee4e94..36dba6843 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -151,6 +151,7 @@ static keyword_t keywords[] = { {"entity", TYPE, &type_entity }, {"quaternion", TYPE, &type_quaternion}, {"integer", TYPE, &type_integer }, + {"function", TYPE, &type_function }, {"local", LOCAL, 0 }, {"return", RETURN, 0 }, {"while", WHILE, 0 }, diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 34eff85bc..8fde0afba 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -706,16 +706,16 @@ PR_FinishCompilation (void) expr_t e; // check to make sure all functions prototyped have code - for (d = pr.def_head.def_next; d; d = d->def_next) { - if (d->type->type == ev_func && !d->scope) { // function args ok -// f = G_FUNCTION(d->ofs); -// if (!f || (!f->code && !f->builtin)) - if (!d->initialized) { - printf ("function %s was not defined\n", d->name); - errors = true; + if (options.undefined_function_warning) + for (d = pr.def_head.def_next; d; d = d->def_next) { + if (d->type->type == ev_func && !d->scope) { // function args ok +// f = G_FUNCTION(d->ofs); +// if (!f || (!f->code && !f->builtin)) + if (!d->initialized) { + warning (0, "function %s was not defined\n", d->name); + } } } - } if (errors) return !errors; @@ -920,15 +920,16 @@ main (int argc, char **argv) if (CheckParm ("-h") || CheckParm ("--help")) { printf ("%s - A compiler for the QuakeC language\n", argv[0]); printf ("Usage: %s [options]\n", argv[0]); - printf ("\ -Options: \n\ - -s, --source