Migrated QCLib stuff over from WIP branch.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3525 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2010-03-26 03:44:22 +00:00
parent d2475339c2
commit a2fbc53631
11 changed files with 281 additions and 157 deletions

View File

@ -43,9 +43,18 @@ int QC_strcasecmp (const char *s1, const char *s2);
#define QC_vsnprintf vsnprintf
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#ifndef LIKEPRINTF
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
#endif
#endif
#ifndef LIKEPRINTF
#define LIKEPRINTF(x)
#endif
double I_FloatTime (void);
void VARGS QCC_Error (int errortype, const char *error, ...);
void VARGS QCC_Error (int errortype, const char *error, ...) LIKEPRINTF(2);
int CheckParm (char *check);

View File

@ -431,7 +431,7 @@ reeval:
st--;
goto cont;
#else
PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
#endif
}
ed = PROG_TO_EDICT(progfuncs, OPA->edict);
@ -448,7 +448,13 @@ reeval:
st--;
goto cont;
#else
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
{
ddef16_t *d16;
fdef_t *f;
d16 = ED_GlobalAtOfs16(progfuncs, st->a);
f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->fieldadjust);
PR_RunError (progfuncs, "assignment to read-only entity in %s (%s.%s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), PR_StringToNative(progfuncs, d16->s_name), f?f->name:NULL);
}
#endif
}

View File

@ -95,9 +95,12 @@ int PR_InitEnts(progfuncs_t *progfuncs, int max_ents)
sv_edicts = PRHunkAlloc(progfuncs, externs->edictsize);
prinst->edicttable[0] = sv_edicts;
((edictrun_t*)prinst->edicttable[0])->fields = PRAddressableAlloc(progfuncs, max_fields_size);
ED_ClearEdict(progfuncs, (edictrun_t *)sv_edicts);
QC_ClearEdict(progfuncs, sv_edicts);
sv_num_edicts = 1;
if (externs->entspawn)
externs->entspawn((struct edict_s *)sv_edicts, false);
return max_fields_size;
}
edictrun_t tempedict; //used as a safty buffer
@ -643,7 +646,8 @@ progfuncs_t deffuncs = {
PR_StringToProgs,
PR_StringToNative,
0,
PR_QueryField
PR_QueryField,
QC_ClearEdict
};
#undef printf

View File

@ -45,13 +45,14 @@ static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}};
/*
=================
ED_ClearEdict
QC_ClearEdict
Sets everything to NULL
=================
*/
void ED_ClearEdict (progfuncs_t *progfuncs, edictrun_t *e)
void QC_ClearEdict (progfuncs_t *progfuncs, struct edict_s *ed)
{
edictrun_t *e = (edictrun_t *)ed;
int num = e->entnum;
memset (e->fields, 0, fields_size);
e->isfree = false;
@ -66,7 +67,7 @@ edictrun_t *ED_AllocIntoTable (progfuncs_t *progfuncs, int num)
memset(e, 0, externs->edictsize);
e->fields = PRAddressableAlloc(progfuncs, fields_size);
e->entnum = num;
ED_ClearEdict(progfuncs, e);
QC_ClearEdict(progfuncs, (struct edict_s*)e);
return e;
}
@ -97,7 +98,7 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs)
if (!e)
e = ED_AllocIntoTable(progfuncs, i);
else
ED_ClearEdict (progfuncs, e);
QC_ClearEdict (progfuncs, (struct edict_s*)e);
if (externs->entspawn)
externs->entspawn((struct edict_s *) e, false);
@ -117,7 +118,7 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs)
if (!e)
e = ED_AllocIntoTable(progfuncs, i);
else
ED_ClearEdict (progfuncs, e);
QC_ClearEdict (progfuncs, (struct edict_s*)e);
if (externs->entspawn)
externs->entspawn((struct edict_s *) e, false);
@ -146,7 +147,7 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs)
if (!e)
e = ED_AllocIntoTable(progfuncs, i);
else
ED_ClearEdict (progfuncs, e);
QC_ClearEdict (progfuncs, (struct edict_s*)e);
if (externs->entspawn)
externs->entspawn((struct edict_s *) e, false);
@ -1165,7 +1166,7 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent)
break;
if (!data)
{
printf ("ED_ParseEntity: EOF without closing brace");
printf ("ED_ParseEntity: EOF without closing brace\n");
return NULL;
}
@ -1184,13 +1185,13 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent)
data = QCC_COM_Parse (data);
if (!data)
{
printf ("ED_ParseEntity: EOF without closing brace");
printf ("ED_ParseEntity: EOF without closing brace\n");
return NULL;
}
if (qcc_token[0] == '}')
{
printf ("ED_ParseEntity: closing brace without data");
printf ("ED_ParseEntity: closing brace without data\n");
return NULL;
}
@ -3112,6 +3113,6 @@ unsigned int NUM_FOR_EDICT(progfuncs_t *progfuncs, struct edict_s *e)
{
edictrun_t *er = (edictrun_t*)e;
if (er->entnum >= maxedicts)
Sys_Error ("QCLIB: NUM_FOR_EDICT: bad pointer (%i)", e);
Sys_Error ("QCLIB: NUM_FOR_EDICT: bad pointer (%p)", e);
return er->entnum;
}

