递归统计项目中的非空白代码行数

      在准备阅读一个开源项目的代码前,可以大约看看整个项目共有多少代码,估计项目的规模。我就写了一个简单的程序来达到此目的,其中的一些代码参考了apue中的代码。

      代码如下:

View Code
复制代码
  1 //程序功能:统计一个文件夹(一个项目)中所有文件的有效代码行数(除去空白行)。
  2 
  3 #include <apue.h>
  4 #include <dirent.h>
  5 #include <limits.h>
  6 #include <string.h>
  7 #include <fcntl.h>
  8 #include <unistd.h>
  9 #define MAXBUF 5000
 10 
 11 typedef int Myfunc(const char *,const struct stat *,int);
 12 
 13 static Myfunc myfunc;
 14 static int    myftw(char *,Myfunc *);
 15 static int    dopath(Myfunc *);
 16 static int    sum_lines=0;//the sum of no empty lines
 17 
 18 static long    nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
 19 
 20 
 21 int
 22 main(int argc, char *argv[])
 23 {
 24     int        ret;
 25 
 26     if (argc != 2)
 27         err_quit("usage:  ftw  <starting-pathname>");
 28 
 29     ret = myftw(argv[1], myfunc);        /* does it all */
 30 
 31     printf("\n\nSum lines: %d lines\n\n\n",sum_lines);
 32     exit(ret);
 33 }
 34 
 35 /*
 36  * Descend through the hierarchy, starting at "pathname".
 37  * The caller's func() is called for every file.
 38  */
 39 #define    FTW_F    1        /* file other than directory */
 40 #define    FTW_D    2        /* directory */
 41 #define    FTW_DNR    3        /* directory that can't be read */
 42 #define    FTW_NS    4        /* file that we can't stat */
 43 
 44 static char    *fullpath;        /* contains full pathname for every file */
 45 
 46 static int                    /* we return whatever func() returns */
 47 myftw(char *pathname, Myfunc *func)
 48 {
 49     int len;
 50     fullpath = path_alloc(&len);    /* malloc's for PATH_MAX+1 bytes */
 51     /* ({Prog pathalloc}) */
 52     strncpy(fullpath, pathname, len);    /* protect against */
 53     fullpath[len-1] = 0;                /* buffer overrun */
 54 
 55     return(dopath(func));
 56 }
 57 
 58 static int dopath(Myfunc * func)
 59 {
 60     struct stat    statbuf;
 61     struct dirent  *dirp;
 62     DIR            *dp;
 63     int            ret;
 64     char           *ptr;
 65 
 66     if(lstat(fullpath,&statbuf)<0)
 67         return (func(fullpath,&statbuf,FTW_NS));
 68     if(S_ISDIR(statbuf.st_mode)==0)
 69         return (func(fullpath,&statbuf,FTW_F));
 70 
 71     if( (ret=func(fullpath,&statbuf,FTW_D))!=0 )
 72         return ret;
 73 
 74     ptr=fullpath+strlen(fullpath);
 75     *ptr++='/';
 76     *ptr=0;
 77 
 78     if((dp=opendir(fullpath))==NULL)
 79         return (func(fullpath,&statbuf,FTW_DNR));
 80     while((dirp=readdir(dp))!=NULL)
 81     {
 82         if(strcmp(dirp->d_name,".")==0 || strcmp(dirp->d_name,"..")==0) 
 83             continue;
 84         strcpy(ptr,dirp->d_name);
 85         if(ret=dopath(func)!=0)
 86             return ret;
 87     }
 88     ptr[-1]=0;
 89     if(closedir(dp)<0)
 90         err_ret("can't close directory %s",fullpath);
 91     return ret;
 92 }
 93 
 94 
 95 static int
 96 myfunc(const char *pathname, const struct stat *statptr, int type)
 97 {
 98     switch (type) {
 99     case FTW_F:
100         {
101             int fd=0;
102             int num=0;
103             char buf[MAXBUF];
104             int file_lines=0;//current file lines
105             if((fd=open(pathname,O_RDONLY))<0)        
106                 err_sys("error open for %s\n",pathname);
107             while((num=read(fd,buf,4096))!=0)
108             {
109                 int index; 
110                 char previous_c=buf[0];
111                 char current_c;
112                 for(index=1;index<num;index++)
113                 {
114                     current_c=buf[index];
115                     if(previous_c!='\n' && current_c=='\n')      
116                         sum_lines++,file_lines++;
117                     previous_c=current_c;
118                 }
119             }
120             if(close(fd)==-1)
121                 err_sys("error close for %s",pathname);
122             printf("%s:%d lines\n",pathname,file_lines);
123         }
124         break;
125 
126     case FTW_D:
127         ndir++;
128         break;
129 
130     case FTW_DNR:
131         err_ret("can't read directory %s", pathname);
132         break;
133 
134     case FTW_NS:
135         err_ret("stat error for %s", pathname);
136         break;
137 
138     default:
139         err_dump("unknown type %d for pathname %s", type, pathname);
140     }
141 
142     return(0);
143 }
复制代码

      编译方法:

gcc -g -o count_line count_line.c fig2_15.c error.c

      其中fig2_15.c和error.c来自apue,分别定义了一些简单的函数和错误处理函数。

      输入样例:在redis这个开源项目的文件夹之下,输入:

./count_line src

      输出:

复制代码
1 src/rio.h:85 lines
2 src/crc16.c:85 lines
3 src/zipmap.h:46 lines
4 src/intset.h:46 lines
5 src/crc64.c:186 lines
6 src/adlist.h:82 lines
7 .....省略
8 
9 Sum lines: 36108 lines
复制代码

      参考资料:apue

展开阅读全文

没有更多推荐了,返回首页