1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 11:50:28 +02:00
Commit graph

232 commits

Author SHA1 Message Date
Andy Wingo
99899b7c9c Remove scm_flush_unlocked / scm_end_input_unlocked
* libguile/ports.h (scm_flush_unlocked, scm_end_input_unlocked):
  Remove.
* libguile/ports.c (scm_c_read_bytes_unlocked):
  (scm_i_unget_bytes_unlocked, scm_setvbuf, scm_force_output)
  (scm_fill_input_unlocked, scm_c_write_bytes_unlocked)
  (scm_c_write_unlocked, scm_lfwrite_unlocked, scm_seek)
  (scm_truncate_file, flush_output_port): Call scm_flush / scm_end_input
  instead of the _unlocked variants.
  (scm_end_input): Lock while discarding the input buffer but not while
  calling out to the seek function.
* libguile/filesys.c (scm_fsync):
* libguile/ioext.c (scm_redirect_port):
* libguile/read.c (scm_i_scan_for_encoding):
* libguile/rw.c (scm_write_string_partial): Use scm_flush, not
  scm_flush_unlocked.
2016-04-23 15:21:43 +02:00
Andy Wingo
69a1b83f31 Remove port rw_active field
* libguile/ports.h (scm_t_port_rw_active): Move type definition to
  ports-internal.h.
  (scm_t_port): Remove rw_active field.  It's sufficient to check the
  port buffer cursors.
* libguile/read.c (scm_i_scan_for_encoding): Just call
  scm_flush_unlocked; it's idempotent.
* libguile/ports.c (scm_c_make_port_with_encoding): Remove rw_active
  field.
  (scm_c_read_bytes_unlocked, scm_c_read, scm_i_unget_bytes_unlocked)
  (scm_end_input_unlocked, scm_flush_unlocked, scm_fill_input_unlocked)
  (scm_port_write_buffer, scm_port_read_buffer)
  (scm_c_write_bytes_unlocked, scm_c_write_unlocked, scm_seek): Remove
  management of rw_active field.
2016-04-22 21:08:30 +02:00
Andy Wingo
4934b69ddf scm_c_read instead of scm_c_read_unlock
* libguile/ports.h (scm_c_read_unlocked): Remove.
* libguile/ports.c (scm_c_read): Rename from scm_c_read_unlocked.
  Remove old scm_c_read.  Lock around access to the rw_active flag, and
  call scm_flush instead of scm_flush_unlocked, and scm_fill_input
  instead of scm_fill_input_unlocked.
* libguile/read.c (scm_i_scan_for_encoding): Use scm_c_read instead of
  the _unlocked function.
2016-04-22 20:42:24 +02:00
Andy Wingo
fb577b59af Refactor to internal get/peek-byte functions
* libguile/ports.h (scm_get_byte_or_eof_unlocked)
  (scm_peek_byte_or_eof_unlocked): Remove inline functions.  The
  important uses are in ports.c anyway and we will use a static function
  there.
  (scm_slow_get_byte_or_eof_unlocked)
  (scm_slow_peek_byte_or_eof_unlocked): Remove declarations without
  definitions.
* libguile/ports.c (looking_at_bytes): Use scm_peek_byte_or_eof instead
  of the _unlocked variant.
  (get_byte_or_eof, peek_byte_or_eof): New static functions.
  (scm_get_byte_or_eof, scm_peek_byte_or_eof): Don't lock: the port
  buffer mechanism means that we won't crash.  More comments to come.
  (get_utf8_codepoint, get_latin1_codepoint, get_iconv_codepoint): Use
  new static functions.
* libguile/read.c (read_token, scm_read_semicolon_comment): Use
  scm_get_byte_or_eof, not scm_get_byte_or_eof_unlocked.
2016-04-22 17:12:58 +02:00
Andy Wingo
5a342f61c4 Port buffers are Scheme values
* libguile/ports-internal.h (scm_port_buffer_bytevector)
  (scm_port_buffer_cur, scm_port_buffer_set_cur)
  (scm_port_buffer_end, scm_port_buffer_set_end)
  (scm_port_buffer_has_eof_p, scm_port_buffer_set_has_eof_p): New
  helpers.
* libguile/ports-internal.h (scm_port_buffer_size)
  (scm_port_buffer_reset, scm_port_buffer_reset_end)
  (scm_port_buffer_can_take, scm_port_buffer_can_put)
  (scm_port_buffer_can_putback, scm_port_buffer_did_take)
  (scm_port_buffer_did_put, scm_port_buffer_take_pointer)
  (scm_port_buffer_put_pointer, scm_port_buffer_take)
  (scm_port_buffer_put, scm_port_buffer_putback): Adapt to treat port
  buffers as SCM values and use helpers to access them.
