zsh-workers
 help / color / mirror / code / Atom feed
* $(nooutput) problem
@ 1996-05-28  9:18 Peter Stephenson
  1996-05-28 11:34 ` Zoltan Hidvegi
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Stephenson @ 1996-05-28  9:18 UTC (permalink / raw)
  To: Zsh hackers list

It seems care is needed: (1) if a command is not a simple one no
arguments may be necessary, so that having no arguments in execcmd()
is perfectly legal; (2) single word substitution needs to keeps its
arguments, for example the variable assignment code expects something
back from prefork(); (3) there's another bug/incompatibility (nearer
the latter than the former) resulting from the failure to delete empty
arguments:

% ksh -c 'cmd=; $cmd print foo'
foo
% zsh -fc 'cmd=; $cmd print foo'
zsh: permission denied: print

(which is certainly not the right answer in any case).

For these reasons I've fixed the problem by getting prefork() to junk
empty nodes if and only if it is not doing single word substitution,
and execcmd() to return if and only if it is a `simple' command with
no arguments.

*** Src/exec.c.empty	Fri May 17 16:25:20 1996
--- Src/exec.c	Tue May 28 10:35:36 1996
***************
*** 1200,1205 ****
--- 1200,1208 ----
      /* Do prefork substitutions */
      prefork(args, (((type == CCASE) ? 4 : 0) | (assign ? 2 : isset(MAGICEQUALSUBST))));
  
+     if (type == SIMPLE && empty(args))
+ 	return;
+ 
      /* Set up special parameter $_ */
      zsfree(underscore);
      if (nonempty(args) && (underscore = ztrdup((char *) getdata(lastnode(args)))))
