/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #include "proitems.h" #include "prowriter.h" #include #include using namespace Qt4ProjectManager::Internal; void ProWriter::addFiles(ProFile *profile, QStringList *lines, const QDir &proFileDir, const QStringList &filePaths, const QString &var) { // Check if variable item exists as child of root item for (ProItem *item = profile->items(); item; item = item->next()) { if (item->kind() == ProItem::VariableKind) { ProVariable *proVar = static_cast(item); if (var == proVar->variable() && proVar->variableOperator() != ProVariable::RemoveOperator && proVar->variableOperator() != ProVariable::ReplaceOperator) { int lineNo = proVar->lineNumber() - 1; for (; lineNo < lines->count(); lineNo++) { QString line = lines->at(lineNo); int idx = line.indexOf(QLatin1Char('#')); if (idx >= 0) line.truncate(idx); while (line.endsWith(QLatin1Char(' ')) || line.endsWith(QLatin1Char('\t'))) line.chop(1); if (line.isEmpty()) { if (idx >= 0) continue; break; } if (!line.endsWith(QLatin1Char('\\'))) { (*lines)[lineNo].insert(line.length(), QLatin1String(" \\")); lineNo++; break; } } QString added; foreach (const QString &filePath, filePaths) added += QLatin1String(" ") + proFileDir.relativeFilePath(filePath) + QLatin1String(" \\\n"); added.chop(3); lines->insert(lineNo, added); return; } } } // Create & append new variable item QString added = QLatin1Char('\n') + var + QLatin1String(" +="); foreach (const QString &filePath, filePaths) added += QLatin1String(" \\\n ") + proFileDir.relativeFilePath(filePath); *lines << added; } static void findProVariables(ProItem *item, const QStringList &vars, QList *proVars) { for (; item; item = item->next()) { if (item->kind() == ProItem::BranchKind) { findProVariables(static_cast(item)->thenItems(), vars, proVars); findProVariables(static_cast(item)->elseItems(), vars, proVars); } else if (item->kind() == ProItem::VariableKind) { ProVariable *proVar = static_cast(item); if (vars.contains(proVar->variable())) *proVars << proVar; } } } QStringList ProWriter::removeFiles(ProFile *profile, QStringList *lines, const QDir &proFileDir, const QStringList &filePaths, const QStringList &vars) { QStringList notChanged = filePaths; QList proVars; findProVariables(profile->items(), vars, &proVars); // This is a tad stupid - basically, it can remove only entries which // the above code added. QStringList relativeFilePaths; foreach (const QString &absoluteFilePath, filePaths) relativeFilePaths << proFileDir.relativeFilePath(absoluteFilePath); // This code expects proVars to be sorted by the variables' appearance in the file. int delta = 1; foreach (ProVariable *proVar, proVars) { if (proVar->variableOperator() != ProVariable::RemoveOperator && proVar->variableOperator() != ProVariable::ReplaceOperator) { bool first = true; int lineNo = proVar->lineNumber() - delta; typedef QPair ContPos; QList contPos; while (lineNo < lines->count()) { QString &line = (*lines)[lineNo]; int lineLen = line.length(); bool killed = false; bool saved = false; int idx = line.indexOf(QLatin1Char('#')); if (idx >= 0) lineLen = idx; QChar *chars = line.data(); forever { if (!lineLen) { if (idx >= 0) goto nextLine; goto nextVar; } QChar c = chars[lineLen - 1]; if (c != QLatin1Char(' ') && c != QLatin1Char('\t')) break; lineLen--; } { int contCol = -1; if (chars[lineLen - 1] == QLatin1Char('\\')) contCol = --lineLen; int colNo = 0; if (first) { colNo = line.indexOf(QLatin1Char('=')) + 1; first = false; saved = true; } while (colNo < lineLen) { QChar c = chars[colNo]; if (c == QLatin1Char(' ') || c == QLatin1Char('\t')) { colNo++; continue; } int varCol = colNo; while (colNo < lineLen) { QChar c = chars[colNo]; if (c == QLatin1Char(' ') || c == QLatin1Char('\t')) break; colNo++; } QString fn = line.mid(varCol, colNo - varCol); if (relativeFilePaths.contains(fn)) { notChanged.removeOne(QDir::cleanPath(proFileDir.absoluteFilePath(fn))); if (colNo < lineLen) colNo++; else if (varCol) varCol--; int len = colNo - varCol; colNo = varCol; line.remove(varCol, len); lineLen -= len; contCol -= len; idx -= len; if (idx >= 0) line.insert(idx, QLatin1String("# ") + fn + QLatin1Char(' ')); killed = true; } else { saved = true; } } if (saved) { // Entries remained contPos.clear(); } else if (killed) { // Entries existed, but were all removed if (contCol < 0) { // This is the last line, so clear continuations leading to it foreach (const ContPos &pos, contPos) { QString &bline = (*lines)[pos.first]; bline.remove(pos.second, 1); if (pos.second == bline.length()) while (bline.endsWith(QLatin1Char(' ')) || bline.endsWith(QLatin1Char('\t'))) bline.chop(1); } contPos.clear(); } if (idx < 0) { // Not even a comment stayed behind, so zap the line lines->removeAt(lineNo); delta++; continue; } } if (contCol >= 0) contPos.append(qMakePair(lineNo, contCol)); } nextLine: lineNo++; } nextVar: ; } } return notChanged; }