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

📄 ctrl.c

📁 一个去掉程序中#ifdef #if 等预处理条件为假的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ctrl - interpretation of preprocessor control lines (e.g. #define...) *  for the selective C preprocessor, scpp. * * Copyright (c) 1985 by * Tektronix, Incorporated Beaverton, Oregon 97077 * All rights reserved. * * Permission is hereby granted for personal, non-commercial * reproduction and use of this program, provided that this * notice and all copyright notices are included in any copy. */# include <stdio.h># include "scpp.h"# include "y.tab.h"/* * valbuf[] the buffer in which to build the value of a macro which has *  parameters. */# define VALLEN 1000		/* max # of chars in a macro value string  */char valbuf[VALLEN];char *valend;			/*				 * always points to the null-terminator				 * of the value while the value is being built				 *//* * form[] the array of formal parameters for a macro. *  Each formal argument of a macro acts as a "local variable" during the *  scan for the value of the macro.  The form[] array contains *  pointers to each argument's slot in the symbol table (used to recognize *  the formal argument in the value) and the previous value of that slot *  (so that the symbol table can be restored to normal after the value *  of the macro has been scanned. */struct aformal {	struct amacro *fm_sym;	/* symbol table slot for this formal	*/	struct amacro  fm_copy;	/* copy of the old contents of that slot */};# define FORMSIZ 40	/* max number of parameters to a macro	*/struct aformal form[FORMSIZ];struct aformal *formtop; /* points to the next empty slot in form[]	*//* * do_xxx() - functions for processing preprocessor control lines. */int do_line();int do_include();int do_define();int do_undef();int do_ifdef();int do_ifndef();int do_if();int do_elif();int do_else();int do_endif();/* * key - the array of preprocessor keywords. */struct akeyword key[] = {	{"line", do_line, 0},	{"include", do_include, 0},	{"define", do_define, 0},	{"undef", do_undef, 0},	{"ifdef", do_ifdef, 0},	{"ifndef", do_ifndef, 0},	{"if", do_if, 0},        {"elif", do_elif, 0},	{"else", do_else, 0},	{"endif", do_endif, 0},	{0,0,0}			/* a zero ak_name marks the end of the list */};/* * ikeywords() - initialize the preprocessor keywords. *  For each keyword, set its ak_sym field and act as if it has been -M'ed. */ikeywords(){	struct akeyword *kp;	for (kp = &key[0]; kp->ak_name; ++kp) {		kp->ak_sym = findmac(kp->ak_name,		    kp->ak_name + strlen(kp->ak_name));		if (kp->ak_sym->am_name) {			bomb("INTERNAL: identical keywords in key[]");		}		kp->ak_sym->am_name = kp->ak_name;		kp->ak_sym->am_npar = -1;		/* leave am_val as 0 */	}}/* * findkey() - find the keyword corresponding to the given symbol table entry, *  returning a pointer to that keyword in key[], *  or zero if no match. */struct akeyword *findkey(mac)struct amacro *mac;{	struct akeyword *kp;	for (kp = &key[0]; kp->ak_name && kp->ak_sym != mac; ++kp)		;	if (!kp->ak_name) {		return((struct akeyword *) 0);	}	return(kp);}/* * doctrl() - process a control line (a line beginning with '#'). */int		/* returned token (NL or 0)	*/doctrl(f)		/* process control lines */char *f;		/* first char of this line (the '#' token) in pend[] */{	int tok;		/* the current token	*/	struct amacro *cmd;	/* the preprocessor command (symbol table)  */	struct akeyword *kp;	/* the preprocessor command (keyword table) */	/*	 * skip initial whitespace and comments (if any);	 * ignore empty command lines;	 * print warnings for garbled command lines;	 * switch on the command name.	 */	if ((tok = nonwhite(gintok)) == 0 || tok == NL) {		return(tok);	}	if (tok != IDENT) {		warnf("undefined control");		tok = endline();		return(tok);	}	cmd = findmac(curtext, nxtout);	if (!cmd->am_name || !(kp = findkey(cmd))) {		/* name is not a preprocessor command */		warnf("undefined control");		tok = endline();		return(tok);	}	/*	 * invoke the appropriate handler	 */	tok = (*kp->ak_proc)(f);	return(tok);}/* * do_line - parse a #line command. *   #line syntax: * 	#[<whitespace>]line[<whitespace>][<int>[<whitespace>]<string> *     where: <int> is the new integer line number for this line, *	      <string> is the new double-quote enclosed filename. */intdo_line(f)char *f;{	int tok;	char *name;		/* the new filename		*/	char *src;	char *dst;	if ((tok = nonwhite(gintok)) == 0 || tok == NL) {		return(tok);	}	if (tok == INT) {		if (curfile >= &filestk[0]) {			curfile->af_line = inttok(curtext, nxtout);		}		if ((tok = nonwhite(gintok)) == 0 || tok == NL) {			return(tok);		}	}	if (tok != STRING) {		tok = endline();		return(tok);	}	name = savtok(curtext, nxtout);	for (dst = name, src = name + 1; (*dst = *src) != '\0';	  ++dst, ++src)		;	if (--dst <= name || *dst != '"') {		free(name);		tok = endline();		return(tok);	}	*dst = '\0';	if (curfile >= &filestk[0]) {		free(curfile->af_name);		curfile->af_name = name;	}	tok = endline();	return(tok);}intdo_include(f)char *f;	/* (unused because #include lines are never deleted)	*/{	char *ifile;		/* the (dynamically alloc'ed) filename	*/	int looktype;		/* type of directory search to perform	*/	int tok;		/* the current token's type		*/	char *src, *dst;        char **ip;	/*	 * pickup the filename, scan the rest of the command line,	 * then include the file.	 */	ifile = (char *) 0;	if ((tok = nonwhite(gintok)) == 0) {		goto badinc;	}	if (tok == STRING) {		/*		 * the filename is enclosed in double-quotes.		 * Set the search type to include the current file's directory;		 * Save the filename, then remove the string delimiters from it.		 */		looktype = PF_DOT;		ifile = savtok(curtext, nxtout);		for (dst = ifile, src = ifile + 1; (*dst = *src) != '\0';		    ++dst, ++src)			;		if (--dst <= ifile || *dst != '"') {			goto badinc;		}		*dst = '\0';	} else if (tok == LT) {		/*		 * The filename is enclosed in angle-brackets.		 * Set the directory search to exclude the current file's		 *  directory; collect and save the filename.		 */		looktype = PF_NODOT;		src = nxtout;		while ((tok = gtok()) != GT && tok != NL && tok != 0)			;		if (tok != GT) {			goto badinc;		}		ifile = savtok(src, curtext);	} else {badinc:		bombf("bad include syntax");		if (ifile) {			free(ifile);		}		tok = endline();		return(tok);	}	tok = endline();	for (ip = &ilist[0]; *ip; ip++) {	    if (!strcmp(ifile, *ip)) {		pushfile(ifile, looktype, !PF_HIDE);                dispose(f);		free(ifile);		return(tok);		}	    }	pushfile(ifile, looktype, PF_HIDE);	free(ifile);	return(tok);}intdo_define(f)char *f;{	int tok;	struct amacro *mac;	/* the macro being defined		*/	struct amacro *arg;	/*				 * points to the slot for the current argument				 * from the definition of a macro with				 * parameters.				 */	struct amacro maccopy;	/*				 * a copy of some of the info from the slot				 *  for the macro being defined.  Copying the				 *  slot allows perverse macro definitions				 *  such as:				 *    # define boo(boo)  boo()				 */	struct aformal *formp;	/* a temp pointer			*/	int defok = TRUE;	/*				 * 'ok to define the macro.' Used to prevent				 * definition of a macro with parameters if				 * there was a syntax error in the definition.				 */	/*	 * scan for the macro name with identifier expansion turned off.	 * Find the slot corresponding to the macro name.	 */	if ((tok = nonwhite(gtok)) == 0) {		return(0);	}	if (tok != IDENT) {		warnf("illegal macro name");		tok = endline();		return(tok);	}	mac = findmac(curtext, nxtout);	if ((tok = gtok()) != LP) {		/*		 * a simple macro.  If it hasn't been -M'ed, ignore it.		 * Otherwise, save the replacement text (disposing of		 *  any quoted newlines, comments, and appropriate		 *  whitespace), define the macro, and dispose of this line.		 */		char *valstrt;	/* points to the macro value within pend[] */		char *valstr;	/* the dynamically alloc'ed value string */		if (!mac->am_name) {			tok = endline();			return(tok);		}		valstrt = curtext;		/*		 * if the delimiter is whitespace, skip the first character		 * of the whitespace (and any preceeding ATTN bytes).		 */		if (tok == WHITE) {			while (valstrt < nxtout && *valstrt == ATTN) {				valstrt += 2;			}			if (valstrt < nxtout) {				valstrt++;			}		}		while (tok != NL && tok != 0) {			if (tok == QNL || (!savcom && tok == COMMENT)) {				(void) dispose(curtext);			}			tok = gtok();		}		if (tok == 0) {			warnf("unterminated preprocessor command");		} else {			valstr = savtok(valstrt, curtext);			if (!savcom) {				stripwhite(valstr);			}			defmac(mac->am_name,			  mac->am_name + strlen(mac->am_name),			  -1 /* npar */, valstr);			free(valstr);		}		(void) dispose(f);		return(tok);	}	/* a macro with parameters.  Copy relevant parts of it. */	maccopy.am_name = mac->am_name;	/*	 * Collect the comma-separated formals of the macro.	 * Temporarily define each formal of the macro, saving the old	 * contents of that formal's slot in the symbol table,	 * marking that symbol as -M'ed, but undefined (so that	 * scanning an uninterpreted macro definition works in the	 * following case:	 *	scpp -MMOO	 *		#define MOO lose	 *		#define goo(MOO) is a MOO.	 *	should generate	 *		#define goo(MOO) is a MOO.	 *	rather than	 *		#define goo(MOO) is a lose.	 */	formtop = &form[0];	while (formtop < &form[FORMSIZ]) {		if ((tok = nonwhite(gtok)) != IDENT) {			break;		}		/* process the formal argument */		formtop->fm_sym = findmac(curtext, nxtout);		for (formp = &form[0]; formp < formtop &&		  formp->fm_sym != formtop->fm_sym; ++formp)			;		if (formp < formtop) {			warnf("duplicate formal names in macro definition");		}		formtop->fm_copy.am_name = formtop->fm_sym->am_name;		formtop->fm_copy.am_npar = formtop->fm_sym->am_npar;		formtop->fm_copy.am_val = formtop->fm_sym->am_val;		formtop->fm_sym->am_name = savtok(curtext, nxtout);		formtop->fm_sym->am_npar = -1;		formtop->fm_sym->am_val = (char *) 0;		++formtop;		if ((tok = nonwhite(gtok)) != CM) {			break;		}	}	if (tok != RP) {		if (formtop >= &form[FORMSIZ]) {			warnf("too many formal arguments");		} else {			warnf("syntax error in formal arguments");		}		tok = endline();		defok = FALSE;		goto rollback;	}	if (!maccopy.am_name) {		/*		 * This macro is not -M'ed, so don't interpret this #define.		 * scan to the end of the line.		 */		tok = endline();		defok = FALSE;	} else {		/*		 * This macro is -M'ed.  Record the number of parameters,		 * then save the value of this macro,		 * marking occurrences of the formal arguments.		 */		maccopy.am_npar = formtop - &form[0];		valend = &valbuf[0];		*valend = '\0';

⌨️ 快捷键说明

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