diff options
| author | Daniel LaLiberte | 1994-03-24 20:26:05 +0000 |
|---|---|---|
| committer | Daniel LaLiberte | 1994-03-24 20:26:05 +0000 |
| commit | 65c3c4ed1cd768020669a1f409787effd7110800 (patch) | |
| tree | 8fc1ca5201dc8bc209bfb36da0fcc0869ff1328b | |
| parent | e6512bcf1f9ef48cfcf96bb4d5f93e109a784c09 (diff) | |
| download | emacs-65c3c4ed1cd768020669a1f409787effd7110800.tar.gz emacs-65c3c4ed1cd768020669a1f409787effd7110800.zip | |
Change "internal" to "original" throughout.
(add-custom-printer, delete-custom-printer) replace old customizers.
(with-custom-print) new
(custom-prin1-to-string) Made it more robust.
| -rw-r--r-- | lisp/emacs-lisp/cust-print.el | 667 |
1 files changed, 406 insertions, 261 deletions
diff --git a/lisp/emacs-lisp/cust-print.el b/lisp/emacs-lisp/cust-print.el index 863c8daaf3b..28569f05985 100644 --- a/lisp/emacs-lisp/cust-print.el +++ b/lisp/emacs-lisp/cust-print.el | |||
| @@ -3,10 +3,14 @@ | |||
| 3 | ;; Copyright (C) 1992 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1992 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu> | 5 | ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu> |
| 6 | ;; Version: 1.0 | ||
| 7 | ;; Adapted-By: ESR | 6 | ;; Adapted-By: ESR |
| 8 | ;; Keywords: extensions | 7 | ;; Keywords: extensions |
| 9 | 8 | ||
| 9 | ;; LCD Archive Entry: | ||
| 10 | ;; cust-print|Daniel LaLiberte|liberte@cs.uiuc.edu | ||
| 11 | ;; |Handle print-level, print-circle and more. | ||
| 12 | ;; |$Date: 1994/03/23 20:34:29 $|$Revision: 1.4 $| | ||
| 13 | |||
| 10 | ;; This file is part of GNU Emacs. | 14 | ;; This file is part of GNU Emacs. |
| 11 | 15 | ||
| 12 | ;; GNU Emacs is free software; you can redistribute it and/or modify | 16 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| @@ -23,6 +27,42 @@ | |||
| 23 | ;; along with GNU Emacs; see the file COPYING. If not, write to | 27 | ;; along with GNU Emacs; see the file COPYING. If not, write to |
| 24 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 28 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
| 25 | 29 | ||
| 30 | ;;; =============================== | ||
| 31 | ;;; $Header: /import/kaplan/kaplan/liberte/Edebug/RCS/cust-print.el,v 1.4 1994/03/23 20:34:29 liberte Exp liberte $ | ||
| 32 | ;;; $Log: cust-print.el,v $ | ||
| 33 | ;;; Revision 1.4 1994/03/23 20:34:29 liberte | ||
| 34 | ;;; * Change "emacs" to "original" - I just can't decide. | ||
| 35 | ;;; | ||
| 36 | ;;; Revision 1.3 1994/02/21 21:25:36 liberte | ||
| 37 | ;;; * Make custom-prin1-to-string more robust when errors occur. | ||
| 38 | ;;; * Change "internal" to "emacs". | ||
| 39 | ;;; | ||
| 40 | ;;; Revision 1.2 1993/11/22 22:36:36 liberte | ||
| 41 | ;;; * Simplified and generalized printer customization. | ||
| 42 | ;;; custom-printers is an alist of (PREDICATE . PRINTER) pairs | ||
| 43 | ;;; for any data types. The PRINTER function should print to | ||
| 44 | ;;; `standard-output' add-custom-printer and delete-custom-printer | ||
| 45 | ;;; change custom-printers. | ||
| 46 | ;;; | ||
| 47 | ;;; * Installation function now called install-custom-print. The | ||
| 48 | ;;; old name is still around for now. | ||
| 49 | ;;; | ||
| 50 | ;;; * New macro with-custom-print (added earlier) - executes like | ||
| 51 | ;;; progn but with custom-print activated temporarily. | ||
| 52 | ;;; | ||
| 53 | ;;; * Cleaned up comments for replacements of standardard printers. | ||
| 54 | ;;; | ||
| 55 | ;;; * Changed custom-prin1-to-string to use a temporary buffer. | ||
| 56 | ;;; | ||
| 57 | ;;; * Option custom-print-vectors (added earlier) - controls whether | ||
| 58 | ;;; vectors should be printed according to print-length and | ||
| 59 | ;;; print-length. Emacs doesnt do this, but cust-print would | ||
| 60 | ;;; otherwise do it only if custom printing is required. | ||
| 61 | ;;; | ||
| 62 | ;;; * Uninterned symbols are treated as non-read-equivalent. | ||
| 63 | ;;; | ||
| 64 | |||
| 65 | |||
| 26 | ;;; Commentary: | 66 | ;;; Commentary: |
| 27 | 67 | ||
| 28 | ;; This package provides a general print handler for prin1 and princ | 68 | ;; This package provides a general print handler for prin1 and princ |
| @@ -39,27 +79,35 @@ | |||
| 39 | ;; circular lists (where cdrs of lists point back; what is the right | 79 | ;; circular lists (where cdrs of lists point back; what is the right |
| 40 | ;; term here?), you can limit the length of printing with | 80 | ;; term here?), you can limit the length of printing with |
| 41 | ;; print-length. But car circular lists and circular vectors generate | 81 | ;; print-length. But car circular lists and circular vectors generate |
| 42 | ;; the above mentioned untrappable error in Emacs version 18. Version | 82 | ;; the above mentioned error in Emacs version 18. Version |
| 43 | ;; 19 will support print-level, but it is often useful to get a better | 83 | ;; 19 supports print-level, but it is often useful to get a better |
| 44 | ;; print representation of circular structures; the print-circle | 84 | ;; print representation of circular and shared structures; the print-circle |
| 45 | ;; option may be used to print more concise representations. | 85 | ;; option may be used to print more concise representations. |
| 46 | 86 | ||
| 47 | ;; There are two main ways to use this package. First, you may | 87 | ;; There are three main ways to use this package. First, you may |
| 48 | ;; replace prin1, princ, and some subroutines that use them by calling | 88 | ;; replace prin1, princ, and some subroutines that use them by calling |
| 49 | ;; install-custom-print-funcs so that any use of these functions in | 89 | ;; install-custom-print so that any use of these functions in |
| 50 | ;; lisp code will be affected. Second, you could call the custom | 90 | ;; Lisp code will be affected; you can later reset with |
| 51 | ;; routines directly, thus only affecting the printing that requires | 91 | ;; uninstall-custom-print. Second, you may temporarily install |
| 52 | ;; them. | 92 | ;; these functions with the macro with-custom-print. Third, you |
| 53 | 93 | ;; could call the custom routines directly, thus only affecting the | |
| 54 | ;; Note that subroutines which call print subroutines directly will not | 94 | ;; printing that requires them. |
| 55 | ;; use the custom print functions. In particular, the evaluation | 95 | |
| 96 | ;; Note that subroutines which call print subroutines directly will | ||
| 97 | ;; not use the custom print functions. In particular, the evaluation | ||
| 56 | ;; functions like eval-region call the print subroutines directly. | 98 | ;; functions like eval-region call the print subroutines directly. |
| 57 | ;; Therefore, evaluating (aref circ-list 0), which calls error | 99 | ;; Therefore, if you evaluate (aref circ-list 0), where circ-list is a |
| 58 | ;; directly (because circ-list is not an array), will jump to the top | 100 | ;; circular list rather than an array, aref calls error directly which |
| 59 | ;; level instead of printing the circular list. | 101 | ;; will jump to the top level instead of printing the circular list. |
| 102 | |||
| 103 | ;; Uninterned symbols are recognized when print-circle is non-nil, | ||
| 104 | ;; but they are not printed specially here. Use the cl-packages package | ||
| 105 | ;; to print according to print-gensym. | ||
| 60 | 106 | ||
| 61 | ;; Obviously the right way to implement this custom-print facility | 107 | ;; Obviously the right way to implement this custom-print facility is |
| 62 | ;; is in C. Please volunteer since I don't have the time or need. | 108 | ;; in C or with hooks into the standard printer. Please volunteer |
| 109 | ;; since I don't have the time or need. More CL-like printing | ||
| 110 | ;; capabilities could be added in the future. | ||
| 63 | 111 | ||
| 64 | ;; Implementation design: we want to use the same list and vector | 112 | ;; Implementation design: we want to use the same list and vector |
| 65 | ;; processing algorithm for all versions of prin1 and princ, since how | 113 | ;; processing algorithm for all versions of prin1 and princ, since how |
| @@ -68,31 +116,49 @@ | |||
| 68 | ;; required before the final printing. Thanks to Jamie Zawinski | 116 | ;; required before the final printing. Thanks to Jamie Zawinski |
| 69 | ;; for motivation and algorithms. | 117 | ;; for motivation and algorithms. |
| 70 | 118 | ||
| 119 | |||
| 120 | ;;; Code: | ||
| 71 | ;;========================================================= | 121 | ;;========================================================= |
| 72 | ;; export list: | ||
| 73 | 122 | ||
| 74 | ;; print-level | 123 | ;; If using cl-packages: |
| 75 | ;; print-circle | 124 | |
| 125 | '(defpackage "cust-print" | ||
| 126 | (:nicknames "CP" "custom-print") | ||
| 127 | (:use "el") | ||
| 128 | (:export | ||
| 129 | print-level | ||
| 130 | print-circle | ||
| 131 | |||
| 132 | install-custom-print | ||
| 133 | uninstall-custom-print | ||
| 134 | custom-print-installed-p | ||
| 135 | with-custom-print | ||
| 136 | |||
| 137 | custom-prin1 | ||
| 138 | custom-princ | ||
| 139 | custom-prin1-to-string | ||
| 140 | custom-print | ||
| 141 | custom-format | ||
| 142 | custom-message | ||
| 143 | custom-error | ||
| 144 | |||
| 145 | custom-printers | ||
| 146 | add-custom-printer | ||
| 147 | )) | ||
| 76 | 148 | ||
| 77 | ;; custom-print-list | 149 | '(in-package cust-print) |
| 78 | ;; custom-print-vector | ||
| 79 | ;; add-custom-print-list | ||
| 80 | ;; add-custom-print-vector | ||
| 81 | 150 | ||
| 82 | ;; install-custom-print-funcs | 151 | (require 'backquote) |
| 83 | ;; uninstall-custom-print-funcs | ||
| 84 | 152 | ||
| 85 | ;; custom-prin1 | 153 | ;; Emacs 18 doesnt have defalias. |
| 86 | ;; custom-princ | 154 | ;; Provide def for byte compiler. |
| 87 | ;; custom-prin1-to-string | 155 | (defun defalias (symbol func) (fset symbol func)) |
| 88 | ;; custom-print | 156 | ;; Better def when loaded. |
| 89 | ;; custom-format | 157 | (or (fboundp 'defalias) (fset 'defalias 'fset)) |
| 90 | ;; custom-message | ||
| 91 | ;; custom-error | ||
| 92 | 158 | ||
| 93 | ;;; Code: | 159 | |
| 94 | 160 | ;; Variables: | |
| 95 | (provide 'custom-print) | 161 | ;;========================================================= |
| 96 | 162 | ||
| 97 | ;;(defvar print-length nil | 163 | ;;(defvar print-length nil |
| 98 | ;; "*Controls how many elements of a list, at each level, are printed. | 164 | ;; "*Controls how many elements of a list, at each level, are printed. |
| @@ -102,7 +168,7 @@ | |||
| 102 | "*Controls how many levels deep a nested data object will print. | 168 | "*Controls how many levels deep a nested data object will print. |
| 103 | 169 | ||
| 104 | If nil, printing proceeds recursively and may lead to | 170 | If nil, printing proceeds recursively and may lead to |
| 105 | max-lisp-eval-depth being exceeded or an untrappable error may occur: | 171 | max-lisp-eval-depth being exceeded or an error may occur: |
| 106 | `Apparently circular structure being printed.' | 172 | `Apparently circular structure being printed.' |
| 107 | Also see `print-length' and `print-circle'. | 173 | Also see `print-length' and `print-circle'. |
| 108 | 174 | ||
| @@ -116,7 +182,7 @@ level 1.") | |||
| 116 | "*Controls the printing of recursive structures. | 182 | "*Controls the printing of recursive structures. |
| 117 | 183 | ||
| 118 | If nil, printing proceeds recursively and may lead to | 184 | If nil, printing proceeds recursively and may lead to |
| 119 | `max-lisp-eval-depth' being exceeded or an untrappable error may occur: | 185 | `max-lisp-eval-depth' being exceeded or an error may occur: |
| 120 | \"Apparently circular structure being printed.\" Also see | 186 | \"Apparently circular structure being printed.\" Also see |
| 121 | `print-length' and `print-level'. | 187 | `print-length' and `print-level'. |
| 122 | 188 | ||
| @@ -125,67 +191,101 @@ with `#N=' before the first occurrence (in the order of the print | |||
| 125 | representation) and `#N#' in place of each subsequent occurrence, | 191 | representation) and `#N#' in place of each subsequent occurrence, |
| 126 | where N is a positive decimal integer. | 192 | where N is a positive decimal integer. |
| 127 | 193 | ||
| 128 | Currently, there is no way to read this representation in Emacs.") | 194 | There is no way to read this representation in standard Emacs, |
| 195 | but if you need to do so, try the cl-read.el package.") | ||
| 129 | 196 | ||
| 130 | 197 | ||
| 131 | (defconst custom-print-list | 198 | (defvar custom-print-vectors nil |
| 132 | nil | 199 | "*Non-nil if printing of vectors should obey print-level and print-length. |
| 133 | ;; e.g. '((floatp . float-to-string)) | ||
| 134 | "An alist for custom printing of lists. | ||
| 135 | Pairs are of the form (PRED . CONVERTER). If PREDICATE is true | ||
| 136 | for an object, then CONVERTER is called with the object and should | ||
| 137 | return a string to be printed with `princ'. | ||
| 138 | Also see `custom-print-vector'.") | ||
| 139 | 200 | ||
| 140 | (defconst custom-print-vector | 201 | For Emacs 18, setting print-level, or adding custom print list or |
| 141 | nil | 202 | vector handling will make this happen anyway. Emacs 19 obeys |
| 142 | "An alist for custom printing of vectors. | 203 | print-level, but not for vectors.") |
| 143 | Pairs are of the form (PRED . CONVERTER). If PREDICATE is true | ||
| 144 | for an object, then CONVERTER is called with the object and should | ||
| 145 | return a string to be printed with `princ'. | ||
| 146 | Also see `custom-print-list'.") | ||
| 147 | 204 | ||
| 205 | |||
| 206 | ;; Custom printers | ||
| 207 | ;;========================================================== | ||
| 148 | 208 | ||
| 149 | (defun add-custom-print-list (pred converter) | 209 | (defconst custom-printers nil |
| 150 | "Add a pair of PREDICATE and CONVERTER to `custom-print-list'. | 210 | ;; e.g. '((symbolp . pkg::print-symbol)) |
| 151 | Any pair that has the same PREDICATE is first removed." | 211 | "An alist for custom printing of any type. |
| 152 | (setq custom-print-list (cons (cons pred converter) | 212 | Pairs are of the form (PREDICATE . PRINTER). If PREDICATE is true |
| 153 | (delq (assq pred custom-print-list) | 213 | for an object, then PRINTER is called with the object. |
| 154 | custom-print-list)))) | 214 | PRINTER should print to `standard-output' using cust-print-original-princ |
| 155 | ;; e.g. (add-custom-print-list 'floatp 'float-to-string) | 215 | if the standard printer is sufficient, or cust-print-prin for complex things. |
| 216 | The PRINTER should return the object being printed. | ||
| 156 | 217 | ||
| 218 | Don't modify this variable directly. Use `add-custom-printer' and | ||
| 219 | `delete-custom-printer'") | ||
| 220 | ;; Should cust-print-original-princ and cust-print-prin be exported symbols? | ||
| 221 | ;; Or should the standard printers functions be replaced by | ||
| 222 | ;; CP ones in elisp so that CP internal functions need not be called? | ||
| 157 | 223 | ||
| 158 | (defun add-custom-print-vector (pred converter) | 224 | (defun add-custom-printer (pred printer) |
| 159 | "Add a pair of PREDICATE and CONVERTER to `custom-print-vector'. | 225 | "Add a pair of PREDICATE and PRINTER to `custom-printers'. |
| 160 | Any pair that has the same PREDICATE is first removed." | 226 | Any pair that has the same PREDICATE is first removed." |
| 161 | (setq custom-print-vector (cons (cons pred converter) | 227 | (setq custom-printers (cons (cons pred printer) |
| 162 | (delq (assq pred custom-print-vector) | 228 | (delq (assq pred custom-printers) |
| 163 | custom-print-vector)))) | 229 | custom-printers))) |
| 164 | 230 | ;; Rather than updating here, we could wait until cust-print-top-level is called. | |
| 165 | 231 | (cust-print-update-custom-printers)) | |
| 232 | |||
| 233 | (defun delete-custom-printer (pred) | ||
| 234 | "Delete the custom printer associated with PREDICATE." | ||
| 235 | (setq custom-printers (delq (assq pred custom-printers) | ||
| 236 | custom-printers)) | ||
| 237 | (cust-print-update-custom-printers)) | ||
| 238 | |||
| 239 | |||
| 240 | (defun cust-print-use-custom-printer (object) | ||
| 241 | ;; Default function returns nil. | ||
| 242 | nil) | ||
| 243 | |||
| 244 | (defun cust-print-update-custom-printers () | ||
| 245 | ;; Modify the definition of cust-print-use-custom-printer | ||
| 246 | (defalias 'cust-print-use-custom-printer | ||
| 247 | ;; We dont really want to require the byte-compiler. | ||
| 248 | ;; (byte-compile | ||
| 249 | (` (lambda (object) | ||
| 250 | (cond | ||
| 251 | (,@ (mapcar (function | ||
| 252 | (lambda (pair) | ||
| 253 | (` (((, (car pair)) object) | ||
| 254 | ((, (cdr pair)) object))))) | ||
| 255 | custom-printers)) | ||
| 256 | ;; Otherwise return nil. | ||
| 257 | (t nil) | ||
| 258 | ))) | ||
| 259 | ;; ) | ||
| 260 | )) | ||
| 261 | |||
| 262 | |||
| 263 | ;; Saving and restoring emacs printing routines. | ||
| 166 | ;;==================================================== | 264 | ;;==================================================== |
| 167 | ;; Saving and restoring internal printing routines. | ||
| 168 | 265 | ||
| 169 | (defun cust-print-set-function-cell (symbol-pair) | 266 | (defun cust-print-set-function-cell (symbol-pair) |
| 170 | (defalias (car symbol-pair) | 267 | (defalias (car symbol-pair) |
| 171 | (symbol-function (car (cdr symbol-pair))))) | 268 | (symbol-function (car (cdr symbol-pair))))) |
| 172 | 269 | ||
| 270 | (defun cust-print-original-princ (object &optional stream)) ; dummy def | ||
| 173 | 271 | ||
| 174 | (if (not (fboundp 'cust-print-internal-prin1)) | 272 | ;; Save emacs routines. |
| 273 | (if (not (fboundp 'cust-print-original-prin1)) | ||
| 175 | (mapcar 'cust-print-set-function-cell | 274 | (mapcar 'cust-print-set-function-cell |
| 176 | '((cust-print-internal-prin1 prin1) | 275 | '((cust-print-original-prin1 prin1) |
| 177 | (cust-print-internal-princ princ) | 276 | (cust-print-original-princ princ) |
| 178 | (cust-print-internal-print print) | 277 | (cust-print-original-print print) |
| 179 | (cust-print-internal-prin1-to-string prin1-to-string) | 278 | (cust-print-original-prin1-to-string prin1-to-string) |
| 180 | (cust-print-internal-format format) | 279 | (cust-print-original-format format) |
| 181 | (cust-print-internal-message message) | 280 | (cust-print-original-message message) |
| 182 | (cust-print-internal-error error)))) | 281 | (cust-print-original-error error)))) |
| 183 | 282 | ||
| 184 | 283 | ||
| 185 | (defun install-custom-print-funcs () | 284 | (defalias 'install-custom-print-funcs 'install-custom-print) |
| 285 | (defun install-custom-print () | ||
| 186 | "Replace print functions with general, customizable, Lisp versions. | 286 | "Replace print functions with general, customizable, Lisp versions. |
| 187 | The internal subroutines are saved away, and you can reinstall them | 287 | The emacs subroutines are saved away, and you can reinstall them |
| 188 | by running `uninstall-custom-print-funcs'." | 288 | by running `uninstall-custom-print'." |
| 189 | (interactive) | 289 | (interactive) |
| 190 | (mapcar 'cust-print-set-function-cell | 290 | (mapcar 'cust-print-set-function-cell |
| 191 | '((prin1 custom-prin1) | 291 | '((prin1 custom-prin1) |
| @@ -195,193 +295,227 @@ by running `uninstall-custom-print-funcs'." | |||
| 195 | (format custom-format) | 295 | (format custom-format) |
| 196 | (message custom-message) | 296 | (message custom-message) |
| 197 | (error custom-error) | 297 | (error custom-error) |
| 198 | ))) | 298 | )) |
| 299 | t) | ||
| 199 | 300 | ||
| 200 | (defun uninstall-custom-print-funcs () | 301 | (defalias 'uninstall-custom-print-funcs 'uninstall-custom-print) |
| 201 | "Reset print functions to their internal subroutines." | 302 | (defun uninstall-custom-print () |
| 303 | "Reset print functions to their emacs subroutines." | ||
| 202 | (interactive) | 304 | (interactive) |
| 203 | (mapcar 'cust-print-set-function-cell | 305 | (mapcar 'cust-print-set-function-cell |
| 204 | '((prin1 cust-print-internal-prin1) | 306 | '((prin1 cust-print-original-prin1) |
| 205 | (princ cust-print-internal-princ) | 307 | (princ cust-print-original-princ) |
| 206 | (print cust-print-internal-print) | 308 | (print cust-print-original-print) |
| 207 | (prin1-to-string cust-print-internal-prin1-to-string) | 309 | (prin1-to-string cust-print-original-prin1-to-string) |
| 208 | (format cust-print-internal-format) | 310 | (format cust-print-original-format) |
| 209 | (message cust-print-internal-message) | 311 | (message cust-print-original-message) |
| 210 | (error cust-print-internal-error) | 312 | (error cust-print-original-error) |
| 211 | ))) | 313 | )) |
| 212 | 314 | t) | |
| 213 | 315 | ||
| 316 | (defalias 'custom-print-funcs-installed-p 'custom-print-installed-p) | ||
| 317 | (defun custom-print-installed-p () | ||
| 318 | "Return t if custom-print is currently installed, nil otherwise." | ||
| 319 | (eq (symbol-function 'custom-prin1) (symbol-function 'prin1))) | ||
| 320 | |||
| 321 | (put 'with-custom-print-funcs 'edebug-form-spec '(body)) | ||
| 322 | (put 'with-custom-print 'edebug-form-spec '(body)) | ||
| 323 | |||
| 324 | (defalias 'with-custom-print-funcs 'with-custom-print) | ||
| 325 | (defmacro with-custom-print (&rest body) | ||
| 326 | "Temporarily install the custom print package while executing BODY." | ||
| 327 | (` (unwind-protect | ||
| 328 | (progn | ||
| 329 | (install-custom-print) | ||
| 330 | (,@ body)) | ||
| 331 | (uninstall-custom-print)))) | ||
| 332 | |||
| 333 | |||
| 334 | ;; Lisp replacements for prin1 and princ, and for some subrs that use them | ||
| 214 | ;;=============================================================== | 335 | ;;=============================================================== |
| 215 | ;; Lisp replacements for prin1 and princ and for subrs that use prin1 | 336 | ;; - so far only the printing and formatting subrs. |
| 216 | ;; (or princ) -- so far only the printing and formatting subrs. | ||
| 217 | 337 | ||
| 218 | (defun custom-prin1 (object &optional stream) | 338 | (defun custom-prin1 (object &optional stream) |
| 219 | "Replacement for standard `prin1'. | 339 | "Output the printed representation of OBJECT, any Lisp object. |
| 220 | Uses the appropriate printer depending on the values of `print-level' | ||
| 221 | and `print-circle' (which see). | ||
| 222 | |||
| 223 | Output the printed representation of OBJECT, any Lisp object. | ||
| 224 | Quoting characters are printed when needed to make output that `read' | 340 | Quoting characters are printed when needed to make output that `read' |
| 225 | can handle, whenever this is possible. | 341 | can handle, whenever this is possible. |
| 226 | Output stream is STREAM, or value of `standard-output' (which see)." | 342 | Output stream is STREAM, or value of `standard-output' (which see). |
| 227 | (cust-print-top-level object stream 'cust-print-internal-prin1)) | 343 | |
| 344 | This is the custom-print replacement for the standard `prin1'. It | ||
| 345 | uses the appropriate printer depending on the values of `print-level' | ||
| 346 | and `print-circle' (which see)." | ||
| 347 | (cust-print-top-level object stream 'cust-print-original-prin1)) | ||
| 228 | 348 | ||
| 229 | 349 | ||
| 230 | (defun custom-princ (object &optional stream) | 350 | (defun custom-princ (object &optional stream) |
| 231 | "Same as `custom-prin1' except no quoting." | 351 | "Output the printed representation of OBJECT, any Lisp object. |
| 232 | (cust-print-top-level object stream 'cust-print-internal-princ)) | 352 | No quoting characters are used; no delimiters are printed around |
| 353 | the contents of strings. | ||
| 354 | Output stream is STREAM, or value of `standard-output' (which see). | ||
| 233 | 355 | ||
| 234 | (defvar custom-prin1-chars) | 356 | This is the custom-print replacement for the standard `princ'." |
| 357 | (cust-print-top-level object stream 'cust-print-original-princ)) | ||
| 235 | 358 | ||
| 236 | (defun custom-prin1-to-string-func (c) | ||
| 237 | "Stream function for `custom-prin1-to-string'." | ||
| 238 | (setq custom-prin1-chars (cons c custom-prin1-chars))) | ||
| 239 | 359 | ||
| 240 | (defun custom-prin1-to-string (object) | 360 | (defun custom-prin1-to-string (object) |
| 241 | "Replacement for standard `prin1-to-string'." | 361 | "Return a string containing the printed representation of OBJECT, |
| 242 | (let ((custom-prin1-chars nil)) | 362 | any Lisp object. Quoting characters are used when needed to make output |
| 243 | (custom-prin1 object 'custom-prin1-to-string-func) | 363 | that `read' can handle, whenever this is possible. |
| 244 | (concat (nreverse custom-prin1-chars)))) | 364 | |
| 365 | This is the custom-print replacement for the standard `prin1-to-string'." | ||
| 366 | (let ((buf (get-buffer-create " *custom-print-temp*"))) | ||
| 367 | ;; We must erase the buffer before printing in case an error | ||
| 368 | ;; occured during the last prin1-to-string and we are in debugger. | ||
| 369 | (save-excursion | ||
| 370 | (set-buffer buf) | ||
| 371 | (erase-buffer)) | ||
| 372 | ;; We must be in the current-buffer when the print occurs. | ||
| 373 | (custom-prin1 object buf) | ||
| 374 | (save-excursion | ||
| 375 | (set-buffer buf) | ||
| 376 | (buffer-string) | ||
| 377 | ;; We could erase the buffer again, but why bother? | ||
| 378 | ))) | ||
| 245 | 379 | ||
| 246 | 380 | ||
| 247 | (defun custom-print (object &optional stream) | 381 | (defun custom-print (object &optional stream) |
| 248 | "Replacement for standard `print'." | 382 | "Output the printed representation of OBJECT, with newlines around it. |
| 249 | (cust-print-internal-princ "\n") | 383 | Quoting characters are printed when needed to make output that `read' |
| 384 | can handle, whenever this is possible. | ||
| 385 | Output stream is STREAM, or value of `standard-output' (which see). | ||
| 386 | |||
| 387 | This is the custom-print replacement for the standard `print'." | ||
| 388 | (cust-print-original-princ "\n" stream) | ||
| 250 | (custom-prin1 object stream) | 389 | (custom-prin1 object stream) |
| 251 | (cust-print-internal-princ "\n")) | 390 | (cust-print-original-princ "\n" stream)) |
| 252 | 391 | ||
| 253 | 392 | ||
| 254 | (defun custom-format (fmt &rest args) | 393 | (defun custom-format (fmt &rest args) |
| 255 | "Replacement for standard `format'. | 394 | "Format a string out of a control-string and arguments. |
| 256 | 395 | The first argument is a control string. It, and subsequent arguments | |
| 257 | Calls format after first making strings for list or vector args. | 396 | substituted into it, become the value, which is a string. |
| 258 | The format specification for such args should be `%s' in any case, so a | 397 | It may contain %s or %d or %c to substitute successive following arguments. |
| 259 | string argument will also work. The string is generated with | 398 | %s means print an argument as a string, %d means print as number in decimal, |
| 260 | `custom-prin1-to-string', which quotes quotable characters." | 399 | %c means print a number as a single character. |
| 261 | (apply 'cust-print-internal-format fmt | 400 | The argument used by %s must be a string or a symbol; |
| 401 | the argument used by %d, %b, %o, %x or %c must be a number. | ||
| 402 | |||
| 403 | This is the custom-print replacement for the standard `format'. It | ||
| 404 | calls the emacs `format' after first making strings for list, | ||
| 405 | vector, or symbol args. The format specification for such args should | ||
| 406 | be `%s' in any case, so a string argument will also work. The string | ||
| 407 | is generated with `custom-prin1-to-string', which quotes quotable | ||
| 408 | characters." | ||
| 409 | (apply 'cust-print-original-format fmt | ||
| 262 | (mapcar (function (lambda (arg) | 410 | (mapcar (function (lambda (arg) |
| 263 | (if (or (listp arg) (vectorp arg)) | 411 | (if (or (listp arg) (vectorp arg) (symbolp arg)) |
| 264 | (custom-prin1-to-string arg) | 412 | (custom-prin1-to-string arg) |
| 265 | arg))) | 413 | arg))) |
| 266 | args))) | 414 | args))) |
| 267 | 415 | ||
| 268 | 416 | ||
| 269 | |||
| 270 | (defun custom-message (fmt &rest args) | 417 | (defun custom-message (fmt &rest args) |
| 271 | "Replacement for standard `message' that works like `custom-format'." | 418 | "Print a one-line message at the bottom of the screen. |
| 272 | ;; It doesn't work to princ the result of custom-format | 419 | The first argument is a control string. |
| 420 | It may contain %s or %d or %c to print successive following arguments. | ||
| 421 | %s means print an argument as a string, %d means print as number in decimal, | ||
| 422 | %c means print a number as a single character. | ||
| 423 | The argument used by %s must be a string or a symbol; | ||
| 424 | the argument used by %d or %c must be a number. | ||
| 425 | |||
| 426 | This is the custom-print replacement for the standard `message'. | ||
| 427 | See `custom-format' for the details." | ||
| 428 | ;; It doesn't work to princ the result of custom-format as in: | ||
| 429 | ;; (cust-print-original-princ (apply 'custom-format fmt args)) | ||
| 273 | ;; because the echo area requires special handling | 430 | ;; because the echo area requires special handling |
| 274 | ;; to avoid duplicating the output. cust-print-internal-message does it right. | 431 | ;; to avoid duplicating the output. |
| 275 | ;; (cust-print-internal-princ (apply 'custom-format fmt args)) | 432 | ;; cust-print-original-message does it right. |
| 276 | (apply 'cust-print-internal-message fmt | 433 | (apply 'cust-print-original-message fmt |
| 277 | (mapcar (function (lambda (arg) | 434 | (mapcar (function (lambda (arg) |
| 278 | (if (or (listp arg) (vectorp arg)) | 435 | (if (or (listp arg) (vectorp arg) (symbolp arg)) |
| 279 | (custom-prin1-to-string arg) | 436 | (custom-prin1-to-string arg) |
| 280 | arg))) | 437 | arg))) |
| 281 | args))) | 438 | args))) |
| 282 | 439 | ||
| 283 | 440 | ||
| 284 | (defun custom-error (fmt &rest args) | 441 | (defun custom-error (fmt &rest args) |
| 285 | "Replacement for standard `error' that uses `custom-format'" | 442 | "Signal an error, making error message by passing all args to `format'. |
| 443 | |||
| 444 | This is the custom-print replacement for the standard `error'. | ||
| 445 | See `custom-format' for the details." | ||
| 286 | (signal 'error (list (apply 'custom-format fmt args)))) | 446 | (signal 'error (list (apply 'custom-format fmt args)))) |
| 287 | 447 | ||
| 288 | 448 | ||
| 289 | ;;========================================= | 449 | |
| 290 | ;; Support for custom prin1 and princ | 450 | ;; Support for custom prin1 and princ |
| 451 | ;;========================================= | ||
| 291 | 452 | ||
| 453 | ;; Defs to quiet byte-compiler. | ||
| 292 | (defvar circle-table) | 454 | (defvar circle-table) |
| 293 | (defvar circle-tree) | 455 | (defvar cust-print-current-level) |
| 294 | (defvar circle-level) | 456 | |
| 457 | (defun cust-print-original-printer (object)) ; One of the standard printers. | ||
| 458 | (defun cust-print-low-level-prin (object)) ; Used internally. | ||
| 459 | (defun cust-print-prin (object)) ; Call this to print recursively. | ||
| 295 | 460 | ||
| 296 | (defun cust-print-top-level (object stream internal-printer) | 461 | (defun cust-print-top-level (object stream emacs-printer) |
| 297 | "Set up for printing." | 462 | ;; Set up for printing. |
| 298 | (let ((standard-output (or stream standard-output)) | 463 | (let ((standard-output (or stream standard-output)) |
| 299 | (circle-table (and print-circle (cust-print-preprocess-circle-tree object))) | 464 | ;; circle-table will be non-nil if anything is circular. |
| 300 | (circle-level (or print-level -1)) | 465 | (circle-table (and print-circle |
| 301 | ) | 466 | (cust-print-preprocess-circle-tree object))) |
| 467 | (cust-print-current-level (or print-level -1))) | ||
| 302 | 468 | ||
| 303 | (defalias 'cust-print-internal-printer internal-printer) | 469 | (defalias 'cust-print-original-printer emacs-printer) |
| 304 | (defalias 'cust-print-low-level-prin | 470 | (defalias 'cust-print-low-level-prin |
| 305 | (cond | 471 | (cond |
| 306 | ((or custom-print-list | 472 | ((or custom-printers |
| 307 | custom-print-vector | 473 | circle-table |
| 308 | print-level ; comment out for version 19 | 474 | print-level ; comment out for version 19 |
| 309 | ) | 475 | ;; Emacs doesn't use print-level or print-length |
| 310 | 'cust-print-custom-object) | 476 | ;; for vectors, but custom-print can. |
| 311 | (circle-table | 477 | (if custom-print-vectors |
| 312 | 'cust-print-object) | 478 | (or print-level print-length))) |
| 313 | (t 'cust-print-internal-printer))) | 479 | 'cust-print-print-object) |
| 314 | (defalias 'cust-print-prin (if circle-table 'cust-print-circular 'cust-print-low-level-prin)) | 480 | (t 'cust-print-original-printer))) |
| 481 | (defalias 'cust-print-prin | ||
| 482 | (if circle-table 'cust-print-print-circular 'cust-print-low-level-prin)) | ||
| 315 | 483 | ||
| 316 | (cust-print-prin object) | 484 | (cust-print-prin object) |
| 317 | object)) | 485 | object)) |
| 318 | 486 | ||
| 319 | 487 | ||
| 320 | ;; Test object type and print accordingly. | 488 | (defun cust-print-print-object (object) |
| 321 | (defun cust-print-object (object) | 489 | ;; Test object type and print accordingly. |
| 322 | ;; Could be called as either cust-print-low-level-prin or cust-print-prin. | 490 | ;; Could be called as either cust-print-low-level-prin or cust-print-prin. |
| 323 | (cond | 491 | (cond |
| 324 | ((null object) (cust-print-internal-printer object)) | 492 | ((null object) (cust-print-original-printer object)) |
| 493 | ((cust-print-use-custom-printer object) object) | ||
| 325 | ((consp object) (cust-print-list object)) | 494 | ((consp object) (cust-print-list object)) |
| 326 | ((vectorp object) (cust-print-vector object)) | 495 | ((vectorp object) (cust-print-vector object)) |
| 327 | ;; All other types, just print. | 496 | ;; All other types, just print. |
| 328 | (t (cust-print-internal-printer object)))) | 497 | (t (cust-print-original-printer object)))) |
| 329 | |||
| 330 | 498 | ||
| 331 | ;; Test object type and print accordingly. | ||
| 332 | (defun cust-print-custom-object (object) | ||
| 333 | ;; Could be called as either cust-print-low-level-prin or cust-print-prin. | ||
| 334 | (cond | ||
| 335 | ((null object) (cust-print-internal-printer object)) | ||
| 336 | 499 | ||
| 337 | ((consp object) | 500 | (defun cust-print-print-circular (object) |
| 338 | (or (and custom-print-list | 501 | ;; Printer for `prin1' and `princ' that handles circular structures. |
| 339 | (cust-print-custom-object1 object custom-print-list)) | 502 | ;; If OBJECT appears multiply, and has not yet been printed, |
| 340 | (cust-print-list object))) | 503 | ;; prefix with label; if it has been printed, use `#N#' instead. |
| 341 | 504 | ;; Otherwise, print normally. | |
| 342 | ((vectorp object) | ||
| 343 | (or (and custom-print-vector | ||
| 344 | (cust-print-custom-object1 object custom-print-vector)) | ||
| 345 | (cust-print-vector object))) | ||
| 346 | |||
| 347 | ;; All other types, just print. | ||
| 348 | (t (cust-print-internal-printer object)))) | ||
| 349 | |||
| 350 | |||
| 351 | ;; Helper for cust-print-custom-object. | ||
| 352 | ;; Print the custom OBJECT using the custom type ALIST. | ||
| 353 | ;; For the first predicate that matches the object, the corresponding | ||
| 354 | ;; converter is evaluated with the object and the string that results is | ||
| 355 | ;; printed with princ. Return nil if no predicate matches the object. | ||
| 356 | (defun cust-print-custom-object1 (object alist) | ||
| 357 | (while (and alist (not (funcall (car (car alist)) object))) | ||
| 358 | (setq alist (cdr alist))) | ||
| 359 | ;; If alist is not null, then something matched. | ||
| 360 | (if alist | ||
| 361 | (cust-print-internal-princ | ||
| 362 | (funcall (cdr (car alist)) object) ; returns string | ||
| 363 | ))) | ||
| 364 | |||
| 365 | |||
| 366 | (defun cust-print-circular (object) | ||
| 367 | "Printer for `prin1' and `princ' that handles circular structures. | ||
| 368 | If OBJECT appears multiply, and has not yet been printed, | ||
| 369 | prefix with label; if it has been printed, use `#N#' instead. | ||
| 370 | Otherwise, print normally." | ||
| 371 | (let ((tag (assq object circle-table))) | 505 | (let ((tag (assq object circle-table))) |
| 372 | (if tag | 506 | (if tag |
| 373 | (let ((id (cdr tag))) | 507 | (let ((id (cdr tag))) |
| 374 | (if (> id 0) | 508 | (if (> id 0) |
| 375 | (progn | 509 | (progn |
| 376 | ;; Already printed, so just print id. | 510 | ;; Already printed, so just print id. |
| 377 | (cust-print-internal-princ "#") | 511 | (cust-print-original-princ "#") |
| 378 | (cust-print-internal-princ id) | 512 | (cust-print-original-princ id) |
| 379 | (cust-print-internal-princ "#")) | 513 | (cust-print-original-princ "#")) |
| 380 | ;; Not printed yet, so label with id and print object. | 514 | ;; Not printed yet, so label with id and print object. |
| 381 | (setcdr tag (- id)) ; mark it as printed | 515 | (setcdr tag (- id)) ; mark it as printed |
| 382 | (cust-print-internal-princ "#") | 516 | (cust-print-original-princ "#") |
| 383 | (cust-print-internal-princ (- id)) | 517 | (cust-print-original-princ (- id)) |
| 384 | (cust-print-internal-princ "=") | 518 | (cust-print-original-princ "=") |
| 385 | (cust-print-low-level-prin object) | 519 | (cust-print-low-level-prin object) |
| 386 | )) | 520 | )) |
| 387 | ;; Not repeated in structure. | 521 | ;; Not repeated in structure. |
| @@ -391,18 +525,18 @@ Otherwise, print normally." | |||
| 391 | ;;================================================ | 525 | ;;================================================ |
| 392 | ;; List and vector processing for print functions. | 526 | ;; List and vector processing for print functions. |
| 393 | 527 | ||
| 394 | ;; Print a list using print-length, print-level, and print-circle. | ||
| 395 | (defun cust-print-list (list) | 528 | (defun cust-print-list (list) |
| 396 | (if (= circle-level 0) | 529 | ;; Print a list using print-length, print-level, and print-circle. |
| 397 | (cust-print-internal-princ "#") | 530 | (if (= cust-print-current-level 0) |
| 398 | (let ((circle-level (1- circle-level))) | 531 | (cust-print-original-princ "#") |
| 399 | (cust-print-internal-princ "(") | 532 | (let ((cust-print-current-level (1- cust-print-current-level))) |
| 533 | (cust-print-original-princ "(") | ||
| 400 | (let ((length (or print-length 0))) | 534 | (let ((length (or print-length 0))) |
| 401 | 535 | ||
| 402 | ;; Print the first element always (even if length = 0). | 536 | ;; Print the first element always (even if length = 0). |
| 403 | (cust-print-prin (car list)) | 537 | (cust-print-prin (car list)) |
| 404 | (setq list (cdr list)) | 538 | (setq list (cdr list)) |
| 405 | (if list (cust-print-internal-princ " ")) | 539 | (if list (cust-print-original-princ " ")) |
| 406 | (setq length (1- length)) | 540 | (setq length (1- length)) |
| 407 | 541 | ||
| 408 | ;; Print the rest of the elements. | 542 | ;; Print the rest of the elements. |
| @@ -414,26 +548,26 @@ Otherwise, print normally." | |||
| 414 | (setq list (cdr list))) | 548 | (setq list (cdr list))) |
| 415 | 549 | ||
| 416 | ;; cdr is not a list, or it is in circle-table. | 550 | ;; cdr is not a list, or it is in circle-table. |
| 417 | (cust-print-internal-princ ". ") | 551 | (cust-print-original-princ ". ") |
| 418 | (cust-print-prin list) | 552 | (cust-print-prin list) |
| 419 | (setq list nil)) | 553 | (setq list nil)) |
| 420 | 554 | ||
| 421 | (setq length (1- length)) | 555 | (setq length (1- length)) |
| 422 | (if list (cust-print-internal-princ " "))) | 556 | (if list (cust-print-original-princ " "))) |
| 423 | 557 | ||
| 424 | (if (and list (= length 0)) (cust-print-internal-princ "...")) | 558 | (if (and list (= length 0)) (cust-print-original-princ "...")) |
| 425 | (cust-print-internal-princ ")")))) | 559 | (cust-print-original-princ ")")))) |
| 426 | list) | 560 | list) |
| 427 | 561 | ||
| 428 | 562 | ||
| 429 | ;; Print a vector according to print-length, print-level, and print-circle. | ||
| 430 | (defun cust-print-vector (vector) | 563 | (defun cust-print-vector (vector) |
| 431 | (if (= circle-level 0) | 564 | ;; Print a vector according to print-length, print-level, and print-circle. |
| 432 | (cust-print-internal-princ "#") | 565 | (if (= cust-print-current-level 0) |
| 433 | (let ((circle-level (1- circle-level)) | 566 | (cust-print-original-princ "#") |
| 567 | (let ((cust-print-current-level (1- cust-print-current-level)) | ||
| 434 | (i 0) | 568 | (i 0) |
| 435 | (len (length vector))) | 569 | (len (length vector))) |
| 436 | (cust-print-internal-princ "[") | 570 | (cust-print-original-princ "[") |
| 437 | 571 | ||
| 438 | (if print-length | 572 | (if print-length |
| 439 | (setq len (min print-length len))) | 573 | (setq len (min print-length len))) |
| @@ -441,16 +575,17 @@ Otherwise, print normally." | |||
| 441 | (while (< i len) | 575 | (while (< i len) |
| 442 | (cust-print-prin (aref vector i)) | 576 | (cust-print-prin (aref vector i)) |
| 443 | (setq i (1+ i)) | 577 | (setq i (1+ i)) |
| 444 | (if (< i (length vector)) (cust-print-internal-princ " "))) | 578 | (if (< i (length vector)) (cust-print-original-princ " "))) |
| 445 | 579 | ||
| 446 | (if (< i (length vector)) (cust-print-internal-princ "...")) | 580 | (if (< i (length vector)) (cust-print-original-princ "...")) |
| 447 | (cust-print-internal-princ "]") | 581 | (cust-print-original-princ "]") |
| 448 | )) | 582 | )) |
| 449 | vector) | 583 | vector) |
| 450 | 584 | ||
| 451 | 585 | ||
| 452 | ;;================================== | 586 | |
| 453 | ;; Circular structure preprocessing | 587 | ;; Circular structure preprocessing |
| 588 | ;;================================== | ||
| 454 | 589 | ||
| 455 | (defun cust-print-preprocess-circle-tree (object) | 590 | (defun cust-print-preprocess-circle-tree (object) |
| 456 | ;; Fill up the table. | 591 | ;; Fill up the table. |
| @@ -492,7 +627,11 @@ Otherwise, print normally." | |||
| 492 | (defun cust-print-walk-circle-tree (object) | 627 | (defun cust-print-walk-circle-tree (object) |
| 493 | (let (read-equivalent-p tag) | 628 | (let (read-equivalent-p tag) |
| 494 | (while object | 629 | (while object |
| 495 | (setq read-equivalent-p (or (numberp object) (symbolp object)) | 630 | (setq read-equivalent-p |
| 631 | (or (numberp object) | ||
| 632 | (and (symbolp object) | ||
| 633 | ;; Check if it is uninterned. | ||
| 634 | (eq object (intern-soft (symbol-name object))))) | ||
| 496 | tag (and (not read-equivalent-p) | 635 | tag (and (not read-equivalent-p) |
| 497 | (assq object (cdr circle-table)))) | 636 | (assq object (cdr circle-table)))) |
| 498 | (cond (tag | 637 | (cond (tag |
| @@ -525,49 +664,55 @@ Otherwise, print normally." | |||
| 525 | (cust-print-walk-circle-tree (aref object j)) | 664 | (cust-print-walk-circle-tree (aref object j)) |
| 526 | (setq j (1+ j)))))))))) | 665 | (setq j (1+ j)))))))))) |
| 527 | 666 | ||
| 667 | |||
| 668 | ;; Example. | ||
| 669 | ;;======================================= | ||
| 528 | 670 | ||
| 671 | '(progn | ||
| 672 | (progn | ||
| 673 | ;; Create some circular structures. | ||
| 674 | (setq circ-sym (let ((x (make-symbol "FOO"))) (list x x))) | ||
| 675 | (setq circ-list (list 'a 'b (vector 1 2 3 4) 'd 'e 'f)) | ||
| 676 | (setcar (nthcdr 3 circ-list) circ-list) | ||
| 677 | (aset (nth 2 circ-list) 2 circ-list) | ||
| 678 | (setq dotted-circ-list (list 'a 'b 'c)) | ||
| 679 | (setcdr (cdr (cdr dotted-circ-list)) dotted-circ-list) | ||
| 680 | (setq circ-vector (vector 1 2 3 4 (list 'a 'b 'c 'd) 6 7)) | ||
| 681 | (aset circ-vector 5 (make-symbol "-gensym-")) | ||
| 682 | (setcar (cdr (aref circ-vector 4)) (aref circ-vector 5)) | ||
| 683 | nil) | ||
| 684 | |||
| 685 | (install-custom-print) | ||
| 686 | ;; (setq print-circle t) | ||
| 687 | |||
| 688 | (let ((print-circle t)) | ||
| 689 | (or (equal (prin1-to-string circ-list) "#1=(a b [1 2 #1# 4] #1# e f)") | ||
| 690 | (error "circular object with array printing"))) | ||
| 691 | |||
| 692 | (let ((print-circle t)) | ||
| 693 | (or (equal (prin1-to-string dotted-circ-list) "#1=(a b c . #1#)") | ||
| 694 | (error "circular object with array printing"))) | ||
| 695 | |||
| 696 | (let* ((print-circle t) | ||
| 697 | (x (list 'p 'q)) | ||
| 698 | (y (list (list 'a 'b) x 'foo x))) | ||
| 699 | (setcdr (cdr (cdr (cdr y))) (cdr y)) | ||
| 700 | (or (equal (prin1-to-string y) "((a b) . #1=(#2=(p q) foo #2# . #1#))" | ||
| 701 | ) | ||
| 702 | (error "circular list example from CL manual"))) | ||
| 529 | 703 | ||
| 530 | ;;======================================= | 704 | (let ((print-circle nil)) |
| 705 | ;; cl-packages.el is required to print uninterned symbols like #:FOO. | ||
| 706 | ;; (require 'cl-packages) | ||
| 707 | (or (equal (prin1-to-string circ-sym) "(#:FOO #:FOO)") | ||
| 708 | (error "uninterned symbols in list"))) | ||
| 709 | (let ((print-circle t)) | ||
| 710 | (or (equal (prin1-to-string circ-sym) "(#1=FOO #1#)") | ||
| 711 | (error "circular uninterned symbols in list"))) | ||
| 531 | 712 | ||
| 532 | ;; Example. | 713 | (uninstall-custom-print) |
| 714 | ) | ||
| 533 | 715 | ||
| 534 | ;;;; Create some circular structures. | 716 | (provide 'cust-print) |
| 535 | ;;(setq circ-sym (let ((x (make-symbol "FOO"))) (list x x))) | ||
| 536 | ;;(setq circ-list (list 'a 'b (vector 1 2 3 4) 'd 'e 'f)) | ||
| 537 | ;;(setcar (nthcdr 3 circ-list) circ-list) | ||
| 538 | ;;(aset (nth 2 circ-list) 2 circ-list) | ||
| 539 | ;;(setq dotted-circ-list (list 'a 'b 'c)) | ||
| 540 | ;;(setcdr (cdr (cdr dotted-circ-list)) dotted-circ-list) | ||
| 541 | ;;(setq circ-vector (vector 1 2 3 4 (list 'a 'b 'c 'd) 6 7)) | ||
| 542 | ;;(aset circ-vector 5 (make-symbol "-gensym-")) | ||
| 543 | ;;(setcar (cdr (aref circ-vector 4)) (aref circ-vector 5)) | ||
| 544 | |||
| 545 | ;;(install-custom-print-funcs) | ||
| 546 | ;;;; (setq print-circle t) | ||
| 547 | |||
| 548 | ;;(let ((print-circle t)) | ||
| 549 | ;; (or (equal (prin1-to-string circ-list) "#1=(a b [1 2 #1# 4] #1# e f)") | ||
| 550 | ;; (error "circular object with array printing"))) | ||
| 551 | |||
| 552 | ;;(let ((print-circle t)) | ||
| 553 | ;; (or (equal (prin1-to-string dotted-circ-list) "#1=(a b c . #1#)") | ||
| 554 | ;; (error "circular object with array printing"))) | ||
| 555 | |||
| 556 | ;;(let* ((print-circle t) | ||
| 557 | ;; (x (list 'p 'q)) | ||
| 558 | ;; (y (list (list 'a 'b) x 'foo x))) | ||
| 559 | ;; (setcdr (cdr (cdr (cdr y))) (cdr y)) | ||
| 560 | ;; (or (equal (prin1-to-string y) "((a b) . #1=(#2=(p q) foo #2# . #1#))" | ||
| 561 | ;; ) | ||
| 562 | ;; (error "circular list example from CL manual"))) | ||
| 563 | |||
| 564 | ;;;; There's no special handling of uninterned symbols in custom-print. | ||
| 565 | ;;(let ((print-circle nil)) | ||
| 566 | ;; (or (equal (prin1-to-string circ-sym) "(#:FOO #:FOO)") | ||
| 567 | ;; (error "uninterned symbols in list"))) | ||
| 568 | ;;(let ((print-circle t)) | ||
| 569 | ;; (or (equal (prin1-to-string circ-sym) "(#1=FOO #1#)") | ||
| 570 | ;; (error "circular uninterned symbols in list"))) | ||
| 571 | ;;(uninstall-custom-print-funcs) | ||
| 572 | 717 | ||
| 573 | ;;; cust-print.el ends here | 718 | ;;; cust-print.el ends here |