/*
* This is a simple tool to count the lines of code in your MUD and break them
* down into actual code, comments, whitespace, and directives. It was inspired
* by the script-based one submitted to MudBytes by Darien after I realized it
* was somewhat innacurate and didn't pick up line comments at all.
*
* To compile:
* gcc lines.c -o lines
*
* To use it:
* ./lines ../src
* ./lines ./QuickMUD/src
*
* Hopefully someone else finds it useful.
*
* - Midboss, 8/30/2007
*/
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <ctype.h>
int main (int argc, char *argv[])
{
long lines = 0, comments = 0, directives = 0, whitespace = 0;
char line[256], tmpname[64];
int i = 0, in_comment = 0;
struct dirent * fname;
FILE * fp;
DIR * src;
/* Start by opening the directory. */
src = opendir (argv[1]);
if (src == NULL)
{
printf ("No such directory!\n");
exit (1);
}
/* Now run through the directory. */
while (fname = readdir (src))
{
/* Make sure this is part of the source code. */
/* Not 100% accurate, probably, but it works for me. */
if (( !strstr (fname->d_name, ".cpp")
&& !strstr (fname->d_name, ".c")
&& !strstr (fname->d_name, ".hpp")
&& !strstr (fname->d_name, ".h"))
|| strstr (fname->d_name, ".bak")
|| strstr (fname->d_name, "~"))
continue;
printf ("Counting: %s", fname->d_name);
/* Open up the file. */
/* Only continue if it fails, we want to attempt every file. */
sprintf (tmpname, "%s/%s", argv[1], fname->d_name);
if ((fp = fopen (tmpname, "r")) == NULL)
{
printf (" (could not open!)\n");
continue;
}
else
printf ("\n");
/* Now read it one line at a time. */
while (fgets (line, 256, fp) != NULL)
{
i = 0;
/* Already in a block comment? */
if (in_comment > 0)
{
while ( line[i] != '/'
&& line[i] != '\n'
&& line[i] != '\0')
++i;
/* If we're at the end, break out of the comment block. */
/* strlen() is always \0, strlen () - 1 is always \n */
if (line[i] == '/')
{
in_comment = -1;
comments++;
}
/* Otherwise just increment the comment line count. */
else
comments++;
}
/* Otherwise... */
else
{
/* Eat up all the leading whitespace. */
while (isspace (line[i]))
++i;
/* If we're at the end, this is a whitespace line. */
if (line[i] == '\0' || line[i] == '\n')
whitespace++;
/* Directive? */
else if (line[i] == '#')
directives++;
/* C++ style comment? */
else if (line[i] == '/' && line[i+1] == '/')
comments++;
/* Beginning of a block comment? */
else if (line[i] == '/' && line[i+1] == '*')
{
in_comment = 1;
comments++;
}
else
lines++;
}
}
/* If the file somehow ended in a comment, break out of it. */
/* Also adds the final 'empty' line as whitespace. */
in_comment = 0;
whitespace++;
fclose (fp);
}
closedir (src);
printf ("\n----------------------------------------\n"
"Total Lines: %ld\n"
"Actual Code: %ld\n"
"Directives: %ld\n"
"Whitespace: %ld\n"
"Comments: %ld\n\n",
lines + whitespace + comments + directives,
lines, directives, whitespace, comments);
return 0;
}