* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (scm_bootstrap_intrinsics): Remove the atomic
intrinsics, as the JIT no longer needs them.
* libguile/vm-engine.c (VM_NAME): Inline the intrinsics.
* libguile/atomics-internal.h (scm_atomic_compare_and_swap_scm): Change
to use same API as atomic-box-compare-and-swap!.
* libguile/intrinsics.c (atomic_compare_and_swap_scm): Remove loop, as
we're using the strong variant now.
* libguile/async.c (scm_i_async_pop, scm_i_async_push): Adapt to new API
of scm_atomic_compare_and_swap_scm.
* libguile/i18n.c (SCM_MAX_ALLOCA): New macro.
(SCM_STRING_TO_U32_BUF): Accept an additional variable to remember
whether we used malloc to allocate the buffer. Use malloc if the
allocation size is greater than SCM_MAX_ALLOCA.
(SCM_CLEANUP_U32_BUF): New macro.
(compare_u32_strings, compare_u32_strings_ci, str_to_case): Adapt.
* libguile/strings.c (SCM_MAX_ALLOCA): New macro.
(normalize_str, unistring_escapes_to_r6rs_escapes): Use malloc if the
allocation size is greater than SCM_MAX_ALLOCA.
* test-suite/tests/i18n.test, test-suite/tests/strings.test: Add tests.
Previously, 'put-u8' used textual I/O to write a single character,
relying on the usual practice of setting the port encoding to ISO-8859-1
for binary ports.
* libguile/r6rs-ports.c (scm_put_u8): Use 'scm_c_write', not 'scm_putc'.
* libguile/numbers.c (scm_exact_integer_sqrt, scm_sqrt)
(exact_integer_is_perfect_square, exact_integer_floor_square_root):
Where it is trivial to do so, use GMP's low-level mpn functions to
avoid heap allocation.
This reverts the change to SCM_MAKE_CHAR made in the previous commit
63818453ad, which used an arithmetic trick
to avoid evaluating its argument more than once.
Here, we restore the previous implementation of SCM_MAKE_CHAR, which
evaluates its argument twice. Instead, we introduce a new inlinable
function 'scm_c_make_char' and replace uses of SCM_MAKE_CHAR with calls
to 'scm_c_make_char' where appropriate.
* libguile/chars.h (scm_c_make_char): New inline function.
* libguile/inline.c: Include chars.h.
* libguile/srfi-13.c (REF_IN_CHARSET, scm_string_any, scm_string_every)
(scm_string_trim, scm_string_trim_right, scm_string_trim_both)
(scm_string_index, scm_string_index_right, scm_string_skip)
(scm_string_skip_right, scm_string_count, string_titlecase_x)
(string_reverse_x, scm_string_fold, scm_string_fold_right)
(scm_string_for_each, scm_string_filter, scm_string_delete):
Use 'scm_c_make_char' instead of 'SCM_MAKE_CHAR' in cases where the
argument calls a function.
* libguile/chars.c (scm_char_upcase, scm_char_downcase, scm_char_titlecase),
libguile/ports.c (scm_port_decode_char),
libguile/print.c (scm_simple_format),
libguile/read.c (scm_read_character),
libguile/strings.c (scm_string_ref, scm_c_string_ref),
The motivation for this change is that SCM_MAKE_CHAR is sometimes passed
an expression that involves a procedure call that is not always trivial.
In other cases, the results are not guaranteed to be the same both
times, which could lead to the creation of invalid SCM objects.
* libguile/chars.h (SCM_MAKE_CHAR): Reimplement.
* libguile/scmsigs.c (signal_delivery_thread): Call scm_async_tick to
give any pending asyncs a chance to run before we block indefinitely
waiting for a signal to arrive.
Reported by Jeffrey Walton <noloader@gmail.com> in
<https://lists.gnu.org/archive/html/guile-devel/2019-03/msg00001.html>.
Note that C11 section 7.1.4 (Use of library functions) states that:
"unless explicitly stated otherwise in the detailed descriptions [of
library functions] that follow: If an argument to a function has an
invalid value (such as ... a null pointer ...) ..., the behavior is
undefined." Note that 'strxfrm' is an example of a standard C function
that explicitly states otherwise, allowing NULL to be passed in the
first argument if the size argument is zero, but no similar allowance is
specified for 'memcpy' or 'memcmp'.
* libguile/bytevectors.c (scm_uniform_array_to_bytevector): Call memcpy
only if 'byte_len' is non-zero.
* libguile/srfi-14.c (charsets_equal): Call memcmp only if the number of
ranges is non-zero.
* libguile/stime.c (setzone): Pass 1-character buffer to
'scm_to_locale_stringbuf', instead of NULL.
* libguile/strings.c (scm_to_locale_stringbuf): Call memcpy only if the
number of bytes to copy is non-zero.
The newlib C library (used in Cygwin) has alternative names for
nl_langinfo GNU extensions
* configure.ac (_NL_NUMERIC_GROUPING): new test
* libguile/i18n.c (INT_CURR_SYMBOL, MON_DECIMAL_POINT, MON_THOUSANDS_SEP)
(MON_GROUPING, POSITIVE_SIGN, NEGATIVE_SIGN, GROUPING, INT_FRAC_DIGITS)
(FRAC_DIGITS, P_CS_PRECEDES, P_SEP_BY_SPACE, N_CS_PRECEDES, N_SEP_BY_SPACE)
(P_SIGN_POSN, N_SIGN_POSN, INT_P_CS_PRECEDES, INT_P_SEP_BY_SPACE)
(INT_N_CS_PRECEDES, INT_N_SEP_BY_SPACE, INT_P_SIGN_POSN, INT_N_SIGN_POSN)
[HAVE_DECL__NL_NUMERIC_GROUPING]: map to newlib C constants, when present
Some operating systems require a O_BINARY flag.
* libguile/filesys.c (scm_i_mkstemp): Don't mask out O_BINARY flag
* test-suite/tests/posix.test ("binary mode honored"): new test
Partially fixes <https://bugs.gnu.org/33044>.
Reported by Tom de Vries <tdevries@suse.de>.
* libguile/random.c (scm_seed_to_random_state): Use 'scm_to_utf8_string'
(or 'scm_to_latin1_string' for a narrow string, for compatibility) to
convert the string into raw bytes for use by 'scm_c_make_rstate'. Make
sure the length in bytes fits within an 'int'.
Partial fix for <https://bugs.gnu.org/33044>.
Reported by Tom de Vries <tdevries@suse.de>.
Fix several instances of the mistake of using 'scm_from_locale_*' for C
strings that originally came from a C string literal. Change several
uses of 'scm_from_latin1_*' as well, to promote the practice of writing
code that works for arbitrary C string literals.
Also add missing years to the copyright notices of changed files, based
on the git history.
* libguile/debug-malloc.c, libguile/deprecation.c, libguile/error.c,
libguile/eval.c, libguile/expand.c, libguile/extensions.c,
libguile/filesys.c, libguile/init.c, libguile/load.c,
libguile/modules.c, libguile/pairs.c, libguile/posix.c,
libguile/print.c, libguile/random.c, libguile/read.c,
libguile/regex-posix.c, libguile/snarf.h, libguile/srfi-13.c,
libguile/stacks.c, libguile/stime.c, libguile/strports.c,
libguile/values.c: Use 'scm_from_utf8_*' where appropriate.
Fixes <https://bugs.gnu.org/21901>.
Reported by Zefram <zefram@fysh.org>.
* libguile/numbers.c: Add another top-level 'verify' to ensure that
LONG_MIN is not a fixnum.
(scm_ash, scm_round_ash): Ensure that when the shift count is LONG_MIN,
it is not handled via the normal code path, to avoid signed overflow
when the shift count is negated.
* test-suite/tests/numbers.test: Add tests.
This is a followup to commit 011aec7e24.
When rounding, right shifting a negative integer by a huge shift count
results in 0, not -1.
* libguile/numbers.c: Add top-level 'verify' to ensure that the
assumptions in 'scm_ash' and 'scm_round_ash' are valid.
(scm_round_ash): In the case that handles huge right shifts, require
that the shift count _exceeds_ the integer length, and return 0 instead
of -1.
* test-suite/tests/numbers.test: Adjust tests accordingly.
Fixes <https://bugs.gnu.org/32644>.
Reported by Stefan Israelsson Tampe <stefan.itampe@gmail.com>.
The need for this arose because the type inferrer for 'ursh' sometimes
passes (- 1 (expt 2 64)) as the second argument to 'ash'.
* libguile/numbers.c (scm_ash, scm_round_ash): Gracefully handle several
cases where the shift count does not fit in a C 'long'.
* test-suite/tests/numbers.test: Add tests.
Fixes <https://bugs.gnu.org/32938>.
Reported by Josh Datko <jbd@cryptotronix.com>.
* libguile/validate.h (SCM_VALIDATE_LIST_COPYLEN)
(SCM_VALIDATE_NONEMPTYLIST_COPYLEN): Use '!=' instead of '>=' to
validate the result of 'scm_ilength' after it has been stored in
the user variable 'cvar'.
* test-suite/tests/bytevectors.test: Add tests. Use '#:use-module'
instead of ':use-module' in 'define-module' form.
* libguile/boolean.c (scm_nil_p): Improve docstring.
* doc/ref/api-languages.texi (Nil): Add documentation for 'nil?', along
with a description of how Elisp interprets Scheme booleans and
end-of-list.
Fixes <https://bugs.gnu.org/32786>.
'scm_atomic_compare_and_swap_scm' is a thin wrapper around
'atomic_compare_exchange_weak' (where available), and therefore it may
spuriously fail on some platforms, leaving the atomic object unchanged
even when the observed value is equal to the expected value. Since
'scm_atomic_compare_and_swap_scm' returns both a boolean result and the
observed value, the caller is able to detect spurious failures when
using that API.
'atomic-box-compare-and-swap!' presents a simpler API, returning only
the observed value. The documentation advises callers to assume that
the exchange succeeded if the observed value is 'eq?' to the expected
value. It's therefore not possible to report spurious failures with
this API.
'atomic-box-compare-and-swap!' uses 'scm_atomic_compare_and_swap_scm',
and prior to this commit would simply ignore the boolean result and
return the observed value. In case of spurious failures, the caller
would legitimately conclude that the exchange had succeeded.
With this commit, 'atomic-box-compare-and-swap!' now retries in case of
spurious failures.
* libguile/atomic.c (scm_atomic_box_compare_and_swap_x): If
'scm_atomic_compare_and_swap_scm' returns false and the observed value
is equal to 'expected', then try again.
* libguile/intrinsics.c (atomic_compare_and_swap_scm): Ditto.