Skip to content

Commit 7e5b760

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 6713e78 commit 7e5b760

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
}
@@ -390,6 +390,9 @@ void Label::parse(const std::string& line, std::vector<std::string>& lineTokens,
390390
parse(line, lineTokens, parse_state, n_, v_, new_v_);
391391
}
392392

393+
#define LABEL_PARSE_NEW_STRATEGY // instead of, LABEL_PARSE_OLD_STRATEGY
394+
395+
#if defined(LABEL_PARSE_OLD_STRATEGY)
393396
void Label::parse(const std::string& line,
394397
std::vector<std::string>& lineTokens,
395398
bool parse_state,
@@ -438,7 +441,7 @@ void Label::parse(const std::string& line,
438441

439442
// state
440443
if (parse_state) {
441-
// label name "value" # "new value"
444+
// label name "value" # "new value"
442445
bool comment_fnd = false;
443446
size_t first_quote_after_comment = 0;
444447
size_t last_quote_after_comment = 0;
@@ -467,6 +470,49 @@ void Label::parse(const std::string& line,
467470
}
468471
}
469472
}
473+
#elif defined(LABEL_PARSE_NEW_STRATEGY)
474+
void Label::parse(const std::string& line,
475+
[[maybe_unused]] std::vector<std::string>& unused,
476+
bool parse_state,
477+
std::string& the_name,
478+
std::string& the_default_value,
479+
std::string& the_actual_value) {
480+
481+
std::vector<std::string_view> tokens = ecf::algorithm::tokenize_quotation(line);
482+
483+
if (tokens.size() < 3) {
484+
throw std::runtime_error("Label::parse: Invalid label :" + line);
485+
}
486+
487+
the_name = tokens[1];
488+
if (tokens.size() >= 3) {
489+
the_default_value = tokens[2];
490+
Str::removeQuotes(the_default_value);
491+
Str::removeSingleQuotes(the_default_value);
492+
if (the_default_value.find("\\n") != std::string::npos) {
493+
Str::replaceall(the_default_value, "\\n", "\n");
494+
}
495+
}
496+
497+
if (parse_state) {
498+
if (tokens.size() >= 5) {
499+
500+
if (tokens[4] == "#") {
501+
throw std::runtime_error("Label::parse: Unexpected state separator :" + line);
502+
}
503+
504+
the_actual_value = tokens[4];
505+
Str::removeQuotes(the_actual_value);
506+
Str::removeSingleQuotes(the_actual_value);
507+
if (the_actual_value.find("\\n") != std::string::npos) {
508+
Str::replaceall(the_actual_value, "\\n", "\n");
509+
}
510+
}
511+
}
512+
}
513+
#else
514+
#error "#define either LABEL_PARSE_OLD_STRATEGY or LABEL_PARSE_NEW_STRATEGY"
515+
#endif
470516

471517
template <class Archive>
472518
void Label::serialize(Archive& ar) {

0 commit comments

Comments
 (0)