aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ruleparser.cpp60
-rw-r--r--src/ruleparser.h11
-rw-r--r--src/svn.cpp6
3 files changed, 77 insertions, 0 deletions
diff --git a/src/ruleparser.cpp b/src/ruleparser.cpp
index eb309bf..8cd71a6 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,9 @@ 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 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);
@@ -175,6 +219,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..26dfa72 100644
--- a/src/ruleparser.h
+++ b/src/ruleparser.h
@@ -57,9 +57,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 +93,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) {