+ /**
+ * Closes a module and deletes the so-file if the associated clean-up flag is true.
+ */
+ void clean_up(const std::vector<filedesc>::const_iterator it)
+ {
+ dlclose(it->module);
+ if (it->clean_up) {
+ remove(it->name.c_str());
+ }
+ }
+ /**
+ * Creates a new C source file and adds a standard header. If filename is
+ * empty, a unique random name is produced and used.
+ */
+ void create_src_file(std::string& filename, std::ofstream& ofs)
+ {
+ if (filename.empty()) {
+ // fill filename with unique random word
+ const char* filename_pattern = "./GiNaCXXXXXX";
+ char* new_filename = new char[strlen(filename_pattern)+1];
+ strcpy(new_filename, filename_pattern);
+ if (!mktemp(new_filename)) {
+ delete new_filename;
+ throw std::runtime_error("mktemp failed");
+ }
+ filename = std::string(new_filename);
+ ofs.open(new_filename, std::ios::out);
+ delete new_filename;
+ } else {
+ // use parameter as filename
+ ofs.open(filename.c_str(), std::ios::out);
+ }
+
+ if (!ofs) {
+ throw std::runtime_error("could not create source code file for compilation");
+ }
+
+ ofs << "#include <stddef.h> " << std::endl;
+ ofs << "#include <stdlib.h> " << std::endl;
+ ofs << "#include <math.h> " << std::endl;
+ ofs << std::endl;
+ }
+ /**
+ * Calls the shell script 'ginac-excompiler' to compile the produced C
+ * source file into an linkable so-file. On demand the C source file is
+ * deleted.
+ */
+ void compile_src_file(const std::string filename, bool clean_up)
+ {
+ std::string strcompile = "ginac-excompiler " + filename;
+ if (system(strcompile.c_str())) {
+ throw std::runtime_error("excompiler::compile_src_file: error compiling source file!");
+ }
+ if (clean_up) {
+ remove(filename.c_str());
+ }
+ }
+ /**
+ * Links a so-file whose filename is given.
+ */
+ void* link_so_file(const std::string filename, bool clean_up)
+ {
+ void* module = NULL;
+ module = dlopen(filename.c_str(), RTLD_NOW);
+ if (module == NULL) {
+ throw std::runtime_error("excompiler::link_so_file: could not open compiled module!");
+ }