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

📄 main.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1984, 1986 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintchar copyright[] ="@(#) Copyright (c) 1984, 1986 The Regents of the University of California.\n\ All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)main.c	7.2 (Berkeley) 5/8/91";#endif /* not lint */#include <stdio.h>#include <ctype.h>#include "inline.h"/* * These are the pattern tables to be loaded */struct pats *vax_inittables[] = {	language_ptab,	libc_ptab,	vax_libc_ptab,	machine_ptab,	vax_ptab,	0};struct pats *vaxsubset_inittables[] = {	language_ptab,	libc_ptab,	vaxsubset_libc_ptab,	machine_ptab,	vaxsubset_ptab,	0};/* * Statistics collection */struct stats {	int	attempted;	/* number of expansion attempts */	int	finished;	/* expansions done before end of basic block */	int	lostmodified;	/* mergers inhibited by intervening mod */	int	savedpush;	/* successful push/pop merger */} stats;extern char *strcpy();char *whoami;int lineno = 0;int dflag;main(argc, argv)	int argc;	char *argv[];{	register char *cp, *lp;	register char *bufp;	register struct pats *pp, **php;	struct pats **tablep;	register struct inststoptbl *itp, **ithp;	int size;	extern char *index();	int subset = 0;	whoami = argv[0];	argc--;	argv++;	while (argc > 0 && argv[0][0] == '-') {		switch(argv[0][1]) {		case 's':			subset++;			break;		case 'd':			dflag++;			break;		default:			break;		}		argc--, argv++;	}	if (argc > 0)		freopen(argv[0], "r", stdin);	if (argc > 1)		freopen(argv[1], "w", stdout);	/*	 * Set up the hash table for the patterns.	 */	if (subset)		tablep = vaxsubset_inittables;	else		tablep = vax_inittables;	for ( ; *tablep; tablep++) {		for (pp = *tablep; pp->name[0] != '\0'; pp++) {			php = &patshdr[hash(pp->name, &size)];			pp->size = size;			pp->next = *php;			*php = pp;		}	}	/*	 * Set up the hash table for the instruction stop table.	 */	for (itp = inststoptable; itp->name[0] != '\0'; itp++) {		ithp = &inststoptblhdr[hash(itp->name, &size)];		itp->size = size;		itp->next = *ithp;		*ithp = itp;	}	/*	 * check each line and replace as appropriate	 */	buftail = bufhead = 0;	bufp = line[0];	while (fgets(bufp, MAXLINELEN, stdin)) {		lineno++;		lp = index(bufp, LABELCHAR);		if (lp != NULL) {			for (cp = bufp; cp < lp; cp++)				if (!isalnum(*cp))					break;			if (cp == lp) {				bufp = newline();				if (*++lp == '\n') {					emptyqueue();					continue;				}				(void) strcpy(bufp, lp);				*lp++ = '\n';				*lp = '\0';				emptyqueue();			}		}		for (cp = bufp; isspace(*cp); cp++)			/* void */;		if ((cp = doreplaceon(cp)) == 0) {			bufp = newline();			continue;		}		for (pp = patshdr[hash(cp, &size)]; pp; pp = pp->next) {			if (pp->size == size && bcmp(pp->name, cp, size) == 0) {				if (argcounterr(pp->args, countargs(bufp), pp->name)) {					pp = NULL;					break;				}				expand(pp->replace);				bufp = line[bufhead];				break;			}		}		if (!pp) {			emptyqueue();			fputs(bufp, stdout);		}	}	emptyqueue();	if (dflag)		fprintf(stderr, "%s: %s %d, %s %d, %s %d, %s %d\n",			whoami,			"attempts", stats.attempted,			"finished", stats.finished,			"inhibited", stats.lostmodified,			"merged", stats.savedpush);	exit(0);}/* * Integrate an expansion into the assembly stream */expand(replace)	char *replace;{	register int curptr;	char *nextreplace, *argv[MAXARGS];	int argc, argreg, foundarg, mod = 0, args = 0;	char parsebuf[BUFSIZ];	stats.attempted++;	for (curptr = bufhead; ; ) {		nextreplace = copyline(replace, line[bufhead]);		argc = parseline(line[bufhead], argv, parsebuf);		argreg = nextarg(argc, argv);		if (argreg == -1)			break;		args++;		for (foundarg = 0; curptr != buftail; ) {			curptr = PRED(curptr);			argc = parseline(line[curptr], argv, parsebuf);			if (isendofblock(argc, argv))				break;			if (foundarg = ispusharg(argc, argv))				break;			mod |= 1 << modifies(argc, argv);		}		if (!foundarg)			break;		replace = nextreplace;		if (mod & (1 << argreg)) {			stats.lostmodified++;			if (curptr == buftail) {				(void)newline();				break;			}			(void)newline();		} else {			stats.savedpush++;			rewrite(line[curptr], argc, argv, argreg);			mod |= 1 << argreg;		}	}	if (argreg == -1)		stats.finished++;	emptyqueue();	fputs(replace, stdout);	cleanup(args);}/* * Parse a line of assembly language into opcode and arguments. */parseline(linep, argv, linebuf)	char *linep;	char *argv[];	char *linebuf;{	register char *bufp = linebuf, *cp = linep;	register int argc = 0;	for (;;) {		/*		 * skip over white space		 */		while (isspace(*cp))			cp++;		if (*cp == '\0')			return (argc);		/*		 * copy argument		 */		if (argc == MAXARGS - 1) {			fprintf(stderr, "instruction too long->%s", linep);			return (argc);		}		argv[argc++] = bufp;		while (!isspace(*cp) && *cp != ARGSEPCHAR && *cp != COMMENTCHAR)			*bufp++ = *cp++;		*bufp++ = '\0';		if (*cp == COMMENTCHAR)			return (argc);		if (*cp == ARGSEPCHAR)			cp++;	}}/* * Check for instructions that end a basic block. */isendofblock(argc, argv)	int argc;	char *argv[];{	register struct inststoptbl *itp;	int size;	if (argc == 0)		return (0);	for (itp = inststoptblhdr[hash(argv[0], &size)]; itp; itp = itp->next)		if (itp->size == size && bcmp(argv[0], itp->name, size) == 0)			return (1);	return (0);}/* * Copy a newline terminated string. * Return pointer to character following last character copied. */char *copyline(from, to)	register char *from, *to;{	while (*from != '\n')		*to++ = *from++;	*to++ = *from++;	*to = '\0';	return (from);}/* * Check for a disparity between the number of arguments a function * is called with and the number which we expect to see. * If the error is unrecoverable, return 1, otherwise 0. */argcounterr(args, callargs, name)	int args, callargs;	char *name;{	register char *cp;	char namebuf[MAXLINELEN];	if (args == callargs)		return (0);	cp = strcpy(namebuf, name);	while (*cp != '\0' && *cp != '\n')		++cp;	if (*cp == '\n')		*cp = '\0';	if (callargs >= 0) {		fprintf(stderr,		"%s: error: arg count mismatch, %d != %d for '%s' at line %d\n",			whoami, callargs, args, namebuf, lineno);		return (1);	}	fprintf(stderr,		"%s: warning: can't verify arg count for '%s' at line %d\n",		whoami, namebuf, lineno);	return (0);}/* * open space for next line in the queue */char *newline(){	bufhead = SUCC(bufhead);	if (bufhead == buftail) {		fputs(line[buftail], stdout);		buftail = SUCC(buftail);	}	return (line[bufhead]);}/* * empty the queue by printing out all its lines. */emptyqueue(){	while (buftail != bufhead) {		fputs(line[buftail], stdout);		buftail = SUCC(buftail);	}}/* * Compute the hash of a string. * Return the hash and the size of the item hashed */hash(cp, size)	char *cp;	int *size;{	register char *cp1 = cp;	register int hash = 0;	while (*cp1 && *cp1 != '\n')		hash += (int)*cp1++;	*size = cp1 - cp + 1;	hash &= HSHSIZ - 1;	return (hash);}

⌨️ 快捷键说明

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