*** Src/subst.c.empty	Tue May 28 10:34:04 1996
--- Src/subst.c	Tue May 28 10:41:15 1996
***************
*** 51,57 ****
  void
  prefork(LinkList list, int flags)
  {
!     LinkNode node;
  
      for (node = firstnode(list); node; incnode(node)) {
  	char *str, *str3;
--- 51,57 ----
  void
  prefork(LinkList list, int flags)
  {
!     LinkNode node, next;
  
      for (node = firstnode(list); node; incnode(node)) {
  	char *str, *str3;
***************
*** 69,77 ****
  	else if (!(node = stringsubst(list, node, flags & 4)))
  	    return;
      }
!     for (node = firstnode(list); node; incnode(node)) {
  	if (*(char *)getdata(node))
  	    remnulargs(getdata(node));
  	if (unset(IGNOREBRACES) && !(flags & 4))
  	    while (hasbraces(getdata(node)))
  		xpandbraces(list, &node);
--- 69,82 ----
  	else if (!(node = stringsubst(list, node, flags & 4)))
  	    return;
      }
!     for (node = firstnode(list); node; node = next) {
! 	next = nextnode(node);
  	if (*(char *)getdata(node))
  	    remnulargs(getdata(node));
+ 	else if (!(flags & 4)) {
+ 	    uremnode(list, node);
+ 	    continue;
+ 	}
  	if (unset(IGNOREBRACES) && !(flags & 4))
  	    while (hasbraces(getdata(node)))
  		xpandbraces(list, &node);


-- 
Peter Stephenson <pws@ifh.de>       Tel: +49 33762 77366
WWW:  http://www.ifh.de/~pws/       Fax: +49 33762 77330
Deutches Electronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen
DESY-IfH, 15735 Zeuthen, Germany.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: $(nooutput) problem
  1996-05-28  9:18 $(nooutput) problem Peter Stephenson
@ 1996-05-28 11:34 ` Zoltan Hidvegi
  1996-05-30 16:58   ` execcmd() reordering Peter Stephenson
  0 siblings, 1 reply; 15+ messages in thread
From: Zoltan Hidvegi @ 1996-05-28 11:34 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

> It seems care is needed: (1) if a command is not a simple one no
> arguments may be necessary, so that having no arguments in execcmd()
> is perfectly legal; (2) single word substitution needs to keeps its
> arguments, for example the variable assignment code expects something
> back from prefork(); (3) there's another bug/incompatibility (nearer
> the latter than the former) resulting from the failure to delete empty
> arguments:
> 
> % ksh -c 'cmd=; $cmd print foo'
> foo
> % zsh -fc 'cmd=; $cmd print foo'
> zsh: permission denied: print
> 
> (which is certainly not the right answer in any case).
> 
> For these reasons I've fixed the problem by getting prefork() to junk
> empty nodes if and only if it is not doing single word substitution,
> and execcmd() to return if and only if it is a `simple' command with
> no arguments.

I'm thinking about a different solution.  The problem is more complicated
since if one write foo* and there is no file beginning with foo and
nullglob is set globlist() will produce empty args.  I think globlist
should be move before fork().  Probably it should be executed right after
prefork.  fixcline may come right after that.  In execcmd there is a test
for empty(args).  This should be moved after prefork/globlist/fixcline.

Also I think that command, exec, noglob, nocorrect and - should be removed
from reswdtab and the related code should be removed from parse.c, and
these should be handled in execcmd.  This would enable to do things like

FOO=exec ; $FOO something

which whould improve sh compatibility.  In bash and ksh exec is a builtin
so it can be disabled or a function called exec can be defined.  This may
be implemented is zsh as well.  Unfortunately I do not fully understand
exec.c so it may take a while for me unless someone else wiser than me
makes these changes.

Zoltan



^ permalink raw reply	[flat|nested] 15+ messages in thread

* execcmd() reordering
  1996-05-28 11:34 ` Zoltan Hidvegi
@ 1996-05-30 16:58   ` Peter Stephenson
  1996-05-30 18:00     ` Zoltan Hidvegi
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Stephenson @ 1996-05-30 16:58 UTC (permalink / raw)
  To: Zsh hackers list

hzoli@cs.elte.hu wrote about problem with command lines expanding to nothing:
> The problem is more complicated
> since if one write foo* and there is no file beginning with foo and
> nullglob is set globlist() will produce empty args.  I think globlist
> should be move before fork().  Probably it should be executed right after
> prefork.  fixcline may come right after that.  In execcmd there is a test
> for empty(args).  This should be moved after prefork/globlist/fixcline.
> 
> Also I think that command, exec, noglob, nocorrect and - should be removed
> from reswdtab and the related code should be removed from parse.c, and
> these should be handled in execcmd.  This would enable to do things like
> 
> FOO=exec ; $FOO something
> 
> which whould improve sh compatibility.

Here's a biggish patch which does that.  I've listed the features of
the change below, in some detail since there are a few
incompatibilities which seem to be minor enough not to cause me any
loss of sleep.  (With a bit of luck, even Bart won't have to change
anything :-)).

WARNING: execcmd() is the center of the whole shooting match.  I
simply can't guarantee that changing things around in it won't have
some unexpected effect (read the following and you'll see what I
mean), though I think I've caught the obvious ones.  Please try this
out if you get a chance.  (It took me half an hour to realise I'd
broken nullexecs, it's that sort of piece of code.)

1) exec, noglob, - and command are treated more like commands; they can
appear from substitution, though not globbing (which would be stupid).
I've hijacked the last1 variable to tell execcmd() if it's the last
command in a pipeline: if it isn't, any exec flag gets ignored.  This
corresponds to the old behaviour implemented in parse.c (exactly, even
up to disallowing `exec >foo' in previous pipeline stages).

2) Now `nocorrect' must appear before any of the above.  Logical,
perhaps, considering that it is applied while the line is still being
parsed, but a change from before when you could say `noglob nocorrect'.

3) Also, variable assignment must appear before exec and friends.
Again, this is natural and is required in other Bourne shell clones.
Unfortunately there was a bug in old versions of the shell that you
couldn't use variable assignment *before* exec, and there was a
workaround that you could put it after.  This now won't work.  This is
probably the most noticeable incompatibility for people with legacy
software problems.

4) $(command-producing-no-output) bugs fixed, also
`blank=; $blank print foo' correctly calls the print builtin.
This patch therefore replaces the previous fix for this.

5) `noglob typeset foo=~/file' do not do tilde expansion without
    ^^^^^^ ^^^^^^
     etc.   etc.
magic_glob_subst set.  Other shells are more generous about when the
`=~' sequence is expanded anyway.  Maybe we should change.  Even
magic_equal_subst is fairly sparing about when to expand:  it insists
on the text before the = consisting only of characters which appear in
identifiers, something I wrote but now rather regret.

6) globbing is expanded before the fork.  Other than getting the
prompt back an iota later when running background commands, I don't
see this is a big deal.  One thing which seems to be a plus is that
failures to match are now handled synchronously for background
commands:

% unsetopt nonomatch
% ls Foo*Bar &
zsh: no matches found: Foo*Bar

instead of something like:

% ls Foo*Bar &
[1] 7621
% zsh: no matches found: Foo*Bar
% 

7) The command line is checked after expansion (but again before
globbing which didn't seem appropriate here) for things like
redirection with no command, implicit fg's and autoresume.  rm *
checks and autocd already behaved this way.

I suppose you might think the restriction that you can't autoresume a
command in the current directory with ./a*, or whatever, somewhat
arbitrary.  This can still be reordered if it's wanted.  The main
point is that the check for AUTORESUME comes most logically after the
one for %something, and that shouldn't be globbed.

Note, however, that globbing of redirs happens elsewhere, so you have
always been able to do `exec <INP*'.  What you can't do is something
like `exec *(N) <foo' where * expands to nothing and expect stdin to
change.

8)  fixcline() got moved up. This means things in the command line which
expand to nothing are removed (if completely blank), or untokenised
(if something like '') earlier.  The only consequent changes are that
for AUTOCD the word mustn't be completely blank, since
otherwise "$nonexistent" would have caused cd to home, which is a
little counterintuitive.  Also, `[' doesn't need specially
untokenising any more --- this must be a sign we're Doing the Right Thing.

9) (Scraping the bottom of the barrel here):
  addvar=varname $nonexistent
previously did an autocd to home, now does nothing at all:  that's
because the empty variable hasn't yet been removed from the command
line, so it doesn't know there is no command.  I think this is reasonable;
otherwise there would be what is essentially a syntactic change
depending on whether or not $nonexistent is set.

10) Technical, supposedly-user-transparent things
  (i)   I had to retain CFLAG_EXEC and hence the flags element of struct
        cmd since it appears once outside execcmd(), in execcursh()
        to determine if a current shell procedure is being exec'd
        and hence doesn't need to return.  It would be nicer to get rid
        of this altogether.
  (ii)  I wrapped a few overlong lines in the first half of exec.c.
  (iii) The test
  	 while (nonempty(args) && (s = (char *) peekfirst(args)) && !*s)
  	     ugetnode(args);
        after the fork is now unnecessary and has been removed.
  (iv)  The new tests for `command', `exec', etc., are just simple
        strcmp's.  It really didn't seem worth doing anything fancy
        for four short strings.
  (v)   In fact, globlist() doesn't appear *immediately* after prefork():
        I've noted above things for which this seems inappropriate.
  (vi)  I haven't looked at where the following unexpected (by me,
        that is) behaviour comes from:
          % NoSuchCom*(N)
          zsh: command not found: NoSuchCom*
        (I would have expected it just to disappear.)
  (vii) I get extra brownie points for doing this the week before the
        annual lattice field theory conference where I'm giving a
        talk.  Please don't tell my collaborators :-).

*** Src/exec.c.words	Thu May 30 15:45:12 1996
--- Src/exec.c	Thu May 30 17:49:09 1996
***************
*** 561,567 ****
   * that is about to exit, so we can exec instead of forking.  It gets *
   * passed all the way down to execcmd() which actually makes the      *
   * decision.  A 0 is always passed if the command is not the last in  *
!  * the pipeline.  This function assumes that the sublist is not NULL. */
  
  /**/
  int
--- 561,570 ----
   * that is about to exit, so we can exec instead of forking.  It gets *
   * passed all the way down to execcmd() which actually makes the      *
   * decision.  A 0 is always passed if the command is not the last in  *
!  * the pipeline.  This function assumes that the sublist is not NULL. *
!  * If last1 is zero but the command is at the end of a pipeline, we   *
!  * pass 2 down to execcmd().                                          *
!  */
  
  /**/
  int
