Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: options to command builtin



This long overdue patch adds support for the various flags to the
command builtin required by posix.

-v and -V are similar to what whence already does. -p uses a default
path to search for commands instead of $path.

Oliver

diff -urw zsh/acconfig.h command-v/acconfig.h
--- zsh/acconfig.h	2003-04-04 15:27:42.000000000 +0200
+++ command-v/acconfig.h	2003-09-10 20:48:49.000000000 +0200
@@ -52,6 +52,9 @@
  * anything                                                          */
 #undef GLOBAL_ZLOGOUT
 
+/* The default path; used when running commands with command -p */
+#undef DEFAULT_PATH
+
 /* Define to 1 if compiler could initialise a union */
 #undef HAVE_UNION_INIT
 
diff -urw zsh/Doc/Zsh/builtins.yo command-v/Doc/Zsh/builtins.yo
--- zsh/Doc/Zsh/builtins.yo	2003-09-03 13:19:05.000000000 +0200
+++ command-v/Doc/Zsh/builtins.yo	2003-09-10 22:15:50.000000000 +0200
@@ -194,7 +194,18 @@
 )
 alias(chdir)(cd)
 module(clone)(zsh/clone)
-prefix(command)
+findex(command)
+item(tt(command) [ tt(-pvV) ] var(simple command))(
+The simple command argument is taken as an external command instead of
+a function or builtin and is executed. If the tt(POSIX_BUILTINS) option
+is set, builtins will also be executed but certain special properties
+of them are suppressed. The tt(-p) flag causes a default path to be
+searched instead of that in tt($path). With the tt(-v) flag, tt(command)
+is similar to tt(whence) and with tt(-V), it is equivalent to tt(whence
+-v).
+
+See also noderef(Precommand Modifiers).
+)
 module(comparguments)(zsh/computil)
 module(compcall)(zsh/compctl)
 module(compctl)(zsh/compctl)
diff -urw zsh/Src/builtin.c command-v/Src/builtin.c
--- zsh/Src/builtin.c	2003-09-03 13:19:08.000000000 +0200
+++ command-v/Src/builtin.c	2003-09-10 20:48:31.000000000 +0200
@@ -2593,7 +2593,7 @@
     return returnval;
 }
 
-/* type, whence, which */
+/* type, whence, which, command */
 
 /**/
 int
@@ -2603,6 +2603,7 @@
     Patprog pprog;
     int returnval = 0;
     int printflags = 0;
+    int aliasflags;
     int csh, all, v, wd;
     int informed;
     char *cnam;
@@ -2624,6 +2625,18 @@
     if (OPT_ISSET(ops,'f'))
 	printflags |= PRINT_WHENCE_FUNCDEF;
 
