All pastes #408458 Raw Edit

c_lines.c

public text v1 · immutable
#408458 ·published 2007-03-24 21:11 UTC
rendered paste body
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <time.h> 
/*---------------------------------------------------------------------------*/ 
/*                                                                           */ 
/*                        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 -> <filename>"                              */ 
/*   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 -> <filename>"                                         */ 
/*   1. The input file contains only an EOF marker.                          */ 
/*                                                                           */ 
/* "ERROR, truncated a line of <filename>" OR                                */ 
/* "ERROR, truncated a line of file -> <filename>"                           */ 
/*   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" <file_name                                         */ 
/*                                                                           */ 
/* "ERROR, EOLN not detected in <filename>" OR                               */ 
/* "ERROR, EOLN not detected in file -> <filename>"                          */ 
/*   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" <file_name                                         */ 
/*                                                                           */ 
/* "ERROR, Word Wrap processing error in <filename>" OR                      */ 
/* "ERROR, Word Wrap processing error in file -> <filename>"                 */ 
/*   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 <filename> 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 <filename>" 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 <filename>" 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 */