コード例 #1
0
/*
 * add builtin
 */
const char *
builtin(const char *name, int (*func) (const char **))
{
	struct tbl *tp;
	uint32_t flag;

	/* see if any flags should be set for this builtin */
	for (flag = 0; ; name++) {
		if (*name == '=')
			/* command does variable assignment */
			flag |= KEEPASN;
		else if (*name == '*')
			/* POSIX special builtin */
			flag |= SPEC_BI;
		else if (*name == '+')
			/* POSIX regular builtin */
			flag |= REG_BI;
		else
			break;
	}

	tp = ktenter(&builtins, name, hash(name));
	tp->flag = DEFINED | flag;
	tp->type = CSHELL;
	tp->val.f = func;

	return (name);
}
コード例 #2
0
ファイル: var.c プロジェクト: rovaughn/distro
void
initvar(void)
{
	int i = 0;
	struct tbl *tp;

	ktinit(APERM, &specials,
	    /* currently 14 specials: 75% of 32 = 2^5 */
	    5);
	while (i < V_MAX - 1) {
		tp = ktenter(&specials, initvar_names[i],
		    hash(initvar_names[i]));
		tp->flag = DEFINED|ISSET;
		tp->type = ++i;
	}
}
コード例 #3
0
ファイル: var.c プロジェクト: tomgrean/mksh
/*
 * Search for local variable, if not found create locally.
 */
struct tbl *
local(const char *n, bool copy)
{
	struct tbl *vp;
	union mksh_cchack vname;
	struct block *l = e->loc;
	bool array;
	uint32_t h, val;

	/*
	 * check to see if this is an array;
	 * dereference namerefs; must come first
	 */
	vn = array_index_calc(n, &array, &val);
	h = hash(vn);
	if (!ctype(*vn, C_ALPHX)) {
		vp = vtemp;
		vp->flag = DEFINED|RDONLY;
		vp->type = 0;
		vp->areap = ATEMP;
		goto out;
	}
	vp = ktenter(&l->vars, vn, h);
	if (copy && !(vp->flag & DEFINED)) {
		struct tbl *vq;

		varsearch(l->next, &vq, vn, h);
		if (vq != NULL) {
			vp->flag |= vq->flag &
			    (EXPORT | INTEGER | RDONLY | LJUST | RJUST |
			    ZEROFIL | LCASEV | UCASEV_AL | INT_U | INT_L);
			if (vq->flag & INTEGER)
				vp->type = vq->type;
			vp->u2.field = vq->u2.field;
		}
	}
	if (array)
		vp = arraysearch(vp, val);
	vp->flag |= DEFINED;
	if (special(vn))
		vp->flag |= SPECIAL;
 out:
	last_lookup_was_array = array;
	if (vn != n)
		afree(vname.rw, ATEMP);
	return (vp);
}
コード例 #4
0
ファイル: var.c プロジェクト: syuu1228/openbsd-src
/*
 * Search for local variable, if not found create locally.
 */
struct tbl *
local(const char *n, bool copy)
{
	struct block *l = e->loc;
	struct tbl *vp;
	unsigned int h;
	bool	 array;
	int	 val;

	/* Check to see if this is an array */
	n = array_index_calc(n, &array, &val);
	h = hash(n);
	if (!letter(*n)) {
		vp = &vtemp;
		vp->flag = DEFINED|RDONLY;
		vp->type = 0;
		vp->areap = ATEMP;
		return vp;
	}
	vp = ktenter(&l->vars, n, h);
	if (copy && !(vp->flag & DEFINED)) {
		struct block *ll = l;
		struct tbl *vq = (struct tbl *) 0;

		while ((ll = ll->next) && !(vq = ktsearch(&ll->vars, n, h)))
			;
		if (vq) {
			vp->flag |= vq->flag &
			    (EXPORT | INTEGER | RDONLY | LJUST | RJUST |
			    ZEROFIL | LCASEV | UCASEV_AL | INT_U | INT_L);
			if (vq->flag & INTEGER)
				vp->type = vq->type;
			vp->u2.field = vq->u2.field;
		}
	}
	if (array)
		vp = arraysearch(vp, val);
	vp->flag |= DEFINED;
	if (special(n))
		vp->flag |= SPECIAL;
	return vp;
}
コード例 #5
0
ファイル: var.c プロジェクト: rovaughn/distro
/*
 * Search for local variable, if not found create locally.
 */
