summaryrefslogtreecommitdiffstats
path: root/stdlib
Commit message (Collapse)AuthorAgeFilesLines
...
* path-components-safe: check symlink link count.Kaz Kylheku2022-07-301-2/+3
| | | | | | * 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.
* path-components-safe: tighten /proc checkKaz Kylheku2022-07-301-15/+14
| | | | | | | | | | | | | | 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.
* path-components-safe: handle consecutive slashes.Kaz Kylheku2022-07-301-4/+2
| | | | | * stdlib/path-test (path-components-safe): Remove empty components from split path.
* path-components-safe: repel /proc symlink attacksKaz Kylheku2022-07-291-17/+42
| | | | | | | | | | | | | | | | | | | | | | 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.
* rel-path, path-equal: relocate.Kaz Kylheku2022-07-292-105/+94
| | | | | | | | * 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.
* in6addr-str: remove useless regsub.Kaz Kylheku2022-07-271-1/+0
| | | | | | | | * 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.
* Take advantage of substring support in regsub.Kaz Kylheku2022-07-273-4/+4
| | | | | | | | | | | | | | | | * 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.
* path-components-safe: refactoring.Kaz Kylheku2022-07-251-55/+37
| | | | | | | | * 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-252-0/+73
| | | | | | | | | | | | | | | | * 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-2/+2
| | | | | | | | | * 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: distinguish nonexistence errors.Kaz Kylheku2022-07-211-8/+10
| | | | | | | | | | | | | | | | | | | 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.
* compile-file: revise hash bang treatment.Kaz Kylheku2022-07-211-5/+11
| | | | | | | | | * 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-2/+2
| | | | | | | | * 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.
* New function: count.Kaz Kylheku2022-07-181-1/+2
| | | | | | | | | | | | | | | | 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.
* Version 278.Kaz Kylheku2022-07-011-1/+1
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * protsym.c: Regenerated.
* Add mode-opt to all I/O convenience functions.Kaz Kylheku2022-06-291-22/+22
| | | | | | | | | | | * 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.
* file-get-lines: missing mode-opt parameter.Kaz Kylheku2022-06-291-2/+2
| | | | | * stdlib/getput.tl (file-get-lines): A mode-opt parameter is documented for this function; it is now actually implemented.
* for/for*: stricter syntax check.Kaz Kylheku2022-06-131-2/+2
| | | | | | | | | | | | | | | | | * 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-38/+38
| | | | | | | | | | | | | | | 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.
* optimizer: fix live set being unexpectedly nil.Kaz Kylheku2022-06-091-2/+2
| | | | | | | | | | | | | | | | | | | | 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.
* optimizer: remove root slot from basic-block.Kaz Kylheku2022-06-091-6/+3
| | | | | | | | | | | | | | 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.
* Version 277.txr-277Kaz Kylheku2022-05-311-1/+1
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated.
* New: spln and tokn functions.Kaz Kylheku2022-05-301-1/+2
| | | | | | | | | | | | | | | 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: compression and decompression functions.Kaz Kylheku2022-05-281-0/+2
| | | | | | | | | * 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.
* I/O convenience functions get mode-opt argument.Kaz Kylheku2022-05-271-36/+36
| | | | | | | | | | | | | | | | | | | | | 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-1/+1
| | | | | | | | | | | | | | * 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.
* New function: trim-path-sepsKaz Kylheku2022-05-201-0/+1
| | | | | | | | | | | | | * 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-1/+2
| | | | | | | | | | | | | | | | | * 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.
* copy-path-rec: bug: trailing slash fail.Kaz Kylheku2022-05-171-4/+1
| | | | | | | | | * 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.
* lambda-match: bug: over-strict match in variadic pattern.Kaz Kylheku2022-05-111-1/+1
| | | | | | | | | | | | * 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.
* Version 275.txr-275Kaz Kylheku2022-05-101-1/+1
| | | | | | | | | | | | | | * 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.
* New: load can search multiple directories.Kaz Kylheku2022-04-251-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* compiler: package-manipulating top-level forms bug.Kaz Kylheku2022-03-311-1/+2
| | | | | | | | | | | | | | * 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.
* New function: isecp.Kaz Kylheku2022-03-302-6/+7
| | | | | | | | | | | | | | | | | * 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.
* New FFI types str-s, bstr-s and wstr-s.Kaz Kylheku2022-03-211-6/+9
| | | | | | | | | | | | | | | | | 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.
* ffi: support intmax-t and uintmax-t types.Kaz Kylheku2022-03-151-8/+10
| | | | | | | | | | | | | * 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.
* New GNU-themed quip.Kaz Kylheku2022-03-081-0/+1
| | | | | | * stdlib/quips.tl (%quips%): Samsung spelled backwards is gnusmaS. In December, don't wish Merry GNUsmas in a GNU mailing list.
* New function: group-map.Kaz Kylheku2022-03-021-1/+2
| | | | | | | | | | | | * 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.
* Version 274.txr-274Kaz Kylheku2022-02-241-1/+1
| | | | | | | | | | | | | | * 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.
* opip: pass through forms in the op family.Kaz Kylheku2022-02-241-1/+1
| | | | | | | | | | | | | | * 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.
* New list-builder method: oust.Kaz Kylheku2022-02-232-4/+12
| | | | | | | | | | | | | | | | * autoload.c (build_set_entries): Add oust symbol. * stdlib/build.tl (list-builder postinit): Call the self argument self instead of bc, for consistency with other methods. (list-builder oust): New method. (list-builder-flets): Add local function oust. * tests/012/seq.tl: New tests. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New function: partition-if.Kaz Kylheku2022-02-231-0/+1
| | | | | | | | | | | | | | | | * eval.c (eval_init): Register partition-if intrinsic. * lib.c (partition_if_countdown_funv, partition_if_func): New functions. (partition_if): New function. * lib.h (partition_if): Declared. * tests/012/seq.tl: New test cases. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* New functions: find-max-key and find-min-key.Kaz Kylheku2022-02-211-0/+2
| | | | | | | | | | | | | * eval.c (eval_init): Register find-max-key and find-min-key intrinsics. * lib.c (find_max_key, find_min_key): New functions. * lib.h (find_max_key, find_min_key): Declared. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* lisplib: rename lisplib funtions to autoload prefix.Kaz Kylheku2022-02-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * lisplib.c (lisplib_init): Follow rename, and rename try-load-fun to autoload-try-fun. (lisplib_try_load_fun, lisplib_try_load_var, lisplib_try_load_fun_var, lisplib_try_load_slot, lisplib_try_load_struct, lisplib_try_load_keyword): Renamed from `lisplib_try_load_@kind` to `autoload_try_@kind`. * lisplib.h (lisplib_try_load_fun, lisplib_try_load_var, lisplib_try_load_fun_var, lisplib_try_load_slot, lisplib_try_load_struct, lisplib_try_load_keyword): Declarations renamed. * eval.c (lookup_global_var, lookup_sym_lisp1, lookup_fun, lookup_mac, lookup_symac, lookup_symac_lisp1, special_var_p, expand_param_macro, rt_defvar, rt_defv, op_defsymacro, rt_defsymacro, rt_defun, rt_defmacro, makunbound, fmakunbound, mmakunbound): Follow rename. * struct.c (make_struct_type, find_struct_type, lookup_slot_load, lookup_static_slot_load, lookup_static_slot_desc_load, slot_types, static_slot_types): Follow rename. * stdlib/place.tl (get-place-macro): Follow rename of try-load-fun to autoload-try-fun.
* lisplib: split lisplib_try_load into namespaces.Kaz Kylheku2022-02-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lisplib.c (lisplib_init): Change sys:try-load (only used by place.tl) to sys:try-load-fun, and register it to (lisplib_try_load): External function becomes static. (lisplib_try_load_fun, lisplib_try_load_var, lisplib_try_load_fun_var, lisplib_try_load_slot, lisplib_try_load_struct, lisplib_try_load_keyword): New functions. * lisplib.h (lisplib_try_load): Declaration removed. (lisplib_try_load): External function becomes static. (lisplib_try_load_fun, lisplib_try_load_var, lisplib_try_load_fun_var, lisplib_try_load_slot, lisplib_try_load_struct, lisplib_try_load_keyword): Declared. * eval.c (lookup_global_var, lookup_var, lookup_symac, lookup_symac_lisp1, rt_defvarl, rt_defv, op_defsymacro, rt_defsymacro, makunbound): Use lisplip_try_load_var. (lookup_fun, lookup_mac, rt_defun, rt_defmacro, fmakunbound, mmakunbound): Use lisplib_try_load_fun. (expand_param_macro): Use lisplib_try_load_keyword, which is a catch-all namespace for anything tied to keywords. * struct.c (make_struct_type, find_struct_type): Use lisplib_try_load_struct. (lookup_sloat_load, lookup_static_slot_load, lookup_static_slot_desc_load, slot_types, static_slot_types): Use lisplib_try_load_slot. * stdlib/place.tl (get-place-macro): Use try-load-fun, rather than try-load.
* New function: cat-files.Kaz Kylheku2022-02-132-0/+14
| | | | | | | | | | | * lisplib.c (copy_file_instantiate): Trigger autoload on cat-files. * stdlib/copy-file.tl (cat-files): New function. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* doc: remove extraneous symbols from doc-syms.Paul A. Patience2022-02-121-17/+0
| | | | | | | * genman.txr: Remove from the name list those names that are not TXR symbols, so that they don't appear in doc-syms. * stdlib/doc-syms.tl: Updated.
* WIP getopts: allow specifying arg names in help.Paul A. Patience2022-02-121-6/+27
| | | | | | | | * stdlib/getopts.tl (basic-type-p): Handle the cons case. (sys:opt-parsed convert-type): Same. (opthelp): Same. (opthelp-types): Same, and for each type in the legend, specify which arguments correspond to it.
* getopts: print legend entries in canonical order.Paul A. Patience2022-02-121-25/+26
| | | | | | | | * stdlib/getopts.tl (opthelp-types): Print the entries in a canonical order rather than in the order of the types' appearance in opt-desc-list. Also, remove one (superfluous) space before the hyphen in all entries and fix typos in the description of HEX and STR.
* getopts: include list/cumul subtypes in legend.Paul A. Patience2022-02-121-1/+6
| | | | | * stdlib/getopts.tl (opthelp-types): Consider list and cumul types when searching for types to include in the legend.