Титульная страница   Пространства имен   Иерархия классов   Алфавитный указатель   Классы   Файлы   Члены пространства имен   Члены классов   Члены файла  

ftext.cpp

См. документацию.
00001 /*
00002  * Copyright (C) Sergey P. Derevyago, 2003-2004.
00003  *
00004  * Permission to copy, use, modify, sell and distribute this software is granted
00005  * provided this copyright notice appears in all copies.
00006  * This software is provided "as is" without express or implied warranty, and
00007  * with no claim as to its suitability for any purpose.
00008  *
00009  */
00010 
00016 #include <stdio.h>
00017 #include "findtext.hpp"
00018 #include "stringbuf.hpp"
00019 
00020 using namespace std;
00021 
00025 class Finder : public Subscriber<FoundMsg>, public Subscriber<ErrorMsg> {
00029       virtual bool regularMsg(const Publisher<FoundMsg>& pub,
00030         const FoundMsg& msg);
00031 
00035       virtual bool regularMsg(const Publisher<ErrorMsg>& pub,
00036         const ErrorMsg& msg);
00037 };
00038 
00039 bool Finder::regularMsg(const Publisher<FoundMsg>&, const FoundMsg& msg)
00040 {
00041  printf("%s:%d:%s\n", msg.fileName.c_str(), msg.lineNum, msg.lineText.c_str());
00042  return 1;
00043 }
00044 
00045 bool Finder::regularMsg(const Publisher<ErrorMsg>&, const ErrorMsg& msg)
00046 {
00047  fprintf(stderr, "%s\n", msg.errMsg.c_str());
00048  return 1;
00049 }
00050 
00055 class Logger : public Subscriber<FoundMsg>, public Subscriber<ErrorMsg>,
00056   public Subscriber<InfoMsg> {
00058       FILE* log;
00059 
00063       virtual bool regularMsg(const Publisher<FoundMsg>& pub,
00064         const FoundMsg& msg);
00065 
00069       virtual bool regularMsg(const Publisher<ErrorMsg>& pub,
00070         const ErrorMsg& msg);
00071 
00075       virtual bool regularMsg(const Publisher<InfoMsg>& pub,
00076         const InfoMsg& msg);
00077 
00078  public:
00080       int filesOpened;
00082       int filesClosed;
00084       int linesFound;
00086       int errorsEncountered;
00087 
00091       Logger(const string& fname);
00092 
00096       ~Logger();
00097 };
00098 
00099 Logger::Logger(const string& fname)
00100 {
00101  log=fopen(fname.c_str(), "a");
00102  if (!log) {
00103     throw newCException(_FLINE_, StringBuf("Can't open \"")+fname+
00104       "\" file for logging");
00105  }
00106 
00107  filesOpened=filesClosed=linesFound=errorsEncountered=0;
00108 }
00109 
00110 Logger::~Logger()
00111 {
00112  fputc('\n', log);
00113 #define PR(var) fprintf(log, #var ": %d\n", var)
00114  PR(filesOpened);
00115  PR(filesClosed);
00116  PR(linesFound);
00117  PR(errorsEncountered);
00118 #undef PR
00119  fputc('\n', log);
00120 
00121  fclose(log);
00122 }
00123 
00124 bool Logger::regularMsg(const Publisher<FoundMsg>& pub, const FoundMsg& msg)
00125 {
00126  linesFound++;
00127  fprintf(log, "FoundMsg: Publisher(%p) FindText(%p) fileName(%s) lineNum(%d) "
00128    "lineText(%s)\n", &pub, &msg.ft, msg.fileName.c_str(), msg.lineNum,
00129    msg.lineText.c_str());
00130 
00131  return 1;
00132 }
00133 
00134 bool Logger::regularMsg(const Publisher<ErrorMsg>& pub, const ErrorMsg& msg)
00135 {
00136  errorsEncountered++;
00137  fprintf(log, "ErrorMsg: Publisher(%p) FindText(%p) errMsg(%s)\n", &pub,
00138    &msg.ft, msg.errMsg.c_str());
00139 
00140  return 1;
00141 }
00142 
00143 bool Logger::regularMsg(const Publisher<InfoMsg>& pub, const InfoMsg& msg)
00144 {
00145  if (msg.type==InfoMsg::opened) filesOpened++;
00146  else filesClosed++;
00147 
00148  fprintf(log, "InfoMsg : Publisher(%p) FindText(%p) type(%s) fileName(%s)\n",
00149    &pub, &msg.ft, (msg.type==InfoMsg::opened) ? "opened" : "closed",
00150    msg.fileName.c_str());
00151 
00152  return 1;
00153 }
00154 
00158 struct CmdLineParser {
00160        bool isL;
00162        string logName;
00164        bool isR;
00166        string dirName;
00168        string mask;
00170        string text;
00171 
00175        CmdLineParser() : isL(0), isR(0) {}
00176 
00183        bool parse(int argc, char** argv);
00184 };
00185 
00186 bool CmdLineParser::parse(int argc, char** argv)
00187 {
00188  if (argc<4 || argc>7) return 0;
00189 
00190  int curr=1;
00191  while (argv[curr][0]=='-') {
00192        string opt(argv[curr]);
00193 
00194        if (opt=="-l") {
00195           if (isL) return 0;
00196 
00197           isL=1;
00198           curr++;
00199 
00200           logName=argv[curr++];
00201        }
00202        else if (opt=="-r") {
00203           if (isR) return 0;
00204 
00205           isR=1;
00206           curr++;
00207        }
00208        else return 0;
00209  }
00210 
00211  if (curr+3!=argc) return 0;
00212 
00213  dirName=argv[curr++];
00214  mask=argv[curr++];
00215  text=argv[curr++];
00216 
00217  return 1;
00218 }
00219 
00223 void printUsage()
00224 {
00225  fprintf(stderr,
00226 "Usage:\n"
00227 "  ftext [-l logname] [-r] dirname mask text\n"
00228 "For example:\n"
00229 "  ftext -l ftext.log -r . *pp return\n"
00230  );
00231 }
00232 
00233 int main(int argc, char** argv)
00234 {
00235  try {
00236      CmdLineParser clp;
00237      if (!clp.parse(argc, argv)) {
00238         // Некоторые системы/реализации вместо "*pp" сразу передают все файлы,
00239         // заканчивающиеся на "pp". Данный цикл печатает все полученные
00240         // параметры для диагностики подобной ситуации.
00241         // На таких системах/реализациях вместо "*pp" лучше передавать просто
00242         // "pp", т.е. без начальной "*".
00243         printf("Invalid command line:\n");
00244         for (int i=0; i<argc; i++)
00245             printf("%s%s", argv[i], (i!=argc-1)? " " : "\n\n");
00246 
00247         printUsage();
00248         return 1;
00249      }
00250 
00251      sh_ptr<FindText> ft=Factory::newFindText();
00252 
00253      Finder f;
00254      ft->foundPub().subscribe(f);
00255      ft->errorPub().subscribe(f);
00256 
00257      sh_ptr<Logger> l;
00258      if (clp.isL) {
00259         l.set(new Logger(clp.logName));
00260 
00261         ft->foundPub().subscribe(*l);
00262         ft->errorPub().subscribe(*l);
00263         ft->infoPub().subscribe(*l);
00264      }
00265      
00266      ft->search(clp.dirName, clp.isR, clp.mask, clp.text);
00267 
00268      return 0;
00269  }
00270  catch (...) {
00271        fprintf(stderr, "Uncaught exception:\n%s",
00272          toCException(_FLINE_)->toStringAll().c_str());
00273        return 2;
00274  }
00275 }

Документация по ftext. Последние изменения: Sat Mar 20 17:58:15 2004. Создано системой doxygen1.3