***************
*** 759,765 ****
      if (pline_level == 1)
  	strcpy(list_pipe_text, getjobtext((void *) pline->left));
      if (pline->type == END) {
! 	execcmd(pline->left, input, output, how, last1);
  	pline->left = NULL;
      } else {
  	int old_list_pipe = list_pipe;
--- 762,768 ----
      if (pline_level == 1)
  	strcpy(list_pipe_text, getjobtext((void *) pline->left));
      if (pline->type == END) {
! 	execcmd(pline->left, input, output, how, last1 ? 1 : 2);
  	pline->left = NULL;
      } else {
  	int old_list_pipe = list_pipe;
***************
*** 1108,1113 ****
--- 1111,1118 ----
      int fil, is_cursh, type, i;
      int nullexec = 0, assign = 0, forked = 0;
      int is_shfunc = 0, is_builtin = 0;
+     /* Various flags to the command. */
+     int cf_command = 0, cf_noglob = 0, cf_dash = 0;
  
      doneps4 = 0;
      args = cmd->args;
***************
*** 1118,1123 ****
--- 1123,1178 ----
  	mfds[i] = NULL;
      }
  
+     /* Check if it's a builtin needing automatic MAGIC_EQUALS_SUBST      *
+      * handling.  Things like typeset need this.  We can't detect the    *
+      * command if it contains some tokens (e.g. x=ex; ${x}port), so this *
+      * only works in simple cases.  has_token() is called to make sure   *
+      * this really is a simple case.
+      *
+      * This is now even simpler, since the case `noglob typeset' is
+      * not handled.
+      */
+     if(type == SIMPLE && nonempty(args)) {
+ 	char *cmdarg = (char *) peekfirst(args);
+ 
+ 	if(!has_token(cmdarg) && !shfunctab->getnode(shfunctab, cmdarg)) {
+ 	    HashNode hn2 = NULL;
+ 	    LinkNode ln = args->first;
+ 
+ 	    while((hn2 = builtintab->getnode(builtintab, (char *) ln->dat)) &&
+ 	        ((Builtin) hn2)->funcid == BIN_BUILTIN &&
+ 		(ln = ln->next) && !has_token((char *) ln->dat));
+ 	    if(hn2)
+ 		assign = (hn2->flags & BINF_MAGICEQUALS);
+ 	}
+     }
+ 
+     /* Do prefork substitutions */
+     prefork(args, (((type == CCASE) ? 4 : 0)
+ 		   | (assign ? 2 : isset(MAGICEQUALSUBST))));
+ 
+     /* Look for pre-command strings: -, exec, command, noglob. */
+     while (nonempty(args)) {
+ 	char *farg = (char *)peekfirst(args);
+ 
+ 	if (*farg == '-' && farg[1] == '\0')
+ 	    cf_dash = 1;
+ 	else if (!strcmp(farg, "exec")) {
+ 	    /* Current shell should not fork unless the
+ 	     * exec occurs at the end of a pipeline.
+ 	     */
+ 	    if (last1 == 2)
+ 		cmd->flags |= CFLAG_EXEC;
+ 	} else if (!strcmp(farg, "command"))
+ 	    cf_command = 1;
+ 	else if (!strcmp(farg, "noglob"))
+ 	    cf_noglob = 1;
+ 	else
+ 	    break;
+ 
+ 	firstnode(args) = nextnode(firstnode(args));
+     }
+ 
      /* Empty command */
      if (type == SIMPLE && empty(args)) {
  	if (nonempty(cmd->redir)) {
***************
*** 1153,1159 ****
      /* If the command begins with `%', then assume it is a *
       * reference to a job in the job table.                */
      if (nonempty(args) && *(char *)peekfirst(args) == '%') {
! 	pushnode(args, dupstring((how & Z_DISOWN) ? "disown" : (how & Z_ASYNC) ? "bg" : "fg"));
  	how = Z_SYNC;
      }
  
--- 1208,1215 ----
      /* If the command begins with `%', then assume it is a *
       * reference to a job in the job table.                */
      if (nonempty(args) && *(char *)peekfirst(args) == '%') {
! 	pushnode(args, dupstring((how & Z_DISOWN)
! 				 ? "disown" : (how & Z_ASYNC) ? "bg" : "fg"));
  	how = Z_SYNC;
      }
  
***************
*** 1176,1216 ****
      else
  	text = NULL;
  
-     /* Check if it's a builtin needing automatic MAGIC_EQUALS_SUBST      *
-      * handling.  Things like typeset need this.  We can't detect the    *
-      * command if it contains some tokens (e.g. x=ex; ${x}port), so this *
-      * only works in simple cases.  has_token() is called to make sure   *
-      * this really is a simple case.                                     */
-     if(type == SIMPLE && nonempty(args)) {
- 	char *cmdarg = (char *) peekfirst(args);
- 
- 	if(!has_token(cmdarg) && !(cmd->flags & CFLAG_COMMAND)
- 	    && !shfunctab->getnode(shfunctab, cmdarg)) {
- 	    HashNode hn2 = NULL;
- 	    LinkNode ln = args->first;
- 
- 	    while((hn2 = builtintab->getnode(builtintab, (char *) ln->dat)) &&
- 	        ((Builtin) hn2)->funcid == BIN_BUILTIN &&
- 		(ln = ln->next) && !has_token((char *) ln->dat));
- 	    if(hn2)
- 		assign = (hn2->flags & BINF_MAGICEQUALS);
- 	}
-     }
- 
-     /* Do prefork substitutions */
-     prefork(args, (((type == CCASE) ? 4 : 0) | (assign ? 2 : isset(MAGICEQUALSUBST))));
- 
      /* Set up special parameter $_ */
      zsfree(underscore);
!     if (nonempty(args) && (underscore = ztrdup((char *) getdata(lastnode(args)))))
  	untokenize(underscore); 
      else
    	underscore = ztrdup("");
  
      /* Warn about "rm *" */
!     if (type == SIMPLE && interact && unset(RMSTARSILENT) && isset(SHINSTDIN) &&
! 	nonempty(args) && nextnode(firstnode(args)) && !strcmp(peekfirst(args), "rm") &&
! 	!(cmd->flags & CFLAG_NOGLOB)) {
  	LinkNode node, next;
  
  	for (node = nextnode(firstnode(args)); node && !errflag; node = next) {
--- 1232,1249 ----
      else
  	text = NULL;
  
      /* Set up special parameter $_ */
      zsfree(underscore);
!     if (nonempty(args)
! 	&& (underscore = ztrdup((char *) getdata(lastnode(args)))))
  	untokenize(underscore); 
      else
    	underscore = ztrdup("");
  
      /* Warn about "rm *" */
!     if (type == SIMPLE && interact && unset(RMSTARSILENT)
! 	&& isset(SHINSTDIN) && nonempty(args) && nextnode(firstnode(args))
! 	&& !strcmp(peekfirst(args), "rm") && !cf_noglob) {
  	LinkNode node, next;
  
  	for (node = nextnode(firstnode(args)); node && !errflag; node = next) {
***************
*** 1234,1282 ****
  	    errflag = 1;
      }
  
      if (errflag) {
  	lastval = 1;
  	return;
      }
  
      /* Resolve simple commands */
!     if (type == SIMPLE && nonempty(args)) {
! 	char *cmdarg, *s;
  
! 	/* Get argument in command position */
! 	cmdarg = (char *) peekfirst(args);
  
! 	/* If the command is `[' then we must untokenize it */
! 	if (cmdarg[0] == Inbrack && cmdarg[1] == '\0')
! 	    cmdarg[0] = '[';
! 
! 	/* Resolve shell functions and builtins */
! 	if (!(cmd->flags & CFLAG_COMMAND)) {
! 	    if ((hn = shfunctab->getnode(shfunctab, cmdarg))) {
! 		is_shfunc = 1;
! 	    } else if ((hn = builtintab->getnode(builtintab, cmdarg))) {
! 		is_builtin = 1;
  	    }
- 	}
  
! 	/* Resolve external commands */
! 	if (!hn) {
! 	    hn = cmdnamtab->getnode(cmdnamtab, cmdarg);
! 	    if (!hn && isset(HASHCMDS) && strcmp(cmdarg, "..")) {
! 		for (s = cmdarg; *s && *s != '/'; s++);
! 		if (!*s)
! 		    hn = (HashNode) hashcmd(cmdarg, pathchecked);
  	    }
- 	}
  
! 	/* If no command found yet, see if it is *
! 	 * a directory we should AUTOCD to.      */
! 	if (!hn && isset(AUTOCD) && isset(SHINSTDIN) && empty(cmd->redir)
! 	    && !nextnode(firstnode(args)) && (s = cancd(peekfirst(args)))) {
! 	    peekfirst(args) = (void *) s;
! 	    pushnode(args, dupstring("cd"));
! 	    if ((hn = builtintab->getnode(builtintab, "cd")))
! 		is_builtin = 1;
  	}
      }
  
--- 1267,1320 ----
  	    errflag = 1;
      }
  
+     if (!cf_noglob && !errflag)
+ 	globlist(args);
+ 
      if (errflag) {
  	lastval = 1;
  	return;
      }
+     fixcline(args);
  
      /* Resolve simple commands */
!     if (type == SIMPLE && !nullexec) {
! 	if (empty(args))
! 	    return;
! 	else {
! 	    char *cmdarg, *s;
  
! 	    /* Get argument in command position */
! 	    cmdarg = (char *) peekfirst(args);
  
! 	    /* Resolve shell functions and builtins */
! 	    if (!cf_command) {
! 		if ((hn = shfunctab->getnode(shfunctab, cmdarg))) {
! 		    is_shfunc = 1;
! 		} else if ((hn = builtintab->getnode(builtintab, cmdarg))) {
! 		    is_builtin = 1;
! 		}
  	    }
  
! 	    /* Resolve external commands */
! 	    if (!hn) {
! 		hn = cmdnamtab->getnode(cmdnamtab, cmdarg);
! 		if (!hn && isset(HASHCMDS) && strcmp(cmdarg, "..")) {
! 		    for (s = cmdarg; *s && *s != '/'; s++);
! 		    if (!*s)
! 			hn = (HashNode) hashcmd(cmdarg, pathchecked);
! 		}
  	    }
  
! 	    /* If no command found yet, see if it is *
! 	     * a directory we should AUTOCD to.      */
! 	    if (!hn && isset(AUTOCD) && isset(SHINSTDIN) && empty(cmd->redir)
! 		&& !nextnode(firstnode(args)) && *(char *)peekfirst(args)
! 		&& (s = cancd(peekfirst(args)))) {
! 		peekfirst(args) = (void *) s;
! 		pushnode(args, dupstring("cd"));
! 		if ((hn = builtintab->getnode(builtintab, "cd")))
! 		    is_builtin = 1;
! 	    }
  	}
      }
  
***************
*** 1291,1297 ****
       *    b) This is an external command and we can't do a `fake exec'.       *
       *                                                                        *
       * A `fake exec' is possible if we have all the following conditions:     *
!      * 1) last1 flag is set.  This indicates that the current shell will not  *
       *    be needed after the current command.  This is typically the case    *
       *    when when the command is the last stage in a subshell, or is the    *
       *    last command after the option `-c'.                                 *
--- 1329,1335 ----
       *    b) This is an external command and we can't do a `fake exec'.       *
       *                                                                        *
       * A `fake exec' is possible if we have all the following conditions:     *
!      * 1) last1 flag is 1.  This indicates that the current shell will not    *
       *    be needed after the current command.  This is typically the case    *
       *    when when the command is the last stage in a subshell, or is the    *
       *    last command after the option `-c'.                                 *
***************
*** 1306,1312 ****
  
      if ((how & Z_ASYNC) || (!(cmd->flags & CFLAG_EXEC) &&
         (((is_builtin || is_shfunc) && output) ||
!        (!is_cursh && (!last1 || sigtrapped[SIGZERR] ||
          sigtrapped[SIGEXIT] || havefiles()))))) {
  
  	pid_t pid;
--- 1344,1350 ----
  
      if ((how & Z_ASYNC) || (!(cmd->flags & CFLAG_EXEC) &&
         (((is_builtin || is_shfunc) && output) ||
!        (!is_cursh && (last1 != 1 || sigtrapped[SIGZERR] ||
          sigtrapped[SIGEXIT] || havefiles()))))) {
  
  	pid_t pid;
***************
*** 1363,1381 ****
  	entersubsh(how, 1, 1);
      }
  
-     if (!(cmd->flags & CFLAG_NOGLOB))
- 	globlist(args);
- 
-     if (errflag) {
- 	lastval = 1;
- 	goto err;
-     } else {
- 	char *s;
- 
- 	while (nonempty(args) && (s = (char *) peekfirst(args)) && !*s)
- 	    ugetnode(args);
-     }
- 
      /* Add pipeline input/output to mnodes */
      if (input)
  	addfd(forked, save, mfds, 0, input, 0);
--- 1401,1406 ----
***************
*** 1496,1502 ****
  		execcursh, exectime, execfuncdef, execfor, execwhile,
  		execrepeat, execif, execcase, execselect, execcond};
  
- 	    fixcline(args);
  	    lastval = (func[type - CURSH]) (cmd);
  	} else if (is_builtin || is_shfunc) {
  	    /* builtin or shell function */
--- 1521,1526 ----
***************
*** 1517,1523 ****
  		    return;
  		}
  	    }
- 	    fixcline(args);
  
  	    if (is_shfunc) {
  		/* It's a shell function */
--- 1541,1546 ----
***************
*** 1591,1609 ****
  	    }
  	    if (type == SIMPLE) {
  		closem(1);
! 		execute((Cmdnam) hn, cmd->flags & CFLAG_DASH);
  	    } else {		/* ( ... ) */
  		list_pipe = 0;
  		if (subsh_close >= 0)
  		    zclose(subsh_close);
                  subsh_close = -1;
  		/* If we're forked (and we should be), no need to return */
! 		execlist(cmd->u.list, 0, last1 || forked);
  	    }
  	}
      }
  
