From ad2bd42c858aa7236e7b7404806d16b5b0efb6ac Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 23 Sep 2005 17:03:16 +0000 Subject: 21758: optimise =(<<<...) to run within the shell. --- Src/exec.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 13 deletions(-) (limited to 'Src/exec.c') diff --git a/Src/exec.c b/Src/exec.c index 95583d4e7..e77a04a53 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2941,33 +2941,50 @@ getherestr(struct redir *fn) return fd; } -/* $(...) */ +/* + * Test if some wordcode starts with a simple redirection of type + * redir_type. If it does, return the name of the file, copied onto + * the heap. If it doesn't, return NULL. + */ -/**/ -LinkList -getoutput(char *cmd, int qt) +static char * +simple_redir_name(Eprog prog, int redir_type) { - Eprog prog; - int pipes[2]; - pid_t pid; Wordcode pc; - if (!(prog = parse_string(cmd))) - return NULL; - pc = prog->prog; if (prog != &dummy_eprog && wc_code(pc[0]) == WC_LIST && (WC_LIST_TYPE(pc[0]) & Z_END) && wc_code(pc[1]) == WC_SUBLIST && !WC_SUBLIST_FLAGS(pc[1]) && WC_SUBLIST_TYPE(pc[1]) == WC_SUBLIST_END && wc_code(pc[2]) == WC_PIPE && WC_PIPE_TYPE(pc[2]) == WC_PIPE_END && - wc_code(pc[3]) == WC_REDIR && WC_REDIR_TYPE(pc[3]) == REDIR_READ && + wc_code(pc[3]) == WC_REDIR && WC_REDIR_TYPE(pc[3]) == redir_type && !WC_REDIR_VARID(pc[3]) && !pc[4] && wc_code(pc[6]) == WC_SIMPLE && !WC_SIMPLE_ARGC(pc[6])) { + return dupstring(ecrawstr(prog, pc + 5, NULL)); + } + + return NULL; +} + +/* $(...) */ + +/**/ +LinkList +getoutput(char *cmd, int qt) +{ + Eprog prog; + int pipes[2]; + pid_t pid; + char *s; + + if (!(prog = parse_string(cmd))) + return NULL; + + if ((s = simple_redir_name(prog, REDIR_READ))) { /* $(< word) */ int stream; - char *s = dupstring(ecrawstr(prog, pc + 5, NULL)); singsub(&s); if (errflag) @@ -3101,6 +3118,7 @@ getoutputfile(char *cmd) char *nam; Eprog prog; int fd; + char *s; if (thisjob == -1) return NULL; @@ -3109,13 +3127,36 @@ getoutputfile(char *cmd) if (!(nam = gettempname(NULL, 0))) return NULL; + if ((s = simple_redir_name(prog, REDIR_HERESTR))) { + /* + * =(<<