* libguile/ports.c (scm_mode_bits): Parse the mode bits as latin1.
(scm_i_set_default_port_encoding, open_iconv_descriptors)
(scm_port_encoding, scm_set_port_encoding_x): Restrict the names of
encodings to ASCII.
* 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.
* libguile/bytevectors.c (STRING_TO_UTF, scm_string_to_utf8)
(UTF_TO_STRING):
* libguile/ports.c (open_iconv_descriptors, close_iconv_descriptors):
* libguile/strings.c (scm_from_stringn, scm_to_stringn): Wrap operations
that acquire and destroy iconv contexts with a mutex. While iconv is
threadsafe, internally it uses a lock, and we need to make sure when
we fork() that no one has that lock -- so we surround it with another
one. Gross.
* libguile/async.c:
* libguile/deprecation.c:
* libguile/fluids.c:
* libguile/gc.c:
* libguile/instructions.c:
* libguile/ports.c:
* libguile/posix.c:
* libguile/strings.c:
* libguile/threads.c: Use the SCM_PTHREAD_ATFORK_LOCK_STATIC_MUTEX
mechanism to lock a number of static mutexen.
* libguile/fports.c (close_the_fd, fport_close): Arrange to always close
the fd, even if the flush procedure throws an exception. Perhaps the
port machinery should do this for us, though. Don't wrap the close
call in SCM_SYSCALL, EINTR leaves the fd in an unspecified state.
Don't bother freeing buffers, the collector will handle that; simply
drop references via scm_port_non_buffer.
* libguile/ports.c (do_free, finalize_port): Catch exceptions caused by
the free procedure. Don't bother setting the stream to 0 at all.
(scm_close_port): Ensure that exceptions thrown by the "close"
procedure don't prevent the port from being marked as closed.
* 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.
* 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.
* libguile/ports.c (scm_init_ports): Export the port fluids to Scheme,
temporarily.
* module/ice-9/boot-9.scm (fluid->parameter): Turn `current-input-port'
et al into srfi-39 parameters, backed by the exported fluids, then
remove the fluids from the guile module.
(%cond-expand-features): Add srfi-39.
* module/srfi/srfi-39.scm: Re-export features from boot-9.
* test-suite/tests/parameters.test: Add tests.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* libguile/ports.h: Slight reorder.
* libguile/ports.c: Reorder ports implementation to match the header
file. This will make it easier to add locking and _unlocked
variants.
* libguile/ports.h (SCM_PORT_DESCRIPTOR): New macro, to get at a port
descriptor in the third word of a port instead of looking it up in a
table.
(scm_c_port_type_ref, scm_c_port_type_add_x): New API for working with
numbered ptob descriptors.
(SCM_PTOBNAME): Implement in terms of scm_c_port_type_ref.
(scm_get_byte_or_eof, scm_peek_byte_or_eof): Use SCM_PORT_DESCRIPTOR.
* libguile/ports.c (scm_c_num_port_types, scm_c_port_type_ref)
(scm_c_port_type_add_x, scm_make_port_type): Protect scm_ptobs access
with a mutex. Have it be an array of pointers instead of an array of
structures. Adapt users to the new APIs.
(scm_c_make_port_with_encoding): Allocate ports with three words. The
third word is the ptob descriptor.
* libguile/backtrace.c:
* libguile/goops.c:
* libguile/ioext.c:
* libguile/print.c: Adapt to use scm_c_port_type_ref and
SCM_PORT_DESCRIPTOR.
* libguile/ports.h (scm_c_lock_port, scm_c_try_lock_port)
(scm_c_unlock_port): New inline functions.
(scm_t_port): Add a lock field, if threads are enabled. This is a
first step towards threadsafe ports.
* libguile/ports.c (scm_c_make_port_with_encoding): Init the port's
lock.
* libguile/inline.c: Residualize the inline functions from ports.h.
* libguile/tags.h (SCM_HEAP_OBJECT_BASE): New macro. Given a SCM,
returns a pointer to the start of its memory area on the heap.
* libguile/bytevectors.c:
* libguile/fluids.c:
* libguile/foreign.c:
* libguile/gc.h:
* libguile/guardians.c:
* libguile/numbers.h:
* libguile/ports.c:
* libguile/smob.c:
* libguile/struct.c:
* libguile/weak-set.c:
* libguile/weak-table.c:
* libguile/weak-vector.c: Use it.
* libguile/tags.h (SCM_UNPACK_POINTER, SCM_PACK_POINTER): New macros.
The old SCM2PTR and PTR2SCM were defined in such a way that
round-tripping through a pointer could lose precision, even in the
case in which you weren't interested in actually dereferencing the
pointer, it was simply that you needed to plumb a SCM through APIs
that take pointers. These new macros are more like SCM_PACK and
SCM_UNPACK, but for pointer types. The bit representation of the
pointer should be the same as the scm_t_bits representation.
* libguile/gc.h (PTR2SCM, SCM2PTR): Remove support for (old) UNICOS
pointers. We are going to try tagging the SCM object itself in the
future, and I don't think that keeping this support is worth its
cost. It probably doesn't work anyway.
* libguile/backtrace.c:
* libguile/bytevectors.c:
* libguile/continuations.c:
* libguile/fluids.c:
* libguile/foreign.c:
* libguile/gc.h:
* libguile/guardians.c:
* libguile/hashtab.c:
* libguile/load.c:
* libguile/numbers.c:
* libguile/ports.c:
* libguile/smob.c:
* libguile/strings.c:
* libguile/symbols.c:
* libguile/vm.c:
* libguile/weak-set.c:
* libguile/weak-table.c:
* libguile/weak-vector.c: Update many sites to use the new macros.
* libguile/ports.c (scm_c_make_port_with_encoding, scm_c_make_port): New
functions, to replace scm_new_port_table_entry. Use a weak set
instead of a weak table.
(scm_i_remove_port):
(scm_c_port_for_each, scm_port_for_each): Adapt to use weak set.
(scm_i_void_port): Use scm_c_make_port.
(scm_init_ports): Make a weak set.
* libguile/fports.c:
* libguile/ioext.c:
* libguile/r6rs-ports.c:
* libguile/strports.c:
* libguile/vports.c: Adapt to use the new scm_c_make_port API.
* libguile/numbers.c (scm_logand): Fix a type error (comparing a SCM
against an int, when we really wanted to compare the unpacked
fixnum).
* libguile/ports.c (scm_i_set_conversion_strategy_x): Check
scm_conversion_strategy_init, not scm_conversion_strategy.
* libguile/read.c (recsexpr): Fix loops to avoid strange test of SCM
values.
* libguile/async.c:
* libguile/async.h:
* libguile/debug.h:
* libguile/deprecated.c:
* libguile/deprecated.h:
* libguile/evalext.h:
* libguile/gc-malloc.c:
* libguile/gc.h:
* libguile/gen-scmconfig.c:
* libguile/numbers.c:
* libguile/ports.c:
* libguile/ports.h:
* libguile/procprop.c:
* libguile/procprop.h:
* libguile/read.c:
* libguile/socket.c:
* libguile/srfi-4.h:
* libguile/strings.c:
* libguile/strings.h:
* libguile/tags.h:
* module/ice-9/boot-9.scm:
* module/ice-9/deprecated.scm: Remove all deprecated code. CPP defines
that were not previously issuing warnings were changed so that their
expansions would indicate the replacement forms to use,
e.g. scm_sizet__GONE__REPLACE_WITH__size_t.
The two exceptions were SCM_LISTN, which did not produce warnings
before, and the string-filter argument order stuff.
Drops the initial dirty memory usage of Guile down to 2.8 MB on my
machine, from 4.4 MB.
Thanks to Mark H. Weaver for pointing this out.
* libguile/ports.c (CONSUME_PEEKED_BYTE): New macro.
(get_utf8_codepoint): New variable `pt'. Use
`scm_peek_byte_or_eof'/`CONSUME_PEEKED_BYTE' pairs instead of
`scm_get_byte_or_eof'.
* test-suite/tests/ports.test ("string ports")[#xc2 #x41 #x42, #xe0 #xa0
#x41 #x42, #xf0 #x88 #x88 #x88]: Fix to conform to Unicode 6.0.0.
[#xe0 #x88 #x88]: Remove test.
[#xf0 #x80 #x80 #x41]: New test.
* libguile/ports.c (update_port_lf): Handle EOF.
(get_utf8_codepoint, get_iconv_codepoint): New functions.
(get_codepoint): Use them.
(scm_i_set_port_encoding_x): Don't open conversion descriptors when
ENCODING is "UTF-8".
* libguile/print.c (display_string_as_utf8, display_string_using_iconv):
New functions.
(display_string): Use them.
* test-suite/tests/ports.test ("string ports")[#xc2 #x41 #x42]: Add a
note that this is not the wrong behavior per Unicode 6.0.0.
* libguile/arrays.c (scm_i_read_array):
* libguile/backtrace.c (display_backtrace_body):
* libguile/filesys.c (scm_readdir)
* libguile/i18n.c (chr_to_case):
* libguile/ports.c (register_finalizer_for_port):
* libguile/posix.c (scm_nice):
* libguile/stacks.c (scm_make_stack): Clean up a number of
set-but-unused vars. Thanks to Douglas Mencken for the report.
* libguile/numbers.c (scm_log, scm_exp): Fix a few #if cases that should
be #ifdef.