00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00086 #include <getopt.h>
00087 #include <cstring>
00088 #include <cstdlib>
00089 #include "executor.h"
00090 #include "version.h"
00091 #include "debug.h"
00092 #include "invalidargumentexception.h"
00093 #include "stringdefs.h"
00094
00096 using namespace std;
00097
00098 #ifdef DBG_YACC
00099
00104 extern int yydebug;
00105 #endif
00106
00111 Executor *exec = NULL;
00112
00117 enum short_opts {
00118
00119 opt_iqstream = '1',
00120 opt_ixstream = '2',
00121 opt_oestream = '3',
00122 opt_odstream = '4',
00123 opt_query_arg = 'q',
00124 opt_xml_arg = 'x',
00125 opt_eout_arg = 'e',
00126 opt_dout_arg = 'o',
00127
00128 opt_debug = 'd',
00129
00130 opt_streamdebug = 's',
00131 opt_streamnodebug = 'b',
00132
00133 opt_fragmentxq = 'f',
00134
00135 opt_version = 'v',
00136 opt_about = 'a',
00137 opt_help = 'h',
00138 };
00139
00144 static struct option long_options[] = {
00145
00146 {"iqstream", required_argument, 0, opt_iqstream},
00147 {"ixstream", required_argument, 0, opt_ixstream},
00148 {"oestream", required_argument, 0, opt_oestream},
00149 {"odstream", required_argument, 0, opt_odstream},
00150 {"query", required_argument, 0, opt_query_arg},
00151 {"xml", required_argument, 0, opt_xml_arg},
00152 {"eout", required_argument, 0, opt_eout_arg},
00153 {"dout", required_argument, 0, opt_dout_arg},
00154
00155 {"debug", no_argument, 0, opt_debug},
00156
00157 {"streamdebug", no_argument, 0, opt_streamdebug},
00158 {"streamnodebug", no_argument, 0, opt_streamnodebug},
00159
00160 {"fragmentxq", no_argument, 0, opt_fragmentxq},
00161
00162 {"version", no_argument, 0, opt_version},
00163 {"about", no_argument, 0, opt_about},
00164 {"help", no_argument, 0, opt_help},
00165 {0, 0, 0, 0}
00166 };
00167
00172 static struct descriptions {
00177 int val;
00178
00183 const char *desc;
00184 }
00185 options_descriptions[] = {
00190
00191 {
00192 opt_iqstream, ": input stream type of query"}, {
00193 opt_ixstream, ": input stream type of xml"}, {
00194 opt_oestream, ": output stream type of query result"}, {
00195 opt_odstream, ": output stream type of debug output"}, {
00196 opt_query_arg, ""}, {
00197 opt_xml_arg, ""}, {
00198 opt_eout_arg, ""}, {
00199 opt_dout_arg, ""},
00200
00201 {
00202 opt_debug, ": print detailed debug information"},
00203
00204 {
00205 opt_streamdebug, ": process stream only (with debug output)"}, {
00206 opt_streamnodebug, ": process stream only (without debug output)"},
00207
00208 {
00209 opt_fragmentxq, ": print supported XQuery fragment (XQ)"},
00210
00211 {
00212 opt_version, ": print version number and compile flags"}, {
00213 opt_about, ": print about information"}, {
00214 opt_help, ": print this information"}
00215 };
00216
00222 void printFragmentXQ() {
00223 cout << FRAGMENT_TXT << endl;
00224 }
00225
00231 void printVersionNumber() {
00232 cout << "This Is \"GCX\" Version " << VERSION_NUMBER << endl;
00233 cout << "Compiled With The Following Flags:";
00234 cout << endl;
00235
00236 cout << " ROLE REFCOUNT => " <<
00237 #ifdef ROLE_REFCOUNT
00238 "on";
00239 #else
00240 "off";
00241 #endif // ifdef ROLE_REFCOUNT
00242 cout << endl;
00243
00244 cout << " NO_OPTIMIZATIONS => " <<
00245 #ifdef NO_OPTIMIZATIONS
00246 "on";
00247 #else
00248 "off";
00249 #endif // ifdef NO_OPTIMIZATIONS
00250 cout << endl;
00251
00252 cout << " REWRITE_VARSTEPS => " <<
00253 #ifdef REWRITE_VARSTEPS
00254 "on";
00255 #else
00256 "off";
00257 #endif // REWRITE_VARSTEPS
00258 cout << endl;
00259
00260 cout << " VALIDATION => " <<
00261 #ifdef VALIDATION
00262 "on";
00263 #else
00264 "off";
00265 #endif // VALIDATION
00266 cout << endl;
00267 }
00268
00274 void printAbout() {
00275 cout << LICENSE_TXT << endl;
00276 cout << "----------------------------------------" << endl << endl;
00277 cout <<
00278 "Contributors: Michael Schmidt (mschmidt@informatik.uni-freiburg.de), Author"
00279 << endl;
00280 cout <<
00281 " Gunnar Jehl (jehl@informatik.uni-freiburg.de), Author" <<
00282 endl;
00283 cout << " Christoph Koch (koch@cs.cornell.edu)" << endl;
00284 cout << " Stefanie Scherzinger, Author" << endl;
00285 }
00286
00294 void invalidCall(const char *exec_name) {
00295 cout << "Usage: " << exec_name << " [STD EVAL MODE] or" << endl;
00296 cout << " " << exec_name << " [EXT EVAL MODE] or" << endl;
00297 cout << " " << exec_name << " [INFO MODE]";
00298 cout << endl << endl;
00299 cout <<
00300 "[STD EVAL MODE] ::= --query <query_file> [--xml <xml_file>] [OPTION]?"
00301 << endl;
00302 cout <<
00303 " (--xml <xml_file> required if document is not given in query)"
00304 << endl;
00305 cout << "[EXT EVAL MODE] ::= [STREAM SPEC]+ [OPTION]?" << endl;
00306 cout << " [OPTION] ::= choose one of the following" << endl;
00307 for (unsigned i = 8; long_options[i].name && i < 11; i++) {
00308 cout << " --" << long_options[i].
00309 name << " " << options_descriptions[i].desc << endl;
00310 }
00311 cout << endl;
00312 cout << " [STREAM SPEC] ::= choose one of the following" << endl;
00313 for (unsigned i = 0; long_options[i].name && i < 2; i++) {
00314 cout << " --" << long_options[i].
00315 name << " [INPUT TYPE] [PARAM]? " << options_descriptions[i].
00316 desc << endl;
00317 }
00318 for (unsigned i = 2; long_options[i].name && i < 4; i++) {
00319 cout << " --" << long_options[i].
00320 name << " [OUTPUT TYPE] [PARAM]? " << options_descriptions[i].
00321 desc << endl;
00322 }
00323 cout << endl;
00324 cout << " [INPUT TYPE] ::= choose one of the following" << endl;
00325 cout << " file : file input (DEFAULT)" << endl;
00326 cout <<
00327 " -> when used with --iqstream provide parameter --query <query_file>"
00328 << endl;
00329 cout <<
00330 " -> when used with --ixstream provide parameter --xml <xml_file>"
00331 << endl;
00332 cout << " (required if document is not given in query)" << endl;
00333 cout <<
00334 " null : no input (support only for --ixstream for debugging purposes)"
00335 << endl;
00336 cout << " stdin : standard input (either for query or for xml document)"
00337 << endl;
00338 cout << endl;
00339 cout << " [OUTPUT TYPE] ::= choose one of the following" << endl;
00340 cout << " file : file output" << endl;
00341 cout <<
00342 " -> when used with --oestream provide parameter --eout <eval_output_file>"
00343 << endl;
00344 cout <<
00345 " -> when used with --odstream provide parameter --dout <debug_output_file>"
00346 << endl;
00347 cout << " null : no output" << endl;
00348 cout << " stdout : standard output (DEFAULT)" << endl;
00349 cout << endl;
00350 cout << "EXAMPLES:" << endl;
00351 cout << exec_name << " --query query.xq --xml doc.xml" << endl;
00352 cout <<
00353 " => query input from file \"query.xq\" and xml input from file \"doc.xml\""
00354 << endl;
00355 cout << " => query result output to stdout" << endl;
00356 cout << exec_name <<
00357 " --iqstream stdin --xml doc.xml --odstream file --dout debug.out --debug"
00358 << endl;
00359 cout << " => query input from stdin and xml input from file \"doc.xml\"" <<
00360 endl;
00361 cout <<
00362 " => debug output to file \"debug.out\" and query result output to stdout"
00363 << endl;
00364 cout << exec_name <<
00365 " --query query.xq --xml doc.xml --oestream file --eout result.xml --odstream null --debug"
00366 << endl;
00367 cout <<
00368 " => query input from file \"query.xq\" and xml input from file \"doc.xml\""
00369 << endl;
00370 cout <<
00371 " => discard debug output and query result output to file \"result.xml\""
00372 << endl;
00373 cout << endl;
00374 cout << "[INFO MODE] ::= choose one of the following" << endl;
00375 for (unsigned i = 11; long_options[i].name; i++) {
00376 cout << " --" << long_options[i].
00377 name << " " << options_descriptions[i].desc << endl;
00378 }
00379 }
00380
00387 ISTREAM_TYPE getInputStreamType(const char *arg) {
00388 if (strcmp(arg, "file") == 0) {
00389 return it_file;
00390 } else if (strcmp(arg, "null") == 0) {
00391 return it_null;
00392 } else if (strcmp(arg, "socket") == 0) {
00393 return it_socket;
00394 } else {
00395 return it_stdin;
00396 }
00397 }
00398
00405 OSTREAM_TYPE getOutputStreamType(const char *arg) {
00406 if (strcmp(arg, "file") == 0) {
00407 return ot_file;
00408 } else if (strcmp(arg, "null") == 0) {
00409 return ot_null;
00410 } else if (strcmp(arg, "socket") == 0) {
00411 return ot_socket;
00412 } else {
00413 return ot_stdout;
00414 }
00415 }
00416
00422 void executeOnExit() {
00423 delete exec;
00424
00425 exec = NULL;
00426 }
00427
00436 int main(int argc, char **argv) {
00437
00438 #ifdef DBG_YACC
00439 yydebug = 1;
00440 #endif
00441
00442 ISTREAM_TYPE query_istream_type(it_file);
00443 ISTREAM_TYPE xml_istream_type(it_file);
00444 OSTREAM_TYPE eout_ostream_type(ot_stdout);
00445 OSTREAM_TYPE dout_ostream_type(ot_stdout);
00446 const char *query_arg(NULL);
00447 const char *xml_arg(NULL);
00448 const char *eout_arg(NULL);
00449 const char *dout_arg(NULL);
00450 bool debug(false);
00451 bool preprocess_stream_debug(false);
00452 bool preprocess_stream_no_debug(false);
00453
00454 if (argc == 1) {
00455 invalidCall(argv[0]);
00456 return EXIT_SUCCESS;
00457 }
00458
00459 unsigned idx = 0;
00460 unsigned req_arg = 0;
00461
00462 for (unsigned i = 0; long_options[i].name; i++) {
00463 if (long_options[i].has_arg == required_argument) {
00464 req_arg++;
00465 }
00466 }
00467 char short_options[(sizeof (long_options) / sizeof (long_options[0]) - 1) +
00468 req_arg];
00469 for (unsigned i = 0; long_options[i].name; i++) {
00470 short_options[idx++] = long_options[i].val;
00471 if (long_options[i].has_arg == required_argument) {
00472 short_options[idx++] = ':';
00473 }
00474 }
00475
00476 while (1) {
00477 int option_index = 0;
00478
00479 short_options[idx] = 0;
00480 int option_int = getopt_long(argc, argv, short_options, long_options,
00481 &option_index);
00482
00483 if (option_int == -1) {
00484 break;
00485 }
00486
00487 switch (option_int) {
00488 case 0:
00489 break;
00490 case opt_iqstream:
00491 if (optarg) {
00492 query_istream_type = getInputStreamType(optarg);
00493 }
00494 break;
00495 case opt_ixstream:
00496 if (optarg) {
00497 xml_istream_type = getInputStreamType(optarg);
00498 }
00499 break;
00500 case opt_oestream:
00501 if (optarg) {
00502 eout_ostream_type = getOutputStreamType(optarg);
00503 }
00504 break;
00505 case opt_odstream:
00506 if (optarg) {
00507 dout_ostream_type = getOutputStreamType(optarg);
00508 }
00509 break;
00510 case opt_query_arg:
00511 if (optarg) {
00512 query_arg = optarg;
00513 }
00514 break;
00515 case opt_xml_arg:
00516 if (optarg) {
00517 xml_arg = optarg;
00518 }
00519 break;
00520 case opt_eout_arg:
00521 if (optarg) {
00522 eout_arg = optarg;
00523 }
00524 break;
00525 case opt_dout_arg:
00526 if (optarg) {
00527 dout_arg = optarg;
00528 }
00529 break;
00530 case opt_debug:
00531 if (!preprocess_stream_no_debug) {
00532 debug = true;
00533 }
00534 break;
00535 case opt_streamdebug:
00536 if (!preprocess_stream_no_debug && !debug) {
00537 preprocess_stream_debug = true;
00538 debug = true;
00539 }
00540 break;
00541 case opt_streamnodebug:
00542 if (!preprocess_stream_debug && !debug) {
00543 preprocess_stream_no_debug = true;
00544 debug = false;
00545 }
00546 break;
00547 case opt_fragmentxq:
00548 if (!preprocess_stream_no_debug && !preprocess_stream_debug
00549 && !debug) {
00550 printFragmentXQ();
00551 return EXIT_SUCCESS;
00552 }
00553 break;
00554 case opt_version:
00555 if (!preprocess_stream_no_debug && !preprocess_stream_debug
00556 && !debug) {
00557 printVersionNumber();
00558 return EXIT_SUCCESS;
00559 }
00560 break;
00561 case opt_about:
00562 if (!preprocess_stream_no_debug && !preprocess_stream_debug
00563 && !debug) {
00564 printAbout();
00565 return EXIT_SUCCESS;
00566 }
00567 break;
00568 case opt_help:
00569 if (!preprocess_stream_no_debug && !preprocess_stream_debug
00570 && !debug) {
00571 invalidCall(argv[0]);
00572 return EXIT_SUCCESS;
00573 }
00574 break;
00575 case '?':
00576 return EXIT_FAILURE;
00577 default:
00578 return EXIT_FAILURE;
00579 }
00580 }
00581
00582 if (optind < argc) {
00583 cout << endl;
00584 cout << "non-option ARGV-element(s): ";
00585 while (optind < argc) {
00586 cout << argv[optind++] << endl;
00587 }
00588 return EXIT_FAILURE;
00589 }
00590
00591 CmdLine *cmd =
00592 new CmdLine(query_istream_type, xml_istream_type, eout_ostream_type,
00593 dout_ostream_type, query_arg, xml_arg, eout_arg, dout_arg,
00594 debug, preprocess_stream_debug,
00595 preprocess_stream_no_debug);
00596
00597 try {
00598 cmd->checkIntegrity();
00599 }
00600 catch(InvalidArgumentException & e) {
00601 cout << e.getDebugMsg();
00602 return EXIT_FAILURE;
00603 }
00604 catch(Exception & e) {
00605 cout << e.getDebugMsg();
00606 return EXIT_FAILURE;
00607 }
00608
00609 exec = new Executor(cmd);
00610 atexit(executeOnExit);
00611 exec->start();
00612 delete exec;
00613
00614 exec = NULL;
00615
00616 return EXIT_SUCCESS;
00617 }