void Game::truncate(const Index& ix) { int at; History* vec = fetchRef(ix, &at); if(!vec) { kError() << "Truncating at an unexisting index"; return; } Entry *e = &(*vec)[at]; UndoTruncate undo(ix); for(int i=at+1; i<(int)vec->size();i++) undo.history.push_back((*vec)[i]); while((int)vec->size()>at+1) vec->pop_back(); undo.variations = e->variations; undo.vcomments = e->vcomments; saveUndo(undo); e->variations.clear(); e->vcomments.clear(); if(undo.history.size()) onRemoved(undo.index.next()); for(Variations::iterator it = undo.variations.begin(); it != undo.variations.end(); ++it) onRemoved(undo.index.next(it->first)); if(current > ix) { current = ix; onCurrentIndexChanged(); } }
void Ko::operator()(GameWrapper* gg) const{ LowLevelBoard* tmp_b = gg->board; Action* tmp_a = gg->action; History* hh = gg->history; if(hh->size() > 1){ Action mu = hh->getActions().at(hh->size()-2); if(mu == tmp_a){ throw KoException(); } } }
QString Game::variationPgn(const History& vec, const Entry& e, int start, const Index& _ix) const { Index ix = _ix; QString res; for (int i = start; i < static_cast<int>(vec.size()); i++) { const Entry& preve = (i > start) ? vec[i-1] : e; QString mv = (vec[i].move && preve.position) ? vec[i].move->toString("compact", preve.position ) : "???"; #if 0 if (ix == current) mv = "[[" + mv + "]]"; #endif int n = ix.totalNumMoves()+1; if(i==start || n%2==0) mv = QString::number(n/2)+(n%2==1 ? ". ... " : ". ") + mv; if (i > start) mv = " " + mv; res += mv; if(!vec[i].comment.isEmpty()) res += " {" + vec[i].comment + "}"; if(i > 0) { for(Variations::const_iterator it = vec[i-1].variations.begin(); it != vec[i-1].variations.end(); ++it) { res += " ("; if(vec[i-1].vcomments.count(it->first)) res += "{" + vec[i-1].vcomments.find(it->first)->second + "} "; res += variationPgn(it->second, vec[i - 1], 0, ix.prev().next(it->first)) + ")"; } } ix = ix.next(); } return res; }
void Game::promoteVariation(const Index& ix, int v) { int at; std::vector<Entry>* vec = fetchRef(ix, &at); Q_ASSERT(vec); Q_ASSERT((*vec)[at].variations.count(v)==1); History vold = (*vec)[at].variations[v]; History vnew; for(int i=at+1; i<(int)vec->size(); i++) vnew.push_back((*vec)[i]); while((int)vec->size()>at+1) vec->pop_back(); for(int i=0; i<(int)vold.size(); i++) vec->push_back(vold[i]); (*vec)[at].variations[v] = vnew; saveUndo(UndoPromote(ix, v)); current = current.flipVariation(ix, v); onPromoteVariation(ix, v); //don't call onCurrentIndexChanged(), as the position did not change actually }
int TraceProcessorX86InterruptLinux::processInstruction(History<TRInstructionX86>& insns) { if (insns.size() < 2) { return (-1); } if (!isInterested(insns.at(0))) { return (-1); } const TRInstructionX86& ins = insns.at(1); if (ins.insn.type != INSTRUCTION_TYPE_MOV) { return (-1); } //the instruction should be something like mov XXX, %eax (in ATT FORMAT) // where %eax is the first operand (in INTEL FORMAT) and XXX is the syscall number // if ( (ins.insn.op1.type != OPERAND_TYPE_REGISTER) || (ins.insn.op1.reg != REG_EAX) ) { return (-1); } if ( (ins.insn.op2.type == OPERAND_TYPE_IMMEDIATE) ) { size_t syscallNum = ins.insn.op2.immediate; if (syscallNum >= SYSCALLTABLE_LINUX_2_6_LEN) { return (-1); } curSyscallName = sysCallTable[syscallNum]; return (0); } return (-1); }
void Game::redo() { if(undo_pos >= (int)undo_history.size()) { kError() << "Nothing to redo"; return; } bool now_undo = undo_pos == 0; bool last_redo = undo_pos == (int)undo_history.size()-1; UndoOp* op = &(undo_history[undo_pos]); undo_pos++; if(boost::get<UndoAdd>(op)) { UndoAdd *a = boost::get<UndoAdd>(op); if(a->index.atVariationStart() ) { Entry* e = fetch(a->index.prev()); Q_ASSERT(e); int v = a->index.nested.back().variation; Q_ASSERT(e->variations.count(v) == 0); History h; h.push_back(a->entry); e->variations[v] = h; } else { int at; std::vector<Entry>* vec = fetchRef(a->index.prev(), &at); Q_ASSERT(vec); Q_ASSERT((int)vec->size() == at+1); vec->push_back(a->entry); } onAdded(a->index); current = a->index; onCurrentIndexChanged(); } else if(boost::get<UndoPromote>(op)) { UndoPromote *p = boost::get<UndoPromote>(op); int at; std::vector<Entry>* vec = fetchRef(p->index, &at); Q_ASSERT(vec); Q_ASSERT((*vec)[at].variations.count(p->variation)==1); History vold = (*vec)[at].variations[p->variation]; History vnew; for(int i=at+1; i<(int)vec->size(); i++) vnew.push_back((*vec)[i]); while((int)vec->size()>at+1) vec->pop_back(); for(int i=0; i<(int)vold.size(); i++) vec->push_back(vold[i]); (*vec)[at].variations[p->variation] = vnew; current = current.flipVariation(p->index, p->variation); onPromoteVariation(p->index, p->variation); //onCurrentIndexChanged(); } else if(boost::get<UndoTruncate>(op)) { UndoTruncate *t = boost::get<UndoTruncate>(op); int at; std::vector<Entry>* vec = fetchRef(t->index, &at); Q_ASSERT(vec); Q_ASSERT((int)vec->size() == at+1+(int)t->history.size()); while((int)vec->size() > at+1) vec->pop_back(); (*vec)[at].variations.clear(); (*vec)[at].vcomments.clear(); if(current > t->index) { current = t->index; onCurrentIndexChanged(); } if(t->history.size()) onRemoved(t->index.next()); for(Variations::iterator it = t->variations.begin(); it != t->variations.end(); ++it) onRemoved(t->index.next(it->first)); } else if(boost::get<UndoRemove>(op)) { UndoRemove *r = boost::get<UndoRemove>(op); Entry *e = fetch(r->index); e->variations.erase(r->variation); e->vcomments.erase(r->variation); onRemoved(r->index.next(r->variation)); } else if(boost::get<UndoClear>(op)) { UndoClear *c = boost::get<UndoClear>(op); Entry *e = fetch(c->index); e->variations.clear(); e->vcomments.clear(); for(Variations::iterator it = c->variations.begin(); it != c->variations.end(); ++it) onRemoved(c->index.next(it->first)); } else if(boost::get<UndoSetComment>(op)) { UndoSetComment *sc = boost::get<UndoSetComment>(op); Entry *e = fetch(sc->index); Q_ASSERT(e); if(sc->variation == -1) { e->comment = sc->new_comment; onSetComment(sc->index, sc->new_comment); } else { if(sc->new_comment.isEmpty()) e->vcomments.erase(sc->variation); else e->vcomments[sc->variation] = sc->new_comment; onSetVComment(sc->index, sc->variation, sc->new_comment); } } else kError() << "Unexpected type in boost::variant"; if(now_undo) onAvailableUndo(true); if(last_redo) onAvailableRedo(false); }
int TraceProcessorX86InterruptLinux::processInstruction(History<string>& strs) { if (strs.size() < 2) { return (-1); } if (!isInterested(strs.at(0))) { return (-1); } const string& prevS = strs.at(1); size_t t = prevS.find("mov"); if (t == string::npos) { return(-1); } //now that we found mov, lets find the $ size_t t2 = prevS.find('$', t); //now that we found the $, we need to find the comma size_t t3 = prevS.find(',',t2); //now we should just make sure that the next thing is eax size_t t4 = prevS.find("%eax", t3); //make sure all characters from t3 to t4 are whitespaces for (size_t i = t3+1; i < t4; i++) { if (!isspace(prevS[i])) { return (-1); } } //if we are here that means everything checked out so lets get // the syscall number uint32_t syscallNum = 0; if(myHexStrToul(syscallNum, prevS.substr(t2+1,t3-t2-1)) != 0) { return (-1); } /* t4 = str.find("$0x80"); outs = str.substr(0, t4); outs += "SYSCALL:"; outs += sysCallTable[syscallNum]; outs += "{"; outs += str.substr(t4, 5); outs += "}"; outs += str.substr(t4+5); */ if (syscallNum >= SYSCALLTABLE_LINUX_2_6_LEN) { return (-1); } curSyscallName = sysCallTable[syscallNum]; return (0); }