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 #define default_case_i 0
54 SCM_PROC (s_read
, "read", 0, 3, 0, scm_read
);
57 scm_read (SCM port
, SCM case_insensative_p
, SCM sharp
)
60 scm_read (port
, case_insensative_p
, sharp
)
62 SCM case_insensative_p
;
70 if (SCM_UNBNDP (port
))
73 SCM_ASSERT (SCM_NIMP (port
) && SCM_OPINPORTP (port
), port
, SCM_ARG1
, s_read
);
75 case_i
= (SCM_UNBNDP (case_insensative_p
)
77 : (case_insensative_p
== SCM_BOOL_F
));
79 if (SCM_UNBNDP (sharp
))
82 c
= scm_flush_ws (port
, (char *) NULL
);
85 scm_gen_ungetc (c
, port
);
87 tok_buf
= scm_makstr (30L, 0);
88 return scm_lreadr (&tok_buf
, port
, case_i
, sharp
);
94 scm_grow_tok_buf (SCM
* tok_buf
)
97 scm_grow_tok_buf (tok_buf
)
104 len
= SCM_LENGTH (*tok_buf
);
105 len
+= (len
/ 2 ? len
/ 2 : 1);
106 t2
= scm_makstr (len
, 0);
111 for (a
= SCM_CHARS (*tok_buf
), b
= SCM_CHARS (t2
), l
= SCM_LENGTH (*tok_buf
);
117 return SCM_CHARS (*tok_buf
);
123 scm_flush_ws (SCM port
, char *eoferr
)
126 scm_flush_ws (port
, eoferr
)
133 switch (c
= scm_gen_getc (port
))
138 scm_wta (SCM_UNDEFINED
, "end of file in ", eoferr
);
142 switch (c
= scm_gen_getc (port
))
148 case SCM_LINE_INCREMENTORS
:
152 case SCM_LINE_INCREMENTORS
:
154 case SCM_SINGLE_SPACES
:
168 scm_casei_streq (char * s1
, char * s2
)
171 scm_casei_streq (s1
, s2
)
177 if (scm_downcase((int)*s1
) != scm_downcase((int)*s2
))
184 return !(*s1
|| *s2
);
190 scm_lreadr (SCM
* tok_buf
, SCM port
, int case_i
, SCM sharp
)
193 scm_lreadr (tok_buf
, port
, case_i
, sharp
)
205 c
= scm_flush_ws (port
, s_read
);
212 return scm_lreadparen (tok_buf
, port
, "list", case_i
, sharp
);
215 scm_wta (SCM_UNDEFINED
, "unexpected \")\"", "read");
219 return scm_cons2 (scm_i_quote
, scm_lreadr (tok_buf
, port
, case_i
, sharp
), SCM_EOL
);
222 return scm_cons2 (scm_i_quasiquote
, scm_lreadr (tok_buf
, port
, case_i
, sharp
), SCM_EOL
);
225 c
= scm_gen_getc (port
);
227 p
= scm_i_uq_splicing
;
230 scm_gen_ungetc (c
, port
);
233 return scm_cons2 (p
, scm_lreadr (tok_buf
, port
, case_i
, sharp
), SCM_EOL
);
236 c
= scm_gen_getc (port
);
240 p
= scm_lreadparen (tok_buf
, port
, "vector", case_i
, sharp
);
241 return SCM_NULLP (p
) ? scm_nullvect
: scm_vector (p
);
262 scm_gen_ungetc (c
, port
);
267 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
268 p
= scm_istr2bve (SCM_CHARS (*tok_buf
) + 1, (long) (j
- 1));
275 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 1);
276 p
= scm_intern (SCM_CHARS (*tok_buf
), j
);
277 if (SCM_PORT_REPRESENTATION (port
) != scm_regular_port
)
278 scm_set_symbol_multi_byte_x (SCM_CAR (p
), SCM_BOOL_T
);
282 c
= scm_gen_getc (port
);
283 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
285 return SCM_MAKICHR (c
);
286 if (c
>= '0' && c
< '8')
288 p
= scm_istr2int (SCM_CHARS (*tok_buf
), (long) j
, 8);
290 return SCM_MAKICHR (SCM_INUM (p
));
292 for (c
= 0; c
< scm_n_charnames
; c
++)
294 && (scm_casei_streq (scm_charnames
[c
], SCM_CHARS (*tok_buf
))))
295 return SCM_MAKICHR (scm_charnums
[c
]);
296 scm_wta (SCM_UNDEFINED
, "unknown # object: #\\", SCM_CHARS (*tok_buf
));
301 if (SCM_NIMP (sharp
))
304 got
= scm_apply (sharp
, SCM_MAKICHR (c
), scm_acons (port
, SCM_EOL
, SCM_EOL
));
305 if (SCM_UNSPECIFIED
== got
)
309 unkshrp
:scm_wta ((SCM
) SCM_MAKICHR (c
), "unknown # object", "");
314 while ('"' != (c
= scm_gen_getc (port
)))
316 SCM_ASSERT (EOF
!= c
, SCM_UNDEFINED
, "end of file in ", "string");
318 while (j
+ sizeof(xwchar_t
) + XMB_CUR_MAX
>= SCM_LENGTH (*tok_buf
))
319 scm_grow_tok_buf (tok_buf
);
322 switch (c
= scm_gen_getc (port
))
348 if (SCM_PORT_REPRESENTATION(port
) == scm_regular_port
)
350 SCM_CHARS (*tok_buf
)[j
] = c
;
356 len
= xwctomb (SCM_CHARS (*tok_buf
) + j
, c
);
359 SCM_ASSERT (len
> 0, SCM_MAKINUM (c
), "bogus char", "read");
365 SCM_CHARS (*tok_buf
)[j
] = 0;
368 str
= scm_makfromstr (SCM_CHARS (*tok_buf
), j
, 0);
369 if (SCM_PORT_REPRESENTATION(port
) != scm_regular_port
)
371 SCM_SETLENGTH (str
, SCM_LENGTH (str
), scm_tc7_mb_string
);
376 case'0':case '1':case '2':case '3':case '4':
377 case '5':case '6':case '7':case '8':case '9':
382 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
383 p
= scm_istring2number (SCM_CHARS (*tok_buf
), (long) j
, 10L);
388 if ((j
== 2) && (scm_gen_getc (port
) == '('))
390 scm_gen_ungetc ('(', port
);
391 c
= SCM_CHARS (*tok_buf
)[1];
394 scm_wta (SCM_UNDEFINED
, "unknown # object", SCM_CHARS (*tok_buf
));
399 j
= scm_read_token ('-', tok_buf
, port
, case_i
, 0);
400 p
= scm_intern (SCM_CHARS (*tok_buf
), j
);
401 if (SCM_PORT_REPRESENTATION (port
) != scm_regular_port
)
402 scm_set_symbol_multi_byte_x (SCM_CAR (p
), SCM_BOOL_T
);
403 return scm_make_keyword_from_dash_symbol (SCM_CAR (p
));
406 j
= scm_read_token (c
, tok_buf
, port
, case_i
, 0);
410 p
= scm_intern (SCM_CHARS (*tok_buf
), j
);
411 if (SCM_PORT_REPRESENTATION (port
) != scm_regular_port
)
412 scm_set_symbol_multi_byte_x (SCM_CAR (p
), SCM_BOOL_T
);
418 _Pragma ("noopt"); /* # pragma _CRI noopt */
422 scm_read_token (int ic
, SCM
* tok_buf
, SCM port
, int case_i
, int weird
)
425 scm_read_token (ic
, * tok_buf
, port
, case_i
, weird
)
433 register scm_sizet j
;
438 p
= SCM_CHARS (*tok_buf
);
445 while (j
+ sizeof(xwchar_t
) + XMB_CUR_MAX
>= SCM_LENGTH (*tok_buf
))
446 p
= scm_grow_tok_buf (tok_buf
);
447 if (SCM_PORT_REPRESENTATION(port
) == scm_regular_port
)
455 len
= xwctomb (p
+ j
, c
);
458 SCM_ASSERT (len
> 0, SCM_MAKINUM (c
), "bogus char", "read");
465 while (j
+ sizeof(xwchar_t
) + XMB_CUR_MAX
>= SCM_LENGTH (*tok_buf
))
466 p
= scm_grow_tok_buf (tok_buf
);
467 c
= scm_gen_getc (port
);
474 case SCM_WHITE_SPACES
:
475 case SCM_LINE_INCREMENTORS
:
479 scm_gen_ungetc (c
, port
);
489 c
= scm_gen_getc (port
);
499 c
= scm_gen_getc (port
);
507 scm_gen_ungetc (c
, port
);
515 c
= (case_i
? scm_downcase(c
) : c
);
516 if (SCM_PORT_REPRESENTATION(port
) == scm_regular_port
)
524 len
= xwctomb (p
+ j
, c
);
527 SCM_ASSERT (len
> 0, SCM_MAKINUM (c
), "bogus char", "read");
536 _Pragma ("opt"); /* # pragma _CRI opt */
541 scm_lreadparen (SCM
* tok_buf
, SCM port
, char *name
, int case_i
, SCM sharp
)
544 scm_lreadparen (tok_buf
, port
, name
, case_i
, sharp
)
557 c
= scm_flush_ws (port
, name
);
560 scm_gen_ungetc (c
, port
);
561 if (scm_i_dot
== (tmp
= scm_lreadr (tok_buf
, port
, case_i
, sharp
)))
563 ans
= scm_lreadr (tok_buf
, port
, case_i
, sharp
);
565 if (')' != (c
= scm_flush_ws (port
, name
)))
566 scm_wta (SCM_UNDEFINED
, "missing close paren", "");
569 ans
= tl
= scm_cons (tmp
, SCM_EOL
);
570 while (')' != (c
= scm_flush_ws (port
, name
)))
572 scm_gen_ungetc (c
, port
);
573 if (scm_i_dot
== (tmp
= scm_lreadr (tok_buf
, port
, case_i
, sharp
)))
575 SCM_CDR (tl
) = scm_lreadr (tok_buf
, port
, case_i
, sharp
);
578 tl
= (SCM_CDR (tl
) = scm_cons (tmp
, SCM_EOL
));