Add methods to get env vars as an optional
This commit is contained in:
@@ -604,6 +604,7 @@ SET(COMMON_OBJS
|
||||
common/intrusive_ptr.h
|
||||
common/math_defs.h
|
||||
common/opthelpers.h
|
||||
common/strutils.cpp
|
||||
common/strutils.h
|
||||
common/threads.cpp
|
||||
common/threads.h
|
||||
|
||||
+3
-2
@@ -42,6 +42,7 @@
|
||||
#include "event.h"
|
||||
#include "inprogext.h"
|
||||
#include "opthelpers.h"
|
||||
#include "strutils.h"
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -73,8 +74,8 @@ constexpr ALchar alBSinc24Resampler[] = "23rd order Sinc";
|
||||
extern "C" AL_API const ALchar* AL_APIENTRY alsoft_get_version(void)
|
||||
START_API_FUNC
|
||||
{
|
||||
const char *spoof{getenv("ALSOFT_SPOOF_VERSION")};
|
||||
if(spoof && spoof[0] != '\0') return spoof;
|
||||
static const auto spoof = al::getenv("ALSOFT_SPOOF_VERSION");
|
||||
if(spoof) return spoof->c_str();
|
||||
return ALSOFT_VERSION;
|
||||
}
|
||||
END_API_FUNC
|
||||
|
||||
+34
-34
@@ -929,25 +929,23 @@ std::recursive_mutex ListLock;
|
||||
|
||||
void alc_initconfig(void)
|
||||
{
|
||||
const char *str{getenv("ALSOFT_LOGLEVEL")};
|
||||
if(str)
|
||||
if(auto loglevel = al::getenv("ALSOFT_LOGLEVEL"))
|
||||
{
|
||||
long lvl = strtol(str, nullptr, 0);
|
||||
long lvl = strtol(loglevel->c_str(), nullptr, 0);
|
||||
if(lvl >= NoLog && lvl <= LogRef)
|
||||
gLogLevel = static_cast<LogLevel>(lvl);
|
||||
}
|
||||
|
||||
str = getenv("ALSOFT_LOGFILE");
|
||||
if(str && str[0])
|
||||
if(auto logfile = al::getenv("ALSOFT_LOGFILE"))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::wstring wname{utf8_to_wstr(str)};
|
||||
FILE *logfile = _wfopen(wname.c_str(), L"wt");
|
||||
std::wstring wname{utf8_to_wstr(logfile->c_str())};
|
||||
FILE *logf{_wfopen(wname.c_str(), L"wt")};
|
||||
#else
|
||||
FILE *logfile = fopen(str, "wt");
|
||||
FILE *logf{fopen(logfile->c_str(), "wt")};
|
||||
#endif
|
||||
if(logfile) gLogFile = logfile;
|
||||
else ERR("Failed to open log file '%s'\n", str);
|
||||
if(logf) gLogFile = logf;
|
||||
else ERR("Failed to open log file '%s'\n", logfile->c_str());
|
||||
}
|
||||
|
||||
TRACE("Initializing library v%s-%s %s\n", ALSOFT_VERSION, ALSOFT_GIT_COMMIT_HASH,
|
||||
@@ -970,16 +968,15 @@ void alc_initconfig(void)
|
||||
}
|
||||
ReadALConfig();
|
||||
|
||||
str = getenv("__ALSOFT_SUSPEND_CONTEXT");
|
||||
if(str && *str)
|
||||
if(auto suspendmode = al::getenv("__ALSOFT_SUSPEND_CONTEXT"))
|
||||
{
|
||||
if(strcasecmp(str, "ignore") == 0)
|
||||
if(strcasecmp(suspendmode->c_str(), "ignore") == 0)
|
||||
{
|
||||
SuspendDefers = false;
|
||||
TRACE("Selected context suspend behavior, \"ignore\"\n");
|
||||
}
|
||||
else
|
||||
ERR("Unhandled context suspend behavior setting: \"%s\"\n", str);
|
||||
ERR("Unhandled context suspend behavior setting: \"%s\"\n", suspendmode->c_str());
|
||||
}
|
||||
|
||||
int capfilter{0};
|
||||
@@ -997,7 +994,7 @@ void alc_initconfig(void)
|
||||
#endif
|
||||
if(auto cpuopt = ConfigValueStr(nullptr, nullptr, "disable-cpu-exts"))
|
||||
{
|
||||
str = cpuopt->c_str();
|
||||
const char *str{cpuopt->c_str()};
|
||||
if(strcasecmp(str, "all") == 0)
|
||||
capfilter = 0;
|
||||
else
|
||||
@@ -1043,22 +1040,31 @@ void alc_initconfig(void)
|
||||
aluInit();
|
||||
aluInitMixer();
|
||||
|
||||
str = getenv("ALSOFT_TRAP_ERROR");
|
||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
||||
auto traperr = al::getenv("ALSOFT_TRAP_ERROR");
|
||||
if(traperr && (strcasecmp(traperr->c_str(), "true") == 0
|
||||
|| strtol(traperr->c_str(), nullptr, 0) == 1))
|
||||
{
|
||||
TrapALError = true;
|
||||
TrapALCError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = getenv("ALSOFT_TRAP_AL_ERROR");
|
||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
||||
TrapALError = true;
|
||||
traperr = al::getenv("ALSOFT_TRAP_AL_ERROR");
|
||||
if(traperr)
|
||||
{
|
||||
if(strcasecmp(traperr->c_str(), "true") == 0
|
||||
|| strtol(traperr->c_str(), nullptr, 0) == 1)
|
||||
TrapALError = true;
|
||||
}
|
||||
TrapALError = !!GetConfigValueBool(nullptr, nullptr, "trap-al-error", TrapALError);
|
||||
|
||||
str = getenv("ALSOFT_TRAP_ALC_ERROR");
|
||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
||||
traperr = al::getenv("ALSOFT_TRAP_ALC_ERROR");
|
||||
if(traperr)
|
||||
{
|
||||
if(strcasecmp(traperr->c_str(), "true") == 0
|
||||
|| strtol(traperr->c_str(), nullptr, 0) == 1)
|
||||
TrapALCError = true;
|
||||
}
|
||||
TrapALCError = !!GetConfigValueBool(nullptr, nullptr, "trap-alc-error", TrapALCError);
|
||||
}
|
||||
|
||||
@@ -1068,13 +1074,8 @@ void alc_initconfig(void)
|
||||
ReverbBoost *= std::pow(10.0f, valf / 20.0f);
|
||||
}
|
||||
|
||||
auto devopt = ConfigValueStr(nullptr, nullptr, "drivers");
|
||||
if(const char *devs{getenv("ALSOFT_DRIVERS")})
|
||||
{
|
||||
if(devs[0])
|
||||
devopt = devs;
|
||||
}
|
||||
if(devopt)
|
||||
auto devopt = al::getenv("ALSOFT_DRIVERS");
|
||||
if(devopt || (devopt=ConfigValueStr(nullptr, nullptr, "drivers")))
|
||||
{
|
||||
auto backendlist_cur = std::begin(BackendList);
|
||||
|
||||
@@ -1165,7 +1166,7 @@ void alc_initconfig(void)
|
||||
{
|
||||
const char *next{exclopt->c_str()};
|
||||
do {
|
||||
str = next;
|
||||
const char *str{next};
|
||||
next = strchr(str, ',');
|
||||
|
||||
if(!str[0] || next == str)
|
||||
@@ -1182,10 +1183,9 @@ void alc_initconfig(void)
|
||||
}
|
||||
|
||||
InitEffect(&DefaultEffect);
|
||||
auto defrevopt = ConfigValueStr(nullptr, nullptr, "default-reverb");
|
||||
if((str=getenv("ALSOFT_DEFAULT_REVERB")) && str[0])
|
||||
defrevopt = str;
|
||||
if(defrevopt) LoadReverbPreset(defrevopt->c_str(), &DefaultEffect);
|
||||
auto defrevopt = al::getenv("ALSOFT_DEFAULT_REVERB");
|
||||
if(defrevopt || (defrevopt=ConfigValueStr(nullptr, nullptr, "default-reverb")))
|
||||
LoadReverbPreset(defrevopt->c_str(), &DefaultEffect);
|
||||
}
|
||||
#define DO_INITCONFIG() std::call_once(alc_config_once, [](){alc_initconfig();})
|
||||
|
||||
|
||||
+26
-28
@@ -81,6 +81,7 @@ std::string expdup(const char *str)
|
||||
{
|
||||
std::string output;
|
||||
|
||||
std::string envval;
|
||||
while(*str != '\0')
|
||||
{
|
||||
const char *addstr;
|
||||
@@ -107,20 +108,20 @@ std::string expdup(const char *str)
|
||||
}
|
||||
else
|
||||
{
|
||||
bool hasbraces{(*str == '{')};
|
||||
const bool hasbraces{(*str == '{')};
|
||||
|
||||
if(hasbraces) str++;
|
||||
|
||||
std::string envname;
|
||||
while((std::isalnum(*str) || *str == '_'))
|
||||
envname += *(str++);
|
||||
|
||||
const char *envstart = str;
|
||||
while(std::isalnum(*str) || *str == '_')
|
||||
++str;
|
||||
if(hasbraces && *str != '}')
|
||||
continue;
|
||||
|
||||
const std::string envname{envstart, str};
|
||||
if(hasbraces) str++;
|
||||
if((addstr=std::getenv(envname.c_str())) == nullptr)
|
||||
continue;
|
||||
addstrlen = std::strlen(addstr);
|
||||
|
||||
envval = al::getenv(envname.c_str()).value_or(std::string{});
|
||||
addstr = envval.data();
|
||||
addstrlen = envval.length();
|
||||
}
|
||||
}
|
||||
if(addstrlen == 0)
|
||||
@@ -308,18 +309,17 @@ void ReadALConfig()
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
const WCHAR *str{_wgetenv(L"ALSOFT_CONF")};
|
||||
if(str != nullptr && *str)
|
||||
if(auto confpath = al::getenv(L"ALSOFT_CONF"))
|
||||
{
|
||||
std::string filepath{wstr_to_utf8(str)};
|
||||
|
||||
TRACE("Loading config %s...\n", filepath.c_str());
|
||||
al::ifstream f{filepath};
|
||||
TRACE("Loading config %s...\n", wstr_to_utf8(confpath->c_str()).c_str());
|
||||
al::ifstream f{*confpath};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ReadALConfig()
|
||||
{
|
||||
const char *str{"/etc/openal/alsoft.conf"};
|
||||
@@ -330,9 +330,7 @@ void ReadALConfig()
|
||||
LoadConfigFromFile(f);
|
||||
f.close();
|
||||
|
||||
if(!(str=getenv("XDG_CONFIG_DIRS")) || str[0] == 0)
|
||||
str = "/etc/xdg";
|
||||
std::string confpaths = str;
|
||||
std::string confpaths{al::getenv("XDG_CONFIG_DIRS").value_or("/etc/xdg")};
|
||||
/* Go through the list in reverse, since "the order of base directories
|
||||
* denotes their importance; the first directory listed is the most
|
||||
* important". Ergo, we need to load the settings from the later dirs
|
||||
@@ -385,9 +383,9 @@ void ReadALConfig()
|
||||
}
|
||||
#endif
|
||||
|
||||
if((str=getenv("HOME")) != nullptr && *str)
|
||||
if(auto homedir = al::getenv("HOME"))
|
||||
{
|
||||
fname = str;
|
||||
fname = *homedir;
|
||||
if(fname.back() != '/') fname += "/.alsoftrc";
|
||||
else fname += ".alsoftrc";
|
||||
|
||||
@@ -397,18 +395,18 @@ void ReadALConfig()
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
if((str=getenv("XDG_CONFIG_HOME")) != nullptr && str[0] != 0)
|
||||
if(auto configdir = al::getenv("XDG_CONFIG_HOME"))
|
||||
{
|
||||
fname = str;
|
||||
fname = *configdir;
|
||||
if(fname.back() != '/') fname += "/alsoft.conf";
|
||||
else fname += "alsoft.conf";
|
||||
}
|
||||
else
|
||||
{
|
||||
fname.clear();
|
||||
if((str=getenv("HOME")) != nullptr && str[0] != 0)
|
||||
if(auto homedir = al::getenv("HOME"))
|
||||
{
|
||||
fname = str;
|
||||
fname = *homedir;
|
||||
if(fname.back() != '/') fname += "/.config/alsoft.conf";
|
||||
else fname += ".config/alsoft.conf";
|
||||
}
|
||||
@@ -433,10 +431,10 @@ void ReadALConfig()
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
if((str=getenv("ALSOFT_CONF")) != nullptr && *str)
|
||||
if(auto confname = al::getenv("ALSOFT_CONF"))
|
||||
{
|
||||
TRACE("Loading config %s...\n", str);
|
||||
al::ifstream f{str};
|
||||
TRACE("Loading config %s...\n", confname->c_str());
|
||||
al::ifstream f{*confname};
|
||||
if(f.is_open())
|
||||
LoadConfigFromFile(f);
|
||||
}
|
||||
|
||||
+11
-6
@@ -73,6 +73,7 @@
|
||||
#include "mixer/defs.h"
|
||||
#include "opthelpers.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "strutils.h"
|
||||
#include "threads.h"
|
||||
#include "uhjfilter.h"
|
||||
#include "vecmat.h"
|
||||
@@ -87,18 +88,22 @@ using namespace std::placeholders;
|
||||
ALfloat InitConeScale()
|
||||
{
|
||||
ALfloat ret{1.0f};
|
||||
const char *str{getenv("__ALSOFT_HALF_ANGLE_CONES")};
|
||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
||||
ret *= 0.5f;
|
||||
if(auto optval = al::getenv("__ALSOFT_HALF_ANGLE_CONES"))
|
||||
{
|
||||
if(strcasecmp(optval->c_str(), "true") == 0 || strtol(optval->c_str(), nullptr, 0) == 1)
|
||||
ret *= 0.5f;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ALfloat InitZScale()
|
||||
{
|
||||
ALfloat ret{1.0f};
|
||||
const char *str{getenv("__ALSOFT_REVERSE_Z")};
|
||||
if(str && (strcasecmp(str, "true") == 0 || strtol(str, nullptr, 0) == 1))
|
||||
ret *= -1.0f;
|
||||
if(auto optval = al::getenv("__ALSOFT_REVERSE_Z"))
|
||||
{
|
||||
if(strcasecmp(optval->c_str(), "true") == 0 || strtol(optval->c_str(), nullptr, 0) == 1)
|
||||
ret *= -1.0f;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "alexcpt.h"
|
||||
#include "compat.h"
|
||||
#include "dynload.h"
|
||||
#include "strutils.h"
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
@@ -855,8 +856,8 @@ ALCenum PulsePlayback::open(const ALCchar *name)
|
||||
|
||||
if(!pulse_name)
|
||||
{
|
||||
pulse_name = getenv("ALSOFT_PULSE_DEFAULT");
|
||||
if(pulse_name && !pulse_name[0]) pulse_name = nullptr;
|
||||
static const auto defname = al::getenv("ALSOFT_PULSE_DEFAULT");
|
||||
if(defname) pulse_name = defname->c_str();
|
||||
}
|
||||
TRACE("Connecting to \"%s\"\n", pulse_name ? pulse_name : "(default)");
|
||||
mStream = pulse_connect_stream(pulse_name, plock, mContext, flags, nullptr, &spec, nullptr,
|
||||
|
||||
+19
-20
@@ -530,22 +530,21 @@ al::vector<std::string> SearchDataFiles(const char *ext, const char *subdir)
|
||||
std::string path;
|
||||
|
||||
/* Search the app-local directory. */
|
||||
WCHAR *cwdbuf{_wgetenv(L"ALSOFT_LOCAL_PATH")};
|
||||
if(cwdbuf && *cwdbuf != '\0')
|
||||
if(auto localpath = al::getenv(L"ALSOFT_LOCAL_PATH"))
|
||||
{
|
||||
path = wstr_to_utf8(cwdbuf);
|
||||
path = wstr_to_utf8(localpath->c_str());
|
||||
if(is_slash(path.back()))
|
||||
path.pop_back();
|
||||
}
|
||||
else if(!(cwdbuf=_wgetcwd(nullptr, 0)))
|
||||
path = ".";
|
||||
else
|
||||
else if(WCHAR *cwdbuf{_wgetcwd(nullptr, 0)})
|
||||
{
|
||||
path = wstr_to_utf8(cwdbuf);
|
||||
if(is_slash(path.back()))
|
||||
path.pop_back();
|
||||
free(cwdbuf);
|
||||
}
|
||||
else
|
||||
path = ".";
|
||||
std::replace(path.begin(), path.end(), '/', '\\');
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
|
||||
@@ -725,9 +724,8 @@ al::vector<std::string> SearchDataFiles(const char *ext, const char *subdir)
|
||||
}
|
||||
|
||||
/* Search the app-local directory. */
|
||||
const char *str{getenv("ALSOFT_LOCAL_PATH")};
|
||||
if(str && *str != '\0')
|
||||
DirectorySearch(str, ext, &results);
|
||||
if(auto localpath = al::getenv("ALSOFT_LOCAL_PATH"))
|
||||
DirectorySearch(localpath->c_str(), ext, &results);
|
||||
else
|
||||
{
|
||||
al::vector<char> cwdbuf(256);
|
||||
@@ -750,17 +748,17 @@ al::vector<std::string> SearchDataFiles(const char *ext, const char *subdir)
|
||||
}
|
||||
|
||||
// Search local data dir
|
||||
if((str=getenv("XDG_DATA_HOME")) != nullptr && str[0] != '\0')
|
||||
if(auto datapath = al::getenv("XDG_DATA_HOME"))
|
||||
{
|
||||
std::string path{str};
|
||||
std::string &path = *datapath;
|
||||
if(path.back() != '/')
|
||||
path += '/';
|
||||
path += subdir;
|
||||
DirectorySearch(path.c_str(), ext, &results);
|
||||
}
|
||||
else if((str=getenv("HOME")) != nullptr && str[0] != '\0')
|
||||
else if(auto homepath = al::getenv("HOME"))
|
||||
{
|
||||
std::string path{str};
|
||||
std::string &path = *homepath;
|
||||
if(path.back() == '/')
|
||||
path.pop_back();
|
||||
path += "/.local/share/";
|
||||
@@ -769,17 +767,18 @@ al::vector<std::string> SearchDataFiles(const char *ext, const char *subdir)
|
||||
}
|
||||
|
||||
// Search global data dirs
|
||||
if((str=getenv("XDG_DATA_DIRS")) == nullptr || str[0] == '\0')
|
||||
str = "/usr/local/share/:/usr/share/";
|
||||
std::string datadirs{al::getenv("XDG_DATA_DIRS").value_or("/usr/local/share/:/usr/share/")};
|
||||
|
||||
const char *next{str};
|
||||
while((str=next) != nullptr && str[0] != '\0')
|
||||
size_t curpos{0u};
|
||||
while(curpos < datadirs.size())
|
||||
{
|
||||
next = strchr(str, ':');
|
||||
size_t nextpos{datadirs.find(':', curpos)};
|
||||
|
||||
std::string path{(nextpos != std::string::npos) ?
|
||||
datadirs.substr(curpos, nextpos++ - curpos) : datadirs.substr(curpos)};
|
||||
curpos = nextpos;
|
||||
|
||||
std::string path = (next ? std::string(str, next++) : std::string(str));
|
||||
if(path.empty()) continue;
|
||||
|
||||
if(path.back() != '/')
|
||||
path += '/';
|
||||
path += subdir;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "strutils.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
namespace al {
|
||||
|
||||
al::optional<std::string> getenv(const char *envname)
|
||||
{
|
||||
const char *str{std::getenv(envname)};
|
||||
if(str && str[0] != '\0') return str;
|
||||
return al::nullopt;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
al::optional<std::wstring> getenv(const WCHAR *envname)
|
||||
{
|
||||
const WCHAR *str{_wgetenv(envname)};
|
||||
if(str && str[0] != L'\0') return str;
|
||||
return al::nullopt;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace al
|
||||
+13
-2
@@ -1,12 +1,14 @@
|
||||
#ifndef AL_STRUTILS_H
|
||||
#define AL_STRUTILS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <string>
|
||||
|
||||
#include "aloptional.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
inline std::string wstr_to_utf8(const WCHAR *wstr)
|
||||
{
|
||||
@@ -40,4 +42,13 @@ inline std::wstring utf8_to_wstr(const char *str)
|
||||
|
||||
#endif
|
||||
|
||||
namespace al {
|
||||
|
||||
al::optional<std::string> getenv(const char *envname);
|
||||
#ifdef _WIN32
|
||||
al::optional<std::wstring> getenv(const WCHAR *envname);
|
||||
#endif
|
||||
|
||||
} // namespace al
|
||||
|
||||
#endif /* AL_STRUTILS_H */
|
||||
|
||||
Reference in New Issue
Block a user