View File

@ -119,7 +119,7 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
int *glob = (int*)current_progstate->globals;
if (current_progstate->numbuiltins)
return;
return false;
jitstatements = numstatements;
@ -259,7 +259,7 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs)
//remember to change the je above
//err... exit depth? no idea
EmitByte(0xcd);EmitByte(op[i].op);
EmitByte(0xcd);EmitByte(op[i].op); //int $X
//ret
@ -560,7 +560,7 @@ EmitByte(0xcc);
//jmp 10
EmitByte(0xeb);EmitByte(0x0a);
//mov 1.0f,glob[C]
EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(1.0f);
EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].c);EmitFloat(1.0f);
break;
case OP_BITOR: //floats...
@ -972,7 +972,55 @@ EmitByte(0xcc);
//add $12,%esp
EmitByte(0x83); EmitByte(0xc4); EmitByte(0x0c);
break;
/*
#if 0
case OP_NOT_V:
//flds 0
//flds glob[A+0]
//fcomip %st(1),%st
//jne _true
//flds glob[A+1]
//fcomip %st(1),%st
//jne _true
//flds glob[A+1]
//fcomip %st(1),%st
//jne _true
//mov 1,C
//jmp done
//_true:
//mov 0,C
//done:
break;
case OP_EQ_V:
//flds glob[A]
EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+0);
//flds glob[B]
EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b+0);
//fcomip %st(1),%st
EmitByte(0xdf);EmitByte(0xe9);
//fstp %st(0) (aka: pop)
EmitByte(0xdd);EmitByte(0xd8);
//jncc _true
if (op[i].op == OP_NE_V)
EmitByte(0x74); //je
else
EmitByte(0x75); //jne
EmitByte(0x0c);
//_false0:
//mov 0.0f,c
EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f);
//jmp done
EmitByte(0xeb); EmitByte(0x0a);
//_true:
//mov 1.0f,c
EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f);
//_done:
break;
case OP_EQ_V:
EmitByte(0xcd);EmitByte(op[i].op);
printf("QCJIT: instruction %i is not implemented\n", op[i].op);
@ -987,7 +1035,7 @@ EmitByte(0xcc);
EmitByte(0xcd);EmitByte(op[i].op);
printf("QCJIT: instruction %i is not implemented\n", op[i].op);
break;
*/
#endif
default:
printf("QCJIT: Extended instruction set %i is not supported, not using jit.\n", op[i].op);
@ -1021,7 +1069,7 @@ void PR_EnterJIT(progfuncs_t *progfuncs, int statement)
{
#ifdef __GNUC__
//call, it clobbers pretty much everything.
asm("call %0" :: "r"(statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx");
asm("call *%0" :: "r"(statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx");
#elif defined(_MSC_VER)
void *entry = statementoffsets[statement+1];
void *edicttable = prinst->edicttable;
@ -1036,4 +1084,4 @@ void PR_EnterJIT(progfuncs_t *progfuncs, int statement)
#error "Sorry, no idea how to enter assembler safely for your compiler"
#endif
}
#endif
#endif

View File

@ -1,4 +1,4 @@
#ifdef WIN32
#ifdef _WIN32
#ifndef AVAIL_ZLIB
#ifdef _MSC_VER
@ -89,8 +89,13 @@ void PRHunkFree(progfuncs_t *progfuncs, int mark);
void *PRHunkAlloc(progfuncs_t *progfuncs, int size);
void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount);
#ifdef printf
#undef LIKEPRINTF
#define LIKEPRINTF(x)
#endif
//void *HunkAlloc (int size);
char *VARGS qcva (char *text, ...);
char *VARGS qcva (char *text, ...) LIKEPRINTF(1);
void QC_InitShares(progfuncs_t *progfuncs);
void QC_StartShares(progfuncs_t *progfuncs);
void QC_AddSharedVar(progfuncs_t *progfuncs, int num, int type);
@ -129,8 +134,6 @@ typedef union eval_s
#endif
*/
#define MAX_ENT_LEAFS 16
typedef struct edictrun_s
{
pbool isfree;
@ -281,7 +284,7 @@ const extern unsigned int type_size[];
extern unsigned short pr_crc;
void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...);
void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...) LIKEPRINTF(2);
void ED_PrintEdicts (progfuncs_t *progfuncs);
void ED_PrintNum (progfuncs_t *progfuncs, int ent);
@ -447,7 +450,7 @@ func_t PR_FindFunc(progfuncs_t *progfncs, char *funcname, progsnum_t pnum);
void PR_Configure (progfuncs_t *progfncs, int addressable_size, int max_progs);
int PR_InitEnts(progfuncs_t *progfncs, int maxents);
char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val);
void ED_ClearEdict (progfuncs_t *progfuncs, edictrun_t *e);
void QC_ClearEdict (progfuncs_t *progfuncs, struct edict_s *ed);
void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount);
void QC_FlushProgsOffsets(progfuncs_t *progfuncs);
@ -466,6 +469,9 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs);
pbool CompileFile(progfuncs_t *progfuncs, char *filename);
pbool PR_GenerateJit(progfuncs_t *progfuncs);
void PR_EnterJIT(progfuncs_t *progfuncs, int statement);
char *QCC_COM_Parse (char *data);
extern char qcc_token[1024];
#endif