-   err:
      if (forked)
  	_exit(lastval);
      fixfds(save);
--- 1614,1631 ----
  	    }
  	    if (type == SIMPLE) {
  		closem(1);
! 		execute((Cmdnam) hn, cf_dash);
  	    } else {		/* ( ... ) */
  		list_pipe = 0;
  		if (subsh_close >= 0)
  		    zclose(subsh_close);
                  subsh_close = -1;
  		/* If we're forked (and we should be), no need to return */
! 		execlist(cmd->u.list, 0, (last1 == 1) || forked);
  	    }
  	}
      }
  
      if (forked)
  	_exit(lastval);
      fixfds(save);
*** Src/hashtable.h.words	Thu May 30 16:00:30 1996
--- Src/hashtable.h	Thu May 30 16:01:32 1996
***************
*** 34,42 ****
  #ifdef GLOBALS
  struct reswd reswds[] =
  {
-     {NULL, "-", 0, DASH},
      {NULL, "case", 0, CASE},
-     {NULL, "command", 0, COMMAND},
      {NULL, "coproc", 0, COPROC},
      {NULL, "do", 0, DO},
      {NULL, "done", 0, DONE},
--- 34,40 ----
***************
*** 44,57 ****
      {NULL, "else", 0, ELSE},
      {NULL, "end", 0, ZEND},
      {NULL, "esac", 0, ESAC},
-     {NULL, "exec", 0, EXEC},
      {NULL, "fi", 0, FI},
      {NULL, "for", 0, FOR},
      {NULL, "foreach", 0, FOREACH},
      {NULL, "function", 0, FUNC},
      {NULL, "if", 0, IF},
      {NULL, "nocorrect", 0, NOCORRECT},
-     {NULL, "noglob", 0, NOGLOB},
      {NULL, "repeat", 0, REPEAT},
      {NULL, "select", 0, SELECT},
      {NULL, "then", 0, THEN},
--- 42,53 ----
*** Src/parse.c.words	Thu May 30 15:57:06 1996
--- Src/parse.c	Thu May 30 16:04:48 1996
***************
*** 255,261 ****
      if (!(c = par_cmd()))
  	return NULL;
      if (tok == BAR) {
- 	c->flags &= ~CFLAG_EXEC;
  	cmdpush(CS_PIPE);
  	yylex();
  	while (tok == SEPER)
--- 255,260 ----
***************
*** 270,276 ****
      } else if (tok == BARAMP) {
  	struct redir *rdr = (struct redir *)allocnode(N_REDIR);
  
- 	c->flags &= ~CFLAG_EXEC;
  	rdr->type = MERGEOUT;
  	rdr->fd1 = 2;
  	rdr->fd2 = 1;
--- 269,274 ----
***************
*** 903,918 ****
  
      c->type = SIMPLE;
      for (;;) {
! 	if (tok == COMMAND)
! 	    c->flags |= CFLAG_COMMAND;
! 	else if (tok == EXEC)
! 	    c->flags |= CFLAG_EXEC;
! 	else if (tok == NOGLOB)
! 	    c->flags |= CFLAG_NOGLOB;
! 	else if (tok == NOCORRECT)
  	    nocorrect = 1;
- 	else if (tok == DASH)
- 	    c->flags |= CFLAG_DASH;
  	else if (tok == ENVSTRING) {
  	    struct varasg *v = (struct varasg *)make_varnode();
  
--- 901,908 ----
  
      c->type = SIMPLE;
      for (;;) {
! 	if (tok == NOCORRECT)
  	    nocorrect = 1;
  	else if (tok == ENVSTRING) {
  	    struct varasg *v = (struct varasg *)make_varnode();
  
*** Src/text.c.words	Mon May  6 16:08:59 1996
--- Src/text.c	Thu May 30 15:57:42 1996
***************
*** 198,211 ****
  	break;
      case N_CMD:
  	nn = _Cmd(n);
- 	if (nn->flags & CFLAG_EXEC)
- 	    taddstr("exec ");
- 	if (nn->flags & CFLAG_COMMAND)
- 	    taddstr("command ");
- 	if (nn->flags & CFLAG_NOGLOB)
- 	    taddstr("noglob ");
- 	if (nn->flags & CFLAG_DASH)
- 	    taddstr("- ");
  	switch (nn->type) {
  	case SIMPLE:
  	    getsimptext(nn);
--- 198,203 ----
*** Src/zsh.h.words	Thu May 30 16:00:33 1996
--- Src/zsh.h	Thu May 30 16:04:24 1996
***************
*** 129,158 ****
  #define AMPERBANG      38
  
  /* Tokens for reserved words */
- #define DASH           39	/* -         */
  #define CASE           40	/* case      */
! #define COMMAND        41	/* command   */
! #define COPROC         42	/* coproc    */
! #define DO             43	/* do        */
! #define DONE           44	/* done      */
! #define ELIF           45	/* elif      */
! #define ELSE           46	/* else      */
! #define ZEND           47	/* end       */
! #define ESAC           48	/* esac      */
! #define EXEC           49	/* exec      */
! #define FI             50	/* fi        */
! #define FOR            51	/* for       */
! #define FOREACH        52	/* foreach   */
! #define FUNC           53	/* function  */
! #define IF             54	/* if        */
! #define NOCORRECT      55	/* nocorrect */
! #define NOGLOB         56	/* noglob    */
! #define REPEAT         57	/* repeat    */
! #define SELECT         58	/* select    */
! #define THEN           59	/* then      */
! #define TIME           60	/* time      */
! #define UNTIL          61	/* until     */
! #define WHILE          62	/* while     */
  
  #define WRITE           0
  #define WRITENOW        1
--- 129,154 ----
  #define AMPERBANG      38
  
  /* Tokens for reserved words */
  #define CASE           40	/* case      */
! #define COPROC         41	/* coproc    */
! #define DO             42	/* do        */
! #define DONE           43	/* done      */
! #define ELIF           44	/* elif      */
! #define ELSE           45	/* else      */
! #define ZEND           46	/* end       */
! #define ESAC           47	/* esac      */
! #define FI             48	/* fi        */
! #define FOR            49	/* for       */
! #define FOREACH        50	/* foreach   */
! #define FUNC           51	/* function  */
! #define IF             52	/* if        */
! #define NOCORRECT      53	/* nocorrect */
! #define REPEAT         54	/* repeat    */
! #define SELECT         55	/* select    */
! #define THEN           56	/* then      */
! #define TIME           57	/* time      */
! #define UNTIL          58	/* until     */
! #define WHILE          59	/* while     */
  
  #define WRITE           0
  #define WRITENOW        1
***************
*** 396,404 ****
  
  /* flags for command modifiers */
  #define CFLAG_EXEC	(1<<0)	/* exec ...    */
- #define CFLAG_COMMAND	(1<<1)	/* command ... */
- #define CFLAG_NOGLOB	(1<<2)	/* noglob ...  */
- #define CFLAG_DASH	(1<<3)	/* - ...       */
  
  /* tree element for redirection lists */
  
--- 392,397 ----

-- 
Peter Stephenson <pws@ifh.de>       Tel: +49 33762 77366
WWW:  http://www.ifh.de/~pws/       Fax: +49 33762 77330
Deutches Electronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen
DESY-IfH, 15735 Zeuthen, Germany.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-30 16:58   ` execcmd() reordering Peter Stephenson
@ 1996-05-30 18:00     ` Zoltan Hidvegi
  1996-05-30 18:26       ` Barton E. Schaefer
  1996-05-30 18:41       ` Zoltan Hidvegi
  0 siblings, 2 replies; 15+ messages in thread
From: Zoltan Hidvegi @ 1996-05-30 18:00 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

> 1) exec, noglob, - and command are treated more like commands; they can
> appear from substitution, though not globbing (which would be stupid).

Yes stupid, but that's how other shells behave.  But since noglob must be
detected before globlist() that's the best we can do.

> 6) globbing is expanded before the fork.  Other than getting the
> prompt back an iota later when running background commands, I don't
> see this is a big deal.  One thing which seems to be a plus is that
> failures to match are now handled synchronously for background
> commands:

Also it makes debugging much easier.  Now prefork is really a historic
name.  There used to be prefork and postfork and a lot of substitutions had
been done in the later.

> 8)  fixcline() got moved up. This means things in the command line which
> expand to nothing are removed (if completely blank), or untokenised
> (if something like '') earlier.  The only consequent changes are that
> for AUTOCD the word mustn't be completely blank, since
> otherwise "$nonexistent" would have caused cd to home, which is a
> little counterintuitive.  Also, `[' doesn't need specially
> untokenising any more --- this must be a sign we're Doing the Right Thing.

Also makecline can be simplified after that patch.

>   (iv)  The new tests for `command', `exec', etc., are just simple
>         strcmp's.  It really didn't seem worth doing anything fancy
>         for four short strings.

I was thinking about adding these into builtintab with some new BINF_
flags: e.g. all of these would have BINF_PREFIX and there would be one more
BINF_ flag for each.  This would improve sh compatibility.  Hopefully a
hash-table lookup is not slower than these strcmps.  If something is found
with BINF_PREFIX shfunctab may be searched which may override builtintab
similarily to ksh.

Zoltan



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-30 18:00     ` Zoltan Hidvegi
@ 1996-05-30 18:26       ` Barton E. Schaefer
  1996-05-30 18:46         ` Zoltan Hidvegi
  1996-05-30 18:41       ` Zoltan Hidvegi
  1 sibling, 1 reply; 15+ messages in thread
From: Barton E. Schaefer @ 1996-05-30 18:26 UTC (permalink / raw)
  To: Zoltan Hidvegi, Peter Stephenson, zsh-workers

On May 30,  8:00pm, Zoltan Hidvegi wrote:
} Subject: Re: execcmd() reordering
}
} > 6) globbing is expanded before the fork.  Other than getting the
} > prompt back an iota later when running background commands, I don't
} > see this is a big deal.  One thing which seems to be a plus is that
} > failures to match are now handled synchronously for background
} > commands:
} 
} Also it makes debugging much easier.  Now prefork is really a historic
} name.  There used to be prefork and postfork and a lot of substitutions had
} been done in the later.

