Skip to content

Commit 1071e67

Browse files
committed
Correct parsing of Label attribute
The changes propose a better (but still not flawless) approach to parsing the Label attribute. Re ECFLOW-1890 Explanation of the Problem: A Label attribute is stores in the .def file in the following format: > label <name> "<value>" # "<new-value>" with the double quotes and hash symbol used as separators. This approach works fine while <value> or <new-value> do not contain any double quotes or hash symbols. When the values contain double quotes or hash symbols, the parsing becomes ambiguous. In the following example > label <name> "value X " # " and Y " # " value Z" Should the parser consider <value> = "value X " # " and Y " <new-value> = " value Z" or <value> = "value X " <new-value> " and Y " # " value Z" ? Both might be correct depending on the user's intents! This becomes even more convoluted when the value contains double quotes, as in this example: label <name> " "value X" " # " # " # " "value Y" "
1 parent 34fdfba commit 1071e67

File tree

4 files changed

+493
-3
lines changed

4 files changed

+493
-3
lines changed

libs/attribute/src/ecflow/attribute/NodeAttr.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Event::Event(int number, const std::string& eventName, bool iv, bool check_name)
5050
v_(iv),
5151
iv_(iv) {
5252
if (!eventName.empty() && check_name) {
53-
string msg;
53+
std::string msg;
5454
if (!Str::valid_name(eventName, msg)) {
5555
throw std::runtime_error("Event::Event: Invalid event name : " + msg);
5656
}
@@ -83,7 +83,7 @@ Event::Event(const std::string& eventName, bool iv) : n_(eventName), v_(iv), iv_
8383
}
8484
}
8585

86-
string msg;
86+
std::string msg;
8787
if (!Str::valid_name(eventName, msg)) {
8888
throw std::runtime_error("Event::Event: Invalid event name : " + msg);
8989
}
@@ -386,6 +386,9 @@ void Label::parse(const std::string& line, std::vector<std::string>& lineTokens,
386386
parse(line, lineTokens, parse_state, n_, v_, new_v_);
387387
}
388388

389+
#define LABEL_PARSE_NEW_STRATEGY // instead of, LABEL_PARSE_OLD_STRATEGY
390+
391+
#if defined(LABEL_PARSE_OLD_STRATEGY)
389392
void Label::parse(const std::string& line,
390393
std::vector<std::string>& lineTokens,
391394
bool parse_state,
@@ -431,7 +434,7 @@ void Label::parse(const std::string& line,
431434

432435
// state
433436
if (parse_state) {
434-
// label name "value" # "new value"
437+
// label name "value" # "new value"
435438
bool comment_fnd = false;
436439
size_t first_quote_after_comment = 0;
437440
size_t last_quote_after_comment = 0;
@@ -459,6 +462,49 @@ void Label::parse(const std::string& line,
459462
}
460463
}
461464
}
465+
#elif defined(LABEL_PARSE_NEW_STRATEGY)
466+
void Label::parse(const std::string& line,
467+
[[maybe_unused]] std::vector<std::string>& unused,
468+
bool parse_state,
469+
std::string& the_name,
470+
std::string& the_default_value,
471+
std::string& the_actual_value) {
472+
473+
std::vector<std::string_view> tokens = ecf::algorithm::tokenize_quotation(line);
474+
475+
if (tokens.size() < 3) {
476+
throw std::runtime_error("Label::parse: Invalid label :" + line);
477+
}
478+
479+
the_name = tokens[1];
480+
if (tokens.size() >= 3) {
481+
the_default_value = tokens[2];
482+
Str::removeQuotes(the_default_value);
483+
Str::removeSingleQuotes(the_default_value);
484+
if (the_default_value.find("\\n") != std::string::npos) {
485+
Str::replaceall(the_default_value, "\\n", "\n");
486+
}
487+
}
488+
489+
if (parse_state) {
490+
if (tokens.size() >= 5) {
491+
492+
if (tokens[4] == "#") {
493+
throw std::runtime_error("Label::parse: Unexpected state separator :" + line);
494+
}
495+
496+
the_actual_value = tokens[4];
497+
Str::removeQuotes(the_actual_value);
498+
Str::removeSingleQuotes(the_actual_value);
499+
if (the_actual_value.find("\\n") != std::string::npos) {
500+
Str::replaceall(the_actual_value, "\\n", "\n");
501+
}
502+
}
503+
}
504+
}
505+
#else
506+
#error "#define either LABEL_PARSE_OLD_STRATEGY or LABEL_PARSE_NEW_STRATEGY"
507+
#endif
462508

463509
template <class Archive>
464510
void Label::serialize(Archive& ar) {

0 commit comments

Comments
 (0)