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 */ }
|