Merge remote-tracking branch 'origin/topic/jsiwek/improve-command-line-option-redefs'

* origin/topic/jsiwek/improve-command-line-option-redefs:
  Integrate review feedback: improve command-line option redef parsing
  Fix several issues with command-line option redefs
This commit is contained in:
Johanna Amann 2020-06-26 16:25:34 +00:00
commit eb1a408b6a
8 changed files with 95 additions and 22 deletions

View file

@ -978,40 +978,54 @@ int yywrap()
return 0;
// Add redef statements for any X=Y command line parameters.
if ( params.size() > 0 )
if ( ! params.empty() )
{
std::string policy;
for ( unsigned int i = 0; i < params.size(); ++i )
for ( const auto& pi : params )
{
char* param = copy_string(params[i].c_str());
char* eq = strchr(param, '=');
char* val = eq + 1;
auto p = pi.data();
*eq = '\0';
while ( isalnum(*p) || *p == '_' || *p == ':' ) ++p;
if ( strlen(val) == 0 )
auto first_non_id_char = p - pi.data();
auto eq_idx = pi.find('=', first_non_id_char);
// Omit the '=' from op just to make fmt string below clearer.
auto op = pi.substr(first_non_id_char, eq_idx - first_non_id_char);
auto id_str = pi.substr(0, first_non_id_char);
auto val_str = pi.substr(eq_idx + 1);
const auto& id = zeek::id::find(id_str);
if ( ! id )
{
delete [] param;
reporter->Error("unknown identifier '%s' in command-line options",
id_str.data());
continue;
}
// Try to find the type of the param, and interpret
// the value intelligently for that type. (So far,
// that just means quoting the value if it's a
// string type.) If no type is found, the value
// is left unchanged.
std::string opt_quote; // no optional quote by default
const auto& param_id = lookup_ID(param, GLOBAL_MODULE_NAME);
Val* v = param_id ? param_id->GetVal().get() : nullptr;
// Interpret the value based on the identifier's type.
// So far, that just means quoting the value for string types.
const auto& type = id->GetType();
if ( v && v->GetType() && v->GetType()->Tag() == zeek::TYPE_STRING )
opt_quote = "\""; // use quotes
if ( ! type )
{
reporter->Error("can't set value of '%s' in command-line "
"options: unknown type", id_str.data());
continue;
}
policy += std::string("redef ") + param + "="
+ opt_quote + val + opt_quote + ";";
if ( val_str.empty() && ! zeek::IsString(type->Tag()) )
{
reporter->Error("must assign non-empty value to '%s' in "
"command-line options", id_str.data());
continue;
}
delete [] param;
auto use_quotes = zeek::IsString(type->Tag());
auto fmt_str = use_quotes ? "redef %s %s= \"%s\";"
: "redef %s %s= %s;";
policy += fmt(fmt_str, id_str.data(), op.data(), val_str.data());
}
params.clear();