diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index c2ac73f3..7f640efc 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -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); diff --git a/engine/qclib/qccguiqt.cpp b/engine/qclib/qccguiqt.cpp index c79c54b2..266955e6 100644 --- a/engine/qclib/qccguiqt.cpp +++ b/engine/qclib/qccguiqt.cpp @@ -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; }