zsh-workers
 help / color / mirror / code / Atom feed
* Re: default command function
@ 1998-03-26 11:07 Andrew Main
  1998-03-28  4:28 ` Richard Coleman
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Main @ 1998-03-26 11:07 UTC (permalink / raw)
  To: gdfast; +Cc: zsh-workers

Gregory D. Fast wrote:
>Perl has an amusing feature whereby the sub named AUTOLOAD, if defined
>in the current package, gets called in place of a "subroutine not
>found" error.  The idea is that AUTOLOAD reads the sub definition from
>somewhere, breathes life into it, and then calls it.  It basically allows
>you to create default behavior for undefined subroutines.
>
>I like it a lot, and wished that I could somehow trick zsh into acting
>likewise, so I modified exec.c so that if a command is not found, it execs
>(assuming it's defined) _default_cmd(), with the (failed) command line
>as its args.

Unfortunately, by the time the command failure is detected, the shell has
already forked, so the most useful application of this sort of feature
-- defining a shell function -- is not possible.  In fact, very little
of any utility is possible.  Therefore this patch is not going into the
next zefram release.

I'd like to have some way for the main shell process to detect reliably
whether external command execution failed, so that this could be done
properly.  Perhaps a close-on-exec pipe, with an error number being sent
down the pipe in case of error?  This would open up other possibilities:
the command search mechanism could be put completely under user control,
with the possibility of user- (or module-) defined forms of command
execution.

Perhaps the command search order (builtin, function, external command,
...) could go into a shell parameter, making `builtin' and `command'
just special cases of this more general facility.  (I think this
sort of feature was first suggested to me by Richard, and I have
recently implemented it, in a very general form, in a shell I wrote
for a non-Unix OS.)

I envision having a new hash table, for command executors; these would
be defined the way builtin commands are (some in the base executable,
with modules being able to add to the table).  When simple commands are
executed then the command executors named by an array parameter would be
tried in sequence.  Really wacky idea: a module could provide a builtin
that provides the capability to invent new command executors based on
a shell function, which gets run with the relevant parameter modified.

-zefram


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

* Re: default command function
  1998-03-26 11:07 default command function Andrew Main
@ 1998-03-28  4:28 ` Richard Coleman
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Coleman @ 1998-03-28  4:28 UTC (permalink / raw)
  To: zsh-workers

> Perhaps the command search order (builtin, function, external command,
> ...) could go into a shell parameter, making `builtin' and `command'
> just special cases of this more general facility.  (I think this
> sort of feature was first suggested to me by Richard, and I have
> recently implemented it, in a very general form, in a shell I wrote
> for a non-Unix OS.)

When I was maintainer, I spent a couple weeks working on this idea,
and eventually threw all the code away.  It just got too hackish.

If you could make this work, it would be great.

As part of this, I wanted to merge the command search code with
the where/whence/type builtin.  There are several different places
where zsh goes searching for a command.

--
Richard Coleman
coleman@math.gatech.edu


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

* Re: default command function
  1998-02-23 19:39 Gregory D. Fast
@ 1998-02-23 22:06 ` Gregory D. Fast
  0 siblings, 0 replies; 4+ messages in thread
From: Gregory D. Fast @ 1998-02-23 22:06 UTC (permalink / raw)
  To: zsh-workers

Thus spake "Gregory D. Fast" <gdfast@usgs.gov>:
>Is there a better way to do this?  My patch against 3.0.5 follows.

Oops.  That was the ugly patch.  This one is a lot cleaner (they both
work, though).

--
Greg Fast


--- zsh-3.0.5/Src/exec.c	Thu Sep 25 20:42:16 1997
+++ zsh-3.0.5-gdf/Src/exec.c	Mon Feb 23 12:53:38 1998
@@ -1,5 +1,5 @@
 /*
- * $Id: exec.c,v 2.93 1996/10/15 20:16:35 hzoli Exp $
+ * $Id: exec.c,v 1.8 1998/02/23 18:53:18 gdfast Exp gdfast $
  *
  * exec.c - command execution
  *
@@ -347,8 +347,38 @@
 	}
     if (eno)
 	zerr("%e: %s", arg0, eno);
-    else
-	zerr("command not found: %s", arg0, 0);
+#ifdef DEFAULT_CMD
+    else {
+      /* if cmd is unknown and function _default_cmd() is defined, 
+       * call _default_cmd() with the faulty cmdline as its args 
+       */
+      char *cmdarg = "_default_cmd";
+      List f; /* Shfunc to execute */
+      LinkNode top; 
+      char * cxx;
+      LinkList fargs = newlinklist();
+
+      addlinknode(fargs, (void *) cmdarg); /* make $0 "_default_cmd" */
+      /* args is global */
+      top = firstnode(args); /* keep track of where to stop rolling args */
+      do {
+	cxx = (char *) peekfirst(args);
+	addlinknode(fargs, (void *) cxx);
+	if (args->first->next==NULL) {
+	  break; /* don't roll if there's nowhere to roll to */
+	}
+	rolllist(args, args->first->next);
+      } while (args->first!=top);
+      if ( (f=getshfunc(cmdarg)) ) {
+	doshfunc(f, fargs, 0, 1);
+      } else {
+	zerr("command not found and no _default_cmd(): %s", arg0, 0);
+      }
+    }
+#else /* no DEFAULT_CMD */
+    else 
+      zerr("command not found: %s", arg0, 0);
+#endif /* DEFAULT_CMD */
     _exit(1);
 }
 


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

* default command function
@ 1998-02-23 19:39 Gregory D. Fast
  1998-02-23 22:06 ` Gregory D. Fast
  0 siblings, 1 reply; 4+ messages in thread
