From 222a48f0179bcebf63fdc3e8c5600b2ad44dd099 Mon Sep 17 00:00:00 2001 From: Torgny Nyblom Date: Tue, 26 Oct 2010 12:17:40 +0200 Subject: Fix filename and linenumber for included rulefiles. --- src/ruleparser.cpp | 238 ++++++++++++++++++++++++++--------------------------- 1 file changed, 115 insertions(+), 123 deletions(-) (limited to 'src/ruleparser.cpp') diff --git a/src/ruleparser.cpp b/src/ruleparser.cpp index 3bad38b..f21f5b6 100644 --- a/src/ruleparser.cpp +++ b/src/ruleparser.cpp @@ -76,37 +76,14 @@ const QList Rules::matchRules() const return m_matchRules; } -QStringList Rules::readRules(const QString &filename) const +void Rules::load() { - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) - qFatal("Could not read the rules file: %s", qPrintable(filename)); - QStringList allLines; - QRegExp includeLine("include\\s+(.*)", Qt::CaseInsensitive); - - QTextStream s(&file); - QStringList lines = s.readAll().split('\n', QString::KeepEmptyParts); - - QStringList::iterator it; - for(it = lines.begin(); it != lines.end(); ++it) { - QString line = *it; - bool isIncludeRule = includeLine.exactMatch(line); - - if (isIncludeRule) { - int index = filename.lastIndexOf("/"); - QString includeFile = filename.left( index + 1) + includeLine.cap(1); - allLines.append( readRules(includeFile)); - } else { - allLines.append(line); - } - } - file.close(); - return allLines; + load(filename); } -void Rules::load() +void Rules::load(const QString &filename) { - QStringList lines = readRules(filename); + qDebug() << "Loading rules from" << filename; // initialize the regexps we will use QRegExp repoLine("create repository\\s+(\\S+)", Qt::CaseInsensitive); @@ -119,6 +96,7 @@ void Rules::load() QRegExp matchPrefixLine("prefix\\s+(\\S+)", Qt::CaseInsensitive); QRegExp declareLine("declare\\s+(\\S+)\\s*=\\s*(\\S+)", Qt::CaseInsensitive); QRegExp variableLine("\\$\\{(\\S+)\\}", Qt::CaseInsensitive); + QRegExp includeLine("include\\s+(.*)", Qt::CaseInsensitive); QMap variables; @@ -127,6 +105,13 @@ void Rules::load() Match match; int lineNumber = 0; + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) + qFatal("Could not read the rules file: %s", qPrintable(filename)); + + QTextStream s(&file); + QStringList lines = s.readAll().split('\n', QString::KeepEmptyParts); + QStringList::iterator it; for(it = lines.begin(); it != lines.end(); ++it) { ++lineNumber; @@ -140,105 +125,112 @@ void Rules::load() if (line.isEmpty()) continue; - int index = variableLine.indexIn(line); - if ( index != -1 ) { - if (!variables.contains(variableLine.cap(1))) - qFatal("Undeclared variable: %s", qPrintable(variableLine.cap(1))); - line = line.replace(variableLine, variables[variableLine.cap(1)]); - } - if (state == ReadingRepository) { - if (matchBranchLine.exactMatch(line)) { - Repository::Branch branch; - branch.name = matchBranchLine.cap(1); - - repo.branches += branch; - continue; - } else if (matchRepoLine.exactMatch(line)) { - repo.forwardTo = matchRepoLine.cap(1); - continue; - } else if (matchPrefixLine.exactMatch(line)) { - repo.prefix = matchPrefixLine.cap(1); - continue; - } else if (line == "end repository") { - m_repositories += repo; - { - // clear out 'repo' - Repository temp; - std::swap(repo, temp); - } - state = ReadingNone; - continue; + bool isIncludeRule = includeLine.exactMatch(line); + if (isIncludeRule) { + int index = filename.lastIndexOf("/"); + QString includeFile = filename.left( index + 1) + includeLine.cap(1); + load(includeFile); + } else { + int index = variableLine.indexIn(line); + if ( index != -1 ) { + if (!variables.contains(variableLine.cap(1))) + qFatal("Undeclared variable: %s", qPrintable(variableLine.cap(1))); + line = line.replace(variableLine, variables[variableLine.cap(1)]); } - } else if (state == ReadingMatch) { - if (matchRepoLine.exactMatch(line)) { - match.repository = matchRepoLine.cap(1); - continue; - } else if (matchBranchLine.exactMatch(line)) { - match.branch = matchBranchLine.cap(1); - continue; - } else if (matchRevLine.exactMatch(line)) { - if (matchRevLine.cap(1) == "min") - match.minRevision = matchRevLine.cap(2).toInt(); - else // must be max - match.maxRevision = matchRevLine.cap(2).toInt(); - continue; - } else if (matchPrefixLine.exactMatch(line)) { - match.prefix = matchPrefixLine.cap(1); - if( match.prefix.startsWith('/')) - match.prefix = match.prefix.mid(1); - continue; - } else if (matchActionLine.exactMatch(line)) { - QString action = matchActionLine.cap(1); - if (action == "export") - match.action = Match::Export; - else if (action == "ignore") - match.action = Match::Ignore; - else if (action == "recurse") - match.action = Match::Recurse; - else - qFatal("Invalid action \"%s\" on line %d", qPrintable(action), lineNumber); - continue; - } else if (matchAnnotateLine.exactMatch(line)) { - match.annotate = matchAnnotateLine.cap(1) == "true"; - continue; - } else if (line == "end match") { - if (!match.repository.isEmpty()) - match.action = Match::Export; - m_matchRules += match; - state = ReadingNone; - continue; + if (state == ReadingRepository) { + if (matchBranchLine.exactMatch(line)) { + Repository::Branch branch; + branch.name = matchBranchLine.cap(1); + + repo.branches += branch; + continue; + } else if (matchRepoLine.exactMatch(line)) { + repo.forwardTo = matchRepoLine.cap(1); + continue; + } else if (matchPrefixLine.exactMatch(line)) { + repo.prefix = matchPrefixLine.cap(1); + continue; + } else if (line == "end repository") { + m_repositories += repo; + { + // clear out 'repo' + Repository temp; + std::swap(repo, temp); + } + state = ReadingNone; + continue; + } + } else if (state == ReadingMatch) { + if (matchRepoLine.exactMatch(line)) { + match.repository = matchRepoLine.cap(1); + continue; + } else if (matchBranchLine.exactMatch(line)) { + match.branch = matchBranchLine.cap(1); + continue; + } else if (matchRevLine.exactMatch(line)) { + if (matchRevLine.cap(1) == "min") + match.minRevision = matchRevLine.cap(2).toInt(); + else // must be max + match.maxRevision = matchRevLine.cap(2).toInt(); + continue; + } else if (matchPrefixLine.exactMatch(line)) { + match.prefix = matchPrefixLine.cap(1); + if( match.prefix.startsWith('/')) + match.prefix = match.prefix.mid(1); + continue; + } else if (matchActionLine.exactMatch(line)) { + QString action = matchActionLine.cap(1); + if (action == "export") + match.action = Match::Export; + else if (action == "ignore") + match.action = Match::Ignore; + else if (action == "recurse") + match.action = Match::Recurse; + else + qFatal("Invalid action \"%s\" on line %d", qPrintable(action), lineNumber); + continue; + } else if (matchAnnotateLine.exactMatch(line)) { + match.annotate = matchAnnotateLine.cap(1) == "true"; + continue; + } else if (line == "end match") { + if (!match.repository.isEmpty()) + match.action = Match::Export; + m_matchRules += match; + state = ReadingNone; + continue; + } } - } - bool isRepositoryRule = repoLine.exactMatch(line); - bool isMatchRule = matchLine.exactMatch(line); - bool isVariableRule = declareLine.exactMatch(line); - - if (isRepositoryRule) { - // repository rule - state = ReadingRepository; - repo = Repository(); // clear - repo.name = repoLine.cap(1); - repo.lineNumber = lineNumber; - repo.filename = filename; - } else if (isMatchRule) { - // match rule - state = ReadingMatch; - match = Match(); - match.rx = QRegExp(matchLine.cap(1), Qt::CaseSensitive, QRegExp::RegExp2); - if( !match.rx.isValid() ) - qFatal("Malformed regular expression '%s' in file:'%s':%d, Error: %s", - qPrintable(matchLine.cap(1)), qPrintable(filename), lineNumber, - qPrintable(match.rx.errorString())); - match.lineNumber = lineNumber; - match.filename = filename; - } else if (isVariableRule) { - QString variable = declareLine.cap(1); - QString value = declareLine.cap(2); - variables.insert(variable, value); - } else { - qFatal("Malformed line in rules file: line %d: %s", - lineNumber, qPrintable(origLine)); + bool isRepositoryRule = repoLine.exactMatch(line); + bool isMatchRule = matchLine.exactMatch(line); + bool isVariableRule = declareLine.exactMatch(line); + + if (isRepositoryRule) { + // repository rule + state = ReadingRepository; + repo = Repository(); // clear + repo.name = repoLine.cap(1); + repo.lineNumber = lineNumber; + repo.filename = filename; + } else if (isMatchRule) { + // match rule + state = ReadingMatch; + match = Match(); + match.rx = QRegExp(matchLine.cap(1), Qt::CaseSensitive, QRegExp::RegExp2); + if( !match.rx.isValid() ) + qFatal("Malformed regular expression '%s' in file:'%s':%d, Error: %s", + qPrintable(matchLine.cap(1)), qPrintable(filename), lineNumber, + qPrintable(match.rx.errorString())); + match.lineNumber = lineNumber; + match.filename = filename; + } else if (isVariableRule) { + QString variable = declareLine.cap(1); + QString value = declareLine.cap(2); + variables.insert(variable, value); + } else { + qFatal("Malformed line in rules file: line %d: %s", + lineNumber, qPrintable(origLine)); + } } } } -- cgit v1.2.1