Remove unused macros in goops.c
[bpt/guile.git] / libguile / ports.h
index 2b72a70..f2ab850 100644 (file)
@@ -4,7 +4,7 @@
 #define SCM_PORTS_H
 
 /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004,
- *   2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ *   2006, 2008, 2009, 2010, 2011, 2012, 2013, 2014 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
@@ -48,18 +48,19 @@ typedef enum scm_t_port_rw_active {
   SCM_PORT_WRITE = 2
 } scm_t_port_rw_active;
 
+/* An internal-only structure defined in ports-internal.h. */
+struct scm_port_internal;
+
 /* C representation of a Scheme port.  */
 
 typedef struct 
 {
   SCM port;                    /* Link back to the port object.  */
-#if SCM_USE_PTHREAD_THREADS
-  scm_i_pthread_mutex_t lock;   /* A recursive lock for this port.  */
-#endif
+  scm_i_pthread_mutex_t *lock;  /* A recursive lock for this port.  */
+
+  /* pointer to internal-only port structure */
+  struct scm_port_internal *internal;
 
-  int revealed;                        /* 0 not revealed, > 1 revealed.
-                                * Revealed ports do not get GC'd.
-                                */
   /* data for the underlying port implementation as a raw C value. */
   scm_t_bits stream;
 
@@ -67,10 +68,6 @@ typedef struct
   long line_number;            /* debugging support.  */
   int column_number;           /* debugging support.  */
 
-  /* Character encoding support  */
-  char *encoding;
-  scm_t_string_failed_conversion_handler ilseq_handler;
-
   /* port buffers.  the buffer(s) are set up for all ports.  
      in the case of string ports, the buffer is the string itself.
      in the case of unbuffered file ports, the buffer is a
@@ -121,9 +118,9 @@ typedef struct
   unsigned char *putback_buf;
   size_t putback_buf_size;        /* allocated size of putback_buf.  */
 
-  /* input/output iconv conversion descriptors */
-  void *input_cd;
-  void *output_cd;
+  /* Character encoding support  */
+  char *encoding;
+  scm_t_string_failed_conversion_handler ilseq_handler;
 } scm_t_port;
 
 
@@ -167,8 +164,6 @@ SCM_INTERNAL SCM scm_i_port_weak_set;
 #define SCM_SET_FILENAME(x, n)    (SCM_PTAB_ENTRY(x)->file_name = (n))
 #define SCM_LINUM(x)              (SCM_PTAB_ENTRY(x)->line_number)
 #define SCM_COL(x)                (SCM_PTAB_ENTRY(x)->column_number)
-#define SCM_REVEALED(x)           (SCM_PTAB_ENTRY(x)->revealed)
-#define SCM_SETREVEALED(x, s)      (SCM_PTAB_ENTRY(x)->revealed = (s))
 
 #define SCM_INCLINE(port)      do {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} while (0)
 #define SCM_ZEROCOL(port)      do {SCM_COL (port) = 0;} while (0)
@@ -181,6 +176,10 @@ SCM_INTERNAL SCM scm_i_port_weak_set;
 
 \f
 
+typedef enum scm_t_port_type_flags {
+  SCM_PORT_TYPE_HAS_FLUSH = 1 << 0
+} scm_t_port_type_flags;
+
 /* port-type description.  */
 typedef struct scm_t_ptob_descriptor
 {
@@ -201,6 +200,14 @@ typedef struct scm_t_ptob_descriptor
   scm_t_off (*seek) (SCM port, scm_t_off OFFSET, int WHENCE);
   void (*truncate) (SCM port, scm_t_off length);
 
+  /* When non-NULL, this is the method called by 'setvbuf' for this port.
+     It must create read and write buffers for PORT with the specified
+     sizes (a size of 0 is for unbuffered ports, which should use the
+     'shortbuf' field.)  Size -1 means to use the port's preferred buffer
+     size.  */
+  void (*setvbuf) (SCM port, long read_size, long write_size);
+
+  unsigned flags;
 } scm_t_ptob_descriptor;
 
 #define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8))
@@ -238,15 +245,19 @@ SCM_API void scm_set_port_truncate (scm_t_bits tc,
                                    void (*truncate) (SCM port,
                                                      scm_t_off length));
 SCM_API void scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) (SCM));
+SCM_API void scm_set_port_setvbuf (scm_t_bits tc,
+                                   void (*setvbuf) (SCM, long, long));
 
 /* The input, output, error, and load ports.  */
 SCM_API SCM scm_current_input_port (void);
 SCM_API SCM scm_current_output_port (void);
 SCM_API SCM scm_current_error_port (void);
+SCM_API SCM scm_current_warning_port (void);
 SCM_API SCM scm_current_load_port (void);
 SCM_API SCM scm_set_current_input_port (SCM port);
 SCM_API SCM scm_set_current_output_port (SCM port);
 SCM_API SCM scm_set_current_error_port (SCM port);
+SCM_API SCM scm_set_current_warning_port (SCM port);
 SCM_API void scm_dynwind_current_input_port (SCM port);
 SCM_API void scm_dynwind_current_output_port (SCM port);
 SCM_API void scm_dynwind_current_error_port (SCM port);
