* options.h, options.c: Options now have documentation strings.
[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[] = {
93 { SCM_OPTION_BOOLEAN, "procnames", 0 },
94};
95
96SCM_PROC (s_print_options, "print-options", 0, 1, 0, scm_print_options);
97#ifdef __STDC__
98SCM
99scm_print_options (SCM new_values)
100#else
101SCM
102scm_print_options (new_values)
103 SCM new_values;
104#endif
105{
106 SCM ans = scm_change_options (new_values,
107 scm_print_opts,
108 N_PRINT_OPTIONS,
109 s_print_options);
110 return ans;
111}
112#endif
113
0f2d19dd
JB
114\f
115/* {Printing of Scheme Objects}
116 */
117
118/* Print generally. Handles both write and display according to WRITING.
119 */
120#ifdef __STDC__
121void
122scm_iprin1 (SCM exp, SCM port, int writing)
123#else
124void
125scm_iprin1 (exp, port, writing)
126 SCM exp;
127 SCM port;
128 int writing;
129#endif
130{
131 register long i;
132taloop:
133 switch (7 & (int) exp)
134 {
135 case 2:
136 case 6:
137 scm_intprint (SCM_INUM (exp), 10, port);
138 break;
139 case 4:
140 if (SCM_ICHRP (exp))
141 {
142 i = SCM_ICHR (exp);
143 scm_put_wchar (i, port, writing);
144
145 }
146 else if ( SCM_IFLAGP (exp)
147 && (SCM_ISYMNUM (exp) < (sizeof scm_isymnames / sizeof (char *))))
148 scm_gen_puts (scm_regular_string, SCM_ISYMSCM_CHARS (exp), port);
149 else if (SCM_ILOCP (exp))
150 {
151 scm_gen_puts (scm_regular_string, "#@", port);
152 scm_intprint ((long) SCM_IFRAME (exp), 10, port);
153 scm_gen_putc (SCM_ICDRP (exp) ? '-' : '+', port);
154 scm_intprint ((long) SCM_IDIST (exp), 10, port);
155 }
156 else
157 goto idef;
158 break;
159 case 1:
160 /* gloc */
161 scm_gen_puts (scm_regular_string, "#@", port);
162 exp = SCM_CAR (exp - 1);
163 goto taloop;
164 default:
165 idef:
166 scm_ipruk ("immediate", exp, port);
167 break;
168 case 0:
169 switch (SCM_TYP7 (exp))
170 {
171 case scm_tcs_cons_gloc:
172
173 if (SCM_CDR (SCM_CAR (exp) - 1L) == 0)
174 {
175 scm_gen_write (scm_regular_string, "#<struct ", (scm_sizet) 9, port);
176 scm_intprint(exp, 16, port);
177 scm_gen_putc ('>', port);
178 break;
179 }
180
181 case scm_tcs_cons_imcar:
182 case scm_tcs_cons_nimcar:
183 scm_iprlist ("(", exp, ')', port, writing);
184 break;
185 case scm_tcs_closures:
186#ifdef DEBUG_EXTENSIONS
187 if (PRINT_PROCNAMES)
188 {
189 SCM name;
190 name = scm_procedure_property (exp, scm_i_name);
191 scm_gen_puts (scm_regular_string, "#<procedure", port);
192 if (SCM_NFALSEP (name))
193 {
194 scm_gen_putc (' ', port);
195 /* FIXME */
196 scm_gen_puts (scm_regular_string, SCM_CHARS (name), port);
197 }
198 scm_gen_putc ('>', port);
199 }
200 else
201#endif
202 {
203 exp = SCM_CODE (exp);
204 scm_iprlist ("#<CLOSURE ", exp, '>', port, writing);
205 }
206 break;
207 case scm_tc7_mb_string:
208 case scm_tc7_mb_substring:
209 scm_print_mb_string (exp, port, writing);
210 break;
211 case scm_tc7_substring:
212 case scm_tc7_string:
213 if (writing)
214 {
215 scm_gen_putc ('\"', port);
216 for (i = 0; i < SCM_ROLENGTH (exp); ++i)
217 switch (SCM_ROCHARS (exp)[i])
218 {
219 case '\"':
220 case '\\':
221 scm_gen_putc ('\\', port);
222 default:
223 scm_gen_putc (SCM_ROCHARS (exp)[i], port);
224 }
225 scm_gen_putc ('\"', port);
226 break;
227 }
228 else
229 scm_gen_write (scm_regular_string, SCM_ROCHARS (exp),
230 (scm_sizet) SCM_ROLENGTH (exp),
231 port);
232 break;
233 case scm_tcs_symbols:
234 if (SCM_MB_STRINGP (exp))
235 {
236 scm_print_mb_symbol (exp, port);
237 break;
238 }
239 else
240 {
241 int pos;
242 int end;
243 int len;
244 char * str;
245 int weird;
246 int maybe_weird;
247 int mw_pos;
248
249 len = SCM_LENGTH (exp);
250 str = SCM_CHARS (exp);
251 scm_remember (&exp);
252 pos = 0;
253 weird = 0;
254 maybe_weird = 0;
255
256 if (len == 0)
257 scm_gen_write (scm_regular_string, "#{}#", 4, port);
258
259 for (end = pos; end < len; ++end)
260 switch (str[end])
261 {
262#ifdef BRACKETS_AS_PARENS
263 case '[':
264 case ']':
265#endif
266 case '(':
267 case ')':
268 case '\"':
269 case ';':
270 case SCM_WHITE_SPACES:
271 case SCM_LINE_INCREMENTORS:
272 weird_handler:
273 if (maybe_weird)
274 {
275 end = mw_pos;
276 maybe_weird = 0;
277 }
278 if (!weird)
279 {
280 scm_gen_write (scm_regular_string, "#{", 2, port);
281 weird = 1;
282 }
283 if (pos < end)
284 {
285 scm_gen_write (scm_regular_string, str + pos, end - pos, port);
286 }
287 {
288 char buf[2];
289 buf[0] = '\\';
290 buf[1] = str[end];
291 scm_gen_write (scm_regular_string, buf, 2, port);
292 }
293 pos = end + 1;
294 break;
295 case '\\':
296 if (weird)
297 goto weird_handler;
298 if (!maybe_weird)
299 {
300 maybe_weird = 1;
301 mw_pos = pos;
302 }
303 break;
304 case '}':
305 case '#':
306 if (weird)
307 goto weird_handler;
308 break;
309 default:
310 break;
311 }
312 if (pos < end)
313 scm_gen_write (scm_regular_string, str + pos, end - pos, port);
314 if (weird)
315 scm_gen_write (scm_regular_string, "}#", 2, port);
316 break;
317 }
318 case scm_tc7_wvect:
319 if (SCM_IS_WHVEC (exp))
320 scm_gen_puts (scm_regular_string, "#wh(", port);
321 else
322 scm_gen_puts (scm_regular_string, "#w(", port);
323 goto common_vector_printer;
324
325 case scm_tc7_vector:
326 scm_gen_puts (scm_regular_string, "#(", port);
327 common_vector_printer:
328 for (i = 0; i + 1 < SCM_LENGTH (exp); ++i)
329 {
330 /* CHECK_INTS; */
331 scm_iprin1 (SCM_VELTS (exp)[i], port, writing);
332 scm_gen_putc (' ', port);
333 }
334 if (i < SCM_LENGTH (exp))
335 {
336 /* CHECK_INTS; */
337 scm_iprin1 (SCM_VELTS (exp)[i], port, writing);
338 }
339 scm_gen_putc (')', port);
340 break;
341 case scm_tc7_bvect:
342 case scm_tc7_byvect:
343 case scm_tc7_svect:
344 case scm_tc7_ivect:
345 case scm_tc7_uvect:
346 case scm_tc7_fvect:
347 case scm_tc7_dvect:
348 case scm_tc7_cvect:
349#ifdef LONGLONGS
350 case scm_tc7_llvect:
351#endif
352 scm_raprin1 (exp, port, writing);
353 break;
354 case scm_tcs_subrs:
355 scm_gen_puts (scm_regular_string, "#<primitive-procedure ", port);
356 scm_gen_puts ((SCM_MB_STRINGP (SCM_SNAME(exp))
357 ? scm_mb_string
358 : scm_regular_string),
359 SCM_CHARS (SCM_SNAME (exp)), port);
360 scm_gen_putc ('>', port);
361 break;
362#ifdef CCLO
363 case scm_tc7_cclo:
364 scm_gen_puts (scm_regular_string, "#<compiled-closure ", port);
365 scm_iprin1 (SCM_CCLO_SUBR (exp), port, writing);
366 scm_gen_putc ('>', port);
367 break;
368#endif
369 case scm_tc7_contin:
370 scm_gen_puts (scm_regular_string, "#<continuation ", port);
371 scm_intprint (SCM_LENGTH (exp), 10, port);
372 scm_gen_puts (scm_regular_string, " @ ", port);
373 scm_intprint ((long) SCM_CHARS (exp), 16, port);
374 scm_gen_putc ('>', port);
375 break;
376 case scm_tc7_port:
377 i = SCM_PTOBNUM (exp);
378 if (i < scm_numptob && scm_ptobs[i].print && (scm_ptobs[i].print) (exp, port, writing))
379 break;
380 goto punk;
381 case scm_tc7_smob:
382 i = SCM_SMOBNUM (exp);
383 if (i < scm_numsmob && scm_smobs[i].print
384 && (scm_smobs[i].print) (exp, port, writing))
385 break;
386 goto punk;
387 default:
388 punk:scm_ipruk ("type", exp, port);
389 }
390 }
391}
392
393
394/* Print an integer.
395 */
396#ifdef __STDC__
397void
398scm_intprint (long n, int radix, SCM port)
399#else
400void
401scm_intprint (n, radix, port)
402 long n;
403 int radix;
404 SCM port;
405#endif
406{
407 char num_buf[SCM_INTBUFLEN];
408 scm_gen_write (scm_regular_string, num_buf, scm_iint2str (n, radix, num_buf), port);
409}
410
411/* Print an object of unrecognized type.
412 */
413#ifdef __STDC__
414void
415scm_ipruk (char *hdr, SCM ptr, SCM port)
416#else
417void
418scm_ipruk (hdr, ptr, port)
419 char *hdr;
420 SCM ptr;
421 SCM port;
422#endif
423{
424 scm_gen_puts (scm_regular_string, "#<unknown-", port);
425 scm_gen_puts (scm_regular_string, hdr, port);
426 if (SCM_CELLP (ptr))
427 {
428 scm_gen_puts (scm_regular_string, " (0x", port);
429 scm_intprint (SCM_CAR (ptr), 16, port);
430 scm_gen_puts (scm_regular_string, " . 0x", port);
431 scm_intprint (SCM_CDR (ptr), 16, port);
432 scm_gen_puts (scm_regular_string, ") @", port);
433 }
434 scm_gen_puts (scm_regular_string, " 0x", port);
435 scm_intprint (ptr, 16, port);
436 scm_gen_putc ('>', port);
437}
438
439/* Print a list.
440 */
441#ifdef __STDC__
442void
443scm_iprlist (char *hdr, SCM exp, char tlr, SCM port, int writing)
444#else
445void
446scm_iprlist (hdr, exp, tlr, port, writing)
447 char *hdr;
448 SCM exp;
449 char tlr;
450 SCM port;
451 int writing;
452#endif
453{
454 scm_gen_puts (scm_regular_string, hdr, port);
455 /* CHECK_INTS; */
456 scm_iprin1 (SCM_CAR (exp), port, writing);
457 exp = SCM_CDR (exp);
458 for (; SCM_NIMP (exp); exp = SCM_CDR (exp))
459 {
460 if (SCM_NECONSP (exp))
461 break;
462 scm_gen_putc (' ', port);
463 /* CHECK_INTS; */
464 scm_iprin1 (SCM_CAR (exp), port, writing);
465 }
466 if (SCM_NNULLP (exp))
467 {
468 scm_gen_puts (scm_regular_string, " . ", port);
469 scm_iprin1 (exp, port, writing);
470 }
471 scm_gen_putc (tlr, port);
472}
473
474\f
475
476SCM_PROC(s_write, "write", 1, 1, 0, scm_write);
477#ifdef __STDC__
478SCM
479scm_write (SCM obj, SCM port)
480#else
481SCM
482scm_write (obj, port)
483 SCM obj;
484 SCM port;
485#endif
486{
487 if (SCM_UNBNDP (port))
488 port = scm_cur_outp;
489 else
490 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG2, s_write);
491 scm_iprin1 (obj, port, 1);
492#ifdef HAVE_PIPE
493# ifdef EPIPE
494 if (EPIPE == errno)
495 scm_close_port (port);
496# endif
497#endif
498 return SCM_UNSPECIFIED;
499}
500
501
502SCM_PROC(s_display, "display", 1, 1, 0, scm_display);
503#ifdef __STDC__
504SCM
505scm_display (SCM obj, SCM port)
506#else
507SCM
508scm_display (obj, port)
509 SCM obj;
510 SCM port;
511#endif
512{
513 if (SCM_UNBNDP (port))
514 port = scm_cur_outp;
515 else
516 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG2, s_display);
517 scm_iprin1 (obj, port, 0);
518#ifdef HAVE_PIPE
519# ifdef EPIPE
520 if (EPIPE == errno)
521 scm_close_port (port);
522# endif
523#endif
524 return SCM_UNSPECIFIED;
525}
526
527SCM_PROC(s_newline, "newline", 0, 1, 0, scm_newline);
528#ifdef __STDC__
529SCM
530scm_newline(SCM port)
531#else
532SCM
533scm_newline (port)
534 SCM port;
535#endif
536{
537 if (SCM_UNBNDP (port))
538 port = scm_cur_outp;
539 else
540 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG1, s_newline);
541 scm_gen_putc ('\n', port);
542#ifdef HAVE_PIPE
543# ifdef EPIPE
544 if (EPIPE == errno)
545 scm_close_port (port);
546 else
547# endif
548#endif
549 if (port == scm_cur_outp)
550 scm_fflush (port);
551 return SCM_UNSPECIFIED;
552}
553
554SCM_PROC(s_write_char, "write-char", 1, 1, 0, scm_write_char);
555#ifdef __STDC__
556SCM
557scm_write_char (SCM chr, SCM port)
558#else
559SCM
560scm_write_char (chr, port)
561 SCM chr;
562 SCM port;
563#endif
564{
565 if (SCM_UNBNDP (port))
566 port = scm_cur_outp;
567 else
568 SCM_ASSERT (SCM_NIMP (port) && SCM_OPOUTPORTP (port), port, SCM_ARG2, s_write_char);
569 SCM_ASSERT (SCM_ICHRP (chr), chr, SCM_ARG1, s_write_char);
570 scm_gen_putc ((int) SCM_ICHR (chr), port);
571#ifdef HAVE_PIPE
572# ifdef EPIPE
573 if (EPIPE == errno)
574 scm_close_port (port);
575# endif
576#endif
577 return SCM_UNSPECIFIED;
578}
579
580
581\f
582
583#ifdef __STDC__
584void
585scm_init_print (void)
586#else
587void
588scm_init_print ()
589#endif
590{
e6e4c9af
MD
591#ifdef DEBUG_EXTENSIONS
592 scm_init_opts (scm_print_options, scm_print_opts, N_PRINT_OPTIONS);
593#endif
0f2d19dd
JB
594#include "print.x"
595}
596