struct tbl *
local(const char *n, bool copy)
{
	struct block *l = e->loc;
	struct tbl *vp;
	bool array;
	uint32_t h, val;

	/*
	 * check to see if this is an array;
	 * dereference namerefs; must come first
	 */
	n = array_index_calc(n, &array, &val);
	h = hash(n);
	if (!ksh_isalphx(*n)) {
		vp = &vtemp;
		vp->flag = DEFINED|RDONLY;
		vp->type = 0;
		vp->areap = ATEMP;
		return (vp);
	}
	vp = ktenter(&l->vars, n, h);
	if (copy && !(vp->flag & DEFINED)) {
		struct tbl *vq;

		varsearch(l->next, &vq, n, h);
		if (vq != NULL) {
			vp->flag |= vq->flag &
			    (EXPORT | INTEGER | RDONLY | LJUST | RJUST |
			    ZEROFIL | LCASEV | UCASEV_AL | INT_U | INT_L);
			if (vq->flag & INTEGER)
				vp->type = vq->type;
			vp->u2.field = vq->u2.field;
		}
	}
	if (array)
		vp = arraysearch(vp, val);
	vp->flag |= DEFINED;
	if (special(n))
		vp->flag |= SPECIAL;
	return (vp);
}
コード例 #6
0
/*
 * Search function tables for a function. If create set, a table entry
 * is created if none is found.
 */
struct tbl *
findfunc(const char *name, uint32_t h, bool create)
{
	struct block *l;
	struct tbl *tp = NULL;

	for (l = e->loc; l; l = l->next) {
		tp = ktsearch(&l->funs, name, h);
		if (tp)
			break;
		if (!l->next && create) {
			tp = ktenter(&l->funs, name, h);
			tp->flag = DEFINED;
			tp->type = CFUNC;
			tp->val.t = NULL;
			break;
		}
	}
	return (tp);
}
コード例 #7
0
ファイル: var.c プロジェクト: syuu1228/openbsd-src
/* called by main() to initialize variable data structures */
void
initvar(void)
{
	static const struct {
		const char *name;
		int v;
	} names[] = {
		{ "COLUMNS",		V_COLUMNS },
		{ "IFS",		V_IFS },
		{ "OPTIND",		V_OPTIND },
		{ "PATH",		V_PATH },
		{ "POSIXLY_CORRECT",	V_POSIXLY_CORRECT },
		{ "TMPDIR",		V_TMPDIR },
#ifdef HISTORY
		{ "HISTFILE",		V_HISTFILE },
		{ "HISTSIZE",		V_HISTSIZE },
#endif /* HISTORY */
#ifdef EDIT
		{ "EDITOR",		V_EDITOR },
		{ "VISUAL",		V_VISUAL },
#endif /* EDIT */
		{ "MAIL",		V_MAIL },
		{ "MAILCHECK",		V_MAILCHECK },
		{ "MAILPATH",		V_MAILPATH },
		{ "RANDOM",		V_RANDOM },
		{ "SECONDS",		V_SECONDS },
		{ "TMOUT",		V_TMOUT },
		{ "LINENO",		V_LINENO },
		{ (char *) 0,	0 }
	};
	int i;
	struct tbl *tp;

	ktinit(&specials, APERM, 32); /* must be 2^n (currently 17 specials) */
	for (i = 0; names[i].name; i++) {
		tp = ktenter(&specials, names[i].name, hash(names[i].name));
		tp->flag = DEFINED|ISSET;
		tp->type = names[i].v;
	}
}
コード例 #8
0
/*
 * find command
 * either function, hashed command, or built-in (in that order)
 */