@@ -284,54 +295,68 @@ SCM_API SCM scm_close_output_port (SCM port);
    characters.  */
 SCM_INTERNAL const char *scm_i_default_port_encoding (void);
 SCM_INTERNAL void scm_i_set_default_port_encoding (const char *);
+SCM_INTERNAL scm_t_string_failed_conversion_handler
+scm_i_default_port_conversion_handler (void);
+SCM_INTERNAL void
+scm_i_set_default_port_conversion_handler (scm_t_string_failed_conversion_handler);
 SCM_INTERNAL void scm_i_set_port_encoding_x (SCM port, const char *str);
 SCM_API SCM scm_port_encoding (SCM port);
 SCM_API SCM scm_set_port_encoding_x (SCM port, SCM encoding);
-SCM_INTERNAL scm_t_string_failed_conversion_handler scm_i_get_conversion_strategy (SCM port);
-SCM_INTERNAL void scm_i_set_conversion_strategy_x (SCM port, 
-                                                  scm_t_string_failed_conversion_handler h);
 SCM_API SCM scm_port_conversion_strategy (SCM port);
 SCM_API SCM scm_set_port_conversion_strategy_x (SCM port, SCM behavior);
 
 /* Acquiring and releasing the port lock.  */
-SCM_INLINE int scm_c_lock_port (scm_t_port *entry);
-SCM_INLINE int scm_c_try_lock_port (scm_t_port *entry);
-SCM_INLINE int scm_c_unlock_port (scm_t_port *entry);
-
-/* Meta.  */
-SCM_API int scm_revealed_count (SCM port);
-SCM_API SCM scm_port_revealed (SCM port);
-SCM_API SCM scm_set_port_revealed_x (SCM port, SCM rcount);
+SCM_API void scm_dynwind_lock_port (SCM port);
+SCM_INLINE int scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
+SCM_INLINE int scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
 
 /* Input.  */
-SCM_INLINE int scm_get_byte_or_eof (SCM port);
-SCM_INLINE int scm_peek_byte_or_eof (SCM port);
+SCM_API int scm_get_byte_or_eof (SCM port);
+SCM_INLINE int scm_get_byte_or_eof_unlocked (SCM port);
+SCM_API int scm_slow_get_byte_or_eof_unlocked (SCM port);
+SCM_API int scm_peek_byte_or_eof (SCM port);
+SCM_INLINE int scm_peek_byte_or_eof_unlocked (SCM port);
+SCM_API int scm_slow_peek_byte_or_eof_unlocked (SCM port);
 SCM_API size_t scm_c_read (SCM port, void *buffer, size_t size);
+SCM_API size_t scm_c_read_unlocked (SCM port, void *buffer, size_t size);
 SCM_API scm_t_wchar scm_getc (SCM port);
-SCM_API SCM scm_peek_char (SCM port);
+SCM_API scm_t_wchar scm_getc_unlocked (SCM port);
 SCM_API SCM scm_read_char (SCM port);
 
 /* Pushback.  */
-SCM_INTERNAL void scm_unget_byte (int c, SCM port); 
+SCM_API void scm_unget_bytes (const unsigned char *buf, size_t len, SCM port);
+SCM_API void scm_unget_bytes_unlocked (const unsigned char *buf, size_t len, SCM port);
+SCM_API void scm_unget_byte (int c, SCM port);
+SCM_API void scm_unget_byte_unlocked (int c, SCM port);
 SCM_API void scm_ungetc (scm_t_wchar c, SCM port);
+SCM_API void scm_ungetc_unlocked (scm_t_wchar c, SCM port);
 SCM_API void scm_ungets (const char *s, int n, SCM port);
+SCM_API void scm_ungets_unlocked (const char *s, int n, SCM port);
+SCM_API SCM scm_peek_char (SCM port);
 SCM_API SCM scm_unread_char (SCM cobj, SCM port);
 SCM_API SCM scm_unread_string (SCM str, SCM port);
 
 /* Manipulating the buffers.  */
 SCM_API void scm_port_non_buffer (scm_t_port *pt);
 SCM_API int scm_fill_input (SCM port);
+SCM_API int scm_fill_input_unlocked (SCM port);
 SCM_INTERNAL size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);
 SCM_API SCM scm_drain_input (SCM port);
 SCM_API void scm_end_input (SCM port);
+SCM_API void scm_end_input_unlocked (SCM port);
 SCM_API SCM scm_force_output (SCM port);
 SCM_API void scm_flush (SCM port);
+SCM_API void scm_flush_unlocked (SCM port);
 
 /* Output.  */
-SCM_INLINE void scm_putc (char c, SCM port);
-SCM_INLINE void scm_puts (const char *str_data, SCM port);
+SCM_API void scm_putc (char c, SCM port);
+SCM_INLINE void scm_putc_unlocked (char c, SCM port);
+SCM_API void scm_puts (const char *str_data, SCM port);
+SCM_INLINE void scm_puts_unlocked (const char *str_data, SCM port);
 SCM_API void scm_c_write (SCM port, const void *buffer, size_t size);
