blob: 153c7125a3753430856edc5977da92eea2111bbe [file] [log] [blame]
// Copyright 2010 The Goma 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 "env_flags.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <string>
#include <sstream>
using std::string;
struct GomaAutoConfigurer {
GomaAutoConfigurer(string (*GetConfiguredValue)(void),
void (*SetConfiguredValue)(void))
: GetConfiguredValue(GetConfiguredValue),
SetConfiguredValue(SetConfiguredValue) {}
string (*GetConfiguredValue)(void);
void (*SetConfiguredValue)(void);
};
static std::set<string>* g_env_flag_names;
typedef std::map<string, GomaAutoConfigurer> AutoConfigurerMap;
static AutoConfigurerMap* g_autoconfigurers;
void RegisterEnvFlag(const char* name) {
if (!g_env_flag_names) {
g_env_flag_names = new std::set<string>;
}
if (!g_env_flag_names->insert(name).second) {
fprintf(stderr, "%s has registered twice\n", name);
exit(1);
}
}
void RegisterEnvAutoConfFlag(const char* name,
string (*GetConfiguredValue)(),
void (*SetConfiguredValue)()) {
if (!g_autoconfigurers) {
g_autoconfigurers = new AutoConfigurerMap;
}
GomaAutoConfigurer configurer(GetConfiguredValue, SetConfiguredValue);
if (!g_autoconfigurers->insert(make_pair(string(name), configurer)).second) {
fprintf(stderr, "%s has registered twice for autoconf\n", name);
exit(1);
}
}
void CheckFlagNames(const char** envp) {
bool ok = true;
for (int i = 0; envp[i]; i++) {
if (strncmp(envp[i], "GOMA_", 5)) {
continue;
}
const char* name_end = strchr(envp[i], '=');
assert(name_end);
const string name(envp[i] + 5, name_end - envp[i] - 5);
if (!g_env_flag_names->count(name)) {
fprintf(stderr, "%s: unknown GOMA_ parameter\n", envp[i]);
ok = false;
}
}
if (!ok) {
exit(1);
}
}
void AutoConfigureFlags(const char** envp) {
std::set<string> goma_set_params;
for (int i = 0; envp[i]; i++) {
if (strncmp(envp[i], "GOMA_", 5))
continue;
const char* name_end = strchr(envp[i], '=');
assert(name_end);
const string name(envp[i] + 5, name_end - envp[i] - 5);
goma_set_params.insert(name);
}
for (const auto& it : *g_autoconfigurers) {
if (goma_set_params.count(it.first))
continue;
it.second.SetConfiguredValue();
}
}
void DumpEnvFlag(std::ostringstream* ss) {
if (g_env_flag_names == nullptr)
return;
for (const auto& iter : *g_env_flag_names) {
const string name = "GOMA_" + iter;
char* v = nullptr;
#ifdef _WIN32
_dupenv_s(&v, nullptr, name.c_str());
#else
v = getenv(name.c_str());
#endif
if (v != nullptr) {
(*ss) << name << "=" << v << std::endl;
} else if (g_autoconfigurers->count(iter)) {
(*ss) << name << "="
<< g_autoconfigurers->find(iter)->second.GetConfiguredValue()
<< " (auto configured)" << std::endl;
}
}
}
#ifdef _WIN32
string GOMA_EnvToString(const char* envname, const char* dflt) {
char* env;
if (_dupenv_s(&env, nullptr, envname) == 0 && env != nullptr) {
string value = env;
free(env);
return value;
} else {
return dflt;
}
}
bool GOMA_EnvToBool(const char* envname, bool dflt) {
char* env;
if (_dupenv_s(&env, nullptr, envname) == 0 && env != nullptr) {
bool value = (memchr("tTyY1\0", env[0], 6) != nullptr);
free(env);
return value;
} else {
return dflt;
}
}
int GOMA_EnvToInt(const char* envname, int dflt) {
char* env;
if (_dupenv_s(&env, nullptr, envname) == 0 && env != nullptr) {
int value = strtol(env, nullptr, 10);
free(env);
return value;
} else {
return dflt;
}
}
#endif