11 #include <boost/algorithm/string/case_conv.hpp>    12 #include <boost/filesystem.hpp>    32     auto cp = getenv(
"VCSN_VERBOSE");
    33     std::istringstream is{cp ? cp : 
"0"};
    45       : 
std::runtime_error(what)
    51 #define XGETENV(Name) xgetenv(#Name, Name)    56       config(
const std::string& var)
    58         auto envvar = 
"VCSN_" + boost::algorithm::to_upper_copy(var);
    59         if (
auto cp = getenv(envvar.c_str()))
    62           return get_config()[
"configuration"][var].str();
    69         if (!res.empty() && res[0] == 
'~')
    71             assert(res.size() == 1 || res[1] == 
'/');
    73             char const *hdrive = getenv(
"HOMEDRIVE");
    74             char const *hres = getenv(
"HOMERES");
    76               res.replace(0, 1, home);
    77             else if (hdrive && hres)
    78               res.replace(0, 1, std::string(hdrive) + hres);
    80               res.replace(0, 1, 
xgetenv(
"VCSN_TMPDIR", 
"/tmp"));
    86       void ensure_parent_directory(
const std::string& path)
    88         boost::filesystem::path p(path);
    89         boost::filesystem::create_directories(p.parent_path());
    93       std::string tmpname(std::string res)
   116         void print(
const std::string& base)
   118           ensure_parent_directory(base);
   121           auto tmp = tmpname(base);
   123             std::ofstream o{tmp + 
".cc"};
   127             boost::filesystem::remove(tmp + 
".cc");
   129             boost::filesystem::rename(tmp + 
".cc", base + 
".cc");
   140         void print_type(
const std::string& 
type)
   148         void throw_compiler_errors(std::string cmd,
   149                                    const std::string& err)
   168           static auto r1 = std::regex{
"static assertion failed: (.*)$",
   169                                       std::regex::extended};
   170           static auto r2 = std::regex{
"static_assert failed \"(.*)\"$",
   171                                       std::regex::extended};
   175           while (std::getline(*is, line))
   176             if (std::regex_search(line, smatch, r1)
   177                 || std::regex_search(line, smatch, r2))
   178               assertions += std::string(smatch[1]) + 
'\n';
   181               cmd += 
"\n  compiler error messages:\n";
   184           throw jit_error(assertions, 
"  failed command:\n    " + cmd);
   191         void cxx(std::string cmd, 
const std::string& tmp)
   193           auto err = tmp + 
".err";
   194           if (getenv(
"VCSN_DEBUG"))
   195             std::cerr << 
"run: " << cmd << 
'\n';
   196           if (system((cmd + 
" 2>'" + err + 
"'").c_str()))
   197             throw_compiler_errors(cmd, err);
   201               std::ifstream 
log{err};
   202               std::cerr << 
log.rdbuf();
   207               boost::filesystem::remove(err);
   214         void cxx_compile(
const std::string& base)
   216           auto tmp = tmpname(base);
   219           auto cmd = (std::string{
"LC_ALL=C"}
   220                       + 
" " + config(
"ccache")
   221                       + 
" " + config(
"cxx")
   222                       + 
" " + config(
"cxxflags")
   223                       + 
" " + config(
"cppflags")
   224                       + 
" -fPIC '" + base + 
".cc' -c"   225                       + 
" -o '" + tmp + 
".o'");
   232         void cxx_link(
const std::string& base)
   234           auto tmp = tmpname(base);
   235           auto cmd = (std::string{
"LC_ALL=C"}
   236                       + 
" " + config(
"cxx")
   237                       + 
" " + config(
"cxxflags")
   238                       + 
" " + config(
"ldflags")
   239                       + 
" -fPIC -lvcsn '" + tmp + 
".o' -shared"   240                       + 
" -o '" + tmp + 
".so'"   246         std::string plugindir()
 const   248           auto res = 
xgetenv(
"VCSN_PLUGINDIR",
   249                              xgetenv(
"VCSN_HOME", 
"~/.vcsn") + 
"/plugins");
   256         std::string 
split(
const std::string& s)
 const   258           auto res = std::string{};
   259           const size_t size = 150;
   260           for (
unsigned i = 0; i < s.length(); i += 
size)
   264               res += s.substr(i, size);
   277         void jit(
const std::string& base)
   279           auto tmp = tmpname(base);
   281             namespace chr = std::chrono;
   282             using clock = chr::steady_clock;
   283             auto start = clock::now();
   284             static bool no_python = !!getenv(
"VCSN_NO_PYTHON");
   289                 boost::filesystem::rename(tmp + 
".so", base + 
".so");
   294                 if (!getenv(
"VCSN_DEBUG"))
   295                   boost::filesystem::remove(tmp + 
".o");
   301                             xgetenv(
"VCSN", 
"vcsn") + 
" compile");
   302                 auto linkflags = 
