Пример #1
0
/*
 * build an input token..
 * consider only those starting with _ or A-Za-z. This is a
 * combo with lookup to speed things up.
 */
static ndptr
inspect(int c, char *tp)
{
	char *name = tp;
	char *etp = tp+MAXTOK;
	ndptr p;
	unsigned int h;

	h = *tp++ = c;

	while ((isalnum(c = gpbc()) || c == '_') && tp < etp)
		h = (h << 5) + h + (*tp++ = c);
	if (c != EOF)
		PUTBACK(c);
	*tp = EOS;
	/* token is too long, it won't match anything, but it can still
	 * be output. */
	if (tp == ep) {
		outputstr(name);
		while (isalnum(c = gpbc()) || c == '_') {
			if (sp < 0)
				putc(c, active);
			else
				CHRSAVE(c);
		}
		*name = EOS;
		return nil;
	}

	for (p = hashtab[h % HASHSIZE]; p != nil; p = p->nxtptr)
		if (h == p->hv && STREQ(name, p->name))
			break;
	return p;
}
Пример #2
0
/*
 * build an input token..
 * consider only those starting with _ or A-Za-z.
 */
static ndptr
inspect(int c, char *tp)
{
	char *name = tp;
	char *etp = tp+MAXTOK;
	ndptr p;

	*tp++ = c;

	while ((isalnum(c = gpbc()) || c == '_') && tp < etp)
		*tp++ = c;
	if (c != EOF)
		PUSHBACK(c);
	*tp = EOS;
	/* token is too long, it won't match anything, but it can still
	 * be output. */
	if (tp == ep) {
		outputstr(name);
		while (isalnum(c = gpbc()) || c == '_') {
			if (sp < 0)
				reallyputchar(c);
			else
				CHRSAVE(c);
		}
		*name = EOS;
		return NULL;
	}

	p = ohash_find(&macros, ohash_qlookupi(&macros, name, (const char **)&tp));
	if (p == NULL)
		return NULL;
	if (macro_getdef(p) == NULL)
		return NULL;
	return p;
}
Пример #3
0
/*
 * output string directly, without pushing it for reparses.
 */
void
outputstr(const char *s)
{
	if (sp < 0)
		reallyoutputstr(s);
	else
		while (*s)
			CHRSAVE(*s++);
}
Пример #4
0
/*
 * output string directly, without pushing it for reparses.
 */
void
outputstr(const char *s)
{
	if (sp < 0)
		while (*s)
			putc(*s++, active);
	else
		while (*s)
			CHRSAVE(*s++);
}
Пример #5
0
/*
 * macro - the work horse..
 */
