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

CountShortIds.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 Wed Aug 20 17:42:54 PDT 1997 by heydon
00020 // Last modified on Mon Aug  9 18:05:10 EDT 2004 by ken@xorian.net  
00021 //      modified on Sat Feb 12 17:57:32 PST 2000 by mann  
00022 //      modified on Thu Aug 21 23:43:20 PDT 1997 by heydon
00023 
00024 #include <sys/types.h> // for stat(2)
00025 #include <sys/stat.h>  // for stat(2)
00026 
00027 #include <Basics.H>
00028 #include <FS.H>
00029 #include <Generics.H>
00030 #include <SourceOrDerived.H>
00031 
00032 #include "HexReader.H"
00033 
00034 using std::ostream;
00035 using std::cout;
00036 using std::cerr;
00037 using std::endl;
00038 
00039 static void Syntax(char *msg, char *arg = NULL) throw ()
00040 {
00041     cerr << "Error: " << msg;
00042     if (arg != NULL) cerr << ": '" << arg << "'";
00043     cerr << endl;
00044     cerr << "Syntax: CountShortIds file ..." << endl;
00045     exit(1);
00046 }
00047 
00048 static char *FileName(char *name) throw ()
00049 {
00050     char *res = name;
00051     if (strncmp(name, "0x", 2) == 0) {
00052         // skip initial "0x"
00053         char *arg = name + 2;
00054 
00055         // parse numeric value
00056         ShortId sid;
00057         if (sscanf(arg, "%x", /*OUT*/ &sid) != 1) {
00058             Syntax("bad 'shortId' argument", name);
00059         }
00060 
00061         // convert to filename
00062         res = SourceOrDerived::shortIdToName(sid, /*tailOnly=*/ false);
00063     }
00064     return res;
00065 }
00066 
00067 static Text FormattedSz(double sz) throw ()
00068 {
00069     const double OneK = 1024.0;
00070     char buff[20];
00071     if (sz < OneK) {
00072         sprintf(buff, "%.1f", sz);
00073     } else {
00074         sz /= OneK;
00075         char suffix = 'K';
00076         if (sz >= OneK) {
00077             sz /= OneK;
00078             suffix = 'M';
00079         }
00080         sprintf(buff, "%.1f%c", sz, suffix);
00081     }
00082     return Text(buff);
00083 }
00084 
00085 static void Process(ostream &os, char *path, bool warn)
00086   throw (FS::Failure, FS::DoesNotExist)
00087 {
00088     // print filename to process
00089     os << path << ":" << endl;
00090 
00091     // open the file using a HexReader
00092     HexReader hexrd(path);
00093 
00094     // process the file
00095     IntIntTbl visited(/*sizeHint=*/ 1000);
00096     int lineNum = 1, dummy;
00097     unsigned totalCnt = 0U, uniqueCnt = 0U, skipCnt = 0U;
00098     unsigned long totalSz = 0UL;
00099     ShortId sid;
00100     while (true) {
00101         try {
00102             sid = hexrd.Next();
00103         } catch (const HexReader::BadValue &v) {
00104             if (warn) {
00105                 os << "  Warning: skipping illegal ShortId on line "
00106                    << v.lineNum << ": '" << v.str << "'" << endl;
00107             }
00108             continue;
00109         }
00110         if (sid == 0) break;
00111 
00112         // test if the file is new
00113         totalCnt++;
00114         if (!visited.Get(sid, /*OUT*/ dummy)) {
00115             // update table
00116             bool inTbl = visited.Put(sid, 1); assert(!inTbl);
00117 
00118             // stat file to get its size
00119             char *nm = SourceOrDerived::shortIdToName(sid, /*tailOnly=*/false);
00120             struct stat stat_buff;
00121             if (stat(nm, /*OUT*/ &stat_buff) != 0) {
00122                 if (warn) {
00123                     os << "  Warning: stat(2) failed on '" << nm
00124                        << "'; skipping..." << endl;
00125                 }
00126                 skipCnt++;
00127             } else {
00128                 uniqueCnt++;
00129                 totalSz += stat_buff.st_size;
00130             }
00131             delete nm;
00132         }
00133         lineNum++;
00134     }
00135 
00136     // print results
00137     os << "  Total files processed  = " << totalCnt << endl;
00138     os << "  Unique files processed = " << uniqueCnt << endl;
00139     os << "  Unique files skipped   = " << skipCnt << endl;
00140     os << "  Total size of unique files = "
00141        << FormattedSz((double)totalSz) << endl;
00142     os << "  Mean size of unique files  =  "
00143        << FormattedSz(((double)totalSz)/((double)uniqueCnt)) << endl;
00144 }
00145 
00146 int main(int argc, char *argv[]) 
00147 {
00148     // parse command-line
00149     int arg = 1;
00150     bool warn = false;
00151     if (argc <= 1) Syntax("too few arguments");
00152     while (*argv[arg] == '-') {
00153         if (strcmp(argv[arg], "-w") == 0) {
00154             warn = true;
00155         } else {
00156             Syntax("unrecognized option", argv[arg]);
00157         }
00158         arg++;
00159     }
00160 
00161     // process files
00162     for (/*SKIP*/; arg < argc; arg++) {
00163         char *path = FileName(argv[arg]);
00164         try {
00165             Process(cout, path, warn);
00166         } catch (FS::DoesNotExist) {
00167             cerr << "Error: file " << path
00168                  << " does not exist; continuing..." << endl;
00169         } catch (const FS::Failure &f) {
00170             cerr << "Error: " << f << "; continuing..." << endl;
00171         }
00172     }
00173     return 0;
00174 }

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