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

2019年(31)

2016年(1)

2014年(16)

2011年(8)

2010年(25)

2009年(115)

分类: 嵌入式

2009-03-22 11:37:37

程序流程图



代码解释

static char *pp_getline(void)
{
    char *line;
    Token *tline;

    while (1) {
        /*
         * Fetch a tokenised line, either from the macro-expansion
         * buffer or from the input file.
         */

        tline = NULL;
        while (istk->expansion && istk->expansion->finishes) {
            Line *l = istk->expansion;
            if (!l->finishes->name && l->finishes->in_progress > 1) {
                Line *ll;

                /*
                 * This is a macro-end marker for a macro with no
                 * name, which means it's not really a macro at all
                 * but a %rep block, and the `in_progress' field is
                 * more than 1, meaning that we still need to
                 * repeat. (1 means the natural last repetition; 0
                 * means termination by %exitrep.) We have
                 * therefore expanded up to the %endrep, and must
                 * push the whole block on to the expansion buffer
                 * again. We don't bother to remove the macro-end
                 * marker: we'd only have to generate another one
                 * if we did.
                 */

                /* 复制 istk->finishes */
                l->finishes->in_progress--;
                for (l = l->finishes->expansion; l; l = l->next) {
                    Token *t, *tt, **tail;

                    ll = nasm_malloc(sizeof(Line));
                    ll->next = istk->expansion;
                    ll->finishes = NULL;
                    ll->first = NULL;
                    tail = &ll->first;

                    for (t = l->first; t; t = t->next) {
                        if (t->text || t->type == TOK_WHITESPACE) {
                            tt = *tail = new_Token(NULL, t->type, t->text, 0);
                            tail = &tt->next;
                        }
                    }

                    istk->expansion = ll;
                }
            } else {
                /*
                 * Check whether a `%rep' was started and not ended
                 * within this macro expansion. This can happen and
                 * should be detected. It's a fatal error because
                 * I'm too confused to work out how to recover
                 * sensibly from it.
                 */

                if (defining) {
                    if (defining->name)
                        error(ERR_PANIC, "defining with name in expansion");
                    else if (istk->mstk->name)
                        error(ERR_FATAL, "`%%rep' without `%%endrep' within expansion of macro `%s'", istk->mstk->name);
                }

                /*
                 * FIXME: investigate the relationship at this point between
                 * istk->mstk and l->finishes
                 */

                {
                    MMacro *m = istk->mstk;
                    istk->mstk = m->next_active;
                    if (m->name) {
                        /*
                         * This was a real macro call, not a %rep, and
                         * therefore the parameter information needs to
                         * be freed.
                         */

                        nasm_free(m->params);
                        free_tlist(m->iline);
                        nasm_free(m->paramlen);
                        l->finishes->in_progress = FALSE;
                    } else
                        free_mmacro(m);
                }
                istk->expansion = l->next;
                nasm_free(l);
                list->downlevel(LIST_MACRO);
            }
        }
        while (1) { /* until we get a line we can use */
            if (istk->expansion) { /* from a macro expansion */
                char *p;
                Line *l = istk->expansion;
                if (istk->mstk)
                    istk->mstk->lineno++;
                tline = l->first;
                istk->expansion = l->next;
                nasm_free(l);
                p = detoken(tline, FALSE);
                list->line(LIST_MACRO, p);
                nasm_free(p);
                break;
            }
            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) {
            /*
             * We're defining a multi-line macro. We emit nothing
             * at all, and just
             * shove the tokenised line on to the macro definition.
             */

            Line *l = nasm_malloc(sizeof(Line));
            l->next = defining->expansion;
            l->first = tline;
            l->finishes = FALSE;
            defining->expansion = l;
            continue;
        } else if (istk->conds && !emitting(istk->conds->state)) {
            /*
             * We're in a non-emitting branch of a condition block.
             * Emit nothing at all, not even a blank line: when we
             * emerge from the condition we'll give a line-number
             * directive so we keep our place correctly.
             */

            free_tlist(tline);
            continue;
        } else if (istk->mstk && !istk->mstk->in_progress) {
            /*
             * We're in a %rep block which has been terminated, so
             * we're walking through to the %endrep without
             * emitting anything. Emit nothing at all, not even a
             * blank line: when we emerge from the %rep block we'll
             * give a line-number directive so we keep our place
             * correctly.
             */

            free_tlist(tline);
            continue;
        } else {
            tline = expand_smacro(tline);
            if (!expand_mmacro(tline)) {
                /*
                 * De-tokenise the line again, and emit it.
                 */

                line = detoken(tline, TRUE);
                free_tlist(tline);
                break;
            } else {
                continue; /* expand_mmacro calls free_tlist */
            }
        }
    }

    return line;
}

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