///////////////////////////////////////////////////////////////// // scanner.cpp - scan specified file and files it includes // // ver 1.2 - 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" using namespace Scanner; using namespace CodeAnal; /////////////////////////////////////////////////////////////// // defaultProc class member functions // /////////////////////////////////////////////////////////////// //----< initializes defaultProc with scanner reference >------- defaultProc::defaultProc(scanner &s) : _scanner(s) {} //----< remove <> or "" from include name >-------------------- std::string defaultProc::extractFileName(CSemiExp &se) { size_t i; for(i=0; i------------ bool defaultProc::process(CSemiExp &se) { std::string name = _scanner.fileName(); while(se.get()) { if(_scanner.isVerbose()) se.show(); //---- process header files if(grammar(se).include()) // anonomous temporary grammar object { // 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<'='>(std::string("Processing ") + name + " again"); } } } //---- process function definitions else if(grammar(se).functionDef()) // another temporary { std::cout << " " << display::functionName(se) << "\n"; if(_scanner.isVerbose()) std::cout << "========================\n\n"; } } return true; } // /////////////////////////////////////////////////////////////// // 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 } } //----< open file for processing by process object >----------- bool scanner::scan(const std::string& filename) { std::ifstream in(filename.c_str()); if(!in.good()) return false; if(!_process) return false; _filename = filename; // save name for display after recursive call CToker toker(&in); CSemiExp se(&toker); CCppCommentFilter CppCommFilter(&toker); se.registerFilter(&CppCommFilter); CCCommentFilter CCommFilter(&toker); se.registerFilter(&CCommFilter); CDoubleQuoteFilter CDoubleQF(&toker); se.registerFilter(&CDoubleQF); CSingleQuoteFilter CSingleQF(&toker); se.registerFilter(&CSingleQF); std::cout << display::title<'='>(std::string("Processing ") + filename); _process->process(se); in.close(); return true; } // /////////////////////////////////////////////////////////////// // test stub // /////////////////////////////////////////////////////////////// #ifdef TEST_SCANNER int main(int argc, char *argv[]) { std::cout << "\n Testing Scanner Module " << "\n ========================\n"; 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