Count lines of source code

David E. Smyth david at jpl-devvax.JPL.NASA.GOV
Fri Feb 22 10:53:20 AEST 1991


snk at bae.bellcore.com (Samuel N Kamens) writes:
>
>Does anybody have or know of a routine that will count the 
>actual statements in a file of C source code?  I want to
>eliminate comments, and compress multi-line statements
>to register as a single statement.

Sure, here is one:

/*
**	real_lines - how many non-blank, non-comment lines ?
*/

#include	<stdio.h>


FILE *file = stdin;

int main(argc,argv)
    int    argc;
    char **argv;
{
    char  c;
    char* name         = *argv;
    long  lines        = 0;
    long  total        = 0;
    FILE* file         = stdin;
    char* filename     = NULL;
    int   exitval      = 0;
    int   more_to_read = (argc > 1 ? argc - 1 : 1);

    while ( more_to_read-- )
    {
	/* if there is no argument, we read from stdin.
	** if there is an argument, use it as a filename.
	*/
	if ( *++argv )
	{
	    if ( NULL == (file = fopen( *argv, "r" )) )
	    {
		fprintf( stderr, "%s: cannot open %s\n", name, argv);
		exitval++;
		continue;	/* next file, if there are more */
	    }
	    filename = *argv;
	}

	/* parse file - FSM */

#define GETC if ( EOF == ( c = fgetc( file )) ) goto end_of_file;

blank_line:
	GETC;
	if (c == '/') goto maybe_comment_in_blank_line;
	if (c == '?' || c == ':') goto blank_line;
	if (c == ';' || c == ',') goto blank_line;
	if (c == '(' || c == ')') goto blank_line;
	if (c == '{' || c == '}') goto blank_line;
	if (c <= ' ') goto blank_line;
	goto real_line;

maybe_comment_in_blank_line:
	GETC;
	if (c == '*') goto comment_in_blank_line;
	goto real_line;

comment_in_blank_line:
	GETC;
	if (c == '*') goto maybe_comment_end_in_blank_line;
	goto comment_in_blank_line;

maybe_comment_end_in_blank_line:
	GETC;
	if (c == '*') goto maybe_comment_end_in_blank_line;
	if (c == '/') goto blank_line;
	goto comment_in_blank_line;

real_line:
	GETC;
	if (c == '\n') { lines++ ; goto blank_line; }
	if (c == '/')  goto maybe_comment_in_real_line;
	goto real_line;

maybe_comment_in_real_line:
	GETC;
	if (c == '*') goto comment_in_real_line;
	if (c == '\n') { lines++ ; goto blank_line; }
	goto real_line;

comment_in_real_line:
	GETC;
	if (c == '*') goto maybe_comment_end_in_real_line;
	goto comment_in_real_line;

maybe_comment_end_in_real_line:
	GETC;
	if (c == '/') goto real_line;
	if (c == '*') goto maybe_comment_end_in_real_line;
	goto comment_in_real_line;

end_of_file:
	/* print file-by-file total if reading from files.
	** if reading stdin (no arg) then only print total.
	*/
	if (filename)
	    printf( "%8ld %s\n", lines, filename);
	total += lines;
	lines = 0;
	
next_file:
	;
    }

totals:
    /* Now print the totals */
    printf( "%8ld Total real lines\n", total );

    return exitval;
}



More information about the Comp.lang.c mailing list