View File

@ -22,10 +22,16 @@ typedef char *string_t;
*/
#ifdef _MSC_VER
#define VARGS __cdecl
#define VARGS __cdecl
#endif
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
#endif
#ifndef LIKEPRINTF
#define LIKEPRINTF(x)
#endif
#ifndef VARGS
#define VARGS
#define VARGS
#endif
@ -60,7 +66,7 @@ struct progfuncs_s {
struct globalvars_s *(*globals) (progfuncs_t *prinst, progsnum_t num); //get the globals of a progs
struct entvars_s *(*entvars) (progfuncs_t *prinst, struct edict_s *ent); //return a pointer to the entvars of an ent. can be achieved via the edict_t structure instead, so obsolete.
void (VARGS *RunError) (progfuncs_t *prinst, char *msg, ...); //builtins call this to say there was a problem
void (VARGS *RunError) (progfuncs_t *prinst, char *msg, ...) LIKEPRINTF(2); //builtins call this to say there was a problem
void (*PrintEdict) (progfuncs_t *prinst, struct edict_s *ed); //get a listing of all vars on an edict (sent back via 'print')
struct edict_s *(*EntAlloc) (progfuncs_t *prinst);
@ -137,7 +143,9 @@ struct progfuncs_s {
char *(*StringToNative) (progfuncs_t *prinst, string_t str);
int stringtablesize;
int (*QueryField) (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset
int (*QueryField) (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset
void (*EntClear) (progfuncs_t *progfuncs, struct edict_s *e);
};
typedef struct progexterns_s {
@ -146,9 +154,9 @@ typedef struct progexterns_s {
unsigned char *(*ReadFile) (char *fname, void *buffer, int len);
int (*FileSize) (char *fname); //-1 if file does not exist
pbool (*WriteFile) (char *name, void *data, int len);
int (VARGS *printf) (const char *, ...);
void (VARGS *Sys_Error) (const char *, ...);
void (VARGS *Abort) (char *, ...);
int (VARGS *printf) (const char *, ...) LIKEPRINTF(1);
void (VARGS *Sys_Error) (const char *, ...) LIKEPRINTF(1);
void (VARGS *Abort) (char *, ...) LIKEPRINTF(1);
int edictsize; //size of edict_t
void (*entspawn) (struct edict_s *ent, int loading); //ent has been spawned, but may not have all the extra variables (that may need to be set) set
@ -183,7 +191,9 @@ typedef struct progexterns_s {
//FIXMEs
void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size);
void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *relstringtable);
void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed);
void ED_Print(progfuncs_t *progfuncs, struct edict_s *ed);
char *PR_RemoveProgsString(progfuncs_t *progfuncs, string_t str);
int PR_GetFuncArgCount(progfuncs_t *progfuncs, func_t func);
#if defined(QCLIBDLL_EXPORTS)
__declspec(dllexport)
@ -218,7 +228,7 @@ typedef union eval_s
#define PR_LoadProgs(pf, s, headercrc, builtins, numb) (*pf->LoadProgs) (pf, s, headercrc, builtins, numb)
#define PR_InitEnts(pf, maxents) (*pf->InitEnts) (pf, maxents)
#define PR_ExecuteProgram(pf, fnum) (*pf->ExecuteProgram) (pf, fnum)
#define PR_SwitchProgs(pf, num) (*pf->SwitchProgs) (pf, num);
#define PR_SwitchProgs(pf, num) (*pf->SwitchProgs) (pf, num)
#define PR_globals(pf, num) (*pf->globals) (pf, num)
#define PR_entvars(pf, ent) (*pf->entvars) (pf, ent)
@ -226,6 +236,7 @@ typedef union eval_s
#define ED_Alloc(pf) (*pf->EntAlloc) (pf)
#define ED_Free(pf, ed) (*pf->EntFree) (pf, ed)
#define ED_Clear(pf, ed) (*pf->EntClear) (pf, ed)
#define PR_LoadEnts(pf, s, kf) (*pf->load_ents) (pf, s, kf)
#define PR_SaveEnts(pf, buf, size, mode) (*pf->save_ents) (pf, buf, size, mode)
@ -251,7 +262,7 @@ typedef union eval_s
#define PR_Alloc(pf,size) (*pf->Tempmem) (pf, size)
#define PROG_TO_EDICT(pf, ed) (*pf->ProgsToEdict) (pf, ed)
#define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, ed)
#define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, (struct edict_s*)ed)
#define PR_RegisterBuiltin(pf, name, func) (*pf->RegisterBuiltin) (pf, name, func)

View File

@ -477,6 +477,7 @@ extern pbool flag_laxcasts;
extern pbool flag_hashonly;
extern pbool flag_fasttrackarrays;
extern pbool flag_assume_integer;
extern pbool flag_msvcstyle;
extern pbool opt_overlaptemps;
extern pbool opt_shortenifnots;

View File

@ -74,6 +74,7 @@ pbool flag_caseinsensative; //symbols will be matched to an insensative case if
pbool flag_laxcasts; //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
pbool flag_hashonly; //Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile
pbool flag_fasttrackarrays; //Faster arrays, dynamically detected, activated only in supporting engines.
pbool flag_msvcstyle; //MSVC style warnings, so msvc's ide works properly
pbool flag_assume_integer; //5 - is that an integer or a float? qcc says float. but we support int too, so maybe we want that instead?
pbool opt_overlaptemps; //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation)
@ -1381,12 +1382,7 @@ static void QCC_LockActiveTemps(void)
t->scope = pr_scope;
t = t->next;
}
}
static void QCC_LockTemp(QCC_def_t *d)
{
if (d->temp && d->temp->used)
d->temp->scope = pr_scope;
}
static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement)
@ -2239,26 +2235,19 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
//don't chain these... this expansion is not the same.
{
int st;
int need_lock = false;
for (st = numstatements-2; st>=0; st--)
{
if (statements[st].op == OP_ADDRESS)
if (statements[st].c == var_b->ofs)
break;
if (statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8 || statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H)
need_lock = true;
//printf("%s\n", pr_opcodes[statements[st].op].opname);
if (statements[st].c == var_b->ofs)
QCC_PR_ParseWarning(0, "Temp-reuse may have broken your %s", op->name);
}
if (st < 0)
QCC_PR_ParseError(ERR_INTERNAL, "XSTOREP_F: pointer was not generated from previous statement");
var_c = QCC_GetTemp(*op->type_c);
if(need_lock)
QCC_LockTemp(var_c); // this will cause the temp to be remapped by QCC_RemapLockedTemps
statement_linenums[statement-statements] = statement_linenums[st];
statement->op = OP_ADDRESS;
@ -2363,7 +2352,6 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
op = &pr_opcodes[OP_STOREP_F];
QCC_FreeTemp(var_c);
var_c = NULL;
QCC_FreeTemp(var_b);
@ -2380,24 +2368,18 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var
//don't chain these... this expansion is not the same.
{
int st;
int need_lock = false;
for (st = numstatements-2; st>=0; st--)
{
if (statements[st].op == OP_ADDRESS)
if (statements[st].c == var_b->ofs)
break;
if (statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8 || statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H)
need_lock = true;
if (statements[st].c == var_b->ofs)
QCC_PR_ParseWarning(0, "Temp-reuse may have broken your %s", op->name);
}
if (st < 0)
QCC_PR_ParseError(ERR_INTERNAL, "XSTOREP_V couldn't find pointer generation");
var_c = QCC_GetTemp(*op->type_c);
if(need_lock)
QCC_LockTemp(var_c); // this will cause the temp to be remapped by QCC_RemapLockedTemps
statement_linenums[statement-statements] = statement_linenums[st];
statement->op = OP_ADDRESS;
@ -3448,6 +3430,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
{
//t = (a/%1) / (nextent(world)/%1)
//a/%1 does a (int)entity to float conversion type thing
func->initialized = 1;
e = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
QCC_PR_Expect(")");
@ -4069,7 +4052,7 @@ PR_ParseValue
Returns the global ofs for the current token
============
*/
QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass)
QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
{
QCC_def_t *ao=NULL; //arrayoffset
QCC_def_t *d, *nd, *od;
@ -4369,7 +4352,7 @@ reloop:
if (d->scope)
QCC_PR_ParseError(0, "Scoped array without specific engine support");
if (QCC_PR_CheckToken("="))
if (allowarrayassign && QCC_PR_CheckToken("="))
{
QCC_def_t *args[2];
@ -4662,7 +4645,7 @@ reloop:
QCC_PR_Expect(")");
}
else
field = QCC_PR_ParseValue(d->type);
field = QCC_PR_ParseValue(d->type, false);
if (field->type->type == ev_field)
{
if (!field->type->aux_type)
@ -4997,7 +4980,7 @@ QCC_def_t *QCC_PR_Term (void)
return e;
}
}
return QCC_PR_ParseValue (pr_classtype);
return QCC_PR_ParseValue (pr_classtype, true);
}
@ -6546,7 +6529,7 @@ void QCC_PR_ParseAsm(void)
{
patch1 = &statements[numstatements];
a = QCC_PR_ParseValue(pr_classtype);
a = QCC_PR_ParseValue(pr_classtype, false);
QCC_PR_Statement3(&pr_opcodes[op], a, NULL, NULL, true);
if (pr_token_type == tt_name)
@ -6565,8 +6548,8 @@ void QCC_PR_ParseAsm(void)
{
patch1 = &statements[numstatements];
a = QCC_PR_ParseValue(pr_classtype);
b = QCC_PR_ParseValue(pr_classtype);
a = QCC_PR_ParseValue(pr_classtype, false);
b = QCC_PR_ParseValue(pr_classtype, false);
QCC_PR_Statement3(&pr_opcodes[op], a, b, NULL, true);
if (pr_token_type == tt_name)
@ -6585,15 +6568,15 @@ void QCC_PR_ParseAsm(void)
else
{
if (pr_opcodes[op].type_a != &type_void)
a = QCC_PR_ParseValue(pr_classtype);
a = QCC_PR_ParseValue(pr_classtype, false);
else
a=NULL;
if (pr_opcodes[op].type_b != &type_void)
b = QCC_PR_ParseValue(pr_classtype);
b = QCC_PR_ParseValue(pr_classtype, false);
else
b=NULL;
if (pr_opcodes[op].associative==ASSOC_LEFT && pr_opcodes[op].type_c != &type_void)
c = QCC_PR_ParseValue(pr_classtype);
c = QCC_PR_ParseValue(pr_classtype, false);
else
c=NULL;
@ -9151,8 +9134,13 @@ void QCC_PR_ParseDefs (char *classname)
i = 0;
do
{
if (QCC_PR_CheckImmediate("0"))
if (pr_token_type == tt_immediate && (
(pr_immediate_type == type_integer && pr_immediate._int == 0) ||
(pr_immediate_type == type_float && pr_immediate._float == 0)))
{
QCC_PR_Lex();
G_FUNCTION(def->ofs+i) = 0;
}
else
{
name = QCC_PR_ParseName ();

View File

@ -1401,7 +1401,7 @@ void QCC_PR_LexNumber (void)
pr_file_p++;
}
pr_token[tokenlen++] = 0;
pr_immediate._float = atof(pr_token);
pr_immediate._float = (float)atof(pr_token);
return;
}
else if (c == 'i')
@ -2419,7 +2419,7 @@ int QCC_PR_CheakCompConst(void)
if (!strncmp(pr_file_p, "__NULL__", 8))
{
static char retbuf[256];
sprintf(retbuf, "~0");
sprintf(retbuf, "0i");
pr_file_p = retbuf;
QCC_PR_Lex(); //translate the macro's value
pr_file_p = oldpr_file_p+8;
@ -2599,7 +2599,12 @@ void QCC_PR_ParsePrintDef (int type, QCC_def_t *def)
if (qccwarningdisabled[type])
return;
if (def->s_file)
printf ("%s:%i: %s is defined here\n", strings + def->s_file, def->s_line, def->name);
{
if (flag_msvcstyle)
printf ("%s(%i) : %s is defined here\n", strings + def->s_file, def->s_line, def->name);
else
printf ("%s:%i: %s is defined here\n", strings + def->s_file, def->s_line, def->name);
}
}
void *errorscope;
void QCC_PR_PrintScope (void)
@ -2645,7 +2650,10 @@ void VARGS QCC_PR_ParseError (int errortype, char *error, ...)
#endif
QCC_PR_PrintScope();
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
if (flag_msvcstyle)
printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string);
else
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
longjmp (pr_parse_abort, 1);
}
@ -2662,7 +2670,10 @@ void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error
editbadfile(strings+s_file, pr_source_line);
#endif
QCC_PR_PrintScope();
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
if (flag_msvcstyle)
printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string);
else
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
QCC_PR_ParsePrintDef(WARN_ERROR, def);
@ -2683,12 +2694,18 @@ void VARGS QCC_PR_ParseWarning (int type, char *error, ...)
QCC_PR_PrintScope();
if (type >= ERR_PARSEERRORS)
{
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
if (flag_msvcstyle)
printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string);
else
printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string);
pr_error_count++;
}
else
{
printf ("%s:%i: warning: %s\n", strings + s_file, pr_source_line, string);
if (flag_msvcstyle)
printf ("%s(%i) : warning: %s\n", strings + s_file, pr_source_line, string);
else
printf ("%s:%i: warning: %s\n", strings + s_file, pr_source_line, string);
pr_warning_count++;
}
}
@ -2707,7 +2724,12 @@ void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...)
QCC_PR_PrintScope();
if (file)
printf ("%s:%i: warning: %s\n", file, line, string);
{
if (flag_msvcstyle)
printf ("%s(%i) : warning: %s\n", file, line, string);
else
printf ("%s:%i: warning: %s\n", file, line, string);
}
else
printf ("warning: %s\n", string);
pr_warning_count++;

