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

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

      如果你觉得我的文章对你有帮助,请推荐一下,非常感谢!

 

你可能感兴趣的:(递归)