⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 preproc.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 5 页
字号:
		      "`%s' expects a parameter count or nothing",		      directives[i]);	    }	    else	    {		searching.nparam_min = searching.nparam_max =			readnum(tline->text, &j);		if (j)		    error(ERR_NONFATAL,			  "unable to parse parameter count `%s'",			  tline->text);	    }	    if (tline && tok_is_(tline->next, "-"))	    {		tline = tline->next->next;		if (tok_is_(tline, "*"))		    searching.nparam_max = INT_MAX;		else if (!tok_type_(tline, TOK_NUMBER))		    error(ERR_NONFATAL,			  "`%s' expects a parameter count after `-'",			  directives[i]);		else		{		    searching.nparam_max = readnum(tline->text, &j);		    if (j)			error(ERR_NONFATAL,				"unable to parse parameter count `%s'",				tline->text);		    if (searching.nparam_min > searching.nparam_max)			error(ERR_NONFATAL,				"minimum parameter count exceeds maximum");		}	    }	    if (tline && tok_is_(tline->next, "+"))	    {		tline = tline->next;		searching.plus = TRUE;	    }	    mmac = mmacros[hash(searching.name)];	    while (mmac)	    {		if (!strcmp(mmac->name, searching.name) &&			(mmac->nparam_min <= searching.nparam_max				|| searching.plus)			&& (searching.nparam_min <= mmac->nparam_max				|| mmac->plus))		{		    found = TRUE;		    break;		}		mmac = mmac->next;	    }	    nasm_free(searching.name);	    free_tlist(origline);	    if (i == PP_IFNMACRO || i == PP_ELIFNMACRO)		found = !found;	    return found;	}	case PP_IFID:	case PP_ELIFID:	case PP_IFNID:	case PP_ELIFNID:	case PP_IFNUM:	case PP_ELIFNUM:	case PP_IFNNUM:	case PP_ELIFNNUM:	case PP_IFSTR:	case PP_ELIFSTR:	case PP_IFNSTR:	case PP_ELIFNSTR:	    tline = expand_smacro(tline);	    t = tline;	    while (tok_type_(t, TOK_WHITESPACE))		t = t->next;	    j = FALSE;		/* placate optimiser */	    if (t)		switch (i)		{		    case PP_IFID:		    case PP_ELIFID:		    case PP_IFNID:		    case PP_ELIFNID:			j = (t->type == TOK_ID);			break;		    case PP_IFNUM:		    case PP_ELIFNUM:		    case PP_IFNNUM:		    case PP_ELIFNNUM:			j = (t->type == TOK_NUMBER);			break;		    case PP_IFSTR:		    case PP_ELIFSTR:		    case PP_IFNSTR:		    case PP_ELIFNSTR:			j = (t->type == TOK_STRING);			break;		}	    if (i == PP_IFNID || i == PP_ELIFNID ||		    i == PP_IFNNUM || i == PP_ELIFNNUM ||		    i == PP_IFNSTR || i == PP_ELIFNSTR)		j = !j;	    free_tlist(tline);	    return j;	case PP_IF:	case PP_ELIF:	    t = tline = expand_smacro(tline);	    tptr = &t;	    tokval.t_type = TOKEN_INVALID;	    evalresult = evaluate(ppscan, tptr, &tokval,		    NULL, pass | CRITICAL, error, NULL);	    free_tlist(tline);	    if (!evalresult)		return -1;	    if (tokval.t_type)		error(ERR_WARNING,			"trailing garbage after expression ignored");	    if (!is_simple(evalresult))	    {		error(ERR_NONFATAL,			"non-constant value given to `%s'", directives[i]);		return -1;	    }	    return reloc_value(evalresult) != 0;	default:	    error(ERR_FATAL,		    "preprocessor directive `%s' not yet implemented",		    directives[i]);	    free_tlist(origline);	    return -1;		/* yeah, right */    }}/* * Expand macros in a string. Used in %error and %include directives. * First tokenise the string, apply "expand_smacro" and then de-tokenise back. * The returned variable should ALWAYS be freed after usage. */voidexpand_macros_in_string(char **p){    Token *line = tokenise(*p);    line = expand_smacro(line);    *p = detoken(line, FALSE);}/** * find and process preprocessor directive in passed line * Find out if a line contains a preprocessor directive, and deal * with it if so. *  * If a directive _is_ found, it is the responsibility of this routine * (and not the caller) to free_tlist() the line. * * @param tline a pointer to the current tokeninzed line linked list * @return DIRECTIVE_FOUND or NO_DIRECTIVE_FOUND *  */static intdo_directive(Token * tline){    int i, j, k, m, nparam, nolist;    int offset;    char *p, *mname;    Include *inc;    Context *ctx;    Cond *cond;    SMacro *smac, **smhead;    MMacro *mmac;    Token *t, *tt, *param_start, *macro_start, *last, **tptr, *origline;    Line *l;    struct tokenval tokval;    expr *evalresult;    MMacro *tmp_defining;	/* Used when manipulating rep_nest */    origline = tline;    skip_white_(tline);    if (!tok_type_(tline, TOK_PREPROC_ID) ||	    (tline->text[1] == '%' || tline->text[1] == '$'		    || tline->text[1] == '!'))	return NO_DIRECTIVE_FOUND;    i = -1;    j = elements(directives);    while (j - i > 1)    {	k = (j + i) / 2;	m = nasm_stricmp(tline->text, directives[k]);	if (m == 0) {		if (tasm_compatible_mode) {	    	i = k;	    	j = -2;		} else if (k != PP_ARG && k != PP_LOCAL && k != PP_STACKSIZE) {		    i = k;	    	j = -2;		}	    break;	}	else if (m < 0) {	    j = k;	}	else	    i = k;    }    /*     * If we're in a non-emitting branch of a condition construct,     * or walking to the end of an already terminated %rep block,     * we should ignore all directives except for condition     * directives.     */    if (((istk->conds && !emitting(istk->conds->state)) ||	 (istk->mstk && !istk->mstk->in_progress)) &&	!is_condition(i))    {	return NO_DIRECTIVE_FOUND;    }    /*     * If we're defining a macro or reading a %rep block, we should     * ignore all directives except for %macro/%imacro (which     * generate an error), %endm/%endmacro, and (only if we're in a     * %rep block) %endrep. If we're in a %rep block, another %rep     * causes an error, so should be let through.     */    if (defining && i != PP_MACRO && i != PP_IMACRO &&	    i != PP_ENDMACRO && i != PP_ENDM &&	    (defining->name || (i != PP_ENDREP && i != PP_REP)))    {	return NO_DIRECTIVE_FOUND;    }    if (j != -2)    {	error(ERR_NONFATAL, "unknown preprocessor directive `%s'",		tline->text);	return NO_DIRECTIVE_FOUND;		/* didn't get it */    }    switch (i)    {	case PP_STACKSIZE:	    /* Directive to tell NASM what the default stack size is. The	     * default is for a 16-bit stack, and this can be overriden with	     * %stacksize large.	     * the following form:	     *	     *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD	     */	    tline = tline->next;	    if (tline && tline->type == TOK_WHITESPACE)		tline = tline->next;	    if (!tline || tline->type != TOK_ID)	    {		error(ERR_NONFATAL, "`%%stacksize' missing size parameter");		free_tlist(origline);		return DIRECTIVE_FOUND;	    }	    if (nasm_stricmp(tline->text, "flat") == 0)	    {		/* All subsequent ARG directives are for a 32-bit stack */		StackSize = 4;		StackPointer = "ebp";		ArgOffset = 8;		LocalOffset = 4;	    }	    else if (nasm_stricmp(tline->text, "large") == 0)	    {		/* All subsequent ARG directives are for a 16-bit stack,		 * far function call.		 */		StackSize = 2;		StackPointer = "bp";		ArgOffset = 4;		LocalOffset = 2;	    }	    else if (nasm_stricmp(tline->text, "small") == 0)	    {		/* All subsequent ARG directives are for a 16-bit stack,		   * far function call. We don't support near functions.		 */		StackSize = 2;		StackPointer = "bp";		ArgOffset = 6;		LocalOffset = 2;	    }	    else	    {		error(ERR_NONFATAL, "`%%stacksize' invalid size type");		free_tlist(origline);		return DIRECTIVE_FOUND;	    }	    free_tlist(origline);	    return DIRECTIVE_FOUND;	case PP_ARG:	    /* TASM like ARG directive to define arguments to functions, in	     * the following form:	     *	     *      ARG arg1:WORD, arg2:DWORD, arg4:QWORD	     */	    offset = ArgOffset;	    do	    {		char *arg, directive[256];		int size = StackSize;		/* Find the argument name */		tline = tline->next;		if (tline && tline->type == TOK_WHITESPACE)		    tline = tline->next;		if (!tline || tline->type != TOK_ID)		{		    error(ERR_NONFATAL, "`%%arg' missing argument parameter");		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		arg = tline->text;		/* Find the argument size type */		tline = tline->next;		if (!tline || tline->type != TOK_OTHER			|| tline->text[0] != ':')		{		    error(ERR_NONFATAL,			    "Syntax error processing `%%arg' directive");		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		tline = tline->next;		if (!tline || tline->type != TOK_ID)		{		    error(ERR_NONFATAL,			    "`%%arg' missing size type parameter");		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		/* Allow macro expansion of type parameter */		tt = tokenise(tline->text);		tt = expand_smacro(tt);		if (nasm_stricmp(tt->text, "byte") == 0)		{		    size = MAX(StackSize, 1);		}		else if (nasm_stricmp(tt->text, "word") == 0)		{		    size = MAX(StackSize, 2);		}		else if (nasm_stricmp(tt->text, "dword") == 0)		{		    size = MAX(StackSize, 4);		}		else if (nasm_stricmp(tt->text, "qword") == 0)		{		    size = MAX(StackSize, 8);		}		else if (nasm_stricmp(tt->text, "tword") == 0)		{		    size = MAX(StackSize, 10);		}		else		{		    error(ERR_NONFATAL,			    "Invalid size type for `%%arg' missing directive");		    free_tlist(tt);		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		free_tlist(tt);		/* Now define the macro for the argument */		sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer,			offset);		do_directive(tokenise(directive));		offset += size;		/* Move to the next argument in the list */		tline = tline->next;		if (tline && tline->type == TOK_WHITESPACE)		    tline = tline->next;	    }	    while (tline && tline->type == TOK_OTHER		    && tline->text[0] == ',');	    free_tlist(origline);	    return DIRECTIVE_FOUND;	case PP_LOCAL:	    /* TASM like LOCAL directive to define local variables for a	     * function, in the following form:	     *	     *      LOCAL local1:WORD, local2:DWORD, local4:QWORD = LocalSize	     *	     * The '= LocalSize' at the end is ignored by NASM, but is	     * required by TASM to define the local parameter size (and used	     * by the TASM macro package).	     */	    offset = LocalOffset;	    do	    {		char *local, directive[256];		int size = StackSize;		/* Find the argument name */		tline = tline->next;		if (tline && tline->type == TOK_WHITESPACE)		    tline = tline->next;		if (!tline || tline->type != TOK_ID)		{		    error(ERR_NONFATAL,			    "`%%local' missing argument parameter");		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		local = tline->text;		/* Find the argument size type */		tline = tline->next;		if (!tline || tline->type != TOK_OTHER			|| tline->text[0] != ':')		{		    error(ERR_NONFATAL,			    "Syntax error processing `%%local' directive");		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		tline = tline->next;		if (!tline || tline->type != TOK_ID)		{		    error(ERR_NONFATAL,			    "`%%local' missing size type parameter");		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		/* Allow macro expansion of type parameter */		tt = tokenise(tline->text);		tt = expand_smacro(tt);		if (nasm_stricmp(tt->text, "byte") == 0)		{		    size = MAX(StackSize, 1);		}		else if (nasm_stricmp(tt->text, "word") == 0)		{		    size = MAX(StackSize, 2);		}		else if (nasm_stricmp(tt->text, "dword") == 0)		{		    size = MAX(StackSize, 4);		}		else if (nasm_stricmp(tt->text, "qword") == 0)		{		    size = MAX(StackSize, 8);		}		else if (nasm_stricmp(tt->text, "tword") == 0)		{		    size = MAX(StackSize, 10);		}		else		{		    error(ERR_NONFATAL,			    "Invalid size type for `%%local' missing directive");		    free_tlist(tt);		    free_tlist(origline);		    return DIRECTIVE_FOUND;		}		free_tlist(tt);		/* Now define the macro for the argument */		sprintf(directive, "%%define %s (%s-%d)", local, StackPointer,			offset);		do_directive(tokenise(directive));		offset += size;		/* Now define the assign to setup the enter_c macro correctly */		sprintf(directive, "%%assign %%$localsize %%$localsize+%d",			size);		do_directive(tokenise(directive));		/* Move to the next argument in the list */		tline = tline->next;		if (tline && tline->type == TOK_WHITESPACE)		    tline = tline->next;	    }	    while (tline && tline->type == TOK_OTHER		    && tline->text[0] == ',');	    free_tlist(origline);	    return DIRECTIVE_FOUND;	case PP_CLEAR:	    if (tline->next)		error(ERR_WARNING,			"trailing garbage after `%%clear' ignored");	    for (j = 0; j < NHASH; j++)	    {		while (mmacros[j])		{		    MMacro *m = mmacros[j];		    mmacros[j] = m->next;		    free_mmacro(m);		}		while (smacros[j])		{		    SMacro *s = smacros[j];		    smacros[j] = smacros[j]->next;		    nasm_free(s->name);		    free_tlist(s->expansion);		    nasm_free(s);		}	    }	    free_tlist(origline);	    return DIRECTIVE_FOUND;	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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -