Go to the documentation of this file.00001 #include "preprocess.hh"
00002
00003 #include <sys/types.h>
00004 #include <sys/stat.h>
00005 #include <sys/wait.h>
00006 #include <fcntl.h>
00007 #include <stdlib.h>
00008 #include <unistd.h>
00009 #include <errno.h>
00010
00011 #include <vector>
00012
00013 #include <iostream>
00014 using namespace std;
00015
00020 #ifndef STDINCPP
00021 # define STDINCPP "gcc -E -"
00022 #endif
00023
00024 typedef std::list<std::string> StringList;
00025 typedef std::vector<std::string> StringVector;
00026
00027 static StringVector split(const string& str, const char* char_set = " \t")
00028 {
00029 StringVector ret;
00030
00031 size_t length(str.length());
00032 size_t begin = 0;
00033 while (begin < length)
00034 {
00035 size_t end = str.find_first_of(char_set, begin);
00036 if (end > length)
00037 end = length;
00038
00039 ret.push_back(str.substr(begin, end - begin));
00040 begin = end + 1;
00041 }
00042
00043 return ret;
00044 }
00045
00046 std::string preprocess(const string& fichier, const StringList& options)
00047 {
00048 char tmpName[17] = "/tmp/genomXXXXXX";
00049
00050
00051 int in = open(fichier.c_str(), O_RDONLY, 0);
00052 if (in < 0) {
00053 cerr << "Cannot open " << fichier << " for reading: " << strerror(errno) << endl;
00054 return string();
00055 }
00056
00057
00058 int out = mkstemp(tmpName);
00059 if (out < 0) {
00060 cerr << "Cannot open temporary file " << tmpName << "for writing: " << strerror(errno) << endl;
00061 return string();
00062 }
00063
00064
00065 StringVector argv = split(STDINCPP);
00066 if (argv.empty())
00067 {
00068 cerr << "No C preprocessor specified, aborting" << endl;
00069 return string();
00070 }
00071 argv.insert(argv.end(), options.begin(), options.end());
00072
00073
00074 int argv_size = argv.size();
00075 char** c_argv = new char*[argv_size + 1];
00076 for (int i = 0; i < argv_size; ++i)
00077 c_argv[i] = const_cast<char *>(argv[i].c_str());
00078 c_argv[argv_size] = 0;
00079
00080
00081 pid_t pid = fork();
00082 if (pid == 0) {
00083
00084 if (dup2(in, fileno(stdin)) < 0)
00085 cerr << "Cannot redirect cpp input: " << strerror(errno) << endl;
00086 else if (dup2(out, fileno(stdout)) < 0)
00087 cerr << "Cannot redirect cpp output: " << strerror(errno) << endl;
00088 else if (execvp(c_argv[0], c_argv) == -1)
00089 {
00090 cerr << "Error running " << c_argv[0] << ": " << strerror(errno) << endl;
00091 exit(1);
00092 }
00093 }
00094
00095
00096
00097
00098 delete[] c_argv;
00099 close(in);
00100 close(out);
00101 if (pid == 0) return string();
00102
00103 int status;
00104 wait( &status );
00105 if (! WIFEXITED(status) || WEXITSTATUS(status) != 0)
00106 {
00107 cerr << "C preprocessor failure" << endl;
00108 return string();
00109 }
00110
00111 return tmpName;
00112 }
00113