1 /* Copyright (C) 1995,1996,1997,1999,2000,2001,2003, 2004, 2006, 2007 Free Software
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libguile/_scm.h"
31 #include "libguile/chars.h"
32 #include "libguile/eval.h"
33 #include "libguile/unif.h"
34 #include "libguile/keywords.h"
35 #include "libguile/alist.h"
36 #include "libguile/srcprop.h"
37 #include "libguile/hashtab.h"
38 #include "libguile/hash.h"
39 #include "libguile/ports.h"
40 #include "libguile/root.h"
41 #include "libguile/strings.h"
42 #include "libguile/strports.h"
43 #include "libguile/vectors.h"
44 #include "libguile/validate.h"
45 #include "libguile/srfi-4.h"
46 #include "libguile/srfi-13.h"
48 #include "libguile/read.h"
49 #include "libguile/private-options.h"
54 SCM_GLOBAL_SYMBOL (scm_sym_dot
, ".");
55 SCM_SYMBOL (scm_keyword_prefix
, "prefix");
57 scm_t_option scm_read_opts
[] = {
58 { SCM_OPTION_BOOLEAN
, "copy", 0,
59 "Copy source code expressions." },
60 { SCM_OPTION_BOOLEAN
, "positions", 0,
61 "Record positions of source code expressions." },
62 { SCM_OPTION_BOOLEAN
, "case-insensitive", 0,
63 "Convert symbols to lower case."},
64 { SCM_OPTION_SCM
, "keywords", SCM_UNPACK (SCM_BOOL_F
),
65 "Style of keyword recognition: #f or 'prefix."},
67 { SCM_OPTION_BOOLEAN
, "elisp-vectors", 0,
68 "Support Elisp vector syntax, namely `[...]'."},
69 { SCM_OPTION_BOOLEAN
, "elisp-strings", 0,
70 "Support `\\(' and `\\)' in strings."},
76 Give meaningful error messages for errors
80 FILE:LINE:COL: MESSAGE
83 This is not standard GNU format, but the test-suite likes the real
84 message to be in front.
90 scm_i_input_error (char const *function
,
91 SCM port
, const char *message
, SCM arg
)
93 SCM fn
= (scm_is_string (SCM_FILENAME(port
))
95 : scm_from_locale_string ("#<unknown port>"));
97 SCM string_port
= scm_open_output_string ();
99 scm_simple_format (string_port
,
100 scm_from_locale_string ("~A:~S:~S: ~A"),
102 scm_from_long (SCM_LINUM (port
) + 1),
103 scm_from_int (SCM_COL (port
) + 1),
104 scm_from_locale_string (message
)));
106 string
= scm_get_output_string (string_port
);
107 scm_close_output_port (string_port
);
108 scm_error_scm (scm_from_locale_symbol ("read-error"),
109 function
? scm_from_locale_string (function
) : SCM_BOOL_F
,
116 SCM_DEFINE (scm_read_options
, "read-options-interface", 0, 1, 0,
118 "Option interface for the read options. Instead of using\n"
119 "this procedure directly, use the procedures @code{read-enable},\n"
120 "@code{read-disable}, @code{read-set!} and @code{read-options}.")
121 #define FUNC_NAME s_scm_read_options
123 SCM ans
= scm_options (setting
,
126 if (SCM_COPY_SOURCE_P
)
127 SCM_RECORD_POSITIONS_P
= 1;
132 /* An association list mapping extra hash characters to procedures. */
133 static SCM
*scm_read_hash_procedures
;
140 /* Size of the C buffer used to read symbols and numbers. */
141 #define READER_BUFFER_SIZE 128
143 /* Size of the C buffer used to read strings. */
144 #define READER_STRING_BUFFER_SIZE 512
146 /* The maximum size of Scheme character names. */
147 #define READER_CHAR_NAME_MAX_SIZE 50
150 /* `isblank' is only in C99. */
151 #define CHAR_IS_BLANK_(_chr) \
152 (((_chr) == ' ') || ((_chr) == '\t') || ((_chr) == '\n') \
156 # define CHAR_IS_BLANK(_chr) \
157 ((CHAR_IS_BLANK_ (chr)) || ((_chr) == 26))
159 # define CHAR_IS_BLANK CHAR_IS_BLANK_
163 /* R5RS one-character delimiters (see section 7.1.1, ``Lexical
165 #define CHAR_IS_R5RS_DELIMITER(c) \
167 || (c == ')') || (c == '(') || (c == ';') || (c == '"'))
169 #define CHAR_IS_DELIMITER CHAR_IS_R5RS_DELIMITER
171 /* Exponent markers, as defined in section 7.1.1 of R5RS, ``Lexical
173 #define CHAR_IS_EXPONENT_MARKER(_chr) \
174 (((_chr) == 'e') || ((_chr) == 's') || ((_chr) == 'f') \
175 || ((_chr) == 'd') || ((_chr) == 'l'))
177 /* An inlinable version of `scm_c_downcase ()'. */
178 #define CHAR_DOWNCASE(_chr) \
179 (((_chr) <= UCHAR_MAX) ? tolower (_chr) : (_chr))
182 /* Helper function similar to `scm_read_token ()'. Read from PORT until a
183 whitespace is read. Return zero if the whole token could fit in BUF,
184 non-zero otherwise. */
186 read_token (SCM port
, char *buf
, size_t buf_size
, size_t *read
)
190 while (*read
< buf_size
)
194 chr
= scm_getc (port
);
195 chr
= (SCM_CASE_INSENSITIVE_P
? CHAR_DOWNCASE (chr
) : chr
);
199 else if (CHAR_IS_DELIMITER (chr
))
201 scm_ungetc (chr
, port
);
215 /* Skip whitespace from PORT and return the first non-whitespace character
216 read. Raise an error on end-of-file. */
218 flush_ws (SCM port
, const char *eoferr
)
222 switch (c
= scm_getc (port
))
228 scm_i_input_error (eoferr
,
237 switch (c
= scm_getc (port
))
243 case SCM_LINE_INCREMENTORS
:
248 case SCM_LINE_INCREMENTORS
:
249 case SCM_SINGLE_SPACES
:
264 static SCM
scm_read_expression (SCM port
);
265 static SCM
scm_read_sharp (int chr
, SCM port
);
266 static SCM
scm_get_hash_procedure (int c
);
267 static SCM
recsexpr (SCM obj
, long line
, int column
, SCM filename
);
271 scm_read_sexp (int chr
, SCM port
)
272 #define FUNC_NAME "scm_i_lreadparen"
276 register SCM tl
, ans
= SCM_EOL
;
277 SCM tl2
= SCM_EOL
, ans2
= SCM_EOL
, copy
= SCM_BOOL_F
;;
278 static const int terminating_char
= ')';
280 /* Need to capture line and column numbers here. */
281 long line
= SCM_LINUM (port
);
282 int column
= SCM_COL (port
) - 1;
285 c
= flush_ws (port
, FUNC_NAME
);
286 if (terminating_char
== c
)
289 scm_ungetc (c
, port
);
290 if (scm_is_eq (scm_sym_dot
,
291 (tmp
= scm_read_expression (port
))))
293 ans
= scm_read_expression (port
);
294 if (terminating_char
!= (c
= flush_ws (port
, FUNC_NAME
)))
295 scm_i_input_error (FUNC_NAME
, port
, "missing close paren",
300 /* Build the head of the list structure. */
301 ans
= tl
= scm_cons (tmp
, SCM_EOL
);
303 if (SCM_COPY_SOURCE_P
)
304 ans2
= tl2
= scm_cons (scm_is_pair (tmp
)
309 while (terminating_char
!= (c
= flush_ws (port
, FUNC_NAME
)))
313 scm_ungetc (c
, port
);
314 if (scm_is_eq (scm_sym_dot
,
315 (tmp
= scm_read_expression (port
))))
317 SCM_SETCDR (tl
, tmp
= scm_read_expression (port
));
319 if (SCM_COPY_SOURCE_P
)
320 SCM_SETCDR (tl2
, scm_cons (scm_is_pair (tmp
) ? copy
: tmp
,
323 c
= flush_ws (port
, FUNC_NAME
);
324 if (terminating_char
!= c
)
325 scm_i_input_error (FUNC_NAME
, port
,
326 "in pair: missing close paren", SCM_EOL
);
330 new_tail
= scm_cons (tmp
, SCM_EOL
);
331 SCM_SETCDR (tl
, new_tail
);
334 if (SCM_COPY_SOURCE_P
)
336 SCM new_tail2
= scm_cons (scm_is_pair (tmp
)
339 SCM_SETCDR (tl2
, new_tail2
);
345 if (SCM_RECORD_POSITIONS_P
)
346 scm_whash_insert (scm_source_whash
,
348 scm_make_srcprops (line
, column
,
359 scm_read_string (int chr
, SCM port
)
360 #define FUNC_NAME "scm_lreadr"
362 /* For strings smaller than C_STR, this function creates only one Scheme
363 object (the string returned). */
365 SCM str
= SCM_BOOL_F
;
366 char c_str
[READER_STRING_BUFFER_SIZE
];
367 unsigned c_str_len
= 0;
370 while ('"' != (c
= scm_getc (port
)))
373 str_eof
: scm_i_input_error (FUNC_NAME
, port
,
374 "end of file in string constant",
377 if (c_str_len
+ 1 >= sizeof (c_str
))
379 /* Flush the C buffer onto a Scheme string. */
382 if (str
== SCM_BOOL_F
)
383 str
= scm_c_make_string (0, SCM_MAKE_CHAR ('X'));
385 addy
= scm_from_locale_stringn (c_str
, c_str_len
);
386 str
= scm_string_append_shared (scm_list_2 (str
, addy
));
392 switch (c
= scm_getc (port
))
402 if (SCM_ESCAPED_PARENS_P
)
433 if (a
== EOF
) goto str_eof
;
435 if (b
== EOF
) goto str_eof
;
436 if ('0' <= a
&& a
<= '9') a
-= '0';
437 else if ('A' <= a
&& a
<= 'F') a
= a
- 'A' + 10;
438 else if ('a' <= a
&& a
<= 'f') a
= a
- 'a' + 10;
439 else goto bad_escaped
;
440 if ('0' <= b
&& b
<= '9') b
-= '0';
441 else if ('A' <= b
&& b
<= 'F') b
= b
- 'A' + 10;
442 else if ('a' <= b
&& b
<= 'f') b
= b
- 'a' + 10;
443 else goto bad_escaped
;
449 scm_i_input_error (FUNC_NAME
, port
,
450 "illegal character in escape sequence: ~S",
451 scm_list_1 (SCM_MAKE_CHAR (c
)));
453 c_str
[c_str_len
++] = c
;
460 addy
= scm_from_locale_stringn (c_str
, c_str_len
);
461 if (str
== SCM_BOOL_F
)
464 str
= scm_string_append_shared (scm_list_2 (str
, addy
));
467 str
= (str
== SCM_BOOL_F
) ? scm_nullstr
: str
;
475 scm_read_number (int chr
, SCM port
)
477 SCM result
, str
= SCM_EOL
;
478 char buffer
[READER_BUFFER_SIZE
];
482 scm_ungetc (chr
, port
);
485 overflow
= read_token (port
, buffer
, sizeof (buffer
), &read
);
487 if ((overflow
) || (scm_is_pair (str
)))
488 str
= scm_cons (scm_from_locale_stringn (buffer
, read
), str
);
492 if (scm_is_pair (str
))
496 str
= scm_string_concatenate (scm_reverse_x (str
, SCM_EOL
));
497 result
= scm_string_to_number (str
, SCM_UNDEFINED
);
498 if (!scm_is_true (result
))
499 /* Return a symbol instead of a number. */
500 result
= scm_string_to_symbol (str
);
504 result
= scm_c_locale_stringn_to_number (buffer
, read
, 10);
505 if (!scm_is_true (result
))
506 /* Return a symbol instead of a number. */
507 result
= scm_from_locale_symboln (buffer
, read
);
514 scm_read_mixed_case_symbol (int chr
, SCM port
)
516 SCM result
, str
= SCM_EOL
;
518 char buffer
[READER_BUFFER_SIZE
];
521 scm_ungetc (chr
, port
);
524 overflow
= read_token (port
, buffer
, sizeof (buffer
), &read
);
526 if ((overflow
) || (scm_is_pair (str
)))
527 str
= scm_cons (scm_from_locale_stringn (buffer
, read
), str
);
531 if (scm_is_pair (str
))
533 str
= scm_string_concatenate (scm_reverse_x (str
, SCM_EOL
));
534 result
= scm_string_to_symbol (str
);
537 /* For symbols smaller than `sizeof (buffer)', we don't need to recur to
538 Scheme strings. Therefore, we only create one Scheme object (a
539 symbol) per symbol read. */
540 result
= scm_from_locale_symboln (buffer
, read
);
546 scm_read_number_and_radix (int chr
, SCM port
)
547 #define FUNC_NAME "scm_lreadr"
549 SCM result
, str
= SCM_EOL
;
551 char buffer
[READER_BUFFER_SIZE
];
578 scm_ungetc (chr
, port
);
579 scm_ungetc ('#', port
);
585 overflow
= read_token (port
, buffer
, sizeof (buffer
), &read
);
587 if ((overflow
) || (scm_is_pair (str
)))
588 str
= scm_cons (scm_from_locale_stringn (buffer
, read
), str
);
592 if (scm_is_pair (str
))
594 str
= scm_string_concatenate (scm_reverse_x (str
, SCM_EOL
));
595 result
= scm_string_to_number (str
, scm_from_uint (radix
));
598 result
= scm_c_locale_stringn_to_number (buffer
, read
, radix
);
600 if (scm_is_true (result
))
603 scm_i_input_error (FUNC_NAME
, port
, "unknown # object", SCM_EOL
);
610 scm_read_quote (int chr
, SCM port
)
613 long line
= SCM_LINUM (port
);
614 int column
= SCM_COL (port
) - 1;
619 p
= scm_sym_quasiquote
;
632 p
= scm_sym_uq_splicing
;
635 scm_ungetc (c
, port
);
642 fprintf (stderr
, "%s: unhandled quote character (%i)\n",
647 p
= scm_cons2 (p
, scm_read_expression (port
), SCM_EOL
);
648 if (SCM_RECORD_POSITIONS_P
)
649 scm_whash_insert (scm_source_whash
, p
,
650 scm_make_srcprops (line
, column
,
653 ? (scm_cons2 (SCM_CAR (p
),
654 SCM_CAR (SCM_CDR (p
)),
664 scm_read_semicolon_comment (int chr
, SCM port
)
668 for (c
= scm_getc (port
);
669 (c
!= EOF
) && (c
!= '\n');
670 c
= scm_getc (port
));
672 return SCM_UNSPECIFIED
;
676 /* Sharp readers, i.e. readers called after a `#' sign has been read. */
679 scm_read_boolean (int chr
, SCM port
)
692 return SCM_UNSPECIFIED
;
696 scm_read_character (int chr
, SCM port
)
697 #define FUNC_NAME "scm_lreadr"
700 char charname
[READER_CHAR_NAME_MAX_SIZE
];
703 if (read_token (port
, charname
, sizeof (charname
), &charname_len
))
706 if (charname_len
== 0)
708 chr
= scm_getc (port
);
710 scm_i_input_error (FUNC_NAME
, port
, "unexpected end of file "
711 "while reading character", SCM_EOL
);
713 /* CHR must be a token delimiter, like a whitespace. */
714 return (SCM_MAKE_CHAR (chr
));
717 if (charname_len
== 1)
718 return SCM_MAKE_CHAR (charname
[0]);
720 if (*charname
>= '0' && *charname
< '8')
722 /* Dirk:FIXME:: This type of character syntax is not R5RS
723 * compliant. Further, it should be verified that the constant
724 * does only consist of octal digits. Finally, it should be
725 * checked whether the resulting fixnum is in the range of
727 SCM p
= scm_c_locale_stringn_to_number (charname
, charname_len
, 8);
729 return SCM_MAKE_CHAR (SCM_I_INUM (p
));
732 for (c
= 0; c
< scm_n_charnames
; c
++)
734 && (!strncasecmp (scm_charnames
[c
], charname
, charname_len
)))
735 return SCM_MAKE_CHAR (scm_charnums
[c
]);
738 scm_i_input_error (FUNC_NAME
, port
, "unknown character name ~a",
739 scm_list_1 (scm_from_locale_stringn (charname
,
742 return SCM_UNSPECIFIED
;
747 scm_read_keyword (int chr
, SCM port
)
751 /* Read the symbol that comprises the keyword. Doing this instead of
752 invoking a specific symbol reader function allows `scm_read_keyword ()'
753 to adapt to the delimiters currently valid of symbols.
755 XXX: This implementation allows sloppy syntaxes like `#: key'. */
756 symbol
= scm_read_expression (port
);
757 if (!scm_is_symbol (symbol
))
758 scm_i_input_error (__FUNCTION__
, port
,
759 "keyword prefix `~a' not followed by a symbol: ~s",
760 scm_list_2 (SCM_MAKE_CHAR (chr
), symbol
));
762 return (scm_symbol_to_keyword (symbol
));
766 scm_read_vector (int chr
, SCM port
)
768 /* Note: We call `scm_read_sexp ()' rather than READER here in order to
769 guarantee that it's going to do what we want. After all, this is an
770 implementation detail of `scm_read_vector ()', not a desirable
772 return (scm_vector (scm_read_sexp (chr
, port
)));
776 scm_read_srfi4_vector (int chr
, SCM port
)
778 return scm_i_read_array (port
, chr
);
782 scm_read_guile_bit_vector (int chr
, SCM port
)
784 /* Read the `#*10101'-style read syntax for bit vectors in Guile. This is
785 terribly inefficient but who cares? */
786 SCM s_bits
= SCM_EOL
;
788 for (chr
= scm_getc (port
);
789 (chr
!= EOF
) && ((chr
== '0') || (chr
== '1'));
790 chr
= scm_getc (port
))
792 s_bits
= scm_cons ((chr
== '0') ? SCM_BOOL_F
: SCM_BOOL_T
, s_bits
);
796 scm_ungetc (chr
, port
);
798 return scm_bitvector (scm_reverse_x (s_bits
, SCM_EOL
));
802 scm_read_scsh_block_comment (int chr
, SCM port
)
808 int c
= scm_getc (port
);
811 scm_i_input_error ("skip_block_comment", port
,
812 "unterminated `#! ... !#' comment", SCM_EOL
);
816 else if (c
== '#' && bang_seen
)
822 return SCM_UNSPECIFIED
;
826 scm_read_extended_symbol (int chr
, SCM port
)
828 /* Guile's extended symbol read syntax looks like this:
830 #{This is all a symbol name}#
832 So here, CHR is expected to be `{'. */
834 int saw_brace
= 0, finished
= 0;
838 result
= scm_c_make_string (0, SCM_MAKE_CHAR ('X'));
840 while ((chr
= scm_getc (port
)) != EOF
)
861 if (len
>= sizeof (buf
) - 2)
863 scm_string_append (scm_list_2 (result
,
864 scm_from_locale_stringn (buf
, len
)));
873 result
= scm_string_append (scm_list_2
875 scm_from_locale_stringn (buf
, len
)));
877 return (scm_string_to_symbol (result
));
882 /* Top-level token readers, i.e., dispatchers. */
885 scm_read_sharp_extension (int chr
, SCM port
)
889 proc
= scm_get_hash_procedure (chr
);
890 if (scm_is_true (scm_procedure_p (proc
)))
892 long line
= SCM_LINUM (port
);
893 int column
= SCM_COL (port
) - 2;
896 got
= scm_call_2 (proc
, SCM_MAKE_CHAR (chr
), port
);
897 if (!scm_is_eq (got
, SCM_UNSPECIFIED
))
899 if (SCM_RECORD_POSITIONS_P
)
900 return (recsexpr (got
, line
, column
,
901 SCM_FILENAME (port
)));
907 return SCM_UNSPECIFIED
;
910 /* The reader for the sharp `#' character. It basically dispatches reads
911 among the above token readers. */
913 scm_read_sharp (int chr
, SCM port
)
914 #define FUNC_NAME "scm_lreadr"
918 chr
= scm_getc (port
);
920 result
= scm_read_sharp_extension (chr
, port
);
921 if (!scm_is_eq (result
, SCM_UNSPECIFIED
))
927 return (scm_read_character (chr
, port
));
929 return (scm_read_vector (chr
, port
));
933 /* This one may return either a boolean or an SRFI-4 vector. */
934 return (scm_read_srfi4_vector (chr
, port
));
936 return (scm_read_guile_bit_vector (chr
, port
));
940 /* This one may return either a boolean or an SRFI-4 vector. */
941 return (scm_read_boolean (chr
, port
));
943 return (scm_read_keyword (chr
, port
));
944 case '0': case '1': case '2': case '3': case '4':
945 case '5': case '6': case '7': case '8': case '9':
947 #if SCM_ENABLE_DEPRECATED
948 /* See below for 'i' and 'e'. */
955 return (scm_i_read_array (port
, chr
));
959 #if SCM_ENABLE_DEPRECATED
961 /* When next char is '(', it really is an old-style
963 int next_c
= scm_getc (port
);
965 scm_ungetc (next_c
, port
);
967 return scm_i_read_array (port
, chr
);
981 return (scm_read_number_and_radix (chr
, port
));
983 return (scm_read_extended_symbol (chr
, port
));
985 return (scm_read_scsh_block_comment (chr
, port
));
987 result
= scm_read_sharp_extension (chr
, port
);
988 if (scm_is_eq (result
, SCM_UNSPECIFIED
))
989 scm_i_input_error (FUNC_NAME
, port
, "Unknown # object: ~S",
990 scm_list_1 (SCM_MAKE_CHAR (chr
)));
995 return SCM_UNSPECIFIED
;
1000 scm_read_expression (SCM port
)
1001 #define FUNC_NAME "scm_read_expression"
1007 chr
= scm_getc (port
);
1011 case SCM_WHITE_SPACES
:
1012 case SCM_LINE_INCREMENTORS
:
1015 (void) scm_read_semicolon_comment (chr
, port
);
1018 return (scm_read_sexp (chr
, port
));
1020 return (scm_read_string (chr
, port
));
1024 return (scm_read_quote (chr
, port
));
1028 result
= scm_read_sharp (chr
, port
);
1029 if (scm_is_eq (result
, SCM_UNSPECIFIED
))
1030 /* We read a comment or some such. */
1036 scm_i_input_error (FUNC_NAME
, port
, "unexpected \")\"", SCM_EOL
);
1041 if (scm_is_eq (SCM_PACK (SCM_KEYWORD_STYLE
), scm_keyword_prefix
))
1042 return scm_symbol_to_keyword (scm_read_expression (port
));
1047 if (((chr
>= '0') && (chr
<= '9'))
1048 || (strchr ("+-.", chr
)))
1049 return (scm_read_number (chr
, port
));
1051 return (scm_read_mixed_case_symbol (chr
, port
));
1059 /* Actual reader. */
1061 SCM_DEFINE (scm_read
, "read", 0, 1, 0,
1063 "Read an s-expression from the input port @var{port}, or from\n"
1064 "the current input port if @var{port} is not specified.\n"
1065 "Any whitespace before the next token is discarded.")
1066 #define FUNC_NAME s_scm_read
1070 if (SCM_UNBNDP (port
))
1071 port
= scm_current_input_port ();
1072 SCM_VALIDATE_OPINPORT (1, port
);
1074 c
= flush_ws (port
, (char *) NULL
);
1077 scm_ungetc (c
, port
);
1079 return (scm_read_expression (port
));
1086 /* Used when recording expressions constructed by `scm_read_sharp ()'. */
1088 recsexpr (SCM obj
, long line
, int column
, SCM filename
)
1090 if (!scm_is_pair(obj
)) {
1093 SCM tmp
= obj
, copy
;
1094 /* If this sexpr is visible in the read:sharp source, we want to
1095 keep that information, so only record non-constant cons cells
1096 which haven't previously been read by the reader. */
1097 if (scm_is_false (scm_whash_lookup (scm_source_whash
, obj
)))
1099 if (SCM_COPY_SOURCE_P
)
1101 copy
= scm_cons (recsexpr (SCM_CAR (obj
), line
, column
, filename
),
1103 while ((tmp
= SCM_CDR (tmp
)) && scm_is_pair (tmp
))
1105 SCM_SETCDR (copy
, scm_cons (recsexpr (SCM_CAR (tmp
),
1110 copy
= SCM_CDR (copy
);
1112 SCM_SETCDR (copy
, tmp
);
1116 recsexpr (SCM_CAR (obj
), line
, column
, filename
);
1117 while ((tmp
= SCM_CDR (tmp
)) && scm_is_pair (tmp
))
1118 recsexpr (SCM_CAR (tmp
), line
, column
, filename
);
1119 copy
= SCM_UNDEFINED
;
1121 scm_whash_insert (scm_source_whash
,
1123 scm_make_srcprops (line
,
1133 /* Manipulate the read-hash-procedures alist. This could be written in
1134 Scheme, but maybe it will also be used by C code during initialisation. */
1135 SCM_DEFINE (scm_read_hash_extend
, "read-hash-extend", 2, 0, 0,
1136 (SCM chr
, SCM proc
),
1137 "Install the procedure @var{proc} for reading expressions\n"
1138 "starting with the character sequence @code{#} and @var{chr}.\n"
1139 "@var{proc} will be called with two arguments: the character\n"
1140 "@var{chr} and the port to read further data from. The object\n"
1141 "returned will be the return value of @code{read}. \n"
1142 "Passing @code{#f} for @var{proc} will remove a previous setting. \n"
1144 #define FUNC_NAME s_scm_read_hash_extend
1149 SCM_VALIDATE_CHAR (1, chr
);
1150 SCM_ASSERT (scm_is_false (proc
)
1151 || scm_is_eq (scm_procedure_p (proc
), SCM_BOOL_T
),
1152 proc
, SCM_ARG2
, FUNC_NAME
);
1154 /* Check if chr is already in the alist. */
1155 this = *scm_read_hash_procedures
;
1159 if (scm_is_null (this))
1161 /* not found, so add it to the beginning. */
1162 if (scm_is_true (proc
))
1164 *scm_read_hash_procedures
=
1165 scm_cons (scm_cons (chr
, proc
), *scm_read_hash_procedures
);
1169 if (scm_is_eq (chr
, SCM_CAAR (this)))
1171 /* already in the alist. */
1172 if (scm_is_false (proc
))
1175 if (scm_is_false (prev
))
1177 *scm_read_hash_procedures
=
1178 SCM_CDR (*scm_read_hash_procedures
);
1181 scm_set_cdr_x (prev
, SCM_CDR (this));
1186 scm_set_cdr_x (SCM_CAR (this), proc
);
1191 this = SCM_CDR (this);
1194 return SCM_UNSPECIFIED
;
1198 /* Recover the read-hash procedure corresponding to char c. */
1200 scm_get_hash_procedure (int c
)
1202 SCM rest
= *scm_read_hash_procedures
;
1206 if (scm_is_null (rest
))
1209 if (SCM_CHAR (SCM_CAAR (rest
)) == c
)
1210 return SCM_CDAR (rest
);
1212 rest
= SCM_CDR (rest
);
1219 scm_read_hash_procedures
=
1220 SCM_VARIABLE_LOC (scm_c_define ("read-hash-procedures", SCM_EOL
));
1222 scm_init_opts (scm_read_options
, scm_read_opts
);
1223 #include "libguile/read.x"