static void
macro(void)
{
	char token[MAXTOK+1];
	int t, l;
	ndptr p;
	int  nlpar;

	cycle {
		t = gpbc();
		if (t == '_' || isalpha(t)) {
			p = inspect(t, token);
			if (p != nil)
				putback(l = gpbc());
			if (p == nil || (l != LPAREN &&
			    (p->type & NEEDARGS) != 0))
				outputstr(token);
			else {
		/*
		 * real thing.. First build a call frame:
		 */
				pushf(fp);	/* previous call frm */
				pushf(p->type); /* type of the call  */
				pushf(0);	/* parenthesis level */
				fp = sp;	/* new frame pointer */
		/*
		 * now push the string arguments:
		 */
				pushs1(p->defn);	/* defn string */
				pushs1(p->name);	/* macro name  */
				pushs(ep);	      	/* start next..*/

				if (l != LPAREN && PARLEV == 0)  {
				    /* no bracks  */
					chrsave(EOS);

					if ((uintptr_t)sp == STACKMAX)
						errx(1, "internal stack overflow");
					eval((const char **) mstack+fp+1, 2,
					    CALTYP);

					ep = PREVEP;	/* flush strspace */
					sp = PREVSP;	/* previous sp..  */
					fp = PREVFP;	/* rewind stack...*/
				}
			}
		} else if (t == EOF) {
			if (sp > -1) {
				warnx( "unexpected end of input, unclosed parenthesis:");
				dump_stack(paren, PARLEV);
				exit(1);
			}
			if (ilevel <= 0)
				break;			/* all done thanks.. */
			release_input(infile+ilevel--);
			free(inname[ilevel+1]);
			bufbase = bbase[ilevel];
			emitline();
			continue;
		}
	/*
	 * non-alpha token possibly seen..
	 * [the order of else if .. stmts is important.]
	 */
		else if (LOOK_AHEAD(t,lquote)) {	/* strip quotes */
			nlpar = 0;
			record(quotes, nlpar++);
			/*
			 * Opening quote: scan forward until matching
			 * closing quote has been found.
			 */
			do {

				l = gpbc();
				if (LOOK_AHEAD(l,rquote)) {
					if (--nlpar > 0)
						outputstr(rquote);
				} else if (LOOK_AHEAD(l,lquote)) {
					record(quotes, nlpar++);
					outputstr(lquote);
				} else if (l == EOF) {
					if (nlpar == 1)
						warnx("unclosed quote:");
					else
						warnx("%d unclosed quotes:", nlpar);
					dump_stack(quotes, nlpar);
					exit(1);
				} else {
					if (nlpar > 0) {
						if (sp < 0)
							putc(l, active);
						else
							CHRSAVE(l);
					}
				}
			}
			while (nlpar != 0);
		}

		else if (sp < 0 && LOOK_AHEAD(t, scommt)) {
			fputs(scommt, active);

			for(;;) {
				t = gpbc();
				if (LOOK_AHEAD(t, ecommt)) {
					fputs(ecommt, active);
					break;
				}
				if (t == EOF)
					break;
				putc(t, active);
			}
		}

		else if (sp < 0) {		/* not in a macro at all */
			putc(t, active);	/* output directly..	 */
		}

		else switch(t) {

		case LPAREN:
			if (PARLEV > 0)
				chrsave(t);
			while (isspace(l = gpbc()))
				;		/* skip blank, tab, nl.. */
			putback(l);
			record(paren, PARLEV++);
			break;

		case RPAREN:
			if (--PARLEV > 0)
				chrsave(t);
			else {			/* end of argument list */
				chrsave(EOS);

				if ((uintptr_t)sp == STACKMAX)
					errx(1, "internal stack overflow");

				eval((const char **) mstack+fp+1, sp-fp,
				    CALTYP);

				ep = PREVEP;	/* flush strspace */
				sp = PREVSP;	/* previous sp..  */
				fp = PREVFP;	/* rewind stack...*/
			}
			break;

		case COMMA:
			if (PARLEV == 1) {
				chrsave(EOS);		/* new argument   */
				while (isspace(l = gpbc()))
					;
				putback(l);
				pushs(ep);
			} else
				chrsave(t);
			break;

		default:
			if (LOOK_AHEAD(t, scommt)) {
				char *pc;
				for (pc = scommt; *pc; pc++)
					chrsave(*pc);
				for(;;) {
					t = gpbc();
					if (LOOK_AHEAD(t, ecommt)) {
						for (pc = ecommt; *pc; pc++)
							chrsave(*pc);
						break;
					}
					if (t == EOF)
					    break;
					CHRSAVE(t);
				}
			} else
				CHRSAVE(t);		/* stack the char */
			break;
		}
	}
}
Пример #6
0
/*
 * macro - the work horse..
 */