Hmm; Is this going to cause a problem with stuff like:

zsh% (sleep 1 ; touch brandnewfile;) & (sleep 3; echo brand*;) &

-- 
Bart Schaefer                     Vice President, Technology, Z-Code Software
schaefer@z-code.com                  Division of NCD Software Corporation
http://www.well.com/www/barts           http://www.ncdsoft.com/ZMail/



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-30 18:00     ` Zoltan Hidvegi
  1996-05-30 18:26       ` Barton E. Schaefer
@ 1996-05-30 18:41       ` Zoltan Hidvegi
  1 sibling, 0 replies; 15+ messages in thread
From: Zoltan Hidvegi @ 1996-05-30 18:41 UTC (permalink / raw)
  To: Zoltan Hidvegi; +Cc: pws, zsh-workers

[-- Attachment #1: Type: application/pgp, Size: 2632 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-30 18:26       ` Barton E. Schaefer
@ 1996-05-30 18:46         ` Zoltan Hidvegi
  0 siblings, 0 replies; 15+ messages in thread
From: Zoltan Hidvegi @ 1996-05-30 18:46 UTC (permalink / raw)
  To: schaefer; +Cc: Zsh workers list

> Hmm; Is this going to cause a problem with stuff like:
> 
> zsh% (sleep 1 ; touch brandnewfile;) & (sleep 3; echo brand*;) &

No, it isn't.

Zoltan



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-31 11:58   ` Peter Stephenson
@ 1996-05-31 16:28     ` Bart Schaefer
  0 siblings, 0 replies; 15+ messages in thread
From: Bart Schaefer @ 1996-05-31 16:28 UTC (permalink / raw)
  To: Peter Stephenson, Zoltan Hidvegi, Duncan Sinclair, Zsh hackers list

On May 31, 12:55pm, Zoltan Hidvegi wrote:
} Subject: Re: execcmd() reordering
}
} > Oh, absolutely!  Does this change mean I can't interrupt long globs???
} > This would be terrible - esp. if the glob goes into a loop.
} 
} Do not worry.  Zsh never forked for builtins and you were able to interrupt
} things like echo **/*.  This is not changed.

Well, it's changed a little:

zagzig% echo **/*		(wait a couple of seconds, ^C)
zsh: bad pattern: **/*

It didn't used to complain about the pattern.  (Beta 19 without the
ececcmd patch has the problem; I haven't tried the execcmd patch yet.)

} ^Z will not work for
} suspending external commands but other than that there should be no
} noticable change

That's a very noticeable change, to me.

} unless something is backgrounded.

And then what?

} ^Z never worked for builtins and shell functions

I know, and that has always annoyed me.

} and the number of arguments that can be passed
} to external commands is always limited by the OS (although on modern
} systems this limit is very high).

What does that have to do with anything?  Zsh is still going to finish
the entire glob.  Even a very small glob is pretty slow on a filesystem
that's NFS mounted over a PPP link (as a pathological example).

On May 31,  1:58pm, Peter Stephenson wrote:
} Subject: Re: execcmd() reordering
}
} I didn't realise the problem with backgrounding recursive globs
} before, since I've never tried it.  I can't think of a way round other
} than using a subshell.  Bummer.  (Interruption is definitely OK,
} though.)

What if globbing was always treated as if it were a command sub?  E.g.
implement

	echo **/*

as

	echo $(echo **/*)

You could even make this behavior an option, SPAWN_GLOBS or some such,
and have an extendedglob metacharacter to use it for individual globs.

Now you've got a process handling the glob, so that can be stopped and
started without messing up the parent shell ... zsh would then have to
do some magic with the job table so that it could stash a partially-
parsed command string along with the job entry.

If the job later is foregrounded again, the current shell restarts the
globjob and picks up the parsing where it left off.

Backgrounding is tougher.  It *could* fork, resume the globjob, and then
the new subshell would pick up the parse; but then the subshell would be
a sibling of the globjob and wouldn't get the exit status notification.
I'd be satisfied with an error about not being able to background the
glob, as long as I could stop it, do something else briefly, and then
pick up again where I left off (rather than having to interrupt and then
start over from scratch).

(Maybe doing it as a command sub works around the problem of not being
able to stop non-builtins?  Then we'd at least be no worse off than we
were before.  I don't know what effect this reordering has on all the
other kinds of substitutions.)

-- 
Bart Schaefer                             Brass Lantern Enterprises
http://www.well.com/user/barts            http://www.nbn.com/people/lantern

New male in /home/schaefer:
>N  2 Justin William Schaefer  Sat May 11 03:43  53/4040  "Happy Birthday"



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-30 19:52   ` Barton E. Schaefer
@ 1996-05-31 14:32     ` Hrvoje Niksic
  0 siblings, 0 replies; 15+ messages in thread
From: Hrvoje Niksic @ 1996-05-31 14:32 UTC (permalink / raw)
  To: zsh-workers

In your mail, you said:
> Furthermore, it'd be really nice to be able to stop (^Z) an unexpectedly
> huge glob and then "bg" it, or to interrupt it with ^C if I decide it was
> a mistake.

It would be a great feature, especially for huge globbings. I've needed it
very often.

-- 
hniksic@srce.hr              |  Student of electrical engineering
hniksic@fly.cc.fer.hr        |  University of Zagreb, Croatia
------------------------------------------------------------------
`VI' - An editor used by those heretics that don't subscribe to
       the Emacs religion.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
