/////////////////////////////////////////////////////////////////// // anal.cpp - analyze C and C++ source code for certain // // ver 1.7 metrics, including cyclomatic complexity // // and function length. // // // // Language: Visual C++, ver 6.0 // // Platform: Micron Dual Pentium Pro 200, Win NT 4.0 // // Application: CSE784 Project #1, Fall 1999 // // Author: Jim Fawcett, CST 2-187, Syracuse Univ. // // (315) 443-3948, fawcett@ecs.syr.edu // /////////////////////////////////////////////////////////////////// /* Module Operations ================= The anal program analyzes C and C++ code. It expects the code to be syntactically correct according to the ISO/ANSI standard, although it deals with only a small subset of the language's grammar. I also use it on C# code, but there are a few anomolies with C# code that I haven't gotten around to fixing. Anal computes cyclomatic complexity and length of each function defined in any file cited on the command line. It also announces global data definitions, local static data definitions, data defined in the public regions of classes, and non-const pointers returned from member functions. The program computes summary statistics for each module (a set of files with the same name, but differing extensions) and for all the code analyzed. You can invoke anal as follows: anal [/c][/s] *.h *.cpp where /s is an optional switch to show the entire function sig- nature and /c is an option to handle improperly nested comments. By default it shows only the function identifiers and prints an error message for improperly nested comments. NOTE: To work properly, anal.exe has to be on your path or in the dir being analyzed. That is, anal won't work with a fully qualified file pattern. */ // /////////////////////////////////////////////////////////////////// // build process // /////////////////////////////////////////////////////////////////// // Required Files: // // anal.cpp, cmdline.h, cmdline.cpp, grammar.h, grammar.cpp, // // dirs.h, dirs.cpp, semi.h, semi.cpp, tok.h, tok.cpp // // Compile Command: // // cl /GX anal.cpp cmdline.cpp grammar.cpp semi.cpp tok.cpp\ // // /link setargv.obj // /////////////////////////////////////////////////////////////////// /* Maintenance History =================== ver 1.7 : 31 Nov 2010 - added a continue statement to skip attempt to process file that can't be opened. ver 1.6 : 20 Feb 2007 - fixed bug in toker's isQuote that crashed if buffer was empty ver 1.5 : 31 May 2003 - added newer versions of the tok and semi modules to the project - made small addition to the manual page about options. ver 1.4 : 18 Sep 2000 - collect () for operator() in grammar::stripSignature - fix information display ver 1.3 : 21 Apr 2000 - fixed bug falsely returning pointer for operator* in grammar module - tok now announces reaching end of file while in a comment - anal has a /c option which treats nested comments like VC++, e.g., terminates comment on * and / even if nested ver 1.2 : 29 Feb 2000 - fixed bug in grammar module ver 1.1 : 26 Feb 2000 - cosmetic modifications to this page ver 1.0 : 10 Dec 1999 - first release Planned Modifications: ====================== This whole analysis process should be replaced with the C++ version of Parser in Handouts\su\cse687\code. This was designed before I figured out how to do code analysis in an effective flexible way with Parser. These are changes I had planned to make to this version, some of which are still relevant for a Parser-based design: - Use fileInfo module to support the use of path names so you can analyze directories other than the current working directory. This will also eliminate the use of setargv.obj which does not always work as expected. - Use of fileInfo will also allow the removal of the dirs module which is not as useful as it should be. - I have gotten an error processing a student's code which I have not tracked down yet. - add functionality to handle differences in C# code (not actually very much, since we only use a small part of the language grammar). */ // //----< program entry point >---------------------------------- #pragma warning(disable : 4786) #include #include #include #include #include "grammar.h" #include "cmdline.h" #include "dirs.h" void main(int argc, char *argv[]) { try { commandLine cl(argc,argv); string msg = "\n --------------------------------------------- "; msg += "\n --- usage: anal [/s][/c] file1 file2 ... --- "; msg += "\n --- /s: display arguments and return --- "; msg += "\n --- type from function signatures --- "; msg += "\n --- /c process improperly nested --- "; msg += "\n --- comments --- "; msg += "\n --- file names may contain wild cards --- "; msg += "\n ---------------------------------------------\n"; cl.usage(msg); if(cl.size() == 0) { cout << cl.usage() << endl; return; } cout << "\n ANAL, v1.6 - Code Analysis Program" << "\n ----------------------------------------------" << "\n copyright (c) Jim Fawcett, 1992-2007" << "\n all rights granted to users" << "\n except right to publish\n\n"; directory dir; cout << "\n file path:\n " << dir.fullPathName(".") << "\n\n"; std::map< string, pair > Penalty; grammar gram; functionDef funcDef; globalDeclar globDec; classDeclar classDec; staticDeclar staticDec; gram.analyze(funcDef); gram.analyze(globDec); gram.analyze(classDec); gram.analyze(staticDec); if(!cl.isCommand("s")) funcDef.doStrip(); if(cl.isCommand("c")) grammar::nestedComments(false); int TotalFuncLines = 0; int TotalLines = 0; int TotalCyclo = 0; int i; for(i=0; i