* libguile/ports.c (scm_i_clear_pending_eof, scm_i_set_pending_eof)
  (scm_c_make_port_buffer, scm_i_read_unlocked)
  (scm_c_read_bytes_unlocked, scm_i_unget_bytes_unlocked)
  (scm_setvbuf, scm_fill_input, scm_take_from_input_buffers)
  (scm_drain_input, scm_end_input_unlocked, scm_flush_unlocked)
  (scm_fill_input_unlocked, scm_i_write_unlocked)
  (scm_c_write_bytes_unlocked, scm_c_write_unlocked)
  (scm_char_ready_p): Adapt to treat port buffers as SCM values and use
  helpers to access them.
  (scm_port_read_buffer, scm_port_write_buffer): New functions,
  allowing (ice-9 ports) to access port buffers.
* libguile/ports.h: Update comments on port buffers.  Replace
  scm_t_port_buffer structure with a Scheme vector whose fields are
  enumerated by "enum scm_port_buffer_field".
  (scm_get_byte_or_eof_unlocked, scm_peek_byte_or_eof_unlocked): Adapt
  these implementations to port buffer representation change.
* libguile/r6rs-ports.c (scm_get_bytevector_some):
* libguile/read.c (scm_i_scan_for_encoding):
* libguile/rw.c (scm_write_string_partial): Port buffers are Scheme
  objects.
2016-04-20 09:22:20 +02:00
Andy Wingo
bb6edc5a35 peek-u8 correctness and speed refactor
* libguile/ports-internal.h (scm_port_buffer_size): Verify that the
  bytevector field is a bytevector, in anticipation of Schemification.
  (scm_port_buffer_can_take, scm_port_buffer_can_put)
  (scm_port_buffer_can_putback): Enforce invariants on cur and end
  here.
  (scm_port_buffer_did_take, scm_port_buffer_did_put): Relax to not call
  other functions.
* libguile/ports.h (scm_get_byte_or_eof_unlocked)
  (scm_peek_byte_or_eof_unlocked): Refactor to call no functions on the
  fast path.
2016-04-19 22:58:33 +02:00
Andy Wingo
ffb4347d53 Port buffer cur/next pointers are Scheme values
* libguile/ports.h (scm_t_port_buffer): Change "cur" and "end" members
  to be SCM values, in preparation for changing port buffers to be
  Scheme vectors.
  (scm_get_byte_or_eof_unlocked, scm_peek_byte_or_eof_unlocked): Adapt.
* libguile/ports.c (scm_c_make_port_buffer): Initialize cur and end
  members.
  (looking_at_bytes): Use helper instead of incrementing cur.
  (scm_i_read_unlocked): Adapt to end type change.
  (CONSUME_PEEKED_BYTE): Use helper instead of incrementing cur.
  (scm_i_unget_bytes_unlocked): Use helper instead of comparing cur.
  (scm_i_write_unlocked): Fix for changing end/cur types.
* libguile/read.c (scm_i_scan_for_encoding): Use helpers instead of
  addressing cursors directly.
* libguile/rw.c (scm_write_string_partial): Likewise.
* libguile/ports-internal.h (scm_port_buffer_reset):
  (scm_port_buffer_reset_end, scm_port_buffer_can_take):
  (scm_port_buffer_can_put, scm_port_buffer_can_putback):
  (scm_port_buffer_did_take, scm_port_buffer_did_put):
  (scm_port_buffer_take_pointer, scm_port_buffer_put_pointer):
  (scm_port_buffer_putback): Adapt to data types.
2016-04-19 20:02:05 +02:00
Andy Wingo
10dc6d043e Remove "buf" field from port buffers
* libguile/ports-internal.h (scm_port_buffer_reset_end): New helper.
  (scm_port_buffer_putback): New helper.
* libguile/ports.h (scm_t_port_buffer): Remove "buf" field.
  (scm_get_byte_or_eof_unlocked, scm_peek_byte_or_eof_unlocked): Adapt.
* libguile/ports.c (scm_c_make_port_buffer): No more "buf" field.
  (scm_i_unget_bytes_unlocked): Use helper.
* libguile/read.c (scm_i_scan_for_encoding): No more "buf" field.
2016-04-18 00:19:24 +02:00
Andy Wingo
b869344a4f Remove size field from port buffers
* libguile/ports.h (scm_t_port_buffer): Remove size field.  Instead use
  bytevector size.
* libguile/ports-internal.h (scm_port_buffer_size)
  (scm_port_buffer_reset)
  (scm_port_buffer_can_take, scm_port_buffer_can_put)
  (scm_port_buffer_did_take, scm_port_buffer_did_put)
  (scm_port_buffer_take_pointer, scm_port_buffer_put_pointer)
  (scm_port_buffer_take, scm_port_buffer_put): New helpers.
* libguile/filesys.c (set_element): Use new helpers.
* libguile/poll.c (scm_primitive_poll): Use new helpers.
* libguile/ports.c (scm_c_make_port_buffer): No more "size" field.
  (scm_i_read_unlocked, scm_c_read_bytes_unlocked)
  (scm_c_read_unlocked, scm_i_unget_bytes_unlocked)
  (scm_unget_bytes, scm_setvbuf, scm_take_from_input_buffers)
  (scm_drain_input, scm_end_input_unlocked, scm_flush_unlocked)
  (scm_fill_input_unlocked, scm_i_write_unlocked)
  (scm_c_write_bytes_unlocked, scm_c_write_unlocked)
  (scm_char_ready_p): Use new helpers.