From: Gregory D. Fast @ 1998-02-23 19:39 UTC (permalink / raw)
  To: zsh-workers

This is something I've been wondering about for a few weeks.  I
couldn't figure out an existing way to do it, so I changed the
source...  If there's already a way, well, it was good practice.
Otherwise, comments?  It's pretty hackish at this point.

Perl has an amusing feature whereby the sub named AUTOLOAD, if defined
in the current package, gets called in place of a "subroutine not
found" error.  The idea is that AUTOLOAD reads the sub definition from
somewhere, breathes life into it, and then calls it.  It basically allows
you to create default behavior for undefined subroutines.

I like it a lot, and wished that I could somehow trick zsh into acting
likewise, so I modified exec.c so that if a command is not found, it execs
(assuming it's defined) _default_cmd(), with the (failed) command line
as its args.

pretty mindless example: I use MH for reading my mail.  Defining
_default_cmd() thusly lets you use "25" for "show 25", etc.

  % _default_cmd() { show $* }

Is there a better way to do this?  My patch against 3.0.5 follows.

--
Greg Fast


--- zsh-3.0.5/Src/exec.c	Thu Sep 25 20:42:16 1997
+++ zsh-3.0.5-gdf/Src/exec.c	Mon Feb 23 01:38:56 1998
@@ -1,5 +1,5 @@
 /*
- * $Id: exec.c,v 2.93 1996/10/15 20:16:35 hzoli Exp $
+ * $Id: exec.c,v 1.7 1998/02/23 07:38:48 gdfast Exp gdfast $
  *
  * exec.c - command execution
  *
@@ -347,8 +347,44 @@
 	}
     if (eno)
 	zerr("%e: %s", arg0, eno);
-    else
-	zerr("command not found: %s", arg0, 0);
+#ifdef DEFAULT_CMD
+    else {
+      /* if cmd is unknown and function _default_cmd() is defined, 
+       * call _default_cmd() with the faulty cmdline as its args 
+       */
+      char *cmdarg = "_default_cmd";
+      HashNode f; /* Shfunc to execute */
+      LinkNode top; 
+      char * cxx;
+      Cmd fcmd = (Cmd) allocnode(N_CMD);
+
+      fcmd->args = newlinklist(); 
+      fcmd->redir = newlinklist();
+      fcmd->vars = newlinklist();
+      fcmd->type = FUNCDEF;
+      fcmd->lineno = 0; /*?*/
+      fcmd->u.generic = NULL; /*?*/
+      addlinknode(fcmd->args, (void *) cmdarg); /* make $0 "_default_cmd" */
+      /* args is global */
+      top = firstnode(args); /* keep track of where to stop rolling args */
+      do {
+	cxx = (char *) peekfirst(args);
+	addlinknode(fcmd->args, (void *) cxx);
+	if (args->first->next==NULL) {
+	  break; /* don't roll if there's nowhere to roll to */
+	}
+	rolllist(args, args->first->next);
+      } while (args->first!=top);
+      if ( (f=shfunctab->getnode(shfunctab, cmdarg)) ) {
+	execshfunc(fcmd, (Shfunc) f); 
+      } else {
+	zerr("command not found and no _default_cmd(): %s", arg0, 0);
+      }
+    }
+#else /* no DEFAULT_CMD */
+    else 
+      zerr("command not found: %s", arg0, 0);
+#endif /* DEFAULT_CMD */
     _exit(1);
 }
 


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

end of thread, other threads:[~1998-03-28  4:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-03-26 11:07 default command function Andrew Main
1998-03-28  4:28 ` Richard Coleman
  -- strict thread matches above, loose matches on Subject: below --
1998-02-23 19:39 Gregory D. Fast
1998-02-23 22:06 ` Gregory D. Fast

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).