chiark / gitweb /
Include `%'-escape substitution.
authormdw <mdw>
Fri, 10 Sep 1999 15:27:40 +0000 (15:27 +0000)
committermdw <mdw>
Fri, 10 Sep 1999 15:27:40 +0000 (15:27 +0000)
src/sw.c
src/sw.h
src/sw_build.c
sw.1

index 4040d91024e79b25c784084468465b32de919dfd..743c426d58b8569fe42aa58b1cfa6bed109b8986 100644 (file)
--- a/src/sw.c
+++ b/src/sw.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: sw.c,v 1.2 1999/07/16 12:50:43 mdw Exp $
+ * $Id: sw.c,v 1.3 1999/09/10 15:27:32 mdw Exp $
  *
  * Main driver code for sw-tools
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: sw.c,v $
+ * Revision 1.3  1999/09/10 15:27:32  mdw
+ * Include `%'-escape substitution.
+ *
  * Revision 1.2  1999/07/16 12:50:43  mdw
  * Replace deprecated `mdwopt' flag name with new version.
  *
@@ -88,7 +91,7 @@ static cmd *cmds = CMD_LINK;
 
 const char *opt_output = 0;
 const char *opt_arch = 0;
-unsigned int opt_flags;
+unsigned int opt_flags = optFlag_percent;
 
 /*----- Helpful GNUy message routines -------------------------------------*/
 
@@ -103,7 +106,7 @@ static void version(FILE *fp)
 
 static void usage(FILE *fp)
 {
-  fprintf(fp, "Usage: %s [-fbi] [-a arch,...] [-o style] command [args]\n",
+  fprintf(fp, "Usage: %s [-fbip] [-a arch,...] [-o style] command [args]\n",
          QUIS);
 }
 
@@ -124,6 +127,7 @@ There are some options which affect a few of the available commands:\n\
 -b, --beep             Beep when the build is complete.\n\
 -i, --install          Mark architectures as done when build succeeds.\n\
 -f, --force            Run build commands on installed architectures.\n\
+-p, --percent          Enable `%'-escapes in build command arguments.\n\
 -o, --output=STYLE     Display output in a particular style.  Use style\n\
                        `help' for a list.\n\
 \n", fp);
@@ -196,7 +200,9 @@ int main(int argc, char *argv[])
       { "force",       0,              0,      'f' },
       { "install",     0,              0,      'i' },
       { "output",      OPTF_ARGREQ,    0,      'o' },
-      { "beep",                0,              0,      'b' },
+      { "beep",                OPTF_NEGATE,    0,      'b' },
+      { "percent",     OPTF_NEGATE,    0,      'p' },
+      { "escape",      OPTF_NEGATE,    0,      'p' },
 
       /* --- Internal-use-only magical options --- *
        *
@@ -210,7 +216,8 @@ int main(int argc, char *argv[])
 
       { 0,             0,              0,      0 }
     };
-    int i = mdwopt(argc, argv, "+hHvu a:bfio:", opt, 0, 0, OPTF_ENVVAR);
+    int i = mdwopt(argc, argv, "+hHvu a:b+p+fio:", opt, 0, 0,
+                  OPTF_ENVVAR | OPTF_NEGATION);
     if (i < 0)
       break;
 
@@ -242,6 +249,15 @@ int main(int argc, char *argv[])
       case 'b':
        opt_flags |= optFlag_beep;
        break;
+      case 'b' | OPTF_NEGATED:
+       opt_flags &= ~optFlag_beep;
+       break;
+      case 'p':
+       opt_flags |= optFlag_percent;
+       break;
+      case 'p' | OPTF_NEGATED:
+       opt_flags &= ~optFlag_percent;
+       break;
       case 'i':
        opt_flags |= optFlag_install;
        break;
index 4d0ef30adfbb55d5b1ef13c64a3bca1310bc5793..13fa5a2403e61a7ed5c73fff239fbaa6ffa7a9f1 100644 (file)
--- a/src/sw.h
+++ b/src/sw.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: sw.h,v 1.1 1999/06/02 16:53:35 mdw Exp $
+ * $Id: sw.h,v 1.2 1999/09/10 15:27:33 mdw Exp $
  *
  * Interface to main options parser
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: sw.h,v $
- * Revision 1.1  1999/06/02 16:53:35  mdw
- * Initial revision
+ * Revision 1.2  1999/09/10 15:27:33  mdw
+ * Include `%'-escape substitution.
+ *
+ * Revision 1.1.1.1  1999/06/02 16:53:35  mdw
+ * Initial import.
  *
  */
 
