-/* Copyright (C) 1995,1996,1997,1999,2000,2001,2003, 2004 Free Software
+/* Copyright (C) 1995,1996,1997,1999,2000,2001,2003, 2004, 2006, 2007 Free Software
* Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libguile/strports.h"
#include "libguile/vectors.h"
#include "libguile/validate.h"
+#include "libguile/srfi-4.h"
#include "libguile/read.h"
+#include "libguile/private-options.h"
+
\f
{ SCM_OPTION_BOOLEAN, "case-insensitive", 0,
"Convert symbols to lower case."},
{ SCM_OPTION_SCM, "keywords", SCM_UNPACK (SCM_BOOL_F),
- "Style of keyword recognition: #f or 'prefix."}
+ "Style of keyword recognition: #f or 'prefix."},
#if SCM_ENABLE_ELISP
- ,
{ SCM_OPTION_BOOLEAN, "elisp-vectors", 0,
"Support Elisp vector syntax, namely `[...]'."},
{ SCM_OPTION_BOOLEAN, "elisp-strings", 0,
- "Support `\\(' and `\\)' in strings."}
+ "Support `\\(' and `\\)' in strings."},
#endif
+ { 0, },
};
/*
*/
-static void
-scm_input_error (char const *function,
- SCM port, const char *message, SCM arg)
+void
+scm_i_input_error (char const *function,
+ SCM port, const char *message, SCM arg)
{
SCM fn = (scm_is_string (SCM_FILENAME(port))
? SCM_FILENAME(port)
scm_simple_format (string_port,
scm_from_locale_string ("~A:~S:~S: ~A"),
scm_list_4 (fn,
- scm_from_int (SCM_LINUM (port) + 1),
+ scm_from_long (SCM_LINUM (port) + 1),
scm_from_int (SCM_COL (port) + 1),
scm_from_locale_string (message)));
string = scm_get_output_string (string_port);
scm_close_output_port (string_port);
scm_error_scm (scm_from_locale_symbol ("read-error"),
- scm_from_locale_string (function),
+ function? scm_from_locale_string (function) : SCM_BOOL_F,
string,
arg,
SCM_BOOL_F);
{
SCM ans = scm_options (setting,
scm_read_opts,
- SCM_N_READ_OPTIONS,
FUNC_NAME);
if (SCM_COPY_SOURCE_P)
SCM_RECORD_POSITIONS_P = 1;
SCM tok_buf, copy;
if (SCM_UNBNDP (port))
- port = scm_cur_inp;
+ port = scm_current_input_port ();
SCM_VALIDATE_OPINPORT (1, port);
c = scm_flush_ws (port, (char *) NULL);
int c = scm_getc (port);
if (c == EOF)
- scm_input_error ("skip_block_comment", port,
- "unterminated `#! ... !#' comment", SCM_EOL);
+ scm_i_input_error ("skip_block_comment", port,
+ "unterminated `#! ... !#' comment", SCM_EOL);
if (c == '!')
bang_seen = 1;
goteof:
if (eoferr)
{
- scm_input_error (eoferr,
- port,
- "end of file",
- SCM_EOL);
+ scm_i_input_error (eoferr,
+ port,
+ "end of file",
+ SCM_EOL);
}
return c;
case ';':
static SCM
recsexpr (SCM obj, long line, int column, SCM filename)
{
- if (!SCM_CONSP(obj)) {
+ if (!scm_is_pair(obj)) {
return obj;
} else {
SCM tmp = obj, copy;
{
copy = scm_cons (recsexpr (SCM_CAR (obj), line, column, filename),
SCM_UNDEFINED);
- while ((tmp = SCM_CDR (tmp)) && SCM_CONSP (tmp))
+ while ((tmp = SCM_CDR (tmp)) && scm_is_pair (tmp))
{
SCM_SETCDR (copy, scm_cons (recsexpr (SCM_CAR (tmp),
line,
else
{
recsexpr (SCM_CAR (obj), line, column, filename);
- while ((tmp = SCM_CDR (tmp)) && SCM_CONSP (tmp))
+ while ((tmp = SCM_CDR (tmp)) && scm_is_pair (tmp))
recsexpr (SCM_CAR (tmp), line, column, filename);
copy = SCM_UNDEFINED;
}
static SCM scm_i_lreadparen (SCM *, SCM, char *, SCM *, char);
static char s_list[]="list";
+#if SCM_ENABLE_ELISP
static char s_vector[]="vector";
+#endif
SCM
scm_lreadr (SCM *tok_buf, SCM port, SCM *copy)
? scm_lreadrecparen (tok_buf, port, s_list, copy)
: scm_i_lreadparen (tok_buf, port, s_list, copy, ')');
case ')':
- scm_input_error (FUNC_NAME, port,"unexpected \")\"", SCM_EOL);
+ scm_i_input_error (FUNC_NAME, port,"unexpected \")\"", SCM_EOL);
goto tryagain;
#if SCM_ENABLE_ELISP
if (SCM_ELISP_VECTORS_P)
{
p = scm_i_lreadparen (tok_buf, port, s_vector, copy, ']');
- return SCM_NULLP (p) ? scm_nullvect : scm_vector (p);
+ return scm_is_null (p) ? scm_nullvect : scm_vector (p);
}
goto read_token;
#endif
SCM sharp = scm_get_hash_procedure (c);
if (scm_is_true (sharp))
{
- int line = SCM_LINUM (port);
+ long line = SCM_LINUM (port);
int column = SCM_COL (port) - 2;
SCM got;
handle_sharp:
switch (c)
{
+ /* Vector, arrays, both uniform and not are handled by this
+ one function. It also disambiguates between '#f' and
+ '#f32' and '#f64'.
+ */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'u': case 's': case 'f':
+ case '@':
case '(':
- p = scm_i_lreadparen (tok_buf, port, s_vector, copy, ')');
- return SCM_NULLP (p) ? scm_nullvect : scm_vector (p);
+#if SCM_ENABLE_DEPRECATED
+ /* See below for 'i' and 'e'. */
+ case 'a':
+ case 'c':
+ case 'y':
+ case 'h':
+ case 'l':
+#endif
+ return scm_i_read_array (port, c);
case 't':
case 'T':
return SCM_BOOL_T;
- case 'f':
+
case 'F':
+ /* See above for lower case 'f'. */
return SCM_BOOL_F;
+
+ case 'i':
+ case 'e':
+#if SCM_ENABLE_DEPRECATED
+ {
+ /* When next char is '(', it really is an old-style
+ uniform array. */
+ int next_c = scm_getc (port);
+ if (next_c != EOF)
+ scm_ungetc (next_c, port);
+ if (next_c == '(')
+ return scm_i_read_array (port, c);
+ /* Fall through. */
+ }
+#endif
case 'b':
case 'B':
case 'o':
case 'D':
case 'x':
case 'X':
- case 'i':
case 'I':
- case 'e':
case 'E':
scm_ungetc (c, port);
c = '#';
over in scm_flush_ws. */
abort ();
-#if SCM_HAVE_ARRAYS
case '*':
j = scm_read_token (c, tok_buf, port, 0);
- p = scm_istr2bve (scm_c_substring_shared (*tok_buf, 1, j-1));
+ p = scm_istr2bve (scm_c_substring_shared (*tok_buf, 1, j));
if (scm_is_true (p))
return p;
else
goto unkshrp;
-#endif
case '{':
j = scm_read_token (c, tok_buf, port, 1);
* does only consist of octal digits. Finally, it should be
* checked whether the resulting fixnum is in the range of
* characters. */
- p = scm_i_mem2number (scm_i_string_chars (*tok_buf), j, 8);
+ p = scm_c_locale_stringn_to_number (scm_i_string_chars (*tok_buf),
+ j, 8);
if (SCM_I_INUMP (p))
return SCM_MAKE_CHAR (SCM_I_INUM (p));
}
&& (scm_i_casei_streq (scm_charnames[c],
scm_i_string_chars (*tok_buf), j)))
return SCM_MAKE_CHAR (scm_charnums[c]);
- scm_input_error (FUNC_NAME, port, "unknown character name ~a",
- scm_list_1 (scm_c_substring (*tok_buf, 0, j)));
+ scm_i_input_error (FUNC_NAME, port, "unknown character name ~a",
+ scm_list_1 (scm_c_substring (*tok_buf, 0, j)));
/* #:SYMBOL is a syntax for keywords supported in all contexts. */
case ':':
- j = scm_read_token ('-', tok_buf, port, 0);
- p = scm_string_to_symbol (scm_c_substring_copy (*tok_buf, 0, j));
- return scm_make_keyword_from_dash_symbol (p);
+ return scm_symbol_to_keyword (scm_read (port));
default:
callshrp:
if (scm_is_true (sharp))
{
- int line = SCM_LINUM (port);
+ long line = SCM_LINUM (port);
int column = SCM_COL (port) - 2;
SCM got;
}
}
unkshrp:
- scm_input_error (FUNC_NAME, port, "Unknown # object: ~S",
- scm_list_1 (SCM_MAKE_CHAR (c)));
+ scm_i_input_error (FUNC_NAME, port, "Unknown # object: ~S",
+ scm_list_1 (SCM_MAKE_CHAR (c)));
}
case '"':
while ('"' != (c = scm_getc (port)))
{
if (c == EOF)
- str_eof: scm_input_error (FUNC_NAME, port, "end of file in string constant", SCM_EOL);
+ str_eof: scm_i_input_error (FUNC_NAME, port,
+ "end of file in string constant",
+ SCM_EOL);
while (j + 2 >= scm_i_string_length (*tok_buf))
scm_grow_tok_buf (tok_buf);
}
default:
bad_escaped:
- scm_input_error(FUNC_NAME, port,
- "illegal character in escape sequence: ~S",
- scm_list_1 (SCM_MAKE_CHAR (c)));
+ scm_i_input_error(FUNC_NAME, port,
+ "illegal character in escape sequence: ~S",
+ scm_list_1 (SCM_MAKE_CHAR (c)));
}
scm_c_string_set_x (*tok_buf, j, SCM_MAKE_CHAR (c));
++j;
}
if (j == 0)
return scm_nullstr;
+
+ /* Change this to scm_c_substring_read_only when
+ SCM_STRING_CHARS has been removed.
+ */
return scm_c_substring_copy (*tok_buf, 0, j);
case '0': case '1': case '2': case '3': case '4':
/* Shortcut: Detected symbol '+ or '- */
goto tok;
- p = scm_i_mem2number (scm_i_string_chars (*tok_buf), j, 10);
+ p = scm_c_locale_stringn_to_number (scm_i_string_chars (*tok_buf), j, 10);
if (scm_is_true (p))
return p;
if (c == '#')
c = scm_i_string_chars (*tok_buf)[1];
goto callshrp;
}
- scm_input_error (FUNC_NAME, port, "unknown # object", SCM_EOL);
+ scm_i_input_error (FUNC_NAME, port, "unknown # object", SCM_EOL);
}
goto tok;
case ':':
if (scm_is_eq (SCM_PACK (SCM_KEYWORD_STYLE), scm_keyword_prefix))
- {
- j = scm_read_token ('-', tok_buf, port, 0);
- p = scm_string_to_symbol (scm_c_substring (*tok_buf, 0, j));
- return scm_make_keyword_from_dash_symbol (p);
- }
+ return scm_symbol_to_keyword (scm_read (port));
+
/* fallthrough */
default:
#if SCM_ENABLE_ELISP
ans = scm_lreadr (tok_buf, port, copy);
closeit:
if (term_char != (c = scm_flush_ws (port, name)))
- scm_input_error (FUNC_NAME, port, "missing close paren", SCM_EOL);
+ scm_i_input_error (FUNC_NAME, port, "missing close paren", SCM_EOL);
return ans;
}
ans = tl = scm_cons (tmp, SCM_EOL);
register SCM tl, tl2 = SCM_EOL;
SCM ans, ans2 = SCM_EOL;
/* Need to capture line and column numbers here. */
- int line = SCM_LINUM (port);
+ long line = SCM_LINUM (port);
int column = SCM_COL (port) - 1;
c = scm_flush_ws (port, name);
{
ans = scm_lreadr (tok_buf, port, copy);
if (')' != (c = scm_flush_ws (port, name)))
- scm_input_error (FUNC_NAME, port, "missing close paren", SCM_EOL);
+ scm_i_input_error (FUNC_NAME, port, "missing close paren", SCM_EOL);
return ans;
}
/* Build the head of the list structure. */
ans = tl = scm_cons (tmp, SCM_EOL);
if (SCM_COPY_SOURCE_P)
- ans2 = tl2 = scm_cons (SCM_CONSP (tmp)
+ ans2 = tl2 = scm_cons (scm_is_pair (tmp)
? *copy
: tmp,
SCM_EOL);
{
SCM_SETCDR (tl, tmp = scm_lreadr (tok_buf, port, copy));
if (SCM_COPY_SOURCE_P)
- SCM_SETCDR (tl2, scm_cons (SCM_CONSP (tmp)
+ SCM_SETCDR (tl2, scm_cons (scm_is_pair (tmp)
? *copy
: tmp,
SCM_EOL));
if (')' != (c = scm_flush_ws (port, name)))
- scm_input_error (FUNC_NAME, port, "missing close paren", SCM_EOL);
+ scm_i_input_error (FUNC_NAME, port,
+ "missing close paren", SCM_EOL);
goto exit;
}
if (SCM_COPY_SOURCE_P)
{
- SCM new_tail2 = scm_cons (SCM_CONSP (tmp) ? *copy : tmp, SCM_EOL);
+ SCM new_tail2 = scm_cons (scm_is_pair (tmp) ? *copy : tmp, SCM_EOL);
SCM_SETCDR (tl2, new_tail2);
tl2 = new_tail2;
}
"starting with the character sequence @code{#} and @var{chr}.\n"
"@var{proc} will be called with two arguments: the character\n"
"@var{chr} and the port to read further data from. The object\n"
- "returned will be the return value of @code{read}.")
+ "returned will be the return value of @code{read}. \n"
+ "Passing @code{#f} for @var{proc} will remove a previous setting. \n"
+ )
#define FUNC_NAME s_scm_read_hash_extend
{
SCM this;
prev = SCM_BOOL_F;
while (1)
{
- if (SCM_NULLP (this))
+ if (scm_is_null (this))
{
/* not found, so add it to the beginning. */
if (scm_is_true (proc))
while (1)
{
- if (SCM_NULLP (rest))
+ if (scm_is_null (rest))
return SCM_BOOL_F;
if (SCM_CHAR (SCM_CAAR (rest)) == c)
scm_read_hash_procedures =
SCM_VARIABLE_LOC (scm_c_define ("read-hash-procedures", SCM_EOL));
- scm_init_opts (scm_read_options, scm_read_opts, SCM_N_READ_OPTIONS);
+ scm_init_opts (scm_read_options, scm_read_opts);
#include "libguile/read.x"
}