invent builtin flags instead of special-casing cat and printf for prefer-external-over-builtin stuff

This commit is contained in:
tg 2016-07-24 23:10:04 +00:00
parent 5401a55a98
commit e8bbf79d8c
4 changed files with 49 additions and 51 deletions

83
exec.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.176 2016/07/24 23:07:19 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.177 2016/07/24 23:10:02 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh"
@ -533,11 +533,7 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
}
if ((tp = findcom(cp, FC_BI)) == NULL)
errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin");
if (tp->type == CSHELL && (tp->val.f == c_cat
#ifdef MKSH_PRINTF_BUILTIN
|| tp->val.f == c_printf
#endif
))
if (tp->type == CSHELL && (tp->flag & LOW_BI))
break;
continue;
} else if (tp->val.f == c_exec) {
@ -595,29 +591,21 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
subst_exstat = 0;
break;
}
} else if (tp->val.f == c_cat) {
} else if (tp->flag & LOW_BI) {
/* if we have any flags, do not use the builtin */
if (ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' &&
if ((ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' &&
/* argument, begins with -, is not - or -- */
(ap[1][1] != '-' || ap[1][2] != '\0')) {
struct tbl *ext_cat;
(ap[1][1] != '-' || ap[1][2] != '\0')) ||
/* always prefer the external utility */
(tp->flag & LOWER_BI)) {
struct tbl *ext_cmd;
ext_cat = findcom(Tcat, FC_PATH | FC_FUNC);
if (ext_cat && (ext_cat->type != CTALIAS ||
(ext_cat->flag & ISSET)))
tp = ext_cat;
ext_cmd = findcom(tp->name, FC_PATH | FC_FUNC);
if (ext_cmd && (ext_cmd->type != CTALIAS ||
(ext_cmd->flag & ISSET)))
tp = ext_cmd;
}
break;
#ifdef MKSH_PRINTF_BUILTIN
} else if (tp->val.f == c_printf) {
struct tbl *ext_printf;
ext_printf = findcom(Tprintf, FC_PATH | FC_FUNC);
if (ext_printf && (ext_printf->type != CTALIAS ||
(ext_printf->flag & ISSET)))
tp = ext_printf;
break;
#endif
} else if (tp->val.f == c_trap) {
t->u.evalflags &= ~DOTCOMEXEC;
break;
@ -727,16 +715,12 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
!(ftp = findfunc(cp, hash(cp), false)) ||
!(ftp->flag & ISSET)) {
rv = errno;
if (!strcmp(cp, Tcat)) {
tp = findcom(Tcat, FC_BI);
if ((ftp = findcom(cp, FC_BI)) &&
(ftp->type == CSHELL) &&
(ftp->flag & LOW_BI)) {
tp = ftp;
goto do_call_builtin;
}
#ifdef MKSH_PRINTF_BUILTIN
if (!strcmp(cp, Tprintf)) {
tp = findcom(Tprintf, FC_BI);
goto do_call_builtin;
}
#endif
if (rv) {
tp->u2.errnov = rv;
cp = tp->u.fpath;
@ -1089,23 +1073,38 @@ builtin(const char *name, int (*func) (const char **))
uint32_t flag = DEFINED;
/* see if any flags should be set for this builtin */
while (1) {
if (*name == '=')
/* command does variable assignment */
flag |= KEEPASN;
else if (*name == '*')
/* POSIX special builtin */
flag |= SPEC_BI;
else
break;
name++;
flags_loop:
switch (*name) {
case '=':
/* command does variable assignment */
flag |= KEEPASN;
break;
case '*':
/* POSIX special builtin */
flag |= SPEC_BI;
break;
case '~':
/* external utility overrides built-in utility, always */
flag |= LOWER_BI;
/* FALLTHROUGH */
case '!':
/* external utility overrides built-in utility, with flags */
flag |= LOW_BI;
break;
default:
goto flags_seen;
}
++name;
goto flags_loop;
flags_seen:
/* enter into the builtins hash table */
tp = ktenter(&builtins, name, hash(name));
tp->flag = flag;
tp->type = CSHELL;
tp->val.f = func;
/* return name, for direct builtin call check in main.c */
return (name);
}

View File

@ -38,7 +38,7 @@
#endif
#endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.297 2016/06/26 00:44:25 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.298 2016/07/24 23:10:02 tg Exp $");
#if HAVE_KILLPG
/*
@ -101,7 +101,7 @@ const struct builtin mkshbuiltins[] = {
{Talias, c_alias},
{"*=break", c_brkcont},
{Tgbuiltin, c_builtin},
{Tcat, c_cat},
{"!cat", c_cat},
{"cd", c_cd},
/* dash compatibility hack */
{"chdir", c_cd},
@ -155,7 +155,7 @@ const struct builtin mkshbuiltins[] = {
{"mknod", c_mknod},
#endif
#ifdef MKSH_PRINTF_BUILTIN
{Tprintf, c_printf},
{"~printf", c_printf},
#endif
#if HAVE_SELECT
{"sleep", c_sleep},

2
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.310 2016/02/26 21:53:36 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.311 2016/07/24 23:10:03 tg Exp $");
extern char **environ;

9
sh.h
View File

@ -175,7 +175,7 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.775 2016/07/12 23:07:10 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.776 2016/07/24 23:10:04 tg Exp $");
#endif
#define MKSH_VERSION "R52 2016/07/12"
@ -864,13 +864,9 @@ EXTERN const char T_typeset[] E_INIT("=typeset");
#define Ttypeset (T_typeset + 1) /* "typeset" */
EXTERN const char Talias[] E_INIT("alias");
EXTERN const char Tunalias[] E_INIT("unalias");
EXTERN const char Tcat[] E_INIT("cat");
#ifdef __OS2__
EXTERN const char Textproc[] E_INIT("extproc");
#endif
#ifdef MKSH_PRINTF_BUILTIN
EXTERN const char Tprintf[] E_INIT("printf");
#endif
EXTERN const char Tsgset[] E_INIT("*=set");
#define Tset (Tsgset + 2) /* "set" */
EXTERN const char Tsgexport[] E_INIT("*=export");
@ -1243,6 +1239,9 @@ EXTERN bool last_lookup_was_array;
#define FDELETE BIT(10) /* function deleted while it was executing */
#define FKSH BIT(11) /* function defined with function x (vs x()) */
#define SPEC_BI BIT(12) /* a POSIX special builtin */
#define LOWER_BI BIT(13) /* (with LOW_BI) override even w/o flags */
#define LOW_BI BIT(14) /* external utility overrides built-in one */
/*
* Attributes that can be set by the user (used to decide if an unset
* param should be repoted by set/typeset). Does not include ARRAY or