diff --git a/src/code/commandline.lisp b/src/code/commandline.lisp index 36f037a015512ffd1c874e8a94ff16c648f9f677..be67ddcd718d3a6da468d234898a81e7145c669b 100644 --- a/src/code/commandline.lisp +++ b/src/code/commandline.lisp @@ -72,7 +72,7 @@ ;;;; Processing the command strings. -(defun process-command-strings () +(defun process-command-strings (init-command-switches-p) (setq *command-line-words* nil) (setq *command-line-switches* nil) (let ((cmd-strings lisp::lisp-command-line-list) @@ -103,7 +103,7 @@ (return-from process-command-strings nil)) ;; Set command line switches. - ;; + ;; (loop (unless str (return (setf *command-line-switches* @@ -119,14 +119,16 @@ (let (word-list) (loop (unless str - (push (make-cmd-switch switch value (nreverse word-list)) - *command-line-switches*) + (when init-command-switches-p + (push (make-cmd-switch switch value (nreverse word-list)) + *command-line-switches*)) (return nil)) (unless (zerop (length (the simple-string str))) (when (char= #\- (schar str 0)) - (push (make-cmd-switch switch value (nreverse word-list)) - *command-line-switches*) + (when init-command-switches-p + (push (make-cmd-switch switch value (nreverse word-list)) + *command-line-switches*)) (when (and (= (length str) 2) (char= #\- (schar str 1))) ;; Gather up everything after --, and exit. @@ -134,7 +136,7 @@ (setf str nil)) (return nil)) (push str word-list)) - (setq str (pop cmd-strings)))))))) + (setq str (pop cmd-strings))))))))) (defun get-command-line-switch (sname) "Accepts the name of a switch as a string and returns the value of diff --git a/src/code/describe.lisp b/src/code/describe.lisp index b1bd93f8cbecc6f927e935198eadc63f6c532f05..3616b3616560e90fd7505273f1309a06b9c6f665 100644 --- a/src/code/describe.lisp +++ b/src/code/describe.lisp @@ -313,11 +313,12 @@ (let ((info (kernel:%code-debug-info code-obj))) (when info (let ((sources (c::debug-info-source info))) - (format t (intl:gettext "~&On ~A it was compiled from:") - (format-universal-time nil - (c::debug-source-compiled - (first sources)) - :style :iso8601)) + (when sources + (format t (intl:gettext "~&On ~A it was compiled from:") + (format-universal-time nil + (c::debug-source-compiled + (first sources)) + :style :iso8601))) (dolist (source sources) (let ((name (c::debug-source-name source))) (ecase (c::debug-source-from source) diff --git a/src/code/save.lisp b/src/code/save.lisp index 11450d0bb0e8216718a288e382ed000080f5fe8b..696d79e7a3d4bc88006d3c98bc730a4539032e86 100644 --- a/src/code/save.lisp +++ b/src/code/save.lisp @@ -153,7 +153,8 @@ (process-command-line t) #+:executable (executable nil) - (batch-mode nil)) + (batch-mode nil) + (quiet nil)) "Saves a CMU Common Lisp core image in the file of the specified name. The following keywords are defined: @@ -191,8 +192,10 @@ :process-command-line If true (the default), process command-line switches via the normal - mechanisms, otherwise ignore all switches (except those processed by the - C startup code). + mechanisms, otherwise ignore all switches (except those processed by + the C startup code). In either case, the command line switches are + saved in *COMMAND-LINE-STRINGS* and + *COMMAND-LINE-APPLICATION-ARGUMENTS*. :executable If nil (the default), save-lisp will save using the traditional @@ -203,7 +206,14 @@ :batch-mode If nil (the default), then the presence of the -batch command-line switch will invoke batch-mode processing. If true, the produced core - will always be in batch-mode, regardless of any command-line switches." + will always be in batch-mode, regardless of any command-line switches. + + :quiet + If non-NIL, loading, compiling, and GC messages are suppressed. + This is equivalent to setting *load-verbose*, *compile-verbose*, + *compile-print*, *compile-progress*, *require-verbose*, and + *gc-verbose* all to NIL. If NIL (the default), the default + values of these variables are used." (unless (probe-file (directory-namestring core-file-name)) (error 'simple-file-error @@ -240,8 +250,7 @@ (environment-init) (dolist (f *after-save-initializations*) (funcall f)) (intl::setlocale) - (when process-command-line - (ext::process-command-strings)) + (ext::process-command-strings process-command-line) (setf *editor-lisp-p* nil) (macrolet ((find-switch (name) `(find ,name *command-line-switches* @@ -249,7 +258,8 @@ :test #'(lambda (x y) (declare (simple-string x y)) (string-equal x y))))) - (when (and process-command-line (find-switch "quiet")) + (when (or quiet + (and process-command-line (find-switch "quiet"))) (setq *load-verbose* nil *compile-verbose* nil *compile-print* nil @@ -285,8 +295,9 @@ (ext::invoke-switch-demons *command-line-switches* *command-switch-demons*)) (when (and print-herald - (not (and process-command-line - (find-switch "quiet")))) + (not (or quiet + (and process-command-line + (find-switch "quiet"))))) ;; Don't print the herald if -quiet is given. (print-herald))))) (funcall init-function)) diff --git a/src/compiler/main.lisp b/src/compiler/main.lisp index 5c5386dd829b723f16ade88b3ea975061008564a..8a5d92d85c4dd69df848ceb39ef27723c8b4120f 100644 --- a/src/compiler/main.lisp +++ b/src/compiler/main.lisp @@ -2041,11 +2041,7 @@ ((or cons eval:interpreted-function) `#',(get-lambda-to-compile definition)) (function - (multiple-value-bind (exp lexenv) - (function-lambda-expression definition) - (if (and exp (not lexenv)) - `#',exp - `',definition))))) + definition))) (*source-info* (make-lisp-source-info form)) (*top-level-lambdas* ()) (*converting-for-interpreter* nil) @@ -2069,6 +2065,14 @@ (*gensym-counter* 0) (*current-function-names* (list name)) (intl::*default-domain* intl::*default-domain*)) + ;; As mentioned above, we can return the same function if the + ;; function was already compiled. We do this when FORM is EQ + ;; to DEFINITION (which happens above if we have a compiled + ;; function that we don't have the source for or was defined + ;; in a non-null environment. + (when (and name (eq form definition)) + (return-from compile + (values name nil nil))) (with-debug-counters (clear-stuff) (find-source-paths form 0) diff --git a/src/docs/cmu-user/cmu-user.tex b/src/docs/cmu-user/cmu-user.tex index ee7eae031205c011626e274d04be70158b355a6c..42654aba0136222269e3c718409a99f59e9c2e1f 100644 --- a/src/docs/cmu-user/cmu-user.tex +++ b/src/docs/cmu-user/cmu-user.tex @@ -48,7 +48,7 @@ \newcommand{\keywords}{lisp, Common Lisp, manual, compiler, programming language implementation, programming environment} -\date{October 2014 \\ 20f} +\date{October 2016 \\ 21b} \begin{document} diff --git a/src/docs/cmu-user/extensions.tex b/src/docs/cmu-user/extensions.tex index 839ce5d6fee4f0fedc8a8e5054c0e4673dab7db8..b5bbfff251abf74288129f5caa1a54b4e50e486b 100644 --- a/src/docs/cmu-user/extensions.tex +++ b/src/docs/cmu-user/extensions.tex @@ -1099,7 +1099,8 @@ It is possible to run programs from Lisp by using the following function. \morekeys{\kwd{if-input-does-not-exist}} \yetmorekeys{\kwd{output} \kwd{if-output-exists}} \yetmorekeys{\kwd{error} \kwd{if-error-exists}} - \yetmorekeys{\kwd{status-hook} \kwd{before-execve}}}} + \yetmorekeys{\kwd{status-hook} \kwd{external-format}} + \yetmorekeys{\kwd{element-type}}}} \code{run-program} runs \var{program} in a child process. \var{Program} should be a pathname or string naming the program. @@ -1154,6 +1155,11 @@ It is possible to run programs from Lisp by using the following function. already contains all the input for the process. In this case \code{run-program} reads all the input from this stream before returning, so this cannot be used to interact with the process. + If \kwd{input} is a string stream, it is up to the caller to call + \code{string-encode} or other function to convert the string to + the appropriate encoding. In either case, the least significant 8 + bits of the \code{char-code} of each \code{character} is + sent to the program. \item[\kwd{if-input-does-not-exist}] This specifies what to do if the input file does not exist. The following values are valid: @@ -1172,7 +1178,10 @@ It is possible to run programs from Lisp by using the following function. \code{process-output} slot contains an input stream from which you can read the program's output. \kwd{output} can also be a stream in which case all output from the process is written to this - stream. + stream. If \kwd{output} is a string-stream, each octet read from + the program is converted to a character using \code{code-char}. + It is up to the caller to convert this using the appropriate + external format to create the desired encoded string. \item[\kwd{if-output-exists}] This specifies what to do if the output file already exists. The following values are valid: @@ -1197,6 +1206,15 @@ It is possible to run programs from Lisp by using the following function. the process changes status. This is especially useful when specifying \kwd{wait} as \nil. The function takes the process as a required argument. + + \item[\kwd{external-format}] This specifies the external format to + use for streams created for \code{run-program}. This does not + apply to string streams passed in as \kwd{input} or \kwd{output} + parameters. + + \item[\kwd{element-type}] If streams are created \code{run-program}, + use this as the \kwd{element-type} for the stream. Defaults to + \code{BASE-CHAR}. % \item[\kwd{before-execve}] This specifies a function to run in the % child process before it becomes the program to run. This is diff --git a/src/general-info/release-21b.txt b/src/general-info/release-21b.txt index 44ab2215253dff0d9a83e1512d22f862ed4d8ae7..9c3ba2da6c642d2a595e420943ae106d7da48f4c 100644 --- a/src/general-info/release-21b.txt +++ b/src/general-info/release-21b.txt @@ -48,7 +48,7 @@ New in this release: WITH-FLOAT-TRAPS-MASKED. * (EXPT 0 power) doesn't throw INTEXP-LIMIT-ERROR anymore for any integer value of power. - * Starting cmucl with "-dyanmic-space-size 0" means using the + * Starting cmucl with "-dynamic-space-size 0" means using the maximum possible heap size for the platform. * More descriptive docstring for * *environment-list* @@ -56,16 +56,21 @@ New in this release: * Maximum dynamic-space-size on Linux reduced to 1530 MB because that's the largest available space on 32-bit Ubuntu 11.10. * For linux, darwin, and solaris/sparc, the binding stack and - control stack are now mapped into memory whereever the OS wishes + control stack are now mapped into memory wherever the OS wishes to place them instead of being mapped into a fixed location. This is indicated by new feature :relocatable-stacks. * ANSI compliance fixes: * PATHNAME-MATCH-P did not accept search-lists. + * (compile 'foo) returns the compiled function if foo is already + compiled. (See Ticket #24). This is a change in behavior for + developers where foo would be recompiled if the source was + available. Developers might want to investigate uncompile + combined with compile to get the old behavior back. - * Bugfixes: + * Bug fixes: * Linux was missing unix-setitimer which prevented saving cores. - * Generate inxact exceptions more carefully. + * Generate inexact exceptions more carefully. * Fix FP issue when building with Xcode 7.2 (and newer versions of clang). (See ticket #12.) * Cleanups in handling floating-point exceptions. See Tickets #15 @@ -94,8 +99,13 @@ New in this release: * Ticket #27 fixed: Regression: ASDF test failures * Ticket #28 fixed: Recursive function definition during cross-compile + * Ticket #30 fixed: Compilation of (describe 'foo) + * Ticket #31 fixed: (compile #'foo) fails + * Ticket #24 fixed: Compilation of (compile 'foo) + * Ticket #32 fixed: doc fix: ext:run-program has no before-execve option * Other changes: + * Update user manual. * Improvements to the PCL implementation of CLOS: diff --git a/src/i18n/locale/cmucl.pot b/src/i18n/locale/cmucl.pot index 5cdda5309bb89201971b17e3931c00fa2a17070f..7847d729e565a9bf5b02e9b2d6cc07f4c7b0e45d 100644 --- a/src/i18n/locale/cmucl.pot +++ b/src/i18n/locale/cmucl.pot @@ -6713,8 +6713,10 @@ msgid "" "\n" " :process-command-line\n" " If true (the default), process command-line switches via the normal\n" -" mechanisms, otherwise ignore all switches (except those processed by the\n" -" C startup code).\n" +" mechanisms, otherwise ignore all switches (except those processed by\n" +" the C startup code). In either case, the command line switches are\n" +" saved in *COMMAND-LINE-STRINGS* and\n" +" *COMMAND-LINE-APPLICATION-ARGUMENTS*.\n" "\n" " :executable\n" " If nil (the default), save-lisp will save using the traditional\n" @@ -6725,7 +6727,14 @@ msgid "" " :batch-mode\n" " If nil (the default), then the presence of the -batch command-line\n" " switch will invoke batch-mode processing. If true, the produced core\n" -" will always be in batch-mode, regardless of any command-line switches." +" will always be in batch-mode, regardless of any command-line switches.\n" +"\n" +" :quiet\n" +" If non-NIL, loading, compiling, and GC messages are suppressed.\n" +" This is equivalent to setting *load-verbose*, *compile-verbose*,\n" +" *compile-print*, *compile-progress*, *require-verbose*, and\n" +" *gc-verbose* all to NIL. If NIL (the default), the default\n" +" values of these variables are used." msgstr "" #: src/code/save.lisp diff --git a/tests/issues.lisp b/tests/issues.lisp index b02fc1266886d13ed1a6771d2f3fe786274ae9ba..d709a71910c4cae2e5aeca42c6ac2e950dc1c1fb 100644 --- a/tests/issues.lisp +++ b/tests/issues.lisp @@ -298,3 +298,26 @@ (assert-eql (length in-string) (length out-string)) (assert-equal in-string out-string))))) + + +(define-test issue.30 + (:tag :issues) + (let* ((test-file #.(merge-pathnames #p"resources/issue-30.lisp" cl:*load-pathname*)) + (fasl-file (compile-file-pathname test-file))) + ;; Compiling and loading the test file should succeed without + ;; errors. + (assert-true (pathnamep test-file)) + (assert-true (pathnamep fasl-file)) + (assert-equalp (list fasl-file nil nil) + (multiple-value-list (compile-file test-file :load t))))) + +(define-test issue.24 + (:tag :issues) + (let* ((test-file #.(merge-pathnames #p"resources/issue-24.lisp" cl:*load-pathname*))) + (assert-true (compile-file test-file :load t)))) + +(define-test issue.32 + (:tag :issues) + (assert-error 'kernel:simple-program-error + (ext:run-program "cat" nil + :before-execve t))) diff --git a/tests/resources/issue-30.lisp b/tests/resources/issue-30.lisp new file mode 100644 index 0000000000000000000000000000000000000000..d924295797b9d8062458a5bce9b49d63f3de5d3a --- /dev/null +++ b/tests/resources/issue-30.lisp @@ -0,0 +1,4 @@ +(defun foo () + (print "Hello world")) + +(describe 'foo)