View File

@ -15,6 +15,7 @@ extern int optres_test2;
int writeasm;
static pbool pr_werror;
pbool verbose;
pbool QCC_PR_SimpleGetToken (void);
@ -230,6 +231,7 @@ compiler_flag_t compiler_flag[] = {
{&flag_laxcasts, FLAG_MIDCOMPILE,"lax", "Lax type checks", "Disables many errors (generating warnings instead) when function calls or operations refer to two normally incompatible types. This is required for reacc support, and can also allow certain (evil) mods to compile that were originally written for frikqcc."}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code.
{&flag_hashonly, FLAG_MIDCOMPILE,"hashonly", "Hash-only constants", "Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile"},
{&opt_logicops, FLAG_MIDCOMPILE,"lo", "Logic ops", "This changes the behaviour of your code. It generates additional if operations to early-out in if statements. With this flag, the line if (0 && somefunction()) will never call the function. It can thus be considered an optimisation. However, due to the change of behaviour, it is not considered so by fteqcc. Note that due to inprecisions with floats, this flag can cause runaway loop errors within the player walk and run functions (without iffloat also enabled). This code is advised:\nplayer_stand1:\n if (self.velocity_x || self.velocity_y)\nplayer_run\n if (!(self.velocity_x || self.velocity_y))"},
{&flag_msvcstyle, FLAG_MIDCOMPILE,"msvcstyle", "MSVC-style errors", "Generates warning and error messages in a format that msvc understands, to facilitate ide integration."},
{&flag_fasttrackarrays, FLAG_MIDCOMPILE|FLAG_ASDEFAULT,"fastarrays","fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes only in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to all arrays or none."},
{&flag_assume_integer, FLAG_MIDCOMPILE,"assumeint", "Assume Integers", "Numerical constants are assumed to be integers, instead of floats."},
{NULL}
@ -634,10 +636,13 @@ pbool QCC_WriteData (int crc)
//include a type block?
types = debugtarget;//!!QCC_PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...).
if (qcc_targetformat == QCF_DARKPLACES)
printf("DarkPlaces or FTE will be required\n");
else
printf("An FTE executor will be required\n");
if (verbose)
{
if (qcc_targetformat == QCF_DARKPLACES)
printf("DarkPlaces or FTE will be required\n");
else
printf("An FTE executor will be required\n");
}
break;
case QCF_KK7:
if (bodylessfuncs)
@ -845,16 +850,20 @@ pbool QCC_WriteData (int crc)
//PrintGlobals ();
strofs = (strofs+3)&~3;
printf ("%6i strofs (of %i)\n", strofs, MAX_STRINGS);
printf ("%6i numstatements (of %i)\n", numstatements, MAX_STATEMENTS);
printf ("%6i numfunctions (of %i)\n", numfunctions, MAX_FUNCTIONS);
printf ("%6i numglobaldefs (of %i)\n", numglobaldefs, MAX_GLOBALS);
printf ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS);
printf ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS);
if (verbose)
{
printf ("%6i strofs (of %i)\n", strofs, MAX_STRINGS);
printf ("%6i numstatements (of %i)\n", numstatements, MAX_STATEMENTS);
printf ("%6i numfunctions (of %i)\n", numfunctions, MAX_FUNCTIONS);
printf ("%6i numglobaldefs (of %i)\n", numglobaldefs, MAX_GLOBALS);
printf ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS);
printf ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS);
}
if (!*destfile)
strcpy(destfile, "progs.dat");
printf("Writing %s\n", destfile);
if (verbose)
printf("Writing %s\n", destfile);
h = SafeOpenWrite (destfile, 2*1024*1024);
SafeWrite (h, &progs, sizeof(progs));
SafeWrite (h, "\r\n\r\n", 4);
@ -1187,7 +1196,8 @@ strofs = (strofs+3)&~3;
break;
}
printf ("%6i TOTAL SIZE\n", (int)SafeSeek (h, 0, SEEK_CUR));
if (verbose)
printf ("%6i TOTAL SIZE\n", (int)SafeSeek (h, 0, SEEK_CUR));
progs.entityfields = pr.size_fields;
@ -1215,7 +1225,8 @@ strofs = (strofs+3)&~3;
unsigned int version = 1;
StripExtension(destfile);
strcat(destfile, ".lno");
printf("Writing %s\n", destfile);
if (verbose)
printf("Writing %s for debugging\n", destfile);
h = SafeOpenWrite (destfile, 2*1024*1024);
SafeWrite (h, &lnotype, sizeof(int));
SafeWrite (h, &version, sizeof(int));
@ -1608,8 +1619,9 @@ int QCC_PR_FinishCompilation (void)
}
else
{
QCC_PR_Warning(WARN_NOTDEFINED, strings + d->s_file, d->s_line, "function %s was not defined",d->name);
QCC_PR_ParseErrorPrintDef(ERR_NOFUNC, d, "function %s was not defined",d->name);
bodylessfuncs = true;
errors = true;
}
// errors = true;
}
@ -1887,28 +1899,35 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
case 12923: //#pragma sourcefile usage
break;
case 54730:
printf("Recognised progs as QuakeWorld\n");
if (verbose)
printf("Recognised progs as QuakeWorld\n");
break;
case 5927:
printf("Recognised progs as NetQuake server gamecode\n");
if (verbose)
printf("Recognised progs as NetQuake server gamecode\n");
break;
case 26940:
printf("Recognised progs as Quake pre-release...\n");
if (verbose)
printf("Recognised progs as Quake pre-release...\n");
break;
case 38488:
printf("Recognised progs as original Hexen2\n");
if (verbose)
printf("Recognised progs as original Hexen2\n");
break;
case 26905:
printf("Recognised progs as Hexen2 Mission Pack\n");
if (verbose)
printf("Recognised progs as Hexen2 Mission Pack\n");
break;
case 14046:
printf("Recognised progs as Hexen2 (demo)\n");
if (verbose)
printf("Recognised progs as Hexen2 (demo)\n");
break;
case 22390: //EXT_CSQC_1
printf("Recognised progs as a CSQC module\n");
if (verbose)
printf("Recognised progs as an EXT_CSQC_1 module\n");
break;
case 17105:
case 32199: //outdated ext_csqc
@ -1918,7 +1937,8 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
printf("Recognised progs as outdated CSQC module\n");
break;
case 10020:
printf("Recognised progs as a DP/FTE Menu module\n");
if (verbose)
printf("Recognised progs as a DP/FTE Menu module\n");
break;
case 32401:
@ -2274,14 +2294,17 @@ void QCC_CopyFiles (void)
char srcdir[1024], destdir[1024];
int p;
if (numsounds > 0)
printf ("%3i unique precache_sounds\n", numsounds);
if (nummodels > 0)
printf ("%3i unique precache_models\n", nummodels);
if (numtextures > 0)
printf ("%3i unique precache_textures\n", numtextures);
if (numfiles > 0)
printf ("%3i unique precache_files\n", numfiles);
if (verbose)
{
if (numsounds > 0)
printf ("%3i unique precache_sounds\n", numsounds);
if (nummodels > 0)
printf ("%3i unique precache_models\n", nummodels);
if (numtextures > 0)
printf ("%3i unique precache_textures\n", numtextures);
if (numfiles > 0)
printf ("%3i unique precache_files\n", numfiles);
}
p = QCC_CheckParm ("-copy");
if (p && p < myargc-2)
@ -3157,7 +3180,9 @@ void QCC_ContinueCompile(void)
if (autoprototype)
printf ("prototyping %s\n", qccmfilename);
else
{
printf ("compiling %s\n", qccmfilename);
}
QCC_LoadFile (qccmfilename, (void *)&qccmsrc2);
if (!QCC_PR_CompileFile (qccmsrc2, qccmfilename) )
@ -3217,58 +3242,61 @@ void QCC_FinishCompile(void)
if (donesomething)
{
printf ("Compile Complete\n\n");
if (verbose)
{
printf ("Compile Complete\n\n");
if (optres_shortenifnots)
printf("optres_shortenifnots %i\n", optres_shortenifnots);
if (optres_overlaptemps)
printf("optres_overlaptemps %i\n", optres_overlaptemps);
if (optres_noduplicatestrings)
printf("optres_noduplicatestrings %i\n", optres_noduplicatestrings);
if (optres_constantarithmatic)
printf("optres_constantarithmatic %i\n", optres_constantarithmatic);
if (optres_nonvec_parms)
printf("optres_nonvec_parms %i\n", optres_nonvec_parms);
if (optres_constant_names)
printf("optres_constant_names %i\n", optres_constant_names);
if (optres_constant_names_strings)
printf("optres_constant_names_strings %i\n", optres_constant_names_strings);
if (optres_precache_file)
printf("optres_precache_file %i\n", optres_precache_file);
if (optres_filenames)
printf("optres_filenames %i\n", optres_filenames);
if (optres_assignments)
printf("optres_assignments %i\n", optres_assignments);
if (optres_unreferenced)
printf("optres_unreferenced %i\n", optres_unreferenced);
if (optres_locals)
printf("optres_locals %i\n", optres_locals);
if (optres_function_names)
printf("optres_function_names %i\n", optres_function_names);
if (optres_dupconstdefs)
printf("optres_dupconstdefs %i\n", optres_dupconstdefs);
if (optres_return_only)
printf("optres_return_only %i\n", optres_return_only);
if (optres_compound_jumps)
printf("optres_compound_jumps %i\n", optres_compound_jumps);
// if (optres_comexprremoval)
// printf("optres_comexprremoval %i\n", optres_comexprremoval);
if (optres_stripfunctions)
printf("optres_stripfunctions %i\n", optres_stripfunctions);
if (optres_locals_marshalling)
printf("optres_locals_marshalling %i\n", optres_locals_marshalling);
if (optres_logicops)
printf("optres_logicops %i\n", optres_logicops);
if (optres_shortenifnots)
printf("optres_shortenifnots %i\n", optres_shortenifnots);
if (optres_overlaptemps)
printf("optres_overlaptemps %i\n", optres_overlaptemps);
if (optres_noduplicatestrings)
printf("optres_noduplicatestrings %i\n", optres_noduplicatestrings);
if (optres_constantarithmatic)
printf("optres_constantarithmatic %i\n", optres_constantarithmatic);
if (optres_nonvec_parms)
printf("optres_nonvec_parms %i\n", optres_nonvec_parms);
if (optres_constant_names)
printf("optres_constant_names %i\n", optres_constant_names);
if (optres_constant_names_strings)
printf("optres_constant_names_strings %i\n", optres_constant_names_strings);
if (optres_precache_file)
printf("optres_precache_file %i\n", optres_precache_file);
if (optres_filenames)
printf("optres_filenames %i\n", optres_filenames);
if (optres_assignments)
printf("optres_assignments %i\n", optres_assignments);
if (optres_unreferenced)
printf("optres_unreferenced %i\n", optres_unreferenced);
if (optres_locals)
printf("optres_locals %i\n", optres_locals);
if (optres_function_names)
printf("optres_function_names %i\n", optres_function_names);
if (optres_dupconstdefs)
printf("optres_dupconstdefs %i\n", optres_dupconstdefs);
if (optres_return_only)
printf("optres_return_only %i\n", optres_return_only);
if (optres_compound_jumps)
printf("optres_compound_jumps %i\n", optres_compound_jumps);
// if (optres_comexprremoval)
// printf("optres_comexprremoval %i\n", optres_comexprremoval);
if (optres_stripfunctions)
printf("optres_stripfunctions %i\n", optres_stripfunctions);
if (optres_locals_marshalling)
printf("optres_locals_marshalling %i\n", optres_locals_marshalling);
if (optres_logicops)
printf("optres_logicops %i\n", optres_logicops);
if (optres_test1)
printf("optres_test1 %i\n", optres_test1);
if (optres_test2)
printf("optres_test2 %i\n", optres_test2);
printf("numtemps %i\n", numtemps);
printf("%i warnings\n", pr_warning_count);
if (optres_test1)
printf("optres_test1 %i\n", optres_test1);
if (optres_test2)
printf("optres_test2 %i\n", optres_test2);
printf("numtemps %i\n", numtemps);
}
if (!flag_msvcstyle)
printf("%i warnings\n", pr_warning_count);
}
qcc_compileactive = false;