#include #include #include #include #include /*---------------------------------------------------------------------------*/ /* */ /* Copyright (C) 1998 - 2006 */ /* University of Southern California Center for Software Engineering */ /* Salvatori 330, 941 West 37th Place, */ /* Los Angeles, California 90089-0781, USA */ /* */ /* This program is free software with limitations; you can redistribute */ /* it and/or modify it under the terms of the USC-CSE Limited Public */ /* License as published by the University of Southern California */ /* Center for Software Engineering; either version 1 of the License, */ /* or (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, but */ /* WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* USC-CSE Limited Public License for more details. */ /* */ /* You should have received a copy of the USC-CSE Limited Public License */ /* along with this program; if not, write to: */ /* University of Southern California */ /* Center for Software Engineering */ /* Salvatori 300, 941 West 37th Place */ /* Los Angeles, California 90089-0781, USA. */ /* */ /*---------------------------------------------------------------------------*/ /* */ /* Original Software Product developed by the Northrop Grumman Corporation */ /* Electronic Sensors and Systems Sector (ES3) and provided to the */ /* University of Southern California (USC) Center for Software */ /* Engineering (CSE) via license to distribute. */ /* */ /*---------------------------------------------------------------------------*/ /* USC CSE UPDATES & REVISIONS */ /* */ /* REVISION DATE AUTHOR MODIFICATION */ /* Rev-1 9/09/98 GEK Transferred via License Agreement to the */ /* Center for Software Engineering at the */ /* University of Southern California. */ /* Version EG17, SWA-91-020, 1991-1998. */ /* */ /* Rev-2 2/19/99 GEK Corrected assignment of returned value from */ /* fgetc from a char to that of an int. This */ /* effects all occurrences of 'list_ch', */ /* 'list_int', 'ch', and 'lch'. */ /* Updated all checks for EOF to be compared */ /* to the integer value returned from fgetc vs.*/ /* the char value. */ /* */ /* Rev-3 3/21/00 GEK Added EXIT_SUCCESS to return statement of */ /* main and defined main to be of type int. */ /* Modified "NAME_LIST" define statements with */ /* improved continuation syntax. */ /* Modified file extension detection code to */ /* identify '.hh', and '.hpp' files as */ /* source code files. */ /* Changed delimiter that signifies a comment */ /* that was commenced on a previous line but */ /* continues across new lines from '/*' */ /* starting in line[0] to a '+' placed in */ /* line[0]. */ /* */ /* Rev-4 11/15/00 GEK Changed 'boolean' to 'bool_type' and defined */ /* enumeration types 'true' and 'false' as */ /* 'True' and 'False' so as not to conflict */ /* 'bool' typedef in C++. */ /* Updated description of commands used to */ /* create the c_list.dat file */ /* (see EXECUTION PROCEDURES, step 1). */ /* Replaced static with extern in all functions.*/ /* Updated transfer_file_name function. */ /* Corrected miscounting of comments when a */ /* slash-asterisk-slash triplet is encountered.*/ /* */ /* Rev-5 1/07/01 GEK Updated get_list_file_size function. */ /* Updated extension function. */ /* */ /* Rev-6 7/09/01 GEK Inserted check for left paren. following */ /* IF and FOR keywords in special processing. */ /* Inserted fclose for outfile.dat file. */ /* Added Word Wrap processing. */ /* Added LINE_WRAP error condition. */ /* Increased MAX_LINE_LENGTH from 132 to 264. */ /* Added 'lf_2' local flag. */ /* Updated get_list_file_size function. */ /* */ /* Rev-7 8/22/01 GEK Inserted check for left paren. following */ /* WHILE keyword in special processing. */ /* Renamed 'num_FOR_IF' to 'num_FOR_IF_WHILE'. */ /* */ /* Rev-8 7/28/03 GEK Check for an empty file before processing. */ /* Correction to Extension function. */ /* Added code to differentiate a double slash */ /* comment delimiter from a series of */ /* asterisk-slash slash-asterisk delimiters. */ /* Ignore a single string delimiter within a */ /* comment delimited by the double-slash. The */ /* error only occurs for languages that */ /* delimit comments using both a matching set */ /* of delimiters AND a separate delimiter */ /* where the comment terminates with the EOLN. */ /* */ /* Rev-9 4/08/06 Aditya Updated MAX_DIRR_TARGETS and DIRR_NAME_LIST */ /* Kulkarni to include the counting of #import and */ /* #using preprocessor directives */ /* */ /* Rev-10 5/16/06 VN Updated the code to make sure 'lch' is */ /* assigned before being referenced */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* USING ORGANIZATION UPDATES & REVISIONS */ /* */ /* REVISION DATE AUTHOR MODIFICATION */ /* Rev-A 9/09/98 USC CSE Release of the USC Distribution config. */ /* */ /* Rev-B ?/??/?? */ /* */ /*---------------------------------------------------------------------------*/ /* This program will count the number of source lines of code within a */ /* C or C++ source code file. The input to this program will be a file */ /* named 'c_list.dat', which contains the full directory and file name */ /* of the C/C++ source files of which will be read. Every file name */ /* pointed to by 'c_list.dat' will be accessed with readonly privilege. */ /* The output of this program will be found in the file 'c_outfile.dat'. */ /* */ /* Refer to the instructions that follow for further information on */ /* the installation and use of this code counting tool. */ /* */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* */ /* BASIC ASSUMPTIONS & DEFINITIONS */ /* */ /* o FILE EXTENSIONS : Files that contain C/C++ source code shall have a */ /* '.C', '.CC', '.CPP', '.H', '.HH', or '.HPP' file extension. */ /* Files without these file extensions are considered to be data files. */ /* The names of files are read/accessed without case sensitivity. */ /* The file version number and ';' when absent shall result in the highest */ /* version of that file to be analyzed. */ /* */ /* o DATA FILES : Data files shall contain only blank lines and data lines. */ /* Data lines shall be counted using the physical SLOC definition. */ /* */ /* o SOURCE FILES : Source code files may contain blank lines, comment */ /* lines (whole or embedded), compiler directives, data lines, or */ /* executable lines. */ /* Source code files to be analyzed shall have previously been compiled */ /* successfully to ensure the integrity of the inclusive syntax. */ /* */ /* o SLOC DEFINITION : The primary definitions for a Source Line of Code */ /* (SLOC) include the physical SLOC and the logical SLOC. */ /* The physical SLOC definition uses the Deliverable Source Instruction */ /* (DSI) concept. */ /* The logical SLOC definition is highly dependent upon the structure of */ /* the programming language to be parsed by the CodeCount tool. */ /* */ /* o PHYSICAL SLOC : The number of physical SLOCs within a source file is */ /* defined to be the sum of the number of physical SLOCs (terminated by */ /* a carriage return or EOLN character) which contain program instructions*/ /* created by project personnel and processed into machine code by some */ /* combination of preprocessors, compilers, interpreters, and/or */ /* assemblers. It excludes comment cards and unmodified utility software.*/ /* It includes job control language (compiler directive), format */ /* statements, and data declarations (data lines). Instructions are */ /* defined as lines of code or card images. Thus, a line containing */ /* two or more source statements count as one physical SLOC; a five line */ /* data declaration counts as five physical SLOCs. */ /* The physical SLOC definition was selected due to (1) compatibility with */ /* parametric software cost modeling tools, (2) ability to support */ /* software metrics collection, and (3) programming language syntax */ /* independence. */ /* */ /* o LOGICAL SLOC : The number of logical SLOC within a source file is */ /* defined to be the sum of the number of logical SLOCs classified as */ /* compiler directives, data lines, or executable lines. It excludes */ /* comments (whole or embedded) and blank lines. Thus, a line containing */ /* two or more source statements count as multiple logical SLOCs; a */ /* single logical statement that extends over five physical lines count */ /* as one logical SLOC. */ /* Specifically, the logical SLOC found within a file containing software */ /* written in the C/C++ programming language may be computed by summing */ /* together the count of (1) the number of terminal semicolons, (2) the */ /* number of end block statements, i.e., '}', (3) the number of FOR, IF */ /* and WHILE statements that do not have a block statement structure, and */ /* (4) the number of logical compiler directives. */ /* The logical SLOC definition was selected due to (1) compatibility with */ /* parametric software cost modeling tools, and (2) ability to support */ /* software metrics collection. */ /* The logical SLOC count is susceptible to erroneous output when the */ /* analyzed source code file contains software that uses overloading or */ /* replacement characters for a few key symbols, e.g., ';' . */ /* */ /* o TAB : A Tab character shall be replaced with a blank character upon */ /* input. */ /* */ /* o FORMFEED : A FormFeed character shall be replaced with a blank */ /* character upon input. */ /* */ /* o BLANK LINE : A blank line is defined as any physical line of the */ /* source file that contains only blank, Tab, or FormFeed characters */ /* prior to the occurrence of a carriage return (EOLN). */ /* */ /* o CHARACTER LITERALS : The contents of any character literals shall be */ /* overwritten with a special character prior to the search for comments */ /* so as not to interfere with the detection of comment delimiters. */ /* Specifically, any character literal designated by a matching set of */ /* single quote characters shall be overwritten. */ /* */ /* o ESCAPE SEQUENCES : Any escape sequences shall be overwritten with a */ /* special character prior to the search for comments or string literals */ /* so as not to interfere with the search for comment or string */ /* deliminters. */ /* Specifically, Only the \' and \" escape sequence shall be overwritten. */ /* */ /* o STRING LITERALS : The contents of any string literals shall be */ /* overwritten with a special character so as not to interfere with the */ /* detection of keywords or other programming language specific */ /* delimiters. */ /* Specifically, any string literal designated by a matching set of */ /* double quotes shall be overwritten. */ /* */ /* o COMMENTS : A comment is defined to be of two possible classifications, */ /* whole line or embedded. */ /* */ /* o WHOLE COMMENT : A whole line comment is defined as any string of */ /* characters which follow the programming language specific comment */ /* delimiter and as such does not co-exist on the same physical line with */ /* compilable source code. */ /* Specifically, a whole line comment is designated by the a slash-asterisk*/ /* and asterisk-slash pair of delimiters. A C++ whole line comment is */ /* designated by a double slash and continues until the carriage return */ /* (EOLN). */ /* Multiple whole line comments that co-exist on the same physical line */ /* shall be counted as a single whole line comment. */ /* Continuations of a whole line comment over multiple physical lines */ /* shall be individually classified and counted as either whole line or */ /* embedded comments in accordance with the definitions. */ /* */ /* o EMBEDDED COMMENT : An embedded comment is defined as any comment string */ /* that co-exists on the same physical line with compilable source code. */ /* Specifically, an embedded comment is designated using the same method */ /* as a whole line comment. */ /* Multiple embedded comments that co-exist of the same physical line */ /* with compilable source code shall be individually counted. */ /* The contents of embedded comments shall be blanked so as not to */ /* interfere with the detection of keywords or other programming language */ /* specific delimiters. */ /* Continuations of an embedded comment over multiple physical lines shall */ /* be individually classified and counted as either whole line or */ /* embedded comments in accordance with the definitions. */ /* */ /* o COMPILER DIRECTIVE : A compiler directive is defined as any line */ /* of code which contains one (or more) of the programming language */ /* specific directive keywords as found within the 'DIRR_NAME_LIST' */ /* constant. */ /* Specifically, the '#' symbol, i.e., DIRR_PREFIX, followed by any number */ /* of spaces (blanks) followed by an entry within the 'DIRR_NAME_LIST' */ /* constant defines the SLOC to be a compiler directive. A compiler */ /* directive terminates with a carriage return (EOLN). */ /* Continuation of a compiler directive over multiple physical lines of */ /* the file shall increment the physical SLOC count accordingly until a */ /* physical line is determined to be of another classification, e.g., */ /* data line or executable line. */ /* Continuation of a compiler directive over multiple physical lines of */ /* the file shall NOT increment the logical SLOC count. */ /* Multiple logical SLOC on the same physical line shall increment the */ /* logical SLOC count accordingly. */ /* A blank line or comment (whole or embedded) shall not cause the */ /* re-classification of a continuation of a compiler directive line. */ /* A compiler directive shall not exist within a data file. */ /* */ /* o DATA LINE : A data line is defined as any line of code which */ /* contains one (or more) of the programming language specific data */ /* keywords as found within the 'DATA_NAME_LIST' constant. */ /* Continuation of the data line over multiple physical lines of */ /* the file shall increment the physical SLOC count accordingly until a */ /* physical line is determined to be of another classification, e.g., */ /* directive or executable line. */ /* Continuation of the data line over multiple physical lines of */ /* the file shall NOT increment the logical SLOC count. */ /* Multiple logical SLOC on the same physical line shall increment the */ /* logical SLOC count accordingly. */ /* A blank line or comment (whole or embedded) shall not cause the */ /* re-classification of a continuation of a data line. */ /* A data line as found within the data file is defined as any physical */ /* line of code which is not a blank line. */ /* */ /* o EXECUTABLE LINE : An executable line is defined as any line of code */ /* which contains one (or more) of the programming language specific */ /* executable keywords as found within the 'EXEC_NAME_LIST' constant */ /* AND/OR has not been classified as a compiler directive or data line. */ /* Continuation of the executable line over multiple physical lines of */ /* the file shall increment the physical SLOC count accordingly until a */ /* physical line is determined to be of another classification, e.g., */ /* directive or data line. */ /* Continuation of an executable line over multiple physical lines of */ /* the file shall NOT increment the logical SLOC count. */ /* Multiple logical SLOC on the same physical line shall increment the */ /* logical SLOC count accordingly. */ /* A blank line or comment (whole or embedded) shall not cause the */ /* re-classification of a continuation of a executable line. */ /* An executable line shall not exist within a data file. */ /* */ /* o TOTAL SIZING: The total sizing of analyzed source code files in terms */ /* the SLOC count contains the highest degree of confidence. However, */ /* the sizing information pertaining to the subclassifications (compiler */ /* directives, data lines, executable lines) has a somewhat lower level */ /* of confidence associated with them. Missclassifications of the */ /* subclassifications of SLOC may occur due to (1) user modifications to */ /* the CodeCount tool, (2) syntax and semantic enhancements to the parsed */ /* programming language, (3) exotic usage of the parsed programming */ /* language, and (4) integrity of the host platform execution environment.*/ /* Additionally, in some programming languages a single SLOC may contain */ /* attributes of both a data declaration and an executable instruction */ /* simultaneously. These occurrences represent events beyond the control */ /* of the CodeCount tool designer and may cause the inclusive parsing */ /* capabilities of the tool to missclassify a particular SLOC. For these */ /* reasons, the counts of subclassifications should be regarded as an */ /* approximation and not as a precise count. In only the physical SLOC */ /* definition does the sum of the subclassification counts equal the */ /* total physical SLOC count. */ /* */ /* o KEYWORD COUNT : The search for any programming language specific */ /* keywords over a physical line of code for purposes of incrementing */ /* the tally of occurrences shall include the detection of multiple */ /* keywords of the same type, e.g., two occurrence of the keyword READ */ /* on the same physical line. */ /* The search for any programming language specific keywords over a */ /* physical line of code for purposes of incrementing the tally of */ /* occurrences shall include the detection on multiple keywords of */ /* different types, e.g., occurrences of keywords READ and WRITE on the */ /* same physical line. */ /* Keywords found within comments (whole or embedded) or string literals */ /* shall not be included in the tally count. */ /* */ /* o KEYWORDS SEARCH : Programming language specific keywords as contained */ /* within the 'NAME_LIST' constants may have any character other than */ /* 'A'..'Z', 'a'..'z', '0'..'9', '_', or '$' adjacent to it. This is */ /* used to differentiate keywords from other source code identifiers, */ /* e.g., READ versus READer versus you_READ. */ /* Characters contained in the SPECIAL set shall be blanked prior to the */ /* search for keywords to ensure that a space (blank) is located adjacent */ /* to all keywords and identifiers. */ /* */ /* o SPECIAL SET : The contents of the 'SPECIAL' set shall not include */ /* characters that are involved in search mechanisms which are */ /* executed following the elimination of the 'special' characters. */ /* */ /* o NAME_LIST ENTRIES : Keywords that appear in the 'NAME_LIST's that are */ /* multiple words, e.g., END IF, may have any amount (greater than one) */ /* of spaces (blanks) separating the component words. */ /* Multiple words, e.g., ELSE IF, must appear prior to occurrences of */ /* any of the components words within the NAME_LIST, e.g., ELSE and/or IF */ /* by themselves. */ /* */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* */ /* INSTALLATION PROCEDURES */ /* */ /* 1. Set the 'TARGET_REVISION' constant to the appropriate symbol to */ /* reflect the host platform environment that the CodeCount tool will */ /* execute upon. The current setting reflects a generic platform. */ /* */ /* 2. Set the 'DIRR_PREFIX' constant to the appropriate symbol to reflect */ /* the platform/language specific symbol that is used to indicate a */ /* compiler directive. Also, update the compiler directive prefix */ /* symbol for every entry in the 'DIRR_NAME_LIST' constant. */ /* */ /* 3. If user modifications to the CodeCount source file have been made, */ /* enter a description of the changes in the section labeled */ /* 'USING ORGANIZATION UPDATES & REVISIONS'. Set the 'USER_REVISION' */ /* constant to reflect the latest revision number. */ /* */ /* 4. Compile/Link the CodeCount tool using an ANSI-C compliant compiler. */ /* */ /* 5. Edit the 'c_lines_environment.dat' file to set the user definable */ /* parameters. These parameters include the name of the program/project */ /* that will be associated with the source code to be counted, along */ /* with other numeric quantities. A default value will be used in place */ /* of any incorrect numeric values read from this file. The default */ /* values are found in the function 'get_user_info' within this file. */ /* NOTE: If case sensitivity is enabled (Compare_Spec = 1), then the case */ /* of each entry contained within 'DIRR_NAME_LIST', 'DATA_NAME_LIST', */ /* 'EXEC_NAME_LIST' and arguments passed by the SEARCH procedure */ /* envoked in main must be adjusted in compliance with the prevailing */ /* coding standard for the source code to be analyzed. */ /* */ /* 6. Proceed to EXECUTION PROCEDURES. */ /* */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* */ /* EXECUTION PROCEDURES */ /* */ /* 1. Create the file 'c_list.dat' file. This file contains a list of */ /* each source file containing software to be counted. The format of */ /* this file is one filename (complete directory/path description) per */ /* physical line. The 'c_list.dat' file may be created by using one */ /* of the following commands : */ /* */ /* UNIX: */ /* ls -1 *.c >c_list.dat */ /* or, use the following to obtain full directory/pathname specification*/ /* find .-name '*.c' > c_list.dat */ /* to append this file with additional filenames use: */ /* find .-name '*.h' >> c_list.dat */ /* */ /* VAX VMS: */ /* Directory/noheading/notrailer/col=1/output=c_list.dat *.c */ /* to append this file with additional list file contents use: */ /* Append c_list1.dat, c_list2.dat c_list.dat */ /* */ /* MS-DOS: */ /* dir/B >c_list.dat *.c */ /* or, use the following to obtain full directory/pathname specification*/ /* along with files in all subdirectories: */ /* dir/B/S > c_list.dat *.c */ /* to append this file with additional filenames use: */ /* dir/B/S >> c_list.dat *.h */ /* */ /* 2. Execute the c_lines tool. A progress message may periodically */ /* appear on the terminal screen during execution. Error messages will */ /* appear on the terminal screen when abnormalities have been detected */ /* during execution. The duration of execution will be dependent upon */ /* the size and number of source files to be counted and the prevailing */ /* loading of the host platform. */ /* */ /* 3. An output file 'c_outfile.dat' is created and contains the output */ /* and any error messages generated during execution of the tool. */ /* */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* */ /* ERROR MESSAGES */ /* */ /* "ERROR, unable to open c_outfile.dat file" */ /* 1. The CodeCount tool is unable to open/create the output file. Check */ /* the privileges associated with file create for that directory. */ /* */ /* "ERROR, unable to open c_list.dat file" */ /* 1. 'c_list.dat' file does not exist in the current directory. */ /* 2. 'c_list.dat' file privileges prevent readonly access. */ /* */ /* "ERROR, unable to read c_list.dat file" */ /* 1. 'c_list.dat' file is an empty file. */ /* 2. 'c_list.dat' file is not in the correct format. */ /* */ /* "ERROR, truncated an entry of the c_list.dat file" */ /* 1. The 'c_list.dat' file contains a filename of length greater than */ /* 'MAX_LIST_FILENAME_LENGTH'. Increase the numerical value of */ /* the 'MAX_LIST_FILENAME_LENGTH' constant, then re-compile the tool. */ /* Since the input file cannot be accessed, the CodeCount tool will */ /* abort parsing of this file and proceed to the next source file */ /* specified in 'c_list.dat' file. */ /* */ /* "ERROR, unable to open c_lines_environment file" */ /* 1. 'c_lines_environment.dat' file does not exist in the current */ /* directory. */ /* 2. 'c_lines_environment.dat' file privileges prevent readonly access. */ /* */ /* "ERROR, error in reading c_lines_environment file" */ /* 1. 'c_lines_environment.dat' file contents is corrupted. */ /* 2. A numeric value contained within the 'c_lines_environment.dat' */ /* file exceed predefined bounds causing the default value to be used. */ /* */ /* "ERROR, unable to access file -> " */ /* 1. The input file does not exist at the directory/path location. */ /* 2. The directory/path specified is incorrect. */ /* 3. The directory/path location does not permit readonly access to files.*/ /* */ /* "ERROR, empty file -> " */ /* 1. The input file contains only an EOF marker. */ /* */ /* "ERROR, truncated a line of " OR */ /* "ERROR, truncated a line of file -> " */ /* 1. The input file contains a line of length less than or equal to the */ /* 'MAX_LINE_LENGTH' constant, but is also greater than the */ /* 'Line_Length' parameter within the 'c_lines_environment.dat' */ /* file. */ /* To prevent SLOC counting errors, the CodeCount tool will abort */ /* parsing of this file and proceed to the next source file specified */ /* in 'c_list.dat'. */ /* To correct this condition, either */ /* A. increase the value of the 'Line_Length' parameter within the */ /* 'c_lines_environment.dat' file, */ /* B. set the 'Line_Length' value to '0' within the */ /* 'c_lines_environment.dat' file to enable wordwrap processing, */ /* C. for UNIX systems, try using the following Korn shell command */ /* to correct for missing EOLN symbols. */ /* %tr -d ^M "\r" " OR */ /* "ERROR, EOLN not detected in file -> " */ /* 1. The input file contains a line of length greater than the */ /* 'MAX_LINE_LENGTH' constant. */ /* To prevent SLOC counting errors, the CodeCount tool will abort */ /* parsing of this file and proceed to the next source file specified */ /* in 'c_list.dat'. */ /* To correct this condition, either */ /* A. increase both the value of the 'Line_Length' parameter within */ /* the 'c_lines_environment.dat' file and the value of the */ /* MAX_LINE_LENGTH constant, */ /* B. set the 'Line_Length' value to '0' within the */ /* 'c_lines_environment.dat' file to enable wordwrap processing, */ /* C. for UNIX systems, try using the following Korn shell command */ /* to correct for missing EOLN symbols. */ /* %tr -d ^M "\r" " OR */ /* "ERROR, Word Wrap processing error in file -> " */ /* 1. The wordwrap processing has detected a non-comment SLOC that was */ /* concatenated to fit within 'line'. As such, keywords and other */ /* valuable code artifacts were lost. */ /* To prevent SLOC counting errors, the CodeCount tool will abort */ /* parsing of this file and proceed to the next source file specified */ /* in 'c_list.dat'. */ /* To correct this condition, either */ /* A. edit to correct the long SLOC statement, */ /* B. increase the value of the MAX_LINE_LENGTH constant. */ /* */ /* "ERROR, unable to open temp_file.dat" */ /* 1. The current directory/path location does not permit creation of */ /* files. */ /* */ /* "ERROR, Physical SLOC counting error in " OR */ /* "ERROR, Physical SLOC counting error in the following file" */ /* 1. Internal CodeCount tool logic has incorrectly processed source code */ /* within the input file. */ /* 2. The input file does not contain compilable source code resulting in */ /* misinterpretation of the source language constructs. */ /* */ /* "ERROR, Logical SLOC counting error in " OR */ /* "ERROR, Logical SLOC counting error in the following file" */ /* 1. Internal CodeCount tool logic has incorrectly processed source code */ /* within the input file. */ /* 2. The input file does not contain compilable source code resulting in */ /* misinterpretation of the source language constructs. */ /* */ /* "ERROR, unable to perform calculation" */ /* 1. Internal CodeCount tool logic has incorrectly processed source code */ /* within the input file. */ /* 2. Erroneous operands have been detected prior to performing a math */ /* calculation that will result in a run-time error. */ /* */ /* "ERROR, processing error detected in Search function" */ /* 1. A call to the Search function was made with erroneous input data. */ /* This may be caused by user modifications to the CodeCount tool. */ /* */ /*---------------------------------------------------------------------------*/ #define USER_REVISION 'A' /* User update revision letter. */ #define TARGET_REVISION 'G' /* Host platform identifier: U = UNIX, */ /* V = VAX11 VMS, A = VAX Alpha VMS, */ /* S = Sun, D = DOS, M = Macintosh, */ /* G = Generic (no specific platform) */ #define DEVELOPER_REVISION "10" /* Developer update revision number. */ #define LICENTIATE "USC CSE and COCOMO II Affiliates " /* Name of purchaser for which the */ /* CodeCount License applies to. */ #define TOOL_PREFIX "c" /* File name prefix used with all files */ /* associated with this CodeCount tool. */ /* Should not exceed 12 characters. */ #define MAX_PROJECT_NAME 45 /* Max length of user-specified project */ /* name. */ #define MAX_LIST_FILENAME_LENGTH 132/* Number of characters to be read when */ /* parsing 'c_list'. Largest entry */ /* should not exceed a value of 132. */ #define MAX_FILENAME_LENGTH 58 /* Number of characters in the name */ /* of the input file. Largest entry */ /* should not exceed a value of 58. */ #define MAX_HEADER_LENGTH 74 /* Number of columns prior to output of */ /* the filename within 'c_outfile'. */ /* DO NOT change this constant! */ /* 132 cols <= MAX_FILENAME_LENGTH + */ /* MAX_HEADER_LENGTH */ #define MAX_LINE_LENGTH 264 /* Length of a source line to be */ /* read from an input file. */ #define MAX_WW_LINE_LENGTH 10 /* Length of a wordwrap buffer that is */ /* appended to end of 'line' when */ /* wordwrap feature is enabled. */ #define MAX_TEST_LENGTH 20 /* DO NOT change this constant! */ #define FF_CHAR '\f' /* This character is a Form Feed. */ #define TAB_CHAR '\t' /* This character is a TAB. */ #define CR_CHAR '\r' /* This character is a carriage retrun. */ #define QUOTE_CHAR '\'' /* This character is a single quote. */ #define MAX_TARGET_LENGTH MAX_TEST_LENGTH /* Number of characters in a keyword. */ #define MAX_TARGETS 32 /* Maximum size of the 'NAME_LISTs. */ #define MAX_DIRR_TARGETS 16 /* The number of entries in the */ /* DIRR_NAME_LIST to be examined. */ #define MAX_DATA_TARGETS 32 /* The number of entries in the */ /* DATA_NAME_LIST to be examined. */ #define MAX_EXEC_TARGETS 31 /* The number of entries in the */ /* EXEC_NAME_LIST to be examined. */ #define MAX_STR_LENGTH MAX_TARGETS * (1 + MAX_TARGET_LENGTH) /* Maximum STRing length to be passed */ /* in calls to load_names_and_tags. */ /* The "+1" is to account for the "*" */ /* used as a flag to indicate if the */ /* number of times that keyword */ /* appeared should be printed out. */ /* If the asterisk is not present the */ /* keyword is used to determine the */ /* type of line being read in. */ #define MAX_EXCLUDE_SET 2*26+10+2 /* Maximum number of characters to be */ /* included in 'exclude' set. */ #define MAX_SPECIAL_SET 22 /* Maximum number of characters to be */ /* included in 'special' set. */ #define CODE 0 /* Replaces 'file_mode_type', used in */ /* 'total_type' and */ #define DATA 1 /* 'file_mode_names_type'. */ #define PHY 0 /* Physical SLOC reference. */ #define LOG 1 /* Logical SLOC reference. */ #define BLANK ' ' #define BAR '-' #define MAX_EOLN_TRIES 2*MAX_LINE_LENGTH /* Maximum consecutive tries to detect */ /* newline before LINE* error is set. */ /* Active when wordwrap feature is off. */ #define DIRR_PREFIX '#' /* Prefix symbol delineating a directive.*/ /* Note: blanks and tabs located between */ /* the DIRR_PREFIX and the compiler */ /* directive identifier are extracted */ /* prior to comparison with entries */ /* with DIRR_NAME_LIST. */ /* Entries without the '*' prefix will */ /* not be included in searches. */ /* MAX_DIRR_TARGETS must be modified */ /* when entries are inserted or deleted.*/ /* MAX_DIRR_TARGETS and MAX_TARGETS must */ /* be modified when the length of this */ /* list is increased or decreased. */ /* Multiple word entries must appear */ /* prior to any single occurrence of a */ /* component word within this list, */ /* e.g., 'ELSE IF' must appear prior to */ /* 'ELSE' and 'IF'. */ #define DIRR_NAME_LIST \ "* #define "\ "* #undef "\ "* #if "\ "* #ifdef "\ "* #ifndef "\ "* #else "\ "* #elif "\ "* #endif "\ "* #include "\ "* #line "\ "* #pragma "\ "* #error "\ "* #dictionary "\ "* #module "\ "* #import "\ "* #using "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " "\ " " /* Entries without the '*' prefix will */ /* not be included in searches. */ /* MAX_DATA_TARGETS must be modified */ /* when entries are inserted or deleted.*/ /* MAX_DATA_TARGETS and MAX_TARGETS must */ /* be modified when the length of this */ /* list is increased or decreased. */ /* Multiple word entries must appear */ /* prior to any single occurrence of a */ /* component word within this list, */ /* e.g., 'ELSE IF' must appear prior to */ /* 'ELSE' and 'IF'. */ #define DATA_NAME_LIST \ "* FILE "\ "* const "\ "* bool "\ "* int "\ "* long "\ "* unsigned "\ "* short "\ "* char "\ "* wchar_t "\ "* float "\ "* double "\ "* enum "\ "* class "\ "* struct "\ "* union "\ "* void "\ "* typedef "\ "* auto "\ "* register "\ "* static "\ "* extern "\ "* namespace "\ "* asm "\ "* template "\ "* operator "\ "* mutable "\ "* friend "\ "* volatile "\ "* using "\ "* explicit "\ "* inline "\ "* virtual " /* Entries without the '*' prefix will */ /* not be included in searches. */ /* MAX_EXEC_TARGETS must be modified */ /* when entries are inserted or deleted.*/ /* MAX_EXEC_TARGETS and MAX_TARGETS must */ /* be modified when the length of this */ /* list is increased or decreased. */ /* Multiple word entries must appear */ /* prior to any single occurrence of a */ /* component word within this list, */ /* e.g., 'ELSE IF' must appear prior to */ /* 'ELSE' and 'IF'. */ #define EXEC_NAME_LIST \ "* goto "\ "* if "\ "* else "\ "* for "\ "* do "\ "* while "\ "* continue "\ "* switch "\ "* case "\ "* break "\ "* default "\ "* return "\ "* entry "\ "* sizeof "\ "* new "\ "* delete "\ "* try "\ "* throw "\ "* catch "\ "* typeid "\ "* const_cast "\ "* static_cast "\ "* dynamic_cast "\ "* reinterpret_cast "\ "* stdin "\ "* stdout "\ "* stderr "\ "* cin "\ "* cout "\ "* cerr "\ "* clog "\ " " FILE *c_lines_environment ; /* Contains User-Defined data*/ FILE *c_list ; /* Contains file names */ FILE *infile ; /* Input source files */ FILE *c_outfile ; /* Contains output info. */ typedef enum {False, True} bool_type ; typedef char filename_type[MAX_FILENAME_LENGTH+1] ; typedef char list_filename_type[132+1] ; typedef char project_name_type[MAX_PROJECT_NAME+1] ; typedef char test_type[MAX_TEST_LENGTH+1] ; typedef char line_type[MAX_LINE_LENGTH+2+1] ; typedef char ww_line_type[MAX_WW_LINE_LENGTH+1] ; typedef char target_type[MAX_TARGET_LENGTH+1] ; typedef target_type target_name_array_type[MAX_TARGETS] ; /* Used to store the */ /* keywords. */ typedef long int target_length_array_type[MAX_TARGETS] ; /* This array type will */ /* contain the lengths of */ /* the keywords, used in */ /* keyword searches */ typedef bool_type target_tag_array_type[MAX_TARGETS] ; /* Arrays of this TAG type */ /* will be used to */ /* indicate which keywords */ /* are to be printed out */ /* in the output section. */ typedef long int target_tally_array_type[MAX_TARGETS] ; /* This array type will be */ /* used to tally the */ /* occurrences of the key */ /* words. */ typedef char str_array_type[MAX_STR_LENGTH+1] ; typedef char exclude_type[MAX_EXCLUDE_SET+1] ; typedef char special_type[MAX_SPECIAL_SET+1] ; typedef enum {YES, UNDEF, NO} new_boolean_type ; typedef long int total_type[2][2] ; /* 1st subscript: CODE = 0 */ /* DATA = 1 */ /* 2nd subscript: PHY = 0 */ /* LOG = 1 */ typedef long int tally_type[2] ; /* 1st subscript: PHY = 0 */ /* LOG = 1 */ typedef enum {ANY, DIR, DAT, EXE} line_mode_type ; typedef target_type file_mode_names_type[2] ; typedef enum {OK , OUTFILE_OPEN , LISTFILE_OPEN , LISTFILE_READ , LISTFILE_TRUNC, ENVFILE_OPEN , ENVFILE_READ , INFILE_OPEN , INFILE_EMPTY , LINE_TRUNC , LINE_SIZE , LINE_WRAP , TEMPFILE_OPEN , PHY_COUNT , LOG_COUNT , MATH_ERROR } error_type ; extern void get_a_piece (char line[], long int loc , long int length, char test[] ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will extract a small piece of the characters contained */ /* within the array 'line', and place that piece into the array 'test'. */ /* */ /* Rev A-D 6/87- 9/96 Original Corrected 'IF' statement by */ /* Developer installing the <= and +1 feature. */ /* Installed 'length' parameter to */ /* be passed by the call. */ /* Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* */ /* Rev-E 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-F ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Get_A_Piece */ long int count ; long int i ; for (i = 0; i < MAX_TEST_LENGTH; i++) /* Clear test array */ test[i] = ' '; if ((loc <= MAX_LINE_LENGTH - length) && (length <= MAX_TEST_LENGTH ) ) { /* If */ count = 0; for (i = loc; i < (loc + length); i++) { /* For */ test[count] = line[i]; count++; } /* For */ } /* If */ } /* Get_A_Piece */ extern void do_upper_case (char line_char , char test_char , bool_type close_match, long int *count_ptr ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will compare the upper case 'line_char' with either a */ /* an upper case 'test_char', or ( IF close_match = FALSE ) */ /* a lower case 'test_char' . */ /* IF close_match had been set to TRUE, then only an upper case to */ /* upper case comparison would be considered to be valid. */ /* */ /* Rev A-C 7/94- 9/96 Original Converted to ANSI-C and unit tested. */ /* Developer Removed redundant enum from boolean. */ /* Added prototype function headings. */ /* Added static void function prefix. */ /* */ /* Rev-D 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-E ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Do_Upper_Case */ #define OFFSET ('A' - 'a') if ((line_char == test_char ) || ((line_char == test_char - OFFSET) && (close_match == False ) ) ) (*count_ptr)++; else *count_ptr = 0; #undef OFFSET } /* Do_Upper_Case */ extern void do_lower_case (char line_char , char test_char , bool_type close_match, long int *count_ptr ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will compare the lower case 'line_char' with either a */ /* a lower case 'test_char', or ( IF close_match = FALSE ) */ /* an upper case 'test_char' . */ /* IF close_match had been set to TRUE, then only an lower case to */ /* lower case comparison would be considered to be valid. */ /* */ /* Rev A-C 7/94- 9/96 Original Converted to ANSI-C and unit tested. */ /* Developer Removed redundant enum from boolean. */ /* Added prototype function headings. */ /* Added static void function prefix. */ /* */ /* Rev-D 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-E ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Do_Lower_Case */ #define OFFSET ('A' - 'a') if ((line_char == test_char ) || ((line_char == test_char + OFFSET) && (close_match == False ) ) ) (*count_ptr)++; else *count_ptr = 0; #undef OFFSET } /* Do_Lower_Case */ extern void search (char line[] , char test[] , long int start , long int stop , bool_type close_match, long int line_length, bool_type *flag_ptr , long int *where_ptr , long int position ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will scan the array 'line' until the string contained */ /* in the array 'test' is found. 'Flag' is returned as TRUE if a */ /* match was found, and FALSE if no match was found. */ /* */ /* Rev A-G 6/87-11/97 Original Revised to include matching of */ /* Developer words which may differ only in */ /* upper versus lower case letters. */ /* Included the capacity to compare */ /* a substring passed within 'test'. */ /* Extension of Search (old function) */ /* POSITION allows the search to */ /* begin from any location in the LINE. */ /* Added 'line_length' to argument list. */ /* Removed 'test_length' from WHILE */ /* condition to allow scan to EOLN. */ /* Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* Renamed function from New_Search. */ /* Deleted 'search_error' variable. */ /* Restructured 1st IF statement. */ /* Added check for null terminator in */ /* 'line' with a blank character in */ /* 'test'. */ /* */ /* Rev-H 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-I ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Search */ long int count ; long int test_length ; long int i ; *flag_ptr = False; *where_ptr = 0; if ((start <= stop ) && (stop <= MAX_TEST_LENGTH) ) { /* If start */ i = position; count = 0; test_length = stop - start + 1; while ((i <= line_length + 1 ) && (*flag_ptr == False ) ) { /* While */ if ((test[count + start] >= 'A') && (test[count + start] <= 'Z') ) do_upper_case(line[i], test[count + start], close_match, &count); else { /* Else */ if ((test[count + start] >= 'a') && (test[count + start] <= 'z') ) do_lower_case(line[i], test[count + start], close_match, &count); else { /* Else */ if ((line[ i ] != ' ') || (line[i+1] != ' ') || ( count != 0 ) ) { /* If */ if (line[i] == test[count + start]) count++; else if ((line[i] == '\0') && (test[count + start] == ' ' ) ) count++; else count = 0; } /* If */ } /* Else */ } /* Else */ if (count == test_length) { /* If */ *flag_ptr = True; *where_ptr = i - test_length + 1; } /* If */ else i++; } /* While */ } /* If start */ else printf("ERROR, processing error detected in Search function\n"); } /* Search */ extern void context_search (char line[] , char test[] , long int start , long int stop , bool_type close_match , long int line_length , bool_type *flag_ptr , long int *where_ptr , long int *where_end_ptr, char exclude[] , long int position , bool_type white_out ) /*---------------------------------------------------------------------------*/ /* */ /* This procedure looks for a keyword in 'line' that is not followed by a */ /* character in the set 'EXCLUDE' . This procedure is a multiple step */ /* recursive procedure. When 'white_out' is set to true, this procedure */ /* will clear occurrences of 'test' from 'line' to support further */ /* searches. */ /* */ /* Rev A-E 7/87-11/97 Original Initial Development. */ /* Developer Allows for multiple words in TEST. */ /* Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* Added 'line_length' to argument list */ /* to increase throughput. */ /* Added check for null terminator as */ /* next character following a keyword. */ /* */ /* Rev-F 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-G ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Context_Search */ long int i, j, k; long int m, n ; long int s, t ; j = 0; /* count the number of blanks*/ for (i = start; i <= stop; i++) if (test[i] == ' ') j++; /* For */ if (j <= 1) /* No blanks in the test */ { /* If j<=1 */ search(line, test, start, stop, close_match, line_length, flag_ptr, where_ptr, position); /* Determine end location of */ *where_end_ptr = *where_ptr + stop - start; /* current word */ if (*flag_ptr == True) /* Check terminator of word */ { /* If */ if (NULL != strchr(exclude, line[*where_end_ptr + 1]) ) *flag_ptr = False; /* Word is not a keyword. */ if (line[*where_end_ptr + 1] == '\0') *flag_ptr = True ; /* Found keyword at EOLN. */ } /* If */ if ((*flag_ptr == True) && /* Remove keyword from 'line'*/ (white_out == True) ) /* to support future search.*/ for (m = *where_ptr; m <= *where_end_ptr; m++) line[m] = ' '; } /* If j<=1 */ else /* Multiple words have been */ { /* detected, must parse each*/ i = start + 1; /* Search for a blank */ while ((i <= stop ) && (test[i] != ' ') ) i++; /* Look for the next word */ j = i; /* in 'test' */ search(line, test, start, i - 1, close_match, line_length, flag_ptr, where_ptr, position); k = *where_ptr; if (*flag_ptr == True) { /* If multiple words */ /* Ending position of */ s = k + i - start; /* found word */ /* Recursive call */ context_search(line, test, j, stop, close_match, line_length, flag_ptr, &t, where_end_ptr, exclude, s, False); if (*flag_ptr == True) { /* If flag_ptr */ n = 0; for (m = s; m < t; m++) if (line[m] != ' ') n = 1; if (n == 0) /* Only blanks inside */ { /* If n==0 */ if (white_out == True) /* Blank out phrase */ for (m = *where_ptr; m <= *where_end_ptr; m++) line[m] = ' '; } /* If n==0 */ /* Failure: try for next */ /* occurrence using a */ /* recursive call */ else context_search(line, test, start, stop, close_match, line_length, flag_ptr, where_ptr, where_end_ptr, exclude, s, white_out); } /* If flag_ptr */ } /* If multiple words */ } /* Else */ } /* Context_Search */ extern void count_targets (char name_array[MAX_TARGETS][MAX_TARGET_LENGTH+1], long int tally_array[] , long int length_array[], long int num , char line[] , bool_type close_match , long int line_length , bool_type *found_ptr , long int *line_loc_ptr , char exclude[] ) /*---------------------------------------------------------------------------*/ /* */ /* This procedure will search through all words contained within the */ /* string 'line', and compare each word to the list of target words found */ /* within 'name_array'. If a match is found, then the number of */ /* occurrences of that particular word is incremented, 'tally_array', and */ /* the target word contained in 'line' is blanked so as not to be */ /* detected again due to the recursive nature of the search process. */ /* */ /* Rev A-C 12/90- 9/96 Original Added 'line_length' to argument list. */ /* Developer Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* */ /* Rev-D 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-E ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Count_Targets */ long int i ; long int j ; long int end_loc; i = 0; /* Beginning of line */ while (i < line_length - 1) /* process whole line */ { /* While */ while ((line[ i ] == ' ' ) && /* Move to one space */ (line[i+1] == ' ' ) && /* before the next word. */ ( i < line_length - 1) ) i++; if (i < line_length - 1) { /* If */ for (j = 0; j < num; j++) /* Consider all targets. */ { /* For */ /* Only search if first */ /* character in target */ /* word is the same as */ /* that of the word in */ /* the line. */ if (toupper(line[i + 1]) == toupper(name_array[j][1])) { /* If */ context_search(line, name_array[j], 0, length_array[j] - 1, close_match, line_length, found_ptr, line_loc_ptr, &end_loc, exclude, i, True); if (*found_ptr == True) tally_array[j] = tally_array[j] + 1; } /* If */ } /* For */ if (i < line_length - 1) /* Move to next location */ i++; while ((line[i] != ' ' ) && /* Pass over current word */ (i < line_length - 1) ) i++; } /* If */ } /* While */ } /* Count_Targets */ extern void load_name_and_tag_arrays (target_name_array_type name_array , target_tag_array_type tag_array , target_length_array_type length_array, str_array_type str , long int num ) /*---------------------------------------------------------------------------*/ /* */ /* Loads the STR_ARRAY into slots in the NAME_ARRAY. */ /* Computes the LENGTH_ARRAY by counting the number of blanks at the end */ /* of the name and subtracting that number from MAX_TARGET_LENGTH. */ /* TAG_ARRAY is also computed. If an asterisk is in the first column, */ /* then the keyword is designated (TRUE) to be printed out; otherwise it */ /* is given the value (FALSE). Note: in either case the first column is */ /* not attached to the NAME_ARRAY. */ /* */ /* Rev A-C 7/87- 9/96 Original Initial Development. */ /* Developer Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* */ /* Rev-D 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-E ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Load_Name_And_Tag_Arrays */ long int i ; long int j ; long int offset ; for (i = 0; i < num; i++) { /* For */ offset = i * (MAX_TARGET_LENGTH + 1) ; /* Compute offset to locate */ /* the '*' within 'str' */ if (str[offset] == '*') /* boolean to 'tag_array' */ tag_array[i] = True; else tag_array[i] = False; for (j = 0; j < MAX_TARGET_LENGTH; j++) /* copy 'str' contents */ name_array[i][j] = str[offset + j + 1]; j = MAX_TARGET_LENGTH - 1; /* search for last blank */ while (( j > 0 ) && ( name_array[i][j] == ' ' )) j-- ; length_array[i] = j + 1; /* no blank included at end */ } /* For */ } /* Load_Name_And_Tag_Arrays */ extern void clear_tally (long int tally_array[], long int num ) /*---------------------------------------------------------------------------*/ /* */ /* Resets the TALLY_ARRAY [1..NUM] to 0. */ /* */ /* Rev A-C 7/87- 9/96 Original Initial Development. */ /* Developer Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* */ /* Rev-D 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-E ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Clear_Tally */ long int i; for (i = 0; i < num; i++) tally_array[i] = 0; } /* Clear_Tally */ extern void write_dots (char str[MAX_TARGET_LENGTH], FILE *outfile ) /*---------------------------------------------------------------------------*/ /* */ /* Takes the STR and fills up the blanks at its end with dots. */ /* */ /* Rev A-C 7/87- 9/96 Original Initial Development. */ /* Developer Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* Added 'outfile' to argument list. */ /* Local variables declared as long int. */ /* */ /* Rev-D 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-E ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Write_Dots */ long int i ; long int j ; /* Search right to left */ /* through 'str' until a */ j = MAX_TARGET_LENGTH - 1; /* non-blank character */ while (( j > 0 ) && (str[j] == ' ') ) j--; j++; /* Move right one space */ for (i = 0; i < j; i++) /* Print contents of 'str' */ fprintf(outfile, "%c", str[i]); for (i = j; i < MAX_TARGET_LENGTH; i++) /* Print remaining spaces */ fprintf(outfile, "."); } /* Write_Dots */ extern void search_for_semi_colon (char line[] , long int line_length, bool_type *flag_ptr , long int *num_ptr ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will search the 'line' for occurrences of a ';'. The */ /* 'flag_ptr' is set to true upon detection of the first ';'. The */ /* total number of detected ';'s is assigned to 'num_ptr'. */ /* */ /* Rev A-D 12/90-11/97 Original Added 'line_length' to argument list. */ /* Developer Converted to ANSI-C and unit tested. */ /* Added prototype function headings. */ /* Modified to return the number of ';'s */ /* detected in 'line'. */ /* */ /* Rev-E 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-F ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Search_For_Semi_Colon */ long int i; *flag_ptr = False; *num_ptr = 0 ; for (i = 1; i <= line_length; i++) { /* For */ if (line[i] == ';') { /* If */ *flag_ptr = True; (*num_ptr)++; } /* If */ } /* For */ } /* Search_For_Semi_Colon */ extern void search_for_continuation (char line[] , long int line_length, bool_type *flag_ptr ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will search for the C/C++ specific continuation characters */ /* within the 'line', i.e. '\' or a ',' as the last character. The */ /* rightmost embedded comments must have been cleared prior to execution */ /* of this function. */ /* */ /* Rev A-D 7/94-11/97 Original Convected to ANSI-C and unit tested. */ /* Developer Added prototype function headings. */ /* Changed >=1 to >0 in While conditional.*/ /* Added search for a ','. */ /* */ /* Rev-E 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-F ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Search_For_Continuation */ long int i; i = line_length; /* Locate last non-blank char*/ while ((i > 0 ) && (line[i] == ' ') ) i--; if ((line[i] == '\\') || (line[i] == ',' ) ) *flag_ptr = True ; else *flag_ptr = False; } /* Search_For_Continuation */ extern void compress_directives (char line[] , char symbol , long int *length_ptr, bool_type *flag_ptr ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will scan 'line' to locate occurrences of any compiler */ /* directives whereas there exists blank spaces between the prefix */ /* symbol and the name of the directive. The blank spaces will be */ /* eliminated thereby compressing the directive name and aiding in the */ /* search processes to follow. */ /* */ /* Rev A-B 8/96- 9/96 Original Created and unit tested. */ /* Developer Added prototype function headings. */ /* */ /* Rev-C 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-D ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Compress_Directives */ long int i ; long int j ; long int n ; long int sum_n; *flag_ptr = False; i = 1; sum_n = 0; while (i <= *length_ptr + 1) { /* While */ if (line[i] == symbol) { /* If */ /* set flag indicating that */ /* a directive prefix */ *flag_ptr = True; /* has been detected. */ /* determine number of */ n = 0; /* blanks to eliminate. */ j = i + 1; while ((j <= *length_ptr + 1) && ( line[j] == ' ' ) ) { /* While */ j++; n++; } /* While */ if (n > 0) /* detected blanks. */ { /* If */ j = i + 1; while (j <= (*length_ptr - n + 1)) /* eliminate blanks */ { /* While */ line[j] = line[j+n]; j++; } /* While */ *length_ptr = *length_ptr - n; /* reduce 'line_length' */ sum_n = sum_n + n; } /* If */ } /* If */ i++; } /* While */ if (sum_n > 0) /* blank trailing char's. */ for (i = (*length_ptr + 1); i < (*length_ptr + 1 + sum_n); i++) line[i] = ' '; } /* Compress_Directives */ extern void extension (char fname[], char ext[] ) /*---------------------------------------------------------------------------*/ /* */ /* Takes the 'fname' and removes the VMS extension and puts it in 'ext'. */ /* - The EXTension is assumed to be between the last '.' */ /* and first ';' OR the last '.' and the first blank character. */ /* For Example: [jones.dir345]file.EXT;67 */ /* - The filename extension is NOT limited to a three character string. */ /* */ /* Rev A-G 7/87- 3/98 Original Initial Development. */ /* Developer Change '<=' to "<" in WHILE loop to */ /* determine the value of stop. */ /* Converted to ANSI-C and unit tested. */ /* Added check for fname[start]='.' */ /* prior to assignment to 'ext' . */ /* Added prototype function headings. */ /* Added null termination of 'ext'. */ /* Added decrement of 'stop' to prevent */ /* copying of ';', or blank, or null */ /* terminator char. to 'ext'. */ /* Inserted '>=' to if statement to allow */ /* copying of file extension delimiter, */ /* i.e., when 'stop' equals 'start'. */ /* Place null only at the end of 'ext'. */ /* Removed "-1" from while conditional of */ /* left-to-right search. */ /* */ /* Rev-H 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-I 1/07/01 GEK Eliminate check for blank character in */ /* left-to-right search in support of */ /* legal filenames that contain blanks. */ /* */ /* Rev-J 7/14/03 GEK Modified left-to-right search of fname */ /* to begin at 'start' instead of '0'. */ /* */ /* Rev-K ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Extension */ long int start; long int stop ; long int k ; for (k = 0; k < MAX_FILENAME_LENGTH; k++) /* Clear 'ext' string */ ext[k] = ' '; /* Search from right to left */ /* through 'fname' until the*/ /* beginning of the file */ start = MAX_FILENAME_LENGTH - 1; /* extension is located */ while ((start >= 0 ) && (fname[start] != '.') ) start--; /* Search from left to right */ /* through 'fname' until the*/ /* end of the file extension*/ stop = start; /* is located */ while ((stop < MAX_FILENAME_LENGTH) && (fname[stop] != ';' ) && (fname[stop] != '\0' ) ) stop++; /* Decrement 'stop' so as */ /* not to copy ';' or blank */ stop--; /* or null terminator char. */ if ((stop >= start ) && /* IF extension has located */ (fname[start] == '.') ) { /* If */ for (k = start; k <= stop; k++) ext[k - start] = fname[k]; /* Copy the extension */ } /* If */ ext[MAX_FILENAME_LENGTH] = '\0'; /* Insert null character */ } /* Extension */ extern void transfer_file_name (char in_filename[] , char out_filename[] ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will transfer the name of the input file to the parameter */ /* 'out_filename'. If the input filename is larger than */ /* MAX_FILENAME_LENGTH, then the rightmost non-blank characters within */ /* 'in_filename' are moved to 'out_filename'. */ /* */ /* Rev A-C 7/94- 5/97 Original Converted to ANSI-C and unit tested. */ /* Developer Added prototype function headings. */ /* Added check for '\0'. */ /* Clear 'out_filename'. */ /* Transfer only required characters. */ /* */ /* Rev D-F 11/15/00 GEK Replaced static with extern. */ /* Test for location of first blank */ /* character removed due to redundancy */ /* with test for the '\0' character. */ /* */ /* Rev-G ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Transfer_File_Name */ long int stop ; long int i ; long int j ; for (i = 0; i <= MAX_FILENAME_LENGTH; i++) out_filename[i] = ' '; /* Clear 'out_filename' */ i = 0; /* Locate string terminator */ while ((i < MAX_LIST_FILENAME_LENGTH) && /* within 'in_filename'. */ (in_filename[i] != '\0' ) ) i++; stop = i; /* Assign value to stop */ if (stop < MAX_FILENAME_LENGTH) { /* If */ for (j = 0; j < stop; j++) out_filename[j] = in_filename[j]; /* Transfer all chars. */ out_filename[stop] = '\0'; /* Insert null character */ } /* If */ else { /* Else */ stop -= MAX_FILENAME_LENGTH; /* Transfer rightmost chars. */ for (j = 0; j < MAX_FILENAME_LENGTH; j++) out_filename[j] = in_filename[stop + j]; out_filename[MAX_FILENAME_LENGTH] = '\0'; /* Insert null character */ } /* Else */ } /* Transfer_File_Name */ extern void get_list_file_size (FILE *listfile , long int *num_files_ptr ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will count the number of files to be processed as contained */ /* is '*_list.dat'. This process is the equivalent of determining the */ /* number of physical lines contained within '*_list.dat'. */ /* */ /* Rev A-B 9/96- 5/97 Original Coded and unit tested. */ /* Developer Installed second test to enhance the */ /* accuracy of the function. */ /* */ /* Rev C-D 11/15/00 GEK Corrected assignment of returned value */ /* from fgetc from a char to that of an */ /* int value. */ /* Updated all checks for EOF to be */ /* compared to the int value returned */ /* from fgetc vs. the char value. */ /* Replaced static with extern. */ /* */ /* Rev-E 1/07/01 GEK Modified first test to eliminate fscanf*/ /* that caused filenames containing blank*/ /* characters to cause an overcount. */ /* */ /* Rev-F 7/09/01 GEK Modified first test to correctly */ /* count when listfile terminates without*/ /* an EOLN prior to the EOF. */ /* */ /* Rev-G ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Get_List_File_Size */ list_filename_type filename ; long int num_1 ; long int num_2 ; char list_ch ; long int list_int ; *num_files_ptr = 0; /* Initialize */ num_1 = 0; /* 1st test. */ while (fgets(filename, MAX_LIST_FILENAME_LENGTH, listfile) != NULL) num_1++; /* Found EOLN, or has read a */ /* filename that terminates */ /* with an EOF character, */ /* update num_1. */ rewind(listfile); /* Reset listfile pointer. */ /* 2nd test, susceptible to */ /* undercount when last */ /* filename terminates with */ num_2 = 0; /* EOF rather than '\n'. */ list_int = fgetc(listfile); list_ch = (char)list_int; /* Get 1st char. */ while (list_int != EOF) { /* While */ if (list_ch == '\n') num_2++; list_int = fgetc(listfile); /* Get next char. */ list_ch = (char)list_int; } /* While */ /* Always take larger number */ /* to prevent number of */ /* files processed from */ if (num_1 > num_2) /* exceeding 100 percent. */ (*num_files_ptr) = num_1; else (*num_files_ptr) = num_2; rewind(listfile); /* Reset listfile pointer. */ } /* Get_List_File_Size */ extern void error_handler (error_type *error_cond, char fname[] , FILE *outfile ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will output appropriate error message as determined by the */ /* value of 'error_cond'. Error messages will appear on the terminal */ /* screen AND within the '*outfile.dat' file. */ /* */ /* Rev A-G 9/96- 3/98 Original Coded and unit tested. */ /* Developer Added 'TEMPFILE_OPEN' option. */ /* Added TOOL_PREFIX processing. */ /* Added LINE_TRUNC condition. */ /* Renamed NO_EOLN to LINE_SIZE. */ /* Added 'fname' to argument list. */ /* Added LISTFILE_TRUNC condition. */ /* Changed DSI_COUNT to PHY_COUNT. */ /* Added LOG_COUNT, MATH_ERROR. */ /* Added MAX_HEADER_LENGTH, spaces. */ /* */ /* Rev-E 11/15/00 GEK Replaced static with extern. */ /* */ /* */ /* Rev-F 6/07/01 GEK Added LINE_WRAP condition. */ /* */ /* Rev-G 3/04/03 GEK Added INFILE_EMPTY condition. */ /* */ /* Rev-H ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Error_Handler */ long int spaces; long int i ; switch (*error_cond) { /* Switch */ case OK : break; case OUTFILE_OPEN : printf("ERROR, unable to open %s_outfile.dat file\n", TOOL_PREFIX); break; case LISTFILE_OPEN : printf("ERROR, unable to open %s_list.dat file\n", TOOL_PREFIX); fprintf(outfile,"ERROR, unable to open %s_list.dat", TOOL_PREFIX); fprintf(outfile," file\n"); break; case LISTFILE_READ : printf("ERROR, unable to read %s_list.dat file\n", TOOL_PREFIX); fprintf(outfile,"ERROR, unable to read %s_list.dat", TOOL_PREFIX); fprintf(outfile," file\n"); break; case LISTFILE_TRUNC: printf("ERROR, truncated an entry of the"); printf(" %s_list.dat file\n", TOOL_PREFIX); fprintf(outfile,"ERROR, truncated an entry of the"); fprintf(outfile," %s_list.dat file\n", TOOL_PREFIX); break; case ENVFILE_OPEN : printf("ERROR, unable to open"); printf(" %s_lines_environment.dat", TOOL_PREFIX); printf(" file, default values used\n"); fprintf(outfile,"ERROR, unable to open"); fprintf(outfile," %s_lines_environment.dat", TOOL_PREFIX); fprintf(outfile," file, default values used\n"); break; case ENVFILE_READ : printf("ERROR, error in reading"); printf(" %s_lines_environment.dat", TOOL_PREFIX); printf(" file, default value used\n"); fprintf(outfile,"ERROR, error in reading"); fprintf(outfile," %s_lines_environment.dat", TOOL_PREFIX); fprintf(outfile," file, default value used\n"); break; case INFILE_OPEN : printf("ERROR, unable to access file -> %s\n",fname); fprintf(outfile,"ERROR, unable to access file ->"); spaces = MAX_HEADER_LENGTH - 31; /* 31 = length of message */ for (i = 0; i < spaces; i++) fprintf(outfile,"%c",BLANK); fprintf(outfile,"%s\n",fname); break; case INFILE_EMPTY: printf("ERROR, file contains only an EOF marker -> %s\n",fname); fprintf(outfile,"ERROR, file contains only an EOF marker ->"); spaces = MAX_HEADER_LENGTH - 42; /* 42 = length of message */ for (i = 0; i < spaces; i++) fprintf(outfile,"%c",BLANK); fprintf(outfile,"%s\n",fname); break; case LINE_TRUNC : printf("ERROR, truncated a line of '%s'\n",fname); fprintf(outfile,"ERROR, truncated a line of file ->"); spaces = MAX_HEADER_LENGTH - 34; /* 34 = length of message */ for (i = 0; i < spaces; i++) fprintf(outfile,"%c",BLANK); fprintf(outfile,"%s\n",fname); break; case LINE_SIZE : printf("ERROR, EOLN not detected in '%s'\n",fname); fprintf(outfile,"ERROR, EOLN not detected in file ->"); spaces = MAX_HEADER_LENGTH - 35; /* 35 = length of message */ for (i = 0; i < spaces; i++) fprintf(outfile,"%c",BLANK); fprintf(outfile,"%s\n",fname); break; case LINE_WRAP : printf("ERROR, Word Wrap processing error in '%s'\n",fname); fprintf(outfile,"ERROR, Word Wrap processing error in file ->"); spaces = MAX_HEADER_LENGTH - 44; /* 44 = length of message */ for (i = 0; i < spaces; i++) fprintf(outfile,"%c",BLANK); fprintf(outfile,"%s\n",fname); break; case TEMPFILE_OPEN : printf("ERROR, unable to open temp_file.dat\n"); fprintf(outfile,"ERROR, unable to open temp_file.dat\n"); break; case PHY_COUNT : printf("ERROR, Physical SLOC counting error in '%s'\n",fname); fprintf(outfile,"ERROR, Physical SLOC counting error in the"); fprintf(outfile," following file\n"); break; case LOG_COUNT : printf("ERROR, Logical SLOC counting error in '%s'\n",fname); fprintf(outfile,"ERROR, Logical SLOC counting error in the"); fprintf(outfile," following file\n"); break; case MATH_ERROR: printf("ERROR, unable to perform calculation\n"); fprintf(outfile,"ERROR, unable to perform calculation\n"); break; } /* Switch */ *error_cond = OK; /* Reset 'error_cond' */ } /* Error_Handler */ extern void output_intro_msg (FILE *outfile) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will output the CodeCount introduction message that appears */ /* as the first page of the output file. This message may be suppressed */ /* by editing the environment data file and setting the 'UD_Intro_Msg' */ /* switch to zero. */ /* */ /* Rev A-B 10/97-11/97 Original Created and unit tested. */ /* Developer Updated due to logical SLOC counting. */ /* */ /* Rev-C 11/15/00 GEK Replaced static with extern. */ /* */ /* Rev-D ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Output_Intro_Msg */ fprintf(outfile,"%20c",BLANK); /* 20 = center in 110 columns*/ fprintf(outfile,"( c ) Copyright 1998 - 2006 "); fprintf(outfile,"University of Southern California, "); fprintf(outfile,"CodeCount (TM)\n"); fprintf(outfile,"%36c",BLANK); /* 36 = center in 110 columns*/ fprintf(outfile,"SOURCE LINES OF CODE COUNTING PROGRAM\n"); fprintf(outfile,"\n"); fprintf(outfile," The purpose of the CodeCount toolset is to automate"); fprintf(outfile," the collection of source code sizing information"); fprintf(outfile," using one of two\n"); fprintf(outfile,"possible Source Lines of Code (SLOC) definitions, physical"); fprintf(outfile," or logical. The physical SLOC definition is based on"); fprintf(outfile," Dr. Barry\n"); fprintf(outfile,"W. Boehm's Deliverable Source Instruction (DSI), i.e.,"); fprintf(outfile," non-blank, non-comment, physical source-level lines of"); fprintf(outfile," code and was\n"); fprintf(outfile,"selected due to its inherent programming language syntax"); fprintf(outfile," independence. The logical SLOC definition is based on"); fprintf(outfile," logical\n"); fprintf(outfile,"statements and will vary across programming languages due"); fprintf(outfile," to language-specific syntax. To select the output of"); fprintf(outfile," physical\n"); fprintf(outfile,"versus logical SLOC, edit the %s_lines_", TOOL_PREFIX); fprintf(outfile,"environment.dat file and set the UD_SLOC_Def switch"); fprintf(outfile," accordingly.\n"); fprintf(outfile," The total sizing of analyzed source code files in"); fprintf(outfile," terms of the SLOC count contains the highest degree of"); fprintf(outfile," confidence.\n"); fprintf(outfile,"However, the sizing data pertaining to the subclass"); fprintf(outfile,"ifications (compiler directives, data declarations,"); fprintf(outfile," executable\n"); fprintf(outfile,"instructions) has a somewhat lower level of confidence"); fprintf(outfile," associated with them. Misclassification of the sub"); fprintf(outfile,"classifications\n"); fprintf(outfile,"of SLOC may occur due to (1) user modifications of the"); fprintf(outfile," tool, (2) syntax and semantic enhancements to the parsed"); fprintf(outfile," programming\n"); fprintf(outfile,"language, (3) exotic usage of parsed programming"); fprintf(outfile," language constructs, and (4) integrity of the host"); fprintf(outfile," platform execution\n"); fprintf(outfile,"environment. Additionally, in some programming"); fprintf(outfile," languages a single SLOC may contain attributes of both"); fprintf(outfile," a data declaration\n"); fprintf(outfile,"and an executable instruction simultaneously. These"); fprintf(outfile," occurrences represent events beyond the control of the"); fprintf(outfile," CodeCount tool\n"); fprintf(outfile,"designer and may cause the inclusive parsing capabilities"); fprintf(outfile," of the tool to misclassify a particular SLOC. For"); fprintf(outfile," these reasons,\n"); fprintf(outfile,"the counts of subclassifications should be regarded as"); fprintf(outfile," an approximation and not as a precise count. In all"); fprintf(outfile," cases, the sum\n"); fprintf(outfile,"of the subclassifications should equal the total SLOC"); fprintf(outfile," sizing, else an error message will be output from the"); fprintf(outfile," tool.\n"); fprintf(outfile," Please refer to the instructions within the header"); fprintf(outfile," documentation of the CodeCount tool under BASIC"); fprintf(outfile," ASSUMPTIONS for more\n"); fprintf(outfile,"information pertaining to the operation of this tool.\n"); fprintf(outfile," To suppress the output of this message, edit the"); fprintf(outfile," %s_lines_environment.dat file and set the ", TOOL_PREFIX); fprintf(outfile,"UD_Intro_Msg switch to zero.\n"); fprintf(outfile," This product is licensed to : %s\n", LICENTIATE); fprintf(outfile,"\f\n"); } /* Output_Intro_Msg */ extern void get_user_info (char ud_project_name[] , long int *ud_qa_switch_ptr , long int *ud_compare_spec_ptr, long int *ud_line_length_ptr , long int *ud_exec_lines_ptr , long int *ud_data_lines_ptr , double *ud_min_percent_ptr , double *ud_inc_percent_ptr , long int *ud_display_file_ptr, long int *ud_intro_msg_ptr , char *ud_SLOC_def_ptr , char *ud_wordwrap_ptr , error_type *error_cond , FILE *env_file ) /*---------------------------------------------------------------------------*/ /* */ /* Procedure will accept user-defined parameters from the external file */ /* '*_lines_environment.dat'. An error upon reading this file will */ /* cause the default parameters to be assigned and an error message to */ /* be embedded into the project name of the output file header. */ /* */ /* Note UD prefix implies that this is a User-Definable quantity. */ /* */ /* Rev A-J 7/94- 3/98 Original Converted to ANSI-C and unit tested. */ /* Developer Added prototype function headings. */ /* Deleted 'read_error'. */ /* Added 'env_file' and 'error_cond' to */ /* argument list. */ /* Moved fopen and fclose of environment */ /* file to the main procedure. */ /* Local variables declared as long int. */ /* Added 'ud_inc_percent argument. */ /* Added termination of 'ud_project_name'.*/ /* Added 'ud_display_file'. */ /* Renamed 'new_val' to 'chr_val'. */ /* Renamed 'old_val' to 'lch_val'. */ /* Modified code that moves file pointer */ /* to the EOLN. */ /* Added test for EOF. */ /* Added 'ud_intro_msg'. */ /* Deleted 'error_message' string. */ /* Added 'ud_SLOC_def_ptr'. */ /* Changed 'ud_min_percent_ptr' to float. */ /* Changed all floats to double. */ /* Changed all %d and %f to %ld and %lf */ /* where long int and doubles are output.*/ /* Added int cast to convert 'chr_val' to */ /* 'lch_val'. */ /* */ /* Rev K-L 11/15/00 GEK Changed assignment of returned value */ /* from fgetc from a char to that of an */ /* int value. */ /* Updated all checks for EOF to be */ /* compared to the int value returned */ /* from fgetc vs. the char value. */ /* Replaced static with extern. */ /* */ /* Rev-M 6/07/01 GEK Added 'ud_wordwrap_ptr'. */ /* */ /* Rev-N ??/??/?? */ /* */ /*---------------------------------------------------------------------------*/ { /* Get_User_Info */ #define DEFAULT_QA_SWITCH 0 /* Default values when the */ #define DEFAULT_COMPARE_SPEC 1 /* environment file could */ #define DEFAULT_LINE_LENGTH MAX_LINE_LENGTH /* not be accessed. */ #define DEFAULT_EXEC_LINES 100 #define DEFAULT_DATA_LINES 100 #define DEFAULT_MIN_PERCENT 60.0 #define DEFAULT_INC_PERCENT 5.0 #define DEFAULT_DISPLAY_SPEC 0 #define DEFAULT_INTRO_MSG 1 #define DEFAULT_SLOC_DEF 'L' #define DEFAULT_WORDWRAP 'N' long int value ; double fvalue ; long int i ; long int lch_val ; char chr_val ; if (*error_cond == ENVFILE_OPEN) { /* If error */ for (i = 0; i < MAX_PROJECT_NAME; i++) ud_project_name[i] = ' '; ud_project_name[MAX_PROJECT_NAME] = '\0'; *ud_qa_switch_ptr = DEFAULT_QA_SWITCH ; *ud_compare_spec_ptr = DEFAULT_COMPARE_SPEC; *ud_line_length_ptr = DEFAULT_LINE_LENGTH ; *ud_exec_lines_ptr = DEFAULT_EXEC_LINES ; *ud_data_lines_ptr = DEFAULT_DATA_LINES ; *ud_min_percent_ptr = DEFAULT_MIN_PERCENT ; *ud_inc_percent_ptr = DEFAULT_INC_PERCENT ; *ud_display_file_ptr = DEFAULT_DISPLAY_SPEC; *ud_intro_msg_ptr = DEFAULT_INTRO_MSG ; *ud_SLOC_def_ptr = DEFAULT_SLOC_DEF ; *ud_wordwrap_ptr = DEFAULT_WORDWRAP ; } /* If error */ else { /* Else no error */ /*---------------------------------------------------------------------------*/ /* Get project name. */ /* Project name centered in */ /* MAX_PROJECT_NAME spaces. */ lch_val = fgetc(env_file); chr_val = (char)lch_val; /* Convert integer to char. */ if (lch_val != EOF) *error_cond = OK; /* Continue processing */ else *error_cond = ENVFILE_READ; /* EOF detected prematurely */ if (lch_val != EOF) { /* If not EOF */ i = 0; while ((chr_val != '\n' ) && (lch_val != EOF ) && (i < MAX_PROJECT_NAME) ) { ud_project_name[i] = chr_val; lch_val = fgetc(env_file); chr_val = (char)lch_val; i++; } ud_project_name[i] = '\0'; /* Terminate string variable.*/ while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get QA_SWITCH. */ /* If set to '1', will */ /* activate software to */ /* output statistics on the */ /* use of certain language */ /* specific keywords. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%ld", &value); /* Input value */ if ((value == 0) || (value == 1) ) *ud_qa_switch_ptr = value; /* Assign input value */ else { /* Assign default value */ *ud_qa_switch_ptr = DEFAULT_QA_SWITCH; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get COMPARE_SPEC. */ /* If set to '1', letters */ /* must compare exactly */ /* during the Search */ /* procedure. If set to */ /* '0', then a valid */ /* comparison will occur */ /* between an upper case */ /* letter and the */ /* corresponding lower case */ /* letter. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%ld", &value); /* Input value */ if ((value == 0) || (value == 1) ) *ud_compare_spec_ptr = value; /* Assign input value */ else { /* Assign default value */ *ud_compare_spec_ptr = DEFAULT_COMPARE_SPEC; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get LINE_LENGTH. */ /* Length of a source line */ /* to be read from an input */ /* file. */ /* Length = 0 turns on the */ /* wordwrap feature. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%ld", &value); /* Input value */ if ((value >= 1 ) && (value <= MAX_LINE_LENGTH) ) { /* Assign input value */ *ud_line_length_ptr = value; *ud_wordwrap_ptr = 'N' ; /* Turn off wordwrap feature */ } else if (value == 0) { /* Assign DEFAULT value */ *ud_line_length_ptr = DEFAULT_LINE_LENGTH; *ud_wordwrap_ptr = 'W'; /* Turn on wordwrap feature */ } else { /* Assign DEFAULT values */ *ud_line_length_ptr = DEFAULT_LINE_LENGTH; *ud_wordwrap_ptr = DEFAULT_WORDWRAP; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get EXEC_LINES. */ /* Maximum number of */ /* executable instructions */ /* allowed per input file. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%ld", &value); /* Input value */ if (value > 0) *ud_exec_lines_ptr = value; /* Assign input value */ else { /* Assign default value */ *ud_exec_lines_ptr = DEFAULT_EXEC_LINES; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get DATA_LINES. */ /* Maximum number of data */ /* declarations allowed per */ /* input file. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%ld", &value); /* Input value */ if (value > 0) *ud_data_lines_ptr = value; /* Assign input value */ else { /* Assign default value */ *ud_data_lines_ptr = DEFAULT_DATA_LINES; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get MIN_PERCENT. */ /* Minimum percent ratio of */ /* comments to deliverable */ /* source instructions. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%lf", &fvalue); /* Input value */ if ((fvalue > 0.0) && (fvalue < 1000.0) ) *ud_min_percent_ptr = fvalue; /* Assign input value */ else { /* Assign default value */ *ud_min_percent_ptr = DEFAULT_MIN_PERCENT; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get INC_PERCENT. */ /* Increment percent used to */ /* report progress through */ /* *_list.dat file. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%lf", &fvalue); /* Input value */ if ((fvalue >= 0.0) && (fvalue <= 100.0) ) *ud_inc_percent_ptr = fvalue; /* Assign input value */ else { /* Assign default value */ *ud_inc_percent_ptr = DEFAULT_INC_PERCENT; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get DISPLAY_FILE. */ /* If set to '1', the name */ /* of the file within */ /* *_list.dat that is */ /* currently being */ /* processed will be */ /* displayed on the terminal*/ /* screen. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%ld", &value); /* Input value */ if ((value == 0) || (value == 1) ) *ud_display_file_ptr = value; /* Assign input value */ else { /* Assign default value */ *ud_display_file_ptr = DEFAULT_DISPLAY_SPEC; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get INTRO_MSG. */ /* If set to '0', the output */ /* of the intro. message */ /* will be suppressed. */ if (lch_val != EOF) { /* If not EOF */ fscanf(env_file, "%ld", &value); /* Input value */ if ((value == 0) || (value == 1) ) *ud_intro_msg_ptr = value; /* Assign input value */ else { /* Assign default value */ *ud_intro_msg_ptr = DEFAULT_INTRO_MSG; *error_cond = ENVFILE_READ; } lch_val = fgetc(env_file); /* Move file pointer to EOLN */ chr_val = (char)lch_val; while ((chr_val != '\n') && (lch_val != EOF ) ) { lch_val = fgetc(env_file); chr_val = (char)lch_val; } if (lch_val == EOF) *error_cond = ENVFILE_READ; /* EOF detected prematurely */ } /* If not EOF */ /*---------------------------------------------------------------------------*/ /* Get SLOC_DEF. */ /* If set to 'P' will enable */ /* physical lines of code. */ /* If set to 'L' will enable */ /* logical lines of code. */ if (lch_val != EOF) { /* If not EOF */ lch_val = fgetc(env_file); /* Input value */ chr_val = (char)lch_val; switch (chr_val) { /* Switch */ case 'P': case 'p': *ud_SLOC_def_ptr = 'P'; /* Assign input value */ break; case 'L': case 'l': *ud_SLOC_def_ptr = 'L'; /* Assign input value */ break; default: *ud_SLOC_def_ptr = DEFAULT_SLOC_DEF; /* Assign default value */ *error_cond = ENVFILE_READ; break; } /* Switch */ } /* If not EOF */ } /* Else no error */ } /* Get_User_Info */ /*---------------------------------------------------------------------------*/ int main() { project_name_type UD_Project_Name ; /* User Definable quantities */ long int UD_QA_Switch ; long int UD_Compare_Spec ; long int UD_Line_Length ; long int UD_Exec_Lines ; long int UD_Data_Lines ; double UD_Min_Percent ; double UD_Inc_Percent ; long int UD_Display_File ; long int UD_Intro_Msg ; char UD_SLOC_Def ; char UD_WordWrap ; list_filename_type list_filename ; filename_type filename ; filename_type ext ; line_type line ; long int line_length ; ww_line_type ww_line ; long int ww_count ; char ch ; long int lch ; char list_ch ; long int list_int ; long int SLOC_mode ; /* PHY..LOG range */ long int file_mode ; /* CODE..DATA range */ file_mode_names_type file_mode_names ; long int lc1,lc2,lc3,lc_t ; /* local index counters */ bool_type lf_1, lf_2 ; /* local flags */ long int i, j ; total_type total_lines ; total_type total_blank_lines ; total_type total_comment_lines ; total_type total_e_comm_lines ; total_type total_directive_lines ; total_type total_data_lines ; total_type total_exec_lines ; total_type total_SLOC_lines ; total_type total_number_files ; long int exceed_UD_Exec_Lines ; long int exceed_UD_Data_Lines ; long int exceed_UD_Min_Percent ; target_name_array_type dirr_names ; /* List of keywords to be */ /* searched for. */ target_tag_array_type dirr_tags ; /* List of keywords to be */ /* printed out. */ target_length_array_type dirr_length ; /* Lengths of each of the */ /* keywords. */ target_tally_array_type dirr_tally ; /* Tally of detected */ /* keywords. */ target_tally_array_type local_dirr_tally ; /* Tally of keywords in a */ /* line to be used as an */ /* indicator to classify */ /* the line. */ target_name_array_type data_names ; /* List of keywords to be */ /* searched for. */ target_tag_array_type data_tags ; /* List of keywords to be */ /* printed out. */ target_length_array_type data_length ; /* Lengths of each of the */ /* keywords. */ target_tally_array_type data_tally ; /* Tally of detected */ /* keywords. */ target_tally_array_type local_data_tally ; /* Tally of keywords in a */ /* line to be used as an */ /* indicator to classify */ /* the line. */ target_name_array_type exec_names ; /* List of keywords to be */ /* searched for. */ target_tag_array_type exec_tags ; /* List of keywords to be */ /* printed out. */ target_length_array_type exec_length ; /* Lengths of each of the */ /* keywords. */ target_tally_array_type exec_tally ; /* Tally of detected */ /* keywords. */ long int lines ; long int blank_lines ; long int comment_lines ; long int e_comm_lines ; tally_type directive_lines ; tally_type data_lines ; tally_type exec_lines ; tally_type SLOC_lines ; long int temp ; double ftemp ; long int spaces ; bool_type found ; double next_percent ; long int files_processed ; long int num_list_files ; bool_type blank_flag ; bool_type comment_flag ; bool_type comment_start ; new_boolean_type comment_stop ; bool_type code_on_left ; bool_type code_on_right ; bool_type double_slash_comm ; long int internal_comment ; bool_type string_flag ; bool_type directive_flag ; bool_type directive_continue ; bool_type begin_paren_flag ; bool_type end_paren_flag ; long int paren_count ; bool_type data_flag ; bool_type data_continue ; bool_type found_brace ; long int num_FOR_IF_WHILE ; long int num_terminators ; bool_type SLOC_end_flag ; line_mode_type line_mode ; bool_type source_flag ; bool_type open_error ; error_type error_cond ; bool_type close_match ; long int line_loc ; time_t today ; struct tm *current_time ; /* Characters that can be */ /* appended to keywords to */ /* make identifiers. */ exclude_type exclude = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$"; /* Characters that can be */ /* located adjacent to a */ /* keyword. */ /* Do not include underscore,*/ /* statement terminator, or */ /* statement separators. */ special_type special = "[]()+/-*<>=,@&~!^?:%{}"; /*****************************************************************************/ /*****************************************************************************/ /* Initialize program, and */ /* open external files. */ /* Open outfile */ if (NULL != (c_outfile = fopen("c_outfile.dat","w"))) error_cond = OK; else { error_cond = OUTFILE_OPEN; error_handler(&error_cond, NULL, c_outfile); exit(EXIT_SUCCESS); /* Halt program */ } /* Open environment file */ if ((NULL != (c_lines_environment = fopen("c_env.dat","r"))) || (NULL != (c_lines_environment = fopen("c_lines_environment.dat","r"))) ) { error_cond = OK; get_user_info( UD_Project_Name, &UD_QA_Switch, &UD_Compare_Spec, &UD_Line_Length, &UD_Exec_Lines, &UD_Data_Lines, &UD_Min_Percent, &UD_Inc_Percent, &UD_Display_File, &UD_Intro_Msg, &UD_SLOC_Def, &UD_WordWrap, &error_cond, c_lines_environment); error_handler(&error_cond, NULL, c_outfile); fclose(c_lines_environment); } else { /* Insert default values. */ error_cond = ENVFILE_OPEN; get_user_info( UD_Project_Name, &UD_QA_Switch, &UD_Compare_Spec, &UD_Line_Length, &UD_Exec_Lines, &UD_Data_Lines, &UD_Min_Percent, &UD_Inc_Percent, &UD_Display_File, &UD_Intro_Msg, &UD_SLOC_Def, &UD_WordWrap, &error_cond, NULL); error_handler(&error_cond, NULL, c_outfile); } /* Open list file */ if ((NULL != (c_list = fopen( "c_lst.dat","r"))) || (NULL != (c_list = fopen("c_list.dat","r"))) ) { error_cond = OK; next_percent = UD_Inc_Percent; files_processed = 0; get_list_file_size(c_list, &num_list_files); if (num_list_files == 0) { error_cond = LISTFILE_READ; error_handler(&error_cond, NULL, c_outfile); exit(EXIT_SUCCESS); /* Halt program */ } } else { error_cond = LISTFILE_OPEN; error_handler(&error_cond, NULL, c_outfile); exit(EXIT_SUCCESS); /* Halt program */ } /*****************************************************************************/ /* Initialize variables. */ load_name_and_tag_arrays(dirr_names, dirr_tags, dirr_length, DIRR_NAME_LIST, MAX_DIRR_TARGETS); load_name_and_tag_arrays(data_names, data_tags, data_length, DATA_NAME_LIST, MAX_DATA_TARGETS); load_name_and_tag_arrays(exec_names, exec_tags, exec_length, EXEC_NAME_LIST, MAX_EXEC_TARGETS); clear_tally(dirr_tally, MAX_DIRR_TARGETS); clear_tally(data_tally, MAX_DATA_TARGETS); clear_tally(exec_tally, MAX_EXEC_TARGETS); for (file_mode = CODE; file_mode <= DATA; file_mode++) for (SLOC_mode = PHY; SLOC_mode <= LOG; SLOC_mode++) { /* For */ total_lines[file_mode][SLOC_mode] = 0 ; total_blank_lines[file_mode][SLOC_mode] = 0 ; total_comment_lines[file_mode][SLOC_mode] = 0 ; total_e_comm_lines[file_mode][SLOC_mode] = 0 ; total_directive_lines[file_mode][SLOC_mode] = 0 ; total_exec_lines[file_mode][SLOC_mode] = 0 ; total_data_lines[file_mode][SLOC_mode] = 0 ; total_SLOC_lines[file_mode][SLOC_mode] = 0 ; total_number_files[file_mode][SLOC_mode] = 0 ; } /* For */ exceed_UD_Exec_Lines = 0 ; exceed_UD_Data_Lines = 0 ; exceed_UD_Min_Percent = 0 ; file_mode_names[CODE][0] = 'C'; file_mode_names[CODE][1] = 'O'; file_mode_names[CODE][2] = 'D'; file_mode_names[CODE][3] = 'E'; file_mode_names[CODE][4] = '\0'; file_mode_names[DATA][0] = 'D'; file_mode_names[DATA][1] = 'A'; file_mode_names[DATA][2] = 'T'; file_mode_names[DATA][3] = 'A'; file_mode_names[DATA][4] = '\0'; if (UD_Compare_Spec == 1) close_match = True ; /* Must compare exactly */ else close_match = False; /* Could compare loosely */ /*****************************************************************************/ /* Print introduction message*/ if (UD_Intro_Msg != 0) output_intro_msg(c_outfile); /*****************************************************************************/ /* Print outfile header */ fprintf(c_outfile,"%28c",BLANK); /* 28 = center in 100 columns*/ fprintf(c_outfile,"C/C++ SOURCE LINES OF CODE COUNTING PROGRAM\n"); fprintf(c_outfile,"%11c",BLANK); /* 11 = center in 100 columns*/ fprintf(c_outfile,"( c ) Copyright 1998 - 2006 "); fprintf(c_outfile,"University of Southern California, "); fprintf(c_outfile,"CodeCount (TM)\n"); fprintf(c_outfile,"\n"); fprintf(c_outfile," University of Southern California retains"); fprintf(c_outfile," ownership of this copy of software. It is"); fprintf(c_outfile," licensed to you.\n"); fprintf(c_outfile,"Use, duplication, or sale of this product,"); fprintf(c_outfile," except as described in the CodeCount License"); fprintf(c_outfile," Agreement, is\n"); fprintf(c_outfile,"strictly prohibited. This License and your"); fprintf(c_outfile," right to use the software automatically"); fprintf(c_outfile," terminate if\n"); fprintf(c_outfile,"you fail to comply with any provisions of"); fprintf(c_outfile," the License Agreement. Violators may be"); fprintf(c_outfile," prosecuted.\n"); fprintf(c_outfile,"This product is licensed to : %s\n", LICENTIATE); fprintf(c_outfile,"\n"); spaces = ((100 - MAX_PROJECT_NAME) / 2); /* 100 = 100 columns */ for (i = 0; i < spaces; i++) fprintf(c_outfile,"%c",BLANK); fprintf(c_outfile,"%s\n", UD_Project_Name); fprintf(c_outfile,"\n"); if (UD_SLOC_Def == 'P') { fprintf(c_outfile," Total Blank | Comments | Compiler Data "); fprintf(c_outfile,"Exec. |Physical| File Module\n"); } else { fprintf(c_outfile," Total Blank | Comments | Compiler Data "); fprintf(c_outfile,"Exec. |Logical | File Module\n"); } fprintf(c_outfile," Lines Lines | Whole Embedded | Direct. Decl. "); fprintf(c_outfile,"Instr. | SLOC | Type Name\n"); spaces = MAX_HEADER_LENGTH + MAX_FILENAME_LENGTH; for (i = 0; i < spaces; i++) fprintf(c_outfile,"%c",BAR); fprintf(c_outfile,"\n"); /*****************************************************************************/ /* Get 'infile' name. */ list_int = fgetc(c_list) ; list_ch = (char)list_int; while (list_int != EOF) { /* While Not EOF(c_list) */ for (i = 0; i < MAX_LIST_FILENAME_LENGTH; i++) list_filename[i] = BLANK ; /* Clear 'list_filename' */ i = 0; /* Read c_list entry */ while ((list_ch != '\n') && (list_int != EOF ) && (i < MAX_LIST_FILENAME_LENGTH) ) { if (list_ch != CR_CHAR) /* Do not write carriage */ list_filename[i] = list_ch; /* returns; MS DOS files. */ list_int = fgetc(c_list) ; list_ch = (char)list_int; i++; } list_filename[i] = '\0' ; /* Insert null character */ while ((list_ch != '\n') && /* Position pointer to next */ (list_int != EOF ) ) /* entry in c_list */ { list_int = fgetc(c_list) ; list_ch = (char)list_int; i++; } if (i > MAX_LIST_FILENAME_LENGTH) { /* Skip file due to filename */ error_cond = LISTFILE_TRUNC; /* error. */ error_handler(&error_cond, NULL, c_outfile); } else if (list_int != EOF) { /* Continue with next line */ list_int = fgetc(c_list) ; /* by parsing over newline */ list_ch = (char)list_int; /* character. */ } /*****************************************************************************/ /* Open 'infile', */ /* process file extension, */ /* initialize parameters */ transfer_file_name(list_filename, filename); if (NULL != (infile = fopen(list_filename,"rw"))) { /* If 'infile' is open */ error_cond = OK; open_error = False; /* Determine if 'infile' */ /* contains C source code */ extension(filename, ext); /* Get file extension. */ source_flag = False; /* Assume data file type */ search(ext,".C ", 0, 4, False, MAX_FILENAME_LENGTH, &found, &line_loc, 0); if (found == True) source_flag = True; search(ext,".CC ", 0, 4, False, MAX_FILENAME_LENGTH, &found, &line_loc, 0); if (found == True) source_flag = True; search(ext,".CPP ", 0, 4, False, MAX_FILENAME_LENGTH, &found, &line_loc, 0); if (found == True) source_flag = True; search(ext,".H ", 0, 4, False, MAX_FILENAME_LENGTH, &found, &line_loc, 0); if (found == True) source_flag = True; search(ext,".HH ", 0, 4, False, MAX_FILENAME_LENGTH, &found, &line_loc, 0); if (found == True) source_flag = True; search(ext,".HPP ", 0, 4, False, MAX_FILENAME_LENGTH, &found, &line_loc, 0); if (found == True) source_flag = True; if (source_flag == True) file_mode = CODE; /* 'infile' is a source file */ else file_mode = DATA; /* 'infile' is a data file */ lines = 0 ; /* Reset for new infile */ blank_lines = 0 ; comment_lines = 0 ; e_comm_lines = 0 ; for (SLOC_mode = PHY; SLOC_mode <= LOG; SLOC_mode++) { /* For */ directive_lines[SLOC_mode] = 0 ; data_lines[SLOC_mode] = 0 ; exec_lines[SLOC_mode] = 0 ; SLOC_lines[SLOC_mode] = 0 ; } /* For */ comment_start = False; comment_stop = UNDEF; double_slash_comm = False; string_flag = False; directive_continue = False; begin_paren_flag = False; end_paren_flag = False; paren_count = 0 ; data_flag = False; data_continue = False; found_brace = False; num_FOR_IF_WHILE = 0 ; num_terminators = 0 ; SLOC_end_flag = False; line_mode = ANY ; } /* If 'infile' is open */ else { /* Else */ open_error = True; error_cond = INFILE_OPEN; error_handler(&error_cond, filename, c_outfile); } /* Else */ /*****************************************************************************/ /* Detected C source */ if (open_error == False) { /* Get first char of infile */ lch = fgetc(infile); ch = (char)lch; if (lch == EOF) /* Process an empty file */ { /* Rev-8 repair */ error_cond = INFILE_EMPTY; error_handler(&error_cond, filename, c_outfile); } } while ((open_error == False) && /*Rev-10, changed the order of*/ (lch != EOF ) && /* '&&' to make sure lch is */ (source_flag == True ) ) /* assigned before being used*/ { /* While Not EOF infile */ /*****************************************************************************/ /* Get a line of 'infile' */ for (i = 0; i < UD_Line_Length + 2; i++) line[i] = BLANK ; /* Clear 'line' */ i = 0; /* Must insert a blank to */ while ((ch != '\n') && /* aid search for any */ (lch != EOF ) && /* embedded comments. */ ( i < UD_Line_Length) ) { /* While */ i++; if ((ch == FF_CHAR) || /* Replace form feeds, tabs, */ (ch == TAB_CHAR) || /* and carriage return */ (ch == CR_CHAR) ) /* chars with a blank char. */ line[i] = BLANK ; else line[i] = ch ; lch = fgetc(infile); /* Get next character. */ ch = (char)lch; } /* While */ line_length = i ; /* Length of 'line' read */ line[i+1] = '\0'; /* Insert null character */ if (UD_WordWrap == 'N') { /* If no wordwrap */ while ((ch != '\n') && /* Position ptr to beginning */ (lch != EOF ) && /* of next line in infile. */ ( i < MAX_EOLN_TRIES) ) { lch = fgetc(infile); ch = (char)lch; i++; } if (i > MAX_LINE_LENGTH) { /* Terminate, info on line of*/ open_error = True; /* infile will not fit into */ error_cond = LINE_SIZE; /* size of 'line'. */ error_handler(&error_cond, filename, c_outfile); fclose(infile); /* No further reads from file*/ lch = EOF; /* Will terminate processing.*/ } else if (i > UD_Line_Length) { /* Terminate, truncated */ open_error = True; /* trailing info. on line of*/ error_cond = LINE_TRUNC; /* infile */ error_handler(&error_cond, filename, c_outfile); fclose(infile); /* No further reads from file*/ lch = EOF; /* Will terminate processing.*/ } } /* If no wordwrap */ else { /* Else, process wordwrap */ if ((ch != '\n') && (ch != EOF ) && (line_length == MAX_LINE_LENGTH)) { /* If, long line */ for (j = 0; j < MAX_WW_LINE_LENGTH; j++) ww_line[j] = BLANK ; /* Clear 'ww_line' */ ww_line[MAX_WW_LINE_LENGTH] = '\0'; /* Insert null character. */ /* Place remaining char's on */ j = 0; /* line into a circular */ ww_count = 0; /* buffer. */ while ((ch != '\n') && (lch != EOF ) ) { /* While, fill 'ww_line' */ if ((ch == FF_CHAR) || /* Replace form feeds, tabs, */ (ch == TAB_CHAR) || /* and carriage return */ (ch == CR_CHAR) ) /* chars with a blank char. */ ww_line[j] = BLANK; else ww_line[j] = ch ; ww_count++; /* Count # chars until EOLN. */ if (j == (MAX_WW_LINE_LENGTH - 1)) /* Update circular ptrs. */ j = 0; /* Reset to zero. */ else j++; /* Increment pointer. */ lch = fgetc(infile); /* Get next character. */ ch = (char)lch; } /* While, fill 'ww_line' */ if (j <= 0) /* Back up pointer one loc */ j = (MAX_WW_LINE_LENGTH - 1); /* due to reading EOLN char.*/ else j--; /* Adjust 'ww_count' to */ if (ww_count > MAX_WW_LINE_LENGTH) /* copy last 'n' chars from */ ww_count = MAX_WW_LINE_LENGTH; /* circular buffer. */ /* Copy n chars from circular*/ /* buffer to last n chars */ for (i = ww_count; i > 0; i--) /* of 'line'. */ { /* For */ line[MAX_LINE_LENGTH - ww_count + i] = ww_line[j]; if (j == 0) /* Update circular ptrs. */ j = MAX_WW_LINE_LENGTH - 1; else j--; } /* For */ /* Insert blank just prior to*/ /* copied chars in 'line'. */ line[MAX_LINE_LENGTH - ww_count] = BLANK; /* Set error condition if */ /* wordwrap processing has */ /* concatenated a SLOC that */ /* is not a comment line. */ search(line, "//", 0, 1, close_match, line_length, &found, &line_loc, 0); /* End delimter should be */ /* located at end of long */ /* comment line. */ search(line, "*/", 0, 1, close_match, line_length, &lf_1, &line_loc, (MAX_LINE_LENGTH - MAX_WW_LINE_LENGTH)); search(line, "/*", 0, 1, close_match, line_length, &lf_2, &line_loc, 0); if ((found == False) && (lf_1 == False) && (lf_2 == False) && (comment_flag == False) ) { /* Terminate, wordwrap has */ open_error = True; /* compressed a non-comment */ error_cond = LINE_WRAP; /* SLOC within 'line'. */ error_handler(&error_cond, filename, c_outfile); fclose(infile); /* No further reads from file*/ lch = EOF; /* Will terminate processing.*/ } } /* If, long line */ } /* Else, process wordwrap */ if (lch != EOF) { /* Continue with next line */ lch = fgetc(infile); /* by parsing over newline */ ch = (char)lch; /* character. */ } /*****************************************************************************/ /* Check for a blank line */ blank_flag = True; i = 1; while ((i <= line_length ) && (blank_flag == True) ) { /* While */ if (line[i] != ' ') blank_flag = False; else i++; } /* While */ if (blank_flag == True) blank_lines++; /*****************************************************************************/ /* Overwrite single character*/ /* literals, escape sequence*/ /* literals, and \" prior */ /* to comment search and */ /* string processing. */ if (blank_flag == False) { /* If */ for (i = 1; i <= line_length - 2; i++) { /* For */ if (line[i] == QUOTE_CHAR) { /* If quote */ if (line[i+3] == QUOTE_CHAR) { /* Found escape sequence */ line[ i ] = '$'; /* inside of a single char. */ line[i+1] = '$'; /* literal, e.g. '\r', '\'',*/ line[i+2] = '$'; /* or '\"'. */ line[i+3] = '$'; } if (line[i+2] == QUOTE_CHAR) { /* Found single char. literal*/ line[ i ] = '$'; /* e.g. 'a'. */ line[i+1] = '$'; line[i+2] = '$'; } } /* If quote */ if (line[i-1] == '\\') if ((line[i] == QUOTE_CHAR) || (line[i] == '\"' ) ) { /* If \' or \" escape seq. */ line[ i ] = '$'; line[i-1] = '$'; } /* If \' or \" escape seq. */ } /* For */ if (line[line_length - 1] == '\\') /* If, epilog of loop */ if ((line[line_length] == QUOTE_CHAR) || (line[line_length] == '"' ) ) { line[ line_length ] = '$'; /* Found \' or \" escape seq.*/ line[line_length - 1] = '$'; } } /* If */ /*****************************************************************************/ /* */ /* Comment / String processing: */ /* - scan each physical line for the beginning comment delimiter. */ /* - note when code appears prior to comment delimiter to indicate */ /* the comment is an embedded comment. */ /* - scan for a string delimiter. */ /* - overwrite contents of comments including the delimiters. */ /* - blank contents of embedded comments including the delimiters. */ /* - set 'comment_flag' to true for whole line comments. */ /* */ /* Notes: */ /* - the "//" indicates the start of a C++ comment terminated by the EOLN. */ /* - the slash-asterisk indicates the start of an ANSI-C comment. */ /* - the asterisk-slash indicates the end of an ANSI-C comment. */ /* - slash-asterisk-slash triplet is interpreted as the start of a comment.*/ /* - two or more whole line comments on the same physical line shall count */ /* as a single comment so as not to corrupt the physical line check. */ /* */ /*****************************************************************************/ comment_flag = False; if (blank_flag == False) { /* Comment processing */ code_on_left = False; code_on_right = False; double_slash_comm = False; internal_comment = 0 ; /* Signifies a comment cont- */ /* inuation on a new line */ /* for rewrite of 'line' */ if ((comment_start == True ) && (comment_stop == UNDEF) ) { line[0] = '+'; } /*****************************************************************************/ /* Continue with comment */ /* processing. */ for (i = 1; i <= line_length; i++) { /* For */ switch (line[i]) { /* Switch */ case ' ': break; /* Do nothing */ case '/': if ((string_flag == False) && (comment_start == False) && (double_slash_comm == False) ) { /* If */ if ((line[i+1] == '/') && (line[i-1] != '*') ) /* Differentiates a double */ /* slash from an asterisk- */ /* slash slash-asterisk set.*/ { /* If C++ */ if (code_on_left == True) { comment_start = True; /* C++ embedded comment */ /* Change delimiters to */ line[i+1] = '*'; /* clear comment */ line[line_length - 1] = '*'; line[line_length ] = '/'; } else { /* Else */ comment_lines++; /* C++ whole line comment */ comment_flag = True; double_slash_comm = True; } /* Else */ } /* If C++ */ else { /* Else ANSI-C */ if ((line[i+1] == '*' ) && (double_slash_comm == False) ) { comment_start = True ; /* Found comment start */ if (line[i+2] == '/') line[i+1] = BLANK ; /* Rev-4 repair */ } } /* Else ANSI-C */ } /* If */ break; case '*': if ((line[i+1] == '/' ) && (comment_start == True ) && /* Rev-4 repair */ (double_slash_comm == False) ) comment_stop = YES; /* Found comment stop */ break; default: if ((comment_start == False) && (double_slash_comm == False) ) { /* If, not a comment */ if (internal_comment == 0) code_on_left = True; /* Code prior to comment */ else code_on_right = True; /* Code following comment */ } /* If, not a comment */ } /* Switch */ /* Delete string contents by */ /* overwrite with '$' to */ /* differentiate from */ /* normal blank lines. */ /* Thus, keywords in strings */ /* are not counted. */ /* Ignore string delimiters */ /* within comments. Rev-8 */ if ((line[i] == '"' ) && (comment_start == False) && (comment_flag == False) ) { /* If string */ if (string_flag == False) string_flag = True ; /* Detected a string start */ else { string_flag = False; /* Detected a string stop */ line[i] = '$' ; } } /* If string */ if (string_flag == True) { /* Don't overwrite if line[i]*/ /* is a continuation char. */ if (line[i] != '\\') line[i] = '$'; /* Clear contents of string */ } if ((comment_start == True) && (comment_stop == YES ) ) { internal_comment++; /* Found an embedded comment */ comment_start = False; comment_stop = UNDEF; } } /* For */ /* Comment starts but does */ /* not end on same line. */ if ((comment_start == True ) && (comment_stop == UNDEF) ) { /* If */ if (code_on_left == False) { /* If */ comment_lines++; /* Whole line comment */ internal_comment = 0; comment_flag = True ; } /* If */ else { /* Else */ e_comm_lines = e_comm_lines + 1 + internal_comment; internal_comment = 0; /* Ensure a matching set */ /* of comment delimiters */ /* for rewrite of 'line' */ line[line_length - 1] = '*'; line[line_length ] = '/'; } /* Else */ } /* If */ /* Continuation of, or */ /* comment starts and ends */ /* on the same line */ if (internal_comment > 0) { /* If > 0 */ if ((code_on_left == False) && (code_on_right == False) ) { /* If */ comment_lines++; /* Whole line comment */ internal_comment = 0; comment_start = False; comment_stop = UNDEF; comment_flag = True ; } /* If */ else { /* Else */ e_comm_lines = e_comm_lines + internal_comment; internal_comment = 0; /* Embedded comment */ comment_start = False; comment_stop = UNDEF; } /* Else */ } /* If > 0 */ } /* Comment processing */ /*****************************************************************************/ /* Eliminate remaining */ /* comments from 'line' */ /* prior to keyword search. */ found = False; if ((comment_flag == False) && (blank_flag == False) ) { /* If */ /* Comment starts on previous*/ /* line and continues onto */ if (line[0] == '+') /* the current line. */ found = True; for (i = 1; i <= line_length; i++) { /* For */ if ((line[ i ] == '/') && (line[i+1] == '*') ) found = True; /* Found a comment start */ if ((line[ i ] == '*') && (line[i+1] == '/') ) { /* Found a comment stop */ found = False; line[ i ] = ' '; /* Blank comment delimiter */ line[i+1] = ' '; } if (found == True) line[i] = ' '; /* Clear contents of comment */ } /* For */ } /* If */ /*****************************************************************************/ /* */ /* Compiler Directive processing: */ /* - scan for DIRR_PREFIX and eliminate spaces (blanks) prior to */ /* directive keyword. */ /* - use DIRR_NAME_LIST to verify that a directive has been detected. */ /* - declare SLOC to be a directive line accordingly. */ /* - increment physical line count. */ /* - search for a continuation character. */ /* - set directive_continue accordingly. */ /* - increment logical line count accordingly. */ /* */ /* Notes: */ /* - directives can continue via a back-slash or via a comma. */ /* - directive processing precedes special processing due to elimination */ /* of DIRR_PREFIX during special processing. */ /* */ /*****************************************************************************/ if ((blank_flag == False) && (comment_flag == False) ) if (directive_continue == False) { /* If check for direct. */ /* Reset when previous line */ if (line_mode == DIR) /* was classified as a */ line_mode = ANY ; /* directive line. */ directive_flag = False; compress_directives(line, DIRR_PREFIX, &line_length, &found); if (found == True) /* Found a directive symbol */ { /* If DIRR_PREFIX */ clear_tally(local_dirr_tally, MAX_DIRR_TARGETS); count_targets(dirr_names, local_dirr_tally, dirr_length, MAX_DIRR_TARGETS, line, close_match, line_length, &found, &line_loc, exclude); lc2 = 0; for (lc1 = 0; lc1 < MAX_DIRR_TARGETS; lc1++) lc2 = lc2 + local_dirr_tally[lc1]; if (lc2 > 0) directive_flag = True ; else directive_flag = False; if (directive_flag == True) { /* Found directive */ line_mode = DIR ; directive_lines[PHY]++; /* Update physical SLOC lines*/ search_for_continuation(line, line_length, &directive_continue); if (directive_continue == False) directive_lines[LOG]++; /* Update logical SLOC lines */ if (UD_QA_Switch == 1) for (lc1 = 0; lc1 < MAX_DIRR_TARGETS; lc1++) dirr_tally[lc1] = dirr_tally[lc1] + local_dirr_tally[lc1]; } /* Found directive */ } /* If DIRR_PREFIX */ } /* If check for direct. */ else { /* Else directive continue */ directive_flag = True ; directive_lines[PHY]++; /* Update physical SLOC lines*/ count_targets(dirr_names, dirr_tally, dirr_length, MAX_DIRR_TARGETS, line, close_match, line_length, &found, &line_loc, exclude); search_for_continuation(line, line_length, &directive_continue); if (directive_continue == False) directive_lines[LOG]++; /* Update logical SLOC lines */ } /* Else directive continue */ /*****************************************************************************/ /* */ /* Special processing: */ /* - determine the number of '}' statement terminators per physical line. */ /* - determine the number of ';' statement terminators per physical line. */ /* - don't count '}' followed immediately by a ';'. */ /* - don't count ';'s inside of parenthesis, e.g. for conditionals. */ /* - increment number of statement terminators due to occurrences of FOR, */ /* IF and WHILE statements that do not terminate with a '}'. */ /* - blank characters from 'line' that are contained in 'special'. */ /* */ /* Notes: */ /* - FOR, IF, and WHILE keywords can be followed by a left paren. */ /* */ /*****************************************************************************/ if ((blank_flag == False) && (comment_flag == False) && (directive_flag == False) ) { /* If */ /* Search for IF */ search(line, " if ", 0, 3, close_match, line_length, &lf_1, &line_loc, 0); search(line, " if(", 0, 3, close_match, line_length, &lf_2, &line_loc, 0); if ((lf_1 == True) || (lf_2 == True) ) num_FOR_IF_WHILE++; /* Inc with each occurrence. */ /* Search for FOR */ search(line, " for ", 0, 4, close_match, line_length, &lf_1, &line_loc, 0); search(line, " for(", 0, 4, close_match, line_length, &lf_2, &line_loc, 0); if ((lf_1 == True) || (lf_2 == True) ) num_FOR_IF_WHILE++; /* Inc with each occurrence. */ /* Search for WHILE */ search(line, " while ", 0, 6, close_match, line_length, &lf_1, &line_loc, 0); search(line, " while(", 0, 6, close_match, line_length, &lf_2, &line_loc, 0); if ((lf_1 == True) || (lf_2 == True) ) num_FOR_IF_WHILE++; /* Inc with each occurrence. */ for (i = 1; i <= line_length; i++) { /* For */ if (line[i] == '(') /* Used to terminate data */ { /* declar. in arg. lists. */ begin_paren_flag = True; paren_count++; } if (line[i] == ')') /* Used to terminate data */ { /* declar. in arg. lists. */ end_paren_flag = True; paren_count--; } if (line[i] == ';') /* Process ';' not within ()s*/ if (paren_count == 0) { if (found_brace == False) { /* Will not update a logical */ SLOC_end_flag = True; /* SLOC when '}' is followed*/ num_terminators++; /* by a ';'. */ if (num_FOR_IF_WHILE >= 0) /* All previous FOR, IF, or */ { /* WHILE statements did not */ /* have a ';' or '}' logical*/ /* SLOC terminator. */ exec_lines[LOG] = exec_lines[LOG] + num_FOR_IF_WHILE; num_FOR_IF_WHILE = 0; /* Reset for next occurrence.*/ } else { /* Error, can't be < 0. */ error_cond = LOG_COUNT; error_handler(&error_cond, filename, c_outfile); num_FOR_IF_WHILE = 0; } } } else line[i] = ' '; /* Blank ';' in FOR construct*/ if (found_brace == True) /* Continue processing '}' */ { /* by examining next char. */ if (line[i] == ',') { SLOC_end_flag = False; /* Continuation of current */ found_brace = False; /* line, '}' is not a */ num_terminators--; /* logical SLOC terminator. */ } if (line[i] != ' ') { /* '}' is a logical SLOC */ found_brace = False; /* terminator, expect to */ } /* detect more ';'s. */ } if (line[i] == '}') { /* Logical SLOC terminator */ SLOC_end_flag = True; found_brace = True; num_terminators++; } if ((line[i] == '{') && /* Block for FOR, IF, or */ (num_FOR_IF_WHILE > 0 ) ) /* WHILE will be processed */ num_FOR_IF_WHILE--; /* when '}' is detected. */ if (NULL != strchr(special, line[i])) line[i] = ' '; } /* For */ } /* If */ /*****************************************************************************/ /* */ /* Data Line processing: */ /* - use DATA_NAME_LIST to determine that a data line has been detected. */ /* - declare SLOC to be a data line accordingly. */ /* - increment physical line count. */ /* - use previous detection of a terminal ';' or '}' to indicate */ /* termination of the data line. */ /* - increment logical line count accordingly. */ /* */ /* Notes: */ /* - default is an executable line. */ /* */ /*****************************************************************************/ if ((blank_flag == False) && (comment_flag == False) && (directive_flag == False) ) { /* If */ /* data_continue is true only*/ /* during processing of */ /* data declarations. */ if ((data_flag == True ) && (data_continue == False) ) data_flag = False; /* Reset data_flag */ clear_tally(local_data_tally, MAX_DATA_TARGETS); count_targets(data_names, local_data_tally, data_length, MAX_DATA_TARGETS, line, close_match, line_length, &found, &line_loc, exclude); lc2 = 0; for (lc1 = 0; lc1 < MAX_DATA_TARGETS; lc1++) lc2 = lc2 + local_data_tally[lc1]; if ((lc2 > 0 ) || (data_continue == True) ) data_flag = True ; else data_flag = False; if (data_flag == True) { /* If data declaration */ line_mode = DAT ; data_lines[PHY]++; /* Update physical SLOC lines*/ if (SLOC_end_flag == True) { /* Update logical SLOC lines */ data_lines[LOG] = data_lines[LOG] + num_terminators; SLOC_end_flag = False; /* Reset for next SLOC line */ num_terminators = 0 ; line_mode = ANY ; data_continue = False; } else data_continue = True ; if (UD_QA_Switch == 1) /* Look for keywords */ for (lc1 = 0; lc1 < MAX_DATA_TARGETS; lc1++) data_tally[lc1] = data_tally[lc1] + local_data_tally[lc1]; } /* If data declaration */ } /* If */ /*****************************************************************************/ /* */ /* Executable Line processing: */ /* - default is an executable line. */ /* - declare SLOC to be a executable line accordingly. */ /* - increment physical line count. */ /* - use previous detection of a terminal ';' or '}' to indicate */ /* termination of the data line. */ /* - increment logical line count accordingly. */ /* - count keywords in EXEC_NAME_LIST. */ /* */ /* Notes: */ /* - */ /* */ /*****************************************************************************/ if ((blank_flag == False) && (comment_flag == False) && (directive_flag == False) && (data_flag == False) ) { /* If */ line_mode = EXE ; exec_lines[PHY]++; /* Update physical SLOC lines*/ if (SLOC_end_flag == True) { /* Update logical SLOC lines */ exec_lines[LOG] = exec_lines[LOG] + num_terminators; SLOC_end_flag = False; /* Reset for next SLOC line */ num_terminators = 0 ; line_mode = ANY ; } if (UD_QA_Switch == 1) /* Search for keywords. */ count_targets(exec_names, exec_tally, exec_length, MAX_EXEC_TARGETS, line, close_match, line_length, &found, &line_loc, exclude); } /* If */ /*****************************************************************************/ /* Fault Tolerance against */ /* misclassification of */ /* data_lines following end */ /* of a function argument */ /* list. */ if ((begin_paren_flag == True) && ( end_paren_flag == True) && (paren_count == 0 ) ) { begin_paren_flag = False; /* Reset, found final */ end_paren_flag = False; /* matching set. */ if ((blank_flag == False) && (comment_flag == False) && (data_flag == True ) && (data_continue == True ) ) { /* Reset BOOLEANS */ comment_start = False; comment_stop = UNDEF; directive_continue = False; data_continue = False; string_flag = False; } /* Reset BOOLEANS */ } /*****************************************************************************/ /* Update total lines */ lines = lines + 1; /*****************************************************************************/ } /* While Not EOF(infile) */ /*****************************************************************************/ /* Detected a data file */ while ((open_error == False) && /*Rev-10, changed the order of*/ (lch != EOF ) && /* '&&' to make sure lch is */ (source_flag == False) ) /* assigned before being used*/ { /* While Not EOF infile */ /*****************************************************************************/ /* Get a line of 'infile' */ for (i = 0; i < UD_Line_Length + 2; i++) line[i] = BLANK ; /* Clear 'line' */ i = 0; /* Must insert a blank to */ while ((ch != '\n') && /* aid search for any */ (lch != EOF ) && /* embedded comments. */ ( i < UD_Line_Length) ) { /* While */ i++; if ((ch == FF_CHAR) || /* Replace form feeds, tabs, */ (ch == TAB_CHAR) || /* and carriage return */ (ch == CR_CHAR) ) /* chars with a blank char. */ line[i] = BLANK ; else line[i] = ch ; lch = fgetc(infile); /* Get next character. */ ch = (char)lch; } /* While */ line_length = i ; /* Length of 'line' read */ line[i+1] = '\0'; /* Insert null character */ while ((ch != '\n') && /* Position ptr to beginning */ (lch != EOF ) && /* of next line in infile. */ ( i < MAX_EOLN_TRIES) ) { lch = fgetc(infile); ch = (char)lch; i++; } if (i > MAX_LINE_LENGTH) { /* Terminate, info on line of*/ open_error = True; /* infile will not fit into */ error_cond = LINE_SIZE; /* size of 'line'. */ error_handler(&error_cond, filename, c_outfile); fclose(infile); /* No further reads from file*/ lch = EOF; /* Will terminate processing.*/ } else if (i > UD_Line_Length) { /* Terminate, truncated */ open_error = True; /* trailing info. on line of*/ error_cond = LINE_TRUNC; /* infile */ error_handler(&error_cond, filename, c_outfile); fclose(infile); /* No further reads from file*/ lch = EOF; /* Will terminate processing.*/ } else if (lch != EOF) { /* Continue with next line */ lch = fgetc(infile); /* by parsing over newline */ ch = (char)lch; /* character. */ } /*****************************************************************************/ /* Check for a blank line */ blank_flag = True; i = 1; while ((i <= line_length ) && (blank_flag == True) ) { /* While */ if (line[i] != ' ') blank_flag = False; else i++; } /* While */ if (blank_flag == True) blank_lines++; else /* Otherwise data line */ { data_lines[PHY]++; /* Update physical SLOC lines*/ data_lines[LOG]++; /* Update logical SLOC lines*/ } /*****************************************************************************/ /* Update total lines */ lines = lines + 1; /*****************************************************************************/ } /* While Not EOF(infile) */ /*****************************************************************************/ /* Update statistics, & */ /* prepare for next infile */ if (open_error == False) { /* If open_error = FALSE */ for (SLOC_mode = PHY; SLOC_mode <= LOG; SLOC_mode++) { /* For */ SLOC_lines[SLOC_mode] = directive_lines[SLOC_mode] + data_lines[SLOC_mode] + exec_lines[SLOC_mode] ; total_lines[file_mode][SLOC_mode] = total_lines[file_mode][SLOC_mode] + lines ; total_blank_lines[file_mode][SLOC_mode] = total_blank_lines[file_mode][SLOC_mode] + blank_lines ; total_comment_lines[file_mode][SLOC_mode] = total_comment_lines[file_mode][SLOC_mode] + comment_lines; total_e_comm_lines[file_mode][SLOC_mode] = total_e_comm_lines[file_mode][SLOC_mode] + e_comm_lines ; total_directive_lines[file_mode][SLOC_mode] = total_directive_lines[file_mode][SLOC_mode] + directive_lines[SLOC_mode] ; total_data_lines[file_mode][SLOC_mode] = total_data_lines[file_mode][SLOC_mode] + data_lines[SLOC_mode] ; total_exec_lines[file_mode][SLOC_mode] = total_exec_lines[file_mode][SLOC_mode] + exec_lines[SLOC_mode] ; total_SLOC_lines[file_mode][SLOC_mode] = total_SLOC_lines[file_mode][SLOC_mode] + SLOC_lines[SLOC_mode] ; total_number_files[file_mode][SLOC_mode] = total_number_files[file_mode][SLOC_mode] + 1 ; } /* For */ if (source_flag == True) { /* If source flag */ if (UD_SLOC_Def == 'P') { /* If physical SLOC */ if (exec_lines[PHY] > UD_Exec_Lines) exceed_UD_Exec_Lines++; if (data_lines[PHY] > UD_Data_Lines) exceed_UD_Data_Lines++; if (SLOC_lines[PHY] > 0 ) { /* If SLOC > 0 */ ftemp = 100.0 * ((float)(comment_lines + e_comm_lines)); ftemp = ftemp / ((float)(SLOC_lines[PHY])); if (ftemp < UD_Min_Percent) exceed_UD_Min_Percent++; } /* If SLOC > 0 */ if ((lines - blank_lines - comment_lines) != SLOC_lines[PHY]) { error_cond = PHY_COUNT; error_handler(&error_cond, filename, c_outfile); } } /* If physical SLOC */ else { /* Else logical SLOC */ if (exec_lines[LOG] > UD_Exec_Lines) exceed_UD_Exec_Lines++; if (data_lines[LOG] > UD_Data_Lines) exceed_UD_Data_Lines++; if (SLOC_lines[LOG] > 0 ) { /* If SLOC > 0 */ ftemp = 100.0 * ((float)(comment_lines + e_comm_lines)); ftemp = ftemp / ((float)(SLOC_lines[LOG])); if (ftemp < UD_Min_Percent) exceed_UD_Min_Percent++; } /* If SLOC > 0 */ } /* Else logical SLOC */ } /* If source flag */ /*****************************************************************************/ /* Close infile & */ /* Print info on infile, */ /* utilize 132 columns */ fclose(infile); fprintf(c_outfile," %5ld", lines); fprintf(c_outfile," %5ld", blank_lines); fprintf(c_outfile," |"); fprintf(c_outfile," %5ld", comment_lines); fprintf(c_outfile," %5ld", e_comm_lines); fprintf(c_outfile," |"); if (UD_SLOC_Def == 'P') { /* Output physical SLOC info.*/ fprintf(c_outfile," %5ld", directive_lines[PHY]); fprintf(c_outfile," %5ld", data_lines[PHY]); fprintf(c_outfile," %5ld", exec_lines[PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %5ld", SLOC_lines[PHY]); } else { /* Output logical SLOC info. */ fprintf(c_outfile," %5ld", directive_lines[LOG]); fprintf(c_outfile," %5ld", data_lines[LOG]); fprintf(c_outfile," %5ld", exec_lines[LOG]); fprintf(c_outfile," |"); fprintf(c_outfile," %5ld", SLOC_lines[LOG]); } fprintf(c_outfile," |"); fprintf(c_outfile," %4s", file_mode_names[file_mode]); fprintf(c_outfile," %s\n", filename); } /* If open_error = FALSE */ /*****************************************************************************/ /* Output progress message */ if (UD_Display_File == 1) printf("Completed File : %s\n", filename); files_processed++; /* Increment number of files */ ftemp = 100.0 * ((float)(files_processed)) / ((float)(num_list_files)); if ((next_percent <= ftemp) && (next_percent != 0.0 ) ) { /* If, output message */ printf("\n"); spaces = 17; /* Tab over 17 spaces. */ for (i = 0; i < spaces; i++) printf("%c",BLANK); printf("%3.1lf%% complete ", ftemp); printf("(%ld-of-%ld files processed)\n",files_processed,num_list_files); printf("\n"); temp = ((int)(ftemp/UD_Inc_Percent)) + 1; next_percent = ((float)(temp)) * UD_Inc_Percent; } /* If, output message */ /*****************************************************************************/ } /* While Not EOF(c_list) */ /*****************************************************************************/ /* Print outfile trailer */ fprintf(c_outfile,"\f\n"); fprintf(c_outfile,"%28c",BLANK); /* 28 = center in 100 columns*/ fprintf(c_outfile,"C/C++ SOURCE LINES OF CODE COUNTING PROGRAM\n"); fprintf(c_outfile,"%11c",BLANK); /* 11 = center in 100 columns*/ fprintf(c_outfile,"( c ) Copyright 1998 - 2006 "); fprintf(c_outfile,"University of Southern California, "); fprintf(c_outfile,"CodeCount (TM)\n"); fprintf(c_outfile,"\n"); fprintf(c_outfile," University of Southern California retains"); fprintf(c_outfile," ownership of this copy of software. It is"); fprintf(c_outfile," licensed to you.\n"); fprintf(c_outfile,"Use, duplication, or sale of this product,"); fprintf(c_outfile," except as described in the CodeCount License"); fprintf(c_outfile," Agreement, is\n"); fprintf(c_outfile,"strictly prohibited. This License and your"); fprintf(c_outfile," right to use the software automatically"); fprintf(c_outfile," terminate if\n"); fprintf(c_outfile,"you fail to comply with any provisions of"); fprintf(c_outfile," the License Agreement. Violators may be"); fprintf(c_outfile," prosecuted.\n"); fprintf(c_outfile,"This product is licensed to : %s\n", LICENTIATE); fprintf(c_outfile,"\n"); spaces = ((100 - MAX_PROJECT_NAME) / 2); /* 100 = 100 columns */ for (i = 0; i < spaces; i++) fprintf(c_outfile,"%c",BLANK); fprintf(c_outfile,"%s\n", UD_Project_Name); fprintf(c_outfile,"The Totals\n"); fprintf(c_outfile," Total Blank | Comments | Compiler "); fprintf(c_outfile,"Data Exec. | Number | File SLOC\n"); fprintf(c_outfile," Lines Lines | Whole Embedded | Direct. "); fprintf(c_outfile,"Decl. Instr. | of Files | SLOC Type "); fprintf(c_outfile," Definition\n"); spaces = MAX_HEADER_LENGTH + MAX_FILENAME_LENGTH; for (i = 0; i < spaces; i++) fprintf(c_outfile,"%c",BAR); fprintf(c_outfile,"\n"); /* Output physical SLOC info.*/ fprintf(c_outfile," %7ld", total_lines[CODE][PHY]); fprintf(c_outfile," %7ld", total_blank_lines[CODE][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_comment_lines[CODE][PHY]); fprintf(c_outfile," %7ld", total_e_comm_lines[CODE][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_directive_lines[CODE][PHY]); fprintf(c_outfile," %7ld", total_data_lines[CODE][PHY]); fprintf(c_outfile," %7ld", total_exec_lines[CODE][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %5ld", total_number_files[CODE][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_SLOC_lines[CODE][PHY]); fprintf(c_outfile," CODE Physical\n"); /* Output logical SLOC info. */ fprintf(c_outfile," %7ld", total_lines[CODE][LOG]); fprintf(c_outfile," %7ld", total_blank_lines[CODE][LOG]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_comment_lines[CODE][LOG]); fprintf(c_outfile," %7ld", total_e_comm_lines[CODE][LOG]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_directive_lines[CODE][LOG]); fprintf(c_outfile," %7ld", total_data_lines[CODE][LOG]); fprintf(c_outfile," %7ld", total_exec_lines[CODE][LOG]); fprintf(c_outfile," |"); fprintf(c_outfile," %5ld", total_number_files[CODE][LOG]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_SLOC_lines[CODE][LOG]); fprintf(c_outfile," CODE Logical\n"); /* Output Data file info. */ fprintf(c_outfile," %7ld", total_lines[DATA][PHY]); fprintf(c_outfile," %7ld", total_blank_lines[DATA][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_comment_lines[DATA][PHY]); fprintf(c_outfile," %7ld", total_e_comm_lines[DATA][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_directive_lines[DATA][PHY]); fprintf(c_outfile," %7ld", total_data_lines[DATA][PHY]); fprintf(c_outfile," %7ld", total_exec_lines[DATA][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %5ld", total_number_files[DATA][PHY]); fprintf(c_outfile," |"); fprintf(c_outfile," %7ld", total_SLOC_lines[DATA][PHY]); fprintf(c_outfile," DATA Physical\n"); if (UD_SLOC_Def == 'P') temp = total_number_files[CODE][PHY] + total_number_files[DATA][PHY]; else temp = total_number_files[CODE][LOG] + total_number_files[DATA][LOG]; fprintf(c_outfile,"\n"); fprintf(c_outfile,"Number of files successfully accessed.........."); fprintf(c_outfile,".............. %5ld out of", temp); fprintf(c_outfile," %ld\n\n", num_list_files); if (total_SLOC_lines[CODE][LOG] > 0) { ftemp = ((float)(total_SLOC_lines[CODE][PHY])); ftemp = ftemp / ((float)(total_SLOC_lines[CODE][LOG])); fprintf(c_outfile,"Ratio of Physical to Logical SLOC............"); fprintf(c_outfile,"................ %8.2lf\n", ftemp); } else if (total_number_files[CODE][LOG] > 0) { error_cond = MATH_ERROR; error_handler(&error_cond, filename, c_outfile); } fprintf(c_outfile,"\n"); fprintf(c_outfile,"Number of files with :\n"); fprintf(c_outfile," Executable Instructions > "); fprintf(c_outfile,"%7ld = ", UD_Exec_Lines); fprintf(c_outfile,"%7ld\n", exceed_UD_Exec_Lines); fprintf(c_outfile," Data Declarations > "); fprintf(c_outfile,"%7ld = ", UD_Data_Lines); fprintf(c_outfile,"%7ld\n", exceed_UD_Data_Lines); fprintf(c_outfile," Percentage of Comments to SLOC < "); fprintf(c_outfile," %7.1lf %% = ", UD_Min_Percent); fprintf(c_outfile,"%7ld", exceed_UD_Min_Percent); if (UD_SLOC_Def == 'P') { /* If, physical */ fprintf(c_outfile,"%6c", BLANK); if (total_SLOC_lines[CODE][PHY] > 0) { ftemp = ((float)(total_comment_lines[CODE][PHY] + total_e_comm_lines[CODE][PHY] )); ftemp = 100.0 * ftemp / ((float)(total_SLOC_lines[CODE][PHY])); fprintf(c_outfile,"Ave. Percentage of Comments to Physical SLOC = "); fprintf(c_outfile," %3.1lf\n", ftemp); } else { error_cond = MATH_ERROR; error_handler(&error_cond, NULL, c_outfile); } } /* If, physical */ else { /* Else, logical */ fprintf(c_outfile,"%6c", BLANK); if (total_SLOC_lines[CODE][LOG] > 0) { ftemp = ((float)(total_comment_lines[CODE][LOG] + total_e_comm_lines[CODE][LOG] )); ftemp = 100.0 * ftemp / ((float)(total_SLOC_lines[CODE][LOG])); fprintf(c_outfile,"Ave. Percentage of Comments to Logical SLOC = "); fprintf(c_outfile," %3.1lf\n", ftemp); } else { error_cond = MATH_ERROR; error_handler(&error_cond, NULL, c_outfile); } } /* Else, logical */ /*****************************************************************************/ if (UD_QA_Switch == 1) { /* If UD_QA_Switch */ fprintf(c_outfile,"\n"); fprintf(c_outfile, "Total occurrences of these C/C++ Keywords :\n"); fprintf(c_outfile,"%3cCompiler Directives", BLANK); fprintf(c_outfile,"%16cData Keywords", BLANK ); fprintf(c_outfile,"%22cExecutable Keywords\n", BLANK); lc1 = 0; lc2 = 0; lc3 = 0; lc_t = 0; lf_1 = True; while ((lc_t < MAX_TARGETS) && (lf_1 == True ) ) { /* While */ while ((lc1 < MAX_DIRR_TARGETS ) && /* Output Directive keywords */ (dirr_tags[lc1] == False) ) lc1++; if (lc1 < MAX_DIRR_TARGETS) { /* If */ write_dots(dirr_names[lc1], c_outfile); fprintf(c_outfile,"%7ld%8c", dirr_tally[lc1], BLANK); lc1++; } /* If */ else for (i = 0; i < (MAX_TARGET_LENGTH + 7 + 8); i++) fprintf(c_outfile, "%c", BLANK); while ((lc2 < MAX_DATA_TARGETS ) && /* Output Data keywords */ (data_tags[lc2] == False) ) lc2++; if (lc2 < MAX_DATA_TARGETS) { /* If */ write_dots(data_names[lc2], c_outfile); fprintf(c_outfile,"%7ld%8c", data_tally[lc2], BLANK); lc2++; } /* If */ else for (i = 0; i < (MAX_TARGET_LENGTH + 7 + 8); i++) fprintf(c_outfile, "%c", BLANK); while ((lc3 < MAX_EXEC_TARGETS ) && /* Output Exec. keywords. */ (exec_tags[lc3] == False) ) lc3++; if (lc3 < MAX_EXEC_TARGETS) { /* If */ write_dots(exec_names[lc3], c_outfile); fprintf(c_outfile,"%7ld", exec_tally[lc3]); lc3++; } /* If */ fprintf(c_outfile,"\n"); if ((lc1 < MAX_DIRR_TARGETS) || /* Are there still keywords */ (lc2 < MAX_DATA_TARGETS) || /* to print out? */ (lc3 < MAX_EXEC_TARGETS) ) lf_1 = True ; else lf_1 = False; lc_t++; /* Increment row count */ } /* While */ } /* If UD_QA_Switch */ today = time(&today) ; current_time = localtime(&today); fprintf(c_outfile,"\n"); fprintf(c_outfile,"REVISION "); fprintf(c_outfile,"%c",USER_REVISION ); fprintf(c_outfile,"%c",TARGET_REVISION ); fprintf(c_outfile,"%s",DEVELOPER_REVISION); fprintf(c_outfile," SOURCE PROGRAM -> C_LINES"); fprintf(c_outfile,"%10c", BLANK); fprintf(c_outfile,"This output produced on %s", asctime(current_time)); fclose(c_outfile); return EXIT_SUCCESS; /*****************************************************************************/ } /* C_LINES */