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