00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define VERSION "0.1.2"
00036
00037 #include <string>
00038 #include <iostream>
00039 #include <fstream>
00040 #include <cstdio>
00041 #include <cstdlib>
00042 #include <vector>
00043
00044 #ifdef __GNUG__
00045 # include <errno.h>
00046 # include <sys/types.h>
00047 # include <sys/wait.h>
00048 # define FILE_SEPARATOR '/'
00049 #else
00050 #ifdef _WIN32
00051
00052 # define FILE_SEPARATOR '\\'
00053 #endif
00054 #endif
00055
00056 #ifdef _DEBUG
00057 # include "backtrace.h"
00058 # define BOOST_SPIRIT_DEBUG
00059 #endif
00060
00061 #define FILE_ITER
00062
00063 #include <boost/spirit/core.hpp>
00064 #include <boost/spirit/utility.hpp>
00065 #include <boost/spirit/symbols.hpp>
00066 #ifdef FILE_ITER
00067 # include <boost/spirit/iterator/file_iterator.hpp>
00068 #endif
00069
00070 using namespace std;
00071 using namespace boost::spirit;
00072
00073 #include "corba_idl3_grammar.hpp"
00074
00075
00076
00077
00078 #ifndef PREPROCESSOR
00079 # define NO_PREPROCESSOR
00080 #endif
00081 #define stringify(token) #token
00082
00083
00084 static bool preprocess(string &filename, string &tempfile, string &error)
00085 {
00086 bool err = true;
00087 string cpp_str = stringify(PREPROCESSOR);
00088 size_t prev, pos;
00089 prev = pos = cpp_str.find_first_of(" ");
00090 string cpp_cmd = cpp_str.substr(0, pos);
00091
00092 vector<string> cpp_args;
00093 while (pos != string::npos) {
00094 pos = cpp_str.find_first_of(" ", prev + 1);
00095 cpp_args.push_back(cpp_str.substr(prev + 1, pos));
00096 prev = pos;
00097 }
00098
00099 #ifdef __GNUG__
00100 int pid, status;
00101 int pfd[2];
00102
00103 if (pipe(pfd)) {
00104 error = strerror(errno);
00105 return false;
00106 }
00107
00108 if (!(pid = fork())) {
00109 unsigned int i;
00110 char* args[cpp_args.size() + 8];
00111 args[0] = (char*)cpp_cmd.c_str();
00112 for (i = 1; i < cpp_args.size() + 1; i++)
00113 args[i] = (char*)cpp_args[i - 1].c_str();
00114 args[i++] = (char*)"-xc";
00115 args[i++] = (char*)"-undef";
00116 args[i++] = (char*)"-P";
00117 args[i++] = (char*)filename.c_str();
00118 args[i++] = (char*)"-o";
00119 args[i++] = (char*)tempfile.c_str();
00120 args[i] = (char*)NULL;
00121
00122 if (pid < 0) {
00123 error = strerror(errno);
00124 return false;
00125 }
00126 close(pfd[0]);
00127 dup2(pfd[1], 1);
00128 close(pfd[1]);
00129 execvp(cpp_cmd.c_str(), args);
00130 perror("execvp");
00131 exit(1);
00132 }
00133
00134 waitpid(pid, &status, WNOHANG);
00135
00136 int e;
00137 close(pfd[1]);
00138 do {
00139 char c;
00140 if ((e = read(pfd[0], &c, sizeof(char))) < 0) {
00141 error = strerror(errno);
00142 break;
00143 }
00144 error += c;
00145 } while (e > 0);
00146 close(pfd[0]);
00147
00148 if (WIFEXITED(status)) {
00149 if (WEXITSTATUS(status) != 0)
00150 err = false;
00151 } else
00152 err = false;
00153 #endif
00154
00155 #ifdef _WIN32
00156
00157 #endif
00158 return err;
00159 }
00160
00161
00162 static void usage(string app)
00163 {
00164 cerr << "Usage: " << app << " [options] file" << endl;
00165 cerr << "Options:" << endl;
00166 cerr << " --nostubs ." << endl;
00167 cerr << " --noskels ." << endl;
00168 cerr << " --nocommon ." << endl;
00169 cerr << " --noheaders ." << endl;
00170 cerr << " --skeleton-impl ." << endl;
00171 cerr << " -I <dir> Add directory <dir> to the list of directories ";
00172 cerr <<"to be searched for included files." << endl;
00173 cerr << " -h,-help Display these options and exit." << endl;
00174 cerr << " -v,-version Display the version of this compiler and exit.";
00175 cerr << endl;
00176 }
00177
00178
00179 int main(int argc, char *argv[])
00180 {
00181 string in_name;
00182 string apppath = argv[0];
00183 string appname = apppath.substr(apppath.find_last_of(FILE_SEPARATOR) + 1,
00184 apppath.size());
00185 bool do_unlink = true;
00186 bool do_preprocessing = false;
00187
00188 if (argc < 2) {
00189 cerr << appname << " error - no input file" << endl;
00190 usage(appname);
00191 return -1;
00192 }
00193 for (int i = 0; i < argc; i++) {
00194 if (argv[i][0] == '-') {
00195 if (strcmp(argv[i], "-h") == 0 ||
00196 strcmp(argv[i], "--help") == 0) {
00197 usage(appname);
00198 return 0;
00199 }
00200 if (strcmp(argv[i], "-v") == 0 ||
00201 strcmp(argv[i], "--version") == 0) {
00202 cerr << appname << " version " << VERSION << endl;
00203 return 0;
00204 }
00205 if (strcmp(argv[i], "--keep-intermediate") == 0)
00206 do_unlink = false;
00207 if (strcmp(argv[i], "--no-preprocessing") == 0)
00208 do_preprocessing = false;
00209 }
00210 else if (i == argc - 1)
00211 in_name = argv[i];
00212 }
00213 #ifdef NO_PREPROCESSOR
00214 do_preprocessing = false;
00215 #endif
00216 if (in_name.empty()) {
00217 cerr << appname << ": no input file" << endl;
00218 usage(appname);
00219 return -1;
00220 }
00221 #ifdef _DEBUG
00222 enable_backtrace();
00223 #endif
00224
00225 int begin_pos = in_name.find_last_of(FILE_SEPARATOR) + 1;
00226 int len = in_name.find_last_of('.') - begin_pos;
00227 string partial = in_name.substr(begin_pos, len);
00228
00229 string out_name = partial + ".c";
00230 string tempfile = partial + ".pp";
00231 string cpp_err;
00232 if (do_preprocessing) {
00233 if (preprocess(in_name, tempfile, cpp_err) == false) {
00234 cerr << appname << " error - Preprocessing error: " << cpp_err << endl;
00235 return 1;
00236 }
00237 }
00238 else
00239 tempfile = in_name;
00240
00241 ofstream outfile(out_name.c_str());
00242 if (!outfile.is_open()) {
00243 cerr << appname << " error - unable to open output file: ";
00244 cerr << out_name << "." << endl;
00245 return -1;
00246 }
00247
00248 try {
00249 #ifdef FILE_ITER
00250 file_iterator<char> first(tempfile.c_str());
00251 if (!first) {
00252 cerr << appname << " error - unable to open temporary file: ";
00253 cerr << tempfile << "." << endl;
00254 return -1;
00255 }
00256 file_iterator<char> last = first.make_end();
00257 #else
00258 ifstream infile(tempfile.c_str());
00259 if (!infile) {
00260 cerr << appname << " error - unable to open temporary file: ";
00261 cerr << tempfile << "." << endl;
00262 return -1;
00263 }
00264 infile.unsetf(ios::skipws);
00265 vector<char> vec;
00266 copy(istream_iterator<char>(infile),
00267 istream_iterator<char>(),
00268 back_inserter(vec));
00269 vector<char>::const_iterator first = vec.begin();
00270 vector<char>::const_iterator last = vec.end();
00271 #endif
00272
00273 grammar_t g;
00274 skip_t s;
00275 functor_t f(outfile);
00276 functor_ptr = &f;
00277
00278 #ifdef FILE_ITER
00279 parse_info< file_iterator<char> > info;
00280 #else
00281 parse_info<vector<char>::const_iterator> info;
00282 #endif
00283 info = parse(first, last, g, s);
00284
00285 cerr << "Parse succeeding ..." << endl;
00286
00287 #ifndef FILE_ITER
00288 infile.close();
00289 #endif
00290 if (do_preprocessing && do_unlink)
00291 unlink(tempfile.c_str());
00292
00293 if (!info.full) {
00294 cerr << appname << " error - " << in_name << ": ";
00295 for (int i = 0; i < 50; i++) {
00296 if (info.stop == last)
00297 break;
00298 cerr << *info.stop++;
00299 }
00300 cerr << endl;
00301 #ifdef _DEBUG
00302 cerr << "Parse failed." << endl;
00303 #endif
00304 return -1;
00305 }
00306 }
00307 catch (exception &e) {
00308 cerr << appname << " error - " << e.what() << endl;
00309 return -1;
00310 }
00311
00312
00313
00314 outfile.close();
00315 #ifdef _DEBUG
00316 cerr << "Parse succeeded." << endl;
00317 #endif
00318 return 0;
00319 }