/* * 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; }