1 /* Copyright (C) 1995,1996 Free Software Foundation, Inc.
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)
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.
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.
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
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.
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
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.
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.
50 #include "mbstrings.h"
58 #define default_case_i 0
62 #ifdef READER_EXTENSIONS
63 scm_option scm_read_opts
[] = {
64 { SCM_OPTION_BOOLEAN
, "copy", 0,
65 "Copy source code expressions." },
66 { SCM_OPTION_BOOLEAN
, "positions", 0,
67 "Record positions of source code expressions." }
70 SCM_PROC (s_read_options
, "read-options-interface", 0, 1, 0, scm_read_options
);
73 scm_read_options (SCM setting
)
76 scm_read_options (setting
)
80 SCM ans
= scm_options (setting
,
84 if (SCM_COPY_SOURCE_P
)
85 SCM_RECORD_POSITIONS_P
= 1;
90 SCM_PROC (s_read
, "read", 0, 3, 0, scm_read
);
93 scm_read (SCM port
, SCM case_insensitive_p
, SCM sharp
)
96 scm_read (port
, case_insensitive_p
, sharp
)
98 SCM case_insensitive_p
;
106 if (SCM_UNBNDP (port
))
109 SCM_ASSERT (SCM_NIMP (port
) && SCM_OPINPORTP (port
), port
, SCM_ARG1
, s_read
);
111 case_i
= (SCM_UNBNDP (case_insensitive_p
)
113 : (case_insensitive_p
== SCM_BOOL_F
));
115 if (SCM_UNBNDP (sharp
))
118 c
= scm_flush_ws (port
, (char *) NULL
);
121 scm_gen_ungetc (c
, port
);
123 tok_buf
= scm_makstr (30L, 0);
124 return scm_lreadr (&tok_buf
, port
, case_i
, sharp
);
130 scm_grow_tok_buf (SCM
* tok_buf
)
133 scm_grow_tok_buf (tok_buf
)
140 len
= SCM_LENGTH (*tok_buf
);
141 len
+= (len
/ 2 ? len
/ 2 : 1);
142 t2
= scm_makstr (len
, 0);
147 for (a
= SCM_CHARS (*tok_buf
), b
= SCM_CHARS (t2
), l
= SCM_LENGTH (*tok_buf
);
153 return SCM_CHARS (*tok_buf
);
159 scm_flush_ws (SCM port
, char *eoferr
)
162 scm_flush_ws (port
, eoferr
)
169 switch (c
= scm_gen_getc (port
))
174 scm_wta (SCM_UNDEFINED
, "end of file in ", eoferr
);
178 switch (c
= scm_gen_getc (port
))
184 case SCM_LINE_INCREMENTORS
:
188 case SCM_LINE_INCREMENTORS
:
190 case SCM_SINGLE_SPACES
:
204 scm_casei_streq (char * s1
, char * s2
)
207 scm_casei_streq (s1
, s2
)
213 if (scm_downcase((int)*s1
) != scm_downcase((int)*s2
))
220 return !(*s1
|| *s2
);
226 scm_lreadr (SCM
* tok_buf
, SCM port
, int case_i
, SCM sharp
)
229 scm_lreadr (tok_buf
, port
, case_i
, sharp
)
241 c
= scm_flush_ws (port
, s_read
);
248 return scm_lreadparen (tok_buf
, port
, "list", case_i
, sharp
);
251 scm_wta (SCM_UNDEFINED
, "unexpected \")\"", "read");
255 return scm_cons2 (scm_i_quote
, scm_lreadr (tok_buf
, port
, case_i
, sharp
), SCM_EOL
);
258 return scm_cons2 (scm_i_quasiquote
, scm_lreadr (tok_buf
, port
, case_i
, sharp
), SCM_EOL
);
261 c
= scm_gen_getc (port
);
263 p
= scm_i_uq_splicing
;
266 scm_gen_ungetc (c
, port
);
269 return scm_cons2 (p
, scm_lreadr (tok_buf
, port
, case_i
, sharp
), SCM_EOL
);
272 c
= scm_gen_getc (port
);
276 p
= scm_lreadparen (tok_buf
, port
, "vector", case_i
, sharp
);
277 return SCM_NULLP (p
) ? scm_nullvect
: scm_vector (p
);
298 scm_gen_ungetc (c
, port
);
303 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
304 p
= scm_istr2bve (SCM_CHARS (*tok_buf
) + 1, (long) (j
- 1));
311 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 1);
312 p
= scm_intern (SCM_CHARS (*tok_buf
), j
);
313 if (SCM_PORT_REPRESENTATION (port
) != scm_regular_port
)
314 scm_set_symbol_multi_byte_x (SCM_CAR (p
), SCM_BOOL_T
);
318 c
= scm_gen_getc (port
);
319 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
321 return SCM_MAKICHR (c
);
322 if (c
>= '0' && c
< '8')
324 p
= scm_istr2int (SCM_CHARS (*tok_buf
), (long) j
, 8);
326 return SCM_MAKICHR (SCM_INUM (p
));
328 for (c
= 0; c
< scm_n_charnames
; c
++)
330 && (scm_casei_streq (scm_charnames
[c
], SCM_CHARS (*tok_buf
))))
331 return SCM_MAKICHR (scm_charnums
[c
]);
332 scm_wta (SCM_UNDEFINED
, "unknown # object: #\\", SCM_CHARS (*tok_buf
));
337 if (SCM_NIMP (sharp
))
340 got
= scm_apply (sharp
, SCM_MAKICHR (c
), scm_acons (port
, SCM_EOL
, SCM_EOL
));
341 if (SCM_UNSPECIFIED
== got
)
345 unkshrp
:scm_wta ((SCM
) SCM_MAKICHR (c
), "unknown # object", "");
350 while ('"' != (c
= scm_gen_getc (port
)))
352 SCM_ASSERT (EOF
!= c
, SCM_UNDEFINED
, "end of file in ", "string");
354 while (j
+ sizeof(xwchar_t
) + XMB_CUR_MAX
>= SCM_LENGTH (*tok_buf
))
355 scm_grow_tok_buf (tok_buf
);
358 switch (c
= scm_gen_getc (port
))
384 if (SCM_PORT_REPRESENTATION(port
) == scm_regular_port
)
386 SCM_CHARS (*tok_buf
)[j
] = c
;
392 len
= xwctomb (SCM_CHARS (*tok_buf
) + j
, c
);
395 SCM_ASSERT (len
> 0, SCM_MAKINUM (c
), "bogus char", "read");
401 SCM_CHARS (*tok_buf
)[j
] = 0;
404 str
= scm_makfromstr (SCM_CHARS (*tok_buf
), j
, 0);
405 if (SCM_PORT_REPRESENTATION(port
) != scm_regular_port
)
407 SCM_SETLENGTH (str
, SCM_LENGTH (str
), scm_tc7_mb_string
);
412 case'0':case '1':case '2':case '3':case '4':
413 case '5':case '6':case '7':case '8':case '9':
418 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
419 p
= scm_istring2number (SCM_CHARS (*tok_buf
), (long) j
, 10L);
424 if ((j
== 2) && (scm_gen_getc (port
) == '('))
426 scm_gen_ungetc ('(', port
);
427 c
= SCM_CHARS (*tok_buf
)[1];
430 scm_wta (SCM_UNDEFINED
, "unknown # object", SCM_CHARS (*tok_buf
));
435 j
= scm_read_token ('-', tok_buf
, port
, case_i
, 0);
436 p
= scm_intern (SCM_CHARS (*tok_buf
), j
);
437 if (SCM_PORT_REPRESENTATION (port
) != scm_regular_port
)
438 scm_set_symbol_multi_byte_x (SCM_CAR (p
), SCM_BOOL_T
);
439 return scm_make_keyword_from_dash_symbol (SCM_CAR (p
));
442 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
446 p
= scm_intern (SCM_CHARS (*tok_buf
), j
);
447 if (SCM_PORT_REPRESENTATION (port
) != scm_regular_port
)
448 scm_set_symbol_multi_byte_x (SCM_CAR (p
), SCM_BOOL_T
);
454 _Pragma ("noopt"); /* # pragma _CRI noopt */
458 scm_read_token (int ic
, SCM
* tok_buf
, SCM port
, int case_i
, int weird
)
461 scm_read_token (ic
, * tok_buf
, port
, case_i
, weird
)
469 register scm_sizet j
;
474 p
= SCM_CHARS (*tok_buf
);
481 while (j
+ sizeof(xwchar_t
) + XMB_CUR_MAX
>= SCM_LENGTH (*tok_buf
))
482 p
= scm_grow_tok_buf (tok_buf
);
483 if (SCM_PORT_REPRESENTATION(port
) == scm_regular_port
)
491 len
= xwctomb (p
+ j
, c
);
494 SCM_ASSERT (len
> 0, SCM_MAKINUM (c
), "bogus char", "read");
501 while (j
+ sizeof(xwchar_t
) + XMB_CUR_MAX
>= SCM_LENGTH (*tok_buf
))
502 p
= scm_grow_tok_buf (tok_buf
);
503 c
= scm_gen_getc (port
);
510 case SCM_WHITE_SPACES
:
511 case SCM_LINE_INCREMENTORS
:
515 scm_gen_ungetc (c
, port
);
525 c
= scm_gen_getc (port
);
535 c
= scm_gen_getc (port
);
543 scm_gen_ungetc (c
, port
);
551 c
= (case_i
? scm_downcase(c
) : c
);
552 if (SCM_PORT_REPRESENTATION(port
) == scm_regular_port
)
560 len
= xwctomb (p
+ j
, c
);
563 SCM_ASSERT (len
> 0, SCM_MAKINUM (c
), "bogus char", "read");
572 _Pragma ("opt"); /* # pragma _CRI opt */
577 scm_lreadparen (SCM
* tok_buf
, SCM port
, char *name
, int case_i
, SCM sharp
)
580 scm_lreadparen (tok_buf
, port
, name
, case_i
, sharp
)
593 c
= scm_flush_ws (port
, name
);
596 scm_gen_ungetc (c
, port
);
597 if (scm_i_dot
== (tmp
= scm_lreadr (tok_buf
, port
, case_i
, sharp
)))
599 ans
= scm_lreadr (tok_buf
, port
, case_i
, sharp
);
601 if (')' != (c
= scm_flush_ws (port
, name
)))
602 scm_wta (SCM_UNDEFINED
, "missing close paren", "");
605 ans
= tl
= scm_cons (tmp
, SCM_EOL
);
606 while (')' != (c
= scm_flush_ws (port
, name
)))
608 scm_gen_ungetc (c
, port
);
609 if (scm_i_dot
== (tmp
= scm_lreadr (tok_buf
, port
, case_i
, sharp
)))
611 SCM_CDR (tl
) = scm_lreadr (tok_buf
, port
, case_i
, sharp
);
614 tl
= (SCM_CDR (tl
) = scm_cons (tmp
, SCM_EOL
));
631 #ifdef READER_EXTENSIONS
632 scm_init_opts (scm_read_options
, scm_read_opts
, SCM_N_READ_OPTIONS
);