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+
7173FxMap::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