@@ -73,7 +76,8 @@ extern unsigned int opt_flags;                /* Various bitflag options */
 enum {
   optFlag_install = 1,
   optFlag_force = 2,
-  optFlag_beep = 4
+  optFlag_beep = 4,
+  optFlag_percent = 8
 };
 
 /*----- That's all, folks -------------------------------------------------*/
index cfa765bb0eb4855c925fddb73f0df524423dcc12..493336388f064573d64e80471c399d1c39f7d276 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: sw_build.c,v 1.2 1999/07/16 12:50:24 mdw Exp $
+ * $Id: sw_build.c,v 1.3 1999/09/10 15:27:33 mdw Exp $
  *
  * Management of build processes
  *
@@ -29,6 +29,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: sw_build.c,v $
+ * Revision 1.3  1999/09/10 15:27:33  mdw
+ * Include `%'-escape substitution.
+ *
  * Revision 1.2  1999/07/16 12:50:24  mdw
  * Improve exit status display.  New interface from `doto' project.
  *
@@ -56,6 +59,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/wait.h>
+#include <sys/utsname.h>
 
 #ifndef DECL_ENVIRON
   extern char **environ;
@@ -227,13 +231,92 @@ int sw_run(int argc, char *argv[])
 
     {
       archcons *aa;
+      dstr d = DSTR_INIT;
+      char **av;
+      struct utsname u;
+
+      /* --- Fill in the hostname --- */
+
+      if (uname(&u))
+       strcpy(u.nodename, "<unknown>");
+
+      /* --- If necessary, set up the output @argv@ array --- */
+
+      if (opt_flags & optFlag_percent)
+       av = xmalloc(argc * sizeof(char *));
+      else
+       av = argv + 1;
+
+      /* --- Run through the target build hosts --- */
 
       FD_ZERO(&fdin);
       for (aa = a; aa; aa = aa->cdr) {
        archent *e = aa->car;
        sw_remote *r = e->r;
+
+       /* --- If necessary, translate `%'-escapes --- */
+
+       if (opt_flags & optFlag_percent) {
+         char **pp, **qq;
+
+         for (pp = argv + 1, qq = av; *pp; pp++, qq++) {
+           if (strchr(*pp, '%') == 0)
+             *qq = *pp;
+           else {
+             char *p;
+             char *q = *pp;
+             for (p = *pp; *p; p++) {
+               if (*p == '%') {
+                 DPUTM(&d, q, p - q);
+                 p++;
+                 switch (*p) {
+                   case 0:
+                     DPUTC(&d, '%');
+                     goto done_arg;
+                   case '%':
+                     DPUTC(&d, '%');
+                     break;
+                   case 'a':
+                     dstr_puts(&d, e->arch);
+                     break;
+                   case 'h':
+                     dstr_puts(&d, e->flags & archFlag_home ?
+                                     u.nodename : e->host);
+                     break;
+                   case 'P':
+                     dstr_puts(&d, PREFIX);
+                     break;
+                   case 'p':
+                     dstr_puts(&d, sw.package);
+                     break;
+                   case 'v':
+                     dstr_puts(&d, sw.version);
+                     break;
+                   case 'u':
+                     dstr_puts(&d, sw.maintainer);
+                     break;
+                   default:
+                     DPUTC(&d, '%');
+                     DPUTC(&d, *p);
+                     break;
+                 }
+                 q = p + 1;
+               }
+             }
+             DPUTM(&d, q, p - q);
+           done_arg:
+             DPUTZ(&d);
+             *qq = xstrdup(d.buf);
+             DRESET(&d);
+           }
+         }
+         *qq++ = 0;
+       }
+
+       /* --- Start a new process off --- */
+
        if (swrsh(r, e->flags & archFlag_home ? 0 : e->host,
-                 "build", argv + 1)) {
+                 "build", av)) {
          dstr d = DSTR_INIT;
          dstr_putf(&d, "%s: couldn't start build for architecture `%s': %s",
                    QUIS, e->arch, strerror(errno));
@@ -248,7 +331,21 @@ int sw_run(int argc, char *argv[])
          active++;
          FD_SET(fd, &fdin);
        }
+
+       /* --- Free up the argument array --- */
+
+       if (opt_flags & optFlag_percent) {
+         char **pp, **qq;
+
+         for (pp = argv + 1, qq = av; *pp; pp++, qq++) {
+           if (*pp != *qq)
+             free(*qq);
+         }
+       }
       }
