template<typename T> static void writeVar(libconfig::Setting& setting, const char* key, T val) { //info("writeVal %s", key); const char* sep = strchr(key, '.'); if (sep) { assert(*sep == '.'); uint32_t plen = (size_t)(sep-key); char prefix[plen+1]; strncpy(prefix, key, plen); prefix[plen] = 0; // libconfig strdups all passed strings, so it's fine that prefix is local. if (!setting.exists(prefix)) { try { setting.add((const char*)prefix, SType::TypeGroup); } catch (libconfig::SettingNameException sne) { panic("libconfig error adding group setting %s", prefix); } } libconfig::Setting& child = setting[(const char*)prefix]; writeVar(child, sep+1, val); } else { if (!setting.exists(key)) { try { setting.add(key, getSType<T>()) = val; } catch (libconfig::SettingNameException sne) { panic("libconfig error adding leaf setting %s", key); } } else { //If this panics, what the hell are you doing in the code? Multiple reads and different defaults?? T origVal = setting[key]; if (!getEq(val, origVal)) panic("Duplicate writes to out config key %s with different values!", key); } } }
// Helper function: Add "*"-prefixed vars, which are used by our scripts but not zsim, to outCfg // Returns number of copied vars static uint32_t copyNonSimVars(libconfig::Setting& s1, libconfig::Setting& s2, std::string prefix) { uint32_t copied = 0; for (uint32_t i = 0; i < (uint32_t)s1.getLength(); i++) { const char* name = s1[i].getName(); if (name[0] == '*') { if (s2.exists(name)) panic("Setting %s was read, should be private", (prefix + name).c_str()); // This could be as simple as: //s2.add(s1[i].getType()) = s1[i]; // However, because Setting kinda sucks, we need to go type by type: libconfig::Setting& ns = s2.add(name, s1[i].getType()); if (libconfig::Setting::Type::TypeInt == s1[i].getType()) ns = (int) s1[i]; else if (libconfig::Setting::Type::TypeInt64 == s1[i].getType()) ns = (lc_int64) s1[i]; else if (libconfig::Setting::Type::TypeBoolean == s1[i].getType()) ns = (bool) s1[i]; else if (libconfig::Setting::Type::TypeString == s1[i].getType()) ns = (const char*) s1[i]; else panic("Unknown type for priv setting %s, cannot copy", (prefix + name).c_str()); copied++; } if (s1[i].isGroup() && s2.exists(name)) { copied += copyNonSimVars(s1[i], s2[name], prefix + name + "."); } } return copied; }