This is count.c in view mode; [Download] [Up]
/* counts number of statements, lines of code, comments, comment lines
* and blank lines
***************************************************************************/
/***************************************************************************
* kdsi has been modified to include headers (titles) above statistics *
* scott maretick *
***************************************************************************/
/***************************************************************************
* kdsi has been modified to also count '//' lines as comments for C++ or *
* Objective-C *
* scott maretick *
***************************************************************************/
#include <stdio.h>
typedef int Token;
#define STOP_INPUT 0
#define NEWLINE 1
#define START_COMMENT 2
#define END_COMMENT 3
#define MISC_CHARACTER 4
#define WHITE_SPACE 5
typedef char Bool;
#define True 1
#define False 0
typedef int State;
#define Code 0
#define Comment 1
#define Quiescent 2
#define FNULL ( (FILE *) 0)
#define CNULL ( (char *) 0)
Bool only_stdin = False; /* true if reading from stdin */
char objc_comm = 'N';
main(argc, argv)
int argc;
char *argv[];
{
Token GetChar();
FILE *nextfp();
register Token input;
register State statevar = Quiescent, laststate = Quiescent;
FILE *fp;
char *filename;
int filecount = 0;
long cod_linect, com_linect, blnk_linect;
long tot_cdline, tot_cmline, tot_bkline;
long grand_tot_cdline, grand_tot_cmline, grand_tot_bkline;
Bool following_com = False;
tot_cdline = tot_cmline = tot_bkline = 0;
grand_tot_cdline = grand_tot_cmline = grand_tot_bkline = 0;
while ( (fp = nextfp(argc, argv, &filename)) != FNULL )
{
cod_linect = com_linect = blnk_linect = 0;
filecount++;
while ( (input = GetChar(fp)) != STOP_INPUT )
{
switch ( input )
{
case NEWLINE:
if ( statevar == Code && objc_comm == 'N')
cod_linect++;
else if ( statevar == Comment || objc_comm == 'Y')
{com_linect++;
objc_comm = 'N';}
/* state is quiescent */
else if ( laststate == Comment )
{
/* if is supposed to catch cases where a comment
* follows a line of code
*/
if ( following_com )
cod_linect++;
else
com_linect++;
}
else
blnk_linect++;
if ( statevar != Comment )
{
laststate = Quiescent;
statevar = Quiescent;
}
following_com = False;
break;
case START_COMMENT:
laststate = statevar;
statevar = Comment;
break;
case END_COMMENT:
/* if true, is a comment on same line as code */
if ( laststate == Code )
following_com = True;
laststate = Comment;
statevar = Quiescent;
break;
case MISC_CHARACTER:
if ( statevar == Quiescent )
{
laststate = statevar;
statevar = Code;
}
break;
default:
fprintf(stderr, "kdsi: illegal token (%d) returned from GetChar\n", input);
exit(1);
break;
}
}
if ( !only_stdin ) {
printf(" LOC BLANKS COMM PGM\n");
printf("%8ld %8ld %6ld %s\n",
cod_linect, blnk_linect, com_linect,
filename); }
else {
printf(" LOC BLANKS COMM PGM\n");
printf("%8ld %8ld %6ld %s\n",
cod_linect, blnk_linect, com_linect); }
tot_cdline += cod_linect;
tot_cmline += com_linect;
tot_bkline += blnk_linect;
grand_tot_cdline += tot_cdline;
grand_tot_cmline += tot_cmline;
grand_tot_bkline += tot_bkline;
}
if ( !only_stdin && filecount > 1 ) {
printf(" TOT TOT TOT TOT \n");
printf(" LOC BLANKS COMM PGM\n");
printf("%8ld %8ld %6ld total\n",
tot_cdline, tot_bkline, tot_cmline); }
/* if (STOP_INPUT) {
printf(" GT_LOC GT_BLANKS GT_COMM PGM\n");
printf("%8ld %8ld %6ld total\n",
grand_tot_cdline, grand_tot_bkline, grand_tot_cmline); }*/
exit(0);
}
Token
GetChar( file )
FILE *file;
{
/* return token for char type, taking into account comment delims */
/* ignores spaces and tabs */
register int c;
register Token retval;
static int buf;
static Bool inbuf = False;
do
{
if ( inbuf )
{
c = buf;
inbuf = False;
}
else
c = getc(file);
switch ( c )
{
case EOF:
retval = STOP_INPUT;
break;
case '\n':
retval = NEWLINE;
break;
case '/':
buf = getc( file );
if ( buf == '*' )
retval = START_COMMENT;
else if (buf == '/' ) {
objc_comm = 'Y';
retval = END_COMMENT; }
else
{
inbuf = True;
retval = MISC_CHARACTER;
}
break;
case '*':
buf = getc( file );
if ( buf == '/' )
retval = END_COMMENT;
else
{
inbuf = True;
retval = MISC_CHARACTER;
}
break;
case ' ':
case '\t':
retval = WHITE_SPACE;
break;
default:
retval = MISC_CHARACTER;
}
}
while ( retval == WHITE_SPACE );
return (retval);
}
FILE *
nextfp( argc, argv, p_filename)
int argc;
char *argv[];
char **p_filename;
{
/* looks through parameters trying to return next FILE * to next
* specified file
* passes back a pointer to the filename as a side effect
*/
static Bool first = True;
static int index = 1;
static FILE *result = FNULL;
*p_filename = CNULL;
if ( result != FNULL )
{
fclose( result );
result = FNULL;
}
while ( index < argc && *argv[index] == '-' )
index++;
if ( index < argc )
{
if ( (result = fopen( argv[index], "r")) == NULL )
{
fprintf(stderr, "%s: unable to open %s for read\n",
argv[0], argv[index]);
exit(1);
}
else
*p_filename = argv[index];
index++;
}
if ( first )
{
/* if no files specified, read from stdin */
/* filename remains null */
if ( result == FNULL )
{
result = stdin;
only_stdin = True;
}
first = False;
}
return ( result );
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.