Fix qcc bug with removed continues/breaks editing other statements after removal.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5429 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
b9fd3c01be
commit
d6d8d4c695
2 changed files with 100 additions and 7 deletions
|
@ -4269,6 +4269,70 @@ QCC_statement_t *QCC_PR_SimpleStatement ( QCC_opcode_t *op, QCC_sref_t var_a, QC
|
|||
return statement;
|
||||
}
|
||||
|
||||
/*
|
||||
Removes trailing statements, rewinding back to a known-safe position.
|
||||
*/
|
||||
void QCC_UngenerateStatements(int newstatementcount)
|
||||
{
|
||||
int i;
|
||||
|
||||
//forget any indexes to statements if those statements are going to go away...
|
||||
for (i = 0; i < num_gotos; )
|
||||
{
|
||||
if (pr_gotos[i].statementno >= newstatementcount)
|
||||
{
|
||||
memmove(&pr_gotos[i], &pr_gotos[i+1], sizeof(*pr_gotos)*(num_gotos-(i+1)));
|
||||
num_gotos--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
for (i = 0; i < num_labels; )
|
||||
{ //FIXME: stripping a label? erk?
|
||||
if (pr_labels[i].statementno >= newstatementcount)
|
||||
{
|
||||
memmove(&pr_labels[i], &pr_labels[i+1], sizeof(*pr_labels)*(num_labels-(i+1)));
|
||||
num_labels--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
for (i = 0; i < num_breaks; )
|
||||
{
|
||||
if (pr_breaks[i] >= newstatementcount)
|
||||
{
|
||||
memmove(&pr_breaks[i], &pr_breaks[i+1], sizeof(*pr_breaks)*(num_breaks-(i+1)));
|
||||
num_breaks--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
for (i = 0; i < num_continues; )
|
||||
{
|
||||
if (pr_continues[i] >= newstatementcount)
|
||||
{
|
||||
memmove(&pr_continues[i], &pr_continues[i+1], sizeof(*pr_continues)*(num_continues-(i+1)));
|
||||
num_continues--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
for (i = 0; i < num_cases; )
|
||||
{
|
||||
if (pr_cases[i] >= newstatementcount)
|
||||
{
|
||||
memmove(&pr_cases[i], &pr_cases[i+1], sizeof(*pr_cases)*(num_cases-(i+1)));
|
||||
memmove(&pr_casesref[i], &pr_casesref[i+1], sizeof(*pr_casesref)*(num_cases-(i+1)));
|
||||
memmove(&pr_casesref2[i], &pr_casesref2[i+1], sizeof(*pr_casesref2)*(num_cases-(i+1)));
|
||||
num_cases--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
numstatements = newstatementcount;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_ParseImmediate
|
||||
|
@ -5363,7 +5427,7 @@ static QCC_sref_t QCC_PR_Inline(QCC_sref_t fdef, QCC_ref_t **arglist, unsigned i
|
|||
}
|
||||
|
||||
if (!ctx.result.cast)
|
||||
numstatements = statements; //on failure, remove the extra statements
|
||||
QCC_UngenerateStatements(statements);
|
||||
else
|
||||
{ //on success, make sure the args were freed
|
||||
while (argcount-->0)
|
||||
|
@ -11071,7 +11135,7 @@ void QCC_PR_ParseStatement (void)
|
|||
QCC_PR_ParseStatement ();
|
||||
if (striptruth && oldlab == num_labels)
|
||||
{
|
||||
numstatements = oldnumst;
|
||||
QCC_UngenerateStatements(oldnumst);
|
||||
patch1 = NULL;
|
||||
}
|
||||
else
|
||||
|
@ -11096,7 +11160,7 @@ void QCC_PR_ParseStatement (void)
|
|||
if (stripfalse && oldlab == num_labels)
|
||||
{
|
||||
patch2 = NULL;
|
||||
numstatements = oldnumst;
|
||||
QCC_UngenerateStatements(oldnumst);
|
||||
|
||||
if (patch1)
|
||||
patch1->b.ofs = &statements[numstatements] - patch1;
|
||||
|
@ -11118,7 +11182,7 @@ void QCC_PR_ParseStatement (void)
|
|||
if (stripfalse && oldlab == num_labels)
|
||||
{
|
||||
patch2 = NULL;
|
||||
numstatements = oldnumst;
|
||||
QCC_UngenerateStatements(oldnumst);
|
||||
|
||||
if (patch1)
|
||||
patch1->b.ofs = &statements[numstatements] - patch1;
|
||||
|
@ -13231,7 +13295,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
|
|||
{ //FIXME: should probably always take this path, but kinda pointless until we have relocs for defs
|
||||
QCC_RemapLockedTemps(f->code, numstatements);
|
||||
QCC_Marshal_Locals(f->code, numstatements);
|
||||
QCC_WriteAsmFunction(f, f->code, f->firstlocal); //FIXME: this will print the entire function, not just the part that we added. and we'll print it all again later, too. should probably make it a function attribute that we check at the end.
|
||||
// QCC_WriteAsmFunction(f, f->code, f->firstlocal); //FIXME: this will print the entire function, not just the part that we added. and we'll print it all again later, too. should probably make it a function attribute that we check at the end.
|
||||
|
||||
f->numstatements = numstatements - f->code;
|
||||
f->statements = qccHunkAlloc(sizeof(*statements)*f->numstatements);
|
||||
|
|
|
@ -395,6 +395,7 @@ public:
|
|||
if (c)
|
||||
return; //already in there.
|
||||
|
||||
beginResetModel();
|
||||
c = new filenode_s();
|
||||
c->name = strdup(filename);
|
||||
c->parent = p;
|
||||
|
@ -402,6 +403,7 @@ public:
|
|||
p->children = cpprealloc(p->children, sizeof(*p->children)*(p->numchildren+1));
|
||||
p->children[p->numchildren] = c;
|
||||
p->numchildren++;
|
||||
endResetModel();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -925,6 +927,29 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool annotate(const char *line)
|
||||
{
|
||||
auto filename = line+6;
|
||||
auto filenameend = strchr(filename, ':');
|
||||
if (!filenameend) return false;
|
||||
auto linenum = atoi(filenameend+1);
|
||||
line = strchr(filenameend+1, ':')+1;
|
||||
if (!line) return false;
|
||||
if (strncmp(curdoc->fname, filename, filenameend-filename) || curdoc->fname[filenameend-filename])
|
||||
{
|
||||
auto d = FindFile(filename);
|
||||
if (d)
|
||||
{
|
||||
curdoc = d;
|
||||
s->setDocument(d->doc);
|
||||
}
|
||||
else
|
||||
return false; //some other file that we're not interested in
|
||||
}
|
||||
|
||||
s->annotate(linenum-1, s->annotation(linenum) + line + "\n", 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool saveDocument(document_s *d)
|
||||
{
|
||||
|
@ -1848,7 +1873,12 @@ int GUIprintf(const char *msg, ...)
|
|||
QString s = l.mid(0, idx);
|
||||
l = l.mid(idx+1);
|
||||
|
||||
if (s.contains(": error") || s.contains(": werror") || !s.mid(0,5).compare("error", Qt::CaseInsensitive))
|
||||
if (!s.mid(0, 6).compare("code: "))
|
||||
{
|
||||
mainwnd->docs.annotate(s.toUtf8().data());
|
||||
continue;
|
||||
}
|
||||
else if (s.contains(": error") || s.contains(": werror") || !s.mid(0,5).compare("error", Qt::CaseInsensitive))
|
||||
mainwnd->log.setTextColor(QColor(255, 0, 0));
|
||||
else if (s.contains(": warning"))
|
||||
mainwnd->log.setTextColor(QColor(128, 128, 0));
|
||||
|
@ -1892,7 +1922,6 @@ void documentlist::EditFile(document_s *c, const char *filename, int linenum, bo
|
|||
if (!CreateDocument(c))
|
||||
{
|
||||
delete(c);
|
||||
numdocuments--;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue