blob: 0a460cc7fd39e74307396a20024f682af8a444cd [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <iostream>
#include <regex>
#include <sstream>
#include <fidl/template_string.h>
namespace fidl {
std::string TemplateString::Substitute(Substitutions substitutions, bool remove_unmatched) const {
std::ostringstream os;
std::smatch match;
// function-local static pointer to non-trivially-destructible type
// is allowed by styleguide
static const auto kRegexReplaceable =
new std::regex(R"((.?)((?:\$\{([A-Z_][A-Z0-9_]*)\})|(?:\$([A-Z_][A-Z0-9_]*))))");
int match_index = 1;
static const int kPrecedingChar = match_index++;
static const int kVarToken = match_index++;
static const int kBracedVar = match_index++;
static const int kUnbracedVar = match_index++;
auto str = str_;
while (std::regex_search(str, match, *kRegexReplaceable)) {
os << match.prefix();
if (match[kPrecedingChar] == "$") {
os << std::string(match[0]).substr(1); // escaped "$"
} else {
if (match[kPrecedingChar].matched) {
os << match[kPrecedingChar];
}
std::string replaceable = match[kBracedVar].matched ? match[kBracedVar] : match[kUnbracedVar];
if (substitutions.find(replaceable) != substitutions.end()) {
os << substitutions[replaceable];
} else if (!remove_unmatched) {
os << match[kVarToken];
}
}
str = match.suffix().str();
}
os << str;
return os.str();
}
} // namespace fidl