@ 1996-05-31 11:58   ` Peter Stephenson
  1996-05-31 16:28     ` Bart Schaefer
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Stephenson @ 1996-05-31 11:58 UTC (permalink / raw)
  To: Zsh hackers list

One extra simplification:  the special handling for wild cards in
cancd(), which handles autocd, can now be removed, since this now
happens after globbing.

I didn't realise the problem with backgrounding recursive globs
before, since I've never tried it.  I can't think of a way round other
than using a subshell.  Bummer.  (Interruption is definitely OK,
though.)

*** Src/exec.c.cancd	Fri May 31 09:36:00 1996
--- Src/exec.c	Fri May 31 10:51:52 1996
***************
*** 2470,2488 ****
      (s[1] == '/' || !s[1] || (s[1] == '.' && (s[2] == '/' || !s[1])));
      char *t;
  
-     if (haswilds(s)) {
- 	LinkList l = newlinklist();
- 	int ne = noerrs;
- 
- 	noerrs = 1;
- 	addlinknode(l, dupstring(s));
- 	globlist(l);
- 	if (!errflag && nonempty(l) && !nextnode(firstnode(l)))
- 	    s = peekfirst(l);
- 	errflag = 0;
- 	noerrs = ne;
-     }
- 
      if (*s != '/') {
  	char sbuf[PATH_MAX], **cp;
  
--- 2470,2475 ----

-- 
Peter Stephenson <pws@ifh.de>       Tel: +49 33762 77366
WWW:  http://www.ifh.de/~pws/       Fax: +49 33762 77330
Deutches Electronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen
DESY-IfH, 15735 Zeuthen, Germany.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-31 10:15 Duncan Sinclair
@ 1996-05-31 10:55 ` Zoltan Hidvegi
  1996-05-31 11:58   ` Peter Stephenson
  0 siblings, 1 reply; 15+ messages in thread
From: Zoltan Hidvegi @ 1996-05-31 10:55 UTC (permalink / raw)
  To: Duncan Sinclair; +Cc: schaefer, zsh-workers

> Oh, absolutely!  Does this change mean I can't interrupt long globs???
> This would be terrible - esp. if the glob goes into a loop.

Do not worry.  Zsh never forked for builtins and you were able to interrupt
things like echo **/*.  This is not changed.  ^Z will not work for
suspending external commands but other than that there should be no
noticable change unless something is backgrounded.  ^Z never worked for
builtins and shell functions and the number of arguments that can be passed
to external commands is always limited by the OS (although on modern
systems this limit is very high).

Zoltan



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
@ 1996-05-31 10:15 Duncan Sinclair
  1996-05-31 10:55 ` Zoltan Hidvegi
  0 siblings, 1 reply; 15+ messages in thread
From: Duncan Sinclair @ 1996-05-31 10:15 UTC (permalink / raw)
  To: schaefer; +Cc: Zoltan Hidvegi, zsh-workers


"Barton E. Schaefer" writes:
>On May 30,  9:10pm, Zoltan Hidvegi wrote:
>} Subject: Re: execcmd() reordering
>}
>} > When you've got a *huge* expansion which is 50% of the run-time
>} > of the command, I'd like to be able to get on with other things.
>} 
>} You can use (foo **/*) &
>
>I tend to agree with Duncan here, I'm afraid.  I may not have any idea
>how large a list the glob is going to expand into; it's ridiculous to
>expect me to subshell every command that might do a glob.
>
>Furthermore, it'd be really nice to be able to stop (^Z) an unexpectedly
>huge glob and then "bg" it, or to interrupt it with ^C if I decide it was
>a mistake.

