软件名: 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[][][]; /* 存储函数信息 */
char macr[][][]; /* 存储宏信息 */
char head[][][]; /* 存储头文件信息 */
}; 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 < ) {
fprintf(stderr, "缺少源文件\n");
return ;
}
if(argc >= ) {
ifilename = argv[];
}
if(argc >= ) {
ofilename = argv[];
} if((fp = fopen(ofilename, "w")) == NULL) {
fprintf(stderr, "open file error!\n");
} read_file(ifilename, buf);
printf("成功读取%s......\n", ifilename); fprintf(fp, "\n##########################头文件########################\n\n");
if(regex_f(buf, pattern_headers, &re_buf, REG_HEADERS) == ) {
for(i=; i<re_buf.cn; i++) {
fprintf(fp, "%d.头文件: %20s\n", i+, re_buf.buf.head[i][]);
}
}
printf("已分析完毕头文件......\n"); fprintf(fp, "\n##########################宏##########################\n\n");
if(regex_f(buf, pattern_macro, &re_buf, REG_MACRO) == ) {
for(i=; i<re_buf.cn; i++) {
fprintf(fp, "%d.宏原型: %s\n", i+, re_buf.buf.macr[i][]);
fprintf(fp, "宏名: %20s\n值: %20s\n", re_buf.buf.macr[i][], re_buf.buf.macr[i][]);
}
}
printf("已分析完毕宏定义......\n"); fprintf(fp, "\n########################函数#########################\n\n"); if(regex_f(buf, pattern_function, &re_buf, REG_FUNCTION) == ) {
for(i=; i<re_buf.cn; i++) {
fprintf(fp, "%d.函数原型: %s\n", i+, re_buf.buf.func[i][]);
fprintf(fp, "函数返回值: %10s\n函数名: %15s\n参数: %20s\n\n", re_buf.buf.func[i][], re_buf.buf.func[i][], re_buf.buf.func[i][]);
}
} printf("已分析完毕函数......\n"); fclose(fp);
printf("已成功写入%s......\n", ofilename);
return ;
} void read_file(char *filename, char *buf) {
FILE *fp;
char temp[]; if((fp = fopen(filename, "r")) == NULL) {
fprintf(stderr, "readerr!\n");
exit();
} buf[] = '\0'; while(fgets(temp, sizeof(temp)-, 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 = ; re_buf->flag = flag; re_buf->cn = ; re = pcre_compile(pattern, , &error, &erroffset, NULL);
if(re == NULL) {
printf("PCRE compilation failed at offset %d: %s\n", erroffset, error);
return ;
} rc = pcre_exec(re, NULL, src, strlen(src), , , ovector, OVECCOUNT);
if(rc < ) {
if(rc == PCRE_ERROR_NOMATCH) printf("Sorry, no match ...\n");
else printf("Matching error %d\n", rc);
free(re);
return -;
} for(i=; i<rc; i++) {
char *substring_start = src + ovector[*i];
int substring_length = ovector[*i+]-ovector[*i]; //printf("%2d: %.*s\n", 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[];
rc = pcre_exec(re, NULL, src, strlen(src), start_offset, , ovector, OVECCOUNT); if(rc == PCRE_ERROR_NOMATCH) { /* 匹配完毕 */
break;
}
else if(rc < ) { /* 匹配错误 */
//printf("Matching error %d\n", rc);
pcre_free(re);
return ;
}
else if(rc == ) { /* 匹配, 但空间不足 */
rc = OVECCOUNT/;
printf("ovector only has room for %d captured substring\n", rc-);
return ;
} for(i=; i<rc; i++) {
char *substring_start = src + ovector[*i];
int substring_length = ovector[*i+] - ovector[*i];
// printf("%2d: %.*s\n", 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 ;
}

说明 :

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

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

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

code_analyzer(代码分析助手)的更多相关文章

  1. Android代码分析工具lint学习

    1 lint简介 1.1 概述 lint是随Android SDK自带的一个静态代码分析工具.它用来对Android工程的源文件进行检查,找出在正确性.安全.性能.可使用性.可访问性及国际化等方面可能 ...

  2. pmd静态代码分析

    在正式进入测试之前,进行一定的静态代码分析及code review对代码质量及系统提高是有帮助的,以上为数据证明 Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可 ...

  3. [Asp.net 5] DependencyInjection项目代码分析-目录

    微软DI文章系列如下所示: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [ ...

  4. [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable<>补充)

    Asp.net 5的依赖注入注入系列可以参考链接: [Asp.net 5] DependencyInjection项目代码分析-目录 我们在之前讲微软的实现时,对于OpenIEnumerableSer ...

  5. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)

    构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...

  6. STM32启动代码分析 IAR 比较好

    stm32启动代码分析 (2012-06-12 09:43:31) 转载▼     最近开始使用ST的stm32w108芯片(也是一款zigbee芯片).开始看他的启动代码看的晕晕呼呼呼的. 还好在c ...

  7. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  8. SonarQube-5.6.3 代码分析平台搭建使用

    python代码分析 官网主页: http://docs.sonarqube.org/display/PLUG/Python+Plugin Windows下安装使用: 快速使用: 1.下载jdk ht ...

  9. angular代码分析之异常日志设计

    angular代码分析之异常日志设计 错误异常是面向对象开发中的记录提示程序执行问题的一种重要机制,在程序执行发生问题的条件下,异常会在中断程序执行,同时会沿着代码的执行路径一步一步的向上抛出异常,最 ...

随机推荐

  1. 为什么你需要使用instancetype而不是id

    四年前Clang添加了关键字instancetype,目的在于取代-alloc和-init等方法的返回类型id,那么使用instancetype到底比id好在哪里? instancetype宣言 不管 ...

  2. Java使用poi对Execl简单_读和写_操作

    1 /** 一.简单读取Execl的步骤: * 1.通过流来读取Execl并存放到内存中: * 2.通过WorkbookFactory工作簿工厂来读取内存中存放的execl文档流并创建出一个工作簿 * ...

  3. 2016年11月1日——jQuery源码学习笔记

    1.instanceof运算符希望左操作数是一个对象,右操作数标识对象的类.如果左侧的对象是右侧类的实例,则表达式返回true,否则返回false 2.RegExp.exec() 如果 exec() ...

  4. Android 控件 之 Menu 菜单

    http://www.cnblogs.com/Mrs-cc/archive/2012/07/21/2603042.html 1.OptionsMenu (选项菜单)用法总结   使用方法: 方法一:添 ...

  5. SQL替换空格,制表符,换行符,回车符.

    首先是空格的替换,很重要的有点是,要确保字段的类型,不是char或nchar等固定的类型,否则无法去掉空格. 去掉空格很简单,如下为SQL实例: --去掉 T_StuffBasic 表中FBranch ...

  6. Gprinter Android SDK V1.0 使用说明

    佳博打印机代理商淘宝店https://shop107172033.taobao.com/index.htm?spm=2013.1.w5002-9520741823.2.Sqz8Pf 在此店购买的打印机 ...

  7. Lua-C交互函数

    lua_gettable(lua_State * , tableIndex) //获取表的在key位置的值 过程:tableIndex为表在栈的位置,例:-2为第二个位置 , 此时会弹(出)栈作为参数 ...

  8. 【BZOJ3211】【并查集+树状数组】花神游历各国

    Description   Input   Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 4 1 100 5 5 5 1 1 2 2 1 2 1 1 2 2 ...

  9. Win异常: 除了chrome浏览器外,所有安装的软件都连不上网

    经查找资料,是LSP被篡改,恢复后使用正常. 百度百科  LSP: Layered Service Provider, 即分层服务提程序,Winsock 作为应用程序的 Windows 的网络套接字工 ...

  10. centos7上安装与配置Tomcat7(整理篇)

    1.检查tomcat7是否已经安装 rpm -qa | grep tomcat ps -ef | grep tomcat 第一条命令查看是用rpm安装过tomcat,由于我们倾向于安装解压版的tomc ...