From d2dbcc6f1030735629591baea985f3519c02488a Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 15 May 2021 14:49:20 +0100 Subject: [PATCH] runlisp.c, eval.lisp, etc.: Add new `-p' option to `princ' expressions. Printing results as Lisp quoted strings is really unhelpful for shell scripts. --- eval.lisp | 6 ++++++ runlisp.1.in | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- runlisp.c | 9 ++++++--- tests.at | 2 ++ 4 files changed, 60 insertions(+), 7 deletions(-) diff --git a/eval.lisp b/eval.lisp index de5da0e..79e5064 100644 --- 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)) diff --git a/runlisp.1.in b/runlisp.1.in index 35378d4..d262389 100644 --- a/runlisp.1.in +++ b/runlisp.1.in @@ -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 diff --git a/runlisp.c b/runlisp.c index 4e13663..87c478f 100644 --- 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; diff --git a/tests.at b/tests.at index 73b13ae..c6c1987 100644 --- 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': () -- 2.11.0