summaryrefslogtreecommitdiffstats
path: root/txr.1
Commit message (Collapse)AuthorAgeFilesLines
...
* txr: close streams.Kaz Kylheku2022-08-291-2/+17
| | | | | | | | | | | | | | | | | | | * 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).
* New macro: close-lazy-streams.Kaz Kylheku2022-08-281-0/+70
| | | | | | | | | | | | | | | | | | | | | | | | * 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.
* New function: search-allKaz Kylheku2022-08-171-0/+54
| | | | | | | | | | | | | | | | | | | | | | | * 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.
* Version 280.txr-280Kaz Kylheku2022-08-091-3/+3
| | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date.
* Version 279.txr-279Kaz Kylheku2022-08-081-3/+3
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated.
* regsub: allow string in place of regex.Kaz Kylheku2022-07-271-3/+12
| | | | | | * regex.c (regsub): Use search_str if regex is a string. * txr.1: Documented.
* repl: revise security checks.Kaz Kylheku2022-07-261-6/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* path-components-safe: refactoring.Kaz Kylheku2022-07-251-1/+2
| | | | | | | | * 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.
* New function: path-components-safe.Kaz Kylheku2022-07-251-20/+40
| | | | | | | | | | | | | | | | * 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.
* path-test: object trust must use effective UID.Kaz Kylheku2022-07-241-8/+20
| | | | | | | | | * 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.
* compile-file: revise hash bang treatment.Kaz Kylheku2022-07-211-2/+16
| | | | | | | | | * 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.
* compiler: try unsuffixed path before adding .tlKaz Kylheku2022-07-211-4/+4
| | | | | | | | * 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.
* Install a txrlisp hard link.Kaz Kylheku2022-07-211-0/+27
| | | | | | | | | | | | | | | | | | * 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.
* doc: pos function.Kaz Kylheku2022-07-181-5/+9
| | | | * txr.1: Improve unclear wording describing pos function.
* New function: count.Kaz Kylheku2022-07-181-19/+55
| | | | | | | | | | | | | | | | 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.
* Date correction; man page typos.txr-278Kaz Kylheku2022-07-011-3/+3
| | | | | | * RELNOTES: 2022-07-01. * txr.1: Likewise and two minor fixes.
* Version 278.Kaz Kylheku2022-07-011-3/+3
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * protsym.c: Regenerated.
* doc: remove references to non-fork platforms.Kaz Kylheku2022-06-291-16/+3
| | | | | | | | | * 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.
* Add mode-opt to all I/O convenience functions.Kaz Kylheku2022-06-291-11/+11
| | | | | | | | | | | * 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.
* doc: document pid argument of open-fileno.Kaz Kylheku2022-06-241-2/+37
| | | | | | * txr.1: pid argument is documented and also missing, documentation added about how close-stream deals with processes.
* for/for*: stricter syntax check.Kaz Kylheku2022-06-131-15/+16
| | | | | | | | | | | | | | | | | * 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.
* New function: strKaz Kylheku2022-06-121-2/+35
| | | | | | | | | | | | | | | 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.
* doc: missing word in tree-insert section.Kaz Kylheku2022-06-011-0/+1
| | | | * txr.1: Add missing "If" at start of sentence.
* Version 277.txr-277Kaz Kylheku2022-05-311-3/+3
| | | | | | | | | | | | * 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: compression tests.Kaz Kylheku2022-05-301-2/+3
| | | | | | | | | | * 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.
* New: spln and tokn functions.Kaz Kylheku2022-05-301-1/+21
| | | | | | | | | | | | | | | 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.
* tok-str: takes count argument.Kaz Kylheku2022-05-281-4/+11
| | | | | | | | | | | | | | * 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: compression and decompression functions.Kaz Kylheku2022-05-281-0/+46
| | | | | | | | | * 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.
* doc: .tlo.gz suffix.Kaz Kylheku2022-05-271-9/+36
| | | | | * txr.1: In all places that mention .tlo in relation to loading, mention support for .tlo.gz suffix.
* doc: document gzip file mode.Kaz Kylheku2022-05-271-1/+44
| | | | | * txr.1: Document the "z" option letter, its optional digit arg, and the restrictions.
* I/O convenience functions get mode-opt argument.Kaz Kylheku2022-05-271-20/+100
| | | | | | | | | | | | | | | | | | | | | 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.
* Version 276.txr-276Kaz Kylheku2022-05-241-3/+3
| | | | | | | | | | | | | | * 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.
* ffi: reproduce odd GNU C behavior for aligned bitfields.Kaz Kylheku2022-05-241-2/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* doc: add a note about pack.Kaz Kylheku2022-05-241-0/+34
| | | | | * txr.1: pack with alignment values greater than 1 doesn't directly correspond to a single GNU C feature.
* ffi: bitfield tests and fixes.Kaz Kylheku2022-05-231-6/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* ffi: allow bitfields based on endian types.Kaz Kylheku2022-05-221-20/+78
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* ffi: pack bugfix and tests.Kaz Kylheku2022-05-201-3/+27
| | | | | | | | | | | | | | * ffi.c (ffi_transform_pack): Fix: return the original syntax in the situation when no cases are recognized, rather than the cdr of the syntax. When the struct/union syntax has no members, return the original syntax to indicate no transformation took place. * txr.1: Document the feature that pack on a typedef name or struct name with no members will do the alignment adjustment only, without the syntactic transformation. * tests/017/pack-align.tl: New file.
* doc: quasiliteral match: formatting problem.Kaz Kylheku2022-05-201-1/+1
| | | | | * txr.1: fix broken quoting which results in stray " character appearing in rendered output.
* doc: undimensioned arrays may be flexible array members.Kaz Kylheku2022-05-201-4/+9
| | | | | | | * txr.1: The documentation for array and zarray wrongly states that if the dimension is omitted, the type may not be used as a structure member. In fact, it may be used as the last member of a flexible structure.
* doc: grammarKaz Kylheku2022-05-201-2/+2
| | | | * txr.1: two instances of "an incomplete arrays" in FFI doc.
* ffi: behavior of align subject to compat.Kaz Kylheku2022-05-201-0/+16
| | | | | | | * ffi.c (ffi_type_compile): Allow align to weaken (lower) alignment if compatibility 275 or lower is requested. * txr.1: Compat note added.
* New function: trim-path-sepsKaz Kylheku2022-05-201-0/+52
| | | | | | | | | | | | | * 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: new pack type operator; align increases only.Kaz Kylheku2022-05-201-23/+186
| | | | | | | | | | | | | | | | | * 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.
* split-str: new count parameter.Kaz Kylheku2022-05-171-4/+33
| | | | | | | | | | | | | | | | | | * eval.c (eval_init): Fix up registration of split-str to account for new parameter. * lib.c (split_str_keep): Implement new optional count argument. (spl): Pass nil value to split_str_keep for new argument. I'd like this function to benefit from this argument also, but the design isn't settled. (split_str): Pass nil argument to split_str_keep. * lib.h (split_str_keep): Declaration updated. * tests/015/split.tl: New tests. * txr.1: Documented.
* doc: grammar under pattern matching.Kaz Kylheku2022-05-171-1/+1
| | | | * txr.1: agreement between "body" and "consist".
* New options: --in-package and --compile.Kaz Kylheku2022-05-121-1/+44
| | | | | | | | | * txr.c (help): Mention new options. (do_compile_opt, do_in_package_opt): New static functions. (txr_main): Implement options. * Makefile (COMPILE_TL): Use the options instead of -e. * txr.1: Document.
* expander: new rule for macro-produced function callsKaz Kylheku2022-05-121-0/+130
| | | | | | | | | | | | | | * eval.c (do_expand): When a function call's arguments are expanded and produce a transformation, then if that function call had been produced by a macro, the transformed function call is tried again as a macro. This is necessary because TXR Lisp allows a symbol to be both a function and macro. When a macro-produced function call's arguments are expanded, the macro version of that function may, as a result of the argument transformations, have more opportunities for expansion. * txr.1: New section outlining how macro expansion generally works, with a special focus on this unusual new rule.
* Version 275.txr-275Kaz Kylheku2022-05-101-3/+3
| | | | | | | | | | | | | | * 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.
* doc: FFI string types map null pointer to nil.Kaz Kylheku2022-04-261-3/+7
| | | | | | * txr.1: Document the existing behavior that the various FFI string types map between the null pointer and the nil object.
* doc: ffi: document the array-of-1 trick.Kaz Kylheku2022-04-261-0/+62
| | | | | * txr.1: Document the (ptr (array 1 <type>)) trick needed for out or in-out parameters.