summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* path-cat: becomes variadic.Kaz Kylheku2021-06-293-8/+103
| | | | | | | | | | | | | * stream.c (path_vcat): New static function. (stream_init): Register path-cat instrinsic to path_vcat rather than path_cat. * tests/018/path.tl: path-cat tests: all examples from documentation, plus others. * txr.1: Documented existing behaviors that were not clear, like when inputs are empty. Documented new variadic semantics. Examples added.
* path-cat: error if arguments are not strings.Kaz Kylheku2021-06-291-2/+2
| | | | | * stream.c (path_cat): Use length_str to enforce a type check. Otherwise, for instance, (path-cat #() "foo") will return "foo".
* doc: mistake in several path-cat examples.Kaz Kylheku2021-06-291-3/+3
| | | | | * txr.1: Corrections to three examples, where one operand is empty, and thus the other is returned.
* doc-lookup: use BROWSER variable; provide fallback.Kaz Kylheku2021-06-292-5/+40
| | | | | | | | | * stdlib/doc-lookup.tl (open-url): On non-Windows platforms, search for a program specified by the BROWSER variable, then by the URL-opening utility, and finally thorugh a fallback list of browsers. * txr.1: Documentation updated.
* New function: find-true.Kaz Kylheku2021-06-295-3/+86
| | | | | | | | | | | | | | | This is like find-if, but returns the value of the predicate function rather than the item. * eval.c (eval_init): Register find-true instrinsic. * lib.c (find_true): New function. * lib.c (find_true): Declared. * stdlib/doc-syms.tl: Updated. * txr.1: Documented.
* New function: path-search.Kaz Kylheku2021-06-295-1/+103
| | | | | | | | | | | | * lisplib.c (path_test_set_entries): Autoload on path-search. * stdlib/path-test.tl (path-search): New function. * tests/018/path-test.tl: New file. * txr.1: Documented. * stdlib/doc-lookup.tl: Updated.
* doc-lookup: handle xdg-open not terminating.Kaz Kylheku2021-06-291-7/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | It is common for web browsers like firefox not to fork themselves into the background when initially run from the command line. Only when an additional instance is executed does that instance terminate immediately, passing the URL to the existing instance. (Which also does not constitute forking into the background, but does have the effect of an immediate exit.) User Paul A. Patience reports that some installations of xdg-open have the isssue of not handling this situation; these versions of xdg-open wait for the browser to terminate, which causes xdg-open to hang until the browser is closed if it is the initial instance. * stdlib/doc-lookup.tl (detached-run): New function. Like run, but forks into the background, running the process in a detached grandchild whose parent terminates, so that it becomes an orphan parented to the init daemon. We redirect *stdout* to *stdnull* because the first instance of the browser can spit ugly, meaningless diagnostics when it terminates. (open-url): Use detached-run instad of run. Don't check the return value for zero; there is no integer exit status.
* doc-lookup: *doc-url* variable must be dynamic.Kaz Kylheku2021-06-281-1/+1
| | | | | * stdlib/doc-lookup.tl (*doc-url*): Define with defvar, not defvarl. Problem reported by Paul A. Patience.
* constantp: fully expand; recognize functions.Kaz Kylheku2021-06-285-56/+158
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch improves the constantp function dramatically. It now performs a full expansion of its argument, and recognizes all of the constant foldable functions that the compiler recognizes. * eval.c (const_foldable_s): New symbol variable. (const_foldable_hash): New static variable. (constantp_noex): Look up function in the hash table of const foldable functions, including in the case when it appears in a dwim form as in [+ 2 2] which is (dwim + 2 2). In this case, recursively check the arguments for constantp_noex. We get the hash table of foldable functions from the sys:%const-foldable% variable, which comes from an autoloaded module. (constantp): Fully expand the input form, not just m macroexpand. (eval_init): Register the const_foldable_s variable. * lisplib.c (constfun_instantiate, constfun_set_entries): New static functions. (lisplib_init): Register auto-loading of constfun module via new static functions. * stdlib/compiler.tl; Load the constfun module if %const-foldable% is not defined. (%const-foldable-funs%, %const-foldable%): Removed from here. * stdlib/constfun.tl: New file. (%const-foldable-funs%, %const-foldable%): Moved here. * txr.1: Documented changes to constantp.
* expander: use constantp_noex for expanded forms.Kaz Kylheku2021-06-281-4/+4
| | | | | | * eval.c (expand_progn, do_expand): Use the constantp_noex helper function of constantp on arguments that we have already fully expanded.
* regex: bugfix: print/read consistency of n-ary ops.Kaz Kylheku2021-06-271-2/+4
| | | | | | | | | | | | | | | | | | The regex-compile function accepts syntax in which certain operators like (or ...) can be n-ary. This representation is converted to the strictly binary form that is understood by the compiler internals (and which regex-parse outputs), as well as the regex printer. Unfrotunately, regex-compile is attaching the original form with the n-ary operators to the regex object, and the printer does not reat this; it renders the syntax with portions missing. It needs the binary form. * regex.c (regex_compile): Capture the intermediate result from calling reg_nary_to_bin, and use that as regex_source. The pass that through the remaining two optimization passes to obtain regex_sexp which is compiled.
* regex: exposing optimization pass a regex-optimizeKaz Kylheku2021-06-273-2/+53
| | | | | | | | | | | | * regex.c (regex_optimize): New static function, capturing the three optimization passes. (regex_compile): Code moved into regex_optimize. (regex_init): Remove sys:reg-optimize function. Register regex-optimize. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* regex-from-trie: correctly handle empty trie.Kaz Kylheku2021-06-272-2/+6
| | | | | | | | | | * filter.c (regex_from_trie): An empty trie matches nothing, so we must return the t regex syntax (match nothing), not nil (match empty string). A hash-based trie matches nothing if it is empty; but if it has user data, then it matches the empty string. * tests/015/trie.tl: Test cases added.
* regex-from-trie: bugs processing compressed trie.Kaz Kylheku2021-06-272-3/+10
| | | | | | | | | | * filter.c (regex_from_trie): If a hash key maps to a string, do not treat that as a trie; it is the value for that node. A value is only a trie if it is a cons or hash. Also, in this case do not make a compound regex. * tests/015/trie.tl: Add duplicate of regex test case using regex from compressed tree.
* filter: remove useless statement.Kaz Kylheku2021-06-271-2/+0
| | | | | | | * filter.c (trie_filter_string): There is no need to convert a character to string for passing it as a second argument to string_extend; it takes characters. Also this had beem coded in a silly way: if chrp is true that implies !stringp.
* regex-from-trie: bugfix: incomplete regex.Kaz Kylheku2021-06-272-1/+3
| | | | | | | | | | * filter.c (regex_from_trie): The code is neglecting to check whether there is a match of the input *at* the given hash table, which is true if it has user data. In that case, the empty regex must be added as a parallel branch. * tests/015/trie.tl: The first regex test case works now. The second one is incorrect and is replaced.
* filter: regex-from-trie produces bad or syntax.Kaz Kylheku2021-06-272-6/+58
| | | | | | | | | | This is not a complete fix yet; the test case still fails. * filter.c (regex_from_trie): The (or ...) operator in the regex language is strictly binary. Do not produce a variable-argument or expression. * tests/015/trie.tl: New file.
* signal: fix warning in older compilers.Kaz Kylheku2021-06-261-1/+1
| | | | | | | | * signal.c (sig_handler): Some older compilers cannot figure out that stack_lim is not used uninitialized, due to the conditional logic here, in which two separate code blocks are guarded by the same condition. Let's initialize the variable, like the others.
* tests: reduce time spent in stack overflow test.Kaz Kylheku2021-06-261-0/+1
| | | | | | * tests/012/stack2.txr: This test case can prove its point in a much smaller stack limit than the one derived from the system default. Let's cut it to 32 kilobytes.
* linenoise: end-of-line/buffer selection glitch.Kaz Kylheku2021-06-261-1/+1
| | | | | | | | | | | | | | | | | In inclusive selection mode, when the selection is reversed (end point is before start), and the starting character is the end of the line or of the buffer, that character is not included in the highlight, as if non-inclusive selection were in effect. This doesn't affect the semantics of the selection, only the way it is rendered visually; the character which is not highlighted is still included in the selection. * linenoise/linenoise.c (sync_data_to_buf): Remove two bogus conditions from the line which extends the visual selection by one character: we must not avoid executing this logic if the current character is zero (end of buffer) or CR (end of line).
* base-name: bug with empty string suffix.Kaz Kylheku2021-06-262-1/+29
| | | | | | | | * stream.c (base_name): We must check for a zero length suffix, otherwise sub(base, zero, neg(length(suff))) produces an empty string. * tests/018/path.tl: Test cases for base-name.
* suffix functions: requirements change.Kaz Kylheku2021-06-263-39/+40
| | | | | | | | | | | | | | | | | The short-suffix and long-suffix functions will now return the suffix including the leading period. This was a suggestion from user Paul A. Patience, which is a good requirement. Since these functions were newly introduced just the last release, I'm not going to provide backwards compatibility switching for them. * stream.c (short_suffix, long_suffix): Duplicate the suffix starting at the dot, not dot + 1. * tests/018/path.tl: Test cases updated. * txr.1: Documentation updated.
* byacc: fix regression caused by yystype.Kaz Kylheku2021-06-261-1/+1
| | | | | | | * parser.c (lisp_parse_impl): Refer to YYSTYPE not yystype, which doesn't exist under byacc. Reported by Sergey Romanov, against CentOS 8.4 using byacc 1.9.20170709-4.el8; easily reproduces with 1.9.20140715 on Ubuntu 18.
* suffix functions: leading dot is not delimiterKaz Kylheku2021-06-263-19/+37
| | | | | | | | | | * stream.c (short_suffix, long_suffix): Do not treat the starting dot of the last componet as a suffix delimiter. * tests/018/path.tl: Test cases edited to reflect requirements change; new tests added. * txr.1: Updated.
* doc: fix while-match syntax.Kaz Kylheku2021-06-251-1/+1
| | | | | * txr.1: fix when-match appearing in place of while-match. Reported by Ray Perry.
* doc: election typo.Kaz Kylheku2021-06-251-1/+1
| | | | * txr.1: Under Listener, selection was mistyped as election.
* build: fix broken building in separate directory.Kaz Kylheku2021-06-251-1/+1
| | | | | | | * configure: create a link farm for stdlib, not share, which no longer exists. I missed this because this is an occurrence of "share" not followed by /txr of \txr. Reported by Paul. A. Patience
* Version 264txr-264Kaz Kylheku2021-06-257-803/+861
| | | | | | | | | | | | * RELNOTES: Updated. * configure, txr.1: Bumped version and date. * stdlib/ver.tl: Bumped. * txr.vim, tl.vim: Regenerated. * protsym.c: Likewise.
* windows: adjust to stdlib rename.Kaz Kylheku2021-06-251-3/+3
| | | | | * inst.nsi: refer to library materials in stdlib rather than share\txr\stdlib.
* vim: improve json unquote situation.Kaz Kylheku2021-06-241-1/+2
| | | | | | | | * genvim.txr (jlist): Include txr_junqtok. (txr_junqtok): New region. Provides okay-ish match for ~ followed by unparenthesized Lisp item. For some reason, keywords aren't lit up specially, but it's still an improvement over just flagging everything as an error.
* signals: disable stack overflow in handler.Kaz Kylheku2021-06-242-0/+15
| | | | | | | | | | | * signal.c (sig_handler): For a is_cpu_exception signal, we temporarily disable the stack limit. It might be executing on the sigaltstack buffer, which is almost certainly below the stack limit. * tests/012/stack.tl: New test case. We raise a SIGSEGV and check that in the handler, the stack limit is disabled, and that we can executed code.
* txr: stack protection in pattern language.Kaz Kylheku2021-06-243-0/+13
| | | | | | | | | * txr.c (do_match_line, match_files): call gc_stack_check on entry. * tests/012/stack2.txr: New file. * tests/012/stack2.expected: New file.
* limit print depth/width when diagnosing oveflow.Kaz Kylheku2021-06-241-0/+11
| | | | | | | | | * eval.c (error_trace): If the error is a stack overflow, then save the printing depth and width, and set them to stringent values, to minimize recursion in the printer. This minimizes the chances of a segfault or runaway iteration under some conditions. A repro test case is (print '#1=(#1#)) entered into the listener.
* doc: standardize on "user-defined".Kaz Kylheku2021-06-241-7/+7
| | | | | * txr.1: Replace a few occurrences of "application-defined" with the more prevalent "user-defined", including in one heading.
* install-tests: use relative path in run.sh.Kaz Kylheku2021-06-241-1/+1
| | | | | | | | * Makefile (install-tests): In the generated run.sh, let's allow flexibility in the installation location of the tests by avoiding a cd to an absolute path where the tests are assumed to be installed. Let's assume that they are installed relative to where the run.sh script is, and cd there.
* parser: no string allocation when scanning floats.Kaz Kylheku2021-06-244-195/+211
| | | | | | | | | | | | | | | | | | | Each time the scanner processes a floating-point token, it allocates a string object, just so it can call flo_str. The object is then garbage. Let's stop doing that. * lib.c (flo_str_utf8): New function, closely based on flo_str. Takes a char * string. * lib.h (flo_str_utf8): Declared. * parser.l (out_of_range_float): Take the token as a const char * string instead of a Lisp string, so we can just pass yytext to this function. (grammar): Use flo_str_utf8 instead flo_str, and pass yytext to out_of_range_float. * lex.yy.c.shipped: Updated.
* Test for stack overflow protection.Kaz Kylheku2021-06-242-0/+34
| | | | | | * tests/012/stack.tl: New file. * tets/common.tl (mvtest): New macro.
* file layout: moving share/txr/stdlib to stdlib.Kaz Kylheku2021-06-2453-13/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This affects run-time also. Txr installations where the executable is not in directory ending in ${bindir} will look for stdlib rather than share/txr/stdlib, relative to the determined installation directory. * txr.c (sysroot_init): If we detect relative to the short name, or fall back on the program directory, use stdlib rather than share/txr/stdlib as the stdlib_path. * INSTALL: Update some installation notes not to refer to share/txr/stdlib but stdlib. * Makefile (STDLIB_SRCS): Refer to stdlib, not share/txr/stdlib. (clean): In unconfigured mode, remove the old share/txr/stdlib entirely. Remove .tlo files from stdlib. (install): Install lib materials from stdlib. * txr.1: Updated documentation under Deployment Directory Structure. * share/txr/stdlib/{asm,awk,build,cadr}.tl: Renamed to stdlib/{asm,awk,build,cadr}.tl. * share/txr/stdlib/{compiler,conv,copy-file,debugger}.tl: Renamed to stdlib/{compiler,conv,copy-file,debugger}.tl. * share/txr/stdlib/{defset,doc-lookup,doc-syms,doloop}.tl: Renamed to stdlib/{defset,doc-lookup,doc-syms,doloop}.tl. * share/txr/stdlib/{each-prod,error,except,ffi}.tl: Renamed to stdlib/{each-prod,error,except,ffi}.tl. * share/txr/stdlib/{getopts,getput,hash,ifa}.tl: Renamed to stdlib/{getopts,getput,hash,ifa}.tl. * share/txr/stdlib/{keyparams,match,op,optimize}.tl: Renamed to stdlib/{keyparams,match,op,optimize}.tl. * share/txr/stdlib/{package,param,path-test,pic}.tl: Renamed to stdlib/{package,param,path-test,pic}.tl. * share/txr/stdlib/{place,pmac,quips,save-exe}.tl: Renamed to stdlib/{place,pmac,quips,save-exe}.tl. * share/txr/stdlib/{socket,stream-wrap,struct,tagbody}.tl: Renamed to stdlib/{socket,stream-wrap,struct,tagbody}.tl. * share/txr/stdlib/{termios,trace,txr-case,type}.tl: Renamed to stdlib/{termios,trace,txr-case,type}.tl. * share/txr/stdlib/{ver,vm-param,with-resources,with-stream}.tl: Renamed to stdlib/{ver,vm-param,with-resources,with-stream}.tl. * share/txr/stdlib/yield.tl: Renamed to stdlib/yield.tl. * share/txr/stdlib/{txr-case,ver}.txr: Renamed to stdlib/{txr-case,ver}.txr. * gencadr.txr: Update to stdlib/place.tl. * genman.txr: Update to stdlib/cadr.tl.
* matcher: new looping macros.Kaz Kylheku2021-06-245-0/+163
| | | | | | | | | | | | | | * lisplib.c (match_set_entries): Autoload on new while-match, while-match-case and while-true-match-case symbols. * share/txr/stdlib/match.tl (while-match, while-match-case, while-true-match-case): New macros. * tests/011/patmatch.tl: Tests. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* matcher: remove unused gensym.Kaz Kylheku2021-06-241-1/+0
| | | | | * share/txr/stdlib/match.tl (if-match): match-p gensym is not used; remove it.
* New: stack overflow protection.Kaz Kylheku2021-06-2310-3/+169
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * configure: detect getrlimit, producing HAVE_RLIMIT in config.h. * eval.c (do_eval, do_expand): Call gc_stack_check inline function to check stack pointer against limit. * gc.c (gc_stack_bottom): Static becomes extern, so inline function in gc.h can refer to it. (gc_stack_limit): New global variable. (gc_init): If we have rlimit, then probe RLIMIT_STACK. If the stack is sufficiently large, then enable the stack overflow protection, which kicks in when the stack pointer appears to be within a certain percentage of the limit. (set_stack_limit, get_stack_limit): New static functions. (gc_late_init): Register set-stack-limit and get-stack-limit intrinsics. (gc_stack_overflow): New function. * gc.h (gc_stack_bottom, gc_stack_limit, gc_stack_overflow): Declared. (gc_stack_check): New inline function. * lib.c (stack_overflow_s): New symbol variable. (obj_print_impl): Call gc_stack_check to protect recursive printing againts overflow. * lib.h (stack_overflow_s): Declared. * unwind.c (uw_init): Register stack-overflow symbol as a an exception symbol subtyped from error. (uw_unwind_to_exit_point): When dealing with an unhandled exception, turn off the stack limit, so we can print the messages without triggering it in a loop. * vm.c (vm_execute_closure, vm_funcall_common): Insert gc_stack_check to the top of the execution of every VM function. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.
* lib: use existing self variable.Kaz Kylheku2021-06-231-2/+2
| | | | | * lib.c (populate_obj_hash): Refer to self, rather than hard coding function name prefix.
* cmp_str: whitespace.Kaz Kylheku2021-06-231-37/+37
| | | | * lib.c (cmp_str): Fix incorrect indentation.
* long-suffix: fix crash reproducing on Cygwin.Kaz Kylheku2021-06-231-3/+1
| | | | | | * stream.c (long_suffix): Remove stray wcspbrk(dot, psc) call from the body of loop, which sometimes occurs when dot is null. It may have been optimized away, so I didn't notice.
* cyr: broken on 64 bit.Kaz Kylheku2021-06-231-2/+3
| | | | * lib.c (cyr): We must use the cnum type for the mask, not int.
* c_str now takes a self argument.Kaz Kylheku2021-06-2321-231/+297
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adding a self parameter to c_str so that when a non-string occurs, the error is reported against a function. Legend: A - Pass existing self to c_str. B - Define self and pass to c_str and possibly other functions. C - Take new self parameter and pass to c_str and possibly other functions. D - Pass existing self to c_str and/or other functions. E - Define self and pass to other functions, not c_str. X - Pass nil to c_str. * buf.c (buf_strm_put_string, buf_str): B. * chksum.c (sha256_str, md5_str): C. (sha256_hash, md5_hash): D. * eval.c (load): D. * ffi.c (ffi_varray_dynsize, ffi_str_put, ffi_wstr_put, ffi_bstr_put): A. (ffi_char_array_put, ffi_wchar_array_put): C. (ffi_bchar_array_put): A. (ffi_array_put, ffi_array_out, ffi_varray_put): D. * ftw.c (ftw_wrap): A. * glob.c (glob_wrap): A. * lib.c (copy_str, length_str, coded_length,split_str_set, list_str, cmp_str, num_str, out_json_str, out_json_rec, display_width): B. (upcase_str, downcase_str, string_extend, search_str, do_match_str, do_rmatch_str, sub_str, replace_str, cat_str_append, split_str_keep, trim_str, int_str, chr_str, span_str, compl_span_str, break_str, length_str_gt, length_str_ge, length_str_lt, length_str_le, find, rfind, pos, rpos, mismatch, rmismatch): A. (c_str): Add self parameter and use in type mismatch diagnostic. If the parameter is nil, use "internal error". (flo_str): B, and correction to "flot-str" typo. (out_lazy_str, out_quasi_str, obj_print_impl): D. * lib.h (c_str): Declaration updated. * match.c (dump_var): X. (v_load): D. * parser.c (open_txr_file): C. (load_rcfile): E. (find_matching_syms, provide_atom): X. (hist_save, repl): B. * parser.h (open_txr_file): Declaration updated. * parser.y (chrlit): X. * regex.c (search_regex): A. * socket.c (getaddrinfo_wrap, sockaddr_pack): A. (dgram_put_string): B. (open_sockfd): D. (sock_connect): E. * stream.c (stdio_put_string, tail_strategy, vformat_str, open_directory, open_file, open_tail, remove_path, rename_path, tmpfile_wrap, mkdtemp_wrap, mkstemp_wrap): B. (do_parse_mode, parse_mode, make_string_byte_input_stream): B. (normalize_mode, normalize_mode_no_bin): E. (string_out_put_string, formatv, put_string, open_fileno, open_subprocess, open_command, base_name, dir_name, short_suffix, long_suffix): A. (run): D. (win_escape_cmd, win_escape_arg): X. * stream.h (parse_mode, normalize_mode, normalize_mode_no_bin): Declarations updated. * sysif.c (mkdir_wrap, do_utimes, dlopen_wrap, dlsym_wrap, dlvsym_wrap): A. (do_stat, do_lstat): C. (mkdir_nothrow_exists, ensure_dir): E. (chdir_wrap, rmdir_wrap, mkfifo_wrap, chmod_wrap, symlink_wrap, link_wrap, readlink_wrap, exec_wrap, getenv_wrap, setenv_wrap, unsetenv_wrap, getpwnam_wrap, getgrnam_wrap, crypt_wrap, fnmatch_wrap, realpath_wrap, opendir_wrap): B. (stat_impl): statfn pointer-to-function argument now takes self parameter. When calling it, we pass name. * syslog.c (openlog_wrap, syslog_wrapv): A. * time.c (time_string_local, time_string_utc, time_string_meth, time_parse_meth): A. (strptime_wrap): B. * txr.c (txr_main): D. * y.tab.c.shipped: Updated.
* short-suffix, long-suffix: no match across slash.Kaz Kylheku2021-06-223-8/+96
| | | | | | | | | | | * stream.c (short_suffix, long_suffix): Take path separator characters into account; the suffix must not span across separators. The trailing separator must also not appear in the suffix. * tests/018/path.tl: Test cases added. * txr.1: Redocumented.
* lib: rmismatch tests and bugfix.Kaz Kylheku2021-06-222-1/+40
| | | | | | | * lib.c (rmismatch): when left is an empty string or vector, and right is nil: we must return -1 not zero. * tests/012/seq.tl: More rmismatch tests.
* lib: optimize mismatch, rmismatch for strings.Kaz Kylheku2021-06-222-3/+95
| | | | | | | | | | | * lib (mismatch, rmismatch): If the arguments are strings or literals, other than lazy strings, keyfun is identity, and equality is by character identity, the operation can be done with an efficient loop over the wchar_t strings. * tests/012/seq.tl: Tests for string case of mismatch, via starts-with function. Test mismatch via ends-with, and also directly for vectors and strings.
* New functions: long-suffix, short-suffix.Kaz Kylheku2021-06-225-0/+116
| | | | | | | | | | | | | | * stream.c (short_suffix, long_suffix): New functions. (stream_init): short-suffix and long-suffix intrinsics registered. * stream.c (short_suffix, long_suffix): Declared. * tests/018/path.tl: New file. * txr.1: Documented. * share/txr/stdlib/doc-syms.tl: Updated.