/** * Add label to repository. * \param [in,out] repository Label repository. * \param [in] name Name. * \param [in] logical Logical address. * \param [in] page Memory page. */ int addLabel(LabelRepository* repository, const char* name, uint16_t logical, uint8_t page) { char *dummy; if(findLabel(repository, logical, page, &dummy)) { if(strcmp(name, dummy)) { // return 0; } return 1; } /* Expand arrays if necessary */ if(repository->last >= repository->size) { Label *ptr; repository->size += LABEL_ARRAY_INC; ptr = (Label*)realloc(repository->labels, repository->size * sizeof(Label)); if(NULL == ptr) { deleteLabelRepository(repository); return 0; } repository->labels = ptr; } /* Push addresses */ repository->labels[repository->last].logical = logical; repository->labels[repository->last].page = page; /* Push name */ if(0 == setLabelName(repository, &repository->labels[repository->last], name)) { deleteLabelRepository(repository); return 0; } ++repository->last; return 1; }
struct ScriptHandler::LabelInfo ScriptHandler::lookupLabel( const char *label ) { int i = findLabel( label ); findAndAddLog( log_info[LABEL_LOG], label_info[i].name, true ); return label_info[i]; }
void WordBookmarkAnalyze(WordBookmark *bookmark, WordSheet *sheet) { // FIXME: Check if the following line is still relevant with the new bookmarks model if (bookmark->element == NULL) // new bookmark return; findTargetAndType(bookmark,sheet); findLabel(bookmark); }
ScriptHandler::LabelInfo ScriptHandler::lookupLabelNext(const pstring& label) { LabelInfo::iterator i = findLabel(label); if (++i != label_info.end()) { label_log.add(label); return *i; } return LabelInfo(); }
unsigned int getOrSubscribePos(char* label, unsigned int where, t_labels* base){ t_label* aux = findLabel(label, base); if(aux->point == -1){ aux->obs = realloc(aux->obs, aux->obsSize+1); aux->obs[aux->obsSize++] = where; return -1; } return aux->point; }
struct ScriptHandler::LabelInfo ScriptHandler::lookupLabelNext( const char *label ) { int i = findLabel( label ); if ( i+1 < num_of_labels ){ findAndAddLog( log_info[LABEL_LOG], label_info[i+1].name, true ); return label_info[i+1]; } return label_info[num_of_labels]; }
void postTranslate(char* label, unsigned int newData, t_labels* base, void (*fun)(short, unsigned int*, char*)){ t_label* aux = findLabel(label, base); aux->point = newData; while( aux->obsSize-- ){ unsigned int cache = aux->obs[aux->obsSize]; fun(sizeof(unsigned int), &cache, (char*)&newData); } free(aux->obs); aux->obs=NULL; }
bool toPieChart::event(QEvent *event) { if (event->type() == QEvent::ToolTip) { QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event); QString t = findLabel(helpEvent->pos()); if (!t.isEmpty()) QToolTip::showText(helpEvent->globalPos(), t); else QToolTip::hideText(); } return QWidget::event(event); }
/* Description- parses a line, and exit when setect error. GET- line: struct that whlie hold info about this line. lineStr: the line that we parse. lineNum: line number in the file. (IC, DC). */ bool parseLine(lineInfo *line, char *lineStr, int lineNum, int *IC, int *DC) { char *startOfNextPart = lineStr; line->lineNum = lineNum; line->address = FIRST_ADDRESS + *IC; line->originalString = allocString(lineStr); line->lineStr = line->originalString; line->label = NULL; line->commandStr = NULL; line->cmd = NULL; if (!line->originalString) { printf("ERR:\tNot enough memory - malloc falied.\n"); return TRUE; } /* Check if the line is a comment */ if (isCommentOrEmpty(line)) { return FALSE; } /* Find label and add it to the label list */ startOfNextPart = findLabel(line, *IC); /* Update the line if startOfNextPart isn't NULL */ if (startOfNextPart) { line->lineStr = startOfNextPart; } /* Find the command token */ line->commandStr = getFirstTok(line->lineStr, &startOfNextPart); line->lineStr = startOfNextPart; /* Parse the command / directive */ if (isDirective(line->commandStr)) { line->commandStr++; /* Remove the '.' from the command */ parseDirective(line, IC, DC); } else { parseCommand(line, IC, DC); } return TRUE; }
//search for a label on the tree bool findLabel(tree t, char *string){ int i; bool founded = false; //see if there is already a tree associated with the label of the tree i = findVar(t -> label); if(i != -1 && variables[i].t != NULL) t = variables[i].t; if(strcmp(t -> label, string) == 0) return true; else{ for(i = 0; (i < t -> n_childs) && !founded; i++) founded = founded || findLabel(t -> childs[i], string); } return founded; }
extern bool ObjLabelDefined( sym_handle sym ) { //********************************************* enum sym_state state; char *sym_name; // Check if it's been emitted by us if( sym && SymLocationKnown( sym ) ) return( TRUE ); // See if it's defined outside sym_name = SymName( sym ); state = AsmQueryState( AsmQuerySymbol( sym_name ) ); if( state != SYM_UNDEFINED ) { return( TRUE ); } // Still need to check the labelList if( findLabel( labelList, sym_name ) ) return( TRUE ); return( FALSE ); }
void CO::removeLabel(const QString &name) { qDebug() << "lets remove label" << name; Label *label = findLabel(name); if(label != 0) { Label *top = label->top(); if(top == 0) m_topLabels.removeOne(label); else top->removeLeaf(label->name()); if(!label->leafs().isEmpty()) foreach(Label *leaf, label->leafs()) leaf->setTop(0); delete label; } }
/* remove a label */ int removeLabel(t_translation_infos *infos, char *ID) { t_asm_label *result; int asm_errorcode; /* initialize the value of `asm_errorcode' */ asm_errorcode = ASM_OK; /* initialize the value of `result' */ result = findLabel(infos, ID, &asm_errorcode); /* postconditions */ if (result == NULL) return asm_errorcode; /* remove the label from the list */ infos->labels = removeElement(infos->labels, result); return asm_errorcode; }
void Quest::processAnswer(int answer) { int curAnswer = 0; for (int i=eip+1; i<commands->size();i++) { if ((*commands)[i][0] == "answer") { if (curAnswer == answer) { int newEip = findLabel((*commands)[i][1]); if (newEip == -1) { logError(QObject::tr("label not found for answer %1").arg(answer)); sendEndDialog(owner); return; } eip = newEip; sendEndDialog(owner); runScript(eip); return; } else curAnswer++; } else if ((*commands)[i][0] == "sayName") continue; else if ((*commands)[i][0] == "sayIcon") continue; else { logError(QObject::tr("answer %1 not found").arg(answer)); sendEndDialog(owner); return; } } }
ScriptHandler::LabelInfo ScriptHandler::lookupLabel(const pstring& label) { LabelInfo::iterator i = findLabel(label); label_log.add(label); return *i; }
void *StatusFrame::processEvent(Event *e) { CommandDef *cmd; switch (e->type()){ case EventCheckState: cmd = (CommandDef*)(e->param()); if ((cmd->menu_id == MenuStatusWnd) && (cmd->id == CmdStatusWnd)){ unsigned n = 0; { QObjectList *l = queryList("StatusLabel"); QObjectListIt itObject(*l); QObject *obj; while ((obj=itObject.current()) != NULL) { ++itObject; StatusLabel *lbl = static_cast<StatusLabel*>(obj); if (lbl->x() + lbl->width() > width()) n++; } delete l; } CommandDef *cmds = new CommandDef[n + 1]; memset(cmds, 0, sizeof(CommandDef) * (n + 1)); QObjectList *l = queryList("StatusLabel"); QObjectListIt itObject(*l); QObject *obj; n = 0; while ((obj=itObject.current()) != NULL) { ++itObject; StatusLabel *lbl = static_cast<StatusLabel*>(obj); if (lbl->x() + lbl->width() > width()){ cmds[n].id = 1; cmds[n].text = "_"; cmds[n].text_wrk = strdup(CorePlugin::m_plugin->clientName(lbl->m_client).utf8()); cmds[n].popup_id = lbl->m_id; if (lbl->m_client->getState() == Client::Error){ cmds[n].icon = "error"; }else{ Protocol *protocol = lbl->m_client->protocol(); const CommandDef *cmd = protocol->description(); cmds[n].icon = cmd->icon; for (cmd = protocol->statusList(); cmd->text; cmd++){ if (cmd->id == lbl->m_client->getStatus()){ cmds[n].icon = cmd->icon; break; } } } n++; } } delete l; cmd->param = cmds; cmd->flags |= COMMAND_RECURSIVE; return e->param(); } break; case EventClientsChanged: addClients(); break; case EventClientChanged:{ StatusLabel *lbl = findLabel((Client*)(e->param())); if (lbl) lbl->setPict(); break; } case EventClientError: if (isVisible()){ clientErrorData *data = (clientErrorData*)(e->param()); if (data->code == AuthError) break; StatusLabel *lbl = findLabel(data->client); if (lbl == NULL) break; if (data->err_str && *data->err_str){ QString msg = i18n(data->err_str); if (data->args) msg = msg.arg(QString::fromUtf8(data->args)); raiseWindow(topLevelWidget()); BalloonMsg::message(msg, lbl); return e->param(); } } break; case EventIconChanged:{ QObjectList *l = queryList("StatusLabel"); QObjectListIt itObject(*l); QObject *obj; while ((obj=itObject.current()) != NULL) { ++itObject; static_cast<StatusLabel*>(obj)->setPict(); } delete l; break; } } return NULL; }
int main(){ FILE* file=NULL; FILE* file2=NULL; file=fopen(INPUT_FILE,"r+"); if (file==NULL){ printf("ERROR: unexistant file\n"); exit(1); } //totalline = nombre de lignes int totalline = countLines(file); //creation du tableau Label* label_tab = createLabelTab(totalline); fclose(file); //remplissage du tableau des etiquettes file=fopen(INPUT_FILE,"r+"); fillLabelTab(file, label_tab); fclose(file); //creation fichier a exporter file=fopen(INPUT_FILE,"r+"); file2=fopen("out.txt","w"); char str[T_MAX]; char *word; //mot a transformer en nombre avec la fonction instrucstions char *arg; //argument de type chaine de caracteres char *useless; //pour ignorer les etiquettes lors de la traduction int argint; //argument de type entier while(fgets(str,T_MAX,file)) { line_n++; //Evite l'etiquette a la traduction et met l'instruction dans word if (strstr(str, ":") != NULL) { useless = strtok(str, " \t\r\n:"); //met l'etiquette de cote word = strtok(NULL, " \t\r\n"); //prend la suite (jusqu'a " \t\r\n") et le met dans word } else { word = strtok(str, " \t\r\n"); } //Met l'argument dans arg arg = strtok(NULL, " \t\r\n:"); //Teste les types d'arguments attendus et le change en entier //On attend aucun argument if (argtype(word) == 0) { if(arg != NULL) { printf("ERROR: too many arguments to function ‘%s’ at line %d\n", word, line_n); exit(1); } argint = 0; } //On attend un nombre else if (argtype(word) == 1) { if (arg == NULL) { printf("ERROR: too few arguments to function ‘%s’ at line %d\n", word, line_n); exit(1); } else if (is_int(arg) == 0) { printf("ERROR: expected ‘int’ argument to function ‘%s’ at line %d\n", word, line_n); exit(1); } else if (strtok(NULL, " \t\r\n") != NULL) { printf("ERROR: too many arguments to function ‘%s’ at line %d\n", word, line_n); exit(1); } argint = atoi(arg); } //On attend une etiquette else if (argtype(word) == 2) { if (arg == NULL) { printf("ERROR: too few arguments to function ‘%s’ at line %d\n", word, line_n); exit(1); } else if (is_int(arg) == 1) { printf("ERROR: expected ‘char *’ but argument is of type ‘int’ at line %d\n", line_n); exit(1); } else if (strtok(NULL, " \t\r\n") != NULL) { printf("ERROR: too many arguments to function ‘%s’ at line %d\n", word, line_n); exit(1); } argint = findLabel(arg, label_tab) - line_n; //difference entre la position actuelle et de l'etiquette } //printf de verification //printf("instruction : %s // argument : %s\n", word, arg); //printf("code intruction : %02X // arg = %08X \n\n",instructions(word), argint); //ecriture sur le fichier de sortie file2 fprintf(file2,"%02X %08X\n",instructions(word), argint); } fclose(file); fclose(file2); free(label_tab); //Liberation de la memoire printf("It's OKAY !! :D"); return 0; }
/*-----------------------------------------------------------------*/ static S4O_RET scan4op (lineNode **pl, const char *pReg, const char *untilOp, lineNode **plCond) { char *p; int len; bool isConditionalJump; int rIdx; S4O_RET ret; bool findPushPop; findPushPop = untilOp && (strcmp (untilOp, "push") == 0 || strcmp (untilOp, "pop") == 0); /* pReg points to e.g. "ar0"..."ar7" */ len = strlen (pReg); /* get index into pReg table */ for (rIdx = 0; rIdx < mcs51_nRegs; ++rIdx) if (strcmp (regs8051[rIdx].name, pReg + 1) == 0) break; /* sanity check */ if (rIdx >= mcs51_nRegs) { DEADMOVEERROR(); return S4O_ABORT; } for (; *pl; *pl = (*pl)->next) { if (!(*pl)->line || (*pl)->isDebug || (*pl)->isComment) continue; /* don't optimize across inline assembler, e.g. isLabel doesn't work there */ if ((*pl)->isInline) return S4O_ABORT; if ((*pl)->visited) return S4O_VISITED; (*pl)->visited = TRUE; /* found untilOp? */ if (untilOp && strncmp ((*pl)->line, untilOp, strlen (untilOp)) == 0) { p = (*pl)->line + strlen (untilOp); if (*p == '\t' && strncmp (p + 1, pReg, len) == 0) return S4O_FOUNDOPCODE; else { /* found untilOp but without our pReg */ return S4O_ABORT; } } /* found pReg? */ p = strchr ((*pl)->line, '\t'); if (p) { /* skip '\t' */ p++; /* when looking for push or pop and we find a direct access of sp: abort */ if (findPushPop && strstr (p, "sp")) return S4O_ABORT; /* course search */ if (strstr (p, pReg + 1)) { /* ok, let's have a closer look */ /* does opcode read from pReg? */ if (bitVectBitValue (port->peep.getRegsRead ((*pl)), rIdx)) return S4O_RD_OP; /* does opcode write to pReg? */ if (bitVectBitValue (port->peep.getRegsWritten ((*pl)), rIdx)) return S4O_WR_OP; /* we can get here, if the register name is part of a variable name: ignore it */ } } /* found label? */ if ((*pl)->isLabel) { const char *start; char label[SDCC_NAME_MAX + 1]; int len; if (!isLabelDefinition ((*pl)->line, &start, &len, FALSE)) return S4O_ABORT; memcpy (label, start, len); label[len] = '\0'; /* register passing this label */ if (!setLabelRefPassedLabel (label)) { DEADMOVEERROR(); return S4O_ABORT; } continue; } /* branch or terminate? */ isConditionalJump = FALSE; switch ((*pl)->line[0]) { case 'a': if (strncmp ("acall", (*pl)->line, 5) == 0) { /* for comments see 'lcall' */ ret = termScanAtFunc (*pl, rIdx); if (ret != S4O_CONTINUE) return ret; break; } if (strncmp ("ajmp", (*pl)->line, 4) == 0) { *pl = findLabel (*pl); if (!*pl) return S4O_ABORT; } break; case 'c': if (strncmp ("cjne", (*pl)->line, 4) == 0) { isConditionalJump = TRUE; break; } break; case 'd': if (strncmp ("djnz", (*pl)->line, 4) == 0) { isConditionalJump = TRUE; break; } break; case 'j': if (strncmp ("jmp", (*pl)->line, 3) == 0) /* "jmp @a+dptr": no chance to trace execution */ return S4O_ABORT; if (strncmp ("jc", (*pl)->line, 2) == 0 || strncmp ("jnc", (*pl)->line, 3) == 0 || strncmp ("jz", (*pl)->line, 2) == 0 || strncmp ("jnz", (*pl)->line, 3) == 0) { isConditionalJump = TRUE; break; } if (strncmp ("jbc", (*pl)->line, 3) == 0 || strncmp ("jb", (*pl)->line, 2) == 0 || strncmp ("jnb", (*pl)->line, 3) == 0) { isConditionalJump = TRUE; break; } break; case 'l': if (strncmp ("lcall", (*pl)->line, 5) == 0) { const char *p = (*pl)->line+5; while (*p == ' ' || *p == '\t') p++; while (isdigit (*p)) p++; if (isdigit(p[-1]) && *p == '$') /* at least one digit */ { /* this is a temp label for a pcall */ *pl = findLabel (*pl); if (!*pl) return S4O_ABORT; break; } ret = termScanAtFunc (*pl, rIdx); /* If it's a 'normal' 'caller save' function call, all registers have been saved until the 'lcall'. The 'life range' of all registers end at the lcall, and we can terminate our search. * If the function is 'banked', the registers r0, r1 and r2 are used to tell the trampoline the destination. After that their 'life range' ends just like the other registers. * If it's a 'callee save' function call, registers are saved by the callee. We've got no information, if the register might live beyond the lcall. Therefore we've to continue the search. */ if (ret != S4O_CONTINUE) return ret; break; } if (strncmp ("ljmp", (*pl)->line, 4) == 0) { *pl = findLabel (*pl); if (!*pl) return S4O_ABORT; } break; case 'p': if (strncmp ("pop", (*pl)->line, 3) == 0 || strncmp ("push", (*pl)->line, 4) == 0) return S4O_PUSHPOP; break; case 'r': if (strncmp ("reti", (*pl)->line, 4) == 0) return S4O_TERM; if (strncmp ("ret", (*pl)->line, 3) == 0) { /* pcall uses 'ret' */ if (isFunc (*pl)) { /* for comments see 'lcall' */ ret = termScanAtFunc (*pl, rIdx); if (ret != S4O_CONTINUE) return ret; break; } /* it's a normal function return */ if (!((*pl)->ic) || (IS_SYMOP (IC_LEFT ((*pl)->ic)) && IS_FUNC (OP_SYM_TYPE(IC_LEFT ((*pl)->ic))) && FUNC_CALLEESAVES (OP_SYM_TYPE(IC_LEFT ((*pl)->ic))))) return S4O_ABORT; else return S4O_TERM; } break; case 's': if (strncmp ("sjmp", (*pl)->line, 4) == 0) { *pl = findLabel (*pl); if (!*pl) return S4O_ABORT; } break; default: break; } /* switch ((*pl)->line[0]) */ if (isConditionalJump) { *plCond = findLabel (*pl); if (!*plCond) return S4O_ABORT; return S4O_CONDJMP; } } /* for (; *pl; *pl = (*pl)->next) */ return S4O_ABORT; }
//Translate the instruction to binary char* mountBinary(char instruction[],int nRegisters,int nConstants,int nLabels, char type, char *opcode, char *function, int currentAddress) { int i = 0, j = 0, nRegsAux = 0, nConstAux = 0, nLabAux = 0; static char binary[32]; char param[10], name[10]; int isRegister = 0, isLabel = 0, isConstant = 0; //Define the initial binary for(i = 0; i < 32; i++) binary[i] = '0'; i = 0; //Push the opcode concatBinary(0, 6, binary, opcode); //Takes the instruction name while(instruction[i] != ' '){ name[i] = instruction[i]; i++; } name[i] = '\0'; i = 0; //Formats the instruction instruction = strchr(instruction, ' '); instruction = ++instruction; while(instruction[i] != '\0'){ //Push the current instruction parameter if(instruction[i] != ','){ param[j] = instruction[i]; j++; } //If the char is comma or it is the instruction final if(instruction[i] == ',' || i == strlen(instruction) - 1){ param[j] = '\0'; //If the parameter is a register if(nRegisters != nRegsAux){ isRegister = 1; isLabel = 0; isConstant = 0; nRegsAux++; } //If the parameter is a constant else if(nConstants != nConstAux){ isRegister = 0; isLabel = 0; isConstant = 1; nConstAux++; } //If the parameter is a label else if(nLabels != nLabAux){ isRegister = 0; isLabel = 1; isConstant = 0; nLabAux++; } //Operation for register if(isRegister == 1){ //To load and store char copy[10]; //Load and Store if(nRegsAux == 2 && (strcmp(name, "lw") == 0 || strcmp(name, "lh") == 0 || strcmp(name, "lb") == 0 || strcmp(name, "sw") == 0 || strcmp(name, "sh") == 0 || strcmp(name, "sb") == 0) ) { strcpy(copy, param); strcpy(param, strchr(param, '$')); param[strlen(param) - 1] = '\0'; isRegister = 0; isLabel = 0; isConstant = 1; nConstAux++; } //Find the register code strcpy(param, findRegister(param)); //If is not exists if(strcmp(param, "NULL") == 0) return "1"; //Push on correct position if(type == 'R'){ if(nRegsAux == 1){ if(strcmp(name, "ext") == 0 || strcmp(name, "ins") == 0) concatBinary(11, 5, binary, param); else if(strcmp(name, "div") == 0 || strcmp(name, "divu") == 0 || strcmp(name, "madd") == 0 || strcmp(name, "maddu") == 0 || strcmp(name, "msub") == 0 || strcmp(name, "msubu") == 0 || strcmp(name, "mult") == 0 || strcmp(name, "multu") == 0 || strcmp(name, "mthi") == 0 || strcmp(name, "mtlo") == 0 || strcmp(name, "jr") == 0) concatBinary(6, 5, binary, param); else concatBinary(16, 5, binary, param); } else if(nRegsAux == 2){ if(strcmp(name, "wsbh") == 0 || strcmp(name, "seh") == 0 || strcmp(name, "seb") == 0 || strcmp(name, "div") == 0 || strcmp(name, "divu") == 0 || strcmp(name, "madd") == 0 || strcmp(name, "maddu") == 0 || strcmp(name, "msub") == 0 || strcmp(name, "msubu") == 0 || strcmp(name, "mult") == 0 || strcmp(name, "multu") == 0 || strcmp(name, "sll") == 0 || strcmp(name, "srl") == 0 || strcmp(name, "sra") == 0 || strcmp(name, "rotr") == 0 || strcmp(name, "sllv") == 0 || strcmp(name, "srav") == 0 || strcmp(name, "srlv") == 0 || strcmp(name, "rotrv") == 0) concatBinary(11, 5, binary, param); else concatBinary(6, 5, binary, param); } else if(nRegsAux == 3){ if(strcmp(name, "sllv") == 0 || strcmp(name, "srav") == 0 || strcmp(name, "srlv") == 0 || strcmp(name, "rotrv") == 0) concatBinary(6, 5, binary, param); else concatBinary(11, 5, binary, param); } } else if(type == 'I'){ if(nRegsAux == 1){ if(strcmp(name, "beq") == 0 || strcmp(name, "bne") == 0 || strcmp(name, "bgtz") == 0 || strcmp(name, "bltz") == 0) concatBinary(6, 5, binary, param); else concatBinary(11, 5, binary, param); } else if(nRegsAux == 2){ if(strcmp(name, "beq") == 0 || strcmp(name, "bne") == 0 || strcmp(name, "bgtz") == 0 || strcmp(name, "bltz") == 0) concatBinary(11, 5, binary, param); else concatBinary(6, 5, binary, param); } } //To load and store if(isConstant == 1){ strcpy(param, copy); strcpy(param, strchr(strrev(param), '(')); strcpy(param, strrev(strchr(param, param[1]))); while(param[0] == ' ' || param[0] == '\t') strcpy(param, strchr(param, param[1])); } } //Operation for label else if(isLabel == 1){ //Find the label code strcpy(param, findLabel(param)); //If is not valid if(strcmp(param, "NULL") == 0) return "2"; //Branchs instructions if(strcmp(name, "beq") == 0 || strcmp(name, "bgtz") == 0 || strcmp(name, "bne") == 0 || strcmp(name, "bltz") == 0) { int labelAddress = 0, i = 0; for(i; i < 16; i++){ if(param[i] == '1') labelAddress++; if(i != 15) labelAddress = labelAddress << 1; } itoa(labelAddress - currentAddress, param, 2); strcpy(param, completeBinary(16, param)); } //Push on correct position concatBinary(16, 16, binary, param); } //Operation for constant if(isConstant == 1){ //Convert to integer int constValue = atoi(param); //Verify if is valid if(constValue == 0 && param[0] != '0') return "3"; if(type != 'R'){ //Unsigned instructions if(strcmp(name, "addiu") == 0 || strcmp(name, "sltiu") == 0) { if(constValue < 0) return "7"; if(constValue > getBinaryRange(17, '+')) return "6"; } //Signed else{ if(constValue > getBinaryRange(16, '+') || constValue < getBinaryRange(16, '-')) return "6"; } //Converts to binary and push to instruction char constant[16]; itoa(constValue, constant, 2); strcpy(constant, completeBinary(16, constant)); concatBinary(16, 16, binary, constant); } else{ if(constValue > getBinaryRange(5, '+') || constValue < getBinaryRange(5, '-')) return "6"; //Shamt, ins and ext char constant[5]; int pos, size; if(strcmp(name, "ext") == 0 && nConstAux == 2) constValue--; itoa(constValue, constant, 2); strcpy(constant, completeBinary(5, constant)); if(strcmp(name, "ext") == 0 && nConstAux == 1) concatBinary(21, 5, binary, constant); else if(strcmp(name, "ext") == 0 && nConstAux == 2) concatBinary(16, 5, binary, constant); else if(strcmp(name, "ins") == 0 && nConstAux == 1) pos = constValue; else if(strcmp(name, "ins") == 0 && nConstAux == 2){ size = constValue; int msb = (pos + size) - 1; itoa(msb, constant, 2); strcpy(constant, completeBinary(5, constant)); concatBinary(16, 5, binary, constant); itoa(pos, constant, 2); strcpy(constant, completeBinary(5, constant)); concatBinary(21, 5, binary, constant); } else concatBinary(21, 5, binary, constant); } } param[0] = '\0'; j = 0; } i++; } //Minus arguments if(nConstants != nConstAux || nRegisters != nRegsAux || nLabels != nLabAux) return "5"; //Place the shamt and function on binary if(type == 'R'){ concatBinary(26, 6, binary, function); //seh, seb and wsbh instructions if(strcmp(opcode, "011111") == 0 && strcmp(function, "100000") == 0){ if(strcmp(name, "seh") == 0) concatBinary(21, 5, binary, "11000"); else if(strcmp(name, "seb") == 0) concatBinary(21, 5, binary, "10000"); else if(strcmp(name, "wsbh") == 0) concatBinary(21, 5, binary, "00010"); } if(strcmp(name, "rotr") == 0) concatBinary(6, 5, binary, "00001"); else if(strcmp(name, "rotrv") == 0) concatBinary(21, 5, binary, "00001"); } binary[32] = '\0'; return binary; }
//find, if possible, the most general unifier bool unifier(tree t1, tree t2){ bool result, var1, var2; tree aux; int i; //see if there is already a tree associated with the variable i = findVar(t1 -> label); if(i != -1 && variables[i].t != NULL) t1 = variables[i].t; i = findVar(t2 -> label); if(i != -1 && variables[i].t != NULL) t2 = variables[i].t; //set boolean variables result = true; var1 = isVariable(t1 -> label); var2 = isVariable(t2 -> label); //comparing step if(strcmp(t1 -> label, t2 -> label) == 0) goto advance; //substitution step else{ //neither of the two labels are variables if(!var1 && !var2) return false; //if the node on t1 is a variable else if(var1 && !var2){ //founded variable with the same name on t2 if(findLabel(t2, t1 -> label) != NULL) return false; //associate t2 with the variable else{ treeToVar(t2, t1 -> label); t1 = t2; } } //if the node on t2 is a variable else{ //founded variable with the same name on t1 if(findLabel(t1, t2 -> label) != NULL) return false; //associate t1 with the variable else{ treeToVar(t1, t2 -> label); t2 = t1; } } } advance: if(t1 -> n_childs == 0 && t2 -> n_childs == 0) return true; else{ //call for the next childs on both trees for(i = 0; result && (i < t1 -> n_childs) && (i < t1 -> n_childs); i++) result = result && unifier(t1 -> childs[i], t2 -> childs[i]); return result; } }
int convertToMachineCode(Instruction* inst, Label* table, int pc) { int res = 0; if (strcmp("add", inst->pOpcode) == 0 || strcmp("and", inst->pOpcode) == 0 || strcmp("xor", inst->pOpcode) == 0) { /* 'add', 'and', and 'xor' only differ by the opcode */ int opcode; if (strcmp("add", inst->pOpcode) == 0) { opcode = 0x1; } /* add */ else if (strcmp("and", inst->pOpcode) == 0) { opcode = 0x5; } /* and*/ else { opcode = 0x9; } /* xor */ res += opcode << 12; int dr, sr1, sr2, imm; /* Check if arg1 and arg2 are valid registers */ dr = getRegister(inst->pArg1); sr1 = getRegister(inst->pArg2); if (dr == -1 || sr1 == -1) { /* first 2 arguments MUST be registers */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append dr and sr1 to res */ res += dr << 9; res += sr1 << 6; /* Check if arg3 is a register or a constant */ char key = inst->pArg3[0]; if (key == 'r') { /* is a register */ sr2 = getRegister(inst->pArg3); if (sr2 == -1) { /* invalid register */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } res += sr2; } else if (key == '#' || key == 'x') { /* is a constant */ imm = toNum(inst->pArg3); if (isConstant(imm, 5) == -1) { printf("ERROR: Invalid constant. Exiting with error code 3."); exit(3); } res += 1 << 5; if (imm < 0) { /* convert negative to positive 2's complement */ imm = convertTwosComplement(imm, 5); } res += imm; } else { printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Check that arg4 is empty */ if (strlen(inst->pArg4) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if ( /* all 8 branch variants */ strcmp("br", inst->pOpcode) == 0 || strcmp("brn", inst->pOpcode) == 0 || strcmp("brz", inst->pOpcode) == 0 || strcmp("brp", inst->pOpcode) == 0 || strcmp("brnz", inst->pOpcode) == 0 || strcmp("brnp", inst->pOpcode) == 0 || strcmp("brzp", inst->pOpcode) == 0 || strcmp("brnzp", inst->pOpcode) == 0 ) { int opcode = 0; if (strcmp("br", inst->pOpcode) == 0 || strcmp("br", inst->pOpcode) == 0) { /* br and brnzp have same machine code output */ opcode = 0x7; } else if (strcmp("brn", inst->pOpcode) == 0) { opcode = 0x4; } else if (strcmp("brz", inst->pOpcode) == 0) { opcode = 0x2; } else if (strcmp("brp", inst->pOpcode) == 0) { opcode = 0x1; } else if (strcmp("brnz", inst->pOpcode) == 0) { opcode = 0x6; } else if (strcmp("brnp", inst->pOpcode) == 0) { opcode = 0x5; } else if (strcmp("brzp", inst->pOpcode) == 0) { opcode = 0x3; } else { /* invalid branch */ printf("ERROR: Invalid opcode. Exiting with error code 2."); exit(2); } res += opcode << 9; /* Check for valid label */ char* labelName = inst->pArg1; if (isValidLabel(labelName) == -1) { /* invalid label name */ printf("ERROR: Invalid label name. Exiting with error code 4."); exit(4); } Label label; strcpy(label.label, labelName); int addr = findLabel(label, table); if (addr == -1) { /* couldn't find label */ printf("ERROR: Couldn't find label. Exiting with error code 1."); exit(1); } /* Calculate PCOffset and append */ int diff = addr - (pc + 1); if (diff < 0) { /* convert negative to positive 2's complement */ diff = convertTwosComplement(diff, 9); } res += diff; /* Check that arg2 is empty */ if (strlen(inst->pArg2) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("halt", inst->pOpcode) == 0) { res = 0xF025; /* Check that all args are empty */ if (strlen(inst->pArg1) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("jmp", inst->pOpcode) == 0) { int opcode = 0x60; res += opcode << 9; /* Check that br is valid */ int br; /* Check if arg1 is valid register */ br = getRegister(inst->pArg1); if (br == -1) { /* first argument MUST be register */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append br to res */ res += br << 6; /* Check that arg2 is empty */ if (strlen(inst->pArg2) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("jsr", inst->pOpcode) == 0) { int opcode = 0x4; res += opcode << 12; res += 1 << 11; /* constant bit */ /* Check for valid label */ char* labelName = inst->pArg1; if (isValidLabel(labelName) == -1) { /* invalid label name */ printf("ERROR: Invalid label name. Exiting with error code 4."); exit(4); } Label label; strcpy(label.label, labelName); int addr = findLabel(label, table); if (addr == -1) { /* couldn't find label */ printf("ERROR: Couldn't find label. Exiting with error code 1."); exit(1); } /* Calculate PCOffset and append */ int diff = addr - (pc + 1); if (diff < 0) { /* convert negative to positive 2's complement */ diff = convertTwosComplement(diff, 11); } res += diff; /* Check that arg2 is empty */ if (strlen(inst->pArg2) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("jsrr", inst->pOpcode) == 0) { int opcode = 0x4; res += opcode << 12; /* Check that br is valid */ int br; /* Check if arg1 is valid register */ br = getRegister(inst->pArg1); if (br == -1) { /* first argument MUST be register */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append br to res */ res += br << 6; /* Check that arg2 is empty */ if (strlen(inst->pArg2) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("ldb", inst->pOpcode) == 0 || strcmp("ldw", inst->pOpcode) == 0) { int opcode; if (strcmp("ldb", inst->pOpcode) == 0) { opcode = 0x2; } /* ldb */ else { opcode = 0x6; } /* ldw */ res += opcode << 12; /* Check that dr and sr are both valid */ int dr, sr, offset; /* Check if arg1 and arg2 are valid registers */ dr = getRegister(inst->pArg1); sr = getRegister(inst->pArg2); if (dr == -1 || sr == -1) { /* first 2 arguments MUST be registers */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append dr and sr1 to res */ res += dr << 9; res += sr << 6; /* Check that arg3 is a constant */ char key = inst->pArg3[0]; if (key == '#' || key == 'x') { /* is a constant */ offset = toNum(inst->pArg3); if (isConstant(offset, 6) == -1) { printf("ERROR: Invalid constant. Exiting with error code 3."); exit(3); } if (offset < 0) { /* convert negative to positive 2's complement */ offset = convertTwosComplement(offset, 6); } res += offset; } else { printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Check that arg4 is empty */ if (strlen(inst->pArg4) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("lea", inst->pOpcode) == 0) { int opcode = 0xE; res += opcode << 12; /* Check that dr is valid */ int dr; /* Check if arg1 is valid register */ dr = getRegister(inst->pArg1); if (dr == -1) { /* first argument MUST be register */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append dr to res */ res += dr << 9; /* Check for valid label */ char* labelName = inst->pArg2; if (isValidLabel(labelName) == -1) { /* invalid label name */ printf("ERROR: Invalid label name. Exiting with error code 4."); exit(4); } Label label; strcpy(label.label, labelName); int addr = findLabel(label, table); if (addr == -1) { /* couldn't find label */ printf("ERROR: Couldn't find label. Exiting with error code 1."); exit(1); } /* Calculate PCOffset and append */ int diff = addr - (pc + 1); if (diff < 0) { /* convert negative to positive 2's complement */ diff = convertTwosComplement(diff, 9); } res += diff; /* Check that arg3 is empty */ if (strlen(inst->pArg3) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("nop", inst->pOpcode) == 0) { res = 0x0000; /* Check that all args are empty */ if (strlen(inst->pArg1) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("not", inst->pOpcode) == 0) { int opcode = 9; res += opcode << 12; /* Check that dr and sr are both valid */ int dr, sr; /* Check if arg1 and arg2 are valid registers */ dr = getRegister(inst->pArg1); sr = getRegister(inst->pArg2); if (dr == -1 || sr == -1) { /* first 2 arguments MUST be registers */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append dr and sr1 to res */ res += dr << 9; res += sr << 6; /* Append trailing 1's */ res += 0x3F; /* Check that arg3 is empty */ if (strlen(inst->pArg3) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("ret", inst->pOpcode) == 0) { res = 0xC1C0; /* Check that all args are empty */ if (strlen(inst->pArg1) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if ( strcmp("lshf", inst->pOpcode) == 0 || strcmp("rshfl", inst->pOpcode) == 0 || strcmp("rshfa", inst->pOpcode) == 0 ) { int opcode = 0xD; res += opcode << 12; int dr, sr, num; /* Check if arg1 and arg2 are valid registers */ dr = getRegister(inst->pArg1); sr = getRegister(inst->pArg2); if (dr == -1 || sr == -1) { /* first 2 arguments MUST be registers */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append dr and sr1 to res */ res += dr << 9; res += sr << 6; /* Check that arg3 is a constant */ char key = inst->pArg3[0]; if (key == '#' || key == 'x') { /* is a constant */ num = toNum(inst->pArg3); if (isConstantUnsigned(num, 4) == -1) { /* check that it is unsigned */ printf("ERROR: Invalid constant. Exiting with error code 3."); exit(3); } /* set bits 5 and 4 */ if (strcmp("rshfa", inst->pOpcode) == 0) { /* 1 1 */ res += 0x3 << 4; } else if (strcmp("rshfl", inst->pOpcode) == 0) { /* 0 1 */ res += 0x1 << 4; } else {} /* 0 0 */ res += num; } else { printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Check that arg4 is empty */ if (strlen(inst->pArg4) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("rti", inst->pOpcode) == 0) { res = 0x8000; /* Check that all args are empty */ if (strlen(inst->pArg1) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("stb", inst->pOpcode) == 0 || strcmp("stw", inst->pOpcode) == 0) { int opcode; if (strcmp("stb", inst->pOpcode) == 0) { opcode = 0x3; } /* stb */ else { opcode = 0x7; } /* stw */ res += opcode << 12; /* Check that dr and sr are both valid */ int sr, br, offset; /* Check if arg1 and arg2 are valid registers */ sr = getRegister(inst->pArg1); br = getRegister(inst->pArg2); if (sr == -1 || br == -1) { /* first 2 arguments MUST be registers */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Append dr and sr1 to res */ res += sr << 9; res += br << 6; /* Check that arg3 is a constant */ char key = inst->pArg3[0]; if (key == '#' || key == 'x') { /* is a constant */ offset = toNum(inst->pArg3); if (isConstant(offset, 6) == -1) { printf("ERROR: Invalid constant. Exiting with error code 3."); exit(3); } if (offset < 0) { /* convert negative to positive 2's complement */ offset = convertTwosComplement(offset, 6); } res += offset; } else { printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } /* Check that arg4 is empty */ if (strlen(inst->pArg4) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else if (strcmp("trap", inst->pOpcode) == 0) { int opcode = 0xF0; res += opcode << 8; /* Check that arg1 is a hex value */ char key = inst->pArg1[0]; int val = 0; if (key == '#' || key == 'x') { /* is an unsigned constant */ val = toNum(inst->pArg1); if (isConstantUnsigned(val, 8) == -1) { printf("ERROR: Invalid constant. Exiting with error code 3."); exit(3); } } else { /* not a valid trap code */ printf("ERROR: Invalid operand. Exiting with error code 4."); exit(4); } res += val; /* Check that arg2 is empty */ if (strlen(inst->pArg2) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } /* shouldn't need these condition checks else if (strcmp(".orig", inst->pOpcode) == 0) { } else if (strcmp(".end", inst->pOpcode) == 0) { } */ else if (strcmp(".fill", inst->pOpcode) == 0) { int num = toNum(inst->pArg1); if (num < 0) { /* check for signed overflow */ if (isConstant(num, 16) == -1) { printf("ERROR: Invalid constant. Exiting with error code 3."); exit(3); } num = convertTwosComplement(num, 16); } else { /* check for unsigned overflow */ if (isConstantUnsigned(num, 16) == -1) { printf("ERROR: Invalid constant. Exiting with error code 3."); exit(3); } } res = num; /* Check that arg2 is empty */ if (strlen(inst->pArg2) > 0) { /* extra operands */ printf("ERROR: Extra operands. Exiting with error code 4."); exit(4); } } else { /* not a valid opcode*/ printf("ERROR: Not a valid opcode. Exiting with error code 2."); exit(2); } return res; }
bool Quest::doCommand(int commandEip) { if (!owner) { app.logMessage(QObject::tr("Quest::doCommand called with no owner")); return false; } //app.logMessage("Executing command "+QString().setNum(eip)); QStringList command = (*commands)[commandEip]; if (command[0] == "label") return true; else if (command[0] == "goto") { if (command.size() != 2) { logError(QObject::tr("goto takes exactly one argument")); return false; } int newEip = findLabel(command[1]); if (newEip == -1) { logError(QObject::tr("label not found")); return false; } eip = newEip; } else if (command[0] == "end") { sendEndDialog(owner); return false; } else if (command[0] == "say") { QString msg, npcName; QList<QString> answers; quint16 iconId=0; bool hasIconId=false; if (command.size() >= 2) { msg = concatAfter(command, 1); npcName = npc->name; } else { logError(QObject::tr("say takes 2 arguments")); return false; } // Parse answers, icon, and name for (int i=commandEip+1; i<commands->size();i++) { if ((*commands)[i][0] == "answer") answers << concatAfter((*commands)[i], 2); else if ((*commands)[i][0] == "sayName") npcName = concatAfter((*commands)[i], 1); else if ((*commands)[i][0] == "sayIcon") { bool ok; int id = (*commands)[i][1].toInt(&ok); if (!ok || id < 0) { logError(QObject::tr("invalid icon id")); return false; } hasIconId = true; iconId = id; } else break; } // Replace special variables msg.replace("$PLAYERNAME", owner->pony.name); for (QString& s : answers) s.replace("$PLAYERNAME", owner->pony.name); // Send sendBeginDialog(owner); if (hasIconId) // Use the 2D sprites { sendDialogMessage(owner, msg, npcName, iconId); sendDialogMessage(owner, msg, npcName, iconId); } else // Use the 3D view { sendDialogMessage(owner, msg, npcName, npc->netviewId, iconId); sendDialogMessage(owner, msg, npcName, npc->netviewId, iconId); } sendDialogOptions(owner, answers); return false; // We stop the script until we get a reply } else if (command[0] == "answer") // can only be ran after a say, sayName, sayIcon, or another answer { logError(QObject::tr("trying to run answer command by itself")); return false; } else if (command[0] == "sayName") // can only be ran after a say, sayIcon, answer, or another sayName { logError(QObject::tr("trying to run sayName command by itself")); return false; } else if (command[0] == "sayIcon") // Answer can only be ran after a say, sayName, answer, or another sayIcon { logError(QObject::tr("trying to run sayIcon command by itself")); return false; } else if (command[0] == "give") { if (command.size() != 3) { logError(QObject::tr("give takes 2 arguments")); return false; } bool ok1,ok2; int itemId = command[1].toInt(&ok1); int qty = command[2].toInt(&ok2); if (!ok1 || !ok2 || itemId<0) { logError(QObject::tr("invalid arguments for command give")); return false; } if (qty > 0) owner->pony.addInventoryItem(itemId, qty); else owner->pony.removeInventoryItem(itemId, -qty); //sendInventoryRPC(owner, owner->pony.inv, owner->pony.worn, owner->pony.nBits); } else if (command[0] == "giveBits") { if (command.size() != 2) { logError(QObject::tr("giveBits takes 1 argument")); return false; } bool ok1; int qty = command[1].toInt(&ok1); if (!ok1) { logError(QObject::tr("invalid argument for command giveBits")); return false; } if (qty<0 && (quint32)-qty > owner->pony.nBits) owner->pony.nBits = 0; else owner->pony.nBits += qty; sendSetBitsRPC(owner); } else if (command[0] == "setQuestState") { if (command.size() == 2) { bool ok1; int newState = command[1].toInt(&ok1); if (!ok1 || newState<0) { logError(QObject::tr("invalid argument for command setQuestState")); return false; } this->state = newState; } else if (command.size() == 3) { bool ok1,ok2; int newState = command[1].toInt(&ok1); int id = command[2].toInt(&ok2); if (!ok1 || !ok2 || newState<0 || id<0) { logError(QObject::tr("invalid arguments for command setQuestState")); return false; } for (Quest& quest : owner->pony.quests) if (quest.id == id) quest.state = newState; } else { logError(QObject::tr("setQuestState takes 1 or 2 arguments")); return false; } } else if (command[0] == "hasItem") { int itemId, qty=1, yesEip, noEip; if (command.size() == 4) { bool ok1; itemId = command[1].toInt(&ok1); if (!ok1 || itemId<0) { logError(QObject::tr("invalid arguments for command hasItem")); return false; } yesEip = findLabel(command[2]); noEip = findLabel(command[3]); } else if (command.size() == 5) { bool ok1,ok2; itemId = command[1].toInt(&ok1); qty = command[2].toInt(&ok2); if (!ok1 || !ok2 || qty<=0 || itemId<0) { logError(QObject::tr("invalid arguments for command hasItem")); return false; } yesEip = findLabel(command[3]); noEip = findLabel(command[4]); } else { logError(QObject::tr("hasItem takes 3 or 4 arguments")); return false; } if (yesEip == -1) { logError(QObject::tr("label for a verified condition not found")); return false; } else if (noEip == -1) { logError(QObject::tr("label for an unverified condition not found")); return false; } if (owner->pony.hasInventoryItem(itemId, qty)) eip=yesEip; else eip=noEip; return true; } else if (command[0] == "hasBits") { if (command.size() != 4) { logError(QObject::tr("hasBits takes 3 arguments")); return false; } int qty, yesEip, noEip; bool ok1; qty = command[1].toInt(&ok1); if (!ok1 || qty<=0) { logError(QObject::tr("invalid arguments for command hasBits")); return false; } yesEip = findLabel(command[2]); noEip = findLabel(command[3]); if (yesEip == -1) { logError(QObject::tr("label for a verified condition not found")); return false; } else if (noEip == -1) { logError(QObject::tr("label for an unverified condition not found")); return false; } eip = owner->pony.nBits >= (quint32)qty ? yesEip : noEip; return true; } else if (command[0] == "gotoIfState") { if (command.size() == 3) { int uState, destEip; bool ok1; uState = command[1].toInt(&ok1); destEip = findLabel(command[2]); if (!ok1 || uState<0) { logError(QObject::tr("invalid arguments for command gotoIfState")); return false; } else if (destEip<0) { logError(QObject::tr("can't find dest label for command gotoIfState")); return false; } if (this->state == uState) eip = destEip; return true; } else if (command.size() == 4) { int uState, questId, destEip; bool ok1,ok2; uState = command[1].toInt(&ok1); questId = command[2].toInt(&ok2); destEip = findLabel(command[3]); if (!ok1 || !ok2 || questId<0 || uState<0) { logError(QObject::tr("invalid arguments for command gotoIfState")); return false; } else if (destEip<0) { logError(QObject::tr("can't find dest label for command gotoIfState")); return false; } for (const Quest& quest : owner->pony.quests) { if (quest.id == questId) { if (quest.state == uState) eip = destEip; return true; } } logError(QObject::tr("invalid quest id for command gotoIfState")); return false; } else { logError(QObject::tr("gotoIfState takes 2 or 3 arguments")); return false; } } else if (command[0] == "gotoAfterState") { if (command.size() == 3) { int uState, destEip; bool ok1; uState = command[1].toInt(&ok1); destEip = findLabel(command[2]); if (!ok1 || uState<0) { logError(QObject::tr("invalid arguments for command gotoAfterState")); return false; } else if (destEip<0) { logError(QObject::tr("can't find dest label for command gotoAfterState")); return false; } if (this->state >= uState) eip = destEip; return true; } else if (command.size() == 4) { int uState, questId, destEip; bool ok1,ok2; uState = command[1].toInt(&ok1); questId = command[2].toInt(&ok2); destEip = findLabel(command[3]); if (!ok1 || !ok2 || questId<0 || uState<0) { logError(QObject::tr("invalid arguments for command gotoAfterState")); return false; } else if (destEip<0) { logError(QObject::tr("can't find dest label for command gotoAfterState")); return false; } for (const Quest& quest : owner->pony.quests) { if (quest.id == questId) { if (quest.state >= uState) eip = destEip; return true; } } logError(QObject::tr("invalid quest id for command gotoAfterState")); return false; } else { logError(QObject::tr("gotoAfterState takes 2 or 3 arguments")); return false; } } else { logError(QObject::tr("unknown command : %1").arg(command[0])); return false; } return true; }