runlisp.c, eval.lisp, etc.: Add new `-p' option to `princ' expressions.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 15 May 2021 13:49:20 +0000 (14:49 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 15 May 2021 13:59:01 +0000 (14:59 +0100)
Printing results as Lisp quoted strings is really unhelpful for shell
scripts.

eval.lisp
runlisp.1.in
runlisp.c
tests.at

index de5da0e..79e5064 100644 (file)
--- a/eval.lisp
+++ b/eval.lisp
@@ -37,6 +37,9 @@
               (loop (let ((form (read in nil token)))
                       (when (eq form token) (return))
                       (funcall func form)))))
+          (princ-form (form)
+            (format t "~@[~{~A~^ ~}~%~]"
+                    (multiple-value-list (eval form))))
           (prin1-form (form)
             (format t "~@[~{~S~^ ~}~%~]"
                     (multiple-value-list (eval form)))))
@@ -49,6 +52,9 @@
                  (#\! (push (lambda ()
                               (foreach-form #'eval rest))
                             list))
+                 (#\= (push (lambda ()
+                              (foreach-form #'princ-form rest))
+                            list))
                  (#\? (push (lambda ()
                               (foreach-form #'prin1-form rest))
                             list))
index 35378d4..d262389 100644 (file)
@@ -64,6 +64,12 @@ runlisp \- run Common Lisp programs as scripts
 .IR form ]
 .RB [ \-l
 .IR file ]
+.RB [ \-p
+.IR form ]
+.if !t \{\
+.br
+       \c
+.\}
 .RB [ \-\- ]
 .RI [ arguments
 \*(..]
@@ -204,7 +210,9 @@ Evaluate the expression(s)
 .I expr
 and print the resulting value(s)
 to standard output
-(as if by
+(with
+.B *print-escape*
+true, as if by
 .BR prin1 ).
 If a form produces multiple values,
 they are printed on a single line,
@@ -216,6 +224,11 @@ This option causes
 to execute in
 .I eval
 mode.
+See also
+.RB ` \-p ',
+which prints with
+.B *print-escape*
+false.
 .
 .TP
 .BI "\-e" "\fR, " "\-\-evaluate-expression=" expr
@@ -266,6 +279,32 @@ and overrides any similarly named setting
 from the configuration file(s).
 .
 .TP
+.BI "\-p" "\fR, " "\-\-print-expression=" expr
+Evaluate the expression(s)
+.I expr
+and print the resulting value(s)
+to standard output
+(with
+.B *print-escape*
+false, as if by
+.BR princ ).
+If a form produces multiple values,
+they are printed on a single line,
+separated by a single space character;
+if a form produces no values at all,
+then nothing is printed \(en not even a newline character.
+This option causes
+.B runlisp
+to execute in
+.I eval
+mode.
+See also
+.RB ` \-d ',
+which prints with
+.B *print-escape*
+true.
+.
+.TP
 .BR "\-q" ", " "\-\-quiet"
 Don't print warning messages.
 This option may be repeated:
@@ -292,8 +331,9 @@ Higher verbosity levels print informational and debugging messages.
 The
 .RB ` \-d ',
 .RB ` \-e ',
+.RB ` \-l ',
 and
-.RB ` \-l '
+.RB ` \-p '
 options may only be given on the command-line itself,
 not following a
 .RB `@ RUNLISP: '
@@ -325,8 +365,9 @@ if desired.
 If the command line contains any of
 .RB ` \-d ',
 .RB ` \-e ',
-or
 .RB ` \-l ',
+or
+.RB ` \-p ',
 then
 .B runlisp
 treats all of its positional arguments as
@@ -424,8 +465,9 @@ is now committed to
 mode, so it's too late for
 .RB ` \-d ',
 .RB ` \-e ',
+.RB ` \-l ',
 and
-.RB ` \-l '
+.RB ` \-p '
 too.
 .PP
 (This feature allows scripts to provide options even if they use
index 4e13663..87c478f 100644 (file)
--- a/runlisp.c
+++ b/runlisp.c
@@ -199,7 +199,8 @@ static void usage(FILE *fp)
   fprintf(fp, "\
 usage:\n\
        %s [OPTIONS] [--] SCRIPT [ARGUMENTS ...]\n\
-       %s [OPTIONS] [-e EXPR] [-d EXPR] [-l FILE] [--] [ARGUMENTS ...]\n\
+       %s [OPTIONS] [-e EXPR] [-d EXPR] [-p EXPR] [-l FILE]\n\
+               [--] [ARGUMENTS ...]\n\
 OPTIONS:\n\
        [-CDEnqv] [+DEn] [-L SYS,SYS,...] [-c CONF] [-o [SECT:]VAR=VAL]\n",
          progname, progname);
@@ -230,7 +231,8 @@ Lisp implementation selection:\n\
 Evaluation mode:\n\
   -d, --dump-expression=EXPR   Print (`prin1') EXPR (repeatable).\n\
   -e, --evaluate-expression=EXPR Evaluate EXPR for effect (repeatable).\n\
-  -l, --load-file=FILE         Load FILE (repeatable).\n",
+  -l, --load-file=FILE         Load FILE (repeatable).\n\
+  -p, --print-expression=EXPR  Print (`princ') EXPR (repeatable).\n",
        fp);
 }
 
@@ -281,7 +283,7 @@ static void parse_options(int argc, char *argv[])
 
   optarg = 0; optind = 0; optprog = (/*unconst*/ char *)progname;
   for (;;) {
-    i = mdwopt(argc, argv, "+hVD+E+L:c:d:e:l:n+o:qv", opts, 0, 0,
+    i = mdwopt(argc, argv, "+hVD+E+L:c:d:e:l:n+o:p:qv", opts, 0, 0,
               OPTF_NEGATION | OPTF_NOPROGNAME);
     if (i < 0) break;
     switch (i) {
@@ -299,6 +301,7 @@ static void parse_options(int argc, char *argv[])
       case 'l': CMDL; push_eval_op('<', optarg); break;
       FLAGOPT('n', AF_DRYRUN, { CMDL; });
       case 'o': CMDL; if (set_config_var(optarg)) flags |= AF_BOGUS; break;
+      case 'p': CMDL; push_eval_op('=', optarg); break;
       case 'q': CMDL; if (verbose) verbose--; break;
       case 'v': CMDL; verbose++; break;
       default: flags |= AF_BOGUS; break;
index 73b13ae..c6c1987 100644 (file)
--- a/tests.at
+++ b/tests.at
@@ -234,12 +234,14 @@ AT_CHECK([RUNLISP_PATH \
                (defvar runlisp-test:bar "stoat!")' \
            -d runlisp-test:foo \
            -d runlisp-test:bar \
+           -p runlisp-test:bar \
            -e '(incf runlisp-test:foo)' \
            -l script.lisp \
            -d runlisp-test:foo \
            -- -e one two three],,
 [1
 "stoat!"
+stoat!
 And we're running the script...
 Command-line arguments: ("-e" "one" "two" "three")
 Symbols in package `COMMON-LISP-USER': ()