| 218 | }; |
| 219 | |
| 220 | Rv<ActiveType> |
| 221 | Config::validate(Extractor::Spec &spec) |
| 222 | { |
| 223 | if (spec._name.empty()) { |
| 224 | return Errata(S_ERROR, R"(Extractor name required but not found.)"); |
| 225 | } |
| 226 | |
| 227 | if (spec._idx < 0) { |
| 228 | auto name = TextView{spec._name}; |
| 229 | auto &&[arg, arg_errata]{parse_arg(name)}; |
| 230 | if (!arg_errata.is_ok()) { |
| 231 | return std::move(arg_errata); |
| 232 | } |
| 233 | |
| 234 | Extractor *ex = nullptr; |
| 235 | if (_local_extractors) { |
| 236 | if (auto spot = _local_extractors->find(name); spot != _local_extractors->end()) { |
| 237 | ex = spot->second; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | if (nullptr == ex) { |
| 242 | ex = Extractor::find(name); |
| 243 | } |
| 244 | |
| 245 | if (nullptr != ex) { |
| 246 | spec._exf = ex; |
| 247 | spec._name = this->localize(name); |
| 248 | spec._ext = this->localize(spec._ext); |
| 249 | auto &&[vt, errata]{ex->validate(*this, spec, arg)}; |
| 250 | if (!errata.is_ok()) { |
| 251 | return std::move(errata); |
| 252 | } |
| 253 | return vt; |
| 254 | } |
| 255 | return Errata(S_ERROR, R"(Extractor "{}" not found.)", name); |
| 256 | } |
| 257 | return {STRING}; // non-negative index => capture group => always a string |
| 258 | } |
| 259 | |
| 260 | Rv<Expr> |
| 261 | Config::parse_unquoted_expr(swoc::TextView const &text) |