Oh, absolutely!  Does this change mean I can't interrupt long globs???
This would be terrible - esp. if the glob goes into a loop.

All the other things, I can live with.  This gives me nightmares.

Bye for now,


Duncan.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-30 19:10 ` Zoltan Hidvegi
@ 1996-05-30 19:52   ` Barton E. Schaefer
  1996-05-31 14:32     ` Hrvoje Niksic
  0 siblings, 1 reply; 15+ messages in thread
From: Barton E. Schaefer @ 1996-05-30 19:52 UTC (permalink / raw)
  To: Zoltan Hidvegi, Duncan Sinclair, zsh-workers

On May 30,  9:10pm, Zoltan Hidvegi wrote:
} Subject: Re: execcmd() reordering
}
} > When you've got a *huge* expansion which is 50% of the run-time
} > of the command, I'd like to be able to get on with other things.
} 
} You can use (foo **/*) &

I tend to agree with Duncan here, I'm afraid.  I may not have any idea
how large a list the glob is going to expand into; it's ridiculous to
expect me to subshell every command that might do a glob.

Furthermore, it'd be really nice to be able to stop (^Z) an unexpectedly
huge glob and then "bg" it, or to interrupt it with ^C if I decide it was
a mistake.

-- 
Bart Schaefer                     Vice President, Technology, Z-Code Software
schaefer@z-code.com                  Division of NCD Software Corporation
http://www.well.com/www/barts           http://www.ncdsoft.com/ZMail/



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
  1996-05-30 18:05 Duncan Sinclair
@ 1996-05-30 19:10 ` Zoltan Hidvegi
  1996-05-30 19:52   ` Barton E. Schaefer
  0 siblings, 1 reply; 15+ messages in thread
From: Zoltan Hidvegi @ 1996-05-30 19:10 UTC (permalink / raw)
  To: Duncan Sinclair

> >2) Now `nocorrect' must appear before any of the above.
> 
> Why?