+SCM_API void scm_c_write_unlocked (SCM port, const void *buffer, size_t size);
 SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port);
+SCM_API void scm_lfwrite_unlocked (const char *ptr, size_t size, SCM port);
 SCM_INTERNAL void scm_lfwrite_substr (SCM str, size_t start, size_t end,
                                      SCM port);
 
@@ -346,6 +371,10 @@ SCM_API SCM scm_set_port_column_x (SCM port, SCM line);
 SCM_API SCM scm_port_filename (SCM port);
 SCM_API SCM scm_set_port_filename_x (SCM port, SCM filename);
 
+/* Port properties.  */
+SCM_INTERNAL SCM scm_i_port_property (SCM port, SCM key);
+SCM_INTERNAL SCM scm_i_set_port_property_x (SCM port, SCM key, SCM value);
+
 /* Implementation helpers for port printing functions.  */
 SCM_API int scm_port_print (SCM exp, SCM port, scm_print_state *);
 SCM_API void scm_print_port_mode (SCM exp, SCM port);
@@ -367,96 +396,68 @@ SCM_INTERNAL void scm_init_ports (void);
 
 #if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES
 SCM_INLINE_IMPLEMENTATION int
-scm_c_lock_port (scm_t_port *entry)
+scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock)
 {
-#if SCM_USE_PTHREAD_THREADS
-  return scm_i_pthread_mutex_lock (&entry->lock);
-#else
-  return 0;
-#endif
-}
+  *lock = SCM_PTAB_ENTRY (port)->lock;
 
-SCM_INLINE_IMPLEMENTATION int
-scm_c_try_lock_port (scm_t_port *entry)
-{
-#if SCM_USE_PTHREAD_THREADS
-  return scm_i_pthread_mutex_trylock (&entry->lock);
-#else
-  return 0;
-#endif
+  if (*lock)
+    return scm_i_pthread_mutex_lock (*lock);
+  else
+    return 0;
 }
 
 SCM_INLINE_IMPLEMENTATION int
-scm_c_unlock_port (scm_t_port *entry)
+scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock)
 {
-#if SCM_USE_PTHREAD_THREADS
-  return scm_i_pthread_mutex_unlock (&entry->lock);
-#else
-  return 0;
-#endif
+  *lock = SCM_PTAB_ENTRY (port)->lock;
+  if (*lock)
+    {
+      int ret = scm_i_pthread_mutex_trylock (*lock);
+      if (ret != 0)
+        *lock = NULL;
+      return ret;
+    }
+  else
+    return 0;
 }
 
 SCM_INLINE_IMPLEMENTATION int
-scm_get_byte_or_eof (SCM port)
+scm_get_byte_or_eof_unlocked (SCM port)
 {
-  int c;
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
 
-  if (pt->rw_active == SCM_PORT_WRITE)
-    /* may be marginally faster than calling scm_flush.  */
-    SCM_PORT_DESCRIPTOR (port)->flush (port);
-
-  if (pt->rw_random)
-    pt->rw_active = SCM_PORT_READ;
-
-  if (pt->read_pos >= pt->read_end)
-    {
-      if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
-       return EOF;
-    }
-
-  c = *(pt->read_pos++);
-
-  return c;
+  if (SCM_LIKELY ((pt->rw_active == SCM_PORT_READ || !pt->rw_random)
+                  && pt->read_pos < pt->read_end))
+    return *pt->read_pos++;
+  else
+    return scm_slow_get_byte_or_eof_unlocked (port);
 }
 
 /* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'.  */
 SCM_INLINE_IMPLEMENTATION int
-scm_peek_byte_or_eof (SCM port)
+scm_peek_byte_or_eof_unlocked (SCM port)
 {
-  int c;
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
 
-  if (pt->rw_active == SCM_PORT_WRITE)
-    /* may be marginally faster than calling scm_flush.  */
-    SCM_PORT_DESCRIPTOR (port)->flush (port);
-
-  if (pt->rw_random)
-    pt->rw_active = SCM_PORT_READ;
-
-  if (pt->read_pos >= pt->read_end)
-    {
-      if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
-       return EOF;
-    }
-
-  c = *pt->read_pos;
-
-  return c;
+  if (SCM_LIKELY ((pt->rw_active == SCM_PORT_READ || !pt->rw_random)
+                  && pt->read_pos < pt->read_end))
+    return *pt->read_pos;
+  else
+    return scm_slow_peek_byte_or_eof_unlocked (port);
 }
 
 SCM_INLINE_IMPLEMENTATION void
-scm_putc (char c, SCM port)
+scm_putc_unlocked (char c, SCM port)
 {
   SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
-  scm_lfwrite (&c, 1, port);
+  scm_lfwrite_unlocked (&c, 1, port);
 }
 
 SCM_INLINE_IMPLEMENTATION void
-scm_puts (const char *s, SCM port)
+scm_puts_unlocked (const char *s, SCM port)
 {
   SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
-  scm_lfwrite (s, strlen (s), port);
+  scm_lfwrite_unlocked (s, strlen (s), port);
 }
 #endif  /* SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES */