diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 94037547..bf2f5fe5 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -89,7 +89,8 @@ void *PRAddressableExtend(progfuncs_t *progfuncs, void *src, size_t srcsize, int char *ptr; int ammount = (srcsize+pad + 4)&~3; //round up to 4 pad = ammount - srcsize; - if (prinst.addressableused + ammount > prinst.addressablesize) + pad++; //make sure there's always a null, to allow strings to be a little more lazy. + if (prinst.addressableused + ammount >= prinst.addressablesize) { /*only do this if the caller states that it can cope with addressable-block relocations/resizes*/ if (externs->addressablerelocated) @@ -127,7 +128,7 @@ void *PRAddressableExtend(progfuncs_t *progfuncs, void *src, size_t srcsize, int #endif } - if (prinst.addressableused + ammount > prinst.addressablesize) + if (prinst.addressableused + ammount >= prinst.addressablesize) externs->Sys_Error("Not enough addressable memory for progs VM (using %gmb)", prinst.addressablesize/(1024.0*1024)); } @@ -135,7 +136,7 @@ void *PRAddressableExtend(progfuncs_t *progfuncs, void *src, size_t srcsize, int progfuncs->funcs.stringtablesize = prinst.addressableused; #if defined(_WIN32) && !defined(WINRT) - if (!VirtualAlloc (prinst.addressablehunk, prinst.addressableused, MEM_COMMIT, PAGE_READWRITE)) + if (!VirtualAlloc (prinst.addressablehunk, prinst.addressableused+1, MEM_COMMIT, PAGE_READWRITE)) externs->Sys_Error("VirtualAlloc failed. Blame windows."); #endif @@ -807,14 +808,14 @@ static char *PDECL PR_VarString (pubprogfuncs_t *ppf, int first) progfuncs_t *progfuncs = (progfuncs_t*)ppf; int i; static char out[1024]; - char *s; - + const char *s; + out[0] = 0; for (i=first ; ifuncs.callargc ; i++) { - if (G_STRING(OFS_PARM0+i*3)) + s = PR_StringToNative(ppf, G_STRING(OFS_PARM0+i*3)); + if (s) { - s=G_STRING((OFS_PARM0+i*3)) + progfuncs->funcs.stringtable; if (strlen(out) + strlen(s) + 1 >= sizeof(out)) return out; strcat (out, s); @@ -1361,6 +1362,7 @@ static void PR_FreeAllTemps (progfuncs_t *progfuncs) } prinst.maxtempstrings = 0; prinst.nexttempstring = 0; + prinst.livetemps = 0; } #else static string_t PDECL PR_AllocTempStringLen (pubprogfuncs_t *ppf, char **str, unsigned int len) diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index c1b035d4..311b92ae 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -415,6 +415,8 @@ enum qcop_e { OP_MOD_F, OP_MOD_I, + OP_MOD_FI, + OP_MOD_IF, OP_MOD_V, OP_BITXOR_F, @@ -439,6 +441,9 @@ enum qcop_e { OP_BITXOR_V, OP_POW_F, + OP_POW_I, + OP_POW_FI, + OP_POW_IF, OP_CROSS_V, OP_EQ_FLD, diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index f8f92896..7e66c764 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -838,7 +838,7 @@ static const char *PR_ParseCast(const char *key, etype_t *t, pbool *isptr) if (*key == '(') { key++; - for (type = 0; type < 10; type++) + for (type = 0; type <= ev_variant; type++) { if (!strncmp(key, basictypenames[type], strlen(basictypenames[type]))) { @@ -854,7 +854,7 @@ static const char *PR_ParseCast(const char *key, etype_t *t, pbool *isptr) break; } } - if (type == 10) + if (type > ev_variant) return NULL; while(*key == ' ') diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 3c26c300..10596c68 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -450,9 +450,6 @@ unsigned int PDECL QC_NUM_FOR_EDICT(pubprogfuncs_t *progfuncs, struct edict_s *e #define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o)) #define G_VECTOR(o) (&pr_globals[o]) #define G_STRING(o) (*(string_t *)&pr_globals[o]) -#define G_STRING2(o) ((char*)*(string_t *)&pr_globals[o]) -#define GQ_STRING(o) (*(QCC_string_t *)&pr_globals[o]) -#define GQ_STRING2(o) ((char*)*(QCC_string_t *)&pr_globals[o]) #define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) #define G_PROG(o) G_FLOAT(o) //simply so it's nice and easy to change... @@ -461,7 +458,7 @@ unsigned int PDECL QC_NUM_FOR_EDICT(pubprogfuncs_t *progfuncs, struct edict_s *e #define E_FLOAT(e,o) (((float*)&e->v)[o]) #define E_INT(e,o) (*(int *)&((float*)&e->v)[o]) #define E_VECTOR(e,o) (&((float*)&e->v)[o]) -#define E_STRING(e,o) (*(string_t *)&((float*)(e+1))[o]) +//#define E_STRING(e,o) (*(string_t *)&((float*)(e+1))[o]) extern const unsigned int type_size[]; diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index af910f83..6b61f786 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -623,6 +623,7 @@ extern pbool keyword_union; //you surly know what a union is! extern pbool keyword_wrap; extern pbool keyword_weak; extern pbool keyword_accumulate; +extern pbool keyword_using; extern pbool keyword_unused; extern pbool keyword_used; @@ -814,6 +815,7 @@ enum { WARN_FORMATSTRING, //sprintf WARN_DEPRECACTEDSYNTAX, //triggered when syntax is used that I'm trying to kill WARN_DEPRECATEDVARIABLE, //triggered from usage of a symbol that someone tried to kill + WARN_MUTEDEPRECATEDVARIABLE, //triggered from usage of a symbol that someone tried to kill (without having been muted). WARN_GMQCC_SPECIFIC, //extension created by gmqcc that conflicts or isn't properly implemented. WARN_FTE_SPECIFIC, //extension that only FTEQCC will have a clue about. WARN_EXTENSION_USED, //extension that frikqcc also understands @@ -948,6 +950,7 @@ enum COL_LOCATION, //to highlight file:line locations COL_NAME, //unknown symbols. COL_SYMBOL, //known symbols + COL_TYPE, //known types COL_MAX }; extern const char *qcccol[COL_MAX]; @@ -957,6 +960,7 @@ extern const char *qcccol[COL_MAX]; #define col_name qcccol[COL_NAME] #define col_warning qcccol[COL_WARNING] #define col_symbol qcccol[COL_SYMBOL] +#define col_type qcccol[COL_TYPE] #define FLAG_KILLSDEBUGGERS 1 #define FLAG_ASDEFAULT 2 diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 7ea9a745..30a822be 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -106,6 +106,7 @@ pbool keyword_union; //you surly know what a union is! pbool keyword_weak; pbool keyword_wrap; pbool keyword_accumulate; +pbool keyword_using; #define keyword_not 1 //hexenc support needs this, and fteqcc can optimise without it, but it adds an extra token after the if, so it can cause no namespace conflicts @@ -236,6 +237,7 @@ QCC_statement_t *QCC_Generate_OP_GOTO(void); QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage); static QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type, unsigned int *pif_flags); static void QCC_StoreToSRef(QCC_sref_t dest, QCC_sref_t source, QCC_type_t *type, pbool preservesource, pbool preservedest); +void QCC_PR_ParseStatement (void); //NOTE: prints may use from the func argument's symbol, which can be awkward if its a temp. QCC_sref_t QCC_PR_GenerateFunctionCallSref (QCC_sref_t newself, QCC_sref_t func, QCC_sref_t *arglist, int argcount); @@ -282,6 +284,7 @@ QCC_type_t *pr_classtype; // the class that the current function is part of. QCC_type_t *pr_assumetermtype; //undefined things get this time, with no warning about being undeclared (used for the state function, so prototypes are not needed) QCC_function_t *pr_assumetermscope; unsigned int pr_assumetermflags; //GDF_ +pbool pr_ignoredeprecation; pbool pr_dumpasm; const char *s_filen; QCC_string_t s_filed; // filename for function definition @@ -739,6 +742,8 @@ QCC_opcode_t pr_opcodes[] = {7, "%", "MOD_F", PC_MULDIV, ASSOC_LEFT, &type_float, &type_float, &type_float, OPF_STD}, {7, "%", "MOD_I", PC_MULDIV, ASSOC_LEFT, &type_integer, &type_integer, &type_integer, OPF_STD}, + {7, "%", "MOD_FI", PC_MULDIV, ASSOC_LEFT, &type_float, &type_integer, &type_integer, OPF_STD}, + {7, "%", "MOD_IF", PC_MULDIV, ASSOC_LEFT, &type_integer, &type_float, &type_integer, OPF_STD}, {7, "%", "MOD_V", PC_MULDIV, ASSOC_LEFT, &type_vector, &type_vector, &type_vector, OPF_STD}, {7, "^", "BITXOR_F", PC_BITXOR, ASSOC_LEFT, &type_float, &type_float, &type_float, OPF_STD}, @@ -763,6 +768,9 @@ QCC_opcode_t pr_opcodes[] = {7, "^", "BITXOR_V", PC_BITXOR, ASSOC_LEFT, &type_vector, &type_vector, &type_vector, OPF_STD}, {7, "*^", "POW_F", PC_MULDIV, ASSOC_LEFT, &type_float, &type_float, &type_float, OPF_STD}, + {7, "*^", "POW_I", PC_MULDIV, ASSOC_LEFT, &type_integer, &type_integer, &type_integer, OPF_STD}, + {7, "*^", "POW_FI", PC_MULDIV, ASSOC_LEFT, &type_float, &type_integer, &type_float, OPF_STD}, + {7, "*^", "POW_IF", PC_MULDIV, ASSOC_LEFT, &type_integer, &type_float, &type_float, OPF_STD}, {7, "><", "CROSS_V", PC_MULDIV, ASSOC_LEFT, &type_vector, &type_vector, &type_vector, OPF_STD}, {7, "==", "EQ_FLD", PC_EQUALITY, ASSOC_LEFT, &type_field, &type_field, &type_float, OPF_STD}, @@ -3417,6 +3425,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ if (!QCC_OPCodeValid(op) && !(flags&STFL_NOEMULATE)) { +#define QCC_PR_EmulationFunc(n) QCC_PR_GetSRef(NULL, #n, pr_scope, false, 0, 0) QCC_sref_t tmp; //FIXME: add support for flags so we don't corrupt temps switch(op - pr_opcodes) @@ -3428,7 +3437,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ break; case OP_ADD_SF: - var_c = QCC_PR_GetSRef(NULL, "AddStringFloat", NULL, false, 0, 0); + var_c = QCC_PR_EmulationFunc(AddStringFloat); if (var_c.cast) var_c = QCC_PR_GenerateFunctionCall2(nullsref, var_c, var_a, type_string, var_b, type_float); else @@ -3453,7 +3462,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ else { QCC_PR_ParseWarning(WARN_DENORMAL, "OP_ADD_EF: denormals are unsafe"); - var_c = QCC_PR_GetSRef(NULL, "nextent", NULL, false, 0, false); + var_c = QCC_PR_EmulationFunc(nextent); if (!var_c.cast) QCC_PR_ParseError(0, "the nextent builtin is not defined"); var_c = QCC_PR_GenerateFunctionCall1 (nullsref, var_c, QCC_MakeIntConst(0), type_entity); @@ -3471,7 +3480,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ QCC_PR_ParseWarning(0, "qccx entity offsets are unsafe"); else { - var_c = QCC_PR_GetSRef(NULL, "nextent", NULL, false, 0, false); + var_c = QCC_PR_EmulationFunc(nextent); if (!var_c.cast) QCC_PR_ParseError(0, "the nextent builtin is not defined"); var_c = QCC_PR_GenerateFunctionCall1 (nullsref, var_c, QCC_MakeIntConst(0), type_entity); @@ -3538,7 +3547,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ case OP_BITAND_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "BitandInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(BitandInt); if (!fnc.cast) QCC_PR_ParseError(0, "BitandInt function not defined: cannot emulate int&int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); @@ -3548,7 +3557,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ break; case OP_BITOR_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "BitorInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(BitorInt); if (!fnc.cast) QCC_PR_ParseError(0, "BitorInt function not defined: cannot emulate int|int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); @@ -3574,7 +3583,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ return var_c; case OP_ADD_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "AddInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(AddInt); if (!fnc.cast) QCC_PR_ParseError(0, "AddInt function not defined: cannot emulate int+int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); @@ -3582,19 +3591,9 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ return var_c; } break; - case OP_MOD_I: - { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "ModInt", NULL, false, 0, 0); - if (!fnc.cast) - QCC_PR_ParseError(0, "ModInt function not defined: cannot emulate int%%int"); - var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); - var_c.cast = type_integer; - return var_c; - } - break; case OP_MOD_F: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "mod", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(mod); if (!fnc.cast) { //a - (n * floor(a/n)); @@ -3611,9 +3610,68 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ return var_c; } break; + case OP_MOD_I: + { + QCC_sref_t fnc = QCC_PR_EmulationFunc(ModInt); + if (!fnc.cast) + { + //a - (n * floor(a/n)); + //(except using v|v instead of floor) + var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_DIV_I], var_a, var_b, NULL, STFL_CONVERTA|STFL_CONVERTB|STFL_PRESERVEA|STFL_PRESERVEB); + //var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_BITOR_I], var_c, var_c, NULL, STFL_PRESERVEA); + var_c = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], var_b, var_c, NULL); + return QCC_PR_Statement(&pr_opcodes[OP_SUB_I], var_a, var_c, NULL); + +// QCC_PR_ParseError(0, "mod function not defined: cannot emulate int%%int"); + } + var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); + var_c.cast = type_integer; + return var_c; + } + break; + case OP_MOD_FI: + { + QCC_sref_t fnc = QCC_PR_EmulationFunc(mod); + if (!fnc.cast) + { + //a - (n * floor(a/n)); + //(except using v|v instead of floor) + var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_DIV_FI], var_a, var_b, NULL, STFL_CONVERTA|STFL_CONVERTB|STFL_PRESERVEA|STFL_PRESERVEB); + var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_BITOR_F], var_c, var_c, NULL, STFL_PRESERVEA); + var_c = QCC_PR_Statement(&pr_opcodes[OP_MUL_IF], var_b, var_c, NULL); + return QCC_PR_Statement(&pr_opcodes[OP_SUB_F], var_a, var_c, NULL); + +// QCC_PR_ParseError(0, "mod function not defined: cannot emulate float%%int"); + } + var_b = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_b, nullsref, NULL, (flags&STFL_PRESERVEB)?STFL_PRESERVEA:0); + var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_float, var_b, type_float); + var_c.cast = type_float; + return var_c; + } + break; + case OP_MOD_IF: + { + QCC_sref_t fnc = QCC_PR_EmulationFunc(mod); + if (!fnc.cast) + { + //a - (n * floor(a/n)); + //(except using v|v instead of floor) + var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_DIV_IF], var_a, var_b, NULL, STFL_CONVERTA|STFL_CONVERTB|STFL_PRESERVEA|STFL_PRESERVEB); + var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_BITOR_F], var_c, var_c, NULL, STFL_PRESERVEA); + var_c = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], var_b, var_c, NULL); + return QCC_PR_Statement(&pr_opcodes[OP_SUB_IF], var_a, var_c, NULL); + +// QCC_PR_ParseError(0, "mod function not defined: cannot emulate int%%float"); + } + var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_a, nullsref, NULL, flags&STFL_PRESERVEA); + var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_float, var_b, type_float); + var_c.cast = type_float; + return var_c; + } + break; case OP_MOD_V: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "ModVec", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(ModVec); if (!fnc.cast) QCC_PR_ParseError(0, "ModVec function not defined: cannot emulate vector%%vector"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_vector, var_b, type_vector); @@ -3623,7 +3681,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ break; case OP_SUB_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "SubInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(SubInt); if (!fnc.cast) QCC_PR_ParseError(0, "SubInt function not defined: cannot emulate int-int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); @@ -3633,7 +3691,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ break; case OP_MUL_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "MulInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(MulInt); if (!fnc.cast) QCC_PR_ParseError(0, "MulInt function not defined: cannot emulate int*int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); @@ -3643,7 +3701,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ break; case OP_DIV_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "DivInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(DivInt); if (!fnc.cast) QCC_PR_ParseError(0, "DivInt function not defined: cannot emulate int/int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_integer, var_b, type_integer); @@ -3661,7 +3719,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ case OP_POW_F: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "pow", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(pow); if (!fnc.cast) QCC_PR_ParseError(0, "pow function not defined: cannot emulate float*^float"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_float, var_b, type_float); @@ -3669,6 +3727,40 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ return var_c; } break; + case OP_POW_I: + { + QCC_sref_t fnc = QCC_PR_EmulationFunc(pow); + if (!fnc.cast) + QCC_PR_ParseError(0, "pow function not defined: cannot emulate float*^float"); + var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_a, nullsref, NULL, flags&STFL_PRESERVEA); + var_b = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_b, nullsref, NULL, (flags&STFL_PRESERVEB)?STFL_PRESERVEA:0); + var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_float, var_b, type_float); + var_c.cast = type_float; + return var_c; + } + break; + case OP_POW_FI: + { + QCC_sref_t fnc = QCC_PR_EmulationFunc(pow); + if (!fnc.cast) + QCC_PR_ParseError(0, "pow function not defined: cannot emulate float*^int"); + var_b = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_b, nullsref, NULL, (flags&STFL_PRESERVEB)?STFL_PRESERVEA:0); + var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_float, var_b, type_float); + var_c.cast = type_float; + return var_c; + } + break; + case OP_POW_IF: + { + QCC_sref_t fnc = QCC_PR_EmulationFunc(pow); + if (!fnc.cast) + QCC_PR_ParseError(0, "pow function not defined: cannot emulate int*^float"); + var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_CONV_FTOI], var_a, nullsref, NULL, flags&STFL_PRESERVEA); + var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, var_a, type_float, var_b, type_float); + var_c.cast = type_float; + return var_c; + } + break; case OP_CROSS_V: { QCC_sref_t t; @@ -3698,7 +3790,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ } else { - var_c = QCC_PR_GetSRef(NULL, "itof", NULL, false, 0, 0); + var_c = QCC_PR_EmulationFunc(itof); if (!var_c.cast) { //with denormals, 5.0 * 1i -> 5i, and 5i / 1i = 5.0 @@ -3724,7 +3816,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ } else { - var_c = QCC_PR_GetSRef(NULL, "ftoi", NULL, false, 0, 0); + var_c = QCC_PR_EmulationFunc(ftoi); if (!var_c.cast) { //with denormals, 5 * 1i -> 5i @@ -3754,7 +3846,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ case OP_BITXOR_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "BitxorInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(BitxorInt); if (!fnc.cast) { QCC_PR_ParseError(0, "BitxorInt function not defined: cannot emulate int^int"); @@ -3867,7 +3959,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ } else { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "SubInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(SubInt); if (!fnc.cast) QCC_PR_ParseError(0, "SubInt function not defined: cannot emulate ~int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, QCC_MakeIntConst(~0), type_integer, var_a, type_integer); @@ -4245,7 +4337,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ case OP_LSHIFT_I: { - QCC_sref_t fnc = QCC_PR_GetSRef(NULL, "LShiftInt", NULL, false, 0, 0); + QCC_sref_t fnc = QCC_PR_EmulationFunc(LShiftInt); if (!fnc.cast) QCC_PR_ParseError(0, "LShiftInt function not defined: cannot emulate int<>int"); var_c = QCC_PR_GenerateFunctionCall2(nullsref, fnc, QCC_MakeIntConst(~0), type_integer, var_a, type_integer); @@ -4275,10 +4367,10 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_ else { QCC_sref_t fnc; - fnc = QCC_PR_GetSRef(NULL, "pow", NULL, false, 0, 0); + fnc = QCC_PR_EmulationFunc(pow); if (fnc.cast) { //a<string, col_none); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: surplus trailing %s%s%s argument(s) for format %s\"%s\"%s", funcname, col_type, TypeName(ARGCTYPE(argpos), temp, sizeof(temp)), col_none, col_name, strings + formatstring->string, col_none); return; case '%': if(*++s == '%') @@ -5214,7 +5306,7 @@ nolength: break; default: { - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires float at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires float at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_type, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); } break; } @@ -5229,7 +5321,7 @@ nolength: case ev_variant: break; default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires pointer at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires pointer at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_type, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); break; } } @@ -5245,7 +5337,7 @@ nolength: break; //fallthrough default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires int at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires int at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_type, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); break; } } @@ -5260,12 +5352,12 @@ nolength: case ev_variant: break; default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires vector at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires vector at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_type, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); break; } } else - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires intvector at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires intvector at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_type, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); break; case 's': case 'S': @@ -5275,7 +5367,7 @@ nolength: case ev_variant: break; default: - QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires string at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); + QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires string at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_type, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none); break; } break; @@ -6627,7 +6719,7 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f func.sym->referenced = true; QCC_FreeTemp(func); - sz = QCC_PR_Expression(TOP_PRIORITY, 0); + sz = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); QCC_PR_Expect(")"); sz = QCC_SupplyConversion(sz, ev_integer, true); //result = push_words((sz+3)/4); @@ -6988,7 +7080,7 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f e = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); QCC_PR_Expect(")"); e = QCC_PR_StatementFlags(&pr_opcodes[OP_DIV_I], e, QCC_MakeIntConst(1), NULL, 0); - d = QCC_PR_GetSRef(NULL, "nextent", NULL, false, 0, false); + d = QCC_PR_EmulationFunc(nextent); if (!d.cast) QCC_PR_ParseError(0, "the nextent builtin is not defined"); QCC_UnFreeTemp(e); @@ -6999,6 +7091,27 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f return e; } } //so it's not an intrinsic. + else if (!newself.cast && t->num_parms == 1 && t->type == ev_function) + { + if (!strcmp(funcname, "checkbuiltin")) + { + pr_ignoredeprecation = true; + param[0] = QCC_PR_RefExpression (¶mbuf[0], TOP_PRIORITY, EXPR_DISALLOW_COMMA); + pr_ignoredeprecation = false; + QCC_PR_Expect(")"); + + if (param[0]->type == REF_GLOBAL && param[0]->cast == param[0]->base.sym->type && !param[0]->base.sym->arraysize) + { + e.ofs = param[0]->base.ofs; + e.cast = param[0]->cast; + e.sym = QCC_PR_DummyDef(e.cast, param[0]->base.sym->name, pr_scope, 0, param[0]->base.sym, 0, true, GDF_STRIP); + e = QCC_PR_GenerateFunctionCallSref(newself, func, &e, 1); + } + else + e = QCC_PR_GenerateFunctionCallRef(newself, func, param, 1); + return e; + } + } if (opt_precache_file) //should we strip out all precache_file calls? { @@ -8847,7 +8960,7 @@ static QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool im char typeb[256]; TypeName(src.cast, typea, sizeof(typea)); TypeName(cast, typeb, sizeof(typeb)); - QCC_PR_ParseWarning(WARN_IMPLICITVARIANTCAST, "Implicit cast from %s to %s", typea, typeb); + QCC_PR_ParseWarning(WARN_IMPLICITVARIANTCAST, "Implicit cast from %s%s%s to %s%s%s", col_type,typea,col_none, col_type,typeb,col_none); } src = QCC_PR_Statement (&pr_opcodes[OP_MUL_FV], src, QCC_MakeVectorConst(1,1,1), NULL); } @@ -8869,7 +8982,7 @@ static QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool im char typeb[256]; TypeName(src.cast, typea, sizeof(typea)); TypeName(cast, typeb, sizeof(typeb)); - QCC_PR_ParseWarning(0, "Implicit cast from %s to %s", typea, typeb); + QCC_PR_ParseWarning(0, "Implicit cast from %s%s%s to %s%s%s", col_type,typea,col_none, col_type,typeb,col_none); } } src.cast = cast; @@ -8892,7 +9005,7 @@ static QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool im char typeb[256]; TypeName(src.cast, typea, sizeof(typea)); TypeName(cast, typeb, sizeof(typeb)); - QCC_PR_ParseWarning(0, "Implicit cast from %s to %s", typea, typeb); + QCC_PR_ParseWarning(0, "Implicit cast from %s%s%s to %s%s%s", col_type,typea,col_none, col_type,typeb,col_none); } } src.cast = cast; @@ -8909,7 +9022,7 @@ static QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool im char typeb[256]; TypeName(src.cast, typea, sizeof(typea)); TypeName(cast, typeb, sizeof(typeb)); - QCC_PR_ParseWarning(WARN_IMPLICITVARIANTCAST, "Implicit cast from %s to %s", typea, typeb); + QCC_PR_ParseWarning(WARN_IMPLICITVARIANTCAST, "Implicit cast from %s%s%s to %s%s%s", col_type,typea,col_none, col_type,typeb,col_none); } } /*these casts are acceptable but probably an error (so warn when implicit)*/ @@ -8934,7 +9047,7 @@ static QCC_sref_t QCC_TryEvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool im char typeb[256]; TypeName(src.cast, typea, sizeof(typea)); TypeName(cast, typeb, sizeof(typeb)); - QCC_PR_ParseWarning(0, "Implicit cast from %s to %s", typea, typeb); + QCC_PR_ParseWarning(0, "Implicit cast from %s%s%s to %s%s%s", col_type,typea,col_none, col_type,typeb,col_none); } src.cast = cast; } @@ -8959,7 +9072,7 @@ QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit) char typeb[256]; TypeName(src.cast, typea, sizeof(typea)); TypeName(cast, typeb, sizeof(typeb)); - QCC_PR_ParseWarning(0, "Implicit cast from %s to %s", typea, typeb); + QCC_PR_ParseWarning(0, "Implicit cast from %s%s%s to %s%s%s", col_type,typea,col_none, col_type,typeb,col_none); } src.cast = cast; return src; @@ -11494,7 +11607,73 @@ static void PR_GenerateReturnOuts(void) } } +static void QCC_PR_ParseStatement_Using(void) +{ //the 'using(...) {}' control statement exists mainly to mute warnings about deprecations within its block. + //it does this by basically creating a private alias for each name given in the parenthasis (new=orig to give the alias a different name). + QCC_def_t *d; + QCC_def_t *subscopestop; + QCC_def_t *subscopestart = pr.local_tail; + //QCC_type_t *lt = NULL, *type; + pbool block = QCC_PR_CheckToken("("); + do + { + /*type = QCC_PR_ParseType (false, true); + if (type) + { + d = QCC_PR_GetDef (type, QCC_PR_ParseName(), pr_scope, true, 0, 0); + if (QCC_PR_CheckToken("=")) + QCC_PR_ParseInitializerDef(d, 0); + QCC_FreeDef(d); + lt = type; + } + else*/ + { //define an alias of the variable with the same name + const char *name = QCC_PR_ParseName(); + + QCC_def_t *def = QCC_PR_GetDef (NULL, name, pr_scope, false, 0, 0); + if (!def) + QCC_PR_ParseError(ERR_NOTDEFINED, "%s is not defined", name); + def->referenced = true; + if (QCC_PR_CheckToken("=")) + name = QCC_PR_ParseName(); //they wanted a different name for it. + if (def->deprecated) + { + if (*def->deprecated) //we have a reason for it + QCC_PR_ParseWarning(WARN_MUTEDEPRECATEDVARIABLE, "Variable \"%s\" is deprecated: %s", def->name, def->deprecated); + else //we don't have any reason for it. + QCC_PR_ParseWarning(WARN_MUTEDEPRECATEDVARIABLE, "Variable \"%s\" is deprecated", def->name); + } + def = QCC_PR_DummyDef(def->type, name, pr_scope, def->arraysize, def, 0, true, GDF_STRIP); + } + } while(QCC_PR_CheckToken(",")); + + pr_assumetermtype = NULL; + if (block) + QCC_PR_Expect(")"); + else + { //applies to whole rest of scope... + QCC_PR_Expect(";"); + return; + } + + subscopestop = pr_subscopedlocals?NULL:pr.local_tail->nextlocal; + + QCC_PR_ParseStatement(); //don't give the hanging ';' warning. + + //remove any new locals from the hashtable. + //typically this is just the stuff inside the for(here;;) + for (d = subscopestart->nextlocal; d != subscopestop; d = d->nextlocal) + { + if (!d->subscoped_away) + { + pHash_RemoveData(&localstable, d->name, d); + d->subscoped_away = true; + } + } + + return; +} /* ============ @@ -11503,7 +11682,6 @@ QCC_PR_ParseStatement_For pulled out of QCC_PR_ParseStatement because of stack use. ============ */ -void QCC_PR_ParseStatement (void); static void QCC_PR_ParseStatement_For(void) { int continues; @@ -12410,6 +12588,12 @@ void QCC_PR_ParseStatement (void) return; } + if (QCC_PR_CheckKeyword(keyword_using, "using")) + { + QCC_PR_ParseStatement_Using(); + return; + } + if (QCC_PR_CheckKeyword(keyword_asm, "asm")) { if (QCC_PR_CheckToken("{")) @@ -14998,10 +15182,10 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_functio def = pHash_GetNext(&localstable, name, def); continue; } - QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2))); + QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s%s%s. %s%s%s, should be %s%s%s",col_symbol,name,col_none, col_type,TypeName(type, typebuf1, sizeof(typebuf1)),col_none, col_type,TypeName(def->type, typebuf2, sizeof(typebuf2)),col_none); } if (def->arraysize != arraysize && arraysize>=0) - QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name); + QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s%s%s do not match",col_symbol,name,col_none); if (allocate && scope && !(flags & GDF_STATIC)) { if (pr_subscopedlocals) @@ -15010,17 +15194,17 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_functio continue; } if (allocate == 2) - QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Duplicate definition of %s.", name); + QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Duplicate definition of %s%s%s.", col_symbol,name,col_none); if (def->isstatic) - QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "nonstatic redeclaration of %s ignored", name); + QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "nonstatic redeclaration of %s%s%s ignored", col_symbol,name,col_none); else - QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name); + QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s%s%s duplicate definition ignored", col_symbol,name,col_none); QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def); // if (!scope) // QCC_PR_ParsePrintDef(def); } else if (allocate && (flags & GDF_STATIC) && !def->isstatic) - QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "static redefinition of %s follows non-static definition.", name); + QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "static redefinition of %s%s%s follows non-static definition.", col_symbol,name,col_none); QCC_ForceUnFreeDef(def); return def; @@ -15058,7 +15242,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_functio if (allocate) { //if we're asserting a type for it in some def then it'll no longer be assumed. if (def->type->type != type->type) - QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. Basic types are different.",name); + QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s%s%s. Basic types are different.",col_symbol,name,col_none); def->type = type; def->assumedtype = false; def->filen = s_filen; @@ -15108,7 +15292,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_functio else { //unequal even when we're lax - QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2))); + QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s%s%s. %s%s%s, should be %s%s%s",col_symbol,name,col_none, col_type,TypeName(type, typebuf1, sizeof(typebuf1)),col_none, col_type,TypeName(def->type, typebuf2, sizeof(typebuf2)),col_none); } } } @@ -15118,7 +15302,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_functio { //if the second def simply has no ..., don't bother warning about it. - QCC_PR_ParseWarning (WARN_TYPEMISMATCHREDECOPTIONAL, "Optional arguments differ on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2))); + QCC_PR_ParseWarning (WARN_TYPEMISMATCHREDECOPTIONAL, "Optional arguments differ on redeclaration of %s%s%s. %s%s%s, should be %s%s%s",col_symbol,name,col_none, col_type,TypeName(type, typebuf1, sizeof(typebuf1)),col_none, col_type,TypeName(def->type, typebuf2, sizeof(typebuf2)),col_none); QCC_PR_ParsePrintDef(WARN_TYPEMISMATCHREDECOPTIONAL, def); if (type->type == ev_function) @@ -15192,7 +15376,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_functio if (scope && qccwarningaction[WARN_SAMENAMEASGLOBAL]) { - def = QCC_PR_GetDef(NULL, name, NULL, false, arraysize, false); + def = QCC_PR_GetDef(NULL, name, NULL, false, arraysize, GDF_SILENT); if (def && def->type->type == type->type) { //allow type differences. this means that arguments called 'min' or 'mins' are accepted with the 'min' builtin or the 'mins' field in existance. QCC_PR_ParseWarning(WARN_SAMENAMEASGLOBAL, "Local \"%s\" hides global with same name and type", name); @@ -15220,9 +15404,9 @@ QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, const char *name, QCC_function_t *s if (def->deprecated) { if (*def->deprecated) //we have a reason for it - QCC_PR_ParseWarning(WARN_DEPRECATEDVARIABLE, "Variable \"%s\" is deprecated: %s", def->name, def->deprecated); + QCC_PR_ParseWarning(pr_ignoredeprecation?WARN_MUTEDEPRECATEDVARIABLE:WARN_DEPRECATEDVARIABLE, "Variable \"%s\" is deprecated: %s", def->name, def->deprecated); else //we don't have any reason for it. - QCC_PR_ParseWarning(WARN_DEPRECATEDVARIABLE, "Variable \"%s\" is deprecated", def->name); + QCC_PR_ParseWarning(pr_ignoredeprecation?WARN_MUTEDEPRECATEDVARIABLE:WARN_DEPRECATEDVARIABLE, "Variable \"%s\" is deprecated", def->name); } return sr; } @@ -15910,9 +16094,11 @@ pbool QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags) { + pr_ignoredeprecation = !!def->deprecated; //mute deprecation warnings if the symbol we're defining has its own warning. if (QCC_PR_ParseInitializerType(def->arraysize, def, QCC_MakeSRef(def, 0, def->type), flags)) if (!def->initialized) def->initialized = 1; + pr_ignoredeprecation = false; QCC_FreeDef(def); } QCC_sref_t QCC_PR_ParseDefaultInitialiser(QCC_type_t *type) @@ -16142,6 +16328,7 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal) const char *aliasof = NULL; pr_assumetermtype = NULL; + pr_ignoredeprecation = false; while (QCC_PR_CheckToken(";")) fatal = false; @@ -16385,7 +16572,14 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal) { if (pr_token_type == tt_immediate && pr_immediate_type == type_string) { - deprecated = strcpy(qccHunkAlloc(strlen(pr_immediate_string)+1), pr_immediate_string); + if (deprecated) + { + char *n = qccHunkAlloc(strlen(deprecated)+2+strlen(pr_immediate_string)+1); + sprintf(n, "%s; %s", deprecated, pr_immediate_string); + deprecated = n; + } + else + deprecated = strcpy(qccHunkAlloc(strlen(pr_immediate_string)+1), pr_immediate_string); QCC_PR_Lex(); } else @@ -16862,7 +17056,7 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal) isconst = (isconstant || (!isvar && !pr_scope)); if (isconst != def->constant) { //we should only be optimising consts if its initialised, so it shouldn't have been read as 0 at any point so far. - QCC_PR_ParseWarning(WARN_REDECLARATIONMISMATCH, "Redeclaration of %s would change const.", def->name); + QCC_PR_ParseWarning(WARN_REDECLARATIONMISMATCH, "Redeclaration of %s would change to %sconst.", def->name, isconst?"":"non-"); QCC_PR_ParsePrintDef(WARN_REDECLARATIONMISMATCH, def); // def->constant = isconst; } @@ -17027,6 +17221,7 @@ pbool QCC_PR_CompileFile (char *string, char *filename) pr_file_p = string; pr_assumetermtype = NULL; + pr_ignoredeprecation = false; pr_source_line = 0; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 7426ccc2..4bda8729 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -5407,9 +5407,9 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) return newt; if (pr_scope) - QCC_PR_ParseError(ERR_REDECLARATION, "Declaration of class %s within function", classname); + QCC_PR_ParseError(ERR_REDECLARATION, "Declaration of class %s%s%s within function", col_type,classname,col_none); if (redeclaration && fieldtype != newt->parentclass) - QCC_PR_ParseError(ERR_REDECLARATION, "Parent class changed on redeclaration of %s", classname); + QCC_PR_ParseError(ERR_REDECLARATION, "Parent class changed on redeclaration of %s%s%s", col_type,classname,col_none); newt->parentclass = fieldtype; if (QCC_PR_CheckToken(",")) diff --git a/engine/qclib/qccguiqt.cpp b/engine/qclib/qccguiqt.cpp index 04962655..fc1290fb 100644 --- a/engine/qclib/qccguiqt.cpp +++ b/engine/qclib/qccguiqt.cpp @@ -2510,22 +2510,28 @@ static bool DebuggerSendCommand(const char *msg, ...) va_end(va); return true; } +extern "C" pbool QCC_PR_SimpleGetToken (void); static void DebuggerStart(void) { DebuggerStop(); const char *engine = enginebinary; - const char *cmdline = enginecommandline; + char *cmdline = enginecommandline; if (!*enginebinary) { engine = "fteqw"; if(!*cmdline) - cmdline = "-window"; + cmdline = (char*)"-window"; } qcdebugger = new QProcess(mainwnd); qcdebugger->setProgram(engine); qcdebugger->setWorkingDirectory(enginebasedir); - qcdebugger->setArguments(QStringList(cmdline)); + + QStringList args; + pr_file_p = cmdline; + while (QCC_PR_SimpleGetToken()) + args.append(pr_token); + qcdebugger->setArguments(args); QObject::connect(qcdebugger, static_cast(&QProcess::finished), [=](int exitcode,QProcess::ExitStatus status) diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index d96cf8ee..39072d84 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -27,11 +27,8 @@ extern int optres_test2; pbool writeasm; pbool verbose; #define VERBOSE_STANDARD 1 -#define VERBOSE_FILELIST 2 -#define VERBOSE_FIELDLIST 2 -#define VERBOSE_AUTOCVARLIST 2 -#define VERBOSE_DEBUG 3 -#define VERBOSE_DEBUGSTATEMENTS 4 //figuring out the files can be expensive. +#define VERBOSE_DEBUG 2 +#define VERBOSE_DEBUGSTATEMENTS 3 //figuring out the files can be expensive. pbool qcc_nopragmaoptimise; pbool opt_stripunusedfields; extern unsigned int locals_marshalled; @@ -139,6 +136,11 @@ int maxtypeinfos; pbool preprocessonly; +static pbool flag_dumpfilenames; +static pbool flag_dumpfields; +static pbool flag_dumpsymbols; +static pbool flag_dumpautocvars; + struct { char *name; @@ -227,6 +229,9 @@ struct { {" F326", WARN_DEPRECATEDVARIABLE}, {" F327", WARN_ENUMFLAGS_NOTINTEGER}, {" F328", WARN_DEPRECACTEDSYNTAX}, + {" F329", WARN_REDECLARATIONMISMATCH}, + {" F330", WARN_MUTEDEPRECATEDVARIABLE}, + {" F331", WARN_SELFNOTTHIS}, {" F207", WARN_NOTREFERENCEDFIELD}, {" F208", WARN_NOTREFERENCEDCONST}, @@ -249,6 +254,7 @@ struct { //we can put longer alternative names here... {" field-redeclared", WARN_REMOVEDWARNING}, + {" deprecated", WARN_DEPRECATEDVARIABLE}, {NULL} }; @@ -308,6 +314,7 @@ optimisations_t optimisations[] = }; #define defaultkeyword FLAG_HIDDENINGUI|FLAG_ASDEFAULT|FLAG_MIDCOMPILE +#define typekeyword FLAG_HIDDENINGUI|FLAG_ASDEFAULT #define nondefaultkeyword FLAG_HIDDENINGUI|0|FLAG_MIDCOMPILE #define hideflag FLAG_HIDDENINGUI|FLAG_MIDCOMPILE #define defaultflag FLAG_ASDEFAULT|FLAG_MIDCOMPILE @@ -330,8 +337,8 @@ compiler_flag_t compiler_flag[] = { {&keyword_float, defaultkeyword, "float", "Keyword: float", "Disables the 'float' keyword. (Disables the float keyword without 'local' preceeding it)"}, {&keyword_for, defaultkeyword, "for", "Keyword: for", "Disables the 'for' keyword. Syntax: for(assignment; while; increment) {codeblock;}"}, {&keyword_goto, defaultkeyword, "goto", "Keyword: goto", "Disables the 'goto' keyword."}, - {&keyword_int, defaultkeyword, "int", "Keyword: int", "Disables the 'int' keyword."}, - {&keyword_integer, defaultkeyword, "integer", "Keyword: integer", "Disables the 'integer' keyword."}, + {&keyword_int, typekeyword, "int", "Keyword: int", "Disables the 'int' keyword."}, + {&keyword_integer, typekeyword, "integer", "Keyword: integer", "Disables the 'integer' keyword."}, {&keyword_noref, defaultkeyword, "noref", "Keyword: noref", "Disables the 'noref' keyword."}, //nowhere else references this, don't warn about it. {&keyword_unused, nondefaultkeyword, "unused", "Keyword: unused", "Disables the 'unused' keyword. 'unused' means that the variable is unused, you're aware that its unused, and you'd rather not know about all the warnings this results in."}, {&keyword_used, nondefaultkeyword, "used", "Keyword: used", "Disables the 'used' keyword. 'used' means that the variable is used even if the qcc can't see how - thus preventing it from ever being stripped."}, @@ -359,6 +366,7 @@ compiler_flag_t compiler_flag[] = { {&keyword_wrap, defaultkeyword, "wrap", "Keyword: wrap", "Disables the 'wrap' keyword."}, {&keyword_weak, defaultkeyword, "weak", "Keyword: weak", "Disables the 'weak' keyword."}, {&keyword_accumulate, nondefaultkeyword,"accumulate", "Keyword: accumulate", "Disables the 'accumulate' keyword."}, + {&keyword_using, nondefaultkeyword,"using", "Keyword: using", "Disables the 'using' keyword."}, //options {&flag_acc, 0, "acc", "Reacc support", "Reacc is a pascall like compiler. It was released before the Quake source was released. This flag has a few effects. It sorts all qc files in the current directory into alphabetical order to compile them. It also allows Reacc global/field distinctions, as well as allows | for linebreaks. Whilst case insensitivity and lax type checking are supported by reacc, they are seperate compiler flags in fteqcc."}, //reacc like behaviour of src files. @@ -400,6 +408,10 @@ compiler_flag_t compiler_flag[] = { {&flag_embedsrc, FLAG_MIDCOMPILE,"embedsrc", "Embed Sources", "Write the sourcecode into the output file. The resulting .dat can be opened as a standard zip archive (or by fteqccgui).\nGood for GPL compliance!"}, // {&flag_noreflection, FLAG_MIDCOMPILE,"omitinternals","Omit Reflection Info", "Keeps internal symbols private (equivelent to unix's hidden visibility). This has the effect of reducing filesize, thwarting debuggers, and breaking saved games. This allows you to use arrays without massively bloating the size of your progs.\nWARNING: The bit about breaking saved games was NOT a joke, but does not apply to menuqc or csqc. It also interferes with FTE_MULTIPROGS."}, + {&flag_dumpfilenames, FLAG_MIDCOMPILE,"dumpfilenames","Write a .lst file", "Writes a .lst file which contains a list of all file names that we can detect from the qc. This file list can then be passed into external compression tools."}, + {&flag_dumpfields, FLAG_MIDCOMPILE,"dumpfields", "Write a .fld file", "Writes a .fld file that shows which fields are defined, along with their offsets etc, for weird debugging."}, + {&flag_dumpsymbols, FLAG_MIDCOMPILE,"dumpsymbols", "Write a .sym file", "Writes a .sym file alongside the dat which contains a list of all global symbols defined in the code (before stripping)"}, + {&flag_dumpautocvars, FLAG_MIDCOMPILE,"dumpautocvars","Write a .cfg file", "Writes a .cfg file that contains a default value for each autocvar listed in the code"}, {NULL} }; @@ -617,20 +629,52 @@ static void QCC_SortFields (void) } } -static void QCC_PrintFields (void) +static void QCC_DumpFields (const char *outputname) { + char line[1024]; extern char *basictypenames[]; int i; QCC_ddef_t *d; + int h; - externs->Printf("Fields Listing:\n"); - - for (i=0 ; i= 0) { - d = &fields[i]; - externs->Printf ("%5i : (%s) %s\n", d->ofs, basictypenames[d->type], strings + d->s_name); + for (i=0 ; iofs, basictypenames[d->type], strings + d->s_name); + } + + SafeClose(h); } } + +static void QCC_DumpSymbols (const char *outputname) +{ + char line[1024]; + QCC_def_t *def; + int h; + + snprintf(line, sizeof(line), "%s.sym", outputname); + h = SafeOpenWrite (line, 2*1024*1024); + if (h >= 0) + { + for (def = pr.def_head.next ; def ; def = def->next) + { + if ((def->scope && !def->isstatic) || !strcmp(def->name, "IMMEDIATE")) + continue; + if (def->symbolheader != def && def->symbolheader->type != def->type) + continue; //try to exclude vector components. + + snprintf(line, sizeof(line), "%s\n", def->name); + SafeWrite(h, line, strlen(line)); + } + SafeClose(h); + } +} + /* static void QCC_PrintGlobals (void) { @@ -646,53 +690,58 @@ static void QCC_PrintGlobals (void) } }*/ -static void QCC_PrintAutoCvars (void) +static void QCC_DumpAutoCvars (const char *outputname) { - int i; + char line[1024]; + int i, h; QCC_ddef_t *d; char *n; - externs->Printf("Auto Cvars:\n"); - for (i=0 ; i= 0) { - d = &qcc_globals[i]; - n = strings + d->s_name; - if (!strncmp(n, "autocvar_", 9)) + for (i=0 ; iofs]; - QCC_def_t *def = QCC_PR_GetDef(NULL, n, NULL, false, 0, 0); - n += 9; - - if (def->comment) - desc = def->comment; - else - desc = NULL; - - switch(d->type & ~(DEF_SAVEGLOBAL|DEF_SHARED)) + d = &qcc_globals[i]; + n = strings + d->s_name; + if (!strncmp(n, "autocvar_", 9)) { - case ev_float: - externs->Printf ("set %s\t%g%s%s\n", n, val->_float, desc?"\t//":"", desc?desc:""); - break; - case ev_vector: - externs->Printf ("set %s\t\"%g %g %g\"%s%s\n", n, val->vector[0], val->vector[1], val->vector[2], desc?"\t//":"", desc?desc:""); - break; - case ev_integer: - externs->Printf ("set %s\t%"pPRIi"%s%s\n", n, val->_int, desc?"\t//":"", desc?desc:""); - break; - case ev_string: - externs->Printf ("set %s\t\"%s\"%s%s\n", n, strings + val->_int, desc?"\t//":"", desc?desc:""); - break; - default: - externs->Printf ("//set %s\t ?%s%s\n", n, desc?"\t//":"", desc?desc:""); - break; + char *desc; + QCC_eval_t *val = &qcc_pr_globals[d->ofs]; + QCC_def_t *def = QCC_PR_GetDef(NULL, n, NULL, false, 0, 0); + n += 9; + + if (def->comment) + desc = def->comment; + else + desc = NULL; + + switch(d->type & ~(DEF_SAVEGLOBAL|DEF_SHARED)) + { + case ev_float: + snprintf(line, sizeof(line), "set %s\t%g%s%s\n", n, val->_float, desc?"\t//":"", desc?desc:""); + break; + case ev_vector: + snprintf(line, sizeof(line), "set %s\t\"%g %g %g\"%s%s\n", n, val->vector[0], val->vector[1], val->vector[2], desc?"\t//":"", desc?desc:""); + break; + case ev_integer: + snprintf(line, sizeof(line), "set %s\t%"pPRIi"%s%s\n", n, val->_int, desc?"\t//":"", desc?desc:""); + break; + case ev_string: + snprintf(line, sizeof(line), "set %s\t\"%s\"%s%s\n", n, strings + val->_int, desc?"\t//":"", desc?desc:""); + break; + default: + snprintf(line, sizeof(line), "//set %s\t ?%s%s\n", n, desc?"\t//":"", desc?desc:""); + break; + } + SafeWrite(h, line, strlen(line)); } } } - externs->Printf("\n"); } -static void QCC_PrintFiles (void) +static void QCC_DumpFiles (const char *outputname) { struct { @@ -1351,7 +1400,7 @@ static const char *QCC_FunctionForStatement(int st) } - +static void QCC_PR_CRCMessages(unsigned short crc); CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def); static pbool QCC_WriteData (int crc) { @@ -1415,6 +1464,7 @@ static pbool QCC_WriteData (int crc) if (i < numstatements) bigjumps = QCC_FunctionForStatement(i); + QCC_PR_CRCMessages(crc); switch (qcc_targetformat) { case QCF_HEXEN2: @@ -2196,14 +2246,16 @@ strofs = (strofs+3)&~3; else SafeWrite (h, funcdata, funcdatasize); - if (verbose >= VERBOSE_FILELIST) - QCC_PrintFiles(); + if (flag_dumpfilenames) + QCC_DumpFiles(destfile); - if (verbose >= VERBOSE_FIELDLIST) - QCC_PrintFields(); + if (flag_dumpfields) + QCC_DumpFields(destfile); - if (verbose >= VERBOSE_AUTOCVARLIST) - QCC_PrintAutoCvars(); + if (flag_dumpsymbols) + QCC_DumpSymbols(destfile); + if (flag_dumpautocvars) + QCC_DumpAutoCvars(destfile); switch(outputsttype) { @@ -3490,6 +3542,64 @@ static void Add_CrcOnly(char *p, unsigned short *crc, char *file) } #define EAT_CRC(p) Add_CrcOnly(p, &crc, file) +static void QCC_PR_CRCMessages(unsigned short crc) +{ + switch (crc) + { + case 12923: //#pragma sourcefile usage + break; + case 54730: + if (verbose) + externs->Printf("Recognised progs as QuakeWorld\n"); + break; + case 5927: + if (verbose) + externs->Printf("Recognised progs as NetQuake server gamecode\n"); + break; + + case 26940: + if (verbose) + externs->Printf("Recognised progs as Quake pre-release...\n"); + break; + + case 38488: + if (verbose) + externs->Printf("Recognised progs as original Hexen2\n"); + break; + case 26905: + if (verbose) + externs->Printf("Recognised progs as Hexen2 Mission Pack\n"); + break; + case 14046: + if (verbose) + externs->Printf("Recognised progs as Hexen2 (demo)\n"); + break; + + case 22390: //EXT_CSQC_1 + if (verbose) + externs->Printf("Recognised progs as an EXT_CSQC_1 module\n"); + break; + case 17105: + case 32199: //outdated ext_csqc + QCC_PR_Warning(WARN_SYSTEMCRC2, NULL, 0, "Recognised progs as outdated CSQC module\n"); + break; + case 52195: //this is what DP requires. don't print it as the warning that it is as that would royally piss off xonotic and their use of -Werror. + externs->Printf("Recognised progs as DP-specific CSQC module\n"); + break; + case 10020: + if (verbose) + externs->Printf("Recognised progs as a MenuQC module\n"); + break; + + case 32401: + QCC_PR_Warning(WARN_SYSTEMCRC, NULL, 0, "please update your tenebrae system defs.\n"); + break; + default: + QCC_PR_Warning(WARN_SYSTEMCRC, NULL, 0, "system defs not recognised from quake nor clones, probably buggy (sys)defs.qc\n"); + break; + } +} + static unsigned short QCC_PR_WriteProgdefs (char *filename) { #define ADD_ONLY(p) QC_strlcat(file, p, sizeof(file)) //no crc (later changes) @@ -3638,62 +3748,6 @@ static unsigned short QCC_PR_WriteProgdefs (char *filename) if (ForcedCRC) crc = ForcedCRC; - switch (crc) - { - case 12923: //#pragma sourcefile usage - break; - case 54730: - if (verbose) - externs->Printf("Recognised progs as QuakeWorld\n"); - break; - case 5927: - if (verbose) - externs->Printf("Recognised progs as NetQuake server gamecode\n"); - break; - - case 26940: - if (verbose) - externs->Printf("Recognised progs as Quake pre-release...\n"); - break; - - case 38488: - if (verbose) - externs->Printf("Recognised progs as original Hexen2\n"); - break; - case 26905: - if (verbose) - externs->Printf("Recognised progs as Hexen2 Mission Pack\n"); - break; - case 14046: - if (verbose) - externs->Printf("Recognised progs as Hexen2 (demo)\n"); - break; - - case 22390: //EXT_CSQC_1 - if (verbose) - externs->Printf("Recognised progs as an EXT_CSQC_1 module\n"); - break; - case 17105: - case 32199: //outdated ext_csqc - QCC_PR_Warning(WARN_SYSTEMCRC2, NULL, 0, "Recognised progs as outdated CSQC module\n"); - break; - case 52195: //this is what DP requires. don't print it as the warning that it is as that would royally piss off xonotic and their use of -Werror. - externs->Printf("Recognised progs as DP-specific CSQC module\n"); - break; - case 10020: - if (verbose) - externs->Printf("Recognised progs as a DP/FTE Menu module\n"); - break; - - case 32401: - QCC_PR_Warning(WARN_SYSTEMCRC, NULL, 0, "please update your tenebrae system defs.\n"); - break; - default: - QCC_PR_Warning(WARN_SYSTEMCRC, NULL, 0, "system defs not recognised from quake nor clones, probably buggy (sys)defs.qc\n"); - break; - } - - return crc; } @@ -4428,9 +4482,10 @@ static void QCC_PR_CommandLinePrecompilerOptions (void) break; //these warnings require -Wextra to enable, as they're too annoying to have to fix - case WARN_NOTREFERENCEDCONST: //warning about every single constant is annoying as heck. note that this includes both stuff like MOVETYPE_ and builtins. - case WARN_EXTRAPRECACHE: //we can't guarentee that we can parse this correctly. this warning is thus a common false positive. its available with -Wextra, and there's intrinsics to reduce false positives. - case WARN_FTE_SPECIFIC: //kinda annoying when its actually valid code. + case WARN_NOTREFERENCEDCONST: //warning about every single constant is annoying as heck. note that this includes both stuff like MOVETYPE_ and builtins. + case WARN_EXTRAPRECACHE: //we can't guarentee that we can parse this correctly. this warning is thus a common false positive. its available with -Wextra, and there's intrinsics to reduce false positives. + case WARN_FTE_SPECIFIC: //kinda annoying when its actually valid code. + case WARN_MUTEDEPRECATEDVARIABLE: //these were explicitly muted by the user using checkbuiltin/etc to mute specific symbols. break; default: @@ -4490,8 +4545,7 @@ static void QCC_PR_CommandLinePrecompilerOptions (void) p = QCC_WarningForName(a); if (p >= 0) qccwarningaction[p] = action; - - if (p < 0) + else QCC_PR_Warning(WARN_BADPARAMS, "cmdline", 0, "Unrecognised warning parameter (%s)", myargv[i]); } } @@ -4622,21 +4676,22 @@ static void QCC_SetDefaultProperties (void) qccwarningaction[i] = WA_ERROR; //play with default warnings. - qccwarningaction[WARN_NOTREFERENCEDCONST] = WA_IGNORE; - qccwarningaction[WARN_MACROINSTRING] = WA_IGNORE; -// qccwarningaction[WARN_ASSIGNMENTTOCONSTANT] = WA_IGNORE; - qccwarningaction[WARN_EXTRAPRECACHE] = WA_IGNORE; - qccwarningaction[WARN_DEADCODE] = WA_IGNORE; - qccwarningaction[WARN_FTE_SPECIFIC] = WA_IGNORE; - qccwarningaction[WARN_EXTENSION_USED] = WA_IGNORE; - qccwarningaction[WARN_IFSTRING_USED] = WA_IGNORE; - qccwarningaction[WARN_CORRECTEDRETURNTYPE] = WA_IGNORE; - qccwarningaction[WARN_NOTUTF8] = WA_IGNORE; - qccwarningaction[WARN_UNINITIALIZED] = WA_IGNORE; //not sure about this being ignored by default. - qccwarningaction[WARN_SELFNOTTHIS] = WA_IGNORE; - qccwarningaction[WARN_EVILPREPROCESSOR] = WA_ERROR; //evil people do evil things. evil must be thwarted! - qccwarningaction[WARN_IDENTICALPRECOMPILER] = WA_IGNORE; - qccwarningaction[WARN_DENORMAL] = WA_ERROR; //DAZ provides a speedup on modern machines, so any engine compiled for sse2+ will have problems with denormals, so make their use look serious. + qccwarningaction[WARN_NOTREFERENCEDCONST] = WA_IGNORE; + qccwarningaction[WARN_MACROINSTRING] = WA_IGNORE; +// qccwarningaction[WARN_ASSIGNMENTTOCONSTANT] = WA_IGNORE; + qccwarningaction[WARN_EXTRAPRECACHE] = WA_IGNORE; + qccwarningaction[WARN_DEADCODE] = WA_IGNORE; + qccwarningaction[WARN_FTE_SPECIFIC] = WA_IGNORE; + qccwarningaction[WARN_MUTEDEPRECATEDVARIABLE] = WA_IGNORE; + qccwarningaction[WARN_EXTENSION_USED] = WA_IGNORE; + qccwarningaction[WARN_IFSTRING_USED] = WA_IGNORE; + qccwarningaction[WARN_CORRECTEDRETURNTYPE] = WA_IGNORE; + qccwarningaction[WARN_NOTUTF8] = WA_IGNORE; + qccwarningaction[WARN_UNINITIALIZED] = WA_IGNORE; //not sure about this being ignored by default. + qccwarningaction[WARN_SELFNOTTHIS] = WA_IGNORE; + qccwarningaction[WARN_EVILPREPROCESSOR] = WA_ERROR; //evil people do evil things. evil must be thwarted! + qccwarningaction[WARN_IDENTICALPRECOMPILER] = WA_IGNORE; + qccwarningaction[WARN_DENORMAL] = WA_ERROR; //DAZ provides a speedup on modern machines, so any engine compiled for sse2+ will have problems with denormals, so make their use look serious. if (qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_UHEXEN2 || qcc_targetformat == QCF_FTEH2) qccwarningaction[WARN_CASEINSENSITIVEFRAMEMACRO] = WA_IGNORE; //hexenc consides these fair game. @@ -5388,7 +5443,7 @@ void QCC_FinishCompile(void) currentchunk = NULL; if (setjmp(pr_parse_abort)) - QCC_Error(ERR_INTERNAL, ""); + QCC_Error(ERR_INTERNAL, "%s", ""); s_filen = ""; s_filed = 0; diff --git a/engine/qclib/qcctui.c b/engine/qclib/qcctui.c index e01c6a86..f40c54e7 100644 --- a/engine/qclib/qcctui.c +++ b/engine/qclib/qcctui.c @@ -165,7 +165,7 @@ int main (int argc, const char **argv) col_warning = "\e[0;33m"; //yellow //col_ = "\e[0;34m"; //blue col_name = "\e[0;35m"; //magenta - //col_ = "\e[0;36m"; //cyan + col_type = "\e[0;36m"; //cyan col_location = "\e[0;1;37m"; //bright white } #else