/* $XConsortium: main.cxx,v 1.7 94/09/23 13:38:28 matt Exp $ */ /* * Copyright (c) 1992-1993 Silicon Graphics, Inc. * Copyright (c) 1993 Fujitsu, Ltd. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Silicon Graphics and Fujitsu may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Silicon Graphics and Fujitsu. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SILICON GRAPHICS OR FUJITSU BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ /* * Main program for C++ parser. */ #include "err.h" #include "expr.h" #include "scanner.h" #include "list.h" #include #include #if defined(AIXV3) extern "C" int yyparse(); #else extern int yyparse(); #endif extern Expr* yyparse_root; #if defined(YYDEBUG) extern int yydebug; #endif declarePtrList(StringList,String) /* generate.cxx has implementPtrList(StringList,String) */ class App { public: App() { } int main(int argc, char** argv); private: Expr* root_; ConfigInfo gen_; const char* filter_; ErrorHandler* errors_; Boolean verbose_; Boolean timing_; Boolean scanning_only_; Boolean resolving_; Boolean generating_; Boolean filtering_; Boolean ucase_; unsigned long heapstart_; unsigned long curheapsize(); void init(); void get_args(int, char**); const char* get_next_arg(long& i, int argc, char** argv); void run(); void parse(); void resolve(Resolver*); void generate(Generator*); void filter(Generator*); void finish(); void stage(const char*); void missing(const char* arg); void bad_arg(const char* arg); void bad_access(const char* filename, Boolean readable); }; int main(int argc, char** argv) { App a; return a.main(argc, argv); } int App::main(int argc, char** argv) { init(); get_args(argc, argv); if (errors_->count() == 0) { run(); } finish(); return errors_->count(); } void App::init() { root_ = nil; gen_.filename = nil; gen_.stubfile = nil; gen_.serverfile = nil; gen_.inclpath = nil; gen_.inclext = ".h"; gen_.includes = new StringList; gen_.stub_includes = new StringList; gen_.server_includes = new StringList; gen_.superclass = nil; gen_.metaclass = nil; gen_.envclass = nil; gen_.envfirst = false; gen_.buffer = "MarshalBuffer"; gen_.exchange = "Exchange"; gen_.except = "Exception"; gen_.user_except = "UserException"; gen_.stubclass = nil; gen_.request = nil; gen_.prefix = nil; gen_.direct = "_"; gen_.transcriptions = new StringList; gen_.refobjs = false; gen_.cdecls = false; gen_.cstubs = false; filter_ = nil; ErrorHandlerKit* errkit = new ErrorHandlerKit; errors_ = errkit->handler(); delete errkit; verbose_ = false; timing_ = false; scanning_only_ = false; resolving_ = true; generating_ = true; filtering_ = false; ucase_ = false; heapstart_ = 0; heapstart_ = curheapsize(); String::case_sensitive(true); stage("init"); } void App::get_args(int argc, char** argv) { String arg; for (long i = 1; i < argc; i++) { arg = argv[i]; if (arg == "-filter") { if (filter_ != nil) { errors_->unrecoverable("Only one -filter allowed"); } else { filter_ = get_next_arg(i, argc, argv); if (access(filter_, R_OK + W_OK) < 0) { bad_access(filter_, access(filter_, R_OK) >= 0); } filtering_ = true; } } else if (arg == "-path") { gen_.inclpath = get_next_arg(i, argc, argv); } else if (arg == "-inclext") { gen_.inclext = get_next_arg(i, argc, argv); } else if (arg == "-i" || arg == "-include") { gen_.includes->append(new String(get_next_arg(i, argc, argv))); } else if (arg == "-stubinclude") { gen_.stub_includes->append( new String(get_next_arg(i, argc, argv)) ); } else if (arg == "-serverinclude") { gen_.server_includes->append( new String(get_next_arg(i, argc, argv)) ); } else if (arg == "-s" || arg == "-superclass") { gen_.superclass = get_next_arg(i, argc, argv); } else if (arg == "-m" || arg == "-metaclass") { gen_.metaclass = get_next_arg(i, argc, argv); } else if (arg == "-r" || arg == "-request") { gen_.request = get_next_arg(i, argc, argv); } else if (arg == "-e" || arg == "-env") { gen_.envclass = get_next_arg(i, argc, argv); } else if (arg == "-envfirst") { gen_.envfirst = true; } else if (arg == "-mb") { gen_.buffer = get_next_arg(i, argc, argv); } else if (arg == "-exch") { gen_.exchange = get_next_arg(i, argc, argv); } else if (arg == "-except") { gen_.except = get_next_arg(i, argc, argv); } else if (arg == "-uexcept") { gen_.user_except = get_next_arg(i, argc, argv); } else if (arg == "-c" || arg == "-stubclass") { gen_.stubclass = get_next_arg(i, argc, argv); } else if (arg == "-stubfile") { gen_.stubfile = get_next_arg(i, argc, argv); } else if (arg == "-serverfile") { gen_.serverfile = get_next_arg(i, argc, argv); } else if (arg == "-f" || arg == "-file") { gen_.filename = get_next_arg(i, argc, argv); } else if (arg == "-p" || arg == "-prefix") { gen_.prefix = get_next_arg(i, argc, argv); } else if (arg == "-direct") { gen_.direct = nil; } else if (arg == "-indirect") { gen_.direct = get_next_arg(i, argc, argv); } else if (arg == "-refobjs") { gen_.refobjs = true; } else if (arg == "-extern") { gen_.transcriptions->append( new String(get_next_arg(i, argc, argv)) ); } else if (arg == "-cdecls") { gen_.cdecls = true; gen_.direct = nil; } else if (arg == "-cstubs") { gen_.cstubs = true; } else if (arg == "-cs") { ucase_ = true; } else if (arg == "-debug") { const char* debugflags = get_next_arg(i, argc, argv); for (const char* p = debugflags; *p != '\0'; p++) { switch (*p) { #if defined(YYDEBUG) case 'y': yydebug = 1; break; #endif case 's': scanning_only_ = true; break; case 't': timing_ = true; generating_ = false; break; case 'v': verbose_ = true; break; case 'p': resolving_ = false; generating_ = false; filtering_ = false; break; case 'r': resolving_ = true; generating_ = false; filtering_ = false; break; case 'c': resolving_ = true; generating_ = true; filtering_ = false; default: errors_->begin_unrecoverable(); errors_->put_chars("Unknown debug flag '"); errors_->put_chars(p); errors_->put_chars("'"); errors_->end(); } } } else { bad_arg(argv[i]); } } } const char* App::get_next_arg(long& i, int argc, char** argv) { long next_i = i + 1; if (next_i >= argc) { missing(argv[i]); return nil; } i = next_i; return argv[i]; } void App::run() { ScannerKit* scanners = new ScannerKit; Scanner* s = scanners->make_scanner(nil, errors_, ucase_); if (scanning_only_) { if (timing_) { while (s->get_token() != 0); } else { for (TokenType t = s->get_token(); t != 0; t = s->get_token()) { s->print_token(t); printf("\n"); } } } else { ExprKit* exprs = new ExprKit(errors_); gen_.symbols = exprs->symbol_table(); Resolver* r = exprs->resolver(gen_); Generator* g = exprs->generator(gen_); parse(); resolve(r); generate(g); filter(g); delete exprs; } s->destroy(); delete scanners; } void App::parse() { stage("parsing"); yyparse(); root_ = yyparse_root; } void App::resolve(Resolver* r) { if (errors_->count() == 0 && resolving_) { stage("resolving"); root_->resolve(r); } } void App::generate(Generator* g) { if (errors_->count() == 0 && generating_ && !filtering_) { stage("generating"); root_->generate(g); } } void App::filter(Generator* g) { if (errors_->count() == 0 && filtering_) { stage("filtering"); String s(filter_); errors_->position()->set(&s, 0); freopen(filter_, "r", stdin); root_->generate_impl(g); fclose(stdin); } } void App::finish() { stage("finish"); } #if !defined(AIXV3) && !defined(__osf__) extern "C" { void* sbrk(int); } #endif unsigned long App::curheapsize() { return (((unsigned long)sbrk(0) + 1023) >> 10) - heapstart_; } void App::stage(const char* s) { if (verbose_) { errors_->begin_comment(); errors_->put_chars(s); errors_->put_chars("("); errors_->put_integer(curheapsize()); errors_->put_chars("k)"); errors_->end(); } } void App::bad_arg(const char* arg) { errors_->begin_unrecoverable(); errors_->put_chars("Unexpected argument "); errors_->put_chars(arg); errors_->end(); } void App::missing(const char* arg) { errors_->begin_unrecoverable(); errors_->put_chars("Expected argument after "); errors_->put_chars(arg); errors_->end(); } void App::bad_access(const char* filename, Boolean readable) { errors_->begin_unrecoverable(); if (readable) { errors_->put_chars("Can't write \""); } else { errors_->put_chars("Can't read \""); } errors_->put_chars(filename); errors_->put_chars("\""); errors_->end(); }