diff options
| author | Jim Blandy | 1991-07-13 22:29:48 +0000 |
|---|---|---|
| committer | Jim Blandy | 1991-07-13 22:29:48 +0000 |
| commit | 38010d507a311f3ff9fb780683ef2cc6e0ea8fc6 (patch) | |
| tree | 799aeea8162a1e6cab4ff30e8d12db7d9eb53ee9 /src | |
| parent | 217a49c2cdc67861b5a2ca3ca16239dbcc6a83e7 (diff) | |
| download | emacs-38010d507a311f3ff9fb780683ef2cc6e0ea8fc6.tar.gz emacs-38010d507a311f3ff9fb780683ef2cc6e0ea8fc6.zip | |
Initial revision
Diffstat (limited to 'src')
| -rw-r--r-- | src/print.c | 969 |
1 files changed, 969 insertions, 0 deletions
diff --git a/src/print.c b/src/print.c new file mode 100644 index 00000000000..9eff5250e63 --- /dev/null +++ b/src/print.c | |||
| @@ -0,0 +1,969 @@ | |||
| 1 | /* Lisp object printing and output streams. | ||
| 2 | Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | ||
| 19 | |||
| 20 | |||
| 21 | #include "config.h" | ||
| 22 | #include <stdio.h> | ||
| 23 | #undef NULL | ||
| 24 | #include "lisp.h" | ||
| 25 | |||
| 26 | #ifndef standalone | ||
| 27 | #include "buffer.h" | ||
| 28 | #include "screen.h" | ||
| 29 | #include "window.h" | ||
| 30 | #include "process.h" | ||
| 31 | #include "dispextern.h" | ||
| 32 | #include "termchar.h" | ||
| 33 | #endif /* not standalone */ | ||
| 34 | |||
| 35 | Lisp_Object Vstandard_output, Qstandard_output; | ||
| 36 | |||
| 37 | #ifdef LISP_FLOAT_TYPE | ||
| 38 | Lisp_Object Vfloat_output_format, Qfloat_output_format; | ||
| 39 | #endif /* LISP_FLOAT_TYPE */ | ||
| 40 | |||
| 41 | /* Avoid actual stack overflow in print. */ | ||
| 42 | int print_depth; | ||
| 43 | |||
| 44 | /* Maximum length of list to print in full; noninteger means | ||
| 45 | effectively infinity */ | ||
| 46 | |||
| 47 | Lisp_Object Vprint_length; | ||
| 48 | |||
| 49 | /* Maximum depth of list to print in full; noninteger means | ||
| 50 | effectively infinity. */ | ||
| 51 | |||
| 52 | Lisp_Object Vprint_level; | ||
| 53 | |||
| 54 | /* Nonzero means print newlines in strings as \n. */ | ||
| 55 | |||
| 56 | int print_escape_newlines; | ||
| 57 | |||
| 58 | Lisp_Object Qprint_escape_newlines; | ||
| 59 | |||
| 60 | /* Nonzero means print newline before next minibuffer message. | ||
| 61 | Defined in xdisp.c */ | ||
| 62 | |||
| 63 | extern int noninteractive_need_newline; | ||
| 64 | #ifdef MAX_PRINT_CHARS | ||
| 65 | static int print_chars; | ||
| 66 | static int max_print; | ||
| 67 | #endif /* MAX_PRINT_CHARS */ | ||
| 68 | |||
| 69 | #if 0 | ||
| 70 | /* Convert between chars and GLYPHs */ | ||
| 71 | |||
| 72 | int | ||
| 73 | glyphlen (glyphs) | ||
| 74 | register GLYPH *glyphs; | ||
| 75 | { | ||
| 76 | register int i = 0; | ||
| 77 | |||
| 78 | while (glyphs[i]) | ||
| 79 | i++; | ||
| 80 | return i; | ||
| 81 | } | ||
| 82 | |||
| 83 | void | ||
| 84 | str_to_glyph_cpy (str, glyphs) | ||
| 85 | char *str; | ||
| 86 | GLYPH *glyphs; | ||
| 87 | { | ||
| 88 | register GLYPH *gp = glyphs; | ||
| 89 | register char *cp = str; | ||
| 90 | |||
| 91 | while (*cp) | ||
| 92 | *gp++ = *cp++; | ||
| 93 | } | ||
| 94 | |||
| 95 | void | ||
| 96 | str_to_glyph_ncpy (str, glyphs, n) | ||
| 97 | char *str; | ||
| 98 | GLYPH *glyphs; | ||
| 99 | register int n; | ||
| 100 | { | ||
| 101 | register GLYPH *gp = glyphs; | ||
| 102 | register char *cp = str; | ||
| 103 | |||
| 104 | while (n-- > 0) | ||
| 105 | *gp++ = *cp++; | ||
| 106 | } | ||
| 107 | |||
| 108 | void | ||
| 109 | glyph_to_str_cpy (glyphs, str) | ||
| 110 | GLYPH *glyphs; | ||
| 111 | char *str; | ||
| 112 | { | ||
| 113 | register GLYPH *gp = glyphs; | ||
| 114 | register char *cp = str; | ||
| 115 | |||
| 116 | while (*gp) | ||
| 117 | *str++ = *gp++ & 0377; | ||
| 118 | } | ||
| 119 | #endif | ||
| 120 | |||
| 121 | /* Low level output routines for charaters and strings */ | ||
| 122 | |||
| 123 | /* Lisp functions to do output using a stream | ||
| 124 | must have the stream in a variable called printcharfun | ||
| 125 | and must start with PRINTPREPARE and end with PRINTFINISH. | ||
| 126 | Use PRINTCHAR to output one character, | ||
| 127 | or call strout to output a block of characters. | ||
| 128 | Also, each one must have the declarations | ||
| 129 | struct buffer *old = current_buffer; | ||
| 130 | int old_point = -1, start_point; | ||
| 131 | Lisp_Object original; | ||
| 132 | */ | ||
| 133 | |||
| 134 | #define PRINTPREPARE \ | ||
| 135 | original = printcharfun; \ | ||
| 136 | if (NULL (printcharfun)) printcharfun = Qt; \ | ||
| 137 | if (XTYPE (printcharfun) == Lisp_Buffer) \ | ||
| 138 | { if (XBUFFER (printcharfun) != current_buffer) Fset_buffer (printcharfun); \ | ||
| 139 | printcharfun = Qnil;}\ | ||
| 140 | if (XTYPE (printcharfun) == Lisp_Marker) \ | ||
| 141 | { if (XMARKER (original)->buffer != current_buffer) \ | ||
| 142 | set_buffer_internal (XMARKER (original)->buffer); \ | ||
| 143 | old_point = point; \ | ||
| 144 | SET_PT (marker_position (printcharfun)); \ | ||
| 145 | start_point = point; \ | ||
| 146 | printcharfun = Qnil;} | ||
| 147 | |||
| 148 | #define PRINTFINISH \ | ||
| 149 | if (XTYPE (original) == Lisp_Marker) \ | ||
| 150 | Fset_marker (original, make_number (point), Qnil); \ | ||
| 151 | if (old_point >= 0) \ | ||
| 152 | SET_PT ((old_point >= start_point ? point - start_point : 0) + old_point); \ | ||
| 153 | if (old != current_buffer) \ | ||
| 154 | set_buffer_internal (old) | ||
| 155 | |||
| 156 | #define PRINTCHAR(ch) printchar (ch, printcharfun) | ||
| 157 | |||
| 158 | /* Index of first unused element of message_buf */ | ||
| 159 | static int printbufidx; | ||
| 160 | |||
| 161 | static void | ||
| 162 | printchar (ch, fun) | ||
| 163 | unsigned char ch; | ||
| 164 | Lisp_Object fun; | ||
| 165 | { | ||
| 166 | Lisp_Object ch1; | ||
| 167 | |||
| 168 | #ifdef MAX_PRINT_CHARS | ||
| 169 | if (max_print) | ||
| 170 | print_chars++; | ||
| 171 | #endif /* MAX_PRINT_CHARS */ | ||
| 172 | #ifndef standalone | ||
| 173 | if (EQ (fun, Qnil)) | ||
| 174 | { | ||
| 175 | QUIT; | ||
| 176 | insert (&ch, 1); | ||
| 177 | return; | ||
| 178 | } | ||
| 179 | |||
| 180 | if (EQ (fun, Qt)) | ||
| 181 | { | ||
| 182 | if (noninteractive) | ||
| 183 | { | ||
| 184 | putchar (ch); | ||
| 185 | noninteractive_need_newline = 1; | ||
| 186 | return; | ||
| 187 | } | ||
| 188 | |||
| 189 | if (echo_area_glyphs != SCREEN_MESSAGE_BUF (selected_screen) | ||
| 190 | || !message_buf_print) | ||
| 191 | { | ||
| 192 | echo_area_glyphs = SCREEN_MESSAGE_BUF (selected_screen); | ||
| 193 | printbufidx = 0; | ||
| 194 | message_buf_print = 1; | ||
| 195 | } | ||
| 196 | |||
| 197 | if (printbufidx < SCREEN_WIDTH (selected_screen) - 1) | ||
| 198 | SCREEN_MESSAGE_BUF (selected_screen)[printbufidx++] = ch; | ||
| 199 | SCREEN_MESSAGE_BUF (selected_screen)[printbufidx] = 0; | ||
| 200 | |||
| 201 | return; | ||
| 202 | } | ||
| 203 | #endif /* not standalone */ | ||
| 204 | |||
| 205 | XFASTINT (ch1) = ch; | ||
| 206 | call1 (fun, ch1); | ||
| 207 | } | ||
| 208 | |||
| 209 | static void | ||
| 210 | strout (ptr, size, printcharfun) | ||
| 211 | char *ptr; | ||
| 212 | int size; | ||
| 213 | Lisp_Object printcharfun; | ||
| 214 | { | ||
| 215 | int i = 0; | ||
| 216 | |||
| 217 | if (EQ (printcharfun, Qnil)) | ||
| 218 | { | ||
| 219 | insert (ptr, size >= 0 ? size : strlen (ptr)); | ||
| 220 | #ifdef MAX_PRINT_CHARS | ||
| 221 | if (max_print) | ||
| 222 | print_chars += size >= 0 ? size : strlen(ptr); | ||
| 223 | #endif /* MAX_PRINT_CHARS */ | ||
| 224 | return; | ||
| 225 | } | ||
| 226 | if (EQ (printcharfun, Qt)) | ||
| 227 | { | ||
| 228 | i = size >= 0 ? size : strlen (ptr); | ||
| 229 | #ifdef MAX_PRINT_CHARS | ||
| 230 | if (max_print) | ||
| 231 | print_chars += i; | ||
| 232 | #endif /* MAX_PRINT_CHARS */ | ||
| 233 | |||
| 234 | if (noninteractive) | ||
| 235 | { | ||
| 236 | fwrite (ptr, 1, i, stdout); | ||
| 237 | noninteractive_need_newline = 1; | ||
| 238 | return; | ||
| 239 | } | ||
| 240 | |||
| 241 | if (echo_area_glyphs != SCREEN_MESSAGE_BUF (selected_screen) | ||
| 242 | || !message_buf_print) | ||
| 243 | { | ||
| 244 | echo_area_glyphs = SCREEN_MESSAGE_BUF (selected_screen); | ||
| 245 | printbufidx = 0; | ||
| 246 | message_buf_print = 1; | ||
| 247 | } | ||
| 248 | |||
| 249 | if (i > SCREEN_WIDTH (selected_screen) - printbufidx - 1) | ||
| 250 | i = SCREEN_WIDTH (selected_screen) - printbufidx - 1; | ||
| 251 | bcopy (ptr, &SCREEN_MESSAGE_BUF (selected_screen) [printbufidx], i); | ||
| 252 | printbufidx += i; | ||
| 253 | SCREEN_MESSAGE_BUF (selected_screen) [printbufidx] = 0; | ||
| 254 | |||
| 255 | return; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (size >= 0) | ||
| 259 | while (i < size) | ||
| 260 | PRINTCHAR (ptr[i++]); | ||
| 261 | else | ||
| 262 | while (ptr[i]) | ||
| 263 | PRINTCHAR (ptr[i++]); | ||
| 264 | } | ||
| 265 | |||
| 266 | /* Print the contents of a string STRING using PRINTCHARFUN. | ||
| 267 | It isn't safe to use strout, because printing one char can relocate. */ | ||
| 268 | |||
| 269 | print_string (string, printcharfun) | ||
| 270 | Lisp_Object string; | ||
| 271 | Lisp_Object printcharfun; | ||
| 272 | { | ||
| 273 | if (EQ (printcharfun, Qnil) || EQ (printcharfun, Qt)) | ||
| 274 | /* In predictable cases, strout is safe: output to buffer or screen. */ | ||
| 275 | strout (XSTRING (string)->data, XSTRING (string)->size, printcharfun); | ||
| 276 | else | ||
| 277 | { | ||
| 278 | /* Otherwise, fetch the string address for each character. */ | ||
| 279 | int i; | ||
| 280 | int size = XSTRING (string)->size; | ||
| 281 | struct gcpro gcpro1; | ||
| 282 | GCPRO1 (string); | ||
| 283 | for (i = 0; i < size; i++) | ||
| 284 | PRINTCHAR (XSTRING (string)->data[i]); | ||
| 285 | UNGCPRO; | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | DEFUN ("write-char", Fwrite_char, Swrite_char, 1, 2, 0, | ||
| 290 | "Output character CHAR to stream STREAM.\n\ | ||
| 291 | STREAM defaults to the value of `standard-output' (which see).") | ||
| 292 | (ch, printcharfun) | ||
| 293 | Lisp_Object ch, printcharfun; | ||
| 294 | { | ||
| 295 | struct buffer *old = current_buffer; | ||
| 296 | int old_point = -1; | ||
| 297 | int start_point; | ||
| 298 | Lisp_Object original; | ||
| 299 | |||
| 300 | if (NULL (printcharfun)) | ||
| 301 | printcharfun = Vstandard_output; | ||
| 302 | CHECK_NUMBER (ch, 0); | ||
| 303 | PRINTPREPARE; | ||
| 304 | PRINTCHAR (XINT (ch)); | ||
| 305 | PRINTFINISH; | ||
| 306 | return ch; | ||
| 307 | } | ||
| 308 | |||
| 309 | /* Used from outside of print.c to print a block of SIZE chars at DATA | ||
| 310 | on the default output stream. | ||
| 311 | Do not use this on the contents of a Lisp string. */ | ||
| 312 | |||
| 313 | write_string (data, size) | ||
| 314 | char *data; | ||
| 315 | int size; | ||
| 316 | { | ||
| 317 | struct buffer *old = current_buffer; | ||
| 318 | Lisp_Object printcharfun; | ||
| 319 | int old_point = -1; | ||
| 320 | int start_point; | ||
| 321 | Lisp_Object original; | ||
| 322 | |||
| 323 | printcharfun = Vstandard_output; | ||
| 324 | |||
| 325 | PRINTPREPARE; | ||
| 326 | strout (data, size, printcharfun); | ||
| 327 | PRINTFINISH; | ||
| 328 | } | ||
| 329 | |||
| 330 | /* Used from outside of print.c to print a block of SIZE chars at DATA | ||
| 331 | on a specified stream PRINTCHARFUN. | ||
| 332 | Do not use this on the contents of a Lisp string. */ | ||
| 333 | |||
| 334 | write_string_1 (data, size, printcharfun) | ||
| 335 | char *data; | ||
| 336 | int size; | ||
| 337 | Lisp_Object printcharfun; | ||
| 338 | { | ||
| 339 | struct buffer *old = current_buffer; | ||
| 340 | int old_point = -1; | ||
| 341 | int start_point; | ||
| 342 | Lisp_Object original; | ||
| 343 | |||
| 344 | PRINTPREPARE; | ||
| 345 | strout (data, size, printcharfun); | ||
| 346 | PRINTFINISH; | ||
| 347 | } | ||
| 348 | |||
| 349 | |||
| 350 | #ifndef standalone | ||
| 351 | |||
| 352 | void | ||
| 353 | temp_output_buffer_setup (bufname) | ||
| 354 | char *bufname; | ||
| 355 | { | ||
| 356 | register struct buffer *old = current_buffer; | ||
| 357 | register Lisp_Object buf; | ||
| 358 | |||
| 359 | Fset_buffer (Fget_buffer_create (build_string (bufname))); | ||
| 360 | |||
| 361 | current_buffer->read_only = Qnil; | ||
| 362 | Ferase_buffer (); | ||
| 363 | |||
| 364 | XSET (buf, Lisp_Buffer, current_buffer); | ||
| 365 | specbind (Qstandard_output, buf); | ||
| 366 | |||
| 367 | set_buffer_internal (old); | ||
| 368 | } | ||
| 369 | |||
| 370 | Lisp_Object | ||
| 371 | internal_with_output_to_temp_buffer (bufname, function, args) | ||
| 372 | char *bufname; | ||
| 373 | Lisp_Object (*function) (); | ||
| 374 | Lisp_Object args; | ||
| 375 | { | ||
| 376 | int count = specpdl_ptr - specpdl; | ||
| 377 | Lisp_Object buf, val; | ||
| 378 | |||
| 379 | record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); | ||
| 380 | temp_output_buffer_setup (bufname); | ||
| 381 | buf = Vstandard_output; | ||
| 382 | |||
| 383 | val = (*function) (args); | ||
| 384 | |||
| 385 | temp_output_buffer_show (buf); | ||
| 386 | |||
| 387 | return unbind_to (count, val); | ||
| 388 | } | ||
| 389 | |||
| 390 | DEFUN ("with-output-to-temp-buffer", Fwith_output_to_temp_buffer, Swith_output_to_temp_buffer, | ||
| 391 | 1, UNEVALLED, 0, | ||
| 392 | "Bind `standard-output' to buffer BUFNAME, eval BODY, then show that buffer.\n\ | ||
| 393 | The buffer is cleared out initially, and marked as unmodified when done.\n\ | ||
| 394 | All output done by BODY is inserted in that buffer by default.\n\ | ||
| 395 | The buffer is displayed in another window, but not selected.\n\ | ||
| 396 | The value of the last form in BODY is returned.\n\ | ||
| 397 | If BODY does not finish normally, the buffer BUFNAME is not displayed.\n\n\ | ||
| 398 | If variable `temp-buffer-show-hook' is non-nil, call it at the end\n\ | ||
| 399 | to get the buffer displayed. It gets one argument, the buffer to display.") | ||
| 400 | (args) | ||
| 401 | Lisp_Object args; | ||
| 402 | { | ||
| 403 | struct gcpro gcpro1; | ||
| 404 | Lisp_Object name; | ||
| 405 | int count = specpdl_ptr - specpdl; | ||
| 406 | Lisp_Object buf, val; | ||
| 407 | |||
| 408 | GCPRO1(args); | ||
| 409 | name = Feval (Fcar (args)); | ||
| 410 | UNGCPRO; | ||
| 411 | |||
| 412 | CHECK_STRING (name, 0); | ||
| 413 | temp_output_buffer_setup (XSTRING (name)->data); | ||
| 414 | buf = Vstandard_output; | ||
| 415 | |||
| 416 | val = Fprogn (Fcdr (args)); | ||
| 417 | |||
| 418 | temp_output_buffer_show (buf); | ||
| 419 | |||
| 420 | return unbind_to (count, val); | ||
| 421 | } | ||
| 422 | #endif /* not standalone */ | ||
| 423 | |||
| 424 | static void print (); | ||
| 425 | |||
| 426 | DEFUN ("terpri", Fterpri, Sterpri, 0, 1, 0, | ||
| 427 | "Output a newline to STREAM.\n\ | ||
| 428 | If STREAM is omitted or nil, the value of `standard-output' is used.") | ||
| 429 | (printcharfun) | ||
| 430 | Lisp_Object printcharfun; | ||
| 431 | { | ||
| 432 | struct buffer *old = current_buffer; | ||
| 433 | int old_point = -1; | ||
| 434 | int start_point; | ||
| 435 | Lisp_Object original; | ||
| 436 | |||
| 437 | if (NULL (printcharfun)) | ||
| 438 | printcharfun = Vstandard_output; | ||
| 439 | PRINTPREPARE; | ||
| 440 | PRINTCHAR ('\n'); | ||
| 441 | PRINTFINISH; | ||
| 442 | return Qt; | ||
| 443 | } | ||
| 444 | |||
| 445 | DEFUN ("prin1", Fprin1, Sprin1, 1, 2, 0, | ||
| 446 | "Output the printed representation of OBJECT, any Lisp object.\n\ | ||
| 447 | Quoting characters are printed when needed to make output that `read'\n\ | ||
| 448 | can handle, whenever this is possible.\n\ | ||
| 449 | Output stream is STREAM, or value of `standard-output' (which see).") | ||
| 450 | (obj, printcharfun) | ||
| 451 | Lisp_Object obj, printcharfun; | ||
| 452 | { | ||
| 453 | struct buffer *old = current_buffer; | ||
| 454 | int old_point = -1; | ||
| 455 | int start_point; | ||
| 456 | Lisp_Object original; | ||
| 457 | |||
| 458 | #ifdef MAX_PRINT_CHARS | ||
| 459 | max_print = 0; | ||
| 460 | #endif /* MAX_PRINT_CHARS */ | ||
| 461 | if (NULL (printcharfun)) | ||
| 462 | printcharfun = Vstandard_output; | ||
| 463 | PRINTPREPARE; | ||
| 464 | print_depth = 0; | ||
| 465 | print (obj, printcharfun, 1); | ||
| 466 | PRINTFINISH; | ||
| 467 | return obj; | ||
| 468 | } | ||
| 469 | |||
| 470 | /* a buffer which is used to hold output being built by prin1-to-string */ | ||
| 471 | Lisp_Object Vprin1_to_string_buffer; | ||
| 472 | |||
| 473 | DEFUN ("prin1-to-string", Fprin1_to_string, Sprin1_to_string, 1, 2, 0, | ||
| 474 | "Return a string containing the printed representation of OBJECT,\n\ | ||
| 475 | any Lisp object. Quoting characters are used when needed to make output\n\ | ||
| 476 | that `read' can handle, whenever this is possible, unless the optional\n\ | ||
| 477 | second argument NOESCAPE is non-nil.") | ||
| 478 | (obj, noescape) | ||
| 479 | Lisp_Object obj, noescape; | ||
| 480 | { | ||
| 481 | struct buffer *old = current_buffer; | ||
| 482 | int old_point = -1; | ||
| 483 | int start_point; | ||
| 484 | Lisp_Object original, printcharfun; | ||
| 485 | struct gcpro gcpro1; | ||
| 486 | |||
| 487 | printcharfun = Vprin1_to_string_buffer; | ||
| 488 | PRINTPREPARE; | ||
| 489 | print_depth = 0; | ||
| 490 | print (obj, printcharfun, NULL (noescape)); | ||
| 491 | /* Make Vprin1_to_string_buffer be the default buffer after PRINTFINSH */ | ||
| 492 | PRINTFINISH; | ||
| 493 | set_buffer_internal (XBUFFER (Vprin1_to_string_buffer)); | ||
| 494 | obj = Fbuffer_string (); | ||
| 495 | |||
| 496 | GCPRO1 (obj); | ||
| 497 | Ferase_buffer (); | ||
| 498 | set_buffer_internal (old); | ||
| 499 | UNGCPRO; | ||
| 500 | |||
| 501 | return obj; | ||
| 502 | } | ||
| 503 | |||
| 504 | DEFUN ("princ", Fprinc, Sprinc, 1, 2, 0, | ||
| 505 | "Output the printed representation of OBJECT, any Lisp object.\n\ | ||
| 506 | No quoting characters are used; no delimiters are printed around\n\ | ||
| 507 | the contents of strings.\n\ | ||
| 508 | Output stream is STREAM, or value of standard-output (which see).") | ||
| 509 | (obj, printcharfun) | ||
| 510 | Lisp_Object obj, printcharfun; | ||
| 511 | { | ||
| 512 | struct buffer *old = current_buffer; | ||
| 513 | int old_point = -1; | ||
| 514 | int start_point; | ||
| 515 | Lisp_Object original; | ||
| 516 | |||
| 517 | if (NULL (printcharfun)) | ||
| 518 | printcharfun = Vstandard_output; | ||
| 519 | PRINTPREPARE; | ||
| 520 | print_depth = 0; | ||
| 521 | print (obj, printcharfun, 0); | ||
| 522 | PRINTFINISH; | ||
| 523 | return obj; | ||
| 524 | } | ||
| 525 | |||
| 526 | DEFUN ("print", Fprint, Sprint, 1, 2, 0, | ||
| 527 | "Output the printed representation of OBJECT, with newlines around it.\n\ | ||
| 528 | Quoting characters are printed when needed to make output that `read'\n\ | ||
| 529 | can handle, whenever this is possible.\n\ | ||
| 530 | Output stream is STREAM, or value of `standard-output' (which see).") | ||
| 531 | (obj, printcharfun) | ||
| 532 | Lisp_Object obj, printcharfun; | ||
| 533 | { | ||
| 534 | struct buffer *old = current_buffer; | ||
| 535 | int old_point = -1; | ||
| 536 | int start_point; | ||
| 537 | Lisp_Object original; | ||
| 538 | struct gcpro gcpro1; | ||
| 539 | |||
| 540 | #ifdef MAX_PRINT_CHARS | ||
| 541 | print_chars = 0; | ||
| 542 | max_print = MAX_PRINT_CHARS; | ||
| 543 | #endif /* MAX_PRINT_CHARS */ | ||
| 544 | if (NULL (printcharfun)) | ||
| 545 | printcharfun = Vstandard_output; | ||
| 546 | GCPRO1 (obj); | ||
| 547 | PRINTPREPARE; | ||
| 548 | print_depth = 0; | ||
| 549 | PRINTCHAR ('\n'); | ||
| 550 | print (obj, printcharfun, 1); | ||
| 551 | PRINTCHAR ('\n'); | ||
| 552 | PRINTFINISH; | ||
| 553 | #ifdef MAX_PRINT_CHARS | ||
| 554 | max_print = 0; | ||
| 555 | print_chars = 0; | ||
| 556 | #endif /* MAX_PRINT_CHARS */ | ||
| 557 | UNGCPRO; | ||
| 558 | return obj; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* The subroutine object for external-debugging-output is kept here | ||
| 562 | for the convenience of the debugger. */ | ||
| 563 | Lisp_Object Qexternal_debugging_output; | ||
| 564 | |||
| 565 | DEFUN ("external-debugging-output", | ||
| 566 | Fexternal_debugging_output, Sexternal_debugging_output, | ||
| 567 | 1, 1, 0, "Write CHARACTER to stderr.\n\ | ||
| 568 | You can call print while debugging emacs, and pass it this function\n\ | ||
| 569 | to make it write to the debugging output.\n") | ||
| 570 | (Lisp_Object character) | ||
| 571 | { | ||
| 572 | CHECK_NUMBER (character, 0); | ||
| 573 | putc (XINT (character), stderr); | ||
| 574 | |||
| 575 | return character; | ||
| 576 | } | ||
| 577 | |||
| 578 | #ifdef LISP_FLOAT_TYPE | ||
| 579 | |||
| 580 | void | ||
| 581 | float_to_string (buf, data) | ||
| 582 | char *buf; | ||
| 583 | /* | ||
| 584 | * This buffer should be at least as large as the max string size of the | ||
| 585 | * largest float, printed in the biggest notation. This is undoubtably | ||
| 586 | * 20d float_output_format, with the negative of the C-constant "HUGE" | ||
| 587 | * from <math.h>. | ||
| 588 | * | ||
| 589 | * On the vax the worst case is -1e38 in 20d format which takes 61 bytes. | ||
| 590 | * | ||
| 591 | * I assume that IEEE-754 format numbers can take 329 bytes for the worst | ||
| 592 | * case of -1e307 in 20d float_output_format. What is one to do (short of | ||
| 593 | * re-writing _doprnt to be more sane)? | ||
| 594 | * -wsr | ||
| 595 | */ | ||
| 596 | double data; | ||
| 597 | { | ||
| 598 | register unsigned char *cp, c; | ||
| 599 | register int width; | ||
| 600 | |||
| 601 | if (NULL (Vfloat_output_format) | ||
| 602 | || XTYPE (Vfloat_output_format) != Lisp_String) | ||
| 603 | lose: | ||
| 604 | sprintf (buf, "%.20g", data); | ||
| 605 | else /* oink oink */ | ||
| 606 | { | ||
| 607 | /* Check that the spec we have is fully valid. | ||
| 608 | This means not only valid for printf, | ||
| 609 | but meant for floats, and reasonable. */ | ||
| 610 | cp = XSTRING (Vfloat_output_format)->data; | ||
| 611 | |||
| 612 | if (cp[0] != '%') | ||
| 613 | goto lose; | ||
| 614 | if (cp[1] != '.') | ||
| 615 | goto lose; | ||
| 616 | |||
| 617 | cp += 2; | ||
| 618 | for (width = 0; | ||
| 619 | ((c = *cp) >= '0' && c <= '9'); | ||
| 620 | cp++) | ||
| 621 | { | ||
| 622 | width *= 10; | ||
| 623 | width += c - '0'; | ||
| 624 | } | ||
| 625 | |||
| 626 | if (*cp != 'e' && *cp != 'f' && *cp != 'g') | ||
| 627 | goto lose; | ||
| 628 | |||
| 629 | if (width < (*cp != 'e') || width > DBL_DIG) | ||
| 630 | goto lose; | ||
| 631 | |||
| 632 | if (cp[1] != 0) | ||
| 633 | goto lose; | ||
| 634 | |||
| 635 | sprintf (buf, XSTRING (Vfloat_output_format)->data, data); | ||
| 636 | } | ||
| 637 | } | ||
| 638 | #endif /* LISP_FLOAT_TYPE */ | ||
| 639 | |||
| 640 | static void | ||
| 641 | print (obj, printcharfun, escapeflag) | ||
| 642 | #ifndef RTPC_REGISTER_BUG | ||
| 643 | register Lisp_Object obj; | ||
| 644 | #else | ||
| 645 | Lisp_Object obj; | ||
| 646 | #endif | ||
| 647 | register Lisp_Object printcharfun; | ||
| 648 | int escapeflag; | ||
| 649 | { | ||
| 650 | char buf[30]; | ||
| 651 | |||
| 652 | QUIT; | ||
| 653 | |||
| 654 | print_depth++; | ||
| 655 | |||
| 656 | if (print_depth > 200) | ||
| 657 | error ("Apparently circular structure being printed"); | ||
| 658 | #ifdef MAX_PRINT_CHARS | ||
| 659 | if (max_print && print_chars > max_print) | ||
| 660 | { | ||
| 661 | PRINTCHAR ('\n'); | ||
| 662 | print_chars = 0; | ||
| 663 | } | ||
| 664 | #endif /* MAX_PRINT_CHARS */ | ||
| 665 | |||
| 666 | #ifdef SWITCH_ENUM_BUG | ||
| 667 | switch ((int) XTYPE (obj)) | ||
| 668 | #else | ||
| 669 | switch (XTYPE (obj)) | ||
| 670 | #endif | ||
| 671 | { | ||
| 672 | default: | ||
| 673 | /* We're in trouble if this happens! | ||
| 674 | Probably should just abort () */ | ||
| 675 | strout ("#<EMACS BUG: INVALID DATATYPE ", -1, printcharfun); | ||
| 676 | sprintf (buf, "(#o%3o)", (int) XTYPE (obj)); | ||
| 677 | strout (buf, -1, printcharfun); | ||
| 678 | strout (" Save your buffers immediately and please report this bug>", | ||
| 679 | -1, printcharfun); | ||
| 680 | break; | ||
| 681 | |||
| 682 | #ifdef LISP_FLOAT_TYPE | ||
| 683 | case Lisp_Float: | ||
| 684 | { | ||
| 685 | char pigbuf[350]; /* see comments in float_to_string */ | ||
| 686 | |||
| 687 | float_to_string (pigbuf, XFLOAT(obj)->data); | ||
| 688 | strout (pigbuf, -1, printcharfun); | ||
| 689 | } | ||
| 690 | break; | ||
| 691 | #endif /* LISP_FLOAT_TYPE */ | ||
| 692 | |||
| 693 | case Lisp_Int: | ||
| 694 | sprintf (buf, "%d", XINT (obj)); | ||
| 695 | strout (buf, -1, printcharfun); | ||
| 696 | break; | ||
| 697 | |||
| 698 | case Lisp_String: | ||
| 699 | if (!escapeflag) | ||
| 700 | print_string (obj, printcharfun); | ||
| 701 | else | ||
| 702 | { | ||
| 703 | register int i; | ||
| 704 | register unsigned char c; | ||
| 705 | Lisp_Object obj1; | ||
| 706 | struct gcpro gcpro1; | ||
| 707 | |||
| 708 | /* You can't gcpro register variables, so copy obj to a | ||
| 709 | non-register variable so we can gcpro it without | ||
| 710 | making it non-register. */ | ||
| 711 | obj1 = obj; | ||
| 712 | GCPRO1 (obj1); | ||
| 713 | |||
| 714 | PRINTCHAR ('\"'); | ||
| 715 | for (i = 0; i < XSTRING (obj)->size; i++) | ||
| 716 | { | ||
| 717 | QUIT; | ||
| 718 | c = XSTRING (obj)->data[i]; | ||
| 719 | if (c == '\n' && print_escape_newlines) | ||
| 720 | { | ||
| 721 | PRINTCHAR ('\\'); | ||
| 722 | PRINTCHAR ('n'); | ||
| 723 | } | ||
| 724 | else | ||
| 725 | { | ||
| 726 | if (c == '\"' || c == '\\') | ||
| 727 | PRINTCHAR ('\\'); | ||
| 728 | PRINTCHAR (c); | ||
| 729 | } | ||
| 730 | } | ||
| 731 | PRINTCHAR ('\"'); | ||
| 732 | UNGCPRO; | ||
| 733 | } | ||
| 734 | break; | ||
| 735 | |||
| 736 | case Lisp_Symbol: | ||
| 737 | { | ||
| 738 | register int confusing; | ||
| 739 | register unsigned char *p = XSYMBOL (obj)->name->data; | ||
| 740 | register unsigned char *end = p + XSYMBOL (obj)->name->size; | ||
| 741 | register unsigned char c; | ||
| 742 | |||
| 743 | if (p != end && (*p == '-' || *p == '+')) p++; | ||
| 744 | if (p == end) | ||
| 745 | confusing = 0; | ||
| 746 | else | ||
| 747 | { | ||
| 748 | while (p != end && *p >= '0' && *p <= '9') | ||
| 749 | p++; | ||
| 750 | confusing = (end == p); | ||
| 751 | } | ||
| 752 | |||
| 753 | p = XSYMBOL (obj)->name->data; | ||
| 754 | while (p != end) | ||
| 755 | { | ||
| 756 | QUIT; | ||
| 757 | c = *p++; | ||
| 758 | if (escapeflag) | ||
| 759 | { | ||
| 760 | if (c == '\"' || c == '\\' || c == '\'' || c == ';' || c == '#' || | ||
| 761 | c == '(' || c == ')' || c == ',' || c =='.' || c == '`' || | ||
| 762 | c == '[' || c == ']' || c == '?' || c <= 040 || confusing) | ||
| 763 | PRINTCHAR ('\\'), confusing = 0; | ||
| 764 | } | ||
| 765 | PRINTCHAR (c); | ||
| 766 | } | ||
| 767 | } | ||
| 768 | break; | ||
| 769 | |||
| 770 | case Lisp_Cons: | ||
| 771 | /* If deeper than spec'd depth, print placeholder. */ | ||
| 772 | if (XTYPE (Vprint_level) == Lisp_Int | ||
| 773 | && print_depth > XINT (Vprint_level)) | ||
| 774 | { | ||
| 775 | strout ("...", -1, printcharfun); | ||
| 776 | break; | ||
| 777 | } | ||
| 778 | |||
| 779 | PRINTCHAR ('('); | ||
| 780 | { | ||
| 781 | register int i = 0; | ||
| 782 | register int max = 0; | ||
| 783 | |||
| 784 | if (XTYPE (Vprint_length) == Lisp_Int) | ||
| 785 | max = XINT (Vprint_length); | ||
| 786 | while (CONSP (obj)) | ||
| 787 | { | ||
| 788 | if (i++) | ||
| 789 | PRINTCHAR (' '); | ||
| 790 | if (max && i > max) | ||
| 791 | { | ||
| 792 | strout ("...", 3, printcharfun); | ||
| 793 | break; | ||
| 794 | } | ||
| 795 | print (Fcar (obj), printcharfun, escapeflag); | ||
| 796 | obj = Fcdr (obj); | ||
| 797 | } | ||
| 798 | } | ||
| 799 | if (!NULL (obj) && !CONSP (obj)) | ||
| 800 | { | ||
| 801 | strout (" . ", 3, printcharfun); | ||
| 802 | print (obj, printcharfun, escapeflag); | ||
| 803 | } | ||
| 804 | PRINTCHAR (')'); | ||
| 805 | break; | ||
| 806 | |||
| 807 | case Lisp_Compiled: | ||
| 808 | strout ("#<byte-code ", -1, printcharfun); | ||
| 809 | case Lisp_Vector: | ||
| 810 | PRINTCHAR ('['); | ||
| 811 | { | ||
| 812 | register int i; | ||
| 813 | register Lisp_Object tem; | ||
| 814 | for (i = 0; i < XVECTOR (obj)->size; i++) | ||
| 815 | { | ||
| 816 | if (i) PRINTCHAR (' '); | ||
| 817 | tem = XVECTOR (obj)->contents[i]; | ||
| 818 | print (tem, printcharfun, escapeflag); | ||
| 819 | } | ||
| 820 | } | ||
| 821 | PRINTCHAR (']'); | ||
| 822 | if (XTYPE (obj) == Lisp_Compiled) | ||
| 823 | PRINTCHAR ('>'); | ||
| 824 | break; | ||
| 825 | |||
| 826 | #ifndef standalone | ||
| 827 | case Lisp_Buffer: | ||
| 828 | if (NULL (XBUFFER (obj)->name)) | ||
| 829 | strout ("#<killed buffer>", -1, printcharfun); | ||
| 830 | else if (escapeflag) | ||
| 831 | { | ||
| 832 | strout ("#<buffer ", -1, printcharfun); | ||
| 833 | print_string (XBUFFER (obj)->name, printcharfun); | ||
| 834 | PRINTCHAR ('>'); | ||
| 835 | } | ||
| 836 | else | ||
| 837 | print_string (XBUFFER (obj)->name, printcharfun); | ||
| 838 | break; | ||
| 839 | |||
| 840 | case Lisp_Process: | ||
| 841 | if (escapeflag) | ||
| 842 | { | ||
| 843 | strout ("#<process ", -1, printcharfun); | ||
| 844 | print_string (XPROCESS (obj)->name, printcharfun); | ||
| 845 | PRINTCHAR ('>'); | ||
| 846 | } | ||
| 847 | else | ||
| 848 | print_string (XPROCESS (obj)->name, printcharfun); | ||
| 849 | break; | ||
| 850 | |||
| 851 | case Lisp_Window: | ||
| 852 | strout ("#<window ", -1, printcharfun); | ||
| 853 | sprintf (buf, "%d", XFASTINT (XWINDOW (obj)->sequence_number)); | ||
| 854 | strout (buf, -1, printcharfun); | ||
| 855 | if (!NULL (XWINDOW (obj)->buffer)) | ||
| 856 | { | ||
| 857 | strout (" on ", -1, printcharfun); | ||
| 858 | print_string (XBUFFER (XWINDOW (obj)->buffer)->name, printcharfun); | ||
| 859 | } | ||
| 860 | PRINTCHAR ('>'); | ||
| 861 | break; | ||
| 862 | |||
| 863 | case Lisp_Window_Configuration: | ||
| 864 | strout ("#<window-configuration>", -1, printcharfun); | ||
| 865 | break; | ||
| 866 | |||
| 867 | #ifdef MULTI_SCREEN | ||
| 868 | case Lisp_Screen: | ||
| 869 | strout ("#<screen ", -1, printcharfun); | ||
| 870 | print_string (XSCREEN (obj)->name, printcharfun); | ||
| 871 | sprintf (buf, " 0x%x", XFASTINT (XSCREEN (obj))); | ||
| 872 | strout (buf, -1, printcharfun); | ||
| 873 | strout (">", -1, printcharfun); | ||
| 874 | break; | ||
| 875 | #endif /* MULTI_SCREEN */ | ||
| 876 | |||
| 877 | case Lisp_Marker: | ||
| 878 | strout ("#<marker ", -1, printcharfun); | ||
| 879 | if (!(XMARKER (obj)->buffer)) | ||
| 880 | strout ("in no buffer", -1, printcharfun); | ||
| 881 | else | ||
| 882 | { | ||
| 883 | sprintf (buf, "at %d", marker_position (obj)); | ||
| 884 | strout (buf, -1, printcharfun); | ||
| 885 | strout (" in ", -1, printcharfun); | ||
| 886 | print_string (XMARKER (obj)->buffer->name, printcharfun); | ||
| 887 | } | ||
| 888 | PRINTCHAR ('>'); | ||
| 889 | break; | ||
| 890 | #endif /* standalone */ | ||
| 891 | |||
| 892 | case Lisp_Subr: | ||
| 893 | strout ("#<subr ", -1, printcharfun); | ||
| 894 | strout (XSUBR (obj)->symbol_name, -1, printcharfun); | ||
| 895 | PRINTCHAR ('>'); | ||
| 896 | break; | ||
| 897 | } | ||
| 898 | |||
| 899 | print_depth--; | ||
| 900 | } | ||
| 901 | |||
| 902 | void | ||
| 903 | syms_of_print () | ||
| 904 | { | ||
| 905 | staticpro (&Qprint_escape_newlines); | ||
| 906 | Qprint_escape_newlines = intern ("print-escape-newlines"); | ||
| 907 | |||
| 908 | DEFVAR_LISP ("standard-output", &Vstandard_output, | ||
| 909 | "Output stream `print' uses by default for outputting a character.\n\ | ||
| 910 | This may be any function of one argument.\n\ | ||
| 911 | It may also be a buffer (output is inserted before point)\n\ | ||
| 912 | or a marker (output is inserted and the marker is advanced)\n\ | ||
| 913 | or the symbol t (output appears in the minibuffer line)."); | ||
| 914 | Vstandard_output = Qt; | ||
| 915 | Qstandard_output = intern ("standard-output"); | ||
| 916 | staticpro (&Qstandard_output); | ||
| 917 | |||
| 918 | #ifdef LISP_FLOAT_TYPE | ||
| 919 | DEFVAR_LISP ("float-output-format", &Vfloat_output_format, | ||
| 920 | "The format descriptor string that lisp uses to print floats.\n\ | ||
| 921 | This is a %-spec like those accepted by `printf' in C,\n\ | ||
| 922 | but with some restrictions. It must start with the two characters `%.'.\n\ | ||
| 923 | After that comes an integer precision specification,\n\ | ||
| 924 | and then a letter which controls the format.\n\ | ||
| 925 | The letters allowed are `e', `f' and `g'.\n\ | ||
| 926 | Use `e' for exponential notation \"DIG.DIGITSeEXPT\"\n\ | ||
| 927 | Use `f' for decimal point notation \"DIGITS.DIGITS\".\n\ | ||
| 928 | Use `g' to choose the shorter of those two formats for the number at hand.\n\ | ||
| 929 | The precision in any of these cases is the number of digits following\n\ | ||
| 930 | the decimal point. With `f', a precision of 0 means to omit the\n\ | ||
| 931 | decimal point. 0 is not allowed with `f' or `g'.\n\n\ | ||
| 932 | A value of nil means to use `%.20g'."); | ||
| 933 | Vfloat_output_format = Qnil; | ||
| 934 | Qfloat_output_format = intern ("float-output-format"); | ||
| 935 | staticpro (&Qfloat_output_format); | ||
| 936 | #endif /* LISP_FLOAT_TYPE */ | ||
| 937 | |||
| 938 | DEFVAR_LISP ("print-length", &Vprint_length, | ||
| 939 | "Maximum length of list to print before abbreviating.\ | ||
| 940 | A value of nil means no limit."); | ||
| 941 | Vprint_length = Qnil; | ||
| 942 | |||
| 943 | DEFVAR_LISP ("print-level", &Vprint_level, | ||
| 944 | "Maximum depth of list nesting to print before abbreviating.\ | ||
| 945 | A value of nil means no limit."); | ||
| 946 | Vprint_level = Qnil; | ||
| 947 | |||
| 948 | DEFVAR_BOOL ("print-escape-newlines", &print_escape_newlines, | ||
| 949 | "Non-nil means print newlines in strings as backslash-n."); | ||
| 950 | print_escape_newlines = 0; | ||
| 951 | |||
| 952 | /* prin1_to_string_buffer initialized in init_buffer_once in buffer.c */ | ||
| 953 | staticpro (&Vprin1_to_string_buffer); | ||
| 954 | |||
| 955 | defsubr (&Sprin1); | ||
| 956 | defsubr (&Sprin1_to_string); | ||
| 957 | defsubr (&Sprinc); | ||
| 958 | defsubr (&Sprint); | ||
| 959 | defsubr (&Sterpri); | ||
| 960 | defsubr (&Swrite_char); | ||
| 961 | defsubr (&Sexternal_debugging_output); | ||
| 962 | |||
| 963 | Qexternal_debugging_output = intern ("external-debugging-output"); | ||
| 964 | staticpro (&Qexternal_debugging_output); | ||
| 965 | |||
| 966 | #ifndef standalone | ||
| 967 | defsubr (&Swith_output_to_temp_buffer); | ||
| 968 | #endif /* not standalone */ | ||
| 969 | } | ||