+
+      if (opt_flags & optFlag_percent)
+       free(av);
     }
 
     /* --- Watch the builds until they do something interesting --- */
@@ -429,7 +526,7 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
   int fd[2];
   pid_t kid;
 
-  /* --- Validate arguments --- */
+  /* --- Validate the arguments --- */
 
   if (!argv[0])
     swdie(r, 1, "Usage: build COMMAND [ARG...]");
@@ -453,7 +550,10 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
     struct tm *tm;
     char buf[64];
     char **p;
+    struct utsname u;
 
+    if (uname(&u))
+      swdie(r, 1, "couldn't get hostname: %s", strerror(errno));
     if (logfd < 0)
       swdie(r, 1, "couldn't open `.build-log' file: %s", strerror(errno));
     if ((logfp = fdopen(logfd, "a")) == 0) {
@@ -463,7 +563,8 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
     t = time(0);
     tm = localtime(&t);
     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
-    fprintf(logfp, "\n\n*** %s: started build: %s", buf, argv[0]);
+    fprintf(logfp, "\n\n*** %s: %s started build: %s",
+           buf, u.nodename, argv[0]);
     for (p = argv + 1; *p; p++)
       fprintf(logfp, " %s", *p);
     fputs("\n\n", logfp);
@@ -499,7 +600,7 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
     if (!n)
       break;
     if (n < 0) {
-      putf(r, logfp, "*** error reading from pipe: %s\n", strerror(errno));
+      putf(r, logfp, "\n*** error reading from pipe: %s\n", strerror(errno));
       kill(kid, SIGTERM);
       break;
     }
@@ -512,15 +613,16 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[])
 
   {
     int status;
-    if (waitpid(kid, &status, 0) < 0)
-      putf(r, logfp, "*** error reading exit status: %s\n", strerror(errno));
-    else {
+    if (waitpid(kid, &status, 0) < 0) {
+      putf(r, logfp, "\n*** error reading exit status: %s\n",
+          strerror(errno));
+    } else {
       if (WIFSIGNALED(status))
-       fprintf(logfp, "*** exited on signal %i\n", WTERMSIG(status));
+       fprintf(logfp, "\n*** exited on signal %i\n", WTERMSIG(status));
       else if (WIFEXITED(status))
-       fprintf(logfp, "*** exited with status %i\n", WEXITSTATUS(status));
+       fprintf(logfp, "\n*** exited with status %i\n", WEXITSTATUS(status));
       else
-       fprintf(logfp, "*** reaped, but didn't exit.  Strange\n");
+       fprintf(logfp, "\n*** reaped, but didn't exit.  Strange\n");
     }
     fclose(logfp);
     swwait(r, status);
diff --git a/sw.1 b/sw.1
index d06930a00a2d289efd336b2732555b15bdda35e8..47e3afc3506a025ef7f07e1486b304b85f0476ba 100644 (file)
--- a/sw.1
+++ b/sw.1
@@ -1,6 +1,6 @@
 .\" -*-nroff-*-
 .\"
-.\" $Id: sw.1,v 1.7 1999/07/30 18:44:33 mdw Exp $
+.\" $Id: sw.1,v 1.8 1999/09/10 15:27:40 mdw Exp $
 .\"
 .\" Manual page for `sw'
 .\"
@@ -28,6 +28,9 @@
 .\"----- Revision history ---------------------------------------------------
 .\"
 .\" $Log: sw.1,v $
+.\" Revision 1.8  1999/09/10 15:27:40  mdw
+.\" Include `%'-escape substitution.
+.\"
 .\" Revision 1.7  1999/07/30 18:44:33  mdw
 .\" Improve cross-references and tidy up formatting.
 .\"
@@ -103,15 +106,15 @@ sw \- tool for convenient software installation
 \fBsw all\-arch
 \fBsw arch
 \fBsw commit
-\fBsw \fR[\fB\-fbi\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBconfigure \fR[\fIconfigure-arg\fR...]
+\fBsw \fR[\fB\-fbip\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBconfigure \fR[\fIconfigure-arg\fR...]
 \fBsw host \fIarch
 \fBsw \fR[\fB\-f\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] \fBlinktree
 \fBsw listarch
-\fBsw \fR[\fB\-fbi\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBmake \fR[\fImake-arg\fR...]
+\fBsw \fR[\fB\-fbip\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBmake \fR[\fImake-arg\fR...]
 \fBsw only\-arch \fIarch \fR[\fIarch\fR...]
 \fBsw reset
 \fBsw rsh \fIhost\fR|\fIarch \fR[\fIcommand \fR[\fIargument\fR...]]
-\fBsw \fR[\fB\-fbi\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBrun \fIcommand \fR[\fIargument\fR...]
+\fBsw \fR[\fB\-fbip\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] [\fB\-o \fIstyle\fR] \fBrun \fIcommand \fR[\fIargument\fR...]
 \fBsw setup \fIpackage version \fR[\fImaintainer\fR]
 \fBsw \fR[\fB\-f\fR] [\fB\-a \fIarch\fB,\fIarch\fR...] \fBsnaplink \fIfile \fR[\fIfile\fR...]
 \fBsw status
@@ -502,7 +505,29 @@ for more details on output styles.
 .B "\-b, \-\-beep"
 For build commands: make a beep noise when the build finishes.  This
 provides a handy reminder if you're getting on with something else while
-waiting for a long build.
+waiting for a long build.  Use
+.RB ` +b '
+or
+.RB ` \-\-no\-beep '
+to turn this option off.  This option is disabled by default, although
+may be enabled in the
+.B SW
+environment variable.
+.TP
+.B "\-p, \-\percent"
+For build commands: enable translation of
+.RB ` % '-escape
+sequences in command strings.  These are described in more detail
+in the section
+.B "`%'-escape sequences"
+below.  Use
+.RB ` +p '
+or
+.RB ` --no-percent '
+to turn the option off.  This option is enabled by default, although may
+be disabled in the
+.B SW
+environment variable.
 .PP
 The remaining options aren't really intended for users.  They're helpful
 for \*(sw's own purposes, though, and described here for completeness' sake.  They
@@ -804,6 +829,16 @@ Executes the program named
 passing it the given
 .IR argument s.
 .PP
+The command name and arguments may be subject to
+.RB ` % '-escape
+substitution, depending on whether the
+.B \-p
+option is enabled.  
+.RB ` % '-escape
+sequences are described in the section
+.B "`%'-escape sequences"
+below.
+.PP
 Output from the command is both appended to the file
 .IB arch/.build-log
 and output in some
@@ -869,6 +904,46 @@ actually need to follow creation of link trees.
 .
 .\"--------------------------------------------------------------------------
 .
+.SH "`%'-ESCAPE SUBSTITUTION"
+.
+If the
+.B \-p
+option is enabled, build commands and arguments are subject to
+.RB ` % '-escape
+substitution before being executed.  Certain two-character sequences,
+with the first character
+.RB ` % '
+are replaced with strings, as follows:
+.TP
+.B %a
+The architecture name of the host executing the command.
+.TP
+.B %h
+The hostname of the host executing the command.
+.TP
+.B %P
+The directory prefix with which \*(sw was installed.
+.TP
+.B %p
+The name of the package being built.
+.TP
+.B %v
+The version number of the package being built.
+.TP
+.B %u
+The name of the maintainer of the package being built.
+.TP
+.B %%
+A literal
+.RB ` % '
+character.
+.PP
+Any
+.RB ` % '
+sequences which aren't understood are left as they are.
+.
+.\"--------------------------------------------------------------------------
+.
 .SH "OUTPUT STYLES"
 .
 Output from a build command is presented in one of a number of named