diff options
-rw-r--r-- | src/repository.cpp | 9 | ||||
-rw-r--r-- | src/ruleparser.cpp | 64 | ||||
-rw-r--r-- | src/ruleparser.h | 12 | ||||
-rw-r--r-- | src/svn.cpp | 6 |
4 files changed, 91 insertions, 0 deletions
diff --git a/src/repository.cpp b/src/repository.cpp index 796604a..04e9bec 100644 --- a/src/repository.cpp +++ b/src/repository.cpp @@ -84,6 +84,15 @@ Repository::Repository(const Rules::Repository &rule) init.setWorkingDirectory(name); init.start("git", QStringList() << "--bare" << "init"); init.waitForFinished(-1); + // Write description + if (!rule.description.isEmpty()) { + QFile fDesc(QDir(name).filePath("description")); + if (fDesc.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { + fDesc.write(rule.description.toUtf8()); + fDesc.putChar('\n'); + fDesc.close(); + } + } { QFile marks(name + "/" + marksFileName(name)); marks.open(QIODevice::WriteOnly); diff --git a/src/ruleparser.cpp b/src/ruleparser.cpp index eb309bf..ebdba4a 100644 --- a/src/ruleparser.cpp +++ b/src/ruleparser.cpp @@ -77,6 +77,48 @@ const QList<Rules::Match> Rules::matchRules() const return m_matchRules; } +Rules::Match::Substitution Rules::parseSubstitution(const QString &string) +{ + if (string.at(0) != 's' || string.length() < 5) + return Match::Substitution(); + + const QChar sep = string.at(1); + + if (string.at(string.length() - 1) != sep) + return Match::Substitution(); + + int i = 2, end = 0; + Match::Substitution subst; + + // Separator might have been escaped with a backslash + while (i > end) { + int backslashCount = 0; + if ((end = string.indexOf(sep, i)) > -1) { + for (i = end - 1; i >= 2; i--) { + if (string.at(i) == '\\') + backslashCount++; + else + break; + } + } else { + return Match::Substitution(); // error + } + + if (backslashCount % 2 != 0) { + // Separator was escaped. Search for another one + i = end + 1; + } + } + + // Found the end of the pattern + subst.pattern = QRegExp(string.mid(2, end - 2)); + if (!subst.pattern.isValid()) + return Match::Substitution(); // error + subst.replacement = string.mid(end + 1, string.length() - 1 - end - 1); + + return subst; +} + void Rules::load() { load(filename); @@ -93,7 +135,10 @@ void Rules::load(const QString &filename) QRegExp matchLine("match\\s+(.*)", Qt::CaseInsensitive); QRegExp matchActionLine("action\\s+(\\w+)", Qt::CaseInsensitive); QRegExp matchRepoLine("repository\\s+(\\S+)", Qt::CaseInsensitive); + QRegExp matchDescLine("description\\s+(.+)$", Qt::CaseInsensitive); + QRegExp matchRepoSubstLine("substitute repository\\s+(.+)$", Qt::CaseInsensitive); QRegExp matchBranchLine("branch\\s+(\\S+)", Qt::CaseInsensitive); + QRegExp matchBranchSubstLine("substitute branch\\s+(.+)$", Qt::CaseInsensitive); QRegExp matchRevLine("(min|max) revision (\\d+)", Qt::CaseInsensitive); QRegExp matchAnnotateLine("annotated\\s+(\\S+)", Qt::CaseInsensitive); QRegExp matchPrefixLine("prefix\\s+(\\S+)", Qt::CaseInsensitive); @@ -152,6 +197,9 @@ void Rules::load(const QString &filename) repo.branches += branch; continue; + } else if (matchDescLine.exactMatch(line)) { + repo.description = matchDescLine.cap(1); + continue; } else if (matchRepoLine.exactMatch(line)) { repo.forwardTo = matchRepoLine.cap(1); continue; @@ -175,6 +223,22 @@ void Rules::load(const QString &filename) } else if (matchBranchLine.exactMatch(line)) { match.branch = matchBranchLine.cap(1); continue; + } else if (matchRepoSubstLine.exactMatch(line)) { + Match::Substitution subst = parseSubstitution(matchRepoSubstLine.cap(1)); + if (!subst.isValid()) { + qFatal("Malformed substitution in rules file: line %d: %s", + lineNumber, qPrintable(origLine)); + } + match.repo_substs += subst; + continue; + } else if (matchBranchSubstLine.exactMatch(line)) { + Match::Substitution subst = parseSubstitution(matchBranchSubstLine.cap(1)); + if (!subst.isValid()) { + qFatal("Malformed substitution in rules file: line %d: %s", + lineNumber, qPrintable(origLine)); + } + match.branch_substs += subst; + continue; } else if (matchRevLine.exactMatch(line)) { if (matchRevLine.cap(1) == "min") match.minRevision = matchRevLine.cap(2).toInt(); diff --git a/src/ruleparser.h b/src/ruleparser.h index 9d21937..9878735 100644 --- a/src/ruleparser.h +++ b/src/ruleparser.h @@ -43,6 +43,7 @@ public: QString name; QList<Branch> branches; + QString description; QString forwardTo; QString prefix; @@ -57,9 +58,19 @@ public: struct Match : Rule { + struct Substitution { + QRegExp pattern; + QString replacement; + + bool isValid() { return !pattern.isEmpty(); } + QString& apply(QString &string) { return string.replace(pattern, replacement); } + }; + QRegExp rx; QString repository; + QList<Substitution> repo_substs; QString branch; + QList<Substitution> branch_substs; QString prefix; int minRevision; int maxRevision; @@ -83,6 +94,7 @@ public: const QList<Repository> repositories() const; const QList<Match> matchRules() const; + Match::Substitution parseSubstitution(const QString &string); void load(); private: diff --git a/src/svn.cpp b/src/svn.cpp index 09495be..c103728 100644 --- a/src/svn.cpp +++ b/src/svn.cpp @@ -214,11 +214,17 @@ static void splitPathName(const Rules::Match &rule, const QString &pathName, QSt if (repository_p) { *repository_p = svnprefix; repository_p->replace(rule.rx, rule.repository); + foreach (Rules::Match::Substitution subst, rule.repo_substs) { + subst.apply(*repository_p); + } } if (branch_p) { *branch_p = svnprefix; branch_p->replace(rule.rx, rule.branch); + foreach (Rules::Match::Substitution subst, rule.branch_substs) { + subst.apply(*branch_p); + } } if (path_p) { |