[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/3] Add internal API to specify reader options at reader invocat
From: |
Andreas Rottmann |
Subject: |
[PATCH 2/3] Add internal API to specify reader options at reader invocation |
Date: |
Sun, 9 Dec 2012 13:47:26 +0100 |
* libguile/private-options.h: Introduce a new enum indexing the read
options, and use its values as indices for scm_read_opts.
* libguile/read.c: Get rid of the bit field offsets #define-s, and
instead use the enum values to caculate them.
* libguile/read.c (enum t_keyword_style, scm_t_read_opts): Moved to
libguile/private-options.h, the names of the keyword style enum having
been prefixed with "SCM_" (use sites adapted accordingly). These have
been moved out of the C file so that they can be used in other parts
of libguile -- they are needed by the scm_i_read()'s interface.
* libguile/read.h (scm_i_read): New procedure, marked SCM_INTERNAL.
(scm_t_read_opts): Opaque typedef for the struct defined in
private-options.h.
* libguile/read.c (init_read_options): Add an additional argument
`preset', to allow the caller to specify reader options that are
preset and should not be changed.
(scm_i_read): New internal procedure, allowing to fix (part of) the
reader options.
---
libguile/private-options.h | 51 ++++++++++++++++----
libguile/read.c | 115 +++++++++++++++++++-------------------------
libguile/read.h | 6 ++-
3 files changed, 95 insertions(+), 77 deletions(-)
diff --git a/libguile/private-options.h b/libguile/private-options.h
index ed0f314..0c85d0c 100644
--- a/libguile/private-options.h
+++ b/libguile/private-options.h
@@ -4,7 +4,7 @@
* We put this in a private header, since layout of data structures
* is an implementation detail that we want to hide.
*
- * Copyright (C) 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -60,15 +60,46 @@ SCM_INTERNAL scm_t_option scm_print_opts[];
*/
SCM_INTERNAL scm_t_option scm_read_opts[];
-#define SCM_COPY_SOURCE_P scm_read_opts[0].val
-#define SCM_RECORD_POSITIONS_P scm_read_opts[1].val
-#define SCM_CASE_INSENSITIVE_P scm_read_opts[2].val
-#define SCM_KEYWORD_STYLE scm_read_opts[3].val
-#define SCM_R6RS_ESCAPES_P scm_read_opts[4].val
-#define SCM_SQUARE_BRACKETS_P scm_read_opts[5].val
-#define SCM_HUNGRY_EOL_ESCAPES_P scm_read_opts[6].val
-#define SCM_CURLY_INFIX_P scm_read_opts[7].val
+enum
+ {
+ SCM_READ_OPTION_COPY_SOURCE_P,
+ SCM_READ_OPTION_RECORD_POSITIONS_P,
+ SCM_READ_OPTION_CASE_INSENSITIVE_P,
+ SCM_READ_OPTION_KEYWORD_STYLE,
+ SCM_READ_OPTION_R6RS_ESCAPES_P,
+ SCM_READ_OPTION_SQUARE_BRACKETS_P,
+ SCM_READ_OPTION_HUNGRY_EOL_ESCAPES_P,
+ SCM_READ_OPTION_CURLY_INFIX_P,
+ SCM_N_READ_OPTIONS
+ };
-#define SCM_N_READ_OPTIONS 7
+typedef enum
+ {
+ SCM_KEYWORD_STYLE_HASH_PREFIX,
+ SCM_KEYWORD_STYLE_PREFIX,
+ SCM_KEYWORD_STYLE_POSTFIX
+ } scm_t_keyword_style;
+
+struct scm_struct_read_opts
+{
+ scm_t_keyword_style keyword_style;
+ unsigned int copy_source_p : 1;
+ unsigned int record_positions_p : 1;
+ unsigned int case_insensitive_p : 1;
+ unsigned int r6rs_escapes_p : 1;
+ unsigned int square_brackets_p : 1;
+ unsigned int hungry_eol_escapes_p : 1;
+ unsigned int curly_infix_p : 1;
+ unsigned int neoteric_p : 1;
+};
+
+#define SCM_COPY_SOURCE_P scm_read_opts[SCM_READ_OPTION_COPY_SOURCE_P].val
+#define SCM_RECORD_POSITIONS_P
scm_read_opts[SCM_READ_OPTION_RECORD_POSITIONS_P].val
+#define SCM_CASE_INSENSITIVE_P
scm_read_opts[SCM_READ_OPTION_CASE_INSENSITIVE_P].val
+#define SCM_KEYWORD_STYLE scm_read_opts[SCM_READ_OPTION_KEYWORD_STYLE].val
+#define SCM_R6RS_ESCAPES_P
scm_read_opts[SCM_READ_OPTION_R6RS_ESCAPES_P].val
+#define SCM_SQUARE_BRACKETS_P
scm_read_opts[SCM_READ_OPTION_SQUARE_BRACKETS_P].val
+#define SCM_HUNGRY_EOL_ESCAPES_P
scm_read_opts[SCM_READ_OPTION_HUNGRY_EOL_ESCAPES_P].val
+#define SCM_CURLY_INFIX_P scm_read_opts[SCM_READ_OPTION_CURLY_INFIX_P].val
#endif /* PRIVATE_OPTIONS */
diff --git a/libguile/read.c b/libguile/read.c
index 222891b..754ea99 100644
--- a/libguile/read.c
+++ b/libguile/read.c
@@ -93,29 +93,6 @@ scm_t_option scm_read_opts[] =
from the global and per-port read options, and a pointer is passed
down to all helper functions. */
-enum t_keyword_style
- {
- KEYWORD_STYLE_HASH_PREFIX,
- KEYWORD_STYLE_PREFIX,
- KEYWORD_STYLE_POSTFIX
- };
-
-struct t_read_opts
-{
- enum t_keyword_style keyword_style;
- unsigned int copy_source_p : 1;
- unsigned int record_positions_p : 1;
- unsigned int case_insensitive_p : 1;
- unsigned int r6rs_escapes_p : 1;
- unsigned int square_brackets_p : 1;
- unsigned int hungry_eol_escapes_p : 1;
- unsigned int curly_infix_p : 1;
- unsigned int neoteric_p : 1;
-};
-
-typedef struct t_read_opts scm_t_read_opts;
-
-
/*
Give meaningful error messages for errors
@@ -737,7 +714,7 @@ scm_read_mixed_case_symbol (scm_t_wchar chr, SCM port,
scm_t_read_opts *opts)
SCM result;
int ends_with_colon = 0;
size_t bytes_read;
- int postfix = (opts->keyword_style == KEYWORD_STYLE_POSTFIX);
+ int postfix = (opts->keyword_style == SCM_KEYWORD_STYLE_POSTFIX);
char local_buffer[READER_BUFFER_SIZE], *buffer;
scm_t_port *pt = SCM_PTAB_ENTRY (port);
SCM str;
@@ -1771,7 +1748,7 @@ read_inner_expression (SCM port, scm_t_read_opts *opts)
case EOF:
return SCM_EOF_VAL;
case ':':
- if (opts->keyword_style == KEYWORD_STYLE_PREFIX)
+ if (opts->keyword_style == SCM_KEYWORD_STYLE_PREFIX)
return scm_symbol_to_keyword (scm_read_expression (port, opts));
/* Fall through. */
@@ -1859,7 +1836,7 @@ scm_read_expression (SCM port, scm_t_read_opts *opts)
/* Actual reader. */
-static void init_read_options (SCM port, scm_t_read_opts *opts);
+static void init_read_options (SCM port, scm_t_read_opts *opts, unsigned int
mask);
SCM_DEFINE (scm_read, "read", 0, 1, 0,
(SCM port),
@@ -1875,7 +1852,7 @@ SCM_DEFINE (scm_read, "read", 0, 1, 0,
port = scm_current_input_port ();
SCM_VALIDATE_OPINPORT (1, port);
- init_read_options (port, &opts);
+ init_read_options (port, &opts, 0);
c = flush_ws (port, &opts, (char *) NULL);
if (EOF == c)
@@ -1887,6 +1864,21 @@ SCM_DEFINE (scm_read, "read", 0, 1, 0,
#undef FUNC_NAME
+SCM scm_i_read (SCM port, const scm_t_read_opts *opts, unsigned int preset)
+{
+ int c;
+ scm_t_read_opts local_opts = *opts;
+
+ init_read_options (port, &local_opts, preset);
+
+ c = flush_ws (port, &local_opts, (char *) NULL);
+ if (EOF == c)
+ return SCM_EOF_VAL;
+ scm_ungetc (c, port);
+
+ return (scm_read_expression (port, &local_opts));
+}
+
/* Manipulate the read-hash-procedures alist. This could be written in
@@ -2158,18 +2150,8 @@ SCM_DEFINE (scm_file_encoding, "file-encoding", 1, 0, 0,
/* Key to read options in per-port alists. */
SCM_SYMBOL (sym_port_read_options, "port-read-options");
-/* Offsets of bit fields for each per-port override */
-#define READ_OPTION_COPY_SOURCE_P 0
-#define READ_OPTION_RECORD_POSITIONS_P 2
-#define READ_OPTION_CASE_INSENSITIVE_P 4
-#define READ_OPTION_KEYWORD_STYLE 6
-#define READ_OPTION_R6RS_ESCAPES_P 8
-#define READ_OPTION_SQUARE_BRACKETS_P 10
-#define READ_OPTION_HUNGRY_EOL_ESCAPES_P 12
-#define READ_OPTION_CURLY_INFIX_P 14
-
/* The total width in bits of the per-port overrides */
-#define READ_OPTIONS_NUM_BITS 16
+#define READ_OPTIONS_NUM_BITS (SCM_N_READ_OPTIONS * 2)
#define READ_OPTIONS_INHERIT_ALL ((1UL << READ_OPTIONS_NUM_BITS) - 1)
#define READ_OPTIONS_MAX_VALUE READ_OPTIONS_INHERIT_ALL
@@ -2191,8 +2173,8 @@ set_port_read_option (SCM port, int option, int new_value)
read_options = scm_to_uint (scm_read_options);
else
read_options = READ_OPTIONS_INHERIT_ALL;
- read_options &= ~(READ_OPTION_MASK << option);
- read_options |= new_value << option;
+ read_options &= ~(READ_OPTION_MASK << (option * 2));
+ read_options |= new_value << (option * 2);
scm_read_options = scm_from_uint (read_options);
alist = scm_assq_set_x (alist, sym_port_read_options, scm_read_options);
scm_hashq_set_x (scm_i_port_weak_hash, port, alist);
@@ -2205,7 +2187,7 @@ set_port_case_insensitive_p (SCM port, scm_t_read_opts
*opts, int value)
{
value = !!value;
opts->case_insensitive_p = value;
- set_port_read_option (port, READ_OPTION_CASE_INSENSITIVE_P, value);
+ set_port_read_option (port, SCM_READ_OPTION_CASE_INSENSITIVE_P, value);
}
/* Set OPTS and PORT's square_brackets_p option according to VALUE. */
@@ -2214,7 +2196,7 @@ set_port_square_brackets_p (SCM port, scm_t_read_opts
*opts, int value)
{
value = !!value;
opts->square_brackets_p = value;
- set_port_read_option (port, READ_OPTION_SQUARE_BRACKETS_P, value);
+ set_port_read_option (port, SCM_READ_OPTION_SQUARE_BRACKETS_P, value);
}
/* Set OPTS and PORT's curly_infix_p option according to VALUE. */
@@ -2223,13 +2205,13 @@ set_port_curly_infix_p (SCM port, scm_t_read_opts
*opts, int value)
{
value = !!value;
opts->curly_infix_p = value;
- set_port_read_option (port, READ_OPTION_CURLY_INFIX_P, value);
+ set_port_read_option (port, SCM_READ_OPTION_CURLY_INFIX_P, value);
}
/* Initialize OPTS based on PORT's read options and the global read
options. */
static void
-init_read_options (SCM port, scm_t_read_opts *opts)
+init_read_options (SCM port, scm_t_read_opts *opts, unsigned int preset)
{
SCM alist, val, scm_read_options;
unsigned int read_options, x;
@@ -2244,28 +2226,29 @@ init_read_options (SCM port, scm_t_read_opts *opts)
else
read_options = READ_OPTIONS_INHERIT_ALL;
- x = READ_OPTION_MASK & (read_options >> READ_OPTION_KEYWORD_STYLE);
- if (x == READ_OPTION_INHERIT)
- {
- val = SCM_PACK (SCM_KEYWORD_STYLE);
- if (scm_is_eq (val, scm_keyword_prefix))
- x = KEYWORD_STYLE_PREFIX;
- else if (scm_is_eq (val, scm_keyword_postfix))
- x = KEYWORD_STYLE_POSTFIX;
- else
- x = KEYWORD_STYLE_HASH_PREFIX;
- }
- opts->keyword_style = x;
-
-#define RESOLVE_BOOLEAN_OPTION(NAME, name) \
- do \
- { \
- x = READ_OPTION_MASK & (read_options >> READ_OPTION_ ## NAME); \
- if (x == READ_OPTION_INHERIT) \
- x = !!SCM_ ## NAME; \
- opts->name = x; \
- } \
- while (0)
+ if ((preset & (1 << SCM_READ_OPTION_KEYWORD_STYLE)) == 0) {
+ x = READ_OPTION_MASK & (read_options >> (SCM_READ_OPTION_KEYWORD_STYLE *
2));
+ if (x == READ_OPTION_INHERIT)
+ {
+ val = SCM_PACK (SCM_KEYWORD_STYLE);
+ if (scm_is_eq (val, scm_keyword_prefix))
+ x = SCM_KEYWORD_STYLE_PREFIX;
+ else if (scm_is_eq (val, scm_keyword_postfix))
+ x = SCM_KEYWORD_STYLE_POSTFIX;
+ else
+ x = SCM_KEYWORD_STYLE_HASH_PREFIX;
+ }
+ opts->keyword_style = x;
+ }
+
+#define RESOLVE_BOOLEAN_OPTION(NAME, name) \
+ if ((preset & (1 << SCM_READ_OPTION_ ## NAME)) == 0) { \
+ x = (READ_OPTION_MASK \
+ & (read_options >> (SCM_READ_OPTION_ ## NAME * 2))); \
+ if (x == READ_OPTION_INHERIT) \
+ x = !!SCM_ ## NAME; \
+ opts->name = x; \
+ }
RESOLVE_BOOLEAN_OPTION (COPY_SOURCE_P, copy_source_p);
RESOLVE_BOOLEAN_OPTION (RECORD_POSITIONS_P, record_positions_p);
diff --git a/libguile/read.h b/libguile/read.h
index 3c47afd..c460d2f 100644
--- a/libguile/read.h
+++ b/libguile/read.h
@@ -3,7 +3,7 @@
#ifndef SCM_READ_H
#define SCM_READ_H
-/* Copyright (C) 1995,1996,2000, 2006, 2008, 2009 Free Software Foundation,
Inc.
+/* Copyright (C) 1995,1996,2000, 2006, 2008, 2009, 2012 Free Software
Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -49,12 +49,16 @@
+typedef struct scm_struct_read_opts scm_t_read_opts;
SCM_API SCM scm_sym_dot;
SCM_API SCM scm_read_options (SCM setting);
SCM_API SCM scm_read (SCM port);
SCM_API SCM scm_read_hash_extend (SCM chr, SCM proc);
+SCM_INTERNAL SCM scm_i_read(SCM port,
+ const scm_t_read_opts *opts,
+ unsigned int preset);
SCM_INTERNAL char *scm_i_scan_for_encoding (SCM port);
SCM_API SCM scm_file_encoding (SCM port);
--
1.7.10.4