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" #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 #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" #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) if ((tp = findcom(cp, FC_BI)) == NULL)
errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin"); errorf("%s: %s: %s", Tbuiltin, cp, "not a builtin");
if (tp->type == CSHELL && (tp->val.f == c_cat if (tp->type == CSHELL && (tp->flag & LOW_BI))
#ifdef MKSH_PRINTF_BUILTIN
|| tp->val.f == c_printf
#endif
))
break; break;
continue; continue;
} else if (tp->val.f == c_exec) { } 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; subst_exstat = 0;
break; 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 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 -- */ /* argument, begins with -, is not - or -- */
(ap[1][1] != '-' || ap[1][2] != '\0')) { (ap[1][1] != '-' || ap[1][2] != '\0')) ||
struct tbl *ext_cat; /* always prefer the external utility */
(tp->flag & LOWER_BI)) {
struct tbl *ext_cmd;
ext_cat = findcom(Tcat, FC_PATH | FC_FUNC); ext_cmd = findcom(tp->name, FC_PATH | FC_FUNC);
if (ext_cat && (ext_cat->type != CTALIAS || if (ext_cmd && (ext_cmd->type != CTALIAS ||
(ext_cat->flag & ISSET))) (ext_cmd->flag & ISSET)))
tp = ext_cat; tp = ext_cmd;
} }
break; 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) { } else if (tp->val.f == c_trap) {
t->u.evalflags &= ~DOTCOMEXEC; t->u.evalflags &= ~DOTCOMEXEC;
break; break;
@ -727,16 +715,12 @@ comexec(struct op *t, struct tbl * volatile tp, const char **ap,
!(ftp = findfunc(cp, hash(cp), false)) || !(ftp = findfunc(cp, hash(cp), false)) ||
!(ftp->flag & ISSET)) { !(ftp->flag & ISSET)) {
rv = errno; rv = errno;
if (!strcmp(cp, Tcat)) { if ((ftp = findcom(cp, FC_BI)) &&
tp = findcom(Tcat, FC_BI); (ftp->type == CSHELL) &&
(ftp->flag & LOW_BI)) {
tp = ftp;
goto do_call_builtin; goto do_call_builtin;
} }
#ifdef MKSH_PRINTF_BUILTIN
if (!strcmp(cp, Tprintf)) {
tp = findcom(Tprintf, FC_BI);
goto do_call_builtin;
}
#endif
if (rv) { if (rv) {
tp->u2.errnov = rv; tp->u2.errnov = rv;
cp = tp->u.fpath; cp = tp->u.fpath;
@ -1089,23 +1073,38 @@ builtin(const char *name, int (*func) (const char **))
uint32_t flag = DEFINED; uint32_t flag = DEFINED;
/* see if any flags should be set for this builtin */ /* see if any flags should be set for this builtin */
while (1) { flags_loop:
if (*name == '=') switch (*name) {
/* command does variable assignment */ case '=':
flag |= KEEPASN; /* command does variable assignment */
else if (*name == '*') flag |= KEEPASN;
/* POSIX special builtin */ break;
flag |= SPEC_BI; case '*':
else /* POSIX special builtin */
break; flag |= SPEC_BI;
name++; 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 = ktenter(&builtins, name, hash(name));
tp->flag = flag; tp->flag = flag;
tp->type = CSHELL; tp->type = CSHELL;
tp->val.f = func; tp->val.f = func;
/* return name, for direct builtin call check in main.c */
return (name); return (name);
} }

View File

@ -38,7 +38,7 @@
#endif #endif
#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 #if HAVE_KILLPG
/* /*
@ -101,7 +101,7 @@ const struct builtin mkshbuiltins[] = {
{Talias, c_alias}, {Talias, c_alias},
{"*=break", c_brkcont}, {"*=break", c_brkcont},
{Tgbuiltin, c_builtin}, {Tgbuiltin, c_builtin},
{Tcat, c_cat}, {"!cat", c_cat},
{"cd", c_cd}, {"cd", c_cd},
/* dash compatibility hack */ /* dash compatibility hack */
{"chdir", c_cd}, {"chdir", c_cd},
@ -155,7 +155,7 @@ const struct builtin mkshbuiltins[] = {
{"mknod", c_mknod}, {"mknod", c_mknod},
#endif #endif
#ifdef MKSH_PRINTF_BUILTIN #ifdef MKSH_PRINTF_BUILTIN
{Tprintf, c_printf}, {"~printf", c_printf},
#endif #endif
#if HAVE_SELECT #if HAVE_SELECT
{"sleep", c_sleep}, {"sleep", c_sleep},

2
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #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; extern char **environ;

9
sh.h
View File

@ -175,7 +175,7 @@
#endif #endif
#ifdef EXTERN #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 #endif
#define MKSH_VERSION "R52 2016/07/12" #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" */ #define Ttypeset (T_typeset + 1) /* "typeset" */
EXTERN const char Talias[] E_INIT("alias"); EXTERN const char Talias[] E_INIT("alias");
EXTERN const char Tunalias[] E_INIT("unalias"); EXTERN const char Tunalias[] E_INIT("unalias");
EXTERN const char Tcat[] E_INIT("cat");
#ifdef __OS2__ #ifdef __OS2__
EXTERN const char Textproc[] E_INIT("extproc"); EXTERN const char Textproc[] E_INIT("extproc");
#endif #endif
#ifdef MKSH_PRINTF_BUILTIN
EXTERN const char Tprintf[] E_INIT("printf");
#endif
EXTERN const char Tsgset[] E_INIT("*=set"); EXTERN const char Tsgset[] E_INIT("*=set");
#define Tset (Tsgset + 2) /* "set" */ #define Tset (Tsgset + 2) /* "set" */
EXTERN const char Tsgexport[] E_INIT("*=export"); 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 FDELETE BIT(10) /* function deleted while it was executing */
#define FKSH BIT(11) /* function defined with function x (vs x()) */ #define FKSH BIT(11) /* function defined with function x (vs x()) */
#define SPEC_BI BIT(12) /* a POSIX special builtin */ #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 * 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 * param should be repoted by set/typeset). Does not include ARRAY or