summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
...
* Add mode-opt to all I/O convenience functions.Kaz Kylheku2022-06-292-33/+33
| | | | | | | | | | | * 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.
* close-stream: process wait cleanup.Kaz Kylheku2022-06-241-18/+6
| | | | | | | | | * stream.c (pipe_close_status_helper): Revise error messages. Get rid of impossible cases: we will not get WIFSTOPPED or WIFCONTINUED unless we used the WUNTRACED option in waitpid, which we don't. No platforms without HAVE_SYS_WAIT, don't throw if the status is nonzero; just return nil. It could be a normal termination.
* 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.
* More HAVE_FORK_STUFF cleanup.Kaz Kylheku2022-06-241-3/+3
| | | | | | * stream.c (pipe_close_status_helper, pipe_close, pipe_ops): Included in #if HAVE_FORK_STUFF block. (stream_init): Refer to pipe ops only if HAVE_FORK_STUFF is true.
* streams: remove old code for popen on MingGW.Kaz Kylheku2022-06-214-174/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is vestigial code from a time when TXR supported being compiled with MinGW. Except in the case of the functions run and sh, which are implementable without fork on Cygwin using the spawn family of functions, there won't be any fallback; if HAVE_FORK_STUFF is zero or missing, then certain functions will be absent. * stream.c (struct stdio_handle): Do not define a pid member if we don't HAVE_FORK_STUFF. (se_pclose): Function removed; we won't be using any non-POSIX platforms popen/pclose. (pipe_close): Don't call the removed se_pclose. (make_pipe_stream): Function removed. (fds_subst, fds_swizzle): Don't define these if HAVE_FORK_STUFF is absent, and so is HAVE_WSPAWN and HAVE_SPAWN. They are now only needed by the version of the run function that uses spawn or wspawn. (open_command, open_process): Remove the versions of these function based on popen. (string_extend_count, win_escape_cmd, win_escape_arg, win_make_cmdline): Remove these functions used by the above open_process; we have no need for encoding arguments into a Windows command line string, since the Cygwin/Cygnal libraries do that for us in their spawn and exec functions. * stream.h (make_pipe_stream): Function removed. * utf8.[ch] (w_popen): Function removed.
* bugfix: missing gzip support in open-command.Kaz Kylheku2022-06-216-55/+118
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * stream.c (pipe_close_status_helper): New function, factored out of pipe_close and used by it, and also by gzio_close. (pipe_close): Call pipe_close, which now contains the classification of process wait status codes. (open_fileno): Now takes optional pid argument. If this specified, then make_pipevp_stream is used. (open_subprocess): Use the open_fileno function, rather than fopen. This simplifies things too, except that we have to catch exception. Pass pid to the newly added parameter of open_fileno so that we obtain a proper pipe stream that will wait for the process to terminate when closed. (mkstemp_wrap): Pass nil for pid argument of open_fileno. (stream_init): Update registration of open-fileno. * gzio.c (struct gzio_handle): New member, pid. (gzio_close): If there is a nonzero pid, wait for the process to terminate. (make_gzio_stream): Initialize h->pid to zero. (make_gzio_pipe_stream): New function. * parser.c (lino_fdopen): Pass nil for pid argument of open_fileno. * gzio.h (make_gzio_pipe_stream): Declared. * tests/018/gzip.tl: New test.
* configure: remove unused android_targetKaz Kylheku2022-06-211-2/+0
| | | | * configure (android_target): Remove unused variable.
* for/for*: stricter syntax check.Kaz Kylheku2022-06-133-18/+19
| | | | | | | | | | | | | | | | | * 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-126-40/+136
| | | | | | | | | | | | | | | 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.
* listener: bugfix: handle warnings around linenoise.Kaz Kylheku2022-06-081-0/+4
| | | | | | | | | | | * parser.c (repl): Also push and pop the warning handler around the linenoise call, like we do around evaluation. The reason is that when the library is used in source code form, it can generate warnings while loading. Loading can be triggered by completion from inside linenoise. Neglecting to handle warnings and throw a continue causes a problem because the warnings then fall victim to the listener's master catch. That then interferes with the load.
* string-out-stream: gc issue.Kaz Kylheku2022-06-061-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The problem being addressed here showed up for me when compiling with either gcc-7 or gcc-11 on Ubuntu 18, using -fsanitize-undefined. A few test test cases run under --gc-debug were crashing. I narrowed it down to this small test case, whose correct output would be "1": ./txr --gc-debug -p '(sys:fmt-simple 1 : : : :)' "\x6700ACB0缻\x6700ACB0缻 " The issue doesn't have anything to do with -fsanitize-undefined; that just how it got reproduced by chance. I'm reasonably certain that in builds for which "make tests" passes, and the above test case doesn't repro, this issue is absent: the code got generated in such a way that it the string_own call doesn't cause the stream object to be reclaimed. * stream.c (get_string_from_stream): change the order of operations in the ownership transfer of the string from the stream to the returned string object. We capture the string in a local variable, and null out so->buf before calling string_own. The problem is that get_string_from_stream is called in a way where the caller no longer has any use for the stream, and so the object is no longer live. It's possible for the string_own call to cause the stream object to be garbage collected. Therefore, the object must not still be hanging on to the wchar_t * string, which was already transferred to the string object.
* txr: fix --free-all crash due to atexit order.Kaz Kylheku2022-06-053-14/+15
| | | | | | | | | | | | | | | | | | | | | | | | The --free-all feature is broken. It is needed for confirming lack of memory leaks during development. What breaks it is the atexit call to run_load_hooks in eval.c, which occurs after the atexit call to free_all in txr.c which blows everything away. * Makefile (tst/tests/019/load-hook.ok): Let's put --free-all on this test case, because it has to with the load hooks. Make no mistake though: everything crashes with --free-all, not this test case specifically. * txr.c (opt_free_all): New global variable. (free_all): Free resources only if opt_free_all is true. Lose the paranoid called flag. (main): Register free_all with atexit before callilng init. This ensures that it will be called after any atexit handlers registered as part of init, like the one in sysif.c and eval.c. (txr_main): The --free-all option now just sets opt_free_all. * txr.h (opt_free_all): Declared.
* doc: missing word in tree-insert section.Kaz Kylheku2022-06-011-0/+1
| | | | * txr.1: Add missing "If" at start of sentence.
* build: fix broken build when we don't HAVE_ZLIB.Kaz Kylheku2022-05-312-0/+21
| | | | | | | | | | | * parser.c (open_txr_file): Use liberal heaps of #if HAVE_ZLIB. If there is no Zlib, and the caller explicitly requests a .tlo.gz file to be loaded, then throw. Do not implicitly look for a .tlo.gz file. * stream.c (open_file): #if HAVE_ZLIB around a goto label that is only used out of HAVE_ZLIB code, to eliminate unused label warning.
* streams: use ~a for self string.Kaz Kylheku2022-05-311-3/+3
| | | | | | * stream.c (parse_mode, open_file, open_fileno): Since self is a string, use ~a to print it, or else quotes will appear.
* Version 277.txr-277Kaz Kylheku2022-05-316-1123/+1158
| | | | | | | | | | | | * RELNOTES: Updated. * configure (txr_ver): Bumped version. * stdlib/ver.tl (lib-version): Bumped. * txr.1: Bumped version and date. * txr.vim, tl.vim: Regenerated.
* crc32: name clash with Zlib on Android.Kaz Kylheku2022-05-312-3/+2
| | | | | | | * chksum.c (crc32): Stop-gap solution: make it static. Also, fix wrong self-string. * chksum.h (crc32): Declaration removed.
* windows: bundle Zlib in installer.Kaz Kylheku2022-05-311-0/+1
| | | | * inst.nsi: pull in cygz.dll.
* cygwin: bug: sh always uses cmd.exe.Kaz Kylheku2022-05-312-18/+7
| | | | | | | | | | * stream.c (sh): Use a single definition for this function, which uses the shell and shell_arg variables to use either /bin/sh -c or cmd.exe /c. We only want to use cmd.exe when running as a Windows native program on Cygnal. * tests/018/process.tl: Remove workaround from test case. This is what was causing the weirdness.
* gzio: unused variable warning.Kaz Kylheku2022-05-311-1/+0
| | | | * gzio.c (gzio_set_prop): Remove unused ops variable.
* gzio: fix multiple definition of gzio_stream_s.Kaz Kylheku2022-05-312-1/+3
| | | | | | | | Failed on Cygwin. * gzio.c (gzio_stream_s): Variable defined here. * gzio.h (gzio_stream_s): Turn to declaration with extern.
* buf: compression tests.Kaz Kylheku2022-05-303-3/+22
| | | | | | | | | | * 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.
* gzio: some tests.Kaz Kylheku2022-05-301-0/+53
| | | | * tests/018/gzip.tl: New file.
* New: spln and tokn functions.Kaz Kylheku2022-05-306-2/+78
| | | | | | | | | | | | | | | 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-285-10/+52
| | | | | | | | | | | | | | * 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.
* gzio: remove unused variables.Kaz Kylheku2022-05-281-2/+0
| | | | * gzio.c (gzio_stream_print, gzio_get_prop): Remove unused locals.
* buf: compression and decompression functions.Kaz Kylheku2022-05-283-0/+119
| | | | | | | | | * 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.
* buf: remove stray utf8 declaration.Kaz Kylheku2022-05-281-2/+0
| | | | * buf.c (utf8_dup_to_buf): stray declaration removed.
* tags: rename to avoid name clash.Kaz Kylheku2022-05-272-1/+1
| | | | | | | | * tags.tl: File renamed to txrtags.tl. * libtags.txr: load "txrtags" rather than "tags". And here is where we can explain the problem being fixed: (load "tags") loads the actual tags file, if it already exists, and not tags.tl.
* streams: remove workaround for older Cygwin bug.Kaz Kylheku2022-05-271-7/+0
| | | | | | * stream.c (se_putc): Remove a workaround for a Cygwin bug that was fixed in 2016 in 2.5.0. Here is the mailing list thread: https://sourceware.org/pipermail/cygwin/2016-March/226554.html
* 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.
* load: support .tlo.gz files.Kaz Kylheku2022-05-271-9/+38
| | | | | | * parser.c (open_txr_file): If a file ends in .tlo.gz, open a gzio stream on it. Also search for .tlo.gz if .tlo is not found.
* gc: bug: fix compilation if HAVE_VALGRIND.Kaz Kylheku2022-05-271-1/+2
| | | | | * gc.c (mark_obj_maybe): Avoid declaration after statement, which is enforced when configured in --maintainer mode.
* gzio: include type in printed representation of stream.Kaz Kylheku2022-05-271-2/+16
| | | | | | * gzio.c (gzio_stream_print): New static function. (gzio_ops_rd, gzio_ops_wr): Wire in function instead of stream_print_op.
* gzio: bugfix: just return descr for :name property.Kaz Kylheku2022-05-271-1/+1
| | | | | | * gzio.c (gzio_get_prop): Don't play games with a computed :name; this property is relied upon for getting the path associated with an open file.
* 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.
* gzio: support :byte-oriented prop.Kaz Kylheku2022-05-271-2/+10
| | | | | | | * gzio.c (gzio_get_prop, gzio_set_prop): Handle :byte-oriented symbol, connecting it to the is_byte_oriented flag. This is already implemented, by copy and paste from the stdio routines.
* gzio: remove real-time-mode flag.Kaz Kylheku2022-05-271-2/+0
| | | | | * gzio.c (struct gzio_handle): Remove is_real_time flag. (make_gzio_stream): Remove initialization of flag.
* I/O convenience functions get mode-opt argument.Kaz Kylheku2022-05-272-56/+136
| | | | | | | | | | | | | | | | | | | | | 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.
* open-fileno: support "z" flag for gzip.Kaz Kylheku2022-05-261-12/+27
| | | | | * stream.c (open_fileno): Use w_gzdopen_mode and make_gzio_stream to make a gzio stream if the gzip flag is present.
* gzio: support more modes in open-file.Kaz Kylheku2022-05-264-3/+49
| | | | | | | | | | | | * gzio.c (w_gzopen_mode): Use w_open_mode if available, in order to support most of the flags (including "x" which Zlib has, but which we are not passing through). * stream.c (w_open_mode): New function formed from w_fopen_mode content. (w_fopen_mode): Call w_open_mode. * stream.c (w_open_mode): Declared.
* First cut at new feature: gzip streams.Kaz Kylheku2022-05-266-9/+631
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Makefile (OBJS): Conditionally include new gzio.o object file. * configure: Detect external zlib, setting up new have_zlib variable in config.make, HAVE_ZLIB in config.h, and also -lz in conf_ldlibs. * gzio.[ch]: New files, implementing the stream abstraction over the gzip file I/O routines in zlib. * stream.h (struct stdio_mode): New gzip flag and gzlevel bitfield to hold a value 0 to 9. (stdio_mode_init_blank, stdio_mode_init_r, stdio_mode_init_rpb): Update intializers to cover new bitfield members. * stream.c: Include <zlib.h> and "gzio.h" if HAVE_ZLIB. (do_parse_mode): Recognize new mode modifier letter "z", setting the gzip flag in the mode structure. If it's followed by a digit, set the gziplevel to that value. (format_mode): Don't output "b" letter for binary mode if gzip is set, because gzopen interprets "b" differently. Don't put out "t" if gzip is set. If gzip mode is specified, do put out the level. If gzip is set, and gziplevel is nonzero then encode the level: gzopen will understand it. (open_file): If gzip mode is requested, then open the file using gzopen mode, a new function in gzio.c. The return a gzio stream based on the returned gzip file handle. However, if we are reading, and the gzip stream indicates that it's not decompressing anything, then we close it and open the file using an ordinary stream. (stream_init): Call gzio_init if HAVE_ZLIB is true. This is done here because the module is integrated with stream.c, and also so that lib.c doesn't have to know about HAVE_ZLIB and <zlib.h>.
* open-file: show function name in bad modes diagnostic.Kaz Kylheku2022-05-261-1/+2
| | | | | | * stream.c (normalize_mode): Include the self symbol in the error message being thrown. This was not forgotten in the sister function normalize_mode_no_bin.
* stream-set-prop: return t on successful :name set.Kaz Kylheku2022-05-261-0/+1
| | | | | | * stream.c (stdio_set_prop): When setting the :name property, return t, to indicate it was recognized and stored, as is documented.
* streams: avoid double access to errno.Kaz Kylheku2022-05-261-2/+3
| | | | | * stream.c (stdio_maybe_read_error): Access errno once, and refer to the value.
* configure: don't exit on no mmap.Kaz Kylheku2022-05-261-2/+0
| | | | | | * configure: do not treat the failure to detect mmap as a fatal condition. This was just debugging commands accidentally left behind.
* tests: fix failing load-search test.Kaz Kylheku2022-05-261-1/+2
| | | | | | * tests/019/load-search.tl: skip a certain test if it is run as superuser; it fails because superuser is not affected by denied directory search and execute permissions.