+    if (func == BIN_COMMAND)
+	if (OPT_ISSET(ops,'V')) {
+	    printflags = aliasflags = PRINT_WHENCE_VERBOSE;
+	    v = 1;
+	} else {
+	    aliasflags = PRINT_LIST;
+	    printflags = PRINT_WHENCE_SIMPLE;
+	    v = 0;
+	}
+    else
+	aliasflags = printflags;
+
     /* With -m option -- treat arguments as a glob patterns */
     if (OPT_ISSET(ops,'m')) {
 	for (; *argv; argv++) {
@@ -2677,7 +2690,7 @@
 
 	    /* Look for alias */
 	    if ((hn = aliastab->getnode(aliastab, *argv))) {
-		aliastab->printnode(hn, printflags);
+		aliastab->printnode(hn, aliasflags);
 		if (!all)
 		    continue;
 		informed = 1;
diff -urw zsh/Src/exec.c command-v/Src/exec.c
--- zsh/Src/exec.c	2003-07-04 11:43:18.000000000 +0200
+++ command-v/Src/exec.c	2003-09-10 22:20:41.000000000 +0200
@@ -143,6 +143,10 @@
     execarith, execautofn
 };
 
+/* structure for command builtin for when it is used with -v or -V */
+static struct builtin commandbn =
+    BUILTIN(0, 0, bin_whence, 0, -1, BIN_COMMAND, "vV", NULL);
+
 /* parse string into a list */
 
 /**/
@@ -243,7 +247,7 @@
  * In zsh this traditionally executes the loop in the current shell, which
  * is nice to have if the loop does something to change the shell, like
  * setting parameters or calling builtins.
- * Putting the loop in a sub-shell makes live easy, because the shell only
+ * Putting the loop in a sub-shell makes life easy, because the shell only
  * has to put it into the job-structure and then treats it as a normal
  * process. Suspending and interrupting is no problem then.
  * Some years ago, zsh either couldn't suspend such things at all, or
@@ -257,7 +261,7 @@
  *  execlist->execpline->execcmd->execwhile->execlist->execpline
  *
  * (when waiting for the grep, ignoring execpline2 for now). At this time,
- * zsh has build two job-table entries for it: one for the cat and one for
+ * zsh has built two job-table entries for it: one for the cat and one for
  * the grep. If the user hits ^Z at this point (and jobbing is used), the 
  * shell is notified that the grep was suspended. The list_pipe flag is
  * used to tell the execpline where it was waiting that it was in a pipeline
@@ -442,7 +446,7 @@
 
 /**/
 void
-execute(Cmdnam not_used_yet, int dash)
+execute(Cmdnam not_used_yet, int dash, int defpath)
 {
     Cmdnam cn;
     char buf[MAXCMDLEN], buf2[MAXCMDLEN];
@@ -451,7 +455,7 @@
     int eno = 0, ee;
 
     arg0 = (char *) peekfirst(args);
-    if (isset(RESTRICTED) && strchr(arg0, '/')) {
+    if (isset(RESTRICTED) && (strchr(arg0, '/') || defpath)) {
 	zerr("%s: restricted", arg0, 0);
 	_exit(1);
     }
@@ -474,8 +478,6 @@
 	zsfree(s);
     }
 
-    cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0);
-
     /* If ARGV0 is in the commands environment, we use *
      * that as argv[0] for this external command       */
     if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
@@ -507,7 +509,43 @@
 	    break;
 	}
 
-    if (cn) {
+    /* for command -p, search the default path */ 
+    if (defpath) {
+      char *s, pbuf[PATH_MAX];
+      char *dptr, *pe, *ps = DEFAULT_PATH;
+
+      for(;ps;ps = pe ? pe+1 : NULL) {
+	  pe = strchr(ps, ':');
+	  if (*ps == '/') {
+	      s = pbuf;
+	      if (pe)
+		  struncpy(&s, ps, pe-ps);
+	      else
+		  strucpy(&s, ps);
+	      *s++ = '/';
+	      if ((s - pbuf) + strlen(arg0) >= PATH_MAX)
+		  continue;
+	      strucpy(&s, arg0);
+	      if (iscom(pbuf))
+		  break;
+	  }
+      }
+      
+      if (!ps) {
+	  zerr("command not found: %s", arg0, 0);
+	  _exit(127);
+      }
+
+      ee = zexecve(pbuf, argv);
+
+      if ((dptr = strrchr(pbuf, '/')))
+	  *dptr = '\0';
+      if (isgooderr(ee, *pbuf ? pbuf : "/"))
+	  eno = ee;
+
+    } else {
+   
+	if ((cn = (Cmdnam) cmdnamtab->getnode(cmdnamtab, arg0))) {
 	char nn[PATH_MAX], *dptr;
 
 	if (cn->flags & HASHED)
@@ -552,6 +590,8 @@
 	    if (isgooderr(ee, *pp))
 		eno = ee;
 	}
+    }
+
     if (eno)
 	zerr("%e: %s", arg0, eno);
     else
@@ -1692,7 +1732,7 @@
     int save[10];
     int fil, dfil, is_cursh, type, do_exec = 0, i, htok = 0;
     int nullexec = 0, assign = 0, forked = 0;
-    int is_shfunc = 0, is_builtin = 0, is_exec = 0;
+    int is_shfunc = 0, is_builtin = 0, is_exec = 0, use_defpath = 0;
     /* Various flags to the command. */
     int cflags = 0, checked = 0, oautocont = opts[AUTOCONTINUE];
     LinkList redir;
@@ -1782,9 +1822,30 @@
 	    }
 	    cflags &= ~BINF_BUILTIN & ~BINF_COMMAND;
 	    cflags |= hn->flags;
+	    checked = 0;
+	    if (cflags & BINF_COMMAND && nextnode(firstnode(args))) {
+		// check for options to command builtin
+		char *next = (char *) getdata(nextnode(firstnode(args)));
+		char *cmdopt;
+		if (next && *next == '-' && strlen(next) == 2 &&
+		        (cmdopt = strchr("pvV", next[1])))
+		{
+		    if (*cmdopt == 'p') {
+			uremnode(args, firstnode(args));
+			use_defpath = 1;
+			if (nextnode(firstnode(args)))
+			    next = (char *) getdata(nextnode(firstnode(args)));
+		    } else {
+			hn = (HashNode)&commandbn;
+			is_builtin = 1;
+			break;
+		    }
+		}
+		if (!strcmp(next, "--"))
+		     uremnode(args, firstnode(args));   
+	    }
 	    uremnode(args, firstnode(args));
 	    hn = NULL;
-	    checked = 0;
 	    if ((cflags & BINF_COMMAND) && unset(POSIXBUILTINS))
 		break;
 	}
