main.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file main.cpp
00004  * \brief Main program for CVC_lite
00005  * 
00006  * Author: Clark Barrett
00007  * 
00008  * Created: Wed Dec  4 17:21:10 2002
00009  *
00010  * <hr>
00011  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 
00030 
00031 #include <signal.h>
00032 #include <unistd.h>
00033 #include <fstream>
00034 #include <iomanip>
00035 
00036 
00037 #include "vc.h"
00038 #include "parser.h"
00039 #include "vc_cmd.h"
00040 #include "command_line_flags.h"
00041 #include "statistics.h"
00042 
00043 
00044 using namespace std;
00045 using namespace CVCL;
00046 
00047 
00048 static void parse_args(int argc, char **argv, CLFlags &flags,
00049                        string& fileName);
00050 static void printUsage(const CLFlags& flags);
00051 
00052 // Our own name 
00053 static string programName;
00054 
00055 IF_DEBUG(static DebugTimer runtime(CVCL::debugger.timer("total runtime")));
00056 
00057 static ValidityChecker* vc = NULL;
00058 
00059 void sighandler(int signum) {
00060   cerr << "\nInterrupted by signal " << signum;
00061   if(signum == SIGALRM)
00062     cerr << " (self-timeout)";
00063   cerr << ".  " << programName << " is aborting.\n";
00064   // Print the debugging info
00065   IF_DEBUG(CVCL::debugger.setElapsed(runtime));
00066   IF_DEBUG(debugger.printAll());
00067   if(vc != NULL && vc->getFlags()["stats"].getBool())
00068     cout << vc->getStatistics() << endl;
00069   exit(1);
00070 }
00071 
00072 int main(int argc, char **argv)
00073 {
00074   CLFlags flags(ValidityChecker::createFlags());
00075   programName = string(argv[0]);
00076  
00077   signal(SIGINT, sighandler);
00078   signal(SIGTERM, sighandler);
00079   signal(SIGQUIT, sighandler);
00080   signal(SIGALRM, sighandler);
00081 
00082   string fileName("");
00083 
00084   try {
00085     parse_args(argc, argv, flags, fileName);
00086   } catch(Exception& e) {
00087     cerr << "*** " << e;
00088     cerr << "\n\nRun with -help option for usage information." << endl;
00089     exit(1);
00090   }
00091 
00092   // Set the timeout, if given in the command line options
00093   int timeout = flags["timeout"].getInt();
00094   if(timeout > 0) {
00095     alarm(timeout);
00096   }
00097 
00098   /*
00099    * Create and run the validity checker
00100    */ 
00101 
00102   // Debugging code may throw an exception
00103   try {
00104     vc = ValidityChecker::create(flags);
00105   } catch(Exception& e) {
00106     cerr << "*** Fatal exception: " << e << endl;
00107     exit(1);
00108   }
00109 
00110   IF_DEBUG( // Initialize the global debugger
00111            CVCL::debugger.init(&(vc->getFlags()["trace"].getStrVec()),
00112                                &(vc->getFlags()["dump-trace"].getString()));
00113   );
00114 
00115   // -h flag sets "help" to false (+h would make it true, but that's
00116   // not what the user normally types in).
00117   if(!vc->getFlags()["help"].getBool()) {
00118     printUsage(vc->getFlags());
00119     return 0;
00120   }
00121 #ifndef VERSION
00122 #define VERSION "unknown"
00123 #endif
00124   // Similarly, -version sets the flag "version" to false
00125   if(!vc->getFlags()["version"].getBool()) {
00126     cout << "This is CVC Lite version " << VERSION
00127       IF_DEBUG( << " (debug build)")
00128          << "\n\n";
00129     cout <<
00130       "Copyright (C) 2003 by the Board of Trustees of Leland Stanford Junior\n"
00131       "University and by New York University.\n\n"
00132       "THIS SOFTWARE PROVIDED AS-IS, WITHOUT ANY WARRANTIES. "
00133       "USE IT AT YOUR OWN RISK.\n"
00134          << endl;
00135     return 0;
00136   }
00137 
00138   try {
00139     // Test if the output language is correctly specified; if not, an
00140     // exception will be thrown
00141     vc->getEM()->getOutputLang();
00142     // Set the timer
00143     IF_DEBUG(CVCL::debugger.setCurrentTime(runtime));
00144     // Read the input file
00145     vc->loadFile(fileName, vc->getEM()->getInputLang(),
00146                  flags["interactive"].getBool());
00147   } catch(Exception& e) {
00148     cerr << "*** Fatal exception: " << e << endl;
00149     exit(1);
00150   }
00151 
00152   IF_DEBUG(CVCL::debugger.setElapsed(runtime));
00153 
00154   if (!flags["quiet"].getBool())
00155       cout << "\n" << programName << " is done.\n";
00156 
00157   // Print the debugging info
00158   IF_DEBUG(debugger.printAll());
00159   // Print statistics
00160   if(vc->getFlags()["stats"].getBool()) vc->printStatistics();
00161   // Destruct the system
00162   TRACE_MSG("delete", "Deleting ValidityChecker [last trace from main.cpp]");
00163   delete vc;
00164   return 0;
00165 }
00166 
00167 void printUsage(const CLFlags& flags) {
00168   cout << "Usage: " << programName << " [options]\n"
00169        << programName << " will read the input from STDIN and \n"
00170        << "print the result on STDOUT.\n"
00171        << "Boolean (b) options are set 'on' by +option and 'off' by -option\n"
00172        << "(for instance, +sat or -sat).\n"
00173        << "Integer (i), string (s) and vector (v) options \n"
00174        << "require a parameter, e.g. -width 80\n" 
00175        << "Also, (v) options can appear multiple times setting "
00176        << "args on and off,\n"
00177        << "as in +trace \"enable this\" -trace \"disable that\".\n"
00178        << "Option names can be abbreviated to the "
00179        << "shortest unambiguous prefix.\n\n"
00180        << "The options are:\n";
00181   vector<string> names;
00182   // Get all the names of options (they all match the empty string)
00183   flags.countFlags("", names);
00184   for(size_t i=0,iend=names.size(); i!=iend; ++i) {
00185     const CLFlag& f(flags[names[i]]);
00186     string tpStr; // Print type of the option
00187     string pref; // Print + or - in front of the option
00188     string name(names[i]); // Print name and optionally the value
00189     CLFlagType tp = f.getType();
00190     switch(tp) {
00191     case CLFLAG_NULL: tpStr = "(null)"; break;
00192     case CLFLAG_BOOL:
00193       tpStr = "(b)"; pref = (f.getBool())? "+" : "-";
00194       break;
00195     case CLFLAG_INT:
00196       tpStr = "(i)"; pref = "-"; name = name+" "+int2string(f.getInt());
00197       break;
00198     case CLFLAG_STRING:
00199       tpStr = "(s)"; pref = "-"; name = name+" "+f.getString();
00200       break;
00201     case CLFLAG_STRVEC:
00202       tpStr = "(v)"; pref = "-"; name = name;
00203       break;
00204     default:
00205       DebugAssert(false, "printUsage: unknown flag type");
00206     }
00207     cout << " " << tpStr << " " << pref << setw(15);
00208     cout.setf(ios::left);
00209     cout << name << " " << f.getHelp() << "\n";
00210   }
00211   cout << endl;
00212 }
00213   
00214 
00215 void parse_args(int argc, char **argv, CLFlags &flags, string& fileName) {
00216   /* skip 0'th argument */
00217   argv++;
00218   argc--;
00219   bool seenFileName(false);
00220 
00221   for( ; argc > 0; argc--, argv++) {
00222     if((*argv)[0] == '-' || (*argv)[0] == '+') {
00223       // A command-line option
00224       vector<string> names;
00225       bool val = ((*argv)[0] == '+');
00226       size_t n = flags.countFlags((*argv)+1, names);
00227       if(n == 0)
00228         throw CLException(string(*argv) + " does not match any known option");
00229       else if(n > 1) {
00230         ostringstream ss;
00231         ss << *argv << " is ambiguous.  Possible matches are:\n";
00232         for(size_t i=0,iend=names.size(); i!=iend; ++i) {
00233           ss << "  " << names[i] << "\n";
00234         }
00235         throw CLException(ss.str());
00236       } else {
00237         string name = names[0];
00238         // Single match; process the option
00239         CLFlagType tp = flags[name].getType();
00240         switch(tp) {
00241         case CLFLAG_BOOL: flags.setFlag(name, val); break;
00242         case CLFLAG_INT:
00243           argc--;
00244           if(argc <= 0)
00245             throw CLException(string(*argv)+" (-"+name
00246                               +") expects an integer argument.");
00247           argv++;
00248           // FIXME: test for *argv being an integer string
00249           flags.setFlag(name, atoi(*argv));
00250           break;
00251         case CLFLAG_STRING:
00252           argc--;
00253           if(argc <= 0)
00254             throw CLException(string(*argv)+" (-"+name
00255                               +") expects a string argument.");
00256           argv++;
00257           flags.setFlag(name, *argv);
00258           break;
00259         case CLFLAG_STRVEC:
00260           argc--;
00261           if(argc <= 0)
00262             throw CLException(string(*argv)+" (-"+name
00263                               +") expects a string argument.");
00264           argv++;
00265           flags.setFlag(name, pair<string,bool>(*argv,val));
00266           break;
00267         default:
00268           DebugAssert(false, "parse_args: Bad flag type: "+int2string(tp));
00269         }
00270       }
00271     } else if(seenFileName) {
00272       throw CLException("More than one file name given: "+fileName
00273                         +" and "+string(*argv));
00274     } else {
00275       fileName = string(*argv);
00276       seenFileName = true;
00277     }
00278   }
00279 }

Generated on Thu Apr 13 16:57:32 2006 for CVC Lite by  doxygen 1.4.4