static void
macro(void)
{
	char token[MAXTOK+1];
	int t, l;
	ndptr p;
	int  nlpar;

	cycle {
		t = gpbc();

		if (LOOK_AHEAD(t,lquote)) {	/* strip quotes */
			nlpar = 0;
			record(quotes, nlpar++);
			/*
			 * Opening quote: scan forward until matching
			 * closing quote has been found.
			 */
			do {

				l = gpbc();
				if (LOOK_AHEAD(l,rquote)) {
					if (--nlpar > 0)
						outputstr(rquote);
				} else if (LOOK_AHEAD(l,lquote)) {
					record(quotes, nlpar++);
					outputstr(lquote);
				} else if (l == EOF) {
					if (nlpar == 1)
						warnx("unclosed quote:");
					else
						warnx("%d unclosed quotes:", nlpar);
					dump_stack(quotes, nlpar);
					exit(1);
				} else {
					if (nlpar > 0) {
						if (sp < 0)
							reallyputchar(l);
						else
							CHRSAVE(l);
					}
				}
			}
			while (nlpar != 0);
		} else if (sp < 0 && LOOK_AHEAD(t, scommt)) {
			reallyoutputstr(scommt);

			for(;;) {
				t = gpbc();
				if (LOOK_AHEAD(t, ecommt)) {
					reallyoutputstr(ecommt);
					break;
				}
				if (t == EOF)
					break;
				reallyputchar(t);
			}
		} else if (t == '_' || isalpha(t)) {
			p = inspect(t, token);
			if (p != NULL)
				pushback(l = gpbc());
			if (p == NULL || (l != LPAREN &&
			    (macro_getdef(p)->type & NEEDARGS) != 0))
				outputstr(token);
			else {
		/*
		 * real thing.. First build a call frame:
		 */
				pushf(fp);	/* previous call frm */
				pushf(macro_getdef(p)->type); /* type of the call  */
				pushf(is_traced(p));
				pushf(0);	/* parenthesis level */
				fp = sp;	/* new frame pointer */
		/*
		 * now push the string arguments:
		 */
				pushs1(macro_getdef(p)->defn);	/* defn string */
				pushs1((char *)macro_name(p));	/* macro name  */
				pushs(ep);			/* start next..*/

				if (l != LPAREN && PARLEV == 0) {
				    /* no bracks  */
					chrsave(EOS);

					if (sp == (int)STACKMAX)
						errx(1, "internal stack overflow");
					eval((const char **) mstack+fp+1, 2,
					    CALTYP, TRACESTATUS);

					ep = PREVEP;	/* flush strspace */
					sp = PREVSP;	/* previous sp..  */
					fp = PREVFP;	/* rewind stack...*/
				}
			}
		} else if (t == EOF) {
			if (!mimic_gnu /* you can puke right there */
			    && sp > -1 && ilevel <= 0) {
				warnx( "unexpected end of input, unclosed parenthesis:");
				dump_stack(paren, PARLEV);
				exit(1);
			}
			if (ilevel <= 0)
				break;			/* all done thanks.. */
			release_input(infile+ilevel--);
			emit_synchline();
			bufbase = bbase[ilevel];
			continue;
		} else if (sp < 0) {		/* not in a macro at all */
			reallyputchar(t);	/* output directly..	 */
		}

		else switch(t) {

		case LPAREN:
			if (PARLEV > 0)
				chrsave(t);
			while (isspace(l = gpbc())) /* skip blank, tab, nl.. */
				if (PARLEV > 0)
					chrsave(l);
			pushback(l);
			record(paren, PARLEV++);
			break;

		case RPAREN:
			if (--PARLEV > 0)
				chrsave(t);
			else {			/* end of argument list */
				chrsave(EOS);

				if (sp == (int)STACKMAX)
					errx(1, "internal stack overflow");

				eval((const char **) mstack+fp+1, sp-fp,
				    CALTYP, TRACESTATUS);

				ep = PREVEP;	/* flush strspace */
				sp = PREVSP;	/* previous sp..  */
				fp = PREVFP;	/* rewind stack...*/
			}
			break;

		case COMMA:
			if (PARLEV == 1) {
				chrsave(EOS);		/* new argument   */
				while (isspace(l = gpbc()))
					;
				pushback(l);
				pushs(ep);
			} else
				chrsave(t);
			break;

		default:
			if (LOOK_AHEAD(t, scommt)) {
				char *cp;
				for (cp = scommt; *cp; cp++)
					chrsave(*cp);
				for(;;) {
					t = gpbc();
					if (LOOK_AHEAD(t, ecommt)) {
						for (cp = ecommt; *cp; cp++)
							chrsave(*cp);
						break;
					}
					if (t == EOF)
					    break;
					CHRSAVE(t);
				}
			} else
				CHRSAVE(t);		/* stack the char */
			break;
		}
	}
}