@@ -2401,7 +2462,7 @@
 		    zsfree(STTYval);
 		    STTYval = 0;
 		}
-		execute((Cmdnam) hn, cflags & BINF_DASH);
+		execute((Cmdnam) hn, cflags & BINF_DASH, use_defpath);
 	    } else {		/* ( ... ) */
 		DPUTS(varspc,
 		      "BUG: assignment before complex command");
diff -urw zsh/Src/hashtable.h command-v/Src/hashtable.h
--- zsh/Src/hashtable.h	2002-08-27 23:10:34.000000000 +0200
+++ command-v/Src/hashtable.h	2003-09-10 20:48:31.000000000 +0200
@@ -58,6 +58,7 @@
 #define BIN_DISABLE  24
 #define BIN_ENABLE   25
 #define BIN_PRINTF   26
+#define BIN_COMMAND  27
 
 /* These currently depend on being 0 and 1. */
 #define BIN_SETOPT    0
diff -urw zsh/zshconfig.ac command-v/zshconfig.ac
--- zsh/zshconfig.ac	2003-08-31 11:41:10.000000000 +0200
+++ command-v/zshconfig.ac	2003-09-10 20:48:49.000000000 +0200
@@ -1323,6 +1323,20 @@
 fi
 
 
+dnl --------------------------------------------
+dnl CHECK FOR DEFAULT PATH (used for command -p)
+dnl --------------------------------------------
+AC_CACHE_VAL(zsh_cv_cs_path,
+[if getconf _CS_PATH >/dev/null 2>&1; then
+  zsh_cv_cs_path=`getconf _CS_PATH`
+elif getconf CS_PATH >/dev/null 2>&1; then
+  zsh_cv_cs_path=`getconf CS_PATH`
+else
+  zsh_cv_cs_path="/bin:/usr/bin"
+fi])
+AC_DEFINE_UNQUOTED(DEFAULT_PATH, "$zsh_cv_cs_path")
+
+
 dnl ----------------------------
 dnl CHECK FOR /dev/fd FILESYSTEM
 dnl ----------------------------



Messages sorted by: Reverse Date, Date, Thread, Author