View Source Code of Tero’s C++ Scripting
Are you looking for Tero’s C++ Scripting homepage?
This is the source code of Tero’s C++ Scripting. This a syntax highlighted copy for reading, not necessarily the latest version. If you want to use Tero’s C++ Scripting on your computer, go to Tero’s C++ Scripting homepage. There you can download the latest version.
Remember that GPL license requires you to use the same license for your work and mention the source if you copy any code.
cppt.cc
// cppt - Teros C++ Scripting // Copyright Tero Karvinen 2007 http://www.iki.fi/karvinen // GNU General Public License version 2. #include <iostream> #include <string> // does this conflict with boost fstream (included later in this file)? #include <fstream> #include <regex.h> using namespace std; const int VERBOSITY_SILENT =0; const int VERBOSITY_VERBOSE =1; const int VERBOSITY_DEBUG =99; int verbose=VERBOSITY_SILENT; void verbosePrint(string s, int level=VERBOSITY_VERBOSE) // print string if global variable verbose >= level { if (verbose>=level) cout << s << endl; } void v(string s, int level=VERBOSITY_VERBOSE) // shortcut for verbosePrint(s) { verbosePrint(s, level); } string readFile(string inputFile) // read contents of file, eg: string contents = readFile("foo.txt"); { string contents=""; string line=""; ifstream in; in.open(inputFile.c_str()); while(getline(in, line)) contents += line + "n"; in.close(); return contents; } int writeFile(string file, string contents) // write contents to file. Overwrites without warning. { ofstream out; if( !out ) { cout << "ERROR opening " << file << " for output!" << endl; exit(-1); } out.open(file.c_str()); out << contents << endl; out.close(); return EXIT_SUCCESS; } // $ sudo apt-get install libboost-regex-dev libboost-doc // g++ -lboost_regex foo.cc #include <boost/regex.hpp> using namespace boost; string regReplace(string haystack, string needle, string replacement) // replace needle (regexp) with replacement in haystack { // this convience funtion saves the trouble of creating a new boost:regex object for every replacement // bug: when regex needle contains escapble chars, user must DOUBLE backslash them: "main(" regex needleReg(needle); return regex_replace(haystack, needleReg, replacement); } bool regMatch(string haystack, string needle) // return true if haystack contains (regex) needle { // convience funtion to avoid creating new regex objects manually // bug: when regex needle contains escapble chars, user must DOUBLE backslash them: "main(" regex needleReg(needle); return regex_search(haystack, needleReg); } int execSystem(string cmd) { // execute cmd. convinience funtion that accepts c++ strings. return system(cmd.c_str()); } string toFullCpp(string s) { // convert partial source code s to full, compilable c++ source code // todo: indent when adding main // todo: smarter checking for "main" and "return" string head= "#include <iostream>n" "using namespace std;nn" "int main(int argc, char *argv[])n" "{n"; string returnOk="return EXIT_SUCCESS;n"; string tail="}n"; if (regMatch(s, "main")) { v("(Main found)"); } else { v("No main found - adding"); s=head+s; if (!regMatch(s, "return")) { v("No return found - adding"); s=s+returnOk; } s+=tail; } return s; } #include <boost/filesystem/config.hpp> #include <boost/filesystem/convenience.hpp> #include <boost/filesystem/exception.hpp> #include <boost/filesystem/operations.hpp> // does this conflict with standard fstream (defined in the beginning of this file)? #include <boost/filesystem/fstream.hpp> #include <boost/filesystem/path.hpp> using namespace boost::filesystem; // $ sudo apt-get install libboost-filesystem-dev // g++ -lboost_filesystem foo.cc -o foo time_t fileModified(string file) // return date of last modification of write, same as 'stat' command { // returns seconds since epoch (created with implicit cast) return last_write_time(file); } int main(int argc, char *argv[]) { // todo: if executableFile is newer than scriptFile, just run executableFile string scriptFile=argv[1]; // filename of .cc script string ccTmpFile=regReplace(scriptFile, ".cc", "-cppt-tmp.cc"); // filename of compilable CPP source file (will not have shebang "#!" etc) string executableFile=regReplace(scriptFile, ".cc", "-cppt-tmp"); // executable filename, created later with 'g++ ccTmpFile' if ( exists(executableFile) and (fileModified(executableFile) > fileModified(scriptFile)) ) { v("ScriptFile "+scriptFile+" not modified, so no recompilation needed."); v("Running executable "+executableFile); execSystem(executableFile); exit(EXIT_SUCCESS); } else v("ScriptFile modified, will convert and compile. "); string src; v("Cppt reading script file "+scriptFile); src = readFile(scriptFile); v("Converting script file to compilabe source code"); src = regReplace(src, "#![^n]+n", ""); src=toFullCpp(src); v("Storing compilable source code to file "+ccTmpFile); writeFile(ccTmpFile, src); v("Compiling "+ccTmpFile+" to create executable "+executableFile); execSystem("g++ "+ccTmpFile+" -o "+executableFile); v("Running executable "+executableFile); execSystem(executableFile); return EXIT_SUCCESS; }