| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
| |
* txr.1: Syntax markup for file-get-buf, :mass-delegate
and file-open options contains an extra space. This causes
the syntax not to be correctly processed for the HTML
version. nroff-based man page rendering and pdf are fine.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* parser.l (remove_char): New static function.
(DIGSEP, XDIGSEP, NUMSEP, FLOSEP, XNUMSEP, ONUMSEP,
BNUMSEP, ONUM, BNUM): New named lex patterns.
(FLODOT): Use DIGSEP instead of DIG.
(ONUM): Use ODIG instead of [0-7].
(BNUM): Use BDIG instead of [0-1].
(grammar): New rule for producing NUMBER from decimal
token with commas based on BNUMSEP instead of BNUM.
This is a copy and paste so that the BNUM rule doesn't
deal with the comma removal, not to slow it down.
For the octal, binary and hex, we just switch to
BNUMSEP, ONUMSEP and XNUMSEP, so they all go through
one case.
Floating point numbers are also handled with a copy
pasted case using FLOSEP.
* tests/012/syntax.tl: New test cases.
* txr.1: Documented.
* genvim.txr (alpha-noe, digsep, hexsep, octsep, binsep): New
variables.
(txr_pnum, txr_xnum, txr_onum, txr_bnum, txr_num): Integrate
separating commas. Some bugs fixed in txr_num, some simplifications,
better txr_badnum pattern.
* lex.yy.c.shipped: Updated.
|
|
|
|
|
|
|
| |
* stdlib/struct.tl (define-struct-clause): Disallow
the :postfini keyword as clause name.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The motivation is that struct clause macros defined
using define-struct-clause may want to introduce
their own initializers and finalizers for the specific
stuff they add to the struct. The uniqueness restrictions
on these initializing and finalizing clauses makes
it impossible to use two clause macros which both want
to inject a definition of the same initializer or finalizer
type.
* stdlib/struct.tl (defstruct): Don't enforce that there
be at most one clause in the category of :init,
:postinit, :fini or :postini. Multiple are allowed.
They all execute left-to-right except for :fini.
* tests/012/fini.tl: New tests.
* tests/012/fini.expected: Updated.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (pct_fun_s): New symbol variable, holding
the usr:%fun% symbol.
(fun_macro_env): New static function.
(do_expand): For defun and defmacro, use fun_macro_env
to establish an environment binding the %fun% symbol
macro, and expand everything in that environment.
(eval_init): Intern the %fun% symbol, initializing
pct_fun_s, and also register a global symbol macro in
that name so that we can freely use %fun% everywhere
without worrying that the code will blow up.
E.g. a logging macro can use it to get the function name,
but still be useful in a top-level form outside of
a named function.
* stdlib/struct.tl (sys:meth-lambda): New macro.
(defstruct, defmeth): Use sys:meth-lambda as a replacement
for lambda to set up the %fun% symbol macro. In the :init
case which doesn't use a lambda, an open-coded symacrolet
does the job.
* tests/019/pct-fun.tl: New file.
* tests/019/pct-fun.expected: Likewise.
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* socket.c (sock_set_entries): Intern str-addr symbol.
There is no autoload on this because the struct types of
which this is a method don't exist if the socket
module has not been loaded.
* stdlib/socket.tl ((sockaddr-in str-addr), (sockaddr-in6
str-addr), (sockaddr-un str-addr)): New methods.
* tests/014/str-addr.tl: New file. This provides
coverage not just for the str-addr method, but the
hitherto untested address to text functions.
This is why the bug was found, that was addressed
in the previous commit. The test case which produces
"8000::1" was actually producing "800:1".
* txr.1: Documented.
* stdlib/doc-syms.tl: Updated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This function "intelligently" constructs an
address object of the right type from a string.
* socket.c (sock_set_entries): Autoload socket.tl
on sockaddr-str function being accessed.
* stdlib/socket.tl (sockaddr-str): New function.
* tests/014/sockaddr-str.tl: New file.
* txr.1: Documented.
* stdlib.doc-syms.tl: Updated.
|
|
|
|
|
| |
* txr.1: describe equote as occuping a semantic midpoint
between full and quoting, rather than being "mongrel".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The :postfini clause registers a finalizer that runs in the
ordinary order: after previously registered ones. This has
the effect of allowing a derived structure to run clean-up
actions after those of inherited structures. Either order
can be useful because the dependencies between base and
derived can go in either direction. It's a huge mistake in
C++ that it supports only derived-first destructor invocation
order.
* stdlib/struct.tl (defstruct): Recognize and translate
:postfini clause. It's exactly like :fini but omits the
t parameter in the finalize call, registering in the
natural order.
* tests/012/fini.tl (derived): Add :postfini handler.
* tests/012/fini.expected: Updated to reflect the messages
coming from the postfini handler, which are happening
in the correct order.
* 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.
|
|
|
|
|
|
|
| |
* txr.1: In the Numbers section, talk about fixnum and
bignum, and the boxed/unboxed terminology, as well as
the possibility that floating-point may be unboxed,
and how to detect that.
|
|
|
|
|
|
|
|
|
| |
* txr.1: Document how ~a and ~s calculate the
effective precision for the second step for
integer and floating-point values, adding
a Rationale paragraph about why it's different
between the two in the case of zero or missing
width.
|
|
|
|
|
| |
* txr.1: Document and advise users that it
doesn't work in 281 or older versions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* match.c (noclose_k): New keyword variable.
(v_next_keys, v_output_keys): New static variables.
(v_next_impl): Use v_next_keys in calculating alist,
rather than freshly allocating it each time.
Check for the new :noclose keyword; if it is missing,
close any locally opened stream when done.
(v_output): Refer to v_output_keys precalculated
list rather than allocating it every time.
(match_files): If a stream is opened in by a call
to open_data_source from this function, then
the stream is closed when this function returns.
(syms_init): Intern the :noclose symbol.
(plist_keys_init): New function.
(match_init): Call plist_keys_init.
* txr.1: Documented new :noclose option of @(next).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* regex.c (regsub): Use search_str if regex is a string.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Summary: we now check the entire path of .txr_history and .txr_profile
files for security issues; we enforce that these files must not be
readable to other users, not just not writable. And there is a bugfix:
we do not load the history if it has a permission problem, instead of
loading it anyway and just issuing a diagnostic.
* repl.c (report_security_problem): Rename to report_file_perm_problem.
Drop the umask check, because we are going to be checking for files
that are not readable for others, which would require a stricter umask
than the usual 022.
(report_path_perm_problem): New static function.
(load_rcfile): Take the needed function symbols as arguments, because
the only caller is repl and it has them; it can pass them down.
Check the path using path-components-safe function, and bail with
an error message if it is bad. Then check the file using
path-strictly-private-to-me-p, rather than path-private-to-me-p
as previously. This requires the file not to be readable to others too.
(repl): path_private_to_me_p variable renamed to ppriv_s for brevity
and holds a different symbol: path-strictly-private-to-me-p,
the function which checks that other users cannot read the file, not
just write. Also capture the path-components-safe symbol as
psafe_s. ppriv_s and psafe_s are passed down to load_rcfile so it
can do checks. Like in the case of the rcfile, we now check the
history file using both functions, validating the path not just
the file's own permissions. Bugfix: we now check the history file's
path before loading the history file, and avoid loading it if the
check fails. We use the path-exists-p function now to check that
the history and rc files exist. That leaves a small flaw: an
attacker could be in control of the paths to these files and
manipulate these paths such that these files appear not to exist;
we will then not report on such a situation.
* txr.1: Documented.
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Makefile (LN): New variable. On platforms where
you can't hard link, this can be replaced with some
other command. Possibly "true" not to have the alternative
executable name created at all.
(HARDLINK): New macro.
(install): Use HARDLINK to create a link named txrlisp
pointing to the same file as txr in the destination
directory.
* txr.c (txr_main): If the executable ends with "lisp"
(or "lisp.exe" on Windows), then default the txr_lisp_p
variable to t, which has the effect as if --lisp had
been processed.
* txr.1: Documented.
|
|
|
|
| |
* txr.1: Improve unclear wording describing pos function.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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: 2022-07-01.
* txr.1: Likewise and two minor fixes.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* protsym.c: Regenerated.
|
|
|
|
|
|
|
|
|
| |
* txr.1: Remove references to limitations in open-process on
platforms which don't have fork. It's simply not implemented on
those platforms at all any more. This documentation referred
to a MinGW port of TXR which has not been maintained in many
years. Also remove text which says that open-subprocess is only
available on platforms with fork.
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
| |
* txr.1: pid argument is documented and also missing,
documentation added about how close-stream deals
with processes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
| |
* txr.1: Add missing "If" at start of sentence.
|
|
|
|
|
|
|
|
|
|
|
|
| |
* RELNOTES: Updated.
* configure (txr_ver): Bumped version.
* stdlib/ver.tl (lib-version): Bumped.
* txr.1: Bumped version and date.
* txr.vim, tl.vim: Regenerated.
|
|
|
|
|
|
|
|
|
|
| |
* buf.c (buf_compress): Let's use the level value of -1
if not specified, so Zlib defaults it to 6, or whatever.
* tests/012/buf.tl: New tests.
* txr.1: Note that -1 is a valid level value and that
is the default.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* eval.c (eval_init): Update registration of tok-str.
* lib.c (tok_str): New argument, count_opt. Implemented
in the compat 155 case; what the heck.
(tok): Pass nil to new parameter of tok_str.
* lib.h (tok_str): Declaration updated.
* tests/015/split.tl: New tests.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
| |
* txr.1: In all places that mention .tlo in relation to loading,
mention support for .tlo.gz suffix.
|
|
|
|
|
| |
* txr.1: Document the "z" option letter, its optional digit arg,
and the restrictions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We've already taken care of imitating the situation that GNU
C allows __attribute__((aligned(n))) to weaken the alignment
of a bitfield, contrary to it being documented that align only
strengthens alignment. Even a value of n == 1 is meaningful
in that it can cause the bitfield to start allocating from
a new byte.
This patch corrects a newly discovered nuance: when a bitfield
is attributed with a weaker alignment than its underlying
type (e.g. uint32_t field marked with 2 byte alignment),
the original type's alignment is still in effect for calculating
the alignment of the structure, and the padding.
* ffi.c (struct txr_ffi_type): New member oalign, for keeping
track of the type's original alignment, prior to adjustment.
(make_ffi_type_struct): For a named bitfield, take the oalign
value into account when determining the most strict member
alignment.
(ffi_type_compile): When marking a type as aligned, the
we remember the original alignment in atft->oalign.
* tests/017/bitfields.tl: New test case, struct s16.
* txr.1: Documented.
|
|
|
|
|
| |
* txr.1: pack with alignment values greater than 1 doesn't
directly correspond to a single GNU C feature.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The bitfield allocation rules are wrong. Some of it is due
to the recent changes which are based on incorrect analysis,
but reverting things doesn't fix it.
The idea that we compare the current member's alignment
with the previous is wrong; it is not borne out by empirical
tests with gcc. So we do a straight revert of that.
In GNU C, an __attribute__((aligned (N))) attribute applied
to a bitfield member will perform the requested alignment if,
evidently, the bit field is already being placed into a new
byte. (If the bit field is about to be packed into an existing
byte, then there is a warning about the align attribute being
ignored). Because we don't have alignment as a member attribute,
but only as a type attribute, we must implement a flag which
indicates that a type has had align applied to it (even if
the alignment didn't change) so we can then honor this in the
right place in the bitfield allocation code.
* ffi.c (struct txr_ffi_type): New attribute flag, aligned.
(make_ffi_type_struct): Remove the prev_align variable and
all related logic. Consolidate all alignment into one place,
which is done before we allocate the bitfield or regular member.
We align if the new member isn't a bitfield, or even if it is
a bitfield if it has the aligned attribute, or if the bitfield
is changing endian compared to the previous member (our local
rule, not from GNU C).
(ffi_type_compile): The align and pack operators now set the
aligned attribute, except in the (pack 1 ...) case which
semantically denotes lack of alignment.
* tests/017/bitfields.tl: New file.
* txr.1: Documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is very nice: you can now declaratively match a structure
that uses bitfields, and comes from a different endian system.
* ffi.c (ffi_kind_t): Replace FFI_KIND_NUM type with FFI_KIND_INT,
FFI_KIND_UINT and FFI_KIND_FLO. Now using the tft->kind value,
we can distinguish integer and floating types, and determine
signedness.
(struct txr_ffi_type): New flag, bigendian, which is set to 1
for all big types that are big endian. This is not just the endian
types like be-int32, but natural types like int, if the underlying
platform is big endian.
(swap_get32, swap_put32, swap_get64, swap_put64): New static functions.
(ffi_generic_swap_fat_ubit_put, ffi_generic_swap_fat_sbit_put,
ffi_generic_swap_fat_ubit_get, ffi_generic_swap_fat_sbit_get,
ffi_generic_swap_ubit_put, ffi_generic_swap_sbit_put,
ffi_generic_swap_ubit_get, ffi_generic_swap_sbit_get): New
static functions.
(ffi_make_type_builtin): On big endian, set the bigendian flag on every
type. For the endian types, this will get adjusted as an additional
construction step.
(make_ffi_type_endian): New static function. Calls ffi_make_type_builtin,
and then initializes the bigendian flag with the given value.
(make_ffi_type_struct, make_ffi_type_union): Because bitfields can
have endiannness now, we can no longer refer to the machine's own
endianness in laying them out; we have to look at the mtft->bigendian
value. Furthermore, we need an additional rule: when a bitfield member
follows a member that has different endian, a new allocation unit
has to begin.
(ffi_type_compile): the sbit and ubit types must set the type to
FFI_KIND_INT and FFI_KIND_UINT now. For the big operator, we can
simplify the error checking: instead of exhaustively comparing the
type to all the supported integer types, we just now check whether
it is FFI_KIND_INT or FFI_KIND_UINT. Here, if we detect that an
endian bitfield has opposite byte order from the machine, then we
instantiate the bitfield with the ffi_generic_swap_* virtual
functions. These perform the required byte swapping accesses to
the bitfield storage cells, so then the bit field manipulation
code just works using the local integer representation (shifting
and masking). Of course, the shift amount depends on the endian;
and that is calculated at type creation time in make_ffi_type_struct.
(ffi_init_types): Replace FFI_KIND_NUM with the appropriate constant
for each affected type. In some cases, we have to calculate whether
to use the INT or UINT one, for the types whose signedness is
not specified. We switch all the endian types to new constructor
make_ffi_type_endian, passing the required value of the bigendian
flag.
* txr.1: Documented.
|