///////////////////////////////////////////////////////////////// // scanner.cpp - scan specified file and files it includes // // ver 1.1 - process each file with an object derived // // from scanProc // // // // Language: Visual C++, ver 7.0 // // Platfrom: Dell Dimension 8100, Windows 2000, SP 2.0 // // Application: Prototype for CSE687 Pr#2, Spring 2003 // // Author: Jim Fawcett, CST 2-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////// #include #include #include #include "scanner.h" #include "grammar.h" #include "display.h" /////////////////////////////////////////////////////////////// // scanner class member functions // /////////////////////////////////////////////////////////////// //----< is this a command line switch? >----------------------- bool scanner::isCommand(const std::string &arg) { return (arg[0] == '/' || arg[0] == '-'); } //----< process command >-------------------------------------- void scanner::processCommand(const std::string &arg) { switch(arg[1]) { // toggle verbose mode - this lets us turn on v for a file // then turn it off for the rest case 'V' : // fall through case 'v' : _verbose = !_verbose; break; default : ; // do nothing } } // //----< is this a source code file? >-------------------------- bool valid(const std::string& filename) { const int numE = 5; static std::string ext[numE] = { ".c", ".cpp", ".cs", ".h", ".hpp" }; std::string file = filename; for(int i=0; i<(int)file.size(); ++i) file[i] = tolower(file[i]); bool isValid = false; for(int j=0; j----------- bool scanner::scan(const std::string& filename) { if(!valid(filename)) return false; std::ifstream in(filename.c_str()); if(!in.good()) return false; if(!_process) return false; _filename = filename; // save name for display after recursive call std::cout << display::title<'='>(sstr("Processing ") + filename); _process->process(semiExp(in)); in.close(); return true; } // /////////////////////////////////////////////////////////////// // test stub // /////////////////////////////////////////////////////////////// #ifdef TEST_SCANNER /////////////////////////////////////////////////////////////// // private defaultProc class // /////////////////////////////////////////////////////////////// class defaultProc : public scanProc { public: defaultProc(scanner &s); bool virtual process(semiExp &se); private: std::string extractFileName(semiExp &se); scanner& _scanner; std::set headersSeen; }; //----< initializes defaultProc with scanner reference >------- defaultProc::defaultProc(scanner &s) : _scanner(s) {} //----< remove <> or "" from include name >-------------------- std::string defaultProc::extractFileName(semiExp &se) { size_t i; for(i=0; i------------ bool defaultProc::process(semiExp &se) { std::string name = _scanner.fileName(); while(se.get()) { if(_scanner.isVerbose()) se.display(); //---- process header files if(grammar(se).include()) { // found a header file, so call recursively if not seen before std::string newName = extractFileName(se); if(headersSeen.find(newName) == headersSeen.end()) { headersSeen.insert(newName); if(_scanner.scan(newName)) { std::cout << display::title<'='>(sstr("Processing ") + name + " again"); } } } //---- process function definitions else if(grammar(se).functionDef()) { std::cout << " " << display::functionName(se) << "\n"; if(_scanner.isVerbose()) std::cout << "========================\n\n"; } } return true; } // int main(int argc, char *argv[]) { if(argc==1) { std::cout << "\n please enter names of files or file patterns" << " to process on the command line\n\n"; return 1; } scanner s; defaultProc dp(s); s.Register(&dp); for(int i=1; i