| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (env rename-var): Method removed.
(compiler comp-let): Instead of initially creating
a let* variable as a gensym, and then renaming it
after compiling the init expression, we now just
obtain the location not bound to a variable, use the
location when compiling the init form, and bind
the location to a variable right after. This is
cleaner since the only thing we are mutating now is
the environment, and we are not wastefully allocating
a gensym. The real motivation is that this is building
up to a bugfix in compiling optional variables in
lambda: stay tuned!
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (env get-loc): New method for
allocating v-reg, split out of extend-var and
extend-var*. Now there is a check for the v-cntr
overflow.
(env (extend-var, extend-var*)): Taken an optional
loc parameter, so the caller can optionally allocate
a v-reg location using get-loc, and then specify
that location when creating a variable. If the
argument is omitted, use get-loc.
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (env (extend-var, extend-var*)):
Return the variable binding rather than the alist
containing it.
(compiler (comp-catch, comp-let, comp-tree-case)):
Drop use of cdar on return value of extend-var
to ferret out the binding from the alist.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/optimize (basic-blocks ling-graph): I'm reverting
an old design decision here. The decision is this:
the basic block of a close instruction points to the
first basic block of the closure as its next block,
but that next block does not point back: it doesn't list
the close instruction's basic block among the rlinks.
The idea was that the close instruction doesn't jump
to that block, and so it shouldn't be linked to it.
However, the next link was set purely so that the graph
is connected. Unfortunately, the inconsistency in the
graph structure which this causes is a problem in the
elim-dead-code method. A situation arises when that
first basic block after the close is removed. Because
pit has an empty rlinks list, the block remains listed
as the next block of the close block, even though it is
removed from the master list of blocks.
(basic-blocks check-bypass-empty): Fix one forgotten detail
in this function: the block being deleted must be removed
from the rlinks list of the next block.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* lib.c (lazy_stream_s): New symbol variable.
(lazy_streams_binding): New static variable.
(lazy_stream_register): New static function
(lazy_stream_cons): If the stream is associated with
a lazy cons, register it with lazy_stream_register.
(obj_init): gc-protect lazy_streams_binding variable.
Intern the sys:*lazy-streams* symbol.
* lib.h (lazy_streams_s): Declared.
* eval.c (eval_init): Register sys:*lazy-streams*
special variable.
* stdlib/getput.tl (close-lazy-streams): New macro.
* autoload.c (getput_set_entries): Trigger autload on
close-lazy-streams symbol.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): search-all intrinsic registered.
* lib.c (search_common): New Boolean argument all,
indicating whether all positions are to be returned.
We must handle this in the two places where empty
key and sequence are handled, and also in the main loop.
A trick is used: the found variable is now bound by
list_collect_decl, but not used for collecting unless
all is true.
(search, rsearch, contains): Pass 0 for all argument
of search_common.
(search_all): New function.
* lib.h (search_all): Declared.
* tests/012/seq.tl: New tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Regenerated.
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
| |
* stdlib/path-test.tl (safe-abs-path): If (uname) doesn't
report Linux, then define this function in a way that it
always returns true. We do this by making the name an alias
for the tf function.
|
|
|
|
|
|
| |
* stdlib/path-test.tl (path-components-safe): Reject symlinks
that have a link count not equal to one. This looks
suspiciously like a hard link attack.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Attacks are possible via /proc/<pid>/fd/<n> involving
a deleted file, whereby the link target changes from
"/path/to/file" to "/path/to/file (deleted)", which
can be perpetrated by a different user, not related
to process <pid>, who has access to perform
unlink("/path/to/file").
* stdlib/path-test.tl (safe-abs-path): Perform the
pattern check regardless of effective user ID.
* tests/018/path-safe.tl: Test cases adjusted.
|
|
|
|
|
| |
* stdlib/path-test (path-components-safe): Remove empty
components from split path.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In a Linux system, it's possible for an unprivileged
user to create a root symlink pointing to any directory,
simply by changing to that directory and running a setuid
executable like "su". That executable will get a process
whose /proc/<pid> directory is root owned, and contains
a symlink named cwd pointing to the current directory.
Other symlinks under /proc look exploitable in this way.
* stdlib/path-test.tl (safe-abs-path): New function.
Here is where we are going to check for unsafe paths.
We use some pattern matching to recognize various unsafe
symlinks under /proc.
(path-components-safe): Simplify code around recognition
of absolute paths. When an absolute path is read from
a symlink, remove the first empty component. Pass every
absolute path through safe-abs-path to check for known
unsafe paths.
* tests/018/path-safe.tl: New tests.
|
|
|
|
|
|
|
|
| |
* stdlib/copy-file.tl (path-simplify, path-split, path-volume,
rel-path, path-equal): Remove from here.
* stdlib/path-test.tl: (path-simplify, path-split, path-volume,
rel-path, path-equal): Move to here.
|
|
|
|
|
|
|
|
| |
* stdlib/socket.tl (in6addr-str): Remove one of
the two repetitions of a string substitution
intended to be done once. The substitution is
idempotent and therefore a second application
of it is redundant regardless of intent.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* txr.c (sysroot_init): Use regsub to look for "\\"
substring instead of regex.
* stdlib/getopts.tl (opt-parsed convert-type):
regsub for "0x" substring rather than #/0x/ regex.
* stdlib/pic.tl (pic-join-oipt): regsub for
"~" substring rather than #/\~/ regex.
* stdlib/socket.tl (in6addr-str): regsub for "::"
substring instead of #/::/ regex in two places.
The double regsub there looks like a mistake; will
address in another commit.
|
|
|
|
|
|
|
|
| |
* stdlib/path-test.tl (path-components-safe): Simplify code;
forget trying to do anything on Windows: just return true.
* txr.1: Document that path-components-safe is useless
on Windows.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* autoload.c (path_test_set_entries): Autoload on
path-components-safe symbol.
* stdlib/path-test.tl (if-windows, if-native-windows):
New system macros.
(path-safe-sticky-dir): New system function.
(path-components-safe): New function.
* tests/018/path-safe.tl: New file.'
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
| |
* stdlib/path-test.tl (path-private-to-me,
path-strictly-private-to-me): Call (getuid) rather
than (geteuid). We won't revert this behavior with
the -C compat option because it's wrong/insecure.
* txr.1: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The compile-file function must only try a different
path, such as with a suffix, if a given path fails
to open due to non-existence. If the failure is for
another reason, like permissions. In that case we want
to propagate the failure.
* stdlib/compiler.tl (ign-notfound): New macro.
This lets through all errors, catching only path-not-found,
converting that to a nil result.
(open-compile-streams): Use ign-notfound instead of
ignerr when trying to open an input file for reading.
Also, we lose the ignerr wrapping around the open-file.
We let any error whatsoever just bubble out so that the user
is better informed about what went wrong. The requirement
to close the input stream is handled by the obvious
unwind-protect.
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (translate-hash-bang): New function.
(compile-file-conditionally): Use translate-hash-bang to
treat hash bang line.
* txr.1: Revised hash bang treatment by file compiler
documented.
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (open-compile-streams): If the in-path
is unsuffixed, try opening it without adding any suffix first.
If that fails, then try .tl in that order.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The general count function, with keyfun and testfun,
is noticeably absent. Let's implement it.
* lib.[ch] (count): New function.
* eval.c (eval_init): Register count intrinsic.
* tests/012/seq.tl: Some tests for count.
* txr.1: Add count to count-if section. Revise documentation
based on pos/pos-if.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/getput.tl (command-get, command-put, command-get-string,
command-put-string, command-get-lines, command-put-lines,
command-put-buf, command-get-json, command-put-json,
command-get-jsons, command-put-jsons): Add mopt parameter,
which is interpolated into appropriate mode string.
This allows "z" to be used for gzip compression.
* txr.1: Updated Syntax synopses.
|
|
|
|
|
| |
* stdlib/getput.tl (file-get-lines): A mode-opt parameter is
documented for this function; it is now actually implemented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (me_for): Require at least one argument.
However, we let the init-forms continue to be optional
and document it.
* txr.1: Refer to for and for* as macros, since they have been
since 2016. The omission of the inc-form list is shown
as a second variant of the syntax. This is to avoid misleading
the reader into thinking that the the inc-form list can be
omitted while body forms are present. A spurious paragraph
reiterating that the macros establish an anonymous block is
removed. That extra text was present in the first draft written
in 2011, and maintained since.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The str function is like mkstring but allows a fill pattern
to be specified.
* eval.c (eval_init): str intrinsic registered.
* lib.[ch[ (str): New function.
* tests/015/str.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The following test case throws an exception:
(compile-toplevel '(when-match @(or
@b @c)
nil nil))
the reason is that in the optimizer, the local-liveness method
resets the bl.live set of live registers to nil. The expectation
is that it will be recalculated. However, what happens is that
* stdlib/optimize.tl (basic-block): Initialize live slot to zero.
(basic-blocks local-liveness): Reset bl.live to 0, rather than nil.
The problem is that sometimes the block in question is not reached
in the graph traversal (down in the same function) which is
supposed to assign it a live value. This happens in the above
test case, and it's not due to any bug: the block is not reached
by the forward traversal because the block has become unreachable.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The root slot is just supposed to be (car bl.list): the
first basic block. Unfortunately, it's not maintained
when bl.list is edited, which could cause bugs.
This change makes no difference in the stdlib compiled files,
other than of course the changes in optimize.tlo from this
code change itself; so that is evidence suggesting
this change is least not making anything worse.
* stdlib/optimize.tl (basic-blocks): Remove root slot.
(basic-blocks (link-graph, calc-liveness, elim-dead-code):
Refer to (car bl.list) instead of bl.root.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of trying to work the new count parameter into the spl and
tok functions, it's better to make new ones.
* eval.c (eval_init): spln and tokn intrinsics registered.
* lib.[ch] (spln, tokn): New functions.
* tests/015/split.tl: New test cases.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_compress, buf_decompress): New static functions.
(buf_init): buf-compress and buf-decompress intrinsics registered.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is motivated by the desired to be able to
specify gzip compression: e.g.
(file-put-string "file.gz" "abc" "z")
However, it has other uses. For instance with "x",
we can exclusively create a file with content in one
call.
* stdlib/getput.tl (file-get, file-put, file-append,
file-get-string, file-put-string, file-append-string,
file-put-lines, file-append-lines, file-get-buf,
file-put-buf, file-place-buf, file-append-buf, file-get-json,
file-put-json, file-append-json, file-get-jsons,
file-put-jsons, file-append-jsons): New option argument
which combines with the open-file mode.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stream.c (trim_path_seps): New function.
(stream_init): trim-path-seps intrinsic registered.
* stream.c (trim_path_seps): Declared.
* tests/018/path.tl: New tests.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* ffi.c (pack_s): New symbol variable.
(ffi_type_compile): Handle new pack type operator together with
align. Allow a one-argument form of align and pack in which
the value is defaulted. The behavior of align changes: align
can only increase alignment now, never decrease, so for
instance (align 1 ...) does nothing. pack must be used to
decrease alignment. Furthermore, for certain argument types,
pack performs transformations of the type syntax, rather than
compiling the argument type and producing a variant of it with
altered alignment.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
| |
* stdlib/copy-file.tl (copy-path-rec): When from-path has
a trailing slash, the starts-with test fails, and the operation
fails without doing anything. Let's just get rid of that test.
It's probably only there because of the ad-hoc path munging
that is calculating rel-path. Why don't we just use the rel-path
function for that.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/match.tl (expand-lambda-match): A pattern that
is shorter than the maximum number of arguments is
augmented with a check ensuring that no fixed arguments
are present beyond those that the pattern requires.
However, this check must be omitted if the pattern is
variadic, because those excess arguments match its tail
pattern.
* tests/011/patmatch.tl: Cases added.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (load_search_dirs_s): New symbol variable.
(load): Initialize the name variable whose address is passed
as the third argument of open_txr_file, which is now
an in-out parameter. Pass t for the new search_dirs parameter,
so that load benefits from the searching.
(eval_init): Initialize load_search_dirs_s and register the
*load-search-dirs* special variable.
* eval.h (load_search_dirs_s): Declared.
(load_search_dirs): New macro.
* match.c (v_load): Initialize the variable passed as third argument
of open_txr_file.
* parser.c (open_txr_file): Take a new argument, search_dirs.
If this is t, it tells the function "if the path is not found,
then recurse on the *load-search-dirs* variable. Otherwise,
if the value is not t, it is a list of the remaining directories
to try. The existing parameter orig_in_resolved_out must now
point to a location which is initialized. It is assumed to hold
the original target that was passed to the load function.
The first_try_path is a the path to actually try, derived from
that one. Thus, the caller of open_txr_file gets to determine
the initial try path using its own algorithm. Then any recursive
calls that go through *load-search-dirs* will pass a first argument
which is made of the original name, combined with a search dir.
(load_rcfile): Pass pointer to initialized location as third
argument of open-txr_file, and pass a nil value for search_dirs:
no search takes place when looking for that file, which is at a
single, fixed location.
* parser.h (open_txr_file): Declaration updated.
* txr.c (sysroot_init): Initialize *load-search-dirs*.
(txr_main): Ensure third argument in all calls to open_txr_file
points to initialized variable, with the correct value,
and pass t for the search_dirs argument.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
New: load can search multiple directories.
* eval.c (load_search_dirs_s): New symbol variable.
(load): Initialize the name variable whose address is passed as
the third argument of open_txr_file, which is now an in-out
parameter. Pass t for the new search_dirs parameter, so that
load benefits from the searching.
(eval_init): Initialize load_search_dirs_s and register the
*load-search-dirs* special variable.
* eval.h (load_search_dirs_s): Declared.
(load_search_dirs): New macro.
* match.c (v_load): Initialize the variable passed as third
* argument
of open_txr_file.
* parser.c (open_txr_file): Take a new argument, search_dirs.
If this is t, it tells the function "if the path is not found,
then recurse on the *load-search-dirs* variable. Otherwise, if
the value is not t, it is a list of the remaining directories
to try. The existing parameter orig_in_resolved_out must now
point to a location which is initialized. It is assumed to hold
the original target that was passed to the load function. The
first_try_path is a the path to actually try, derived from that
one. Thus, the caller of open_txr_file gets to determine the
initial try path using its own algorithm. Then any recursive
calls that go through *load-search-dirs* will pass a first
argument which is made of the original name, combined with a
search dir.
(load_rcfile): Pass pointer to initialized location as third
argument of open-txr_file, and pass a nil value for
search_dirs: no search takes place when looking for that file,
which is at a single, fixed location.
* parser.h (open_txr_file): Declaration updated.
* txr.c (sysroot_init): Initialize *load-search-dirs*.
(txr_main): Ensure third argument in all calls to open_txr_file
points to initialized variable, with the correct value, and
pass t for the search_dirs argument.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/compiler.tl (compile-file-conditionally): Recognize a
potential package-manipulating form not checking whether its
main operator is in %pakage-manip% list, but whether any
global functions that its compiled image references are in
that list. This is the same approach that is used in
dump-compiled-objects. This fix is needed for correctly
recognizing defpackage as a package-manipulating form.
defpackage macro-expands to a let form which contains a call
to make-package. Testing whether let is in %package-manip% is
useless; of course it isn't, and the test overlooks
make-package.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Register isecp intrinsic.
* lib.c (isecp): New function.
* lib.h (isecp): Declared.
* stdlib/compiler.tl (lambda-apply-transform,
dump-compiled-objects): Use isecp instead of isec, since the
actual intersection of symbols isn't needed, only whether it
exists.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These types actually make it possible to receive a string by
pointer from a C function, without trying to free it.
It is now possible to write a FFI wrapper for strtol or
wcstol, which is done in the new test case.
* ffi.c (str_s_s, bstr_s_s, wstr_s_s): New symbol variables.
(ffi_init_types): Register the types str-s, bstr-s and wstr-s.
(ffi_init): Intern the new symbols.
* tests/017/str-s.tl: New file.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* configure: detect intmax_t and place HAVE_INTMAX_T into
config.h.
* ffi.c (ffi_init_extra_types): register intmax-t and
uintmax-t types. If HAVE_INTMAX_T is missing, then make them
aliases for longlong and ulonglong.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
| |
* stdlib/quips.tl (%quips%): Samsung spelled backwards is
gnusmaS. In December, don't wish Merry GNUsmas in a GNU
mailing list.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* hash.c (group_map): New function.
(hash_init): group-map intrinsic registered.
* hash.h (group_map): Declared.
* tests/010/hash.tl: New test case.
* txr.1: Documented together with group-by.
Extra paren removed from group-by example.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
* protsym.c: Likewise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* stdlib/op.tl (sys:opip-expand): Add op, do, lop, ldo, ap,
ip, ado, ido, ret and aret to the operators whose forms are
passed through untransformed. This is important because it
lets us override the implicit (op ...) and (do ...) chosen
by the expander. When a pipeline element produces a list, for
instance, we want to be able to use (ap ...) in the next
element to spread the list into arguments.
* tests/012/op.tl: Add bellied numbers test case.
* txr.1: Documented.
|