Line Counting
I really like wc; it's great tool to have handy. I also like to periodically count up the number of lines in projects or files I'm working on, largely out of idle curiosity about how much I've accomplished and how verbose I'm being1. The only trouble with using wc -l for this task is that it's very literal about counting lines, whereas what I'm interested in is lines of actual code that do stuff. Comments are good, but they aren't code2, and there are also blank lines which appear for various reasons. Since I felt today like taking a break from other stuff I was working on, I wrote my own little program, 'clines', to count the lines of C or C-like code in files:
/* clines by Niemand */
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string.h>
#include <cctype>
int scan(std::string& str, bool& inComment){
bool foundCode=false;
unsigned int len=str.length();
for(unsigned int i=0; i<len; i++){
if(i<len-1 && !inComment && str[i]=='/' && str[i+1]=='/')
break;
else if(i<len-1 && !inComment && str[i]=='/' && str[i+1]=='*'){
inComment=true;
i++;
}
else if(i<len-1 && inComment && str[i]=='*' && str[i+1]=='/'){
inComment=false;
i++;
}
else if(!inComment && !isspace(str[i]))
foundCode=true;
}
return(foundCode?1:0);
}
int main(int argc, char* argv[]){
unsigned long totalLines=0;
for(int i=1; i<argc; i++){
std::ifstream infile(argv[i]);
if(!infile.good()){
std::cerr << "Unable to open " << argv[i] << std::endl;
continue;
}
std::string str;
int res=0;
bool inComment=false;
unsigned long lines=0;
while(!infile.eof() && infile.good()){
getline(infile,str);
lines+=scan(str,inComment);
}
std::cout << std::setw(8) << std::right << lines
<< " " << std::left << argv[i] << std::endl;
totalLines+=lines;
}
if(argc>2)
std::cout << std::setw(8) << std::right << totalLines
<< " " << std::left << "total" << std::endl;
return(0);
}
It formats output about the same as wc and will report the total number of lines in all the files it read if it read more than one. One way I like to use it is:
find . -type f ( -name '*.h' -o -name '*.cpp' ) | xargs clines
This will count all of the lines in all files matching *.cpp or *.h in the current directory and all of its subdirectories.