Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1140338
  • 博文数量: 196
  • 博客积分: 4141
  • 博客等级: 中将
  • 技术积分: 2253
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-21 20:04
文章存档

2019年(31)

2016年(1)

2014年(16)

2011年(8)

2010年(25)

2009年(115)

分类:

2009-03-22 11:56:16

功能简介:

       给定一文件,输出该文件的依赖关系

算法简介:

       采用深度搜索


Nasm.c:

    case op_depend: /* 生成依赖关系(注意:在-a参数下,该功能无法正确实现) */
        {
            char *line;
            preproc->reset(inname, 0, report_error, evaluate, &nasmlist);
            if (outname[0] == '\0')
                ofmt->filename(inname, outname, report_error); /* .o 结尾的扩展名或者 nasm.out */
            ofile = NULL;
            fprintf(stdout, "%s: %s", outname, inname);
            while ((line = preproc->getline())) /* 实际处理 */
                nasm_free(line);
            preproc->cleanup(0);
            putc('\n', stdout);
        }

        break;

preproc.c:
/*
 *file : 输入文件名
 *apass : 预处理是pass 0
 *errfunc : 错误处理函数
 *eval : 在 eval.c 中
 *listgen : 在 listing.c 中实现
 */

static void
pp_reset(char *file, int apass, efunc errfunc, evalfunc eval, ListGen * listgen)
{
    int h;

    _error = errfunc;
    cstk = NULL;
    istk = nasm_malloc(sizeof(Include));
    istk->next = NULL;
    istk->conds = NULL;
    istk->expansion = NULL;
    istk->mstk = NULL;
    istk->fp = fopen(file, "r");
    istk->fname = NULL;
    src_set_fname(nasm_strdup(file)); /* 在 nasmlib.c */
    src_set_linnum(0); /* 在 nasmlib.c */
    istk->lineinc = 1;
    if (!istk->fp)
        error(ERR_FATAL | ERR_NOFILE, "unable to open input file `%s'", file);
    defining = NULL;
    for (h = 0; h < NHASH; h++) {
        mmacros[h] = NULL;
        smacros[h] = NULL;
    }

    unique = 0;

    if (tasm_compatible_mode) {
        stdmacpos = stdmac;
    } else {
        stdmacpos = &stdmac[TASM_MACRO_COUNT];
    }

    any_extrastdmac = (extrastdmac != NULL);
    list = listgen;
    evaluate = eval;
    pass = apass;
}

在preproc.c文件的 pp_getline 函数中:
…….
            line = read_line();
            if (line) { /* from the current input file */
                line = prepreproc(line);
                tline = tokenise(line);
                nasm_free(line);
                break;
            }

            /*
             * The current file has ended; work down the istk
             */

            {
                /* 删除一个 Include 节点 */
                Include *i = istk;

                fclose(i->fp);

                if (i->conds)
                    error(ERR_FATAL, "expected `%%endif' before end of file");


                /* only set line and file name if there's a next node */
                if (i->next) {
                    src_set_linnum(i->lineno);
                    nasm_free(src_set_fname(i->fname));
                }

                istk = i->next;
                list->downlevel(LIST_INCLUDE);
                nasm_free(i);

                if (!istk)
                    return NULL;
            }
        }

        /*
         * We must expand MMacro parameters and MMacro-local labels
         * _before_ we plunge into directive processing, to cope
         * with things like `%define something %1' such as STRUC
         * uses. Unless we're _defining_ a MMacro, in which case
         * those tokens should be left alone to go into the
         * definition; and unless we're in a non-emitting
         * condition, in which case we don't want to meddle with
         * anything.
         */

        if (!defining && !(istk->conds && !emitting(istk->conds->state))) /* #define emitting(x) ( (x) == COND_IF_TRUE || (x) == COND_ELSE_TRUE )
                                                                                     * (!istk->conds || COND_IF_TRUE || COND_ELSE_TRUE) && !defining                                                                                        */


            tline = expand_mmac_params(tline);
        /*
         * Check the line to see if it's a preprocessor directive.
         */

        if (do_directive(tline) == DIRECTIVE_FOUND) {
            continue;
        } else if (defining) {
……

在preproc.c 的do_directive 的函数中:
……
    case PP_INCLUDE:
        tline = tline->next;
        skip_white_(tline);

        if (!tline || (tline->type != TOK_STRING && tline->type != TOK_INTERNAL_STRING)) {
            error(ERR_NONFATAL, "`%%include' expects a file name");
            free_tlist(origline);
            return DIRECTIVE_FOUND; /* but we did _something_ */
        }

        if (tline->next)
            error(ERR_WARNING, "trailing garbage after `%%include' ignored");
        if (tline->type != TOK_INTERNAL_STRING) {
            p = tline->text + 1; /* point past the quote to the name */
            p[strlen(p) - 1] = '\0'; /* remove the trailing quote */
        } else
            p = tline->text; /* internal_string is easier */
        expand_macros_in_string(&p);

        /* 插入istk链表 */
        inc = nasm_malloc(sizeof(Include));
        inc->next = istk;
        inc->conds = NULL;
        inc->fp = inc_fopen(p);
        inc->fname = src_set_fname(p);
        inc->lineno = src_set_linnum(0);
        inc->lineinc = 1;
        inc->expansion = NULL;
        inc->mstk = NULL;
        istk = inc;

        list->uplevel(LIST_INCLUDE);
        free_tlist(origline);
        return DIRECTIVE_FOUND;

……

/*
 * Open an include file. This routine must always return a valid
 * file pointer if it returns - it's responsible for throwing an
 * ERR_FATAL and bombing out completely if not. It should also try
 * the include path one by one until it finds the file or reaches
 * the end of the path.
 */

static FILE *inc_fopen(char *file)
{
    FILE *fp;
    char *prefix = "", *combine;
    IncPath *ip = ipath;
    static int namelen = 0;
    int len = strlen(file);

    while (1) {
        combine = nasm_malloc(strlen(prefix) + len + 1);
        strcpy(combine, prefix);
        strcat(combine, file);
        fp = fopen(combine, "r");

        if (pass == 0 && fp) {
            namelen += strlen(combine) + 1;

            if (namelen > 62) {
                printf(" \\\n ");
                namelen = 2;
            }
            printf(" %s", combine);
        }

        nasm_free(combine);

        if (fp)
            return fp;
        if (!ip)
            break;

        prefix = ip->path;
        ip = ip->next;
    }

    error(ERR_FATAL, "unable to open include file `%s'", file);
    return NULL; /* never reached - placate compilers */
}

阅读(1565) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~