| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
| |
* txr.1: A symbol is not "returned" by the reader; drop that
text. Use the terminology that a token is interned.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We can avoid calling in methods in the by-value nuance
(copy == 0) on types known not to have by-value in semantics.
Basic types have no by-value in.
Pointers inherently have by-value in.
An aggregate has by-value in semantics if any of one
of its members does, otherwise not.
* ffi.c (struct txr_ffi_type): New bitfield member,
by_value_in.
(ffi_ptr_in_in, ffi_ptr_in_d_in): Elite in call if target
type's by_value_in flag is clear.
(ffi_struct_in): Short-circuit to a return if doing by-value,
and the FFI struct type has no by-value semantics.
(ffi_array_in_common): Likewise. In this code change, we
just have to replace the test whether the element type has
an in method with a test of its by_value_in flag.
(make_ffi_type_pointer): Set by_value_in flag to 1, since
pointers have by value in semantics. This is true also of
ptr-in, because a structure passed as an in parameter to a
function via ptr-in could itself contain ptr or ptr-out
elements.
(make_ffi_type_struct): Set the type's by_value_in if
any element type's by_value_in is true.
(make_ffi_type_array): Propagate the by_value_in flag from
the element type to the array type.
(ffi_call_wrap): Calculate the in_pass_needed local flag
from the by_value_in flags of the arguments, not from whether
or not they have an in function. Only call the in function
for arguments which have the flag set.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The theme here is that if a struct or array is
being subject to a by-value in operation, there
is nothing to do for that aggregate itself. So
if there is no corresponding Lisp object, we
should not create one. The caller isn't expecting
it and will throw it away. If it is known that no
element of an aggregate supports by-value semantics,
then the operation should short-circuit, and not
perform a useless loop.
* ffi.c (ffi_struct_in): If the strct parameter is nil,
don't unconditionally make a new structure; do so only
when the copy flag is asserted (by reference semantics).
If there is no Lisp struct object and by value semantics is
in effect, there is no point in doing anything; just
short-circuit to a nil return.
(ffi_array_in_common): If doing by value semantics, and
there is no vector object or the structure element type
has no by value in semantics (such as a basic type),
then short circuit to an early return.
(ffi_array_in): Only do the special string decoding when
reference semantics is in effect; there is no point
in extracting strings back from a by-value struct.
If by-value semantics is in effect, we fall through to
the ffi_array_in_common call even for character types;
but since those types have no by-value in semantics,
that function will just short-circuit, which is what we want.
(ffi_varray_in): If there is no vec, bail out with nil,
regardless of whether this is by value or not.
Just return vec if by-value semantics is in effect; don't
try to update it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (union_s): New symbol variable.
(ffi_find_memb, ffi_memb_not_found): New static functions.
(ffi_union_in, ffi_union_put, ffi_union_get): New static
functions.
(make_ffi_type_union): New static function.
(ffi_struct_compile): Handle union syntax using
ffi_struct_compile to compile the member definitions to types,
and make_ffi_type_union to produce the type node.
(struct uni): New struct type.
(uni_struct, uni_struct_checked): New static functions.
(union_destroy_op, union_mark_op): New static functions.
(union_ops): New static struct.
(make_union_common, make_union_tft): New static functions.
(union_get_ptr, make_union, union_members, union_get,
union_put, union_in, union_out): New functions.
(ffi_init): Initialize union_s. Register intrinsics
make-union, union-members, union-get, union-put, union-in,
union-out.
* ffi.h (union_s, union_get_ptr, make_union, union_members,
union_get, union_put, union_in, union_out): Declared.
* txr.1: Documented unions.
|
|
|
|
|
|
|
|
|
|
|
| |
Upcoming work is going to benefit from a pointer for
navigating from the txr_ffi_type structure to the Lisp object
whose implementation is that structure.
* ffi.c (struct txr_ffi_type): New member, self.
(make_ffi_type_builtin, make_ffi_type_pointer,
make_ffi_type_struct, make_ffi_type_array,
make_ffi_type_enum): Initialize self pointer.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Don't bother creating and filling the ffi_type elements[]
array for a structs or array. Let's punch in the size and
alignment fields with the values we calculate ourselves
already, and set up a dummy elements[] array that contains
only a null terminator.
* ffi.c (struct txr_ffi_type): New member, elements:
one element dummy array that holds a null pointer.
(ffi_type_struct_destroy_op): Do not free ft->elements,
since it isn't dynamically allocated any more.
(ffi_struct_clone, ffi_array_clone): Don't copy the elements
array; just set up a dummy elements array in the copied type.
(make_ffi_type_struct, make_ffi_type_array): Eliminate the
dynamic allocation of the elements array. Point ft->elements
to the dummy array. Set up the ft->size and ft->alignment.
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_float_put): Fix silly range check:
FLT_MIN and FLT_MAX are, of course, both positive.
Also, fix num being used as an argument in the error
diagnostic. It's the address of a C function, not
an object.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (bool_s): New symbol variable.
(ffi_bool_put, ffi_bool_get): New static functions.
(ffi_type_compile): Handle (bool <type>) parametrized type.
(ffi_init_types): Register bool typedef for (bool uchar).
(ffi_init): Initialize bool_s.
* ffi.h (bool_s): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Update registration of cptr-int and
cptr-obj with one optional argument.
* lib.c (cptr_int): New type symbol argument, defaulting
to nil. Also, don't bother defaulting the integer argument;
the function isn't registered for that being optional.
(cptr_obj): New type symbol argument, defaulting to nil.
* lib.h (cptr_int, cptr_obj): Declarations updated.
* txr.1: Documented cptr-int and cptr-obj function changes.
Added discussion of type tag to introductory paragraph.
Also added neglected documentation of the FFI cptr type,
both unparametrized and parametrized.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The problem here is that ensure-stream ignores the mode
argument and decides between "r" and "w". That is incorrect;
the mode could be "a" for append.
The second problem is that the ignored mode strings are
also wrong. For an input pipe, "w" is specified rather than
"r".
* share/txr/stdlib/awk.tl (sys:awk-state ensure-stream): Use
the mode argument. The cases consolidate, because all that
need be distinguished here is file versus pipe.
(sys:awk-mac-let): for the <! redirection (input from pipe),
the mode must be "r", not "w".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the case when the :output clause of the awk macro opens a
stream, it isn't closing it. Why don't we treat such a stream
uniformly with redirections.
* share/txr/stdlib/awk.tl (sys:awk-state :postinit):
If a file is opened for output, then don't just install
this file as self.output. Also place it into the self.streams
hash, identified by using the key (:outf <name>), just
like a (-> "name") redirection. This ensures that it will
be closed when the awk macro terminates. It's also potentially
useful in that output redirections referring to the name will
use the same stream.
* txr.1: Documented that streams opened by :output are
closed, and that they are treated uniformly with redirections.
|
|
|
|
|
|
|
| |
* match.c (h_trailer): Prevent LOG_MATCH call from
being evaluated in failed case, when the position is nil.
This situation triggers an exception, because LOG_MATCH
prints the position as an integer using ~d.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim, protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (do_mp_error): New function.
(num_from_buffer, plus, minus, mul, floordiv, expt, exptmod,
logtrunc, sign_extend, ash, bit): Handle errors from select
MPI functions: those that have the mp_ign attribute.
* ffi.c (unum_carray, num_carray): Likewise.
* rand.c (random): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Using a feature of GCC, we mark some functions with the
warn_unused_result attribute. Specifically, those functions
which could return the MP_TOOBIG overflow error.
* mpi/mpi.h (mp_nign): New macro.
(mp_init_size, mp_add_d, mp_sub_d, mp_mul_d, mp_mul_2,
mp_div_d, mp_div_2, mp_expt_d, mp_add, mp_sub, mp_mul,
mp_mul_2d, mp_sqr, mp_expt, mp_2expt, mp_sqrt, mp_addmod,
mp_submod, mp_mulmod, mp_sqrmod, mp_exptmod, mp_exptmod_d,
mp_lcm, mp_xgcd, mp_invmod, mp_trunc_comp, mp_trunc, mp_shift,
mp_to_double, mp_read_signed_bin, mp_read_unsigned_bin,
mp_read_radix): Functions attributed with unused result
warning.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The main purpose of this patch is to prevent two cases of
numeric overflow.
One is when an arithmetic operation produces a result which
would have more digits than can be represented by mp_size. The
calculation for the digits in the result operand will simply
overflow, resulting in an undersized buffer that is then
overrun.
Another overflow is in calculations which work with bit
indexing. Even if the digits is in range of mp_size, the bit
number is eight times larger and can be out of range.
We can address both problems by clamping integers to have only
so many digits, that every bit has an offset that fits into
mp_size. If mp_size is 32 bits, that means we can still have
bignums that are half a gigabyte, which seems reasonable for
nearly any conceivable application of bignums.
After this patch, we must adjust the code in arith.c and
other places to detect errors, at least out of the functions
that can produce larger integers than their inputs.
* mpi/mpi-types.h (MP_MAX_BITS, MP_MAX_DIGITS): New macro.
* mpi/mpi.c (mp_err_string): New entry corresponding to the
new MP_TOOBIG error.
(mp_init_size, s_mp_grow): Reject, with the MP_TOOBIG error,
attemps to create or grow an mp_int mp_int such that it would
have more digits than MP_MAX_DIGITS.
* mpi/mpi.h (MP_TOOBIG): New macro code.
(MP_LAST_CODE): Redefined to MP_TOOBIG.
|
|
|
|
|
|
|
|
|
|
|
| |
* mpi.c (s_mp_cmp): Rewrite loop as a for with
a bottom test, and the increments in the usual place.
ap and bp aren't decremented if the index is zero.
Ironic to fix this, given that we march through the
stack in the garbage collector.
(s_mp_ispow2): Similar restructuring, with an additional
guard around ix being set up to descend from the
second-to-last digit.
|
|
|
|
| |
* mpi/mpi-config.h (MP_DEFPREC): Change from 16 to 8.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
MPI has a mp_size type for sizing of the digit arrays and some
other uses. It is not consistently used. Moreover, it is
typedef'd as a signed type. The type int is used for
iterating over digits, instead of the matching mpi_size type.
The int type is used as a size argument in some functions,
and in functions that return the number of bits.
This patch makes mp_size unsigned and replaces most uses of
int with a more appropriate type.
Because mp_size is now used for indexing, and is unsigned,
some downward loop termination tests have to be changed;
the always true condition ix >= 0 cannot be used.
* arith.c (width): Use mp_size for local variable which
iterates over digits inside mpi_int object, and for bit
count. Use unum to convert bit count to Lisp integer:
mp_size could be out of range of cnum.
* mpi/mpi-types.h (mp_size): Typedef to unsigned.
(MP_SIZE_MAX): New macro.
(MP_DIGIT_BIT, MP_WORD_BIT): Cast the value to mp_size rather
than to int.
* mpi/mpi.c (s_mp_defprec): Declare variable as mp_size.
(s_mp_setz, s_mp_copy, mp_size, s_highest_bit_mp,
s_mp_set_bit, s_mp_ispow2, s_mp_outlen, mp_set_int,
mp_set_uintptr, mp_set_double_intptr, mp_expt, mp_sqrt,
mp_exptmod, mp_hash, mp_gcd, mp_shift, mp_bit, mp_to_double,
mp_print, mp_read_signed_bin, mp_signed_bin_size,
mp_read_unsigned_bin, mp_unsigned_bin_size,
mp_to_unsigned_bin, mp_to_unsigned_buf, mp_count_bits,
mp_is_pow_two, mp_read_radix, mp_radix_size,
mp_value_radix_size, mp_toradix_case, s_mp_setz, s_mp_copy,
mp_size, s_highest_bit_mp, s_mp_set_bit, s_mp_mul_2,
s_mp_mod_2d, s_mp_div_2d, s_mp_div_d, s_mp_sqr, s_mp_sqr,
s_mp_div, s_mp_cmp, s_mp_cmp_d, s_mp_ispow2, s_mp_outlen): In
all these functions, use size_t for external size, mp_size for
number of digits and bits, in return values, arguments and
local variables. Tests in descending loops are adjusted for
unsigned logic.
* mpi/mpi.h (mp_get_prec, mp_set_prec, mp_read_signed_bin,
mp_signed_bin_size, mp_read_unsigned_bin,
mp_unsigned_bin_size, mp_to_unsigned_buf, mp_count_bits,
mp_is_pow_two, mp_radix_size, mp_value_radix_size):
Declarations updated.
* mpi/mplogic.c (mpl_not, mpl_and, mpl_or, mpl_xor, mpl_rsh,
mpl_lsh, mpl_num_set, mpl_num_clear, mpl_parity): Just like
in mpi.c
* rand.c (make_random_state): Use mp_size and ucnum for local
variables holding digit and bit counts.
* sysif.c (off_t_num): Use mp_size for digit count.
|
|
|
|
|
|
|
|
|
| |
mp_shift takes an int argument, but we decode bits to
a cnum, leaving possible room for overflow, such as
when cnum is 64 bits and int is 32. If the value
* arith.c (ash): Check that the value is in the range
of INT_MIN to INT_MAX.
|
|
|
|
|
| |
* arith.c (ash): Refer to ash in error messages rather than
ashift.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Multi-line expressions can now be entered just using
Enter for line breaks without Ctrl-V.
Multi-line mode becomes default.
* parser.c (is_balanced_line): New static function.
(repl): Install is_balanced_line as enter callback
in linenoise object.
(parse_init): Default *listener-multi-line-p* variable to t.
* txr.1: Documentation about multi-line mode updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The idea is that when the user types Enter to submit a line,
it can be checked whether it is complete syntax using a
callback. If the callback indicates that the syntax is
incomplete (there are open expressions, string literals or
whatever), then Enter is inserted verbatim. This is active
in multi-line mode only.
* linenoise.c (struct lino_state): New members, enter_callback
and ce_ctx.
(lino_set_enter_cb): New function.
(edit): If enter is issued, and multi-line mode is in effect,
and there is an enter callback, then call it. If the callback
returns false, then just insert the character.
* linenoise.h (lino_enter_cb_t): New typedef.
(lino_set_enter_cb): Declared.
|
|
|
|
|
|
| |
* lib.c (toseq, reverse, nreverse): Classify the
sequence with seq_info, and simplify the code by
just dealing with the sequence kinds.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This will help simplify writing generic sequence code, while
allowing lists and vectors to be handled specially.
* lib.h (enum seq_kind, seq_kind_t): New enum and typedef.
(struct seq_info, seq_info_t): New struct and typedef.
(seq_kind_tab, seq_info): Declared.
* lib.c (seq_kind_tab): New global array.
(seq_info): New function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With this change, nreverse is possible on a struct,
if it has lambda, lambda-set and length methods.
* lib.c (length_s): New symbol variable.
(length): Check for length method and call it,
in preference to checking for car method and falling
back on cdr-based length.
(empty): If object has a length method, call it and
compare result to zero.
(obj_init): Initialize length_s.
* txr.1: Documented. We now have the concepts of structs
being vector-like sequences or list-like sequences.
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (ref, refset): Check for lambda and lambda-set,
respectively, and use it.
* txr.1: Documented.
* tests/012/aseq.tl (add lambda): Fix previously unused
broken method which now causes test to go into infinite
recursion.
|
|
|
|
|
|
|
|
| |
* lib.c (reverse): Support COBJ via list
operations, but handle carray via vector case.
(nreverse): Support COBJ via vector case.
This will work for carray. Fixes are needed in
ref and refset to work with structs.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (copy_carray): New function
(ffi_init): Register copy-carray intrinsic.
* ffi.h (copy_carray): Declared.
* lib.c (copy): Call copy_array for carray objects.
* txr.1: Documented copy-carray and updated
copy description.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (put_carray, fill_carray): New functions.
(ffi_init): put-carray and fill-carray intrinsics
registered.
* ffi.h (put_carray, fill_carray): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (carray_unum, carray_num, unum_carray, num_carray):
New functions.
(ffi_init): New intrinsics registered: carray-unum,
carray-num, unum-carray, num-carray.
* ffi.h (carray_unum, carray_num, unum_carray, num_carray):
Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* arith.c (sign_extend): After taking the two's complement
which works at the granularity of digits, not the exact
number of bits, we must truncate the number to the
exact number of bits before negating. Otherwise we end up
with an excessively large value. For instance if a bignum
like #x80... is sign extended tightly to the upper
1 bit, the resulting value is something like #-xFFFF80...,
rather than #x-80... as it should be. There are extra
1 bits padding up to the bignum digit. These must be
chopped away.
|
|
|
|
|
|
|
|
| |
* mpi/logtab.h, mpi/mpi-config.h mpi/mpi-types.h mpi/mpi.c,
mpi/mpi.h mpi/mplogic.c mpi/mplogic.h: Reformatted comments.
Removed useless comments. Removed superfluous blank lines and
whitespace. Added space between C keywords if, for, while,
sizeof and opening parens. Removed #if 0 blocks. Tabs to spaces.
|
|
|
|
| |
* txr.c (banner): Text updated.
|
|
|
|
|
| |
* linenoise/linenoise.c (show_help): New static function.
(edit): Call show_help on Ctrl-X ?.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (ffi_set_entries): Register carray-sub
for autoload.
* share/txr/stdlib/ffi.tl (carray-sub): New place
macro, aliases to sub. This is not 100% correct since
that means it will admit non-carray objects, but
the alternative is to clone the entire sub expander
with a few changes, or else factor out sub expansion
into a shared routine. Bleh ...
* txr.1: Documented. We don't cover up the ruse we
perpetrated, and reveal that it's just a place macro
targetting sub.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
TXR Lisp doesn't autoload the definition of places.
For instance if a (set (foo x) y) appears out of the
blue and foo is keyed for autoload, it doesn't happen.
The right place to fix this is to do the autload check
in the place macro expander, since every place form is
tried as a macro.
We need to expose the lisplib_try_load function as a Lisp
intrinsic.
* lisplib.c (lisplib_init): Register sys:try-load
intrinsic, mapped to lisplib_try_load.
* share/txr/stdlib/place.tl (sys:get-place-macro):
New function.
(sys:pl-expand): Use sys:get-place-macro instead of
direct lookup in *place-macro* hash. The new function
tries to autoload the symbol if it finds no place
macro for it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct): When there is no room in the
current bitfield, two mistakes are made. When bit_offs is
reset to zero in this case, the dependent variable bits_alloc
that was calculated from it (bits allocated to current unit)
must also be reset. The subsequent shift depends on it.
Secondly, when we establish the memb[i].offs field, that
must come from offs, not from unit_offs, because unit_offs
is always the base offset of the existing cell (which doesn't
have room for the new bitfield in this case); the main offset
variable offs is what gets gets adjusted to the cell which has
room for the new bitfield.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure, txr.1: Bumped version and date.
* share/txr/stdlib/ver.tl: Likewise.
* txr.vim, tl.vim, protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
| |
* ffi.c (ffi_generic_sbit_put, fi_generic_sbit_get,
ffi_generic_ubit_put, fi_generic_ubit_get): Add needed
coerce from zalloca to mem_t *.
(make_ffi_type_struct): Fix signed/unsigned comparison.
* lib.c (vector): Fix signed/unsigned comparison.
|
|
|
|
|
| |
* genprotsym.txr: Sort groups so that the protsym.c
deltas, going forward, are more stable.
|
|
|
|
|
|
| |
* genprotsym.txr: use @(first) directive trick to
eliminate leading blank lines in front of items
that are not controlled by a preprocessor symbol.
|
|
|
|
|
|
|
|
|
| |
* buf.c (bufp): New function.
(buf_init): Registered bufp intrisic.
* buf.h (bufp): Declared.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
| |
* share/txr/stdlib/conv.tl (sys:conv-let): New
local functions c and cz, using the new #\c
radix conversion.
* txr.1: Documented new extension under the fconv
awk macro. Also fixed a typo here; the b conversion
was exemplified as (c str).
|
|
|
|
|
|
|
|
|
| |
* lib.c (int_str): Support #\c base, recognizing
0x as hex and leading 0 as octal. We don't rely on
the wcstol function's ability to do this conversion,
but scan it ourselves.
* txr.1: Documented.
|
|
|
|
|
| |
* txr.1: Put carray and buf cases into the description of
the indexing notation under the dwim operator.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (make_ffi_type_struct): Use chk_xalloc instead of
chk_malloc.
(make_ffi_type_array): Use chk_xalloc. Since there are
multiple callers, take a self argument to pass down to
chk_xalloc.
(ffi_type_compile): Pass self down to make_ffi_type_array.
(ffi_make_call_desc): Use chk_xalloc.
(carray_ensure_artype): Take a self argument and pass down to
make_ffi_type_array.
(carray_get_common, carray_put_common): Pass self down to
carray_ensure_artype.
|
|
|
|
|
|
|
|
|
| |
* stream.c (open_process): Check that manipulations of nargs
do not overflow int type. Use chk_xalloc. Allocation is
done before pipe so we have no file descriptors to clean up
if chk_xalloc throws.
(run): In both versions of run, check that manipulations of
nargs don't overflow int and use chk_xalloc.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* sysif.c (excec_wrap): Check that our nargs manipulation
doesn't exceed INT_MAX. Use chk_xalloc to allocate the
argument vector, providing an overflow check. Use self
variable in place function name embedded in literal.
(getgroups_wrap): Use chk_xalloc instead of chk_malloc,
so multiplication overflow is checked. Use self variable
in place function name embedded in literal.
(setgroups_wrap): Revamp existing overflow check. Use
ucnum for the size, check that it can convert to size_t
and back without loss of value, and use chk_xalloc
instead of chk_malloc.
|