Skip to content

Commit 8063a77

Browse files
committed
dev: FxMap: Refactor one monolithic regular expression into several smaller ones to make extending the file format easier.
1 parent d092e5b commit 8063a77

File tree

1 file changed

+36
-43
lines changed

1 file changed

+36
-43
lines changed

src/fxMap.cpp

Lines changed: 36 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,14 @@
1818
#include "fxMap.h"
1919
#include "reaKontrol.h"
2020

21-
static const std::regex RE_LINE(
22-
// Ignore any space at the start of a line.
23-
"^\\s*"
24-
"(?:"
25-
// Group 1: the line may be the map name, ending with a colon.
26-
"([^#]+):"
27-
// Groups 2 and 3: or a parameter number, optionally followed by space and
28-
// a name.
29-
"|(\\d+)(?:\\s+([^#]+))?"
30-
// Group 4: or a page break indicator.
31-
"|(---)"
32-
// Group 5: or a section name in square brackets.
33-
"|\\[([^#]+)\\]"
34-
")?"
35-
// This may be followed by optional space and an optional comment starting
36-
// with "#".
37-
"\\s*(?:#.*)?$"
38-
);
21+
// Strip leading and trailing space, as well as comments.
22+
static const std::regex RE_STRIP(R"(^\s+|\s*#.*$|\s+$)");
23+
// The map name, ending with a colon.
24+
static const std::regex RE_MAP_NAME("(.*):");
25+
// A parameter number, optionally followed by space and a name.
26+
static const std::regex RE_PARAM(R"((\d+)(?:\s+(.+))?)");
27+
// A section name in square brackets.
28+
static const std::regex RE_SECTION(R"(\[(.+)\])");
3929

4030
// The generateMapFileForSelectedFx action can't access the FxMap instance,
4131
// so we cache the last selected FX here.
@@ -68,6 +58,18 @@ static std::filesystem::path getFxMapFileName(MediaTrack* track, int fx) {
6858
return path;
6959
}
7060

61+
static std::string getLine(std::ifstream& input) {
62+
std::string line;
63+
while (std::getline(input, line)) {
64+
line = std::regex_replace(line, RE_STRIP, "");
65+
if (!line.empty()) {
66+
// Not a blank line, only space or a comment.
67+
return line;
68+
}
69+
}
70+
return "";
71+
}
72+
7173
FxMap::FxMap(MediaTrack* track, int fx) : _track(track), _fx(fx) {
7274
lastTrack = track;
7375
lastFx = fx;
@@ -81,15 +83,10 @@ FxMap::FxMap(MediaTrack* track, int fx) : _track(track), _fx(fx) {
8183
return;
8284
}
8385
log("loading FX map " << path);
84-
std::string line;
85-
while (std::getline(input, line)) {
86+
for (std::string line = getLine(input); !line.empty(); line = getLine(input)) {
8687
std::smatch m;
87-
std::regex_search(line, m, RE_LINE);
88-
if (m.empty()) {
89-
log("invalid FX map line: " << line);
90-
continue;
91-
}
92-
if (!m.str(1).empty()) {
88+
std::regex_search(line, m, RE_MAP_NAME);
89+
if (!m.empty()) {
9390
if (!this->_mapName.empty()) {
9491
log("map name specified more than once, ignoring: " << line);
9592
continue;
@@ -98,30 +95,32 @@ FxMap::FxMap(MediaTrack* track, int fx) : _track(track), _fx(fx) {
9895
log("map name: " << this->_mapName);
9996
continue;
10097
}
101-
const std::string numStr = m.str(2);
102-
if (!numStr.empty()) {
103-
const int rp = std::atoi(numStr.c_str());
98+
std::regex_search(line, m, RE_PARAM);
99+
if (!m.empty()) {
100+
const int rp = std::atoi(m.str(1).c_str());
104101
const int mp = this->_reaperParams.size();
105102
this->_reaperParams.push_back(rp);
106103
this->_mapParams.insert({rp, mp});
107-
const std::string paramName = m.str(3);
104+
const std::string paramName = m.str(2);
108105
if (!paramName.empty()) {
109106
this->_paramNames.insert({mp, paramName});
110107
}
111108
continue;
112109
}
113-
if (!m.str(4).empty()) {
110+
if (line == "---") {
114111
// A page break has been requested. Any remaining slots on this page
115112
// should be empty.
116113
while (this->_reaperParams.size() % BANK_NUM_SLOTS != 0) {
117114
this->_reaperParams.push_back(-1);
118115
}
119116
continue;
120117
}
121-
const std::string section = m.str(5);
122-
if (!section.empty()) {
123-
this->_sections.insert({this->_reaperParams.size(), section});
118+
std::regex_search(line, m, RE_SECTION);
119+
if (!m.empty()) {
120+
this->_sections.insert({this->_reaperParams.size(), m.str(1)});
121+
continue;
124122
}
123+
log("invalid FX map line: " << line);
125124
}
126125
log("loaded " << this->_mapParams.size() << " params from FX map");
127126
}
@@ -211,21 +210,15 @@ std::string FxMap::getMapNameFor(MediaTrack* track, int fx) {
211210
if (!input) {
212211
return getOrigName();
213212
}
214-
std::string line;
215-
while (std::getline(input, line)) {
213+
for (std::string line = getLine(input); !line.empty(); line = getLine(input)) {
216214
std::smatch m;
217-
std::regex_search(line, m, RE_LINE);
215+
std::regex_search(line, m, RE_MAP_NAME);
218216
if (m.empty()) {
219-
continue;
220-
}
221-
if (!m.str(1).empty()) {
222-
return m.str(1);
223-
}
224-
if (!m.str(2).empty() || !m.str(4).empty() || !m.str(5).empty()) {
225217
// The map name must be the first non-comment, non-blank line. If we hit
226218
// anything else, there's no map name, so don't process any further.
227219
break;
228220
}
221+
return m.str(1);
229222
}
230223
return getOrigName();
231224
}

0 commit comments

Comments
 (0)