guile-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]