* libguile/r6rs-ports.c (scm_get_bytevector_some): Use new helpers.
* libguile/rw.c (scm_write_string_partial): Use new helpers.
2016-04-17 19:38:44 +02:00
Andy Wingo
f62974000f Port buffer has-eof? field is SCM value
* libguile/ports.h (scm_t_port_buffer): Rename has_eof member to
  has_eof_p, and be a Scheme value, in anticipation of moving the port
  buffers to be Scheme objects.
2016-04-17 15:42:13 +02:00
Andy Wingo
f7027a8b88 Port read/write functions take bytevectors
This will allow better Scheme integration for ports.

* libguile/ports.h (scm_t_port_buffer): Change "holder" member to be a
  bytevector defined to have "buf" as its starting point.
  (scm_t_ptob_descriptor): Change read and write functions to take
  bytevectors as arguments and to return the number of octets read or
  written.
  (scm_make_port_type): Adapt accordingly.
  (scm_c_read_bytes, scm_c_write_bytes): New functions that take
  bytevectors.
* libguile/ports.c (scm_make_port_type): Adapt to read/write function
  prototype change.
  (scm_c_make_port_buffer): Arrange to populate the "bytevector" field.
  (scm_i_read_bytes_unlocked): New function.
  (scm_i_read_unlocked): Use scm_i_read_bytes_unlocked.
  (scm_c_read_bytes_unlocked): New function.
  (scm_c_read_unlocked): Update comment, and always go through the
  buffer.
  (scm_c_read_bytes): New function.
  (scm_flush_unlocked): Use scm_i_write_unlocked instead of the port's
  write function.
  (scm_i_write_bytes_unlocked): New function.
  (scm_i_write_unlocked): Use scm_i_write_bytes_unlocked.
  (scm_c_write_bytes_unlocked): New function.
  (scm_c_write_unlocked): Always write through the buffer.
  (scm_c_write_bytes): New function.
  (scm_truncate_file): Remove unused variable.
  (void_port_read, void_port_write): Adapt to read/write prototype
  change.
* libguile/fports.c (fport_read, fport_write):
* libguile/r6rs-ports.c (bytevector_input_port_read)
  (custom_binary_input_port_read, bytevector_output_port_write)
  (custom_binary_output_port_write, transcoded_port_write)
  (transcoded_port_read): Adapt to read/write prototype
  change.
  (scm_get_bytevector_n, scm_get_bytevector_n_x)
  (scm_get_bytevector_all): Use scm_c_read_bytes.
  (scm_put_bytevector): Use scm_c_write_bytes.
* libguile/strports.c (string_port_read, string_port_write):
* libguile/vports.c (soft_port_write, soft_port_read): Adapt to
  read/write prototype change.
* test-suite/standalone/test-scm-c-read.c (custom_port_read): Fix for
  read API change.
