Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

VestaWeed.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Created on Mon Mar  3 16:31:49 PST 1997 by heydon
00020 
00021 // Last modified on Mon Aug  9 17:27:09 EDT 2004 by ken@xorian.net  
00022 //      modified on Tue Jun 27 17:23:16 PDT 2000 by mann  
00023 //      modified on Mon Jun  7 13:50:10 PDT 1999 by heydon
00024 
00025 // VestaWeed.C -- the Vesta-2 weeder
00026 
00027 #include <Basics.H>
00028 #include <FS.H>
00029 #include <VestaConfig.H>
00030 #include <CacheIntf.H>
00031 #include <CacheConfig.H>
00032 #include <Debug.H>
00033 
00034 #include "WeederConfig.H"
00035 #include "WeedArgs.H"
00036 #include "RootTbl.H"
00037 #include "CommonErrors.H"
00038 #include "Weeder.H"
00039 
00040 using std::cout;
00041 using std::cerr;
00042 using std::endl;
00043 
00044 // ----------------------------------------------------------------------
00045 // version string
00046 
00047 // 1.4: Fixed the keep duration weeding bug that tried to keep all
00048 //      roots for a given build even though only those newer than the
00049 //      keepTime had their children marked.
00050 
00051 static const char *Version = "1.4, 09-May-2002";
00052 // ----------------------------------------------------------------------
00053 
00054 static void SyntaxError(char *msg) throw ()
00055 {
00056     cerr << "Error: " << msg << "; exiting..." << endl;
00057     cerr << "Syntax: VestaWeed " << endl;
00058     cerr << "  [-nodelete | -query] [-models] [-roots] [-keep dur] [-debug level] [file]" << endl;
00059     exit(1);
00060 }
00061 
00062 static void ProcessArgs(int argc, char *argv[], /*OUT*/ WeedArgs &args)
00063   throw ()
00064 {
00065     // set defaults
00066     args.instrFile = (char *)NULL;
00067     args.debug = CacheIntf::None;
00068     args.delStatus = WeedArgs::DoDeletions;
00069     args.globInstrs = false;
00070     args.printRoots = false;
00071     args.keepSecs = 0;
00072 
00073     // process arguments
00074     int arg;
00075     bool sawNorQ = false;
00076     bool sawK = false;
00077     for (arg = 1; arg < argc && *argv[arg] == '-'; arg++) {
00078         if (!strcmp(argv[arg], "-d") || !strcmp(argv[arg], "-debug")) {
00079             arg++;
00080             if (arg >= argc) {
00081                 SyntaxError("no 'level' specified for '-debug'");
00082             }
00083             if (sscanf(argv[arg], "%d", &(args.debug)) != 1) {
00084                 int i;
00085                 for (i = 0; i <= CacheIntf::All; i++) {
00086                   if (strcasecmp(argv[arg], CacheIntf::DebugName(i)) == 0)
00087                     break;
00088                 }
00089                 args.debug = (CacheIntf::DebugLevel)i;
00090             }
00091             if (args.debug < CacheIntf::None || args.debug > CacheIntf::All) {
00092                 SyntaxError("unrecognized debug level");
00093             }
00094         } else if (strcmp(argv[arg], "-n") == 0 ||
00095                    strcmp(argv[arg], "-nodelete") == 0) {
00096             if (sawNorQ) {
00097                 SyntaxError("-nodelete and -query are mutually exclusive");
00098             }
00099             sawNorQ = true;
00100             args.delStatus = WeedArgs::NoDeletions;
00101         } else if (strcmp(argv[arg], "-q") == 0 ||
00102                    strcmp(argv[arg], "-query") == 0) {
00103             if (sawNorQ) {
00104                 SyntaxError("-nodelete and -query are mutually exclusive");
00105             }
00106             sawNorQ = true;
00107             args.delStatus = WeedArgs::QueryDeletions;
00108         } else if (strcmp(argv[arg], "-m") == 0 ||
00109                    strcmp(argv[arg], "-models") == 0) {
00110             args.globInstrs = true;
00111         } else if (strcmp(argv[arg], "-r") == 0 ||
00112                    strcmp(argv[arg], "-roots") == 0) {
00113             args.printRoots = true;
00114         } else if (!strcmp(argv[arg], "-k") || !strcmp(argv[arg], "-keep")) {
00115             arg++;
00116             if (arg >= argc) {
00117                 SyntaxError("no duration argument specified for '-keep'");
00118             }
00119             sawK = true;
00120             char *dur = argv[arg];
00121             int last = strlen(dur) - 1;
00122             int units = 60 * 60; // default is "hours"
00123             switch (dur[last]) {
00124               case 'd': units = 60 * 60 * 24; break;
00125               case 'h': units = 60 * 60; break;
00126               case 'm': units = 60; break;
00127               default:
00128                 if (!isdigit(dur[last])) {
00129                     SyntaxError("unrecognized unit specifier for '-keep' arg");
00130                     exit(1);
00131                 }
00132             }
00133             if (sscanf(argv[arg], "%d", &(args.keepSecs)) != 1) {
00134                 SyntaxError("argument following '-keep' is not an integer");
00135             }
00136             if (args.keepSecs < 0) {
00137                 SyntaxError("argument following '-keep' cannot be negative");
00138             }
00139             args.keepSecs *= units; // convert to appropriate units
00140         } else {
00141             SyntaxError("unrecognized command-line switch");
00142         }
00143     }
00144     if (arg < argc - 1) {
00145         SyntaxError("too many arguments");
00146     } else if (arg < argc) {
00147         assert(arg == argc - 1);
00148         args.instrFile = argv[arg];
00149         args.noNew = false;
00150     } else {
00151         args.noNew = true;  // finish an old weed but don't start a new one
00152         if (sawK) {
00153           SyntaxError("-keep flag is meaningless with no input filename");
00154         }
00155         if (args.globInstrs) {
00156           SyntaxError("-models flag is meaningless with no input filename");
00157         }
00158         if (args.printRoots) {
00159           SyntaxError("-roots flag is meaningless with no input filename");
00160         }
00161     }
00162 
00163     // echo command-line if necessary
00164     if (args.debug >= CacheIntf::StatusMsgs) {
00165         cout << Debug::Timestamp() << "Command-line:" << endl << "  ";
00166         for (int i = 0; i < argc; i++) {
00167             cout << argv[i] << ' ';
00168         }
00169         cout << endl << endl;
00170     }
00171 }
00172 
00173 static bool CentralCache() throw ()
00174 {
00175     return (Config_Host == WeedConfig_CacheHost)
00176       && (Config_Port == WeedConfig_CachePort)
00177       && (Config_MDRoot == WeedConfig_CacheMDRoot)
00178       && (Config_MDDir == WeedConfig_CacheMDDir)
00179       && (Config_GraphLogDir == WeedConfig_CacheGLDir);
00180 }
00181 
00182 int main(int argc, char *argv[]) 
00183 {
00184     // process command-line
00185     WeedArgs args;
00186     ProcessArgs(argc, argv, /*OUT*/ args);
00187 
00188     // check that we are not running on local cache
00189     if (!CentralCache()) {
00190         cerr << "Fatal error: weeder must be run against the central cache!";
00191         cerr << " Exiting..." << endl;
00192         exit(1);
00193     }
00194 
00195     try {
00196         // initialize the weeder
00197         Weeder weeder(args.debug);
00198 
00199         // status message
00200         if (args.debug >= CacheIntf::StatusMsgs) {
00201             cout << Debug::Timestamp() << "Weeder started:" << endl;
00202             cout << "  Version: " << Version << endl;
00203             cout << "  Configuration file: " <<
00204               VestaConfig::get_location() << endl;
00205             cout << "  Graph log directory: " << Config_GraphLogPath << endl;
00206             cout << "  Keeping all builds less than "
00207                  << args.keepSecs / 3600 << " hours old" << endl;
00208             cout << "  Debugging level = "
00209                  << CacheIntf::DebugName(args.debug) << endl;
00210             cout << endl;
00211         }
00212 
00213         // do the weed, or resume an old weed
00214         bool resumed = weeder.Weed(args);
00215 
00216         if (resumed) {
00217            // finished an old weed; now need to do the new one
00218            Weeder weeder2(args.debug);
00219            (void) weeder2.Weed(args);
00220         }
00221 
00222     }
00223     catch (SRPC::failure &f) {
00224         cerr << "SRPC failure:" << endl;
00225         cerr << "  " << f.msg << endl;
00226         cerr << "Exiting..." << endl;
00227         exit(1);
00228     }
00229     catch (FS::DoesNotExist) {
00230         cerr << "Error: file '" << args.instrFile << "' does not exist"<< endl;
00231         cerr << "Exiting..." << endl;
00232         exit(1);
00233     }
00234     catch (FS::EndOfFile) {
00235         cerr << "Error: premature end-of-file; exiting..." << endl;
00236         exit(1);
00237     }
00238     catch (FS::Failure &f) {
00239         cerr << "Error: reading input file:" << endl;
00240         cerr << "  " << f << endl;
00241         cerr << "Exiting..." << endl;
00242         exit(1);
00243     }
00244     catch (VestaLog::Error &err) {
00245         cerr << "VestaLog fatal error -- failed reading graph log:" << endl;
00246         cerr << "  " << err.msg << endl;
00247         cerr << "Exiting..." << endl;
00248         exit(1);
00249     }
00250     catch (VestaLog::Eof) {
00251         cerr << "VestaLog fatal error: ";
00252         cerr << "unexpected EOF while reading graph log; exiting..." << endl;
00253         exit(1);
00254     }
00255     catch (InputError &err) {
00256         cerr << "Error in input file '" << args.instrFile << "':" << endl;
00257         cerr << err;
00258         cerr << "Exiting..." << endl;
00259         exit(1);
00260     }
00261     catch (SysError &err) {
00262         cerr << err;
00263         cerr << "Exiting..." << endl;
00264         exit(1);
00265     }
00266     catch (ReposError &err) {
00267         cerr << err;
00268         cerr << "Exiting..." << endl;
00269         exit(1);
00270     }
00271     return 0;
00272 }

Generated on Mon May 8 00:48:59 2006 for Vesta by  doxygen 1.4.2