void dspIndentedBOM::sFillList() { _bomitem->clear(); if (_item->isValid()) { q.prepare("SELECT * FROM indentedBOM(:item_id, :revision_id, :expired, :effective) " "WHERE (bomdata_item_id > 0);"); q.bindValue(":item_id", _item->id()); q.bindValue(":revision_id", _revision->id()); if (!_showExpired->isChecked()) q.bindValue(":expired", 0); else q.bindValue(":expired", _expiredDays->value()); if (!_showFuture->isChecked()) q.bindValue(":effective", 0); else q.bindValue(":effective", _effectiveDays->value()); q.exec(); QStack<XTreeWidgetItem*> parent; XTreeWidgetItem *last = 0; int level = 1; while(q.next()) { // If the level this item is on is lower than the last level we just did then we need // to pop the stack a number of times till we are equal. while(q.value("bomdata_bomwork_level").toInt() < level) { level--; last = parent.pop(); } // If the level this item is on is higher than the last level we need to push the last // item onto the stack a number of times till we are equal. (Should only ever be 1.) while(q.value("bomdata_bomwork_level").toInt() > level) { level++; parent.push(last); last = 0; } // If there is an item in the stack use that as the parameter to the new xlistviewitem // otherwise we'll just use the xlistview _layout if(!parent.isEmpty() && parent.top()) last = new XTreeWidgetItem(parent.top(), last, q.value("bomdata_bomwork_id").toInt(), q.value("bomdata_bomwork_seqnumber"), q.value("bomdata_item_number"), q.value("bomdata_itemdescription"), q.value("bomdata_uom_name"), q.value("bomdata_qtyper"), q.value("bomdata_scrap"), q.value("bomdata_effective"), q.value("bomdata_expires") ); else last = new XTreeWidgetItem(_bomitem, last, q.value("bomdata_bomwork_id").toInt(), q.value("bomdata_bomwork_seqnumber"), q.value("bomdata_item_number"), q.value("bomdata_itemdescription"), q.value("bomdata_uom_name"), q.value("bomdata_qtyper"), q.value("bomdata_scrap"), q.value("bomdata_effective"), q.value("bomdata_expires") ); if (q.value("bomdata_expired").toBool()) last->setTextColor("red"); else if (q.value("bomdata_future").toBool()) last->setTextColor("blue"); } _bomitem->expandAll(); } }
bool SGFParser::doParse(const QString &toParseStr) { if (toParseStr.isNull() || toParseStr.isEmpty()) { qWarning("Failed loading from file. Is it empty?"); return false; } QString tmp; if(!loadedfromfile) { /* This bit of ugliness is because sgfs are used to duplicate boards as well * as load from file FIXME */ parseProperty(toParseStr, "CA", tmp); //codec if (!tmp.isEmpty()) readCodec = QTextCodec::codecForName(tmp.toLatin1().constData()); } const MyString *toParse = NULL; //////TODO if (static_cast<Codec>(setting->readIntEntry("CODEC")) == codecNone) ///////// toParse = new MySimpleString(toParseStr); /////// else toParse = new MyString(toParseStr); Q_CHECK_PTR(toParse); int pos = 0, posVarBegin = 0, posVarEnd = 0, posNode = 0, moves = 0, i, x=-1, y=-1; int a_offset = QChar::fromLatin1('a').unicode() - 1 ; unsigned int pointer = 0, strLength = toParse->length(); bool black = true, setup = false, old_label = false; isRoot = true; bool remember_root; QString unknownProperty; State state; MarkType markType; QString moveStr, commentStr; Position *position; MoveNum *moveNum; QStack<Move*> stack; QStack<MoveNum*> movesStack; /* FIXME toRemove, et., al., appears unused Remove it */ QStack<Position*> toRemove; /* ////TODO stack.setAutoDelete(false); movesStack.setAutoDelete(true); toRemove.setAutoDelete(true); */ // Initialises the tree with board size parseProperty(toParseStr, "SZ", tmp); // Tree *tree = new Tree(tmp.isEmpty() ? 19 : tmp.toInt()) ;// boardHandler->getTree(); state = stateVarBegin; bool cancel = false; //FIXME abort does nothing!! // qDebug("File length = %d", strLength); tree->setLoadingSGF(true); QString sss=""; do { posVarBegin = toParse->find('(', pointer); posVarEnd = toParse->find(')', pointer); posNode = toParse->find(';', pointer); pos = minPos(posVarBegin, posVarEnd, posNode); // Switch states // Node -> VarEnd if (state == stateNode && pos == posVarEnd) state = stateVarEnd; // Node -> VarBegin if (state == stateNode && pos == posVarBegin) state = stateVarBegin; // VarBegin -> Node else if (state == stateVarBegin && pos == posNode) state = stateNode; // VarEnd -> VarBegin else if (state == stateVarEnd && pos == posVarBegin) state = stateVarBegin; // qDebug("State after switch = %d", state); // Do the work switch (state) { case stateVarBegin: if (pos != posVarBegin) { delete toParse; return corruptSgf(pos); } // qDebug("Var BEGIN at %d, moves = %d", pos, moves); stack.push(tree->getCurrent()); moveNum = new MoveNum; moveNum->n = moves; movesStack.push(moveNum); pointer = pos + 1; break; case stateVarEnd: if (pos != posVarEnd) { delete toParse; return corruptSgf(pos); } // qDebug("VAR END"); if (!movesStack.isEmpty() && !stack.isEmpty()) { Move *m = stack.pop(); Q_CHECK_PTR(m); x = movesStack.pop()->n; // qDebug("Var END at %d, moves = %d, moves from stack = %d", pos, moves, x); for (i=moves; i > x; i--) { position = toRemove.pop(); if (position == NULL) continue; /////////////////// boardHandler->getStoneHandler()->removeStone(position->x, position->y); // tree->removeStone(position->x, position->y); // qDebug("Removing %d %d from stoneHandler.", position->x, position->y); } moves = x; tree->setCurrent(m); } pointer = pos + 1; break; case stateNode: if (pos != posNode) { delete toParse; return corruptSgf(pos); } // qDebug("Node at %d", pos); commentStr = QString(); setup = false; markType = markNone; // Create empty node remember_root = isRoot; if (!isRoot) { ///////////////////// boardHandler->createMoveSGF(); // qDebug("############### Before creating move ####################"); // qDebug(toParse->Str.toLatin1().constData()); //tree->createMoveSGF(); /* This does happen, why??? FIXME */ // qDebug("############### ####################"); // qDebug(toParse->Str.toLatin1().constData()); // qDebug("############### After creating move ####################"); unknownProperty = QString(); #ifdef FIXME //why is this a warning? this happens on loading a file with time info if (tree->getCurrent()->getTimeinfo()) qWarning("*** Timeinfo set !!!!"); #endif //FIXME //tree->getCurrent()->setTimeinfo(false); } else isRoot = false; Property prop; pos ++; do { uint tmppos=0; pos = toParse->next_nonspace (pos); if ((tmppos = toParse->isProperty("B",pos))) { prop = moveBlack; pos = tmppos; black = true; } else if ((tmppos = toParse->isProperty("W",pos))) { prop = moveWhite; pos = tmppos; black = false; } else if ((tmppos = toParse->isProperty("N",pos))) { prop = nodeName; pos = tmppos; } else if ((tmppos = toParse->isProperty("AB",pos))) { prop = editBlack; pos = tmppos; setup = true; black = true; } else if ((tmppos = toParse->isProperty("AW",pos))) { prop = editWhite; pos = tmppos; setup = true; black = false; } else if ((tmppos = toParse->isProperty("AE",pos))) { prop = editErase; pos = tmppos; setup = true; } else if ((tmppos = toParse->isProperty("TR",pos))) { prop = editMark; markType = markTriangle; pos = tmppos; } else if ((tmppos = toParse->isProperty("CR",pos))) { prop = editMark; markType = markCircle; pos = tmppos; } else if ((tmppos = toParse->isProperty("SQ",pos))) { prop = editMark; markType = markSquare; pos = tmppos; } else if ((tmppos = toParse->isProperty("MA",pos))) { prop = editMark; markType = markCross; pos = tmppos; } // old definition else if ((tmppos = toParse->isProperty("M",pos))) { prop = editMark; markType = markCross; pos = tmppos; } else if ((tmppos = toParse->isProperty("LB",pos))) { prop = editMark; markType = markText; pos = tmppos; old_label = false; } // Added old L property. This is not SGF4, but many files contain this tag. else if ((tmppos = toParse->isProperty("L",pos))) { prop = editMark; markType = markText; pos = tmppos; old_label = true; } else if ((tmppos = toParse->isProperty("C",pos))) { prop = comment; pos = tmppos; } else if ((tmppos = toParse->isProperty("TB",pos))) { prop = editMark; markType = markTerrBlack; pos = tmppos; black = true; } else if ((tmppos = toParse->isProperty("TW",pos))) { prop = editMark; markType = markTerrWhite; pos = tmppos; black = false; } else if ((tmppos = toParse->isProperty("BL",pos))) { prop = timeLeft; pos = tmppos; black = true; } else if ((tmppos = toParse->isProperty("WL",pos))) { prop = timeLeft; pos = tmppos; black = false; } else if ((tmppos = toParse->isProperty("OB",pos))) { prop = openMoves; pos = tmppos; black = true; } else if ((tmppos = toParse->isProperty("OW",pos))) { prop = openMoves; pos = tmppos; black = false; } else if ((tmppos = toParse->isProperty("PL",pos))) { prop = nextMove; pos = tmppos; } else if ((tmppos = toParse->isProperty("RG",pos))) { prop = unknownProp; pos = tmppos; setup = true; } // Empty node else if (toParse->at(pos) == ';' || toParse->at(pos) == '(' || toParse->at(pos) == ')') { qDebug("Found empty node at %d", pos); while (toParse->at(pos).isSpace()) pos++; continue; } else { // handle like comment prop = unknownProp; pos = toParse->next_nonspace (pos); //qDebug("SGF: next nonspace (1st):" + QString(toParse->at(pos)) + QString(toParse->at(pos+1)) + QString(toParse->at(pos+2))); } //qDebug("Start do loop : FOUND PROP %d, pos at %d now", prop, pos); //qDebug(toParse->getStr()); //causes crash // Next is one or more '[xx]'. // Only one in a move property, several in a setup propery do { if (toParse->at(pos) != '[' && prop != unknownProp) { delete toParse; return corruptSgf(pos); } // Empty type if (toParse->at(pos+1) == ']') { // CGoban stores pass as 'B[]' or 'W[]' if (prop == moveBlack || prop == moveWhite) { tree->doPass(true); // Remember this move for later, to remove from the matrix. position = new Position; position->x = x; position->y = y; toRemove.push(position); moves ++; } pos += 2; continue; } switch (prop) { case moveBlack: case moveWhite: // rare case: root contains move or placed stone: if (remember_root) { qDebug("root contains stone -> node created"); /* Something is screwy here, inconsistencies * in the way SGF's are treated. Like the below: * the whole point of "remember_root", FIXME*/ tree->addEmptyMove(); isRoot = false; unknownProperty = QString(); #ifdef FIXME //why is this a warning? if (tree->getCurrent()->getTimeinfo()) qWarning("*** Timeinfo set (2)!!!!"); #endif //FIXME //tree->getCurrent()->setTimeinfo(false); } case editBlack: case editWhite: case editErase: { x = toParse->at(pos+1).unicode() - a_offset ;// - 'a';// + 1; y = toParse->at(pos+2).unicode() - a_offset ; //- 'a' + 1; int x1, y1; bool compressed_list; // check for compressed lists if (toParse->at(pos+3) == ':') { x1 = toParse->at(pos+4).unicode() -a_offset;// - 'a' + 1; y1 = toParse->at(pos+5).unicode() -a_offset;// - 'a' + 1; compressed_list = true; } else { x1 = x; y1 = y; compressed_list = false; } /* * TODO Do we nned this when the tree is created from file ? * boardHandler->setModeSGF(setup || compressed_list ? modeEdit : modeNormal); */ int i, j; for (i = x; i <= x1; i++) for (j = y; j <= y1; j++) { if (prop == editErase) { tree->addStoneToCurrentMove(stoneErase, i, j); } else { if(setup) { if ((!remember_root) && (stack.top() == tree->getCurrent())) tree->addEmptyMove(); //if this is first in branch we need to add an empty move tree->addStoneToCurrentMove(black ? stoneBlack : stoneWhite, i, j); } else { Move *result = tree->getCurrent()->makeMove(black ? stoneBlack : stoneWhite, i, j); if (result) tree->setCurrent(result); } } // tree->getCurrent()->getMatrix()->debug(); //qDebug("ADDING MOVE %s %d/%d", black?"B":"W", x, y); // Remember this move for later, to remove from the matrix. position = new Position; position->x = i; position->y = j; toRemove.push(position); moves ++; } if (compressed_list) // Advance pos by 7 pos += 7; else // Advance pos by 4 pos += 4; break; } case nodeName: { commentStr = QString(); bool skip = false; while (toParse->at(++pos) != ']') { if (static_cast<unsigned int>(pos) > strLength-1) { qDebug("SGF: Nodename string ended immediately"); delete toParse; return corruptSgf(pos, "SGF: Nodename string ended immediately"); } // white spaces if (toParse->at(pos) == '\\') { while (toParse->at(pos+1).isSpace() && static_cast<unsigned int>(pos) < strLength-2) pos++; if (toParse->at(pos).isSpace()) pos++; // case: "../<cr><lf>]" if (toParse->at(pos) == ']') { pos--; skip = true; } } // escaped chars: '\', ']', ':' if (!(toParse->at(pos) == '\\' && (toParse->at(pos+1) == ']' || toParse->at(pos+1) == '\\' || toParse->at(pos+1) == ':')) && !skip && // no formatting !(toParse->at(pos) == '\n') && !(toParse->at(pos) == '\r')) commentStr.append(toParse->at(pos)); } //qDebug("Node name read: %s", commentStr.toLatin1().constData()); if (!commentStr.isEmpty()) // add comment; skip 'C[]' tree->getCurrent()->setNodeName(commentStr); pos++; break; } case comment: { commentStr = QString(); bool skip = false; while (toParse->at(++pos) != ']' || (toParse->at(pos-1) == '\\' && toParse->at(pos) == ']')) { if (static_cast<unsigned int>(pos) > strLength-1) { qDebug("SGF: Comment string ended immediately"); delete toParse; return corruptSgf(pos, "SGF: Comment string ended immediately"); } // white spaces if (toParse->at(pos) == '\\') { while (toParse->at(pos+1).isSpace() && static_cast<unsigned int>(pos) < strLength-2) pos++; if (toParse->at(pos).isSpace()) pos++; // case: "../<cr><lf>]" if (toParse->at(pos) == ']') { pos--; skip = true; } } // escaped chars: '\', ']', ':' if (!(toParse->at(pos) == '\\' && (toParse->at(pos+1) == ']' || toParse->at(pos+1) == '\\' || toParse->at(pos+1) == ':')) && !skip) commentStr.append(toParse->at(pos)); } //qDebug("Comment read: %s", commentStr.toLatin1().constData()); if (!commentStr.isEmpty()) { // add comment; skip 'C[]' if(readCodec) tree->getCurrent()->setComment(readCodec->toUnicode(commentStr.toLatin1().constData())); else tree->getCurrent()->setComment(commentStr.toLatin1().constData()); } pos ++; break; } case unknownProp: { // skip if property is known anyway bool skip = false; // save correct property name (or p.n. + '[') commentStr = QString(toParse->at(pos)); commentStr += toParse->at(tmppos = toParse->next_nonspace (pos + 1)); pos = tmppos; // check if it's really necessary to hold properties // maybe they are handled at another position if (commentStr == "WR" || commentStr == "BR" || commentStr == "PW" || commentStr == "PB" || commentStr == "SZ" || commentStr == "KM" || commentStr == "HA" || commentStr == "RE" || commentStr == "DT" || commentStr == "PC" || commentStr == "CP" || commentStr == "GN" || commentStr == "OT" || commentStr == "TM" || // now: general options commentStr == "GM" || commentStr == "ST" || commentStr == "AP" || commentStr == "FF") { skip = true; } sss= toParse->at(pos); while (toParse->at(++pos) != ']' || (toParse->at(pos-1) == '\\' && toParse->at(pos) == ']')) { if (static_cast<unsigned int>(pos) > strLength-1) { qDebug("SGF: Unknown property ended immediately"); delete toParse; return corruptSgf(pos, "SGF: Unknown property ended immediately"); } sss= toParse->at(pos); if (!skip) commentStr.append(toParse->at(pos)); } if (!skip) commentStr.append("]"); // qDebug("Comment read: %s", commentStr.latin1()); if ((!commentStr.isEmpty()) && (!skip)) { // cumulate unknown properties; skip empty property 'XZ[]' unknownProperty += commentStr; tree->getCurrent()->setUnknownProperty(unknownProperty); } pos ++; sss= toParse->at(pos); break; } case editMark: // set moveStr for increment labels of old 'L[]' property moveStr = "A"; while (toParse->at(pos) == '[' && static_cast<unsigned int>(pos) < strLength) { x = toParse->at(pos+1).unicode() -a_offset;// - 'a' + 1; y = toParse->at(pos+2).unicode() -a_offset;// - 'a' + 1; // qDebug("MARK: %d at %d/%d", markType, x, y); pos += 3; // 'LB' property? Then we need to get the text if (markType == markText && !old_label) { if (toParse->at(pos) != ':') { delete toParse; return corruptSgf(pos); } moveStr = ""; while (toParse->at(++pos) != ']' && static_cast<unsigned int>(pos) < strLength) moveStr.append(toParse->at(pos)); // qDebug("LB TEXT = %s", moveStr.latin1()); // It might me a number mark? bool check = false; moveStr.toInt(&check); // Try to convert to Integer // treat integers as characters... check = false; if (check) tree->getCurrent()->getMatrix()-> insertMark(x, y, markNumber); // Worked, its a number else tree->getCurrent()->getMatrix()-> insertMark(x, y, markType); // Nope, its a letter tree->getCurrent()->getMatrix()-> setMarkText(x, y, moveStr); /*else //fastload { if (check) // Number tree->getCurrent()->insertFastLoadMark(x, y, markNumber); else // Text tree->getCurrent()->insertFastLoadMark(x, y, markType, moveStr); }*/ } else { int x1, y1; bool compressed_list; // check for compressed lists if (toParse->at(pos) == ':') { x1 = toParse->at(pos+1).unicode() -a_offset;// - 'a' + 1; y1 = toParse->at(pos+2).unicode() -a_offset;// - 'a' + 1; compressed_list = true; } else { x1 = x; y1 = y; compressed_list = false; } int i, j; for (i = x; i <= x1; i++) for (j = y; j <= y1; j++) { tree->getCurrent()->getMatrix()->insertMark(i, j, markType); //else //fastload // tree->getCurrent()->insertFastLoadMark(i, j, markType); // auto increment for old property 'L' if (old_label) { tree->getCurrent()->getMatrix()-> setMarkText(x, y, moveStr); QChar c1 = moveStr[0]; if (c1 == 'Z') moveStr = QString("a"); else moveStr = c1.unicode() + 1; } } // new_node = false; if (compressed_list) // Advance pos by 3 pos += 3; if((markType == markTerrWhite || markType == markTerrBlack) && !tree->getCurrent()->isTerritoryMarked()) tree->getCurrent()->setTerritoryMarked(); } //old_label = false; pos ++; while (toParse->at(pos).isSpace()) pos++; } break; case openMoves: { QString tmp_mv; while (toParse->at(++pos) != ']') tmp_mv += toParse->at(pos); tree->getCurrent()->setOpenMoves(tmp_mv.toInt()); pos++; if (!tree->getCurrent()->getTimeinfo()) { tree->getCurrent()->setTimeinfo(true); tree->getCurrent()->setTimeLeft(0); } break; } case timeLeft: { QString tmp_mv; while (toParse->at(++pos) != ']') tmp_mv += toParse->at(pos); tree->getCurrent()->setTimeLeft(tmp_mv.toFloat()); pos++; if (!tree->getCurrent()->getTimeinfo()) { tree->getCurrent()->setTimeinfo(true); tree->getCurrent()->setOpenMoves(0); } break; } case nextMove: if (toParse->at(++pos) == 'W') tree->getCurrent()->setPLinfo(stoneWhite); else if (toParse->at(pos) == 'B') tree->getCurrent()->setPLinfo(stoneBlack); pos += 2; break; default: break; } while (toParse->at(pos).isSpace()) pos++; sss= toParse->at(pos); } while (setup && toParse->at(pos) == '['); // tree->getCurrent()->getMatrix()->debug(); // qDebug("end do loop"); // qDebug(toParse->getStr()); while (toParse->at(pos).isSpace()) pos++; } while (toParse->at(pos) != ';' && toParse->at(pos) != '(' && toParse->at(pos) != ')' && static_cast<unsigned int>(pos) < strLength); // Advance pointer pointer = pos; break; default: delete toParse; return corruptSgf(pointer); } } while (pointer < strLength && pos >= 0); tree->setLoadingSGF(false); delete toParse; return !cancel; }
QString MessageValidator::validateMessage(QString message, bool* illformed, HTMLTextFormatter* formatter) { // qDebug() << "IMG val0" << message; QDomDocument doc("document"); *illformed = false; QString errorMessage; int line, column; QDomDocument tmpDoc; //used by textformatter xmlSource.setData(message); if (!doc.setContent(&xmlSource, &xmlReader, &errorMessage, &line, &column)) { qDebug() << errorMessage << " " << line << " " << column << message; *illformed = true; qDebug() << "WARNING: MessageValidator::validateMessage() - illformed message"; return "illformed message!!!"; } //now DOM tree will be traversed in preorder. QStack<QDomElement> stack; //current element, QStack is used to avoid possible stack overflow in ordinary recursion stack.push(doc.documentElement()); while (!stack.empty()) { QDomElement cur = stack.top(); stack.pop(); // Traverse through DOM Tree(cur), cut off bad elements/attributes // and format text nodes using textFormatter // qDebug() << QString(4, ' ') << cur.tagName(); QString parentName = cur.tagName(); NodeInfo curNI = allowed[parentName]; //delete disallowed attributes for (int i = 0; i < cur.attributes().count(); i++) { QString attrName = cur.attributes().item(i).toAttr().name(); if (!curNI.allowedAttributes.contains(attrName)) { // qDebug() << "VALIDATIN ERR" << "TA" << attrName << " in " << parentName; // qDebug() << "note allowed attributes are:" << curNI.allowedAttributes; cur.attributes().removeNamedItem(attrName); i--; } } QDomNodeList children = cur.childNodes(); for (int i = children.size() - 1; i >= 0; i--) { QDomNode node = children.at(i); if (node.isElement()) { QString childName = node.toElement().tagName(); if (childName == "a") { // always show hyperlink destination QString href = node.toElement().attribute("href"); node.appendChild(doc.createTextNode(" [ " + href + " ]")); } if (childName == "style") { //NOTE: this action is not XHTML-IM compliant! (css rules should be displayed, but it's stupid) cur.removeChild(node); } else if (childName == "img") { //disabling images until they are whitelisted QString href = node.toElement().attribute("src"); QDomElement newElement = doc.createElement("a"); newElement.setAttribute("class", "psi_disabled_image"); newElement.setAttribute("href", "javascript:psi_addToWhiteList('" + href + "')"); newElement.appendChild(doc.createTextNode("[ click here to display: " + href + " ]")); cur.replaceChild(newElement, node); } else if (!curNI.allowedTags.contains(childName)) {//is subElement valid here? qDebug() << "VALIDATIN ERR" << "TS" << childName << " in " << parentName; qDebug() << "note allowed subElements are:" << curNI.allowedTags; //append bad node's children (they will be validated in next loop iteration) int j = 0; while (node.hasChildNodes()) { cur.insertBefore(node.firstChild(), node); j++; } i = i + j; //j nodes were inserted //delete bad node cur.removeChild(node); } else { stack.push(node.toElement()); } } else if (node.isText() && !node.isCDATASection()) { if (!curNI.canHaveText) { cur.removeChild(node); } else { //format text QString formattedText = "<tmp>" + formatter->format(Qt::escape(node.toText().data()), cur) + "</tmp>"; //NOTE: we don't need to escape quotes, and we want this code be more reusable/decoupled, //NOTE: so we use Qt::escape() instead of TextUtil::escape() xmlSource.setData(formattedText); tmpDoc.setContent(&xmlSource, &xmlReader); QDomNode tmpElement = tmpDoc.firstChild(); while (tmpElement.hasChildNodes()) { //append <tmp>'s children. They won't be validated cur.insertBefore(tmpElement.firstChild(), node); } cur.removeChild(node); } } }//foreach child } //stack/dfs // qDebug() << "IMG MV:" << doc.toString(0); return doc.toString(0); }
static void parse( Translator *tor ) { QString text; QString com; QString extracomment; yyCh = getChar(); yyTok = getToken(); while ( yyTok != Tok_Eof ) { switch ( yyTok ) { case Tok_class: yyTok = getToken(); if(yyTok == Tok_Ident) { yyScope.push(new Scope(yyIdent, Scope::Clazz, yyLineNo)); } else { yyMsg() << qPrintable(LU::tr("'class' must be followed by a class name.\n")); break; } while (!match(Tok_LeftBrace)) { yyTok = getToken(); } break; case Tok_tr: yyTok = getToken(); if ( match(Tok_LeftParen) && matchString(text) ) { com.clear(); bool plural = false; if ( match(Tok_RightParen) ) { // no comment } else if (match(Tok_Comma) && matchStringOrNull(com)) { //comment if ( match(Tok_RightParen)) { // ok, } else if (match(Tok_Comma)) { plural = true; } } if (!text.isEmpty()) recordMessage(tor, context(), text, com, extracomment, plural); } break; case Tok_translate: { QString contextOverride; yyTok = getToken(); if ( match(Tok_LeftParen) && matchString(contextOverride) && match(Tok_Comma) && matchString(text) ) { com.clear(); bool plural = false; if (!match(Tok_RightParen)) { // look for comment if ( match(Tok_Comma) && matchStringOrNull(com)) { if (!match(Tok_RightParen)) { if (match(Tok_Comma) && matchExpression() && match(Tok_RightParen)) { plural = true; } else { break; } } } else { break; } } if (!text.isEmpty()) recordMessage(tor, contextOverride, text, com, extracomment, plural); } } break; case Tok_Ident: yyTok = getToken(); break; case Tok_Comment: if (yyComment.startsWith(QLatin1Char(':'))) { yyComment.remove(0, 1); extracomment.append(yyComment); } yyTok = getToken(); break; case Tok_RightBrace: if ( yyScope.isEmpty() ) { yyMsg() << qPrintable(LU::tr("Excess closing brace.\n")); } else delete (yyScope.pop()); extracomment.clear(); yyTok = getToken(); break; case Tok_LeftBrace: yyScope.push(new Scope(QString(), Scope::Other, yyLineNo)); yyTok = getToken(); break; case Tok_Semicolon: extracomment.clear(); yyTok = getToken(); break; case Tok_Package: yyTok = getToken(); while(!match(Tok_Semicolon)) { switch(yyTok) { case Tok_Ident: yyPackage.append(yyIdent); break; case Tok_Dot: yyPackage.append(QLatin1String(".")); break; default: yyMsg() << qPrintable(LU::tr("'package' must be followed by package name.\n")); break; } yyTok = getToken(); } break; default: yyTok = getToken(); } } if ( !yyScope.isEmpty() ) yyMsg(yyScope.top()->line) << qPrintable(LU::tr("Unbalanced opening brace.\n")); else if ( yyParenDepth != 0 ) yyMsg(yyParenLineNo) << qPrintable(LU::tr("Unbalanced opening parenthesis.\n")); }
void Loader::load() { QFile in(QLatin1String("tree.xml")); /* LoadingModel::m_result will be null, signalling failure. */ if(!in.open(QIODevice::ReadOnly)) return; QXmlStreamReader reader(&in); while(!reader.atEnd()) { reader.readNext(); switch(reader.tokenType()) { case QXmlStreamReader::StartDocument: /* Fallthrough. */ case QXmlStreamReader::StartElement: { QXmlName name; if(reader.tokenType() == QXmlStreamReader::StartElement) { name = QXmlName(m_namePool, reader.name().toString(), reader.namespaceUri().toString(), reader.prefix().toString()); } /* Else, the name is null. */ LoadingModel::Node *const tmp = new LoadingModel::Node(reader.tokenType() == QXmlStreamReader::StartElement ? QXmlNodeModelIndex::Element : QXmlNodeModelIndex::Document, m_parentStack.top(), QString(), name); m_result.append(tmp); if(m_currentNode) { if(m_currentNode->parent == m_parentStack.top()) m_currentNode->followingSibling = tmp; } const QXmlStreamAttributes attributes(reader.attributes()); const int len = attributes.count(); for(int i = 0; i < len; ++i) { const QXmlStreamAttribute &attr = attributes.at(i); const LoadingModel::Node *const a = new LoadingModel::Node(QXmlNodeModelIndex::Attribute, m_parentStack.top(), attr.value().toString(), QXmlName(m_namePool, attr.name().toString(), attr.namespaceUri().toString(), attr.prefix().toString())); /* We add it also to m_result such that compareOrder() is correct * for attributes. m_result owns a. */ tmp->attributes.append(a); m_result.append(a); } adjustSiblings(tmp); m_parentStack.push(m_currentNode); break; } case QXmlStreamReader::EndDocument: /* Fallthrough. */ case QXmlStreamReader::EndElement: { m_currentNode->followingSibling = 0; m_currentNode = m_parentStack.pop(); if(reader.tokenType() == QXmlStreamReader::EndDocument) const_cast<LoadingModel::Node *>(m_result.first())->followingSibling = 0; break; } case QXmlStreamReader::Characters: { LoadingModel::Node *const tmp = new LoadingModel::Node(QXmlNodeModelIndex::Text, m_parentStack.top(), reader.text().toString()); m_result.append(tmp); adjustSiblings(tmp); break; } case QXmlStreamReader::ProcessingInstruction: { LoadingModel::Node *const tmp = new LoadingModel::Node(QXmlNodeModelIndex::ProcessingInstruction, m_parentStack.top(), reader.processingInstructionData().toString(), QXmlName(m_namePool, reader.processingInstructionTarget().toString())); m_result.append(tmp); adjustSiblings(tmp); break; } case QXmlStreamReader::Comment: { LoadingModel::Node *const tmp = new LoadingModel::Node(QXmlNodeModelIndex::Comment, m_parentStack.top(), reader.text().toString()); m_result.append(tmp); adjustSiblings(tmp); break; } case QXmlStreamReader::DTD: qFatal("%s: QXmlStreamReader::DTD token is not supported", Q_FUNC_INFO); break; case QXmlStreamReader::EntityReference: qFatal("%s: QXmlStreamReader::EntityReference token is not supported", Q_FUNC_INFO); break; case QXmlStreamReader::NoToken: /* Fallthrough. */ case QXmlStreamReader::Invalid: { qWarning("%s", qPrintable(reader.errorString())); m_result.clear(); return; } } } if(reader.hasError()) { qWarning("%s", qPrintable(reader.errorString())); m_result.clear(); } }
TableFieldBinaryTreeEvalNode* TableFieldBinaryTreeEvalNode::buildTree(QList<TableFieldEvalNode *>& list, QObject *parent) { if (list.isEmpty()) { return nullptr; } // Build a new list that is surrounded with parenthesis. QList<TableFieldEvalNode *> safeList; TableFieldEvalNode leftParenEvalNode(TableFieldEvalNode::L_PAREN); TableFieldEvalNode rightParenEvalNode(TableFieldEvalNode::R_PAREN); TableFieldBinaryTreeEvalNode* headNode = new TableFieldBinaryTreeEvalNode(parent); safeList.append(&leftParenEvalNode); safeList.append(list); safeList.append(&rightParenEvalNode); bool isError = false; QStack<TableFieldBinaryTreeEvalNode*> values; QStack<TableFieldBinaryTreeEvalNode*> operators; QListIterator<TableFieldEvalNode*> i(safeList); while (i.hasNext() && !isError) { TableFieldEvalNode* eNode = i.next(); if (eNode == nullptr) { qDebug(qPrintable(tr("Cannot build a tree from null nodes."))); isError = true; } else if (eNode->isValue()) { // Push value nodes on the value stack. TableFieldBinaryTreeEvalNode* bNode = new TableFieldBinaryTreeEvalNode(headNode); bNode->setNode(eNode->clone(bNode)); values.push(bNode); } else if (eNode->isLeftParen()) { // Push left parenthesis onto the operator stack. // Will be removed when a right parenthesis is found. TableFieldBinaryTreeEvalNode* bNode = new TableFieldBinaryTreeEvalNode(headNode); bNode->setNode(eNode->clone(bNode)); operators.push(bNode); } else if (eNode->isRightParen()) { // Found a right parenthesis. // Process all operators until a left parenthesis is found then get rid of it. while (!isError && !operators.isEmpty() && !operators.top()->isLeftParen()) { isError = processOneTreeLevel(values, operators); } if (!isError) { if (operators.isEmpty()) { qDebug(qPrintable(tr("Have a ')' without a '('"))); isError = true; } else { // Dispose of the open parenthesis. TableFieldBinaryTreeEvalNode* opNode = operators.pop(); delete opNode; } } } else if (eNode->isNoType()) { qDebug(qPrintable(tr("Cannot build a tree from raw nodes with no type"))); isError = true; } else { // Found an operator. // Process all operators whose priority / precidence is the same or greater than this one. // So, after reading "a OR b OR", you know you can set "a OR b", but you don't know yet if you can // process the second OR. while (!isError && !operators.isEmpty() && !operators.top()->isLeftParen() && operators.top()->nodePriority() >= eNode->nodePriority()) { isError = processOneTreeLevel(values, operators); } if (!isError) { // No error, so push the operator onto the operator stack. TableFieldBinaryTreeEvalNode* bNode = new TableFieldBinaryTreeEvalNode(headNode); bNode->setNode(eNode->clone(bNode)); operators.push(bNode); } } } if (!isError) { if (!operators.isEmpty()) { isError = true; qDebug(qPrintable(tr("Unprocessed Operators left in the stack after processing"))); } else if (values.size() != 1) { isError = true; qDebug(qPrintable(tr("There should be only one value left after processing, not %1").arg(values.size()))); } else { // tree parent node should already be null. // Perform a shallow copy of the top node into the head node. TableFieldBinaryTreeEvalNode* topNode = values.top(); // Clone the node so that the parent / owner is properly set. headNode->m_node = topNode->m_node->clone(headNode); for (int i=0; i<topNode->m_children.size(); ++i) { headNode->addChild(topNode->m_children.at(i)); } delete topNode; return headNode; } } if (isError) { // All of the created nodes are a child of the head node. delete headNode; } return nullptr; }
TypeParser::Info TypeParser::parse(const QString &str) { Scanner scanner(str); Info info; QStack<Info *> stack; stack.push(&info); bool colon_prefix = false; bool in_array = false; QString array; Scanner::Token tok = scanner.nextToken(); while (tok != Scanner::NoToken) { switch (tok) { case Scanner::StarToken: ++stack.top()->indirections; break; case Scanner::AmpersandToken: stack.top()->is_reference = true; break; case Scanner::LessThanToken: stack.top()->template_instantiations << Info(); stack.push(&stack.top()->template_instantiations.last()); break; case Scanner::CommaToken: stack.pop(); stack.top()->template_instantiations << Info(); stack.push(&stack.top()->template_instantiations.last()); break; case Scanner::GreaterThanToken: stack.pop(); break; case Scanner::ColonToken: colon_prefix = true; break; case Scanner::ConstToken: stack.top()->is_constant = true; break; case Scanner::OpenParenToken: // function pointers not supported case Scanner::CloseParenToken: { Info i; i.is_busted = true; return i; } case Scanner::Identifier: parseIdentifier(scanner, stack, array, in_array, colon_prefix); break; case Scanner::SquareBegin: in_array = true; break; case Scanner::SquareEnd: in_array = false; stack.top()->arrays += array; break; default: break; } tok = scanner.nextToken(); } return info; }
void TraceLoader::parseTrace() { QList<ApiTraceFrame*> frames; ApiTraceFrame *currentFrame = 0; int frameCount = 0; QStack<ApiTraceCall*> groups; QVector<ApiTraceCall*> topLevelItems; QVector<ApiTraceCall*> allCalls; quint64 binaryDataSize = 0; int lastPercentReport = 0; trace::Call *call = m_parser.parse_call(); while (call) { //std::cout << *call; if (!currentFrame) { currentFrame = new ApiTraceFrame(); currentFrame->number = frameCount; ++frameCount; } ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash, currentFrame, groups.isEmpty() ? 0 : groups.top(), this); allCalls.append(apiCall); if (groups.count() == 0) { topLevelItems.append(apiCall); } if (call->flags & trace::CALL_FLAG_MARKER_PUSH) { groups.push(apiCall); } else if (call->flags & trace::CALL_FLAG_MARKER_POP) { groups.top()->finishedAddingChildren(); groups.pop(); } if (!groups.isEmpty()) { groups.top()->addChild(apiCall); } if (apiCall->hasBinaryData()) { QByteArray data = apiCall->arguments()[apiCall->binaryDataIndex()].toByteArray(); binaryDataSize += data.size(); } if (call->flags & trace::CALL_FLAG_END_FRAME) { allCalls.squeeze(); topLevelItems.squeeze(); if (topLevelItems.count() == allCalls.count()) { currentFrame->setCalls(allCalls, allCalls, binaryDataSize); } else { currentFrame->setCalls(topLevelItems, allCalls, binaryDataSize); } allCalls.clear(); groups.clear(); topLevelItems.clear(); frames.append(currentFrame); currentFrame = 0; binaryDataSize = 0; if (frames.count() >= FRAMES_TO_CACHE) { emit framesLoaded(frames); frames.clear(); } if (m_parser.percentRead() - lastPercentReport >= 5) { emit parsed(m_parser.percentRead()); lastPercentReport = m_parser.percentRead(); } } delete call; call = m_parser.parse_call(); } //last frames won't have markers // it's just a bunch of Delete calls for every object // after the last SwapBuffers if (currentFrame) { allCalls.squeeze(); if (topLevelItems.count() == allCalls.count()) { currentFrame->setCalls(allCalls, allCalls, binaryDataSize); } else { currentFrame->setCalls(topLevelItems, allCalls, binaryDataSize); } frames.append(currentFrame); currentFrame = 0; } if (frames.count()) { emit framesLoaded(frames); } }
void AccelTree::copyNodeTo(const QXmlNodeModelIndex &node, QAbstractXmlReceiver *const receiver, const NodeCopySettings &settings) const { /* This code piece can be seen as a customized version of * QAbstractXmlReceiver::item/sendAsNode(). */ Q_ASSERT(receiver); Q_ASSERT(!node.isNull()); typedef QHash<QXmlName::PrefixCode, QXmlName::NamespaceCode> Binding; QStack<Binding> outputted; switch(node.kind()) { case QXmlNodeModelIndex::Element: { outputted.push(Binding()); /* Add the namespace for our element name. */ const QXmlName elementName(node.name()); receiver->startElement(elementName); if(!settings.testFlag(InheritNamespaces)) receiver->namespaceBinding(QXmlName(StandardNamespaces::StopNamespaceInheritance, 0, StandardPrefixes::StopNamespaceInheritance)); if(settings.testFlag(PreserveNamespaces)) node.sendNamespaces(receiver); else { /* Find the namespaces that we actually use and add them to outputted. These are drawn * from the element name, and the node's attributes. */ outputted.top().insert(elementName.prefix(), elementName.namespaceURI()); const QXmlNodeModelIndex::Iterator::Ptr attributes(iterate(node, QXmlNodeModelIndex::AxisAttribute)); QXmlNodeModelIndex attr(attributes->next()); while(!attr.isNull()) { const QXmlName &attrName = attr.name(); outputted.top().insert(attrName.prefix(), attrName.namespaceURI()); attr = attributes->next(); } Binding::const_iterator it(outputted.top().constBegin()); const Binding::const_iterator end(outputted.top().constEnd()); for(; it != end; ++it) receiver->namespaceBinding(QXmlName(it.value(), 0, it.key())); } /* Send the attributes of the element. */ { QXmlNodeModelIndex::Iterator::Ptr attributes(node.iterate(QXmlNodeModelIndex::AxisAttribute)); QXmlNodeModelIndex attribute(attributes->next()); while(!attribute.isNull()) { const QString &v = attribute.stringValue(); receiver->attribute(attribute.name(), QStringRef(&v)); attribute = attributes->next(); } } /* Send the children of the element. */ copyChildren(node, receiver, settings); receiver->endElement(); outputted.pop(); break; } case QXmlNodeModelIndex::Document: { /* We need to intercept and grab the elements of the document node, such * that we preserve/inherit preference applies to them. */ receiver->startDocument(); copyChildren(node, receiver, settings); receiver->endDocument(); break; } default: receiver->item(node); } }
bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, const QString &fname, QString currentPath, bool ignoreErrors) { Q_ASSERT(m_errorDevice); const QChar slash = QLatin1Char('/'); if (!currentPath.isEmpty() && !currentPath.endsWith(slash)) currentPath += slash; QXmlStreamReader reader(inputDevice); QStack<RCCXmlTag> tokens; QString prefix; QLocale::Language language = QLocale::c().language(); QLocale::Country country = QLocale::c().country(); QString alias; int compressLevel = m_compressLevel; int compressThreshold = m_compressThreshold; while (!reader.atEnd()) { QXmlStreamReader::TokenType t = reader.readNext(); switch (t) { case QXmlStreamReader::StartElement: if (reader.name() == m_strings.TAG_RCC) { if (!tokens.isEmpty()) reader.raiseError(QLatin1String("expected <RCC> tag")); else tokens.push(RccTag); } else if (reader.name() == m_strings.TAG_RESOURCE) { if (tokens.isEmpty() || tokens.top() != RccTag) { reader.raiseError(QLatin1String("unexpected <RESOURCE> tag")); } else { tokens.push(ResourceTag); QXmlStreamAttributes attributes = reader.attributes(); language = QLocale::c().language(); country = QLocale::c().country(); if (attributes.hasAttribute(m_strings.ATTRIBUTE_LANG)) { QString attribute = attributes.value(m_strings.ATTRIBUTE_LANG).toString(); QLocale lang = QLocale(attribute); language = lang.language(); if (2 == attribute.length()) { // Language only country = QLocale::AnyCountry; } else { country = lang.country(); } } prefix.clear(); if (attributes.hasAttribute(m_strings.ATTRIBUTE_PREFIX)) prefix = attributes.value(m_strings.ATTRIBUTE_PREFIX).toString(); if (!prefix.startsWith(slash)) prefix.prepend(slash); if (!prefix.endsWith(slash)) prefix += slash; } } else if (reader.name() == m_strings.TAG_FILE) { if (tokens.isEmpty() || tokens.top() != ResourceTag) { reader.raiseError(QLatin1String("unexpected <FILE> tag")); } else { tokens.push(FileTag); QXmlStreamAttributes attributes = reader.attributes(); alias.clear(); if (attributes.hasAttribute(m_strings.ATTRIBUTE_ALIAS)) alias = attributes.value(m_strings.ATTRIBUTE_ALIAS).toString(); compressLevel = m_compressLevel; if (attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESS)) compressLevel = attributes.value(m_strings.ATTRIBUTE_COMPRESS).toString().toInt(); compressThreshold = m_compressThreshold; if (attributes.hasAttribute(m_strings.ATTRIBUTE_THRESHOLD)) compressThreshold = attributes.value(m_strings.ATTRIBUTE_THRESHOLD).toString().toInt(); // Special case for -no-compress. Overrides all other settings. if (m_compressLevel == -2) compressLevel = 0; } } else { reader.raiseError(QString(QLatin1String("unexpected tag: %1")).arg(reader.name().toString())); } break; case QXmlStreamReader::EndElement: if (reader.name() == m_strings.TAG_RCC) { if (!tokens.isEmpty() && tokens.top() == RccTag) tokens.pop(); else reader.raiseError(QLatin1String("unexpected closing tag")); } else if (reader.name() == m_strings.TAG_RESOURCE) { if (!tokens.isEmpty() && tokens.top() == ResourceTag) tokens.pop(); else reader.raiseError(QLatin1String("unexpected closing tag")); } else if (reader.name() == m_strings.TAG_FILE) { if (!tokens.isEmpty() && tokens.top() == FileTag) tokens.pop(); else reader.raiseError(QLatin1String("unexpected closing tag")); } break; case QXmlStreamReader::Characters: if (reader.isWhitespace()) break; if (tokens.isEmpty() || tokens.top() != FileTag) { reader.raiseError(QLatin1String("unexpected text")); } else { QString fileName = reader.text().toString(); if (fileName.isEmpty()) { const QString msg = QString::fromLatin1("RCC: Warning: Null node in XML of '%1'\n").arg(fname); m_errorDevice->write(msg.toUtf8()); } if (alias.isNull()) alias = fileName; alias = QDir::cleanPath(alias); while (alias.startsWith(QLatin1String("../"))) alias.remove(0, 3); alias = QDir::cleanPath(m_resourceRoot) + prefix + alias; QString absFileName = fileName; if (QDir::isRelativePath(absFileName)) absFileName.prepend(currentPath); QFileInfo file(absFileName); if (!file.exists()) { m_failedResources.push_back(absFileName); const QString msg = QString::fromLatin1("RCC: Error in '%1': Cannot find file '%2'\n").arg(fname).arg(fileName); m_errorDevice->write(msg.toUtf8()); if (ignoreErrors) continue; else return false; } else if (file.isFile()) { const bool arc = addFile(alias, RCCFileInfo(alias.section(slash, -1), file, language, country, RCCFileInfo::NoFlags, compressLevel, compressThreshold) ); if (!arc) m_failedResources.push_back(absFileName); } else { QDir dir; if (file.isDir()) { dir.setPath(file.filePath()); } else { dir.setPath(file.path()); dir.setNameFilters(QStringList(file.fileName())); if (alias.endsWith(file.fileName())) alias = alias.left(alias.length()-file.fileName().length()); } if (!alias.endsWith(slash)) alias += slash; QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories); while (it.hasNext()) { it.next(); QFileInfo child(it.fileInfo()); if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) { const bool arc = addFile(alias + child.fileName(), RCCFileInfo(child.fileName(), child, language, country, RCCFileInfo::NoFlags, compressLevel, compressThreshold) ); if (!arc) m_failedResources.push_back(child.fileName()); } } } } break; default: break; } } if (reader.hasError()) { if (ignoreErrors) return true; int errorLine = reader.lineNumber(); int errorColumn = reader.columnNumber(); QString errorMessage = reader.errorString(); QString msg = QString::fromLatin1("RCC Parse Error: '%1' Line: %2 Column: %3 [%4]\n").arg(fname).arg(errorLine).arg(errorColumn).arg(errorMessage); m_errorDevice->write(msg.toUtf8()); return false; } if (m_root == 0) { const QString msg = QString::fromUtf8("RCC: Warning: No resources in '%1'.\n").arg(fname); m_errorDevice->write(msg.toUtf8()); if (!ignoreErrors && m_format == Binary) { // create dummy entry, otherwise loading with QResource will crash m_root = new RCCFileInfo(QString(), QFileInfo(), QLocale::C, QLocale::AnyCountry, RCCFileInfo::Directory); } } return true; }
void dspIndentedWhereUsed::sFillList() { _bomitem->clear(); if (_item->isValid()) { q.prepare("SELECT indentedWhereUsed(:item_id) AS workset_id;"); q.bindValue(":item_id", _item->id()); q.exec(); if (q.first()) { int worksetid = q.value("workset_id").toInt(); QString sql( "SELECT bomwork_level, bomwork_id, item_id, bomwork_parent_id," " bomworkitemsequence(bomwork_id) as seqord, " " bomwork_seqnumber, item_number, uom_name," " (item_descrip1 || ' ' || item_descrip2) AS itemdescription," " formatQtyPer(bomwork_qtyper) AS qtyper," " formatScrap(bomwork_scrap) AS scrap," " formatDate(bomwork_effective, 'Always') AS effective," " formatDate(bomwork_expires, 'Never') AS expires " "FROM bomwork, item, uom " "WHERE ( (bomwork_item_id=item_id)" " AND (item_inv_uom_id=uom_id)" " AND (bomwork_set_id=:bomwork_set_id)" ); if (!_showExpired->isChecked()) sql += " AND (bomwork_expires > CURRENT_DATE)"; if (!_showFuture->isChecked()) sql += " AND (bomwork_effective <= CURRENT_DATE)"; sql += ") " "ORDER BY seqord;"; q.prepare(sql); q.bindValue(":bomwork_set_id", worksetid); q.exec(); QStack<XTreeWidgetItem*> parent; XTreeWidgetItem *last = 0; int level = 0; while(q.next()) { // If the level this item is on is lower than the last level we just did then we need // to pop the stack a number of times till we are equal. while(q.value("bomwork_level").toInt() < level) { level--; last = parent.pop(); } // If the level this item is on is higher than the last level we need to push the last // item onto the stack a number of times till we are equal. (Should only ever be 1.) while(q.value("bomwork_level").toInt() > level) { level++; parent.push(last); last = 0; } // If there is an item in the stack use that as the parameter to the new xlistviewitem // otherwise we'll just use the xlistview _layout if(!parent.isEmpty() && parent.top()) last = new XTreeWidgetItem(parent.top(), last, q.value("bomwork_id").toInt(), q.value("item_id").toInt(), q.value("bomwork_seqnumber"), q.value("item_number"), q.value("itemdescription"), q.value("uom_name"), q.value("qtyper"), q.value("scrap"), q.value("effective"), q.value("expires") ); else last = new XTreeWidgetItem(_bomitem, last, q.value("bomwork_id").toInt(), q.value("item_id").toInt(), q.value("bomwork_seqnumber"), q.value("item_number"), q.value("itemdescription"), q.value("uom_name"), q.value("qtyper"), q.value("scrap"), q.value("effective"), q.value("expires") ); } _bomitem->expandAll(); q.prepare("SELECT deleteBOMWorkset(:workset_id) AS result;"); q.bindValue(":bomwork_set_id", worksetid); q.exec(); } } }
void OwncloudPropagator::start(const SyncFileItemVector &items) { Q_ASSERT(std::is_sorted(items.begin(), items.end())); /* This builds all the jobs needed for the propagation. * Each directory is a PropagateDirectory job, which contains the files in it. * In order to do that we loop over the items. (which are sorted by destination) * When we enter a directory, we can create the directory job and push it on the stack. */ _rootJob.reset(new PropagateDirectory(this)); QStack<QPair<QString /* directory name */, PropagateDirectory * /* job */>> directories; directories.push(qMakePair(QString(), _rootJob.data())); QVector<PropagatorJob *> directoriesToRemove; QString removedDirectory; foreach (const SyncFileItemPtr &item, items) { if (!removedDirectory.isEmpty() && item->_file.startsWith(removedDirectory)) { // this is an item in a directory which is going to be removed. PropagateDirectory *delDirJob = qobject_cast<PropagateDirectory *>(directoriesToRemove.first()); if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) { // already taken care of. (by the removal of the parent directory) // increase the number of subjobs that would be there. if (delDirJob) { delDirJob->increaseAffectedCount(); } continue; } else if (item->isDirectory() && (item->_instruction == CSYNC_INSTRUCTION_NEW || item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE)) { // create a new directory within a deleted directory? That can happen if the directory // etag was not fetched properly on the previous sync because the sync was aborted // while uploading this directory (which is now removed). We can ignore it. if (delDirJob) { delDirJob->increaseAffectedCount(); } continue; } else if (item->_instruction == CSYNC_INSTRUCTION_IGNORE) { continue; } else if (item->_instruction == CSYNC_INSTRUCTION_RENAME) { // all is good, the rename will be executed before the directory deletion } else { qCWarning(lcPropagator) << "WARNING: Job within a removed directory? This should not happen!" << item->_file << item->_instruction; } } while (!item->destination().startsWith(directories.top().first)) { directories.pop(); } if (item->isDirectory()) { PropagateDirectory *dir = new PropagateDirectory(this, item); if (item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE && item->_direction == SyncFileItem::Up) { // Skip all potential uploads to the new folder. // Processing them now leads to problems with permissions: // checkForPermissions() has already run and used the permissions // of the file we're about to delete to decide whether uploading // to the new dir is ok... foreach (const SyncFileItemPtr &item2, items) { if (item2->destination().startsWith(item->destination() + "/")) { item2->_instruction = CSYNC_INSTRUCTION_NONE; _anotherSyncNeeded = true; } } } if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) { // We do the removal of directories at the end, because there might be moves from // these directories that will happen later. directoriesToRemove.prepend(dir); removedDirectory = item->_file + "/"; // We should not update the etag of parent directories of the removed directory // since it would be done before the actual remove (issue #1845) // NOTE: Currently this means that we don't update those etag at all in this sync, // but it should not be a problem, they will be updated in the next sync. for (int i = 0; i < directories.size(); ++i) { if (directories[i].second->_item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) directories[i].second->_item->_instruction = CSYNC_INSTRUCTION_NONE; } } else { PropagateDirectory *currentDirJob = directories.top().second; currentDirJob->appendJob(dir); } directories.push(qMakePair(item->destination() + "/", dir)); } else {
QVector<ApiTraceCall*> TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame) { Q_ASSERT(currentFrame); if (currentFrame->isLoaded()) { return currentFrame->calls(); } if (m_parser.supportsOffsets()) { unsigned frameIdx = currentFrame->number; int numOfCalls = numberOfCallsInFrame(frameIdx); if (numOfCalls) { quint64 binaryDataSize = 0; QStack<ApiTraceCall*> groups; QVector<ApiTraceCall*> topLevelItems; QVector<ApiTraceCall*> allCalls(numOfCalls); const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx]; m_parser.setBookmark(frameBookmark.start); trace::Call *call; int parsedCalls = 0; while ((call = m_parser.parse_call())) { ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash, currentFrame, groups.isEmpty() ? 0 : groups.top(), this); Q_ASSERT(apiCall); Q_ASSERT(parsedCalls < allCalls.size()); allCalls[parsedCalls++] = apiCall; if (groups.count() == 0) { topLevelItems.append(apiCall); } else { groups.top()->addChild(apiCall); } if (call->flags & trace::CALL_FLAG_MARKER_PUSH) { groups.push(apiCall); } else if (call->flags & trace::CALL_FLAG_MARKER_POP) { if (groups.count()) { groups.top()->finishedAddingChildren(); groups.pop(); } } if (apiCall->hasBinaryData()) { QByteArray data = apiCall->arguments()[ apiCall->binaryDataIndex()].toByteArray(); binaryDataSize += data.size(); } delete call; if (apiCall->flags() & trace::CALL_FLAG_END_FRAME) { break; } } // There can be fewer parsed calls when call in different // threads cross the frame boundary Q_ASSERT(parsedCalls <= numOfCalls); Q_ASSERT(parsedCalls <= allCalls.size()); allCalls.resize(parsedCalls); allCalls.squeeze(); Q_ASSERT(parsedCalls <= currentFrame->numChildrenToLoad()); if (topLevelItems.count() == allCalls.count()) { emit frameContentsLoaded(currentFrame, allCalls, allCalls, binaryDataSize); } else { emit frameContentsLoaded(currentFrame, topLevelItems, allCalls, binaryDataSize); } return allCalls; } } return QVector<ApiTraceCall*>(); }
void Highlighter::iterateThroughRules(const QString &text, const int length, ProgressData *progress, const bool childRule, const QList<QSharedPointer<Rule> > &rules) { typedef QList<QSharedPointer<Rule> >::const_iterator RuleIterator; bool contextChanged = false; bool atLeastOneMatch = false; RuleIterator it = rules.begin(); RuleIterator endIt = rules.end(); while (it != endIt && progress->offset() < length) { int startOffset = progress->offset(); const QSharedPointer<Rule> &rule = *it; if (rule->matchSucceed(text, length, progress)) { atLeastOneMatch = true; if (!m_indentationBasedFolding) { if (!rule->beginRegion().isEmpty()) { blockData(currentBlockUserData())->m_foldingRegions.push(rule->beginRegion()); ++m_regionDepth; if (progress->isOpeningBraceMatchAtFirstNonSpace()) ++blockData(currentBlockUserData())->m_foldingIndentDelta; } if (!rule->endRegion().isEmpty()) { QStack<QString> *currentRegions = &blockData(currentBlockUserData())->m_foldingRegions; if (!currentRegions->isEmpty() && rule->endRegion() == currentRegions->top()) { currentRegions->pop(); --m_regionDepth; if (progress->isClosingBraceMatchAtNonEnd()) --blockData(currentBlockUserData())->m_foldingIndentDelta; } } progress->clearBracesMatches(); } if (progress->isWillContinueLine()) { createWillContinueBlock(); progress->setWillContinueLine(false); } else { if (rule->hasChildren()) iterateThroughRules(text, length, progress, true, rule->children()); if (!rule->context().isEmpty() && contextChangeRequired(rule->context())) { m_currentCaptures = progress->captures(); changeContext(rule->context(), rule->definition()); contextChanged = true; } } // Format is not applied to child rules directly (but relative to the offset of their // parent) nor to look ahead rules. if (!childRule && !rule->isLookAhead()) { if (rule->itemData().isEmpty()) applyFormat(startOffset, progress->offset() - startOffset, m_currentContext->itemData(), m_currentContext->definition()); else applyFormat(startOffset, progress->offset() - startOffset, rule->itemData(), rule->definition()); } // When there is a match of one child rule the others should be skipped. Otherwise // the highlighting would be incorret in a case like 9ULLLULLLUULLULLUL, for example. if (contextChanged || childRule) { break; } else { it = rules.begin(); continue; } } ++it; } if (!childRule && !atLeastOneMatch) { if (m_currentContext->isFallthrough()) { handleContextChange(m_currentContext->fallthroughContext(), m_currentContext->definition()); iterateThroughRules(text, length, progress, false, m_currentContext->rules()); } else { applyFormat(progress->offset(), 1, m_currentContext->itemData(), m_currentContext->definition()); if (progress->isOnlySpacesSoFar() && !text.at(progress->offset()).isSpace()) progress->setOnlySpacesSoFar(false); progress->incrementOffset(); } } }
void QmlProfilerEventsModelProxy::loadData(qint64 rangeStart, qint64 rangeEnd) { clear(); qint64 qmlTime = 0; qint64 lastEndTime = 0; QHash <int, QVector<qint64> > durations; const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1); const QVector<QmlProfilerDataModel::QmlEventData> &eventList = d->modelManager->qmlModel()->getEvents(); const QVector<QmlProfilerDataModel::QmlEventTypeData> &typesList = d->modelManager->qmlModel()->getEventTypes(); // used by binding loop detection QStack<const QmlProfilerDataModel::QmlEventData*> callStack; callStack.push(0); // artificial root for (int i = 0; i < eventList.size(); ++i) { const QmlProfilerDataModel::QmlEventData *event = &eventList[i]; const QmlProfilerDataModel::QmlEventTypeData *type = &typesList[event->typeIndex]; if (!d->acceptedTypes.contains(type->rangeType)) continue; if (checkRanges) { if ((event->startTime + event->duration < rangeStart) || (event->startTime > rangeEnd)) continue; } // update stats QmlEventStats *stats = &d->data[event->typeIndex]; stats->duration += event->duration; if (event->duration < stats->minTime) stats->minTime = event->duration; if (event->duration > stats->maxTime) stats->maxTime = event->duration; stats->calls++; // for median computing durations[event->typeIndex].append(event->duration); // qml time computation if (event->startTime > lastEndTime) { // assume parent event if starts before last end qmlTime += event->duration; lastEndTime = event->startTime + event->duration; } // // binding loop detection // const QmlProfilerDataModel::QmlEventData *potentialParent = callStack.top(); while (potentialParent && !(potentialParent->startTime + potentialParent->duration > event->startTime)) { callStack.pop(); potentialParent = callStack.top(); } // check whether event is already in stack for (int ii = 1; ii < callStack.size(); ++ii) { if (callStack.at(ii)->typeIndex == event->typeIndex) { d->eventsInBindingLoop.insert(event->typeIndex); break; } } callStack.push(event); d->modelManager->modelProxyCountUpdated(d->modelId, i, eventList.count()*2); } // post-process: calc mean time, median time, percentoftime int i = d->data.size(); int total = i * 2; for (QHash<int, QmlEventStats>::iterator it = d->data.begin(); it != d->data.end(); ++it) { QmlEventStats* stats = &it.value(); if (stats->calls > 0) stats->timePerCall = stats->duration / (double)stats->calls; QVector<qint64> eventDurations = durations[it.key()]; if (!eventDurations.isEmpty()) { Utils::sort(eventDurations); stats->medianTime = eventDurations.at(eventDurations.count()/2); } stats->percentOfTime = stats->duration * 100.0 / qmlTime; d->modelManager->modelProxyCountUpdated(d->modelId, i++, total); } // set binding loop flag foreach (int typeIndex, d->eventsInBindingLoop) d->data[typeIndex].isBindingLoop = true; // insert root event QmlEventStats rootEvent; rootEvent.duration = rootEvent.minTime = rootEvent.maxTime = rootEvent.timePerCall = rootEvent.medianTime = qmlTime + 1; rootEvent.calls = 1; rootEvent.percentOfTime = 100.0; d->data.insert(-1, rootEvent); d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); emit dataAvailable(); }
/*! \internal */ void QDirIteratorPrivate::advance() { // Store the current entry if (!fileEngineIterators.isEmpty()) currentFilePath = fileEngineIterators.top()->currentFilePath(); // Advance to the next entry if (followNextDir) { // Start by navigating into the current directory. followNextDir = false; QAbstractFileEngineIterator *it = fileEngineIterators.top(); QString subDir = it->currentFilePath(); #ifdef Q_OS_WIN if (fileInfo.isSymLink()) subDir = fileInfo.canonicalFilePath(); #endif pushSubDirectory(subDir, it->nameFilters(), it->filters()); } if (fileEngineIterators.isEmpty()) done = true; bool foundValidEntry = false; while (!fileEngineIterators.isEmpty()) { QAbstractFileEngineIterator *it = fileEngineIterators.top(); // Find the next valid iterator that matches the filters. foundValidEntry = false; while (it->hasNext()) { it->next(); if (matchesFilters(it)) { foundValidEntry = true; break; } } if (!foundValidEntry) { // If this iterator is done, pop and delete it, and continue // iteration on the parent. Otherwise break, we're done. if (!fileEngineIterators.isEmpty()) { delete it; it = fileEngineIterators.pop(); continue; } break; } fileInfo = it->currentFileInfo(); // If we're doing flat iteration, we're done. if (!(iteratorFlags & QDirIterator::Subdirectories)) break; // Subdirectory iteration. QString filePath = fileInfo.filePath(); // Never follow . and .. if (fileInfo.fileName() == QLatin1String(".") || fileInfo.fileName() == QLatin1String("..")) break; // Never follow non-directory entries if (!fileInfo.isDir()) break; // Check symlinks if (fileInfo.isSymLink() && !(iteratorFlags & QDirIterator::FollowSymlinks)) { // Follow symlinks only if FollowSymlinks was passed break; } // Stop link loops if (visitedLinks.contains(fileInfo.canonicalFilePath())) break; // Signal that we want to follow this entry. followNextDir = true; break; } if (!foundValidEntry) done = true; }
TypeParser::Info TypeParser::parse(const QString &str) { Scanner scanner(str); Info info; QStack<Info *> stack; stack.push(&info); bool colon_prefix = false; bool in_array = false; QString array; Scanner::Token tok = scanner.nextToken(); while (tok != Scanner::NoToken) { // switch (tok) { // case Scanner::StarToken: printf(" - *\n"); break; // case Scanner::AmpersandToken: printf(" - &\n"); break; // case Scanner::LessThanToken: printf(" - <\n"); break; // case Scanner::GreaterThanToken: printf(" - >\n"); break; // case Scanner::ColonToken: printf(" - ::\n"); break; // case Scanner::CommaToken: printf(" - ,\n"); break; // case Scanner::ConstToken: printf(" - const\n"); break; // case Scanner::SquareBegin: printf(" - [\n"); break; // case Scanner::SquareEnd: printf(" - ]\n"); break; // case Scanner::Identifier: printf(" - '%s'\n", qPrintable(scanner.identifier())); break; // default: // break; // } switch (tok) { case Scanner::StarToken: ++stack.top()->indirections; break; case Scanner::AmpersandToken: stack.top()->is_reference = true; break; case Scanner::LessThanToken: stack.top()->template_instantiations << Info(); stack.push(&stack.top()->template_instantiations.last()); break; case Scanner::CommaToken: stack.pop(); stack.top()->template_instantiations << Info(); stack.push(&stack.top()->template_instantiations.last()); break; case Scanner::GreaterThanToken: stack.pop(); break; case Scanner::ColonToken: colon_prefix = true; break; case Scanner::ConstToken: stack.top()->is_constant = true; break; case Scanner::OpenParenToken: // function pointers not supported case Scanner::CloseParenToken: { Info i; i.is_busted = true; return i; } case Scanner::Identifier: if (in_array) { array = scanner.identifier(); } else if (colon_prefix || stack.top()->qualified_name.isEmpty()) { stack.top()->qualified_name << scanner.identifier(); colon_prefix = false; } else { stack.top()->qualified_name.last().append(" " + scanner.identifier()); } break; case Scanner::SquareBegin: in_array = true; break; case Scanner::SquareEnd: in_array = false; stack.top()->arrays += array; break; default: break; } tok = scanner.nextToken(); } return info; }