struct tbl *
findcom(const char *name, int flags)
{
	static struct tbl temp;
	uint32_t h = hash(name);
	struct tbl *tp = NULL, *tbi;
	/* insert if not found */
	unsigned char insert = Flag(FTRACKALL);
	/* for function autoloading */
	char *fpath;
	union mksh_cchack npath;

	if (vstrchr(name, '/')) {
		insert = 0;
		/* prevent FPATH search below */
		flags &= ~FC_FUNC;
		goto Search;
	}
	tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h) : NULL;
	/*
	 * POSIX says special builtins first, then functions, then
	 * POSIX regular builtins, then search path...
	 */
	if ((flags & FC_SPECBI) && tbi && (tbi->flag & SPEC_BI))
		tp = tbi;
	if (!tp && (flags & FC_FUNC)) {
		tp = findfunc(name, h, false);
		if (tp && !(tp->flag & ISSET)) {
			if ((fpath = str_val(global("FPATH"))) == null) {
				tp->u.fpath = NULL;
				tp->u2.errnov = ENOENT;
			} else
				tp->u.fpath = search_path(name, fpath, R_OK,
				    &tp->u2.errnov);
		}
	}
	if (!tp && (flags & FC_REGBI) && tbi && (tbi->flag & REG_BI))
		tp = tbi;
	if (!tp && (flags & FC_UNREGBI) && tbi)
		tp = tbi;
	if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
		tp = ktsearch(&taliases, name, h);
		if (tp && (tp->flag & ISSET) &&
		    ksh_access(tp->val.s, X_OK) != 0) {
			if (tp->flag & ALLOC) {
				tp->flag &= ~ALLOC;
				afree(tp->val.s, APERM);
			}
			tp->flag &= ~ISSET;
		}
	}

 Search:
	if ((!tp || (tp->type == CTALIAS && !(tp->flag&ISSET))) &&
	    (flags & FC_PATH)) {
		if (!tp) {
			if (insert && !(flags & FC_DEFPATH)) {
				tp = ktenter(&taliases, name, h);
				tp->type = CTALIAS;
			} else {
				tp = &temp;
				tp->type = CEXEC;
			}
			/* make ~ISSET */
			tp->flag = DEFINED;
		}
		npath.ro = search_path(name,
		    (flags & FC_DEFPATH) ? def_path : path,
		    X_OK, &tp->u2.errnov);
		if (npath.ro) {
			strdupx(tp->val.s, npath.ro, APERM);
			if (npath.ro != name)
				afree(npath.rw, ATEMP);
			tp->flag |= ISSET|ALLOC;
		} else if ((flags & FC_FUNC) &&
		    (fpath = str_val(global("FPATH"))) != null &&
		    (npath.ro = search_path(name, fpath, R_OK,
		    &tp->u2.errnov)) != NULL) {
			/*
			 * An undocumented feature of AT&T ksh is that
			 * it searches FPATH if a command is not found,
			 * even if the command hasn't been set up as an
			 * autoloaded function (ie, no typeset -uf).
			 */
			tp = &temp;
			tp->type = CFUNC;
			/* make ~ISSET */
			tp->flag = DEFINED;
			tp->u.fpath = npath.ro;
		}
	}
	return (tp);
}
コード例 #9
0
ファイル: var.c プロジェクト: syuu1228/openbsd-src
/*
 * Search for variable, if not found create globally.
 */
struct tbl *
global(const char *n)
{
	struct block *l = e->loc;
	struct tbl *vp;
	int c;
	unsigned int h;
	bool	 array;
	int	 val;

	/* Check to see if this is an array */
	n = array_index_calc(n, &array, &val);
	h = hash(n);
	c = n[0];
	if (!letter(c)) {
		if (array)
			errorf("bad substitution");
		vp = &vtemp;
		vp->flag = DEFINED;
		vp->type = 0;
		vp->areap = ATEMP;
		*vp->name = c;
		if (digit(c)) {
			for (c = 0; digit(*n); n++)
				c = c*10 + *n-'0';
			if (c <= l->argc)
				/* setstr can't fail here */
				setstr(vp, l->argv[c], KSH_RETURN_ERROR);
			vp->flag |= RDONLY;
			return vp;
		}
		vp->flag |= RDONLY;
		if (n[1] != '\0')
			return vp;
		vp->flag |= ISSET|INTEGER;
		switch (c) {
		case '$':
			vp->val.i = kshpid;
			break;
		case '!':
			/* If no job, expand to nothing */
			if ((vp->val.i = j_async()) == 0)
				vp->flag &= ~(ISSET|INTEGER);
			break;
		case '?':
			vp->val.i = exstat;
			break;
		case '#':
			vp->val.i = l->argc;
			break;
		case '-':
			vp->flag &= ~INTEGER;
			vp->val.s = getoptions();
			break;
		default:
			vp->flag &= ~(ISSET|INTEGER);
		}
		return vp;
	}
	for (l = e->loc; ; l = l->next) {
		vp = ktsearch(&l->vars, n, h);
		if (vp != NULL) {
			if (array)
				return arraysearch(vp, val);
			else
				return vp;
		}
		if (l->next == NULL)
			break;
	}
	vp = ktenter(&l->vars, n, h);
	if (array)
		vp = arraysearch(vp, val);
	vp->flag |= DEFINED;
	if (special(n))
		vp->flag |= SPECIAL;
	return vp;
}
コード例 #10
0
ファイル: var.c プロジェクト: rovaughn/distro
/*
 * Search for variable, if not found create globally.
 */
