1
0
Fork 0
forked from fte/fteqw

Fix some recent bugs in fteqcc.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5740 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2020-08-03 10:34:44 +00:00
parent 48d4e97515
commit 437a3091e4
6 changed files with 159 additions and 77 deletions

View file

@ -1104,7 +1104,7 @@ reeval:
break;
case OP_MULSTOREP_VF:
i = OPB->_int;
errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
errorif (QCPOINTERWRITEFAIL(i, sizeof(pvec3_t)))
{
prinst.pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
@ -1148,7 +1148,7 @@ reeval:
break;
case OP_ADDSTOREP_V:
i = OPB->_int;
errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
errorif (QCPOINTERWRITEFAIL(i, sizeof(pvec3_t)))
{
prinst.pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
@ -1178,7 +1178,7 @@ reeval:
break;
case OP_SUBSTOREP_V:
i = OPB->_int;
errorif (QCPOINTERWRITEFAIL(i, sizeof(float)))
errorif (QCPOINTERWRITEFAIL(i, sizeof(pvec3_t)))
{
prinst.pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused);
@ -1256,6 +1256,15 @@ reeval:
RUNAWAYCHECK();
st += (sofs)st->b - 1; // offset the s++
break;
case OP_SWITCH_I:
//the case opcodes depend upon the preceding switch.
//otherwise the switch itself is much like a goto
//don't embed the case/caserange checks directly into the switch so that custom caseranges can be potentially be implemented with hybrid emulation.
switchcomparison = OP_SWITCH_E - OP_SWITCH_F;
switchref = OPA;
RUNAWAYCHECK();
st += (sofs)st->b - 1; // offset the s++
break;
case OP_CASE:
//if the comparison is true, jump (back up) to the relevent code block
if (casecmp[switchcomparison](progfuncs, switchref, OPA))

View file

@ -1477,7 +1477,7 @@ static struct {
{QCF_STANDARD, "quakec"},
{QCF_STANDARD, "qs"},
// {QCF_QSS, "qss"},
{QCF_QSS, "qss"},
{QCF_HEXEN2, "hexen2"},
{QCF_HEXEN2, "h2"},
@ -5648,7 +5648,7 @@ static char *QCC_PR_InlineStatements(struct inlinectx_s *ctx)
if (!QCC_PR_InlinePushResult(ctx, st->b, c))
return "too many temps";
}
else
else if (OpAssignsToC(st->op))
{
//a+b->c
if (st->a.cast)
@ -5697,6 +5697,10 @@ static char *QCC_PR_InlineStatements(struct inlinectx_s *ctx)
QCC_PR_SimpleStatement(&pr_opcodes[st->op], a, b, c, false);
}
}
else
{
return "nonstandard opcode form";
}
break;
}
st++;
@ -15686,6 +15690,7 @@ QCC_sref_t QCC_PR_ParseInitializerType_Internal(int arraysize, QCC_def_t *basede
else
{
//FIXME: inheritance makes stuff weird
int i;
isunion = ((type)->type == ev_union);
for (partnum = 0; partnum < (type)->num_parms; partnum++)
{
@ -15693,12 +15698,19 @@ QCC_sref_t QCC_PR_ParseInitializerType_Internal(int arraysize, QCC_def_t *basede
break;
if ((type)->params[partnum].isvirtual)
continue; //these are pre-initialised....
if ((type)->params[partnum].optional)
continue; //float parts of a vector.
// if ((type)->params[partnum].optional)
// continue; //float parts of a vector.
def.cast = (type)->params[partnum].type;
def.ofs = (type)->params[partnum].ofs;
isinited[def.ofs] = true;
if (isinited[def.ofs])
continue;
i = (type)->params[partnum].arraysize;
if (!i)
i = 1;
i *= (type)->params[partnum].type->size;
while(i --> 0)
isinited[def.ofs+i] = true;
def.ofs += offset;
ret &= QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags);

View file

@ -17,7 +17,7 @@ void QCC_FreeDef(QCC_def_t *def);
extern pbool destfile_explicit;
extern char destfile[1024];
static const QCC_sref_t nullsref = {0};
//static const QCC_sref_t nullsref = {0};
#define MAXINCLUDEDIRS 8
char qccincludedir[MAXINCLUDEDIRS][256]; //the -src path, for #includes
@ -6044,7 +6044,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
parms[numparms].defltvalue = defaultval;
numparms++;
if (type->type == ev_vector && arraysize == 0)
/*if (type->type == ev_vector && arraysize == 0)
{ //add in vec_x/y/z members too.
int c;
for (c = 0; c < 3; c++)
@ -6054,13 +6054,13 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
parms[numparms].out = false;
parms[numparms].optional = true;
parms[numparms].isvirtual = isvirt;
parms[numparms].paramname = qccHunkAlloc(strlen(pr_token)+3);
parms[numparms].paramname = qccHunkAlloc(strlen(parmname)+3);
sprintf(parms[numparms].paramname, "%s_%c", parmname, 'x'+c);
parms[numparms].type = type_float;
parms[numparms].defltvalue = nullsref;
numparms++;
}
}
}*/
}
if (!numparms)
QCC_PR_ParseError(ERR_NOTANAME, "%s %s has no members", structtype==ev_union?"union":"struct", newt->name);

View file

@ -521,6 +521,16 @@ protected:
class documentlist : public QAbstractListModel
{
public: enum endings_e
{
NONE = 0, //no endings at all yet
UNIX = 1,
MAC = 2,
MIXED = 3,
WINDOWS = 4,
};
private:
WrappedQsciScintilla *s; //this is the widget that we load our documents into
int numdocuments;
@ -531,6 +541,7 @@ class documentlist : public QAbstractListModel
time_t filemodifiedtime;
bool modified;
int cursorline;
enum endings_e endings; //line endings for this file.
int savefmt; //encoding to save as
QsciDocument doc;
QsciLexer *l;
@ -919,6 +930,60 @@ public:
}
*/ }
void SwitchToDocument_Internal(document_s *ed)
{
curdoc = ed;
s->setDocument(ed->doc);
switch(ed->endings)
{
#ifdef _WIN32
case endings_e::NONE: //new file with no endings, default to windows on windows.
#endif
case endings_e::WINDOWS: //windows
s->setEolMode(QsciScintilla::EolMode::EolWindows);
s->setEolVisibility(false);
break;
#ifndef _WIN32
case endings_e::NONE: //new file with no endings, default to unix on non-windows.
#endif
case endings_e::UNIX: //unix
s->setEolMode(QsciScintilla::EolMode::EolUnix);
s->setEolVisibility(false);
break;
case endings_e::MAC: //mac. traditionally qccs have never supported this. one of the mission packs has a \r in the middle of some single-line comment.
s->setEolMode(QsciScintilla::EolMode::EolMac);
s->setEolVisibility(false);
break;
default: //panic! everyone panic!
s->setEolMode(QsciScintilla::EolMode::EolUnix);
s->setEolVisibility(true);
break;
}
s->setUtf8(ed->savefmt != UTF_ANSI);
}
void ConvertEndings(endings_e newendings)
{
curdoc->endings = newendings;
switch(newendings)
{
case endings_e::WINDOWS: //windows
s->convertEols(QsciScintilla::EolWindows);
break;
case endings_e::UNIX: //unix
s->convertEols(QsciScintilla::EolUnix);
break;
case endings_e::MAC: //mac. traditionally qccs have never supported this. one of the mission packs has a \r in the middle of some single-line comment.
s->convertEols(QsciScintilla::EolMac);
break;
default:
break; //not real endings.
}
SwitchToDocument_Internal(curdoc);
}
bool CreateDocument(document_s *ed)
{
size_t flensz;
@ -932,7 +997,7 @@ public:
QCC_StatFile(ed->fname, &sbuf);
ed->filemodifiedtime = sbuf.st_mtime;
int endings = 0;
endings_e endings = endings_e::NONE;
char *e, *stop;
for (e = file, stop=file+flen; e < stop; )
{
@ -942,43 +1007,27 @@ public:
if (*e == '\n')
{
e++;
endings |= 4;
if (endings != endings_e::WINDOWS)
endings = endings?(endings_e::MIXED):endings_e::WINDOWS;
}
else
endings |= 2;
{
if (endings != endings_e::MAC)
endings = endings?(endings_e::MIXED):endings_e::MAC;
}
}
else if (*e == '\n')
{
e++;
endings |= 1;
if (endings != endings_e::UNIX)
endings = endings?(endings_e::MIXED):endings_e::UNIX;
}
else
e++;
}
ed->endings = endings;
curdoc = ed;
s->setDocument(ed->doc);
switch(endings)
{
case 0: //new file with no endings, default to windows on windows.
case 4: //windows
s->setEolMode(QsciScintilla::EolMode::EolWindows);
s->setEolVisibility(false);
break;
case 1: //unix
s->setEolMode(QsciScintilla::EolMode::EolUnix);
s->setEolVisibility(false);
break;
case 2: //mac. traditionally qccs have never supported this. one of the mission packs has a \r in the middle of some single-line comment.
s->setEolMode(QsciScintilla::EolMode::EolMac);
s->setEolVisibility(false);
break;
default: //panic! everyone panic!
s->setEolMode(QsciScintilla::EolMode::EolUnix);
s->setEolVisibility(true);
break;
}
SwitchToDocument_Internal(ed);
connect(s, &QsciScintillaBase::SCN_CHARADDED, [=](int charadded)
{
@ -992,7 +1041,6 @@ public:
}
});
s->setUtf8(ed->savefmt != UTF_ANSI);
s->setText(QString(file));
SetupScintilla(ed);
@ -1012,8 +1060,7 @@ public:
return;
}
curdoc = ed;
s->setDocument(ed->doc);
SwitchToDocument_Internal(ed);
}
document_s *FindFile(const char *filename)
@ -1798,15 +1845,13 @@ private:
editMenu->addAction(convertunix);
connect(convertunix, &QAction::triggered, [=]()
{
s.convertEols(QsciScintilla::EolUnix);
s.setEolVisibility(false);
docs.ConvertEndings(documentlist::endings_e::UNIX);
});
auto convertdos = new QAction(tr("Convert to DOS Endings"), this);
editMenu->addAction(convertdos);
connect(convertdos, &QAction::triggered, [=]()
{
s.convertEols(QsciScintilla::EolWindows);
s.setEolVisibility(false);
docs.ConvertEndings(documentlist::endings_e::WINDOWS);
});
//convert to utf-8 chars

