summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2012-06-08 12:45:30 -0700
committerSage Weil <sage@inktank.com>2012-06-12 11:50:54 -0700
commitd422bf159d59345eb96483169de80bd5dc9996fc (patch)
treecbada0f29783329bcee47887421d12cd0b14251a /src/common
parent500c72e8eed3f3b35e62b74952db340be69caaac (diff)
downloadceph-d422bf159d59345eb96483169de80bd5dc9996fc.tar.gz
config: expand any config variable in config
This is currently broken wrt 'foo' vs 'foo_bar', but otherwise works. Signed-off-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'src/common')
-rw-r--r--src/common/config.cc60
1 files changed, 49 insertions, 11 deletions
diff --git a/src/common/config.cc b/src/common/config.cc
index 77843388922..fcbf61a53bf 100644
--- a/src/common/config.cc
+++ b/src/common/config.cc
@@ -875,21 +875,30 @@ void md_config_t::expand_all_meta()
}
}
-bool md_config_t::expand_meta(std::string &val) const
+bool md_config_t::expand_meta(std::string &origval) const
{
assert(lock.is_locked());
bool found_meta = false;
+
+ set<string> resolved;
+
+ string::size_type sz;
+ string val = origval;
+
+ restart:
+ sz = val.size();
string out;
- string::size_type sz = val.size();
out.reserve(sz);
+
for (string::size_type s = 0; s < sz; ) {
if (val[s] != '$') {
out += val[s++];
continue;
}
string::size_type rem = sz - (s + 1);
- int i;
- for (i = 0; i < NUM_CONF_METAVARIABLES; ++i) {
+
+ // special metavariable?
+ for (int i = 0; i < NUM_CONF_METAVARIABLES; ++i) {
size_t clen = strlen(CONF_METAVARIABLES[i]);
if (rem < clen)
continue;
@@ -910,14 +919,43 @@ bool md_config_t::expand_meta(std::string &val) const
else
assert(0); // unreachable
found_meta = true;
- break;
- }
- if (i == NUM_CONF_METAVARIABLES)
- out += val[s++];
- else
s += strlen(CONF_METAVARIABLES[i]) + 1;
- }
- val = out;
+ out += val.substr(s);
+ val = out;
+ goto restart;
+ }
+
+ // config option?
+ for (int i = 0; i < NUM_CONFIG_OPTIONS; i++) {
+ config_option *opt = &config_optionsp[i];
+ size_t clen = strlen(opt->name);
+ if (rem < clen)
+ continue;
+ if (strncmp(val.c_str() + s + 1, opt->name, clen))
+ continue;
+
+ // avoid loops
+ if (resolved.count(opt->name))
+ continue; // loop; skip
+ resolved.insert(opt->name);
+
+ found_meta = true;
+ char *vv = NULL;
+ _get_val(opt->name, &vv, -1);
+ out += vv;
+ s += strlen(opt->name) + 1;
+ out += val.substr(s);
+ //cout << "val '" << val << "' s " << s << " out '" << out << "' after sub " << opt->name << " -> " << vv << std::endl;
+ val = out;
+ free(vv);
+ goto restart;
+ }
+
+ // pass it thru
+ out += val[s++];
+ }
+ //cout << "done '" << origval << "' -> '" << out << "'" << std::endl;
+ origval = out;
return found_meta;
}