Because nocorrect must be handled in parse.c.  It cannot be moved into
exec.c since exec.c deals with parsed commands and nocorrect affects
parsing.

> There's a flag (-k, I think) which will allow the bourne shell to take
> variable assignments at any point of the command - does this work?

No.

> >magic_equal_subst is fairly sparing about when to expand:  it insists
> >on the text before the = consisting only of characters which appear in
> >identifiers, something I wrote but now rather regret.
> 
> Is this the stuff we argued about years ago?  I'm all for a change here.

I like the present behaviour of magic_equal_subst.  Could you tell me an
example when a less restrictive behaviour is desirable?

> >6) globbing is expanded before the fork.
> 
> I don't like this at all.
> 
> >Other than getting the
> >prompt back an iota later when running background commands, I don't
> >see this is a big deal.
> 
> When you've got a *huge* expansion which is 50% of the run-time
> of the command, I'd like to be able to get on with other things.
> 

You can use (foo **/*) &

Zoltan



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: execcmd() reordering
@ 1996-05-30 18:05 Duncan Sinclair
  1996-05-30 19:10 ` Zoltan Hidvegi
  0 siblings, 1 reply; 15+ messages in thread
From: Duncan Sinclair @ 1996-05-30 18:05 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list


Peter wrote about exec stuff:
>Here's a biggish patch which does that. ...

>2) Now `nocorrect' must appear before any of the above.

Why?

>3) Also, variable assignment must appear before exec and friends.
>Again, this is natural and is required in other Bourne shell clones.

There's a flag (-k, I think) which will allow the bourne shell to take
variable assignments at any point of the command - does this work?

>5) `noglob typeset foo=~/file' do not do tilde expansion without...

>Maybe we should change.  Even
>magic_equal_subst is fairly sparing about when to expand:  it insists
>on the text before the = consisting only of characters which appear in
>identifiers, something I wrote but now rather regret.

Is this the stuff we argued about years ago?  I'm all for a change here.

>6) globbing is expanded before the fork.

I don't like this at all.

>Other than getting the
>prompt back an iota later when running background commands, I don't
>see this is a big deal.

When you've got a *huge* expansion which is 50% of the run-time
of the command, I'd like to be able to get on with other things.

>  (vii) I get extra brownie points for doing this the week before the
>        annual lattice field theory conference where I'm giving a
>        talk.  Please don't tell my collaborators :-).

Have fun!



Duncan.



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~1996-05-31 16:49 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-05-28  9:18 $(nooutput) problem Peter Stephenson
1996-05-28 11:34 ` Zoltan Hidvegi
1996-05-30 16:58   ` execcmd() reordering Peter Stephenson
1996-05-30 18:00     ` Zoltan Hidvegi
1996-05-30 18:26       ` Barton E. Schaefer
1996-05-30 18:46         ` Zoltan Hidvegi
1996-05-30 18:41       ` Zoltan Hidvegi
1996-05-30 18:05 Duncan Sinclair
1996-05-30 19:10 ` Zoltan Hidvegi
1996-05-30 19:52   ` Barton E. Schaefer
1996-05-31 14:32     ` Hrvoje Niksic
1996-05-31 10:15 Duncan Sinclair
1996-05-31 10:55 ` Zoltan Hidvegi
1996-05-31 11:58   ` Peter Stephenson
1996-05-31 16:28     ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).