View file

@ -358,7 +358,10 @@ static char *GUI_ParseInPlace(char **state)
for (end = str, fmt = str; *end; )
{
if (*end == '\"')
{
end++;
break;
}
else if (*end == '\'' && end[1] == '\\')
*fmt = '\\';
else if (*end == '\'' && end[1] == '\"')
@ -379,10 +382,21 @@ static char *GUI_ParseInPlace(char **state)
}
}
else
for (end = str; *end&&*end!=' '&&*end !='\t' && *end != '#'; end++)
;
{
for (end = str; *end; end++)
{
if (*end == '#')
{
while (*end && *end != '\n')
end++;
break;
}
if (*end==' ' || *end =='\t' || *end == '\n')
break;
}
}
*end = 0;
*state = end+1;
*state = end;
return str;
}
static int GUI_ParseIntInPlace(char **state, int defaultval)
@ -492,7 +506,7 @@ void GUI_LoadConfig(void)
fl_ftetarg = GUI_ParseBooleanInPlace(&str, false);
else if (*token)
{
puts("Unknown setting: "); puts(token); puts("\n");
puts("Unknown setting: \""); puts(token); puts("\"\n");
}
}
fclose(file);

View file

@ -1005,7 +1005,6 @@ static void QCC_DetermineNeededSymbols(QCC_def_t *endsyssym)
}
}
const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref);
//allocates final space for the def, making it a true def
static void QCC_FinaliseDef(QCC_def_t *def)
{
@ -1172,7 +1171,7 @@ static void QCC_FinaliseDef(QCC_def_t *def)
sr.sym = def;
sr.ofs = 0;
sr.cast = def->type;
v = QCC_SRef_EvalConst(sr);
v = &sr.sym->symboldata[sr.ofs];
if (v && def->type->type == ev_float)
externs->Printf("Finalise %s(%f) @ %i+%i\n", def->name, v->_float, def->ofs, ssize);
else if (v && def->type->type == ev_vector)
@ -1184,9 +1183,9 @@ static void QCC_FinaliseDef(QCC_def_t *def)
else if (v && def->type->type == ev_field)
externs->Printf("Finalise %s(.%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize);
else if (v && def->type->type == ev_string)
externs->Printf("Finalise %s(%s) @ %i+%i\n", def->name, strings+v->_int, def->ofs, ssize);
externs->Printf("Finalise %s(\"%s\") @ %i+%i\n", def->name, strings+v->_int, def->ofs, ssize);
else
externs->Printf("Finalise %s @ %i+%i\n", def->name, def->ofs, ssize);
externs->Printf("Finalise %s(?) @ %i+%i\n", def->name, def->ofs, ssize);
#endif
}
@ -2510,6 +2509,8 @@ strofs = (strofs+3)&~3;
progs.crc = crc;
if (flag_qccx)
{
def = QCC_PR_GetDef(NULL, "progs", NULL, false, 0, 0); //this is for qccx support
if (def && (def->type->type == ev_entity || (def->type->type == ev_accessor && def->type->parentclass->type == ev_entity)))
{
@ -2540,6 +2541,7 @@ strofs = (strofs+3)&~3;
SafeWrite (h, &i, 4);
}
}
}
// qbyte swap the header and write it out
for (i=0 ; i<sizeof(progs)/4 ; i++)