2016-04-11 22:23:47 +02:00
Andy Wingo
8399e7af51 Generic port facility provides buffering uniformly
* libguile/ports.h (struct scm_t_port_buffer): New data type.
  (struct scm_t_port): Refactor to use port buffers instead of
  implementation-managed read and write pointers.  Add "read_buffering"
  member.
  (SCM_INITIAL_PUTBACK_BUF_SIZE, SCM_READ_BUFFER_EMPTY_P): Remove.
  (scm_t_ptob_descriptor): Rename "fill_input" function to "read", and
  take a port buffer, returning void.  Likewise "write" takes a port
  buffer and returns void.  Remove "end_input"; instead if there is
  buffered input and rw_random is true, then there must be a seek
  function, so just seek back if needed.  Remove "flush"; instead all
  calls to the "write" function implicitly include a "flush", since the
  buffering happens in the generic port code now.  Remove "setvbuf", but
  add "get_natural_buffer_sizes"; instead the generic port code can
  buffer any port.
  (scm_make_port_type): Adapt to read and write prototype changes.
  (scm_set_port_flush, scm_set_port_end_input, scm_set_port_setvbuf):
  Remove.
  (scm_slow_get_byte_or_eof_unlocked)
  (scm_slow_get_peek_or_eof_unlocked): Remove; the slow path is to call
  scm_fill_input.
  (scm_set_port_get_natural_buffer_sizes): New function.
  (scm_c_make_port_buffer): New internal function.
  (scm_port_non_buffer): Remove.  This was a function for
  implementations that is no longer needed.  Instead open with BUF0 or
  use (setvbuf port 'none).
  (scm_fill_input, scm_fill_input_unlocked): Return the filled port
  buffer.
  (scm_get_byte_or_eof_unlocked, scm_peek_byte_or_eof_unlocked): Adapt
  to changes in buffering and EOF management.
* libguile/ports.c: Adapt to port interface changes.
  (initialize_port_buffers): New function, using the port mode flags to
  set up appropriate initial buffering for all ports.
  (scm_c_make_port_with_encoding): Create port buffers here instead of
  delegating to implementations.
  (scm_close_port): Flush the port if needed instead of delegating to
  the implementation.
* libguile/filesys.c (set_element): Adapt to buffering changes.
* libguile/fports.c (fport_get_natural_buffer_sizes): New function,
  replacing scm_fport_buffer_add.
  (fport_write, fport_read): Update to let the generic ports code do the
  buffering.
  (fport_flush, fport_end_input): Remove.
  (fport_close): Don't flush in a dynwind; that's the core ports' job.
  (scm_make_fptob): Adapt.
* libguile/ioext.c (scm_redirect_port): Adapt to buffering changes.
* libguile/poll.c (scm_primitive_poll): Adapt to buffering changes.
* libguile/ports-internal.h (struct scm_port_internal): Remove
  pending_eof flag; this is now set on the read buffer.
* libguile/r6rs-ports.c (struct bytevector_input_port): New type.  The
  new buffering arrangement means that there's now an intermediate
  buffer between the bytevector and the user of the port; this could
  lead to a perf degradation, but on the other hand there are some other
  speedups enabled by the buffering refactor, so probably the memcpy
  cost is dwarfed by the cost of the other parts of the ports
  machinery.
  (make_bytevector_input_port, bytevector_input_port_read):
  (bytevector_input_port_seek, initialize_bytevector_input_ports): Adapt
  to new buffering arrangement.
  (struct custom_binary_port): Remove read buffer, as Guile handles that
  now.
  (custom_binary_input_port_setvbuf): Remove; now handled by Guile.
  (make_custom_binary_input_port, custom_binary_input_port_read)
  (initialize_custom_binary_input_ports): Adapt.
  (scm_get_bytevector_some): Adapt to new EOF management.
  (scm_t_bytevector_output_port_buffer): Hold on to the underlying port,
  so we can flush it if it's open.
  (make_bytevector_output_port, bytevector_output_port_write):
  (bytevector_output_port_seek): Adapt.
  (bytevector_output_port_procedure): Flush the port as appropriate, so
  that we get all the bytes.
  (make_custom_binary_output_port, custom_binary_output_port_write):
  Adapt.
  (make_transcoded_port): Don't muck with buffering.
  (transcoded_port_write): Simply forward the write to the underlying
  port.
  (transcoded_port_read): Likewise.
  (transcoded_port_close): No need to flush.
  (initialize_transcoded_ports): Adapt.
* libguile/read.c (scm_i_scan_for_encoding): Adapt to buffering
  changes.
* libguile/rw.c (scm_write_string_partial): Adapt to buffering changes.
* libguile/strports.c: Adapt to the fact that we don't manage the
  buffer.  Probably room for speed improvements here...
* libguile/vports.c (soft_port_get_natural_buffer_sizes): New function.
  Adapt the rest of the file for the new buffering regime.
* test-suite/tests/r6rs-ports.test ("8.2.10 Output ports"): Custom
  binary output ports need to be flushed before you can rely on the
  write! procedure having been called.  Add necessary flush-port
  invocations.
  ("8.2.6  Input and output ports"): Transcoded ports now have an
  internal buffer by default.  This test checks that the characters are
  transcoded one at a time, so to do that, call setvbuf on the
  transcoded port to remove the buffer.
* test-suite/tests/web-client.test (run-with-http-transcript): Fix for
  different flushing regime on soft ports.  (The vestigial flush
  procedure is now called after each write, which is not what the test
  was expecting.)
* test-suite/standalone/test-scm-c-read.c: Update for changes to the C
  interface for defining port types.
* doc/ref/api-io.texi (Ports): Update to discuss buffering in a generic
  way, and to remove a hand-wavey paragraph describing string ports as
  "interesting and powerful".
  (Reading, Writing): Remove placeholder comments.  Document
  `scm_lfwrite'.
  (Buffering): New section.
  (File Ports): Link to buffering.
  (I/O Extensions): Join subnodes into parent and describe new API,
  including buffering API.
* doc/ref/posix.texi (Ports and File Descriptors): Link to buffering.
  Remove unread-char etc, as they are documented elsewhere.
  (Pipes, Network Sockets and Communication): Link to buffering.
2016-04-06 19:21:44 +02:00
Andy Wingo
e8eeeeb1d4 Port close functions return void
* libguile/ports.h (scm_t_ptob_descriptor): The port close function now
  returns void.
  (scm_set_port_close): Adapt prototype.
* libguile/ports.c (scm_close_port): Always return true if we managed to
  call the close function.  There's no other sensible result; exceptions
  are handled, well, exceptionally.

* libguile/fports.c (fport_close)
* libguile/r6rs-ports.c (custom_binary_port_close, transcoded_port_close):
* libguile/vports.c (soft_port_close): Adapt.

* doc/ref/api-io.texi (Port Implementation): Update.
2016-04-05 15:16:26 +02:00
Andy Wingo
e98f64009d Remove port equal functions
* doc/ref/api-io.texi (Port Implementation): Remove mention of port
  equal functions.
* NEWS: Update.
* libguile/ports.c (scm_set_port_equalp): Remove.
* libguile/ports.h (scm_t_ptob_descriptor): Remove equalp function.
2016-04-04 16:30:56 +02:00
Andy Wingo
67b147fb7a Remove port free functions; just close instead
* libguile/ports.h (scm_t_port_type_flags): Replace
  SCM_PORT_TYPE_HAS_FLUSH with SCM_PORT_TYPE_NEEDS_CLOSE_ON_GC.
  (scm_t_ptob_descriptor): Remove free function.
* libguile/ports.c (scm_set_port_needs_close_on_gc): New function.
  (scm_set_port_flush): Don't set flags.
  (scm_c_make_port_with_encoding, scm_close_port): Use the new flag to
  determine when to add a finalizer and also when to include the port in
  the weak set.
  (scm_set_port_free): Remove.
  (do_close, finalize_port): Close port instead of calling free
  function.
* libguile/r6rs-ports.c (initialize_transcoded_ports):
* libguile/vports.c (scm_make_sfptob):
* libguile/fports.c (scm_make_fptob): Mark these ports as needing close
  on GC.
* libguile/fports.c (fport_free): Remove.
* NEWS: Update.
* doc/ref/api-io.texi (Port Implementation): Update.
2016-04-04 16:30:56 +02:00
Andy Wingo
4460f1f152 Remove port mark functions
* doc/ref/api-io.texi (Port Implementation): Remove documentation.
* libguile/ports.c (scm_set_port_mark): Remove function.
* libguile/ports.h (scm_t_ptob_descriptor): Remove mark function.
* NEWS: Add entry.
2016-04-04 16:30:56 +02:00
Andy Wingo
0a0a8d819d Move setvbuf impl to ports.[ch]
* libguile/fports.h (scm_setbuf0): Remove extraneous declaration.
* libguile/fports.c:
* libguile/ports.c:
* libguile/ports.c (scm_setvbuf): Move setvbuf to ports.[ch].
  (scm_init_ports): Move _IONBF, _IOLBF, _IOFBF definitions here.
2016-04-04 16:30:56 +02:00
Andy Wingo
e140d85d53 Merge commit '122f24cc8a'
Conflicts:
	libguile/fports.c
	libguile/ports.c
2014-02-07 14:39:01 +01:00
Andy Wingo
9b95f3ced4 Merge commit 'a38024baaa'
Conflicts:
	libguile/ports.h
2013-11-28 16:15:38 +01:00
Mark H Weaver
a38024baaa Make port properties accessible from Scheme.
* libguile/ports.c (scm_i_port_alist, scm_i_set_port_alist_x): Removed.
  (scm_i_port_property, scm_i_set_port_property_x): New procedures,
  available from Scheme as '%port-property' and '%set-port-property!'.

* libguile/ports.h (scm_i_port_alist, scm_i_set_port_alist_x): Removed.
  (scm_i_port_property, scm_i_set_port_property_x): New prototypes.

* libguile/read.c (set_port_read_option, init_read_options): Adapt to
  use scm_i_port_property and scm_i_set_port_property_x.
2013-11-23 15:47:31 -05:00
Mark H Weaver
f6f4feb0a2 Merge remote-tracking branch 'origin/stable-2.0'
Conflicts:
	GUILE-VERSION
	libguile/array-map.c
	libguile/fports.h
	libguile/gc.h
	libguile/inline.h
	libguile/ports.c
	libguile/ports.h
	libguile/print.c
	libguile/r6rs-ports.c
	libguile/read.c
	test-suite/tests/00-socket.test
2013-04-14 02:48:33 -04:00
Mark H Weaver
7f6c3f8f00 Implement efficient 'scm_unget_bytes' and 'unget-bytevector'.
* libguile/ports.c (scm_i_unget_bytes): New static function.
  (scm_unget_bytes): New API function.
  (scm_unget_byte): Rewrite to simply call 'scm_i_unget_bytes'.
  (scm_ungetc, scm_peek_char, looking_at_bytes): Use 'scm_i_unget_bytes'.

* libguile/ports.h: Add prototype for 'scm_unget_bytes'.

* libguile/fports.c (scm_setvbuf): Use 'scm_unget_bytes'.

* libguile/r6rs-ports.c (scm_unget_bytevector): New procedure.

* module/ice-9/binary-ports.scm (unget-bytevector): New export.

* doc/ref/api-io.texi (R6RS Binary Input): Add documentation.
  (R6RS I/O Ports): Update brief description of (ice-9 binary-ports) to
  reflect the new reality: it is no longer a subset of (rnrs io ports).

* test-suite/tests/ports.test ("unget-bytevector"): Add test.
2013-04-07 10:14:44 -04:00
Mark H Weaver
e00793d7a9 Rename 'scm_i_get_byte_or_eof' et al; mark them as SCM_API.
* libguile/ports.c (scm_i_get_byte_or_eof, scm_i_peek_byte_or_eof):
  Rename to 'scm_slow_get_byte_or_eof' and 'scm_slow_peek_byte_or_eof',
  respectively.

* libguile/ports.h (scm_i_get_byte_or_eof, scm_i_peek_byte_or_eof):
  Rename to 'scm_slow_get_byte_or_eof' and 'scm_slow_peek_byte_or_eof',
  respectively, and mark them as SCM_API.

* libguile/inline.h (scm_get_byte_or_eof, scm_peek_byte_or_eof): Adjust
  to use the new names.
2013-04-02 19:35:43 -04:00
Mark H Weaver
8a2b596579 Move slow path out of 'scm_get_byte_or_eof' et al.
Suggested by Andy Wingo.

* libguile/inline.h (scm_get_byte_or_eof, scm_peek_byte_or_eof): Keep
  only the fast path here, with fallback to 'scm_i_get_byte_or_eof' and
  'scm_i_peek_byte_or_eof'.

* libguile/ports.c (scm_i_get_byte_or_eof, scm_i_peek_byte_or_eof):
  New internal functions.

* libguile/ports.h (scm_i_get_byte_or_eof, scm_i_peek_byte_or_eof): Add
  prototypes.
2013-04-02 13:43:20 -04:00
Mark H Weaver
05d7f76296 Move the port alist from the hash table to the internal port structure.
* libguile/ports-internal.h (struct scm_port_internal): Add 'alist'
  member.

* libguile/ports.c (scm_i_port_alist, scm_i_set_port_alist_x): New
  internal functions.
  (scm_i_port_weak_hash): Update comment: the hash table is no longer
  used to store the port's alist.
  (scm_new_port_table_entry): Initialize 'alist'.  Store SCM_BOOL_F in
  the port weak hash, not SCM_EOL.

* libguile/ports.h (scm_i_port_alist, scm_i_set_port_alist_x): Add
  protoypes.

* libguile/read.c (set_port_read_option, init_read_options): Access the
  port's alist via 'scm_i_port_alist' and 'scm_i_set_port_alist_x'.
2013-04-01 17:09:17 -04:00
Mark H Weaver
e459855936 Add internal-only port structure and move iconv descriptors there.
* libguile/ports-internal.h: New file.

* libguile/Makefile.am (noinst_HEADERS): Add ports-internal.h.

* libguile/ports.h (scm_t_port): Add a comment mentioning that the
  'input_cd' and 'output_cd' fields of the public structure are no
  longer what they seem to be.

* libguile/ports.c: Include ports-internal.h.

  (finalize_port, scm_i_remove_port, get_iconv_codepoint, get_codepoint,
  scm_i_set_port_encoding_x): Access 'input_cd' and 'output_cd' via the
  new internal port structure.

  (scm_new_port_table_entry): Allocate and initialize the internal port
  structure.

* libguile/print.c: Include ports-internal.h.

  (display_string_using_iconv, display_string): Access 'input_cd' and
  'output_cd' via 'internal' pointer.
2013-04-01 16:13:47 -04:00
Andy Wingo
419c873624 Revert "detect and consume byte-order marks for textual ports"
This reverts commit b2cb557d75, which was
pushed accidentally.
2013-01-30 15:30:31 +01:00
Andy Wingo
b2cb557d75 detect and consume byte-order marks for textual ports
* libguile/ports.h:
* libguile/ports.c (scm_consume_byte_order_mark): New procedure.

* libguile/fports.c (scm_open_file): Call consume-byte-order-mark if we
  are opening a file in "r" mode.

* libguile/read.c (scm_i_scan_for_encoding): Don't do anything about
  byte-order marks.

* libguile/load.c (scm_primitive_load): Add a note about the duplicate
  encoding scan.

* test-suite/tests/filesys.test: Add tests for UTF-8, UTF-16BE, and
  UTF-16LE BOM handling.
2013-01-30 13:52:01 +01:00
Mark H Weaver
fa980bcc0f Merge remote-tracking branch 'origin/stable-2.0'
Moved scm_i_struct_hash from struct.c to hash.c and made it static.

The port's alist is now a field of 'scm_t_port'.

Conflicts:
	libguile/arrays.c
	libguile/hash.c
	libguile/ports.c
	libguile/print.h
	libguile/read.c
2012-10-30 23:46:31 -04:00
Andy Wingo
0dd7c54075 Merge remote-tracking branch 'origin/stable-2.0'
Conflicts:
	libguile/deprecated.c
	libguile/ports.c
	libguile/ports.h
	libguile/strports.c
	test-suite/tests/cse.test
2012-06-22 13:18:02 +02:00
Ludovic Courtès
b22e94db7c Add the `%default-port-conversion-strategy' fluid.
Fixes <http://bugs.gnu.org/11468>.

* libguile/ports.c (scm_conversion_strategy): Remove.
  (default_conversion_strategy_var, sym_error, sym_substitute,
  sym_escape): New variables.
  (scm_i_get_conversion_strategy, scm_i_set_conversion_strategy_x):
  Remove.
  (scm_i_default_port_conversion_handler,
  scm_i_set_default_port_conversion_handler): New functions.
  (scm_port_conversion_strategy): Use
  `scm_i_default_port_conversion_handler' when PORT is #f.
  (scm_set_port_conversion_strategy_x): Use SYM_ERROR, SYM_SUBSTITUTE,
  and SYM_ESCAPE.  Use `scm_i_set_default_port_conversion_handler' when
  PORT is #f.
  (scm_init_ports): Initialize DEFAULT_CONVERSION_STRATEGY_VAR.

* libguile/ports.h: Update declarations accordingly.

* libguile/foreign.c: Change
  `scm_i_get_conversion_strategy (SCM_BOOL_F)' to
  `scm_i_default_port_conversion_handler ()'.
* libguile/strings.c: Likewise.

* test-suite/tests/ports.test ("%default-port-conversion-strategy"): New
  test prefix.

* test-suite/tests/foreign.test ("pointer<->string")["%default-port-conversion-strategy
  is error", "%default-port-conversion-strategy is soft"]: New tests.

* test-suite/test-suite/lib.scm (exception:encoding-error): Allow the
  regexp to match `scm_to_stringn' error messages.

* doc/ref/api-io.texi (Ports): Document `%default-port-conversion-strategy'.
2012-05-31 00:50:36 +02:00
Andy Wingo
a3ded46520 Merge remote-tracking branch 'origin/stable-2.0'
Conflicts:
	libguile/ports.c
	libguile/ports.h
	libguile/read.c
	libguile/vm-i-system.c
2012-05-08 22:43:04 +02:00
Ludovic Courtès
33672b0711 Add missing SCM_API' for scm_take_from_input_buffers'.
* libguile/ports.h (scm_take_from_input_buffers): Add `SCM_API'.
2012-05-08 16:11:13 +02:00
Ludovic Courtès
5bbd632fc3 Make `scm_unget_byte' public.
* libguile/ports.h (scm_unget_byte): Make `SCM_API' instead of
  `SCM_INTERNAL'.
2012-05-06 22:24:47 +02:00
Andy Wingo
79eb47ea47 port i/o optimizations for iso-8859-1
* libguile/ports.h (scm_t_port_encoding_mode):
* libguile/ports.c (scm_c_make_port_with_encoding):
  (scm_i_set_port_encoding_x): Add special treatment for latin1
  encoding.
  (get_latin1_codepoint, get_codepoint): Add latin1 fast-path.

* libguile/print.c (display_string_as_latin1): Add latin1 fastpath.
2012-02-24 23:05:34 +01:00
Andy Wingo
3753e22736 move revealed-count mechanism to fports.c
* libguile/fports.c (scm_revealed_count, scm_port_revealed)
  (scm_set_port_revealed_x, scm_adjust_port_revealed_x): Move these APIs
  here, and only operate on fports.  To keep revealed ports alive, now
  we will just keep them in a data structure that the GC knows about --
  a static list.

* libguile/fports.h: Add revealed count to scm_t_fport, and move decls
  of revealed-count functions here.

* libguile/ports.h:
* libguile/ports.c: Adapt to change.  Remove SCM_REVEALED and
  SCM_SETREVEALED; since they only apply to fports now, keeping them
  around would be inviting type errors.
  (finalize_port): We don't need to worry about resuscitating ports
  here.

* libguile/init.c: Use the scm_set_port_revealed_x function to set the
  revealed counts on stream ports.
2012-02-19 13:30:30 +01:00
Andy Wingo
03a2eeb0cc ports: avoid adding port table entries and finalizers if possible
* libguile/ports.h (scm_t_port_type_flags, scm_t_ptob_descriptor): Add
  flags to ptob descriptors.

* libguile/ports.c (scm_set_port_flush): Set the SCM_PORT_TYPE_HAS_FLUSH
  flag here.
  (scm_c_make_port_with_encoding): Only add ports to the table if
  SCM_PORT_TYPE_HAS_FLUSH is set.  Only add finalizers to ports if there
  is a free function.
  (scm_close_port): Inline scm_i_remove_port here.  Only remove from the
  weak set if SCM_PORT_TYPE_HAS_FLUSH is set.
  (scm_set_port_revealed_x): Add a comment.
2012-02-14 14:10:53 +01:00
Andy Wingo
6c98257f2e refactor port encoding modes: utf-8 and iconv
* libguile/ports.h (struct scm_t_port): Add a flag for the port encoding
  mode: UTF8 or iconv.  The iconv descriptors are now in a separate
  structure so that we can avoid attaching finalizers to the ports
  themselves, in some cases.

* libguile/ports.c (scm_c_make_port_with_encoding): Init the encoding
  mode.
  (scm_i_remove_port): Adapt to call close_iconv_descriptors.
  (finalize_iconv_descriptors, open_iconv_descriptors):
  (close_iconv_descriptors): New infrastructure to manage iconv
  descriptors.
  (scm_i_port_iconv_descriptors): New internal helper.
  (scm_i_set_port_encoding_x): Use open_iconv_descriptors, if needed.
  (get_iconv_codepoint): Use pt->iconv_descriptors.
  (get_codepoint): Check the port encoding mode flags.

* libguile/print.c (display_string_using_iconv): Use
  scm_i_port_iconv_descriptors.
  (display_string): Use pt->encoding_mode flag.
2012-02-14 14:10:53 +01:00
Andy Wingo
04ec290f8b Merge remote-tracking branch 'origin/stable-2.0'
Conflicts:
	libguile/deprecation.c
	libguile/load.c
	libguile/print.c
2011-12-06 19:14:50 +01:00
Andy Wingo
92c0ebac90 port locking refactor
* libguile/ports.h (struct scm_t_port): Make the lock into a pointer
  field instead of an inline field.  It should be possible to make
  unlocked ports by having a NULL lock field.
  (scm_c_lock_port, scm_c_try_lock_port): Return the mutex if the port
  was actually locked.
  (scm_c_unlock_port): Remove.

* libguile/ports.c (scm_c_make_port_with_encoding): For now, leave
  `lock' set to 0.
  Change scm_c_lock_port callers to pay attention to the new API.

* libguile/print.c (scm_write, scm_display): Fix call to
  dynwind-lock-port for ports-with-print-states.
2011-12-06 18:01:45 +01:00
Andy Wingo
3972de7675 add current-warning-port
* libguile/ports.h:
* libguile/ports.c (scm_current_warning_port)
  (scm_set_current_warning_port): New functions, wrapping the Scheme
  parameter.

* module/ice-9/boot-9.scm (current-warning-port): New parameter,
  defining a port for warnings.
2011-12-05 18:07:06 +01:00
Andy Wingo
b86b70fece disable port locking
* libguile/ports.h (scm_c_lock_port, scm_c_try_lock_port)
  (scm_c_unlock_port): Disable port locking until I have time to sort
  out the bugs that are coming up.
2011-11-09 23:02:02 +01:00
Andy Wingo
14dcb5ccd2 add scm_dynwind_lock_port
* libguile/ports.h:
* libguile/ports.c (scm_dynwind_lock_port): New function.
2011-11-08 19:16:33 +01:00
Andy Wingo
f209aeee9f locking for write, lfwrite
* libguile/ports.c (scm_c_write_unlocked, scm_c_write)
  (scm_lfwrite_unlocked, scm_lfwrite): Add locking and _unlocked
  variants.  Change uses to _unlocked.
2011-11-08 00:55:06 +01:00
Andy Wingo
0607ebbfcf locking for putc, puts
* libguile/ports.c (scm_putc, scm_puts):
* libguile/ports.h (scm_putc_unlocked, scm_puts_unlocked): Separate into
  _unlocked and locked variants.  Change all callers to use the
  _unlocked versions.
2011-11-08 00:55:05 +01:00
Andy Wingo
4251ae2e28 locking on port buffering operations
* libguile/ports.c (scm_fill_input_unlocked, scm_fill_input)
  (scm_end_input, scm_end_input_unlocked, scm_flush)
  (scm_flush_unlocked): Add locking and _unlocked variants.

* libguile/filesys.c:
* libguile/fports.c:
* libguile/gdbint.c:
* libguile/r6rs-ports.c:
* libguile/read.c:
* libguile/rw.c: Adapt callers to use _unlocked variants.
2011-11-08 00:55:01 +01:00
Andy Wingo
c932ce0b55 locking on unget_byte, ungetc, ungets
* libguile/ports.h:
* libguile/ports.c (scm_unget_byte_unlocked, scm_unget_byte)
  (scm_ungetc_unlocked, scm_ungetc, scm_ungets_unlocked, scm_ungets):
  Add locking and _unlocked variants.

* libguile/arrays.c:
* libguile/rdelim.c:
* libguile/read.c:
* libguile/vports.c: Adapt callers to use the _unlocked variants.
2011-11-08 00:54:58 +01:00
Andy Wingo
be632904ca locking on scm_c_read, scm_getc
* libguile/ports.c (scm_c_read_unlocked, scm_c_read, scm_getc_unlocked)
  (scm_getc): Split getc and read operations into locked and unlocked
  variants.  Change most uses to use the _unlocked version.
2011-11-08 00:54:58 +01:00
Andy Wingo
0d959103f9 threadsafe get-byte-or-eof, peek-byte-or-eof
* libguile/ports.h (scm_get_byte_or_eof_unlocked):
  (scm_peek_byte_or_eof_unlocked): Rename, adding _unlocked.
* libguile/ports.c (scm_get_byte_or_eof, scm_peek_byte_or_eof): Add
  locking implementations.  Adapt callers to use _unlocked variants;
  they will do locking.

* libguile/read.c (read_token, scm_read_semicolon_comment)
  (scm_read_shebang): Use unlocked variants.  We will add locking
  later.
2011-11-08 00:54:57 +01:00
Andy Wingo
b262d3065c threadsafe port revealed counts
* libguile/ports.h:
* libguile/ports.c (scm_revealed_count, scm_set_port_revealed_x): Make
  threadsafe.
  (scm_adjust_port_revealed_x): New function, to adjust a port's
  revealed count in a threadsafe way.
2011-11-08 00:54:52 +01:00