printer_.linkflags();
   303                 if (!linkflags.empty())
   304                   linkflags = 
" LDFLAGS+='" + linkflags + 
"'";
   305                 cxx(cmd + 
" -shared" + linkflags + 
" '" + base + 
".cc'",
   309               = chr::duration_cast<chr::milliseconds>(clock::now() - start);
   310             if (getenv(
"VCSN_TIME"))
   312                 std::ofstream{
"/tmp/vcsn-compile.log",
   315                 << (no_python ? 
"C++, " : 
"Py,  ")
   316                 << 
'\'' << base.substr(plugindir().
size()) << 
'\''   318                 if (getenv(
"VCSN_TIME2"))
   319                   std::cerr << d.count() << 
"ms: " << base << 
'\n';
   330         void compile(
const std::string& ctx)
   332           printer_.header(
"vcsn/ctx/instantiate.hh");
   333           auto base = plugindir() + 
"contexts/" + 
split(ctx);
   341             "  VCSN_CTX_INSTANTIATE(ctx_t);\n"   351           printer_.header(
"vcsn/misc/attributes.hh"); 
   352           printer_.header(
"vcsn/dyn/name.hh"); 
   353           printer_.header(
"vcsn/dyn/registries.hh");
   354           for (
const auto& algo: algos)
   358           for (
const auto& algo: algos)
   361                  << 
"// " << algo.first << 
'.';
   364               for (
const auto& s: algo.second)
   371                   types += (first ? 
"" : 
", ") + t;
   377                 "static bool vcsn_" << algo.first << 
" ATTRIBUTE_USED ="   379                  << 
"vcsn::dyn::detail::" << algo.first << 
"_register("   381                  << 
"vcsn::ssignature<" << types << 
">(),"   383                  << 
"vcsn::dyn::detail::" << algo.first << 
"<" << types << 
">"   390           auto base = (plugindir()
   392                        + begin(algos)->first + 
"/"   393                        + 
split(begin(algos)->second.to_string()));
   399         std::ostringstream 
os;
   406       translation translate;
   407       translate.compile(ctx);
   412       translation translate;
   413       std::set<std::pair<std::string, signature>> algos{{algo, sig}};
   414       if (algo == 
"delay_automaton"   415           || algo == 
"is_synchronized")
   417           algos.emplace(
"delay_automaton", sig);
   418           algos.emplace(
"is_synchronized", sig);
   420       translate.compile(algos);
 Request the set implementation (bool weights). 
xlt_handle open(const std::string &s)
std::string type(const automaton &a)
The implementation type of a. 
std::shared_ptr< std::istream > open_input_file(const std::string &file)
Open file for reading and return its autoclosing stream. 
xlt_advise & global(bool global)
std::ostream & print(const automaton &aut, std::ostream &out=std::cout, const std::string &format="default")
Print automaton a on out using format format. 
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation. 
bool equal_files(const std::string &fn1, const std::string &fn2)
Whether two files have exactly equal contents. 
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation. 
weightset_mixin< detail::log_impl > log
std::ostream & print_context(const context &ctx, std::ostream &o, const std::string &fmt)
Bridge (print). 
std::string expand_tilda(const std::string &res)
Expand initial "~" in res. 
detail::config & get_config()
Get the configuration singleton. 
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
std::ostringstream os
The output stream: the corresponding C++ snippet to compile. 
Signature of a function call. 
std::shared_ptr< ast_node > parse_type(const std::string &type)
Parse a type, and return its AST. 
std::string xgetenv(const std::string &var, const std::string &val="")
getenv(var) if defined, otherwise val. 
std::shared_ptr< ast_node > parse_context(const std::string &ctx)
Parse a context, and return its AST. 
ast::context_printer printer_
xlt_advise & verbose(int v)
Whether to report dlopen attempts. 
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s. 
jit_error(const std::string &assert, const std::string &what)
polynomial split(const expression &exp)
Break exp. 
void compile(const std::string &ctx)
Compile, and load, a DSO with instantiations for ctx. 
std::string get_file_contents(const std::string &file)
Return the contents of file. 
Indentation relative functions. 
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation. 
std::string assertions
If defined, static assertions that failed (ends with a eol). 
std::string to_string(identities i)
Wrapper around operator<<.