blob: 29f2eb5671660e8a62be8d6d5a2619f1119a2bf1 [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.
#ifndef DEVTOOLS_GOMA_CLIENT_ENV_FLAGS_H_
#define DEVTOOLS_GOMA_CLIENT_ENV_FLAGS_H_
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sstream>
void RegisterEnvFlag(const char* name);
void RegisterEnvAutoConfFlag(const char* name,
std::string (*GetConfiguredValue)(),
void (*SetConfiguredValue)());
void CheckFlagNames(const char** envp);
void AutoConfigureFlags(const char** envp);
void DumpEnvFlag(std::ostringstream* ss);
#ifdef _WIN32
// MSVS warns the usage of 'getenv'.
std::string GOMA_EnvToString(const char* envname, const char* dflt);
bool GOMA_EnvToBool(const char* envname, bool dflt);
int GOMA_EnvToInt(const char* envname, int dflt);
#else
// These macros (could be functions, but I don't want to bother with a .cc
// file), make it easier to initialize flags from the environment.
#define GOMA_EnvToString(envname, dflt) \
(!getenv(envname) ? (dflt) : getenv(envname))
#define GOMA_EnvToBool(envname, dflt) \
(!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL)
#define GOMA_EnvToInt(envname, dflt) \
(!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10))
#endif
#define GOMA_REGISTER_FLAG_NAME(name) \
struct RegisterEnvFlag##name { \
explicit RegisterEnvFlag##name() { \
RegisterEnvFlag(#name); \
} \
}; \
RegisterEnvFlag##name g_register_env_flag_##name
#define GOMA_REGISTER_AUTOCONF_FLAG_NAME(name, func) \
struct RegisterEnvAutoConfFlagSetter##name { \
static void SetConfiguredValue() { \
FLAGS_ ## name = func(); \
} \
/* Since we would like to use this kind of method for all types */ \
/* (e.g. int, bool, etc.), we chose to return string */ \
static std::string GetConfiguredValue() { \
std::ostringstream ss; \
ss << func(); \
return ss.str(); \
} \
}; \
struct RegisterEnvAutoConfFlag##name { \
RegisterEnvAutoConfFlag##name() { \
RegisterEnvAutoConfFlag( \
#name, \
RegisterEnvAutoConfFlagSetter##name::GetConfiguredValue, \
RegisterEnvAutoConfFlagSetter##name::SetConfiguredValue); \
} \
}; \
RegisterEnvAutoConfFlag##name g_register_autoconf_flag_##name; \
#define GOMA_DECLARE_VARIABLE(type, name, tn) \
namespace FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_##tn##_instead { \
extern type FLAGS_##name; \
} \
using FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_##tn##_instead::FLAGS_##name
#define GOMA_DEFINE_VARIABLE(type, name, value, meaning, tn) \
namespace FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_##tn##_instead { \
type FLAGS_##name(value); \
} \
using FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_##tn##_instead::FLAGS_##name;\
GOMA_REGISTER_FLAG_NAME(name)
// bool specialization
#define GOMA_DECLARE_bool(name) \
GOMA_DECLARE_VARIABLE(bool, name, bool)
#define GOMA_DEFINE_bool(name, value, meaning) \
GOMA_DEFINE_VARIABLE(bool, name, GOMA_EnvToBool("GOMA_" #name, value), \
meaning, bool)
typedef int int32;
// int32 specialization
#define GOMA_DECLARE_int32(name) \
GOMA_DECLARE_VARIABLE(int32, name, int32)
#define GOMA_DEFINE_int32(name, value, meaning) \
GOMA_DEFINE_VARIABLE(int32, name, GOMA_EnvToInt("GOMA_" #name, value), \
meaning, int32)
#define GOMA_DEFINE_AUTOCONF_int32(name, func, meaning) \
GOMA_DEFINE_int32(name, 0, meaning); \
GOMA_REGISTER_AUTOCONF_FLAG_NAME(name, func)
// Special case for string, because we have to specify the namespace
// std::string, which doesn't play nicely with our FLAG__namespace hackery.
#define GOMA_DECLARE_string(name) \
namespace FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_string_instead { \
extern std::string FLAGS_##name; \
} \
using FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_string_instead::FLAGS_##name
#define GOMA_DEFINE_string(name, value, meaning) \
namespace FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_string_instead { \
std::string FLAGS_##name(GOMA_EnvToString("GOMA_" #name, value)); \
} \
using FLAG__namespace_do_not_use_directly_use_GOMA_DECLARE_string_instead::FLAGS_##name; \
GOMA_REGISTER_FLAG_NAME(name)
#endif // DEVTOOLS_GOMA_CLIENT_ENV_FLAGS_H_