Do not store getenv() pointers in static variables.

... or the pointer might be invalidated if the environments
changes.  Fixes #63.

* src/taalgos/dotty.cc, src/tgbaalgos/dotty.cc,
src/tgbaalgos/dtbasat.cc, src/tgbaalgos/dtgbasat.cc:
Copy the environment in strings instead.
* wrap/python/tests/automata.ipynb: Adjust comment.
This commit is contained in:
Alexandre Duret-Lutz 2015-03-20 19:07:02 +01:00
parent 519f5e3cee
commit 125fa983ab
5 changed files with 71 additions and 31 deletions

View file

@ -41,8 +41,18 @@ namespace spot
{
os_ << "digraph G {\n";
static const char* extra = getenv("SPOT_DOTEXTRA");
if (extra)
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string extra = []()
{
auto s = getenv("SPOT_DOTEXTRA");
return s ? s : "";
}();
// Any extra text passed in the SPOT_DOTEXTRA environment
// variable should be output at the end of the "header", so
// that our setup can be overridden.
if (!extra.empty())
os_ << " " << extra << '\n';
artificial_initial_state_ = t_automata_->get_artificial_initial_state();

View file

@ -88,13 +88,22 @@ namespace spot
{
case '.':
{
static const char* def = getenv("SPOT_DOTDEFAULT");
// Copy the value in a string, so future calls to
// parse_opts do not fail if the environment has
// changed. (This matters particularly in an ipython
// notebook, where it is tempting to redefine
// SPOT_DOTDEFAULT.)
static std::string def = []()
{
auto s = getenv("SPOT_DOTDEFAULT");
return s ? s : "";
}();
// Prevent infinite recursions...
if (orig == def)
if (orig == def.c_str())
throw std::runtime_error
(std::string("SPOT_DOTDEFAULT should not contain '.'"));
if (def)
parse_opts(def);
if (!def.empty())
parse_opts(def.c_str());
break;
}
case 'a':
@ -269,11 +278,18 @@ namespace spot
<< "\"\n node [fontname=\"" << opt_font_
<< "\"]\n edge [fontname=\"" << opt_font_
<< "\"]\n";
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string extra = []()
{
auto s = getenv("SPOT_DOTEXTRA");
return s ? s : "";
}();
// Any extra text passed in the SPOT_DOTEXTRA environment
// variable should be output at the end of the "header", so
// that our setup can be overridden.
static const char* extra = getenv("SPOT_DOTEXTRA");
if (extra && *extra)
if (!extra.empty())
os_ << " " << extra << '\n';
os_ << " I [label=\"\", style=invis, ";
os_ << (opt_horizontal_ ? "width" : "height");

View file

@ -766,8 +766,15 @@ namespace spot
if (!solution.second.empty())
res = sat_build(solution.second, d, a, state_based);
static const char* log = getenv("SPOT_SATLOG");
if (log)
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string log = []()
{
auto s = getenv("SPOT_SATLOG");
return s ? s : "";
}();
if (!log.empty())
{
std::fstream out(log,
std::ios_base::app | std::ios_base::out);
@ -790,7 +797,7 @@ namespace spot
<< te.utime() << ',' << te.stime() << ','
<< ts.utime() << ',' << ts.stime() << '\n';
}
static const char* show = getenv("SPOT_SATSHOW");
static bool show = getenv("SPOT_SATSHOW");
if (show && res)
dotty_reachable(std::cout, res);

View file

@ -906,8 +906,15 @@ namespace spot
if (!solution.second.empty())
res = sat_build(solution.second, d, a, state_based);
static const char* log = getenv("SPOT_SATLOG");
if (log)
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string log = []()
{
auto s = getenv("SPOT_SATLOG");
return s ? s : "";
}();
if (!log.empty())
{
std::fstream out(log,
std::ios_base::app | std::ios_base::out);
@ -930,7 +937,7 @@ namespace spot
<< te.utime() << ',' << te.stime() << ','
<< ts.utime() << ',' << ts.stime() << '\n';
}
static const char* show = getenv("SPOT_SATSHOW");
static bool show = getenv("SPOT_SATSHOW");
if (show && res)
dotty_reachable(std::cout, res);