zoukankan      html  css  js  c++  java
  • code_analyzer(代码分析助手)

    软件名: code_analyzer

    使用c语言 pcre正则库分析源码文件,包括文件中的头文件、宏定义、函数。

    用途:

    无聊时,可以用来打发下时间。

    演示:

    对于本源程序的分析结果如下:

    ##########################头文件########################
    
    1.头文件:              stdio.h
    2.头文件:             stdlib.h
    3.头文件:             string.h
    4.头文件:               pcre.h
    
    ##########################宏##########################
    
    1.宏原型: #define OVECCOUNT 30
    宏名:            OVECCOUNT
    值:                   30
    2.宏原型: #define EBUFLEN 128
    宏名:              EBUFLEN
    值:                  128
    3.宏原型: #define BUFLEN 10024
    宏名:               BUFLEN
    值:                10024
    
    ########################函数#########################
    
    1.函数原型: int main(int argc, char *argv[])
    函数返回值:       int 
    函数名:            main
    参数: int argc, char *argv[]
    
    2.函数原型: void read_file(char *filename, char *buf)
    函数返回值:      void 
    函数名:       read_file
    参数: char *filename, char *buf
    
    3.函数原型: int regex_f(char *src, char *pattern, regex_buf *re_buf, regex_flag flag)
    函数返回值:       int 
    函数名:         regex_f
    参数: char *src, char *pattern, regex_buf *re_buf, regex_flag flag
    

    使用方法:

    命令行使用方法是:

    参数1:源程序文件, 参数2:输出文件名(可选项,默认out.txt)

    源码:

    //********************************************************************************
    //            Author:             tanhehe
    //            DateTime:           Mon Aug 26 19:34:47 2013
    //            SearchMe:           http://www.cnblogs.com/tanhehe
    //            email:              443016215@qq.com
    //            程序名:              CodeAnalyzer
    //            Description:        代码分析助手
    //
    //********************************************************************************
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pcre.h>
    
    #define OVECCOUNT 30
    #define EBUFLEN 128
    #define BUFLEN 10024
    
    typedef enum regex_flag {REG_FUNCTION, REG_MACRO, REG_HEADERS, REG_VARIABLES}regex_flag;
    
    union regex_content {
        char func[100][5][100];    /* 存储函数信息 */
        char macr[100][3][30];    /* 存储宏信息 */
        char head[100][2][30];    /* 存储头文件信息 */
    };
    
    typedef struct regex_buf {
        int cn;
        regex_flag flag;
        union regex_content buf;
    }regex_buf;
    
    void read_file(char *filename, char *buf);
    int regex_f(char *src, char *pattern, regex_buf *re_buf, regex_flag flag);
    
    char buf[BUFLEN];
    
    int main(int argc, char *argv[]) {
        char    *ifilename        = "main.c";
        char    *ofilename        = "out.txt";
        char    *pattern_function    = "((\w+\s+\*?)(?#返回值)\s*+(\w+)(?#函数名)\s*\(((.(?!["=><])(?#参数内不能包含引号))*)(?#参数)\))\s*{";
        char    *pattern_macro        = "#\s?define\s+(\w+)\s+(.+)";
        //char    *pattern_variables    = "(\w+)\s+(\w+);";
        char    *pattern_headers    = "#\s*include\s*<(.+)>";
    
        FILE    *fp;
        regex_buf    re_buf;
        int        i;
    
        if(argc < 2) {
            fprintf(stderr, "缺少源文件
    ");
            return 1;
        }
        if(argc >= 2) {
            ifilename = argv[1];
        }
        if(argc >= 3) {
            ofilename = argv[2];
        }
    
        if((fp = fopen(ofilename, "w")) == NULL) {
            fprintf(stderr, "open file error!
    ");
        }
    
        read_file(ifilename, buf);
        printf("成功读取%s......
    ", ifilename);
    
        fprintf(fp, "
    ##########################头文件########################
    
    ");
        if(regex_f(buf, pattern_headers, &re_buf, REG_HEADERS) == 0) {
            for(i=0; i<re_buf.cn; i++) {
                fprintf(fp, "%d.头文件: %20s
    ", i+1, re_buf.buf.head[i][1]);
            }
        }
        printf("已分析完毕头文件......
    ");
    
        fprintf(fp, "
    ##########################宏##########################
    
    ");
        if(regex_f(buf, pattern_macro, &re_buf, REG_MACRO) == 0) {
            for(i=0; i<re_buf.cn; i++) {
                fprintf(fp, "%d.宏原型: %s
    ", i+1, re_buf.buf.macr[i][0]);
                fprintf(fp, "宏名: %20s
    值: %20s
    ", re_buf.buf.macr[i][1], re_buf.buf.macr[i][2]);
            }
        }
        printf("已分析完毕宏定义......
    ");
    
        fprintf(fp, "
    ########################函数#########################
    
    ");
    
        if(regex_f(buf, pattern_function, &re_buf, REG_FUNCTION) == 0) {
            for(i=0; i<re_buf.cn; i++) {
                fprintf(fp, "%d.函数原型: %s
    ", i+1, re_buf.buf.func[i][1]);
                fprintf(fp, "函数返回值: %10s
    函数名: %15s
    参数: %20s
    
    ", re_buf.buf.func[i][2], re_buf.buf.func[i][3], re_buf.buf.func[i][4]);
            }
        }
    
        printf("已分析完毕函数......
    ");
    
        fclose(fp);
        printf("已成功写入%s......
    ", ofilename);
        return 0;
    }
    
    void read_file(char *filename, char *buf) {
        FILE            *fp;
        char        temp[1000];
    
        if((fp = fopen(filename, "r")) == NULL) {
            fprintf(stderr, "readerr!
    ");
            exit(1);
        }
    
        buf[0] = '';
    
        while(fgets(temp, sizeof(temp)-1, fp)) {
            strcat(buf, temp);
        }
    }
    
    
    int regex_f(char *src, char *pattern, regex_buf *re_buf, regex_flag flag) {
        pcre        *re;
        const char        *error;
        int            erroffset;
        int            ovector[OVECCOUNT];
        int            rc, i;
        int            cn = 0;
    
        re_buf->flag = flag; re_buf->cn = 0;
    
        re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
        if(re == NULL) {
            printf("PCRE compilation failed at offset %d: %s
    ", erroffset, error);
            return 1;
        }
    
        rc = pcre_exec(re, NULL, src, strlen(src), 0, 0, ovector, OVECCOUNT);
        if(rc < 0) {
            if(rc == PCRE_ERROR_NOMATCH) printf("Sorry, no match ...
    ");
            else printf("Matching error %d
    ", rc);
            free(re);
            return -1;
        }
    
        for(i=0; i<rc; i++) {
            char *substring_start = src + ovector[2*i];
            int substring_length = ovector[2*i+1]-ovector[2*i];
    
            //printf("%2d: %.*s
    ", i, substring_length, substring_start);
            switch(flag) {
            case REG_MACRO:
                sprintf(re_buf->buf.macr[cn][i], "%.*s", substring_length, substring_start);
                break;
            case REG_FUNCTION:
                sprintf(re_buf->buf.func[cn][i], "%.*s", substring_length, substring_start);
                break;
            case REG_HEADERS:
                sprintf(re_buf->buf.head[cn][i], "%.*s", substring_length, substring_start);
                break;
                //  扩展
            }
        }
        cn++;
    
        for(;;) {
            int start_offset = ovector[1];
            rc = pcre_exec(re,  NULL, src, strlen(src), start_offset, 0, ovector, OVECCOUNT);
    
            if(rc == PCRE_ERROR_NOMATCH) { /* 匹配完毕 */
                break;
            }
            else if(rc < 0) {    /* 匹配错误 */
                //printf("Matching error %d
    ", rc);
                pcre_free(re);
                return 1;
            }
            else if(rc == 0) {            /* 匹配, 但空间不足 */
                rc = OVECCOUNT/3;
                printf("ovector only has room for %d captured substring
    ", rc-1);
                return 1;
            }
    
            for(i=0; i<rc; i++) {
                char *substring_start = src + ovector[2*i];
                int substring_length = ovector[2*i+1] - ovector[2*i];
        //        printf("%2d: %.*s
    ", i, substring_length, substring_start);
                switch(flag) {
                case REG_MACRO:
                    sprintf(re_buf->buf.macr[cn][i], "%.*s", substring_length, substring_start);
                    break;
                case REG_FUNCTION:
                    sprintf(re_buf->buf.func[cn][i], "%.*s", substring_length, substring_start);
                    break;
                case REG_HEADERS:
                    sprintf(re_buf->buf.head[cn][i], "%.*s", substring_length, substring_start);
                    break;
                // 扩展
                }
            }
            cn++;
        }
    
        pcre_free(re);
    
        re_buf->cn = cn;
        return 0;
    }

    说明 :

    因为在windows下,配置pcre库未成功,所以不打算弄个windows版本了。只有linux版本.
    其实呢, 这个软件上一个 是我目标软件中的两个功能。现在把他们单独实现。随着以后的学习,有能力时,会继续完成其他功能,然后整合在一起。

    源程序http://tanhe123.ys168.com/

    源代码https://github.com/tanhe123/code_analyzer

     

  • 相关阅读:
    centOS7 安装docker
    go中json的tag使用
    secureCRT操作redis-cli时, 不断追加ip:port
    golang gorm框架的默认时区问题
    java Date 转mysql timestamp 秒数不一致
    golang sqlx查询时, struct字段冲突
    golang入门time与string转换, time加减时间, 两个时间差
    idea设置每次打开手动选择工作空间
    panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
    Render函数(4):开发可进行排序的表格组件
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3284531.html
Copyright © 2011-2022 走看看