struct tbl *
global(const char *n)
{
	struct block *l = e->loc;
	struct tbl *vp;
	int c;
	bool array;
	uint32_t h, val;

	/*
	 * check to see if this is an array;
	 * dereference namerefs; must come first
	 */
	n = array_index_calc(n, &array, &val);
	h = hash(n);
	c = (unsigned char)n[0];
	if (!ksh_isalphx(c)) {
		if (array)
			errorf("bad substitution");
		vp = &vtemp;
		vp->flag = DEFINED;
		vp->type = 0;
		vp->areap = ATEMP;
		*vp->name = c;
		if (ksh_isdigit(c)) {
			if (getn(n, &c) && (c <= l->argc))
				/* setstr can't fail here */
				setstr(vp, l->argv[c], KSH_RETURN_ERROR);
			vp->flag |= RDONLY;
			return (vp);
		}
		vp->flag |= RDONLY;
		if (n[1] != '\0')
			return (vp);
		vp->flag |= ISSET|INTEGER;
		switch (c) {
		case '$':
			vp->val.i = kshpid;
			break;
		case '!':
			/* if no job, expand to nothing */
			if ((vp->val.i = j_async()) == 0)
				vp->flag &= ~(ISSET|INTEGER);
			break;
		case '?':
			vp->val.i = exstat & 0xFF;
			break;
		case '#':
			vp->val.i = l->argc;
			break;
		case '-':
			vp->flag &= ~INTEGER;
			vp->val.s = getoptions();
			break;
		default:
			vp->flag &= ~(ISSET|INTEGER);
		}
		return (vp);
	}
	l = varsearch(e->loc, &vp, n, h);
	if (vp != NULL)
		return (array ? arraysearch(vp, val) : vp);
	vp = ktenter(&l->vars, n, h);
	if (array)
		vp = arraysearch(vp, val);
	vp->flag |= DEFINED;
	if (special(n))
		vp->flag |= SPECIAL;
	return (vp);
}
コード例 #11
0
ファイル: var.c プロジェクト: tomgrean/mksh
/* search for variable; if not found, return NULL or create globally */
struct tbl *
isglobal(const char *n, bool docreate)
{
	struct tbl *vp;
	union mksh_cchack vname;
	struct block *l = e->loc;
	int c;
	bool array;
	uint32_t h, val;

	/*
	 * check to see if this is an array;
	 * dereference namerefs; must come first
	 */
	vn = array_index_calc(n, &array, &val);
	h = hash(vn);
	c = (unsigned char)vn[0];
	if (!ctype(c, C_ALPHX)) {
		if (array)
			errorf(Tbadsubst);
		vp = vtemp;
		vp->flag = DEFINED;
		vp->type = 0;
		vp->areap = ATEMP;
		if (ctype(c, C_DIGIT)) {
			if (getn(vn, &c)) {
				/* main.c:main_init() says 12 */
				shf_snprintf(vp->name, 12, Tf_d, c);
				if (c <= l->argc) {
					/* setstr can't fail here */
					setstr(vp, l->argv[c],
					    KSH_RETURN_ERROR);
				}
			} else
				vp->name[0] = '\0';
			vp->flag |= RDONLY;
			goto out;
		}
		vp->name[0] = c;
		vp->name[1] = '\0';
		vp->flag |= RDONLY;
		if (vn[1] != '\0')
			goto out;
		vp->flag |= ISSET|INTEGER;
		switch (c) {
		case '$':
			vp->val.i = kshpid;
			break;
		case '!':
			/* if no job, expand to nothing */
			if ((vp->val.i = j_async()) == 0)
				vp->flag &= ~(ISSET|INTEGER);
			break;
		case '?':
			vp->val.i = exstat & 0xFF;
			break;
		case '#':
			vp->val.i = l->argc;
			break;
		case '-':
			vp->flag &= ~INTEGER;
			vp->val.s = getoptions();
			break;
		default:
			vp->flag &= ~(ISSET|INTEGER);
		}
		goto out;
	}
	l = varsearch(e->loc, &vp, vn, h);
	if (vp == NULL && docreate)
		vp = ktenter(&l->vars, vn, h);
	else
		docreate = false;
	if (vp != NULL) {
		if (array)
			vp = arraysearch(vp, val);
		if (docreate) {
			vp->flag |= DEFINED;
			if (special(vn))
				vp->flag |= SPECIAL;
		}
	}
 out:
	last_lookup_was_array = array;
	if (vn != n)
		afree(vname.rw, ATEMP);
	return (vp);
}