コード例 #1
0
ファイル: exec_cmd.c プロジェクト: seblu/42sh
void			exec_cmd(s_cmd_node *cmd)
{
  assert(cmd);
  if (DEBUG_EXEC)
    cmd_debugger(cmd);
  //FIXME: expansions here
  if (!cmd->argv) {
    if (cmd->prefix) exec_prefix(cmd->prefix, 0);
    return;
  }
  if (func_exist(shell->func, cmd->argv[0]))
    exec_function(cmd->argv);
  else if (is_a_builtin(cmd->argv[0]))
    shell->status = get_builtin(cmd->argv[0])(cmd->argv);
  else
    shell->status = exec_program(cmd);
}
コード例 #2
0
ファイル: git.c プロジェクト: felipec/git
static void handle_builtin(int argc, const char **argv)
{
	const char *cmd;
	struct cmd_struct *builtin;

	strip_extension(argv);
	cmd = argv[0];

	/* Turn "git cmd --help" into "git help cmd" */
	if (argc > 1 && !strcmp(argv[1], "--help")) {
		argv[1] = argv[0];
		argv[0] = cmd = "help";
	}

	builtin = get_builtin(cmd);
	if (builtin)
		exit(run_builtin(builtin, argc, argv));
}
コード例 #3
0
ファイル: git.c プロジェクト: benpeart/git
int is_builtin(const char *s)
{
	return !!get_builtin(s);
}
コード例 #4
0
ファイル: lex.c プロジェクト: tomgrean/mksh
int
yylex(int cf)
{
	Lex_state states[STATE_BSIZE], *statep, *s2, *base;
	State_info state_info;
	int c, c2, state;
	size_t cz;
	XString ws;		/* expandable output word */
	char *wp;		/* output word pointer */
	char *sp, *dp;

 Again:
	states[0].type = SINVALID;
	states[0].ls_base = NULL;
	statep = &states[1];
	state_info.base = states;
	state_info.end = &state_info.base[STATE_BSIZE];

	Xinit(ws, wp, 64, ATEMP);

	backslash_skip = 0;
	ignore_backslash_newline = 0;

	if (cf & ONEWORD)
		state = SWORD;
	else if (cf & LETEXPR) {
		/* enclose arguments in (double) quotes */
		*wp++ = OQUOTE;
		state = SLETPAREN;
		statep->nparen = 0;
	} else {
		/* normal lexing */
		state = (cf & HEREDELIM) ? SHEREDELIM : SBASE;
		while (ctype((c = getsc()), C_BLANK))
			;
		if (c == '#') {
			ignore_backslash_newline++;
			while (!ctype((c = getsc()), C_NUL | C_LF))
				;
			ignore_backslash_newline--;
		}
		ungetsc(c);
	}
	if (source->flags & SF_ALIAS) {
		/* trailing ' ' in alias definition */
		source->flags &= ~SF_ALIAS;
		/* POSIX: trailing space only counts if parsing simple cmd */
		if (!Flag(FPOSIX) || (cf & CMDWORD))
			cf |= ALIAS;
	}

	/* Initial state: one of SWORD SLETPAREN SHEREDELIM SBASE */
	statep->type = state;

	/* collect non-special or quoted characters to form word */
	while (!((c = getsc()) == 0 ||
	    ((state == SBASE || state == SHEREDELIM) && ctype(c, C_LEX1)))) {
		if (state == SBASE &&
		    subshell_nesting_type == ord(/*{*/ '}') &&
		    c == ord(/*{*/ '}'))
			/* possibly end ${ :;} */
			break;
		Xcheck(ws, wp);
		switch (state) {
		case SADELIM:
			if (c == ord('('))
				statep->nparen++;
			else if (c == ord(')'))
				statep->nparen--;
			else if (statep->nparen == 0 && (c == ord(/*{*/ '}') ||
			    c == (int)statep->ls_adelim.delimiter)) {
				*wp++ = ADELIM;
				*wp++ = c;
				if (c == ord(/*{*/ '}') || --statep->ls_adelim.num == 0)
					POP_STATE();
				if (c == ord(/*{*/ '}'))
					POP_STATE();
				break;
			}
			/* FALLTHROUGH */
		case SBASE:
			if (c == ord('[') && (cf & CMDASN)) {
				/* temporary */
				*wp = EOS;
				if (is_wdvarname(Xstring(ws, wp), false)) {
					char *p, *tmp;

					if (arraysub(&tmp)) {
						*wp++ = CHAR;
						*wp++ = c;
						for (p = tmp; *p; ) {
							Xcheck(ws, wp);
							*wp++ = CHAR;
							*wp++ = *p++;
						}
						afree(tmp, ATEMP);
						break;
					} else {
						Source *s;

						s = pushs(SREREAD,
						    source->areap);
						s->start = s->str =
						    s->u.freeme = tmp;
						s->next = source;
						source = s;
					}
				}
				*wp++ = CHAR;
				*wp++ = c;
				break;
			}
			/* FALLTHROUGH */
 Sbase1:		/* includes *(...|...) pattern (*+?@!) */
			if (ctype(c, C_PATMO)) {
				c2 = getsc();
				if (c2 == ord('(' /*)*/)) {
					*wp++ = OPAT;
					*wp++ = c;
					PUSH_STATE(SPATTERN);
					break;
				}
				ungetsc(c2);
			}
			/* FALLTHROUGH */
 Sbase2:		/* doesn't include *(...|...) pattern (*+?@!) */
			switch (c) {
			case ord('\\'):
 getsc_qchar:
				if ((c = getsc())) {
					/* trailing \ is lost */
					*wp++ = QCHAR;
					*wp++ = c;
				}
				break;
			case ord('\''):
 open_ssquote_unless_heredoc:
				if ((cf & HEREDOC))
					goto store_char;
				*wp++ = OQUOTE;
				ignore_backslash_newline++;
				PUSH_STATE(SSQUOTE);
				break;
			case ord('"'):
 open_sdquote:
				*wp++ = OQUOTE;
				PUSH_STATE(SDQUOTE);
				break;
			case ord('$'):
				/*
				 * processing of dollar sign belongs into
				 * Subst, except for those which can open
				 * a string: $'…' and $"…"
				 */
 subst_dollar_ex:
				c = getsc();
				switch (c) {
				case ord('"'):
					goto open_sdquote;
				case ord('\''):
					goto open_sequote;
				default:
					goto SubstS;
				}
			default:
				goto Subst;
			}
			break;

 Subst:
			switch (c) {
			case ord('\\'):
				c = getsc();
				switch (c) {
				case ord('"'):
					if ((cf & HEREDOC))
						goto heredocquote;
					/* FALLTHROUGH */
				case ord('\\'):
				case ord('$'):
				case ord('`'):
 store_qchar:
					*wp++ = QCHAR;
					*wp++ = c;
					break;
				default:
 heredocquote:
					Xcheck(ws, wp);
					if (c) {
						/* trailing \ is lost */
						*wp++ = CHAR;
						*wp++ = '\\';
						*wp++ = CHAR;
						*wp++ = c;
					}
					break;
				}
				break;
			case ord('$'):
				c = getsc();
 SubstS:
				if (c == ord('(' /*)*/)) {
					c = getsc();
					if (c == ord('(' /*)*/)) {
						*wp++ = EXPRSUB;
						PUSH_SRETRACE(SASPAREN);
						statep->nparen = 2;
						*retrace_info->xp++ = '(';
					} else {
						ungetsc(c);
 subst_command:
						c = COMSUB;
 subst_command2:
						sp = yyrecursive(c);
						cz = strlen(sp) + 1;
						XcheckN(ws, wp, cz);
						*wp++ = c;
						memcpy(wp, sp, cz);
						wp += cz;
					}
				} else if (c == ord('{' /*}*/)) {
					if ((c = getsc()) == ord('|')) {
						/*
						 * non-subenvironment
						 * value substitution
						 */
						c = VALSUB;
						goto subst_command2;
					} else if (ctype(c, C_IFSWS)) {
						/*
						 * non-subenvironment
						 * "command" substitution
						 */
						c = FUNSUB;
						goto subst_command2;
					}
					ungetsc(c);
					*wp++ = OSUBST;
					*wp++ = '{' /*}*/;
					wp = get_brace_var(&ws, wp);
					c = getsc();
					/* allow :# and :% (ksh88 compat) */
					if (c == ord(':')) {
						*wp++ = CHAR;
						*wp++ = c;
						c = getsc();
						if (c == ord(':')) {
							*wp++ = CHAR;
							*wp++ = '0';
							*wp++ = ADELIM;
							*wp++ = ':';
							PUSH_STATE(SBRACE);
							PUSH_STATE(SADELIM);
							statep->ls_adelim.delimiter = ':';
							statep->ls_adelim.num = 1;
							statep->nparen = 0;
							break;
						} else if (ctype(c, C_DIGIT | C_DOLAR | C_SPC) ||
						    /*XXX what else? */
						    c == '(' /*)*/) {
							/* substring subst. */
							if (c != ' ') {
								*wp++ = CHAR;
								*wp++ = ' ';
							}
							ungetsc(c);
							PUSH_STATE(SBRACE);
							PUSH_STATE(SADELIM);
							statep->ls_adelim.delimiter = ':';
							statep->ls_adelim.num = 2;
							statep->nparen = 0;
							break;
						}
					} else if (c == '/') {
						c2 = ADELIM;
 parse_adelim_slash:
						*wp++ = CHAR;
						*wp++ = c;
						if ((c = getsc()) == ord('/')) {
							*wp++ = c2;
							*wp++ = c;
						} else
							ungetsc(c);
						PUSH_STATE(SBRACE);
						PUSH_STATE(SADELIM);
						statep->ls_adelim.delimiter = '/';
						statep->ls_adelim.num = 1;
						statep->nparen = 0;
						break;
					} else if (c == '@') {
						c2 = getsc();
						ungetsc(c2);
						if (c2 == ord('/')) {
							c2 = CHAR;
							goto parse_adelim_slash;
						}
					}
					/*
					 * If this is a trim operation,
					 * treat (,|,) specially in STBRACE.
					 */
					if (ctype(c, C_SUB2)) {
						ungetsc(c);
						if (Flag(FSH))
							PUSH_STATE(STBRACEBOURNE);
						else
							PUSH_STATE(STBRACEKORN);
					} else {
						ungetsc(c);
						if (state == SDQUOTE ||
						    state == SQBRACE)
							PUSH_STATE(SQBRACE);
						else
							PUSH_STATE(SBRACE);
					}
				} else if (ctype(c, C_ALPHX)) {
					*wp++ = OSUBST;
					*wp++ = 'X';
					do {
						Xcheck(ws, wp);
						*wp++ = c;
						c = getsc();
					} while (ctype(c, C_ALNUX));
					*wp++ = '\0';
					*wp++ = CSUBST;
					*wp++ = 'X';
					ungetsc(c);
				} else if (ctype(c, C_VAR1 | C_DIGIT)) {
					Xcheck(ws, wp);
					*wp++ = OSUBST;
					*wp++ = 'X';
					*wp++ = c;
					*wp++ = '\0';
					*wp++ = CSUBST;
					*wp++ = 'X';
				} else {
					*wp++ = CHAR;
					*wp++ = '$';
					ungetsc(c);
				}
				break;
			case ord('`'):
 subst_gravis:
				PUSH_STATE(SBQUOTE);
				*wp++ = COMASUB;
				/*
				 * We need to know whether we are within double
				 * quotes in order to translate \" to " within
				 * "…`…\"…`…" because, unlike for COMSUBs, the
				 * outer double quoteing changes the backslash
				 * meaning for the inside. For more details:
				 * http://austingroupbugs.net/view.php?id=1015
				 */
				statep->ls_bool = false;
				s2 = statep;
				base = state_info.base;
				while (/* CONSTCOND */ 1) {
					for (; s2 != base; s2--) {
						if (s2->type == SDQUOTE) {
							statep->ls_bool = true;
							break;
						}
					}
					if (s2 != base)
						break;
					if (!(s2 = s2->ls_base))
						break;
					base = s2-- - STATE_BSIZE;
				}
				break;
			case QCHAR:
				if (cf & LQCHAR) {
					*wp++ = QCHAR;
					*wp++ = getsc();
					break;
				}
				/* FALLTHROUGH */
			default:
 store_char:
				*wp++ = CHAR;
				*wp++ = c;
			}
			break;

		case SEQUOTE:
			if (c == ord('\'')) {
				POP_STATE();
				*wp++ = CQUOTE;
				ignore_backslash_newline--;
			} else if (c == ord('\\')) {
				if ((c2 = unbksl(true, getsc_i, ungetsc)) == -1)
					c2 = getsc();
				if (c2 == 0)
					statep->ls_bool = true;
				if (!statep->ls_bool) {
					char ts[4];

					if ((unsigned int)c2 < 0x100) {
						*wp++ = QCHAR;
						*wp++ = c2;
					} else {
						cz = utf_wctomb(ts, c2 - 0x100);
						ts[cz] = 0;
						cz = 0;
						do {
							*wp++ = QCHAR;
							*wp++ = ts[cz];
						} while (ts[++cz]);
					}
				}
			} else if (!statep->ls_bool) {
				*wp++ = QCHAR;
				*wp++ = c;
			}
			break;

		case SSQUOTE:
			if (c == ord('\'')) {
				POP_STATE();
				if ((cf & HEREDOC) || state == SQBRACE)
					goto store_char;
				*wp++ = CQUOTE;
				ignore_backslash_newline--;
			} else {
				*wp++ = QCHAR;
				*wp++ = c;
			}
			break;

		case SDQUOTE:
			if (c == ord('"')) {
				POP_STATE();
				*wp++ = CQUOTE;
			} else
				goto Subst;
			break;

		/* $(( ... )) */
		case SASPAREN:
			if (c == ord('('))
				statep->nparen++;
			else if (c == ord(')')) {
				statep->nparen--;
				if (statep->nparen == 1) {
					/* end of EXPRSUB */
					POP_SRETRACE();

					if ((c2 = getsc()) == ord(/*(*/ ')')) {
						cz = strlen(sp) - 2;
						XcheckN(ws, wp, cz);
						memcpy(wp, sp + 1, cz);
						wp += cz;
						afree(sp, ATEMP);
						*wp++ = '\0';
						break;
					} else {
						Source *s;

						ungetsc(c2);
						/*
						 * mismatched parenthesis -
						 * assume we were really
						 * parsing a $(...) expression
						 */
						--wp;
						s = pushs(SREREAD,
						    source->areap);
						s->start = s->str =
						    s->u.freeme = sp;
						s->next = source;
						source = s;
						goto subst_command;
					}
				}
			}
			/* reuse existing state machine */
			goto Sbase2;

		case SQBRACE:
			if (c == ord('\\')) {
				/*
				 * perform POSIX "quote removal" if the back-
				 * slash is "special", i.e. same cases as the
				 * {case '\\':} in Subst: plus closing brace;
				 * in mksh code "quote removal" on '\c' means
				 * write QCHAR+c, otherwise CHAR+\+CHAR+c are
				 * emitted (in heredocquote:)
				 */
				if ((c = getsc()) == ord('"') || c == ord('\\') ||
				    ctype(c, C_DOLAR | C_GRAVE) || c == ord(/*{*/ '}'))
					goto store_qchar;
				goto heredocquote;
			}
			goto common_SQBRACE;

		case SBRACE:
			if (c == ord('\''))
				goto open_ssquote_unless_heredoc;
			else if (c == ord('\\'))
				goto getsc_qchar;
 common_SQBRACE:
			if (c == ord('"'))
				goto open_sdquote;
			else if (c == ord('$'))
				goto subst_dollar_ex;
			else if (c == ord('`'))
				goto subst_gravis;
			else if (c != ord(/*{*/ '}'))
				goto store_char;
			POP_STATE();
			*wp++ = CSUBST;
			*wp++ = /*{*/ '}';
			break;

		/* Same as SBASE, except (,|,) treated specially */
		case STBRACEKORN:
			if (c == ord('|'))
				*wp++ = SPAT;
			else if (c == ord('(')) {
				*wp++ = OPAT;
				/* simile for @ */
				*wp++ = ' ';
				PUSH_STATE(SPATTERN);
			} else /* FALLTHROUGH */
		case STBRACEBOURNE:
			  if (c == ord(/*{*/ '}')) {
				POP_STATE();
				*wp++ = CSUBST;
				*wp++ = /*{*/ '}';
			} else
				goto Sbase1;
			break;

		case SBQUOTE:
			if (c == ord('`')) {
				*wp++ = 0;
				POP_STATE();
			} else if (c == ord('\\')) {
				switch (c = getsc()) {
				case 0:
					/* trailing \ is lost */
					break;
				case ord('$'):
				case ord('`'):
				case ord('\\'):
					*wp++ = c;
					break;
				case ord('"'):
					if (statep->ls_bool) {
						*wp++ = c;
						break;
					}
					/* FALLTHROUGH */
				default:
					*wp++ = '\\';
					*wp++ = c;
					break;
				}
			} else
				*wp++ = c;
			break;

		/* ONEWORD */
		case SWORD:
			goto Subst;

		/* LETEXPR: (( ... )) */
		case SLETPAREN:
			if (c == ord(/*(*/ ')')) {
				if (statep->nparen > 0)
					--statep->nparen;
				else if ((c2 = getsc()) == ord(/*(*/ ')')) {
					c = 0;
					*wp++ = CQUOTE;
					goto Done;
				} else {
					Source *s;

					ungetsc(c2);
					ungetsc(c);
					/*
					 * mismatched parenthesis -
					 * assume we were really
					 * parsing a (...) expression
					 */
					*wp = EOS;
					sp = Xstring(ws, wp);
					dp = wdstrip(sp + 1, WDS_TPUTS);
					s = pushs(SREREAD, source->areap);
					s->start = s->str = s->u.freeme = dp;
					s->next = source;
					source = s;
					ungetsc('(' /*)*/);
					return (ord('(' /*)*/));
				}
			} else if (c == ord('('))
				/*
				 * parentheses inside quotes and
				 * backslashes are lost, but AT&T ksh
				 * doesn't count them either
				 */
				++statep->nparen;
			goto Sbase2;

		/* << or <<- delimiter */
		case SHEREDELIM:
			/*
			 * here delimiters need a special case since
			 * $ and `...` are not to be treated specially
			 */
			switch (c) {
			case ord('\\'):
				if ((c = getsc())) {
					/* trailing \ is lost */
					*wp++ = QCHAR;
					*wp++ = c;
				}
				break;
			case ord('\''):
				goto open_ssquote_unless_heredoc;
			case ord('$'):
				if ((c2 = getsc()) == ord('\'')) {
 open_sequote:
					*wp++ = OQUOTE;
					ignore_backslash_newline++;
					PUSH_STATE(SEQUOTE);
					statep->ls_bool = false;
					break;
				} else if (c2 == ord('"')) {
					/* FALLTHROUGH */
			case ord('"'):
					PUSH_SRETRACE(SHEREDQUOTE);
					break;
				}
				ungetsc(c2);
				/* FALLTHROUGH */
			default:
				*wp++ = CHAR;
				*wp++ = c;
			}
			break;

		/* " in << or <<- delimiter */
		case SHEREDQUOTE:
			if (c != ord('"'))
				goto Subst;
			POP_SRETRACE();
			dp = strnul(sp) - 1;
			/* remove the trailing double quote */
			*dp = '\0';
			/* store the quoted string */
			*wp++ = OQUOTE;
			XcheckN(ws, wp, (dp - sp) * 2);
			dp = sp;
			while ((c = *dp++)) {
				if (c == '\\') {
					switch ((c = *dp++)) {
					case ord('\\'):
					case ord('"'):
					case ord('$'):
					case ord('`'):
						break;
					default:
						*wp++ = CHAR;
						*wp++ = '\\';
						break;
					}
				}
				*wp++ = CHAR;
				*wp++ = c;
			}
			afree(sp, ATEMP);
			*wp++ = CQUOTE;
			state = statep->type = SHEREDELIM;
			break;

		/* in *(...|...) pattern (*+?@!) */
		case SPATTERN:
			if (c == ord(/*(*/ ')')) {
				*wp++ = CPAT;
				POP_STATE();
			} else if (c == ord('|')) {
				*wp++ = SPAT;
			} else if (c == ord('(')) {
				*wp++ = OPAT;
				/* simile for @ */
				*wp++ = ' ';
				PUSH_STATE(SPATTERN);
			} else
				goto Sbase1;
			break;
		}
	}
 Done:
	Xcheck(ws, wp);
	if (statep != &states[1])
		/* XXX figure out what is missing */
		yyerror("no closing quote");

	/* This done to avoid tests for SHEREDELIM wherever SBASE tested */
	if (state == SHEREDELIM)
		state = SBASE;

	dp = Xstring(ws, wp);
	if (state == SBASE && (
	    (c == '&' && !Flag(FSH) && !Flag(FPOSIX)) ||
	    ctype(c, C_ANGLE)) && ((c2 = Xlength(ws, wp)) == 0 ||
	    (c2 == 2 && dp[0] == CHAR && ctype(dp[1], C_DIGIT)))) {
		struct ioword *iop = alloc(sizeof(struct ioword), ATEMP);

		iop->unit = c2 == 2 ? ksh_numdig(dp[1]) : c == '<' ? 0 : 1;

		if (c == '&') {
			if ((c2 = getsc()) != ord('>')) {
				ungetsc(c2);
				goto no_iop;
			}
			c = c2;
			iop->ioflag = IOBASH;
		} else
			iop->ioflag = 0;

		c2 = getsc();
		/* <<, >>, <> are ok, >< is not */
		if (c == c2 || (c == ord('<') && c2 == ord('>'))) {
			iop->ioflag |= c == c2 ?
			    (c == ord('>') ? IOCAT : IOHERE) : IORDWR;
			if (iop->ioflag == IOHERE) {
				if ((c2 = getsc()) == ord('-'))
					iop->ioflag |= IOSKIP;
				else if (c2 == ord('<'))
					iop->ioflag |= IOHERESTR;
				else
					ungetsc(c2);
			}
		} else if (c2 == ord('&'))
			iop->ioflag |= IODUP | (c == ord('<') ? IORDUP : 0);
		else {
			iop->ioflag |= c == ord('>') ? IOWRITE : IOREAD;
			if (c == ord('>') && c2 == ord('|'))
				iop->ioflag |= IOCLOB;
			else
				ungetsc(c2);
		}

		iop->ioname = NULL;
		iop->delim = NULL;
		iop->heredoc = NULL;
		/* free word */
		Xfree(ws, wp);
		yylval.iop = iop;
		return (REDIR);
 no_iop:
		afree(iop, ATEMP);
	}

	if (wp == dp && state == SBASE) {
		/* free word */
		Xfree(ws, wp);
		/* no word, process LEX1 character */
		if ((c == ord('|')) || (c == ord('&')) || (c == ord(';')) ||
		    (c == ord('(' /*)*/))) {
			if ((c2 = getsc()) == c)
				c = (c == ord(';')) ? BREAK :
				    (c == ord('|')) ? LOGOR :
				    (c == ord('&')) ? LOGAND :
				    /* c == ord('(' )) */ MDPAREN;
			else if (c == ord('|') && c2 == ord('&'))
				c = COPROC;
			else if (c == ord(';') && c2 == ord('|'))
				c = BRKEV;
			else if (c == ord(';') && c2 == ord('&'))
				c = BRKFT;
			else
				ungetsc(c2);
#ifndef MKSH_SMALL
			if (c == BREAK) {
				if ((c2 = getsc()) == ord('&'))
					c = BRKEV;
				else
					ungetsc(c2);
			}
#endif
		} else if (c == ord('\n')) {
			if (cf & HEREDELIM)
				ungetsc(c);
			else {
				gethere();
				if (cf & CONTIN)
					goto Again;
			}
		} else if (c == '\0' && !(cf & HEREDELIM)) {
			struct ioword **p = heres;

			while (p < herep)
				if ((*p)->ioflag & IOHERESTR)
					++p;
				else
					/* ksh -c 'cat <<EOF' can cause this */
					yyerror(Tf_heredoc,
					    evalstr((*p)->delim, 0));
		}
		return (c);
	}

	/* terminate word */
	*wp++ = EOS;
	yylval.cp = Xclose(ws, wp);
	if (state == SWORD || state == SLETPAREN
	    /* XXX ONEWORD? */)
		return (LWORD);

	/* unget terminator */
	ungetsc(c);

	/*
	 * note: the alias-vs-function code below depends on several
	 * interna: starting from here, source->str is not modified;
	 * the way getsc() and ungetsc() operate; etc.
	 */

	/* copy word to unprefixed string ident */
	sp = yylval.cp;
	dp = ident;
	while ((dp - ident) < IDENT && (c = *sp++) == CHAR)
		*dp++ = *sp++;
	if (c != EOS)
		/* word is not unquoted, or space ran out */
		dp = ident;
	/* make sure the ident array stays NUL padded */
	memset(dp, 0, (ident + IDENT) - dp + 1);

	if (*ident != '\0' && (cf & (KEYWORD | ALIAS))) {
		struct tbl *p;
		uint32_t h = hash(ident);

		if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&
		    (!(cf & ESACONLY) || p->val.i == ESAC ||
		    p->val.i == ord(/*{*/ '}'))) {
			afree(yylval.cp, ATEMP);
			return (p->val.i);
		}
		if ((cf & ALIAS) && (p = ktsearch(&aliases, ident, h)) &&
		    (p->flag & ISSET)) {
			/*
			 * this still points to the same character as the
			 * ungetsc'd terminator from above
			 */
			const char *cp = source->str;

			/* prefer POSIX but not Korn functions over aliases */
			while (ctype(*cp, C_BLANK))
				/*
				 * this is like getsc() without skipping
				 * over Source boundaries (including not
				 * parsing ungetsc'd characters that got
				 * pushed into an SREREAD) which is what
				 * we want here anyway: find out whether
				 * the alias name is followed by a POSIX
				 * function definition
				 */
				++cp;
			/* prefer functions over aliases */
			if (cp[0] != '(' || cp[1] != ')') {
				Source *s = source;

				while (s && (s->flags & SF_HASALIAS))
					if (s->u.tblp == p)
						return (LWORD);
					else
						s = s->next;
				/* push alias expansion */
				s = pushs(SALIAS, source->areap);
				s->start = s->str = p->val.s;
				s->u.tblp = p;
				s->flags |= SF_HASALIAS;
				s->line = source->line;
				s->next = source;
				if (source->type == SEOF) {
					/* prevent infinite recursion at EOS */
					source->u.tblp = p;
					source->flags |= SF_HASALIAS;
				}
				source = s;
				afree(yylval.cp, ATEMP);
				goto Again;
			}
		}
	} else if (*ident == '\0') {
		/* retain typeset et al. even when quoted */
		struct tbl *tt = get_builtin((dp = wdstrip(yylval.cp, 0)));
		uint32_t flag = tt ? tt->flag : 0;

		if (flag & (DECL_UTIL | DECL_FWDR))
			strlcpy(ident, dp, sizeof(ident));
		afree(dp, ATEMP);
	}

	return (LWORD);
}
コード例 #5
0
ファイル: gg08.c プロジェクト: glammar/glammar
init_builtins ()
{
  long rule, alt;

  equal = get_builtin ("equal");
  if (meta_uniq_flag)
    *(REPR (equal)) = 'f';
  notequal = get_builtin ("notequal");
  if (meta_uniq_flag)
    *(REPR (notequal)) = 'f';

  endofsentence = get_builtin ("endofsentence");
  evalmeta = get_builtin ("evalmeta");
  explintersect = get_builtin ("explintersect_");
  falseip = get_builtin ("falseip_");
  getip = get_builtin ("getip_");
  initmeta = get_builtin ("initmeta");
  initmint = get_builtin ("initmint_");
  intersect = get_builtin ("intersect_");
  metaterminal = get_builtin ("metaterminal");
  metaterminal2 = get_builtin ("metaterminal2_");
  nestaralt = get_builtin ("nestaralt_");
  nestarset = get_builtin ("nestarset");
  detnestarset = get_builtin ("detnestarset");
  detprefix = get_builtin ("detprefix");
  detprefix2 = get_builtin ("detprefix2_");
  equalsempty = get_builtin ("equalsempty");
  nlcr = get_builtin ("nlcr");
  pair = get_builtin ("pair");
  repair = get_builtin ("repair");
  resetinputptr = get_builtin ("resetinputptr_");
  restoreip = get_builtin ("restoreip_");
  setinputptrto = get_builtin ("setinputptrto_");
  skip = get_builtin ("skip_");
  tltraditional = get_builtin ("tltraditional_");
  tltraditionalterm = get_builtin ("tltraditionalterm_");
  transformlattice = get_builtin ("transformlattice_");
  transformlatticeterm = get_builtin ("transformlatticeterm_");
  unpair = get_builtin ("unpair");
  where = get_builtin ("where");
  getlist_ = get_builtin ("getlist_");
  add_to = get_builtin ("addto");
  assign = get_builtin ("assign");

  meta_empty = get_meta_builtin ("empty");
}