| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lisplib.c (arith_each_instantiate, arith_each_set_entries): New
functions.
(each_prod_set_entries): Add sum-each-prod, sum-each-prod*,
mul-each-prod and mul-each-prod* as autoload triggers for
each-prod.tl, where those macros are now defined.
(lisplib_init): Register autoloading of arith-each.tl via the
two new functions.
* stdlib/arith-each.tl: New file.
* stdlib/each-prod.tl (sys:expand-each-prod*): Handle sum-each-prod* and
mul-each-prod* in the same way, by mapping to their parallel binding
counterparts.
(sys:expand-arith-each-prod): New function.
(sym-each-prod, mul-each-prod, sum-each-prod*, mul-each-prod*): New
macros.
* tests/016/arith.tl: New tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (psquare.o): New object file.
* arith.c (psq_ops): New static structure.
(quant_fun): New static function.
(quantile): New function.
(arith_init): Register quantile intrinsic.
* arith.h (quantile): Declared.
* psquare.c, psquare.h: New files.
* tests/016/arith.tl: New tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
| |
* txr.1: To begin a troff line with a period that is to be
treated as literal, we use \& before that dot, not simply \.
This was giving warnings and not rendering properly.
The \& produces good output in man, HTML and PDF.
|
|
|
|
| |
* txr.1: Remove stray comment from string-get-code example.
|
|
|
|
|
|
|
|
| |
* vm.c (struct vm_closure): Use the FLEX_ARRAY macro to define
the trailing array at the end of the structure instead of
hard-coding [1].
* struct.c (struct struct_inst): Likewise.
|
|
|
|
| |
* vm.c (vm_desc_nlevels): vm_desc_nlevels -> vm-desc-nlevels.
|
|
|
|
| |
* lib.c (cmp_str): Fix self name and use it in uw_throwf call.
|
|
|
|
|
|
|
| |
Calling maprodo with one list argument would fall back on mappend
rather than mapdo.
* eval.c (maprodo): mappendv -> mapdov.
|
|
|
|
|
| |
* txr.1: Interchange the first arguments of buf-str and str-buf,
and their descriptions also.
|
|
|
|
|
|
| |
* txr.1: Fix typos in .meIP and .mets lines. Fix a .code that
should be .codn. Add missing closing parenthesis in description
of greater function. Unparenthesize make-random-state in a .code.
|
|
|
|
|
| |
* stdlib/compiler.tl (compiler comp-fun-form): Reduce
single-argument logior and logand calls to just the argument.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/defset.tl (set-mask, clear-mask): New update macros.
* stdlib/optimize.tl (calc-liveness): Use the new macros.
* stdlib/socket.tl (sys:str-inaddr-net-impl, str-in6addr-net):
Same.
* stdlib/termios.tl (set-iflags, set-oflags, set-cflags,
set-lflags, clear-iflags, clear-oflags, clear-cflags,
clear-lflags): Same.
* lisplib.c (defset_set_entries): Add set-mask and clear-mask
to autoload symbols for defset.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
At optimization level 2 or higher, an issue occurs whereby
code generation exhibits instabilities. The same code is
compiled slightly differently (but not incorrectly) depending
on irrelevant circumstances, due to some different registers
being used.
* stdlib/compiler.tl (compiler eliminate-frame): Do not free
the newly allocated t-registers inside a dohash loop.
We have a separate list of them in order; just hand that off
to free-tregs. The dohash loop is not ordered, because it
traverses a hash, which is keyed by object identities; i.e.
machine addresses assigned by memory allocation.
|
|
|
|
|
|
|
|
|
| |
* lib.c (si_vec_ops): This must be initialized with
seq_iter_ops_init_nomark, since it uses a cnum index, and not
a val iter; the seq_iter_mark_op will pass the cnum bit
pattern to gc_mark an cause a crash.
(si_null_ops): While we are at it, this should also use
seq_iter_ops_init_nomark, because it->ui.iter is always nil.
|
|
|
|
|
|
|
|
|
| |
* hash.c (copy_hash): The order of allocating the hash object
and vector is incorrect. The hash must be allocated last, like
it is in do_make_hash and make_similar_hash. If the vector is
allocated after the hash, it can trigger gc, and then the
garbage collector will traverse the uninitialized parts of the
hash object.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The new sock-opt and sock-set-opt functions are wrappers around
getsockopt and setsockopt, respectively.
All POSIX socket options are registered. Platform-specific
options may be added in the future.
* ffi.c (sock_opt, sock_set_opt): New functions.
(ffi_init): Register sock-opt, sock-set-opt, sol-socket,
ipproto-ip, ipproto-ipv6, ipproto-tcp, ipproto-udp,
so-acceptconn, so-broadcast, so-debug, so-dontroute, so-error,
so-keepalive, so-linger, so-oobinline, so-rcvbuf, so-rcvlowat,
so-rcvtimeo, so-reuseaddr, so-sndbuf, so-sndlowat, so-sndtimeo,
so-type, ipv6-join-group, ipv6-leave-group, ipv6-multicast-hops,
ipv6-multicast-if, ipv6-multicast-loop, ipv6-unicast-hops,
ipv6-v6only, tcp-nodelay.
* lisplib.c (sock_set_entries): Add sock-opt and sock-set-opt.
* stdlib/socket.tl (sock-opt): Define as syntactic place.
* tests/014/socket-misc.tl: New cases, for sock-opt.
(set-and-get): New macro.
* txr.1: Documented. Also, mention that sock-bind enables
so-reuseaddr.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
| |
* tests/014/socket-misc.tl: Test that we can perform a place
update operation on a (sock-peer s) place.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Paul A. Patience reports a regression in
3d5d525eb525cfad8f643917c31e3d9fedce2874, whereby the code
marked with #if SOCK_NONBLOCK || SOCK_CLOEXEC is being
excluded by the preprocoessor, and so those flags are not
being cleared from the socket type that we retain.
This is because these preprocessor symbols are not necessarily
integer constants. They may expand to C enum identifiers,
in which case, in preprocessor expressions they appear to take
on the value zero.
* socket.c (open_socket, socketpair_wrap): Use the if
statement to test for SOCK_NONBLOCK or SOCK_CLOEXEC being
nonzero, rather than a preprocessor #if. This should still be
optimized away as unreachable code if they are zero.
* tests/014/socket-misc.tl: New file.
|
|
|
|
|
| |
* stdlib/socket.tl (sock-peer): Remove excess apostrophe in
getter.
|
|
|
|
|
|
|
|
|
| |
* txr.1: use-symbol -> use-sym; socket-open -> open-socket;
af-inet -> af-unix in description of open-socket; r+ -> r+b in
description of sock-accept; get-obj -> fill-obj in description of
fill-obj; offs -> offset in description of carray-buf; caddr-ref
-> carray-ref; caddr-refset -> carray-refset; fix int-carray's
argument list.
|
|
|
|
|
|
|
|
|
|
| |
The open_socket function was not checking the result of the
socket call for failure, which would cause datagram socket
streams to be initialized with an invalid file descriptor (-1)
and, when opening stream sockets, throw an error not
representative of the actual problem.
* socket.c (open_socket): Throw exception if socket call fails.
|
|
|
|
| |
* ffi.c (mmap_op): mmaped -> mmapped.
|
|
|
|
|
|
|
| |
* stdlib/match.tl (match-pat-error, match-error): New functions.
(match, match-ecase): Generate more compact code which just
calls match-pat-error rather than throwf, and doesn't contain any string
literals.
|
|
|
|
|
|
|
|
| |
* struct.c (lookup_slot): Do not repeat the slot lookup logic
for the case when the symbol's slot_cache must be boostrapped,
which only happens exactly once in the life of a symbol. Just
allocate the cache if necessary and fall through to the
have-cache case.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As reported by Paul A. Patience, GCC 11 warns about situations
in a few places where we do args_decl(args, 0) to allocate an
absolutely empty argument list object.
(This by the way, is only done in places where we are
absolutely sure that the function we call will not be
accessing the arguments. The usual rule is that there have
to be at least ARGS_MIN arguments allocated, currently 4,
and code relies on that being the case! So the places which
call args_decl(args, 0) are coded carefully, checking that
args is not passed anywhere where ARGS_MIN space is
required.)
Anyway, in the 0 case, the val arg[1] member of struct args is
not allocated at all, because we call alloca(offsetof (struct
args, arg)). Now GCC 11 notices this and complains that
accesses to the other members like args->fill or args->list
are using a struct that has not been entirely allocated. This,
even though those members lie entirely within the allocated
area.
The fix for this is two faceted. Firstly, on C99, this
diagnostic goes away if we make one simple change: declare
the arg array as a flexible array member: val arg[].
However, we still support C90 in maintainer mode. So in
maintainer mode, we stick with the 1. But we ensure that the
places which call args_decl(args, 0) will pass 1 instead of 0,
so the whole structure is allocated.
* lib.h (FLEX_ARRAY): New macro: empty definition in C99 or
later, otherwise 1.
* args.h (struct args): Declare the size of the arg member
using the new FLEX_ARRAY macro from lib.h.
(ARGS_ABS_MIN): New macro, the absolute args minimum: zero in
C99 mode, 1 in maintainer C90 mode.
* ffi.c (ffi_struct_in, ffi_struct_get, make_zstruct): Use
ARGS_ABS_MIN instead of 0 when preparing dummy args for
make_struct call.
* struct.c (struct_from_plist, struct_from_args,
make_struct_lit): Use ARGS_ABS_MIN instead of zero when
preparing dummy args for make_struct_impl or make_struct call.
|
|
|
|
|
|
|
| |
* sysif.c (poll_wrap): April 23, 2020 commit
7fbf6b853893f65193ea9c81cf467be08c651244 left behind some
stray free calls, which happen only in some error cases.
Reported by Paul A. Patience, by way of GCC 11 testing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Basic idea: when we throw an exception that pertains to a
system error which has an errno code, we can stick the errno
into the memory area of the character string, into the wchar_t
that immediately follows the null terminator. We can do this
because strings track their actual allocation size.
A pair of setter/getter functions to set and retrieve this
value are provided, and all functions in the code which can
set such a code are updated to do so, simply by calling the
newly added uw_ethrowf that drop-in replaces for uw_throwf.
* lib.[ch] (string_set_code, string_get_code): New functions.
* unwind.[ch] (uw_ethrowf): New function.
* eval.c (eval_init): Register string-set-code and
string-get-code intrinsics.
* ftw.c (ftw_wrap): Switch to uw_ethrowf.
* parser.c (open_txr_file): Likewise.
* socket.c (dgram_overflow): Store the ENOBUFS error in errno,
and use uw_ethrowf instead uw_throwf.
(dgram_get_byte_callback, dgram_flush, sock_bind, to_connect,
open_sockfd, sock_connect, sock_listen, sock_accept,
sock_shutdown, sock_timeout, socketpair_wrap): Switch to
uw_ethrowf.
* stream.c (dev_null_get_fd, stdio_maybe_read_error,
stdio_maybe_error, stdio_close, pipe_close, open_directory,
open_file, open_fileno, open_tail, fds_subst,
open_subprocess, open_command, remove_path, rename_path,
tmpfile_wrap, mkdtemp_wrap, mkstemp_wrap): Switch to uw_ethrowf.
* sysif.c (mkdir_wrap, ensure_dir, chdir_wrap, getcwd_wrap,
rmdir_wrap, mknod_wrap, mkfifo_wrap, chmod_wrap, do_chown,
symlink_wrap, link_wrap, readlink_wrap, close_wrap, val
exec_wrap, stat_impl, do_utimes, pipe_wrap, poll_wrap,
getgroups_wrap, setuid_wrap, seteuid_wrap, setgid_wrap,
setegid_wrap, setgroups_wrap, getresuid_wrap, setresuid_wrap,
setresgid_wrap, crypt_wrap, uname_wrap, opendir_wrap,
getrlimit_wrap, setrlimit_wrap): Likewise.
* termios.c (tcgetattr_wrap, tcsetattr_wrap, tcsendbreak_wrap,
tcdrain_wrap, tcflush_wrap, tcflow_wrap): Likewise.
* tests/018/errno.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
| |
* unwind.[ch] (uw_errorf): Function removed.
|
|
|
|
|
|
|
|
| |
* lib.c (string_extend, string_finish): When we update the alloc value
in the string, we should be using num, because the cnum value is not
necessarily in the fixnum range. That's the whole reason we are using
the set macro: because the assigned value could be a heap-allocated
bignum. Which it will never be, if we use num_fast.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register string-finish intrinsic.
* lib.c (string_finish): New function.
* lib.h (string_finish): Declared.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A Boolean optional argument to string-extend indicates whether
this is likely the last call to string-extend, so memory can
be trimmed accordingly.
* eval.c (eval_init): Update string-extend registration.
* filter.c (trie_filter_string): Pass nil for new argument of
string_extend.
* lib.c (str_seq, replace_str,
lazy_str_force, lazy_str_force_upto): Pass nil for new
argument of string_extend.
(rem_impl, remove_if, separate): Pass t for new argument of
string_extend on last iteration, nil otherwise.
(string_extend): Implement new third argument, defaulted to
nil. Switch from chk_grow_vec to the more specific chk_wrealloc,
which simplifies the code.
* lib.h (string_extend): Declaration updated.
* parser.y (litchars): Pass t as last argument of
string_extend since we know syntactically that these
reductions finalize the string.
(restlitchar): Pass nil as the last argument of string_extend,
since we know syntactically that it isn't the last.
* regex.c (scan_until_common): Pass nil for new argument of
string_extend.
* txr.1: Documented.
|
|
|
|
|
|
| |
* Makefile (tst/tests/019/%): Clear TXR_DBG_OPTS for this
recently introduced directory, so txr isn't run with
--gc-debug.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A number of functions take an argument which is a ffi type.
Typically, this argument is produced using by a
ffi-type-compile call which is produced by the ffi macro. But
this ffi-type-compile call is invoked at run time, each time
such a function is called. A solution for this is to have the
ffi macro hoist the compilation to load time.
* stdlib/ffi.tl (ffi): Add load-time wrapping to generated
expression.
* txr.1: Updated correspondence between (ffi ...) form and
equivalent (ffi-type-compile form).
|
|
|
|
|
|
|
|
| |
* socket.c (SOCK_NONBLOCK, SOCK_CLOEXEC): #define these as 0 if
they are missing.
(open_socket, socketpair_wrap): Clear the SOCK_NONBLOCK and
SOCK_CLOEXEC flags in a single operation instead of two. Use C
native arithmetic instead of Lisp logand and lognot.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The SOCK_NONBLOCK and SOCK_CLOEXEC non-type bits are a
convenience allowed by the socket and socketpair functions, but
they prevent simple comparisons with the actual socket types
SOCK_STREAM, SOCK_DGRAM, etc.
Before this commit, opening datagram sockets with any of these
bits ORed into the type would result in TXR not realizing that
such sockets were datagram sockets because the type would be
compared directly with SOCK_DGRAM.
Various problems would ensue, such as calling listen on a
datagram socket.
This commit clears the SOCK_NONBLOCK and SOCK_CLOEXEC bits after
calling socket or socketpair so that the socket streams get the
actual socket type.
A potentially better solution would be to manually define
SOCK_TYPE_MASK as 0xF (because although Linux defines it as such
in include/linux/net.h, it doesn't export it to userspace) and
AND it with the socket type, because clearing SOCK_NONBLOCK and
SOCK_CLOEXEC will not be enough if new flags are added in the
future, and it's probably more likely for that to happen than for
SOCK_TYPE_MASK to be changed.
* socket.c (open_socket, socketpair_wrap): Clear the
SOCK_NONBLOCK and SOCK_CLOEXEC bits from the socket type after
calling socket or socketpair, and before initializing the socket
streams.
|
|
|
|
|
|
|
|
|
|
| |
* socket.c (dgram_set_sock_peer): set-sock-peer -> sock-set-peer.
(sock_bind, to_connect, sock_accept, socketpair_wrap): Use ~a and
self in uv_throwf calls.
(to_connect): Add colon after self in a uv_throwf call not
reporting "failed".
(sock_listen): Remove colon after self from uv_throwf call
reporting "failed".
|
|
|
|
| |
* rand.c: Remove redundant inclusion of buf.h.
|
|
|
|
|
|
|
|
| |
The optional type argument of carray-uint and carray-int was
documented as defaulting to uint, but it actually defaults to
uchar.
* txr.1: uint -> uchar.
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c: Include <sys/socket.h> if we HAVE_SOCKETS.
(ffi_init_extra_types): Initialize socklen-t type if we
HAVE_SOCKETS.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
| |
It has actually never yet been used since its introduction in
commit 543f15cdc6b77f31639d87081b35aae3f1caf84a because we never
HAVE_DBL_INTPTR_T (it's a typo).
* itypes.h: HAVE_DBL_INTPTR_T -> HAVE_DOUBLE_INTPTR_T.
|
|
|
|
|
|
| |
* txr.1: Looks like quasiliteral patterns are staying the way
they are. The feature has been out for a number of releases,
so can be considered out of beta.
|
|
|
|
|
| |
* txr.1: Structural Pattern Matching info now mentions and
describes the two never macros.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (run_load_hooks): Install the given environment as dyn_env
temporarily, and don't restore it until after calling the hooks.
Thus the specified environment is now in effect when running the
hooks. Also, pass nil to lookup_var, in the spirit of the previous
commit. The fact that load_dyn_env had to be passed to lookup_var
previously, which is an anti-pattern, tells us that this scoping rule
was a code smell. If the *load-hooks* value comes from a given
dynamic environment, then those functions should be executed in
exactly that environment.
* txr.1: Documentation updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since lookup_var(nil, ...) skips the environment and goes for dyn_env,
there is no need to pass dyn_env explicitly; it's a bit of an
anti-pattern. The argument is intended for lexical scopes.
* eval.c (eval_exception, expand_eval, load): Pass nil to lookup_var
instead of the current dynamic environment.
* match.c (v_load): Likewise.
* parser.c (txr_parse, read_eval_ret_last): Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_push_after_load, me_pop_after_load): New static
functions.
(eval_init): Register push-after-load and pop-after-load
intrinsic macros.
* tests/019/load-hook.tl: Tests for correct expansion.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register delcons intrinsic.
* lib.[ch] (delcons): New function.
* tests/010/cons.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
*load-hooks* lets a .txr, .tl or .tlo file specify actions to be taken
when the loading of that file completes, whether normally or via
an exception. They are also honored by process exit.
For instance, with this, we can have a Lisp file that behaves like
a script which cleans up after itself (e.g. removing temporary files)
even if it is not run as a stand-alone program, but invoked
via (load ...). Because it's not a stand-alone program, it cannot
simply use the at-exit-call mechanism. The unwind-protect operator could
be used, but it's inconvenient because it protects a single form.
The *load-hooks* feature in effect protects all the top level forms of a
load, similarly to unwind-protect. Also, unwind-protect does not
guard against a process exit. (However, *load-hooks* does not guard
against an abnormal exit, only normal termination).
* eval.c (load_hooks_s): New symbol variable.
(run_load_hooks): New function.
(run_load_hooks_atexit): New static function.
(load): bind *load-hooks* to nil around load. Implement
the hooks processing via run_load_hooks, taking care to pass the
load-time dynamic environment that has already been undone.
(eval_init): Initialize load_hooks_s and register the *load-hooks*
variable. Register run_load_hooks_atexit with atexit, so the
current value of *load-hooks* is processed on process exit.
* eval.h (load_hooks_s, run_load_hooks): Declared.
* match.c (v_load): Similar changes as in load.
* txr.c (txr_main): Run the load hooks with run_load_hooks immediately
after processing the .txr or .tl file, before entering the listener.
* tests/019/load-hook.tl: New directory and file
* tests/load-hook.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
| |
* libtags.txr: use git ls-files instead of glob to
obtain list of .c files. This also means that we go into
subdirectories now, since git ls-files '*.c' lists items like
linenoise/linenoise.c and chksums/md5.c. For now, we are not
finding any new tags in these places, but in the future that
could change.
|
|
|
|
|
|
|
|
|
|
|
| |
The open-compile-streams function was calling trim-right with the
arguments in the wrong order, resulting in an output path equal
to the suffix of the input path.
Regression introduced in 8d8fee2e506806d9c117b17432ef3a5ec0d6f457.
* stdlib/compiler.tl (open-compile-streams): Swap in-path and
suff arguments in trim-right call.
|
|
|
|
|
|
|
| |
* libtags.txr: Use @(mdo) for defining variables and
structures, so this is done as libtags.txr is parsed.
The remaining top-level actions are split off in a
separate @(do ...) placed later.
|