C files should #include only the header files they need, not
[bpt/guile.git] / libguile / print.c
CommitLineData
0f2d19dd
JB
1/* Copyright (C) 1995,1996 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
19 *
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
25 *
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
28 *
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
36 *
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
40 */
41\f
42
43#include <stdio.h>
44#include "_scm.h"
45
46\f
47
48\f
49
50/* {Names of immediate symbols}
51 *
52 * This table must agree with the declarations in scm.h: {Immediate Symbols}.
53 */
54
55char *scm_isymnames[] =
56{
57 /* This table must agree with the declarations */
58 "#@and",
59 "#@begin",
60 "#@case",
61 "#@cond",
62 "#@do",
63 "#@if",
64 "#@lambda",
65 "#@let",
66 "#@let*",
67 "#@letrec",
68 "#@or",
69 "#@quote",
70 "#@set!",
71 "#@define",
72#if 0
73 "#@literal-variable-ref",
74 "#@literal-variable-set!",
75#endif
76 "#@apply",
77 "#@call-with-current-continuation",
78
79 /* user visible ISYMS */
80 /* other keywords */
81 /* Flags */
82
83 "#f",
84 "#t",
85 "#<undefined>",
86 "#<eof>",
87 "()",
88 "#<unspecified>"
89};
90
e6e4c9af
MD
91#ifdef DEBUG_EXTENSIONS
92scm_option scm_print_opts[] = {
b7ff98dd
MD
93 { SCM_OPTION_BOOLEAN, "procnames", 0,
94 "Print names instead of closures." },
95 { SCM_OPTION_SCM, "closure-hook", SCM_BOOL_F,
96 "Procedure used to print closures." }
e6e4c9af
MD
97};
98
b7ff98dd 99SCM_PROC (s_print_options, "print-options-interface", 0, 1, 0, scm_print_options);
e6e4c9af
MD
100#ifdef __STDC__
101SCM
102scm_print_options (SCM new_values)
103#else
104SCM
105scm_print_options (new_values)
106 SCM new_values;
107#endif
108{
b7ff98dd
MD
109 SCM ans = scm_options (new_values,
110 scm_print_opts,
111 SCM_N_PRINT_OPTIONS,
112 s_print_options);
e6e4c9af
MD
113 return ans;
114}
115#endif
116
0f2d19dd
JB
117\f
118/* {Printing of Scheme Objects}
119 */
120
121/* Print generally. Handles both write and display according to WRITING.
122 */
123#ifdef __STDC__
124void
125scm_iprin1 (SCM exp, SCM port, int writing)
126#else
127void
128scm_iprin1 (exp, port, writing)
129 SCM exp;
130 SCM port;
131 int writing;
132#endif
133{
134 register long i;
135taloop:
136 switch (7 & (int) exp)
137 {
138 case 2:
139 case 6:
140 scm_intprint (SCM_INUM (exp), 10, port);
141 break;
142 case 4:
143 if (SCM_ICHRP (exp))
144 {
145 i = SCM_ICHR (exp);
146 scm_put_wchar (i, port, writing);
147
148 }
149 else if ( SCM_IFLAGP (exp)
150 && (SCM_ISYMNUM (exp) < (sizeof scm_isymnames / sizeof (char *))))
151 scm_gen_puts (scm_regular_string, SCM_ISYMSCM_CHARS (exp), port);
152 else if (SCM_ILOCP (exp))
153 {
154 scm_gen_puts (scm_regular_string, "#@", port);
155 scm_intprint ((long) SCM_IFRAME (exp), 10, port);
156 scm_gen_putc (SCM_ICDRP (exp) ? '-' : '+', port);
157 scm_intprint ((long) SCM_IDIST (exp), 10, port);
158 }
159 else
160 goto idef;
161 break;
162 case 1:
163 /* gloc */
164 scm_gen_puts (scm_regular_string, "#@", port);
165 exp = SCM_CAR (exp - 1);
166 goto taloop;
167 default:
168 idef:
169 scm_ipruk ("immediate", exp, port);
170 break;
171 case 0:
172 switch (SCM_TYP7 (exp))
173 {
174 case scm_tcs_cons_gloc:
175
176 if (SCM_CDR (SCM_CAR (exp) - 1L) == 0)
177 {
178 scm_gen_write (scm_regular_string, "#<struct ", (scm_sizet) 9, port);
179 scm_intprint(exp, 16, port);
180 scm_gen_putc ('>', port);
181 break;
182 }
183
184 case scm_tcs_cons_imcar:
185 case scm_tcs_cons_nimcar:
186 scm_iprlist ("(", exp, ')', port, writing);
187 break;
188 case scm_tcs_closures:
189#ifdef DEBUG_EXTENSIONS
b7ff98dd 190 if (SCM_PRINT_PROCNAMES_P)
0f2d19dd
JB
191 {
192 SCM name;
193 name = scm_procedure_property (exp, scm_i_name);
194 scm_gen_puts (scm_regular_string, "#<procedure", port);
195 if (SCM_NFALSEP (name))
196 {
197 scm_gen_putc (' ', port);
198 /* FIXME */
199 scm_gen_puts (scm_regular_string, SCM_CHARS (name), port);
200 }
201 scm_gen_putc ('>', port);
202 }
203 else
204#endif
205 {
206 exp = SCM_CODE (exp);
207 scm_iprlist ("#<CLOSURE ", exp, '>', port, writing);
208 }
209 break;
210 case scm_tc7_mb_string:
211 case scm_tc7_mb_substring:
212 scm_print_mb_string (exp, port, writing);
213 break;
214 case scm_tc7_substring:
215 case scm_tc7_string:
216 if (writing)
217 {
218 scm_gen_putc ('\"', port);
219 for (i = 0; i < SCM_ROLENGTH (exp); ++i)
220 switch (SCM_ROCHARS (exp)[i])
221 {
222 case '\"':
223 case '\\':
224 scm_gen_putc ('\\', port);
225 default:
226 scm_gen_putc (SCM_ROCHARS (exp)[i], port);
227 }
228 scm_gen_putc ('\"', port);
229 break;
230 }
231 else
232 scm_gen_write (scm_regular_string, SCM_ROCHARS (exp),
233 (scm_sizet) SCM_ROLENGTH (exp),
234 port);
235 break;
236 case scm_tcs_symbols:
237 if (SCM_MB_STRINGP (exp))
238 {
239 scm_print_mb_symbol (exp, port);
240 break;
241 }
242 else
243 {
244 int pos;
245 int end;
246 int len;
247 char * str;
248 int weird;
249 int maybe_weird;
250 int mw_pos;
251
252 len = SCM_LENGTH (exp);
253 str = SCM_CHARS (exp);
254 scm_remember (&exp);
255 pos = 0;
256 weird = 0;
257 maybe_weird = 0;
258
259 if (len == 0)
260 scm_gen_write (scm_regular_string, "#{}#", 4, port);
261
262 for (end = pos; end < len; ++end)
263 switch (str[end])
264 {
265#ifdef BRACKETS_AS_PARENS
266 case '[':
267 case ']':
268#endif
269 case '(':
270 case ')':
271 case '\"':
272 case ';':
273 case SCM_WHITE_SPACES:
274 case SCM_LINE_INCREMENTORS:
275 weird_handler:
276 if (maybe_weird)
277 {
278 end = mw_pos;
279 maybe_weird = 0;
280 }
281 if (!weird)
282 {
283 scm_gen_write (scm_regular_string, "#{", 2, port);
284 weird = 1;
285 }
286 if (pos < end)
287 {
288 scm_gen_write (scm_regular_string, str + pos, end - pos, port);
289 }
290 {
291 char buf[2];
292 buf[0] = '\\';
293 buf[1] = str[end];
294 scm_gen_write (scm_regular_string, buf, 2, port);
295 }
296 pos = end + 1;
297 break;
298 case '\\':
299 if (weird)
300 goto weird_handler;
301 if (!maybe_weird)
302 {
303 maybe_weird = 1;
304 mw_pos = pos;
305 }
306 break;
307 case '}':
308 case '#':
309 if (weird)
310 goto weird_handler;
311 break;
312 default:
313 break;
314 }
315 if (pos < end)
316 scm_gen_write (scm_regular_string, str + pos, end - pos, port);
317 if (weird)
318 scm_gen_write (scm_regular_string, "}#", 2, port);
319 break;
320 }
321 case scm_tc7_wvect:
322 if (SCM_IS_WHVEC (exp))
323 scm_gen_puts (scm_regular_string, "#wh(", port);
324 else
325 scm_gen_puts (scm_regular_string, "#w(", port);
326 goto common_vector_printer;
327
328 case scm_tc7_vector:
329 scm_gen_puts (scm_regular_string, "#(", port);
330 common_vector_printer:
331 for (i = 0; i + 1 < SCM_LENGTH (exp); ++i)
332 {
333 /* CHECK_INTS; */
334 scm_iprin1 (SCM_VELTS (exp)[i], port, writing);
335 scm_gen_putc (' ', port);
336 }
337 if (i < SCM_LENGTH (exp))
338 {
339 /* CHECK_INTS; */
340 scm_iprin1 (SCM_VELTS (exp)[i], port, writing);
341 }
342 scm_gen_putc (')', port);
343 break;
344 case scm_tc7_bvect:
345 case scm_tc7_byvect:
346 case scm_tc7_svect:
347 case scm_tc7_ivect:
348 case scm_tc7_uvect:
349 case scm_tc7_fvect:
350 case scm_tc7_dvect:
351 case scm_tc7_cvect:
352#ifdef LONGLONGS
353 case scm_tc7_llvect:
354#endif
355 scm_raprin1 (exp, port, writing);
356 break;
357 case scm_tcs_subrs:
358 scm_gen_puts (scm_regular_string, "#<primitive-procedure ", port);
359 scm_gen_puts ((SCM_MB_STRINGP (SCM_SNAME(exp))
360 ? scm_mb_string
361 : scm_regular_string),
362 SCM_CHARS (SCM_SNAME (exp)), port);
363 scm_gen_putc ('>', port);
364 break;
365#ifdef CCLO
366 case scm_tc7_cclo:
367 scm_gen_puts (scm_regular_string, "#<compiled-closure ", port);
368 scm_iprin1 (SCM_CCLO_SUBR (exp), port, writing);
369 scm_gen_putc ('>', port);
370 break;
371#endif
372 case scm_tc7_contin:
373 scm_gen_puts (scm_regular_string, "#<continuation ", port);
374 scm_intprint (SCM_LENGTH (exp), 10, port);
375 scm_gen_puts (scm_regular_string, " @ ", port);
376 scm_intprint ((long) SCM_CHARS (exp), 16, port);
377 scm_gen_putc ('>', port);
378 break;
379 case scm_tc7_port:
380 i = SCM_PTOBNUM (exp);
381 if (i < scm_numptob && scm_ptobs[i].print && (scm_ptobs[i].print) (exp, port, writing))
382 break;
383 goto punk;
384 case scm_tc7_smob:
385 i = SCM_SMOBNUM (exp);
386 if (i < scm_numsmob && scm_smobs[i].print
387 && (scm_smobs[i].print) (exp, port, writing))
388 break;
389 goto punk;
390 default:
391 punk:scm_ipruk ("type", exp, port);
392 }
393 }
394}
395
396
397/* Print an integer.
398 */
399#ifdef __STDC__
400void
401scm_intprint (long n, int radix, SCM port)
402#else
403void
404scm_intprint (n, radix, port)
405 long n;
406 int radix;
407 SCM port;
408#endif
409{
410 char num_buf[SCM_INTBUFLEN];
411 scm_gen_write (scm_regular_string, num_buf, scm_iint2str (n, radix, num_buf), port);
412}
413
414/* Print an object of unrecognized type.
415 */
416#ifdef __STDC__
417void
418scm_ipruk (char *hdr, SCM ptr, SCM port)
419#else
420void
421scm_ipruk (hdr, ptr, port)
422 char *hdr;
423 SCM ptr;
424 SCM port;
425#endif
426{
427 scm_gen_puts (scm_regular_string, "#<unknown-", port);
428 scm_gen_puts (scm_regular_string, hdr, port);
429 if (SCM_CELLP (ptr))
430 {
431 scm_gen_puts (scm_regular_string, " (0x", port);
432 scm_intprint (SCM_CAR (ptr), 16, port);
433 scm_gen_puts (scm_regular_string, " . 0x", port);
434 scm_intprint (SCM_CDR (ptr), 16, port);
435 scm_gen_puts (scm_regular_string, ") @", port);
436 }
437 scm_gen_puts (scm_regular_string, " 0x", port);
438 scm_intprint (ptr, 16, port);
439 scm_gen_putc ('>', port);
440}
441
442/* Print a list.
443 */
444#ifdef __STDC__
445void
446scm_iprlist (char *hdr, SCM exp, char tlr, SCM port, int writing)
447#else
448void
449scm_iprlist (hdr, exp, tlr, port, writing)
450 char *hdr;
451 SCM exp;
452 char tlr;
453 SCM port;
454 int writing;
455#endif
456{
457 scm_gen_puts (scm_regular_string, hdr, port);
458 /* CHECK_INTS; */
459 scm_iprin1 (SCM_CAR (exp), port, writing);
460 exp = SCM_CDR (exp);
461 for (; SCM_NIMP (exp); exp = SCM_CDR (exp))
462 {
463 if (SCM_NECONSP (exp))
464 break;
465 scm_gen_putc (' ', port);
466 /* CHECK_INTS; */
467 scm_iprin1 (SCM_CAR (exp), port, writing);
468 }
469 if (SCM_NNULLP (exp))
470 {
471 scm_gen_puts (scm_regular_string, " . ", port);
472 scm_iprin1 (exp, port, writing);
473 }
474 scm_gen_putc (tlr, port);
475}
476
477\f
478
479SCM_PROC(s_write, "write", 1, 1, 0, scm_write);
480#ifdef __STDC__
481SCM
482scm_write (SCM obj, SCM port)
483#else
484SCM
485scm_write (obj, port)
486 SCM obj;
487 SCM port;
488#endif
489{
490 if (SCM_UNBNDP (port))
491 port = scm_cur_outp;
492 else
493 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG2, s_write);
494 scm_iprin1 (obj, port, 1);
495#ifdef HAVE_PIPE
496# ifdef EPIPE
497 if (EPIPE == errno)
498 scm_close_port (port);
499# endif
500#endif
501 return SCM_UNSPECIFIED;
502}
503
504
505SCM_PROC(s_display, "display", 1, 1, 0, scm_display);
506#ifdef __STDC__
507SCM
508scm_display (SCM obj, SCM port)
509#else
510SCM
511scm_display (obj, port)
512 SCM obj;
513 SCM port;
514#endif
515{
516 if (SCM_UNBNDP (port))
517 port = scm_cur_outp;
518 else
519 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG2, s_display);
520 scm_iprin1 (obj, port, 0);
521#ifdef HAVE_PIPE
522# ifdef EPIPE
523 if (EPIPE == errno)
524 scm_close_port (port);
525# endif
526#endif
527 return SCM_UNSPECIFIED;
528}
529
530SCM_PROC(s_newline, "newline", 0, 1, 0, scm_newline);
531#ifdef __STDC__
532SCM
533scm_newline(SCM port)
534#else
535SCM
536scm_newline (port)
537 SCM port;
538#endif
539{
540 if (SCM_UNBNDP (port))
541 port = scm_cur_outp;
542 else
543 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG1, s_newline);
544 scm_gen_putc ('\n', port);
545#ifdef HAVE_PIPE
546# ifdef EPIPE
547 if (EPIPE == errno)
548 scm_close_port (port);
549 else
550# endif
551#endif
552 if (port == scm_cur_outp)
553 scm_fflush (port);
554 return SCM_UNSPECIFIED;
555}
556
557SCM_PROC(s_write_char, "write-char", 1, 1, 0, scm_write_char);
558#ifdef __STDC__
559SCM
560scm_write_char (SCM chr, SCM port)
561#else
562SCM
563scm_write_char (chr, port)
564 SCM chr;
565 SCM port;
566#endif
567{
568 if (SCM_UNBNDP (port))
569 port = scm_cur_outp;
570 else
571 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG2, s_write_char);
572 SCM_ASSERT (SCM_ICHRP (chr), chr, SCM_ARG1, s_write_char);
573 scm_gen_putc ((int) SCM_ICHR (chr), port);
574#ifdef HAVE_PIPE
575# ifdef EPIPE
576 if (EPIPE == errno)
577 scm_close_port (port);
578# endif
579#endif
580 return SCM_UNSPECIFIED;
581}
582
583
584\f
585
586#ifdef __STDC__
587void
588scm_init_print (void)
589#else
590void
591scm_init_print ()
592#endif
593{
e6e4c9af 594#ifdef DEBUG_EXTENSIONS
b7ff98dd 595 scm_init_opts (scm_print_options, scm_print_opts, SCM_N_PRINT_OPTIONS);
e6e4c9af 596#endif
0f2d19dd
JB
597#include "print.x"
598}
599