mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
A few fixes for nehahara/reacc compat. I got a working progs.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4620 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c604c0c17f
commit
b282a31f35
9 changed files with 323 additions and 231 deletions
|
@ -292,6 +292,21 @@ void Hash_Remove(hashtable_t *table, const char *name)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hash_RemoveDataInsensative(hashtable_t *table, const char *name, void *data)
|
||||||
|
{
|
||||||
|
unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
|
||||||
|
bucket_t **link, *buck;
|
||||||
|
|
||||||
|
for (link = &table->bucket[bucknum]; *link; link = &(*link)->next)
|
||||||
|
{
|
||||||
|
buck = *link;
|
||||||
|
if (buck->data == data && !stricmp(name, buck->key.string))
|
||||||
|
{
|
||||||
|
*link = buck->next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
void Hash_RemoveData(hashtable_t *table, const char *name, void *data)
|
void Hash_RemoveData(hashtable_t *table, const char *name, void *data)
|
||||||
{
|
{
|
||||||
unsigned int bucknum = Hash_Key(name, table->numbuckets);
|
unsigned int bucknum = Hash_Key(name, table->numbuckets);
|
||||||
|
@ -306,7 +321,6 @@ void Hash_RemoveData(hashtable_t *table, const char *name, void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
void Hash_RemoveBucket(hashtable_t *table, const char *name, bucket_t *data)
|
void Hash_RemoveBucket(hashtable_t *table, const char *name, bucket_t *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,7 @@ void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck)
|
||||||
void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck);
|
void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck);
|
||||||
void Hash_Remove(hashtable_t *table, const char *name);
|
void Hash_Remove(hashtable_t *table, const char *name);
|
||||||
void Hash_RemoveData(hashtable_t *table, const char *name, void *data);
|
void Hash_RemoveData(hashtable_t *table, const char *name, void *data);
|
||||||
|
void Hash_RemoveDataInsensative(hashtable_t *table, const char *name, void *data);
|
||||||
void Hash_RemoveBucket(hashtable_t *table, const char *name, bucket_t *data);
|
void Hash_RemoveBucket(hashtable_t *table, const char *name, bucket_t *data);
|
||||||
void Hash_RemoveKey(hashtable_t *table, unsigned int key);
|
void Hash_RemoveKey(hashtable_t *table, unsigned int key);
|
||||||
void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck);
|
void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#define PROGSUSED
|
#define PROGSUSED
|
||||||
#include "progsint.h"
|
#include "progsint.h"
|
||||||
|
|
||||||
//#define MAPPING_DEBUG
|
#define MAPPING_DEBUG
|
||||||
//#define MAPPING_PARANOID //may actually break unions, so beware.
|
#define MAPPING_PARANOID //may actually break unions, so beware.
|
||||||
|
|
||||||
void PR_SetBuiltins(int type);
|
void PR_SetBuiltins(int type);
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -995,3 +995,4 @@ pbool QCC_PR_UnInclude(void);
|
||||||
extern void *(*pHash_Get)(hashtable_t *table, const char *name);
|
extern void *(*pHash_Get)(hashtable_t *table, const char *name);
|
||||||
extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
|
extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
|
||||||
extern void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *);
|
extern void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *);
|
||||||
|
extern void (*pHash_RemoveData)(hashtable_t *table, const char *name, void *data);
|
||||||
|
|
|
@ -136,6 +136,7 @@ int optres_test2;
|
||||||
void *(*pHash_Get)(hashtable_t *table, const char *name);
|
void *(*pHash_Get)(hashtable_t *table, const char *name);
|
||||||
void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
|
void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old);
|
||||||
void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *);
|
void *(*pHash_Add)(hashtable_t *table, const char *name, void *data, bucket_t *);
|
||||||
|
void (*pHash_RemoveData)(hashtable_t *table, const char *name, void *data);
|
||||||
|
|
||||||
QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int arraysize, unsigned int ofs, int referable, unsigned int flags);
|
QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int arraysize, unsigned int ofs, int referable, unsigned int flags);
|
||||||
QCC_type_t *QCC_PR_FindType (QCC_type_t *type);
|
QCC_type_t *QCC_PR_FindType (QCC_type_t *type);
|
||||||
|
@ -1316,8 +1317,15 @@ QCC_def_t *QCC_SupplyConversionForAssignment(QCC_def_t *to, QCC_def_t *from, ety
|
||||||
if (o < 0)
|
if (o < 0)
|
||||||
{
|
{
|
||||||
if (fatal && wanted != ev_variant && from->type->type != ev_variant)
|
if (fatal && wanted != ev_variant && from->type->type != ev_variant)
|
||||||
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, from, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", to->name, basictypenames[wanted], basictypenames[from->type->type]);
|
{
|
||||||
|
if (flag_laxcasts)
|
||||||
|
{
|
||||||
|
QCC_PR_ParseWarning(WARN_LAXCAST, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", to->name, basictypenames[wanted], basictypenames[from->type->type]);
|
||||||
|
QCC_PR_ParsePrintDef(WARN_LAXCAST, from);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, from, "Implicit type mismatch on assignment to %s. Needed %s, got %s.", to->name, basictypenames[wanted], basictypenames[from->type->type]);
|
||||||
|
}
|
||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1337,8 +1345,15 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted, pbool fatal)
|
||||||
if (o < 0)
|
if (o < 0)
|
||||||
{
|
{
|
||||||
if (fatal && wanted != ev_variant && var->type->type != ev_variant)
|
if (fatal && wanted != ev_variant && var->type->type != ev_variant)
|
||||||
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], basictypenames[var->type->type]);
|
{
|
||||||
|
if (flag_laxcasts)
|
||||||
|
{
|
||||||
|
QCC_PR_ParseWarning(WARN_LAXCAST, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], basictypenames[var->type->type]);
|
||||||
|
QCC_PR_ParsePrintDef(WARN_LAXCAST, var);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], basictypenames[var->type->type]);
|
||||||
|
}
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4605,8 +4620,8 @@ QCC_def_t *QCC_MakeFloatConst(float value)
|
||||||
pr.def_tail->next = cn;
|
pr.def_tail->next = cn;
|
||||||
pr.def_tail = cn;
|
pr.def_tail = cn;
|
||||||
|
|
||||||
cn->s_file = s_file;
|
// cn->s_file = s_file;
|
||||||
cn->s_line = pr_source_line;
|
// cn->s_line = pr_source_line;
|
||||||
cn->type = type_float;
|
cn->type = type_float;
|
||||||
cn->name = "IMMEDIATE";
|
cn->name = "IMMEDIATE";
|
||||||
cn->constant = true;
|
cn->constant = true;
|
||||||
|
@ -5673,10 +5688,18 @@ QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags)
|
||||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0, NULL); //functions are integer values too.
|
e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0, NULL); //functions are integer values too.
|
||||||
else if (t == ev_pointer)
|
else if (t == ev_pointer)
|
||||||
e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0, NULL); //Pointers are too.
|
e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0, NULL); //Pointers are too.
|
||||||
|
else if (t == ev_void && flag_laxcasts)
|
||||||
|
{
|
||||||
|
QCC_PR_ParseWarning(WARN_LAXCAST, "Type mismatch: !void");
|
||||||
|
e2 = QCC_PR_Statement (&pr_opcodes[OP_NOT_F], e, 0, NULL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
char etype[256];
|
||||||
|
TypeName(e->type, etype, sizeof(etype));
|
||||||
|
|
||||||
e2 = NULL; // shut up compiler warning;
|
e2 = NULL; // shut up compiler warning;
|
||||||
QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for !");
|
QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch: !%s", etype);
|
||||||
}
|
}
|
||||||
return QCC_DefToRef(retbuf, e2);
|
return QCC_DefToRef(retbuf, e2);
|
||||||
}
|
}
|
||||||
|
@ -7190,7 +7213,7 @@ void QCC_PR_ParseStatement (void)
|
||||||
{
|
{
|
||||||
if (!e2->subscoped_away)
|
if (!e2->subscoped_away)
|
||||||
{
|
{
|
||||||
Hash_RemoveData(&localstable, e2->name, e2);
|
pHash_RemoveData(&localstable, e2->name, e2);
|
||||||
e2->subscoped_away = true;
|
e2->subscoped_away = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9753,6 +9776,9 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
|
||||||
QCC_def_t *def, *first=NULL;
|
QCC_def_t *def, *first=NULL;
|
||||||
char typebuf[1024];
|
char typebuf[1024];
|
||||||
|
|
||||||
|
if (name && !strcmp(name, "ImpulseCommands"))
|
||||||
|
QCC_PR_Note(0, strings+s_file, pr_source_line, "Defining %s", name);
|
||||||
|
|
||||||
#define KEYWORD(x) if (!STRCMP(name, #x) && keyword_##x) {if (keyword_##x)QCC_PR_ParseWarning(WARN_KEYWORDDISABLED, "\""#x"\" keyword used as variable name%s", keywords_coexist?" - coexisting":" - disabling");keyword_##x=keywords_coexist;}
|
#define KEYWORD(x) if (!STRCMP(name, #x) && keyword_##x) {if (keyword_##x)QCC_PR_ParseWarning(WARN_KEYWORDDISABLED, "\""#x"\" keyword used as variable name%s", keywords_coexist?" - coexisting":" - disabling");keyword_##x=keywords_coexist;}
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
|
@ -9930,19 +9956,39 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
|
||||||
// char element[MAX_NAME];
|
// char element[MAX_NAME];
|
||||||
QCC_def_t *foundstatic = NULL;
|
QCC_def_t *foundstatic = NULL;
|
||||||
char typebuf1[1024], typebuf2[1024];
|
char typebuf1[1024], typebuf2[1024];
|
||||||
|
int ins, insmax;
|
||||||
|
|
||||||
if (!allocate)
|
if (!allocate)
|
||||||
arraysize = -1;
|
arraysize = -1;
|
||||||
|
|
||||||
|
if (pHash_Get != &Hash_Get)
|
||||||
|
{
|
||||||
|
ins = 0;
|
||||||
|
insmax = allocate?1:2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ins = 1;
|
||||||
|
insmax = 2;
|
||||||
|
}
|
||||||
|
for (; ins < insmax; ins++)
|
||||||
|
{
|
||||||
if (scope)
|
if (scope)
|
||||||
{
|
{
|
||||||
def = Hash_Get(&localstable, name);
|
def = pHash_Get(&localstable, name);
|
||||||
|
|
||||||
while(def)
|
while(def)
|
||||||
{
|
{
|
||||||
|
//ignore differing case the first time around.
|
||||||
|
if (ins == 0 && strcmp(def->name, name))
|
||||||
|
{
|
||||||
|
def = pHash_GetNext(&globalstable, name, def);
|
||||||
|
continue; // in a different function
|
||||||
|
}
|
||||||
|
|
||||||
if ( def->scope && def->scope != scope)
|
if ( def->scope && def->scope != scope)
|
||||||
{
|
{
|
||||||
def = Hash_GetNext(&localstable, name, def);
|
def = pHash_GetNext(&localstable, name, def);
|
||||||
continue; // in a different function
|
continue; // in a different function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9954,28 +10000,36 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
|
||||||
{
|
{
|
||||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
||||||
QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
|
QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
|
||||||
// if (!scope)
|
// if (!scope)
|
||||||
// QCC_PR_ParsePrintDef(def);
|
// QCC_PR_ParsePrintDef(def);
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def = pHash_Get(&globalstable, name);
|
||||||
def = Hash_Get(&globalstable, name);
|
|
||||||
|
|
||||||
while(def)
|
while(def)
|
||||||
{
|
{
|
||||||
if ( (def->scope || (scope && allocate)) && def->scope != scope)
|
//ignore differing case the first time around.
|
||||||
|
if (ins == 0 && strcmp(def->name, name))
|
||||||
{
|
{
|
||||||
def = Hash_GetNext(&globalstable, name, def);
|
def = pHash_GetNext(&globalstable, name, def);
|
||||||
continue; // in a different function
|
continue; // in a different function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( (def->scope || (scope && allocate)) && def->scope != scope)
|
||||||
|
{
|
||||||
|
def = pHash_GetNext(&globalstable, name, def);
|
||||||
|
continue; // in a different function
|
||||||
|
}
|
||||||
|
|
||||||
|
//ignore it if its static in some other file.
|
||||||
if (def->isstatic && strcmp(strings+def->s_file, strings+s_file))
|
if (def->isstatic && strcmp(strings+def->s_file, strings+s_file))
|
||||||
{ //warn? or would that be pointless?
|
{
|
||||||
foundstatic = def;
|
if (!foundstatic)
|
||||||
def = Hash_GetNext(&globalstable, name, def);
|
foundstatic = def; //save it off purely as a warning.
|
||||||
|
def = pHash_GetNext(&globalstable, name, def);
|
||||||
continue; // in a different function
|
continue; // in a different function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10003,85 +10057,6 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
|
||||||
if (def->arraysize != arraysize && arraysize>=0)
|
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 do not match",name);
|
||||||
if (allocate && scope)
|
if (allocate && scope)
|
||||||
{
|
|
||||||
if (pr_scope)
|
|
||||||
{ //warn? or would that be pointless?
|
|
||||||
def = Hash_GetNext(&globalstable, name, def);
|
|
||||||
continue; // in a different function
|
|
||||||
}
|
|
||||||
|
|
||||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
|
||||||
QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
|
|
||||||
// if (!scope)
|
|
||||||
// QCC_PR_ParsePrintDef(def);
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pHash_Get != &Hash_Get && !allocate) //do we want to try case insensative too?
|
|
||||||
{
|
|
||||||
if (scope)
|
|
||||||
{
|
|
||||||
def = pHash_Get(&localstable, name);
|
|
||||||
|
|
||||||
while(def)
|
|
||||||
{
|
|
||||||
if ( def->scope && def->scope != scope)
|
|
||||||
{
|
|
||||||
def = pHash_GetNext(&localstable, name, def);
|
|
||||||
continue; // in a different function
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type && typecmp(def->type, type))
|
|
||||||
QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2)));
|
|
||||||
if (def->arraysize != arraysize && arraysize>=0)
|
|
||||||
QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
|
|
||||||
if (allocate && scope)
|
|
||||||
{
|
|
||||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
|
||||||
QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
|
|
||||||
// if (!scope)
|
|
||||||
// QCC_PR_ParsePrintDef(def);
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def = pHash_Get(&globalstable, name);
|
|
||||||
|
|
||||||
while(def)
|
|
||||||
{
|
|
||||||
if ( def->scope && def->scope != scope)
|
|
||||||
{
|
|
||||||
def = pHash_GetNext(&globalstable, name, def);
|
|
||||||
continue; // in a different function
|
|
||||||
}
|
|
||||||
|
|
||||||
if (def->isstatic && def->s_file != s_file)
|
|
||||||
{ //warn? or would that be pointless?
|
|
||||||
foundstatic = def;
|
|
||||||
def = Hash_GetNext(&globalstable, name, def);
|
|
||||||
continue; // in a different function
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type && typecmp(def->type, type))
|
|
||||||
{
|
|
||||||
if (!pr_scope)
|
|
||||||
{
|
|
||||||
char typebuf1[1024], typebuf2[1024];
|
|
||||||
if (typecmp_lax(def->type, type))
|
|
||||||
{
|
|
||||||
//unequal even when we're lax
|
|
||||||
QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
QCC_PR_ParseWarning (WARN_LAXCAST, "Optional arguments differ on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (def->arraysize != arraysize && arraysize>=0)
|
|
||||||
QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
|
|
||||||
if (allocate && scope)
|
|
||||||
{
|
{
|
||||||
if (pr_scope)
|
if (pr_scope)
|
||||||
{ //warn? or would that be pointless?
|
{ //warn? or would that be pointless?
|
||||||
|
@ -10509,6 +10484,7 @@ void QCC_PR_ParseInitializerDef(QCC_def_t *def)
|
||||||
}
|
}
|
||||||
|
|
||||||
int accglobalsblock; //0 = error, 1 = var, 2 = function, 3 = objdata
|
int accglobalsblock; //0 = error, 1 = var, 2 = function, 3 = objdata
|
||||||
|
int qcc_debugflag;
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
PR_ParseDefs
|
PR_ParseDefs
|
||||||
|
@ -10878,7 +10854,7 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
name = QCC_PR_ParseName();
|
name = QCC_PR_ParseName();
|
||||||
QCC_PR_GetDef(type_function, name, NULL, true, 1, true);
|
QCC_PR_GetDef(type_function, name, NULL, true, 0, true);
|
||||||
QCC_PR_CheckToken (";");
|
QCC_PR_CheckToken (";");
|
||||||
return;
|
return;
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -10894,20 +10870,41 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (QCC_PR_CheckKeyword(keyword_object, "object"))
|
if (QCC_PR_CheckKeyword(keyword_object, "object"))
|
||||||
QCC_PR_GetDef(QCC_PR_FieldType(type_entity), name, NULL, true, 0, true);
|
def = QCC_PR_GetDef(QCC_PR_FieldType(type_entity), name, NULL, true, 0, GDF_CONST|GDF_SAVED);
|
||||||
else if (QCC_PR_CheckKeyword(keyword_string, "string"))
|
else if (QCC_PR_CheckKeyword(keyword_string, "string"))
|
||||||
QCC_PR_GetDef(QCC_PR_FieldType(type_string), name, NULL, true, 0, true);
|
def = QCC_PR_GetDef(QCC_PR_FieldType(type_string), name, NULL, true, 0, GDF_CONST|GDF_SAVED);
|
||||||
else if (QCC_PR_CheckKeyword(keyword_real, "real"))
|
else if (QCC_PR_CheckKeyword(keyword_real, "real"))
|
||||||
QCC_PR_GetDef(QCC_PR_FieldType(type_float), name, NULL, true, 0, true);
|
def = QCC_PR_GetDef(QCC_PR_FieldType(type_float), name, NULL, true, 0, GDF_CONST|GDF_SAVED);
|
||||||
else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
|
else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
|
||||||
QCC_PR_GetDef(QCC_PR_FieldType(type_vector), name, NULL, true, 0, true);
|
def = QCC_PR_GetDef(QCC_PR_FieldType(type_vector), name, NULL, true, 0, GDF_CONST|GDF_SAVED);
|
||||||
else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
|
else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
|
||||||
QCC_PR_GetDef(QCC_PR_FieldType(type_function), name, NULL, true, 0, true);
|
def = QCC_PR_GetDef(QCC_PR_FieldType(type_function), name, NULL, true, 0, GDF_CONST|GDF_SAVED);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
|
QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
|
||||||
QCC_PR_Expect (";");
|
QCC_PR_Expect (";");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!def->initialized)
|
||||||
|
{
|
||||||
|
def->initialized = 1;
|
||||||
|
for (i = 0; i < def->type->size*(def->arraysize?def->arraysize:1); i++) //make arrays of fields work.
|
||||||
|
{
|
||||||
|
if (*(int *)&qcc_pr_globals[def->ofs+i])
|
||||||
|
{
|
||||||
|
QCC_PR_ParseWarning(0, "Field def already has a value:");
|
||||||
|
QCC_PR_ParsePrintDef(0, def);
|
||||||
|
}
|
||||||
|
*(int *)&qcc_pr_globals[def->ofs+i] = pr.size_fields+i;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr.size_fields += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
QCC_PR_Expect (";");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
|
@ -10948,14 +10945,28 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
externfnc=false;
|
externfnc=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qcc_debugflag)
|
||||||
|
if (!QCC_PR_GetDef (type_function, "ImpulseCommands", NULL, false, 0, false))
|
||||||
|
QCC_PR_Note(0, strings+s_file, pr_source_line, "ImpulseCommands no longer defined");
|
||||||
|
|
||||||
|
|
||||||
if (!pr_scope && QCC_PR_CheckKeyword(keyword_function, "function")) //reacc support.
|
if (!pr_scope && QCC_PR_CheckKeyword(keyword_function, "function")) //reacc support.
|
||||||
{
|
{
|
||||||
name = QCC_PR_ParseName ();
|
name = QCC_PR_ParseName ();
|
||||||
QCC_PR_Expect("(");
|
QCC_PR_Expect("(");
|
||||||
type = QCC_PR_ParseFunctionTypeReacc(false, type);
|
type = QCC_PR_ParseFunctionTypeReacc(false, type);
|
||||||
QCC_PR_Expect(";");
|
QCC_PR_Expect(";");
|
||||||
|
|
||||||
def = QCC_PR_GetDef (type, name, NULL, true, 0, false);
|
def = QCC_PR_GetDef (type, name, NULL, true, 0, false);
|
||||||
|
|
||||||
|
if (name && !strcmp(name, "ImpulseCommands"))
|
||||||
|
qcc_debugflag = true;
|
||||||
|
|
||||||
|
|
||||||
|
if (qcc_debugflag)
|
||||||
|
if (!QCC_PR_GetDef (type_function, "ImpulseCommands", NULL, false, 0, false))
|
||||||
|
QCC_PR_Note(0, strings+s_file, pr_source_line, "ImpulseCommands no longer defined at the start of %s", name);
|
||||||
|
|
||||||
if (autoprototype)
|
if (autoprototype)
|
||||||
{ //ignore the code and stuff
|
{ //ignore the code and stuff
|
||||||
|
|
||||||
|
@ -10993,7 +11004,8 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
def->references++;
|
def->references++;
|
||||||
|
|
||||||
pr_scope = def;
|
pr_scope = def;
|
||||||
|
@ -11003,13 +11015,13 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
def->isstatic = isstatic;
|
def->isstatic = isstatic;
|
||||||
G_FUNCTION(def->ofs) = numfunctions;
|
G_FUNCTION(def->ofs) = numfunctions;
|
||||||
f->def = def;
|
f->def = def;
|
||||||
// if (pr_dumpasm)
|
// if (pr_dumpasm)
|
||||||
// PR_PrintFunction (def);
|
// PR_PrintFunction (def);
|
||||||
|
|
||||||
if (numfunctions >= MAX_FUNCTIONS)
|
if (numfunctions >= MAX_FUNCTIONS)
|
||||||
QCC_Error(ERR_INTERNAL, "Too many function defs");
|
QCC_Error(ERR_INTERNAL, "Too many function defs");
|
||||||
|
|
||||||
// fill in the dfunction
|
// fill in the dfunction
|
||||||
df = &functions[numfunctions];
|
df = &functions[numfunctions];
|
||||||
numfunctions++;
|
numfunctions++;
|
||||||
if (f->builtin)
|
if (f->builtin)
|
||||||
|
@ -11029,7 +11041,10 @@ void QCC_PR_ParseDefs (char *classname)
|
||||||
{
|
{
|
||||||
df->parm_size[i] = type->params[i].type->size;
|
df->parm_size[i] = type->params[i].type->size;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (qcc_debugflag)
|
||||||
|
if (!QCC_PR_GetDef (type_function, "ImpulseCommands", NULL, false, 0, false))
|
||||||
|
QCC_PR_Note(0, strings+s_file, pr_source_line, "ImpulseCommands no longer defined at the end of %s", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3684,7 +3684,13 @@ char *TypeName(QCC_type_t *type, char *buffer, int buffersize)
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
if (type->type == ev_void)
|
if (type->type == ev_void)
|
||||||
return "void";
|
{
|
||||||
|
if (buffersize < 0)
|
||||||
|
return buffer;
|
||||||
|
*buffer = 0;
|
||||||
|
Q_strlcat(buffer, "void", buffersize);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
if (type->type == ev_pointer)
|
if (type->type == ev_pointer)
|
||||||
{
|
{
|
||||||
|
@ -3717,7 +3723,7 @@ char *TypeName(QCC_type_t *type, char *buffer, int buffersize)
|
||||||
args--;
|
args--;
|
||||||
|
|
||||||
Q_strlcat(buffer, type->params[i].type->name, buffersize);
|
Q_strlcat(buffer, type->params[i].type->name, buffersize);
|
||||||
if (type->params[i].paramname)
|
if (type->params[i].paramname && *type->params[i].paramname)
|
||||||
{
|
{
|
||||||
Q_strlcat(buffer, " ", buffersize);
|
Q_strlcat(buffer, " ", buffersize);
|
||||||
Q_strlcat(buffer, type->params[i].paramname, buffersize);
|
Q_strlcat(buffer, type->params[i].paramname, buffersize);
|
||||||
|
@ -3955,10 +3961,11 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
|
||||||
}
|
}
|
||||||
QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
|
QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
|
||||||
{
|
{
|
||||||
QCC_type_t *ftype;
|
QCC_type_t *ftype, *nptype;
|
||||||
// char *name;
|
char *name;
|
||||||
// char argname[64];
|
int definenames = !recursivefunctiontype;
|
||||||
// int definenames = !recursivefunctiontype;
|
int numparms = 0;
|
||||||
|
struct QCC_typeparam_s paramlist[MAX_PARMS+MAX_EXTRA_PARMS];
|
||||||
|
|
||||||
recursivefunctiontype++;
|
recursivefunctiontype++;
|
||||||
|
|
||||||
|
@ -3971,33 +3978,25 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
|
||||||
|
|
||||||
if (!QCC_PR_CheckToken (")"))
|
if (!QCC_PR_CheckToken (")"))
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
#pragma message("I broke reacc support")
|
|
||||||
#else
|
|
||||||
if (QCC_PR_CheckToken ("..."))
|
|
||||||
ftype->num_parms = -1; // variable args
|
|
||||||
else
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (ftype->num_parms>=MAX_PARMS+MAX_EXTRA_PARMS)
|
if (numparms>=MAX_PARMS+MAX_EXTRA_PARMS)
|
||||||
QCC_PR_ParseError(ERR_TOOMANYTOTALPARAMETERS, "Too many parameters. Sorry. (limit is %i)\n", MAX_PARMS+MAX_EXTRA_PARMS);
|
QCC_PR_ParseError(ERR_TOOMANYTOTALPARAMETERS, "Too many parameters. Sorry. (limit is %i)\n", MAX_PARMS+MAX_EXTRA_PARMS);
|
||||||
|
|
||||||
if (QCC_PR_CheckToken ("..."))
|
if (QCC_PR_CheckToken ("..."))
|
||||||
{
|
{
|
||||||
ftype->num_parms = (ftype->num_parms * -1) - 1;
|
ftype->vargs = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QCC_PR_CheckName("arg"))
|
if (QCC_PR_CheckName("arg"))
|
||||||
{
|
{
|
||||||
sprintf(argname, "arg%i", ftype->num_parms);
|
name = "";
|
||||||
name = argname;
|
|
||||||
nptype = QCC_PR_NewType("Variant", ev_variant, false);
|
nptype = QCC_PR_NewType("Variant", ev_variant, false);
|
||||||
}
|
}
|
||||||
else if (QCC_PR_CheckName("vect")) //this can only be of vector sizes, so...
|
else if (QCC_PR_CheckName("vect")) //this can only be of vector sizes, so...
|
||||||
{
|
{
|
||||||
sprintf(argname, "arg%i", ftype->num_parms);
|
name = "";
|
||||||
name = argname;
|
|
||||||
nptype = QCC_PR_NewType("Vector", ev_vector, false);
|
nptype = QCC_PR_NewType("Vector", ev_vector, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4009,25 +4008,31 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
|
||||||
|
|
||||||
if (nptype->type == ev_void)
|
if (nptype->type == ev_void)
|
||||||
break;
|
break;
|
||||||
if (!ptype)
|
|
||||||
{
|
|
||||||
ptype = nptype;
|
|
||||||
ftype->param = ptype;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptype->next = nptype;
|
|
||||||
ptype = ptype->next;
|
|
||||||
}
|
|
||||||
// type->name = "FUNC PARAMETER";
|
// type->name = "FUNC PARAMETER";
|
||||||
|
|
||||||
|
|
||||||
|
paramlist[numparms].optional = false;
|
||||||
|
paramlist[numparms].ofs = 0;
|
||||||
|
paramlist[numparms].arraysize = 0;
|
||||||
|
paramlist[numparms].type = nptype;
|
||||||
|
|
||||||
|
if (!*name)
|
||||||
|
paramlist[numparms].paramname = "";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
paramlist[numparms].paramname = qccHunkAlloc(strlen(name)+1);
|
||||||
|
strcpy(paramlist[numparms].paramname, name);
|
||||||
|
}
|
||||||
if (definenames)
|
if (definenames)
|
||||||
strcpy (pr_parm_names[ftype->num_parms], name);
|
QC_snprintfz(pr_parm_names[numparms], MAX_NAME, "%s", name);
|
||||||
ftype->num_parms++;
|
|
||||||
|
numparms++;
|
||||||
} while (QCC_PR_CheckToken (";"));
|
} while (QCC_PR_CheckToken (";"));
|
||||||
#endif
|
|
||||||
QCC_PR_Expect (")");
|
QCC_PR_Expect (")");
|
||||||
}
|
}
|
||||||
|
ftype->num_parms = numparms;
|
||||||
|
ftype->params = qccHunkAlloc(sizeof(*ftype->params) * numparms);
|
||||||
|
memcpy(ftype->params, paramlist, sizeof(*ftype->params) * numparms);
|
||||||
recursivefunctiontype--;
|
recursivefunctiontype--;
|
||||||
if (newtype)
|
if (newtype)
|
||||||
return ftype;
|
return ftype;
|
||||||
|
|
|
@ -2837,6 +2837,7 @@ void SetProgsSrc(void)
|
||||||
|
|
||||||
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
|
pbool fl_acc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
WNDCLASS wndclass;
|
WNDCLASS wndclass;
|
||||||
ghInstance= hInstance;
|
ghInstance= hInstance;
|
||||||
|
@ -2878,7 +2879,16 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
||||||
|
|
||||||
GUI_RevealOptions();
|
GUI_RevealOptions();
|
||||||
|
|
||||||
if (/*!fl_acc &&*/ !*progssrcname)
|
for (i = 0, fl_acc = false; compiler_flag[i].enabled; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp("acc", compiler_flag[i].abbrev))
|
||||||
|
{
|
||||||
|
fl_acc = !!(compiler_flag[i].flags & FLAG_SETINGUI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fl_acc && !*progssrcname)
|
||||||
{
|
{
|
||||||
strcpy(progssrcname, "preprogs.src");
|
strcpy(progssrcname, "preprogs.src");
|
||||||
if (QCC_FileSize(progssrcname)==-1)
|
if (QCC_FileSize(progssrcname)==-1)
|
||||||
|
@ -3098,6 +3108,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
||||||
if (buttons[ID_EDIT].washit)
|
if (buttons[ID_EDIT].washit)
|
||||||
{
|
{
|
||||||
buttons[ID_EDIT].washit = false;
|
buttons[ID_EDIT].washit = false;
|
||||||
|
if (*progssrcname)
|
||||||
EditFile(progssrcname, -1);
|
EditFile(progssrcname, -1);
|
||||||
}
|
}
|
||||||
#ifdef EMBEDDEBUG
|
#ifdef EMBEDDEBUG
|
||||||
|
|
|
@ -174,6 +174,46 @@ void GUI_ParseCommandLine(char *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strnicmp(parameters+paramlen, "-F", 2) || !strnicmp(parameters+paramlen, "/F", 2) || !strnicmp(parameters+paramlen, "-K", 2) || !strnicmp(parameters+paramlen, "/K", 2))
|
||||||
|
{
|
||||||
|
if (parameters[paramlen+2])
|
||||||
|
{
|
||||||
|
if (!strncmp(parameters+paramlen+2, "no-", 3))
|
||||||
|
{
|
||||||
|
if (parameters[paramlen+5])
|
||||||
|
{
|
||||||
|
for (p = 0; compiler_flag[p].enabled; p++)
|
||||||
|
if ((*compiler_flag[p].abbrev && !strcmp(parameters+paramlen+5, compiler_flag[p].abbrev)) || !strcmp(parameters+paramlen+5, compiler_flag[p].fullname))
|
||||||
|
{
|
||||||
|
compiler_flag[p].flags &= ~FLAG_SETINGUI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compiler_flag[p].enabled)
|
||||||
|
{
|
||||||
|
parameters[paramlen+next-args] = ' ';
|
||||||
|
paramlen += l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (p = 0; compiler_flag[p].enabled; p++)
|
||||||
|
if ((*compiler_flag[p].abbrev && !strcmp(parameters+paramlen+2, compiler_flag[p].abbrev)) || !strcmp(parameters+paramlen+2, compiler_flag[p].fullname))
|
||||||
|
{
|
||||||
|
compiler_flag[p].flags |= FLAG_SETINGUI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compiler_flag[p].enabled)
|
||||||
|
{
|
||||||
|
parameters[paramlen+next-args] = ' ';
|
||||||
|
paramlen += l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
else if (!strnicmp(parameters+paramlen, "-Fno-kce", 8) || !strnicmp(parameters+paramlen, "/Fno-kce", 8)) //keywords stuph
|
else if (!strnicmp(parameters+paramlen, "-Fno-kce", 8) || !strnicmp(parameters+paramlen, "/Fno-kce", 8)) //keywords stuph
|
||||||
{
|
{
|
||||||
|
|
|
@ -856,9 +856,10 @@ pbool QCC_WriteData (int crc)
|
||||||
pr_scope = def->scope;
|
pr_scope = def->scope;
|
||||||
if (strcmp(def->name, "IMMEDIATE"))
|
if (strcmp(def->name, "IMMEDIATE"))
|
||||||
{
|
{
|
||||||
if (QCC_PR_Warning(wt, strings + def->s_file, def->s_line, "%s no references.", def->name))
|
char typestr[256];
|
||||||
|
if (QCC_PR_Warning(wt, strings + def->s_file, def->s_line, "%s %s no references.", TypeName(def->type, typestr, sizeof(typestr)), def->name))
|
||||||
{
|
{
|
||||||
if (!warnedunref)
|
if (!warnedunref && wt == WARN_NOTREFERENCED)
|
||||||
{
|
{
|
||||||
QCC_PR_Note(WARN_NOTREFERENCED, NULL, 0, "You can use the noref prefix or pragma to silence this message.");
|
QCC_PR_Note(WARN_NOTREFERENCED, NULL, 0, "You can use the noref prefix or pragma to silence this message.");
|
||||||
warnedunref = true;
|
warnedunref = true;
|
||||||
|
@ -3054,6 +3055,7 @@ int QCC_FindQCFiles()
|
||||||
|
|
||||||
int qcc_compileactive = false;
|
int qcc_compileactive = false;
|
||||||
extern int accglobalsblock;
|
extern int accglobalsblock;
|
||||||
|
extern int qcc_debugflag;
|
||||||
char *originalqccmsrc; //for autoprototype.
|
char *originalqccmsrc; //for autoprototype.
|
||||||
void QCC_main (int argc, char **argv) //as part of the quake engine
|
void QCC_main (int argc, char **argv) //as part of the quake engine
|
||||||
{
|
{
|
||||||
|
@ -3079,6 +3081,7 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
|
||||||
pHash_Get = &Hash_Get;
|
pHash_Get = &Hash_Get;
|
||||||
pHash_GetNext = &Hash_GetNext;
|
pHash_GetNext = &Hash_GetNext;
|
||||||
pHash_Add = &Hash_Add;
|
pHash_Add = &Hash_Add;
|
||||||
|
pHash_RemoveData = &Hash_RemoveData;
|
||||||
|
|
||||||
MAX_REGS = 1<<17;
|
MAX_REGS = 1<<17;
|
||||||
MAX_STRINGS = 1000000;
|
MAX_STRINGS = 1000000;
|
||||||
|
@ -3185,6 +3188,7 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
|
||||||
optres_test2 = 0;
|
optres_test2 = 0;
|
||||||
|
|
||||||
accglobalsblock = 0;
|
accglobalsblock = 0;
|
||||||
|
qcc_debugflag = false;
|
||||||
|
|
||||||
|
|
||||||
numtemps = 0;
|
numtemps = 0;
|
||||||
|
@ -3283,6 +3287,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
|
||||||
pHash_Get = &Hash_GetInsensative;
|
pHash_Get = &Hash_GetInsensative;
|
||||||
pHash_GetNext = &Hash_GetNextInsensative;
|
pHash_GetNext = &Hash_GetNextInsensative;
|
||||||
pHash_Add = &Hash_AddInsensative;
|
pHash_Add = &Hash_AddInsensative;
|
||||||
|
pHash_RemoveData = &Hash_RemoveDataInsensative;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = QCC_CheckParm ("-src");
|
p = QCC_CheckParm ("-src");
|
||||||
|
@ -3303,8 +3308,8 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
|
||||||
|
|
||||||
if (flag_acc)
|
if (flag_acc)
|
||||||
{
|
{
|
||||||
if (!QCC_FindQCFiles())
|
if (!QCC_FindQCFiles(qccmsourcedir))
|
||||||
QCC_Error (ERR_COULDNTOPENFILE, "Couldn't open file for asm output.");
|
QCC_Error (ERR_COULDNTOPENFILE, "Couldn't find any qc files.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue