现在的位置: 首页 > 综合 > 正文

使用flex编程解析内存依赖的.o.cmd文件

2013年11月08日 ⁄ 综合 ⁄ 共 2135字 ⁄ 字号 评论关闭

编译内核之后相应的文件会产生一个 .*.o.cmd的依赖文件, 根据此文件可以看出被编译的.o文件依赖哪些头文件,以及被编译的参数.

.o.cmd文件的格式为:

cmd_dir/output.o := commands

dep_dir/output.o := depended_files

     总的来说由两部份组成, 一个是编译命令, 另一个是依赖文件. 所以此法分析分成两结: CMD_SECTION(命令) 和 DEP_SETION(依赖), 进入的条件分别是 cmd_... 和 dep_...

我们要提取出依赖的头文件, 所以CMD_SETION不做任何处理.

DEP_SETION 中分别由 $(wildcard include-file),   include-file两部分组成, 而且都有续行符号"\".

这里遇到 include-file 后判断是否是.h文件以及不带解决路径的头文件, 如果是的话打印文件名到标准输出即可. (带绝对路径的是标准库头文件, 这里不需要).

编译命令:   flex scan.l; gcc lex.yy.c

============================scan.l==============================================

%{

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int linenum = 1;
char file[2048];
%}
NAME    ([[:alpha:]_][[:alnum:]_\-]*)

FILE_NAME   [[:alnum:]_\-./]+
DEP_NAME    (deps_{NAME}\/{NAME}\.o)
CMD_NAME    (cmd_{NAME}\/{NAME}\.o)
NL          \r?\n
WS          [[:blank:]]+
OPTWS       [[:blank:]]*

%x CMD_SECTION DEP_SETION
%%
    int line_continue = 0;

<INITIAL>{
    ^{CMD_NAME}     BEGIN(CMD_SECTION);
    ^{DEP_NAME}     BEGIN(DEP_SETION);
    {NL}            linenum++;
    .       /* ignore spurious characters */
}

<CMD_SECTION>{
    {NL}            BEGIN(INITIAL); linenum++;
    {OPTWS}":="           
    .
}

<DEP_SETION>{
    {NL}  {
        if (!line_continue) {
            // fprintf(stderr, "goto initial now at line %d\n", linenum);
            BEGIN(INITIAL);
        }
        line_continue = 0;       
        linenum++;
    }
    \\$             line_continue = 1;//fprintf(stderr, "get continue line\n");
    {OPTWS}":="     // fprintf(stderr, "get ==\n");
    "$(wildcard "   // fprintf(stderr, "get wildcard\n");
    ")"             // fprintf(stderr, "get )\n");
    {FILE_NAME} {
        // fprintf(stderr, "get file %s\n", yytext);
        strncpy(file, yytext, sizeof(file));
        file[sizeof(file)-1] = '\0';
        filter_inc_files(file);
    }
    .               // fprintf(stderr, "text : '%s'\n", yytext);

}

%%
int filter_inc_files(const char *file)
{
    int len;

    if (file[0] == '/')
        return 0;

    len = strlen(file);

    if (len < 3) return -1;

    if (file[len-1]!='h' || file[len-2] != '.')
        return -1;

/*
    if (access(file, 0)) {
        fprintf(stderr, "include file '%s' no exist\n", file);
        return -1;
    }
*/
    printf("%s\n", file);

    return 0;
}

int yywrap(void)
{
    return 1;
}

int main(int argc, char **argv)
{
    yylex();
    return 0;
}

抱歉!评论已关闭.