summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* random: shift bug uncovered by ubsan.Kaz Kylheku2022-02-141-1/+3
| | | | | | * rand.c (random): When calculating the msb_rand_mask, avoid shifting a 32 bit value by 32 bits. In that case we want the mask to be 0xFFFFFFFF, so we shift by zero.
* tests: don't run tets/012/stack.tl if built with ubsan.Kaz Kylheku2022-02-142-0/+8
| | | | | | | | | * configure (have_ubsan): New variable. This is set to y in the ubsan test, if detected. (gen_config_make): Add have_ubsan variable to config.make. * Makefile (TESTS_OK): If have_ubsan is true, filter out the ../012/stack.ok target that calls for that test case.
* tree: fix array underruns found by ubsan.Kaz Kylheku2022-02-141-11/+17
| | | | | | | | | | | | | | | | | | | | | * tree.c (tn_find_low): In this function it may happen that we are looking for a low bound that is beyond the highest value in the tree. In this situation, tdi->lastnode is nil; the loop that walks back up the path will not find it, and underrun. Now the word before the path array is the tree_iter_state, which is zero. That zero word terminates the loop so things work by fluke. (tr_find_rebuild_scapegoat): Firstly, since in this function we pre-decrement ti->depth, we guard the whole thing by ti->depth > 0. This is just a precaution; the algorithm guarantees that a scapegoat will be found, so this will not recurse to the depth == 0 case. The main fix here is this: we sometimes call tr_rebuild in the case when the parent is the root node. In that case, there is no grandparent. The path is empty and we are accessing before the array to try to fetch the nonexistent grandparent. Again, by fluke, there is a zero there thanks to the tree_iter_state which turns into a null pointer that tells tr_rebuild that the node has no parent. The correct way is to check the depth and pass nil as the grandparent if ti->depth is zero.
* Fix more -fsanitize=implicit-conversion findings.Kaz Kylheku2022-02-143-4/+7
| | | | | | | | | | | | | | | | | | | | | * arith.c (highest_significant_bit): Bugfix: do not pass a negative value to highest_bit, where we will get then get the wrong idea about the number of significant bits in the value, since the __builtin_clz primitives will include the sign bit. We want to complement the all the bits, so that the sign bit will go to zero. We can do this arithmetically by taking the additive inverse (which is the two's complement (which is the complement plus one)) and subtracting one. (ash): Avoid left shifting a negative number in HAVE_UBSAN mode using the same trick as in num_fast. * ffi.c (ffi_swap_u16): Here the shift and or calculation is producing a value beyond 16 bits which we are relying on the implicit conversion back to uin16_t to trim away. We add the cast to uint16_t to make it explicit. * hash.c (equal_hash): Also handle the CHR and NUM cases here via c_u like in eql_hash and eq_hash.
* Fix some issues found by ubsan.Kaz Kylheku2022-02-143-24/+29
| | | | | | | | | | | | | | | | * lib.h (num_fast): Under HAVE_UBSAN, avoid left shifting a negative value, which is diagnosed by ubsan (by default), but is otherwise a documented GCC extension that behaves sanely in the manner one would expect on two's complement machines. * mpi/mpi.c (s_mp_mul_2d): Fix instance of undefined shift equal to the width of the type. This occurs in the case when d == 0. In that case, we try to calculate a 32 or 64 bit full mask by shifting 1 to the left that many times and then subtracting 1. However, the entire code for the fractional shift is not necessary in that case and may be skipped. I'm also removing the unnecesary s_mp_clamp call. If the number is clamped on entry into the function, it stays clamped.
* configure: detect ubsan compilation.Kaz Kylheku2022-02-141-0/+21
| | | | | | | | * configure: detect that the compiler is generating undefined behavior sanitizer code, a feature supported in GCC and Clang. The tell-tale sign of this is that "ubsan" occurs in the executable. If so, we deposit #define HAVE_UBSAN 1 into config.h.
* Another implicit conversion in continuations implementation.Kaz Kylheku2022-02-141-1/+1
| | | | | | * unwind.c (revive_cont): Explicitly convert delta, which is necessarily signed because it may be negative, to uint_ptr_t before adding it to that type.
* Few adjustments to no-implicit-conversion patch.Kaz Kylheku2022-02-143-15/+15
| | | | | | | | | | | | | | | | | | | | * lib.h (c_u): New inline function: unsafe conversion to ucnum, analogous to c_n for cnum. * hash.c (equal_hash, hash_iter_init): Use UINT_PTR_MAX instead of convert(ucnum, -1). (eql_hash): mp_hash returns unsigned long, so shouldn't require a cast to go to the uint_ptr_t. The types are of the same size, or at worst it is a widening. Also replace convert(ucnum, -1) by UINT_PTR_MAX here. Combining the TAG_CHR and TAG_NUM cases, and using c_u, which is more efficient since c_chr and c_num are non-inlined functions which redundantly check type. We no longer need a self variable in this function. (eq_hash): Same TAG_CHR and TAG_NUM changes as eql_hash. * regex.c (char_set_add): Reformat change to avoid line break across assignment.
* Fix various instances of implicit conversions.Paul A. Patience2022-02-146-13/+14
| | | | | | | | | | | | | | | | | | | | | The implicit conversions were discovered with Clang's UBSan (with the -fsanitizer=implicit-conversion option). * gc.c (sweep_one): Convert only the inverted REACHABLE, since block->t.type is already of the right type. * hash.c (eql_hash, eq_hash, hash_iter_init, us_hash_iter_init): Explicitly convert to ucnum. * linenoise/linenoise.c (enable_raw_mode): Explicitly convert the inverted flag sets to tcflag_t. * mpi/mpi.c (mp_set_uintptr): Explicitly convert to uint_ptr_t. * regex.c (char_set_add): Explicitly convert to bitcell_t. * struct.c (struct_inst_hash): Correct type of hash from cnum to ucnum.
* sockets: appease -Wint-in-bool-context warning.Paul A. Patience2022-02-131-2/+2
| | | | | | * socket.c (open_socket, socketpair_wrap): Replace logical OR of SOCK_NONBLOCK and SOCK_CLOEXEC with bitwise OR in order to silence Clang 13's -Wint-in-bool-context warning.
* doc: document catenated .tlo files.Kaz Kylheku2022-02-131-0/+35
| | | | | * txr.1: Under load and compile-file, mention the support for loading catenated .tlo files.
* New function: cat-files.Kaz Kylheku2022-02-134-1/+35
| | | | | | | | | | | * 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.
* load: support loading catenated .tlo files.Kaz Kylheku2022-02-131-13/+20
| | | | | | | | * parser.c (read_file_common): Tolerate the presence of version expressions, as long as they match the initial version under equal. Thus a larger .tlo file can be made of two or more .tlo files by simple catenation; it will load as long as they have exactly the same version.
* all: wrong self name.Kaz Kylheku2022-02-131-1/+1
| | | | * lib.c (all_satisfy): self should be "all" rather than "some".
* doc: remove extraneous symbols from doc-syms.Paul A. Patience2022-02-122-30/+16
| | | | | | | * 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.
* doc: add missing < and << in some .mets lines.Paul A. Patience2022-02-121-13/+13
| | | | | * txr.1: Add < and << in the signatures of various stream methods.
* 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.
* getopts: forbid :bool in list/cumul types.Paul A. Patience2022-02-122-7/+17
| | | | | | | * stdlib/getopts.tl (list-type-p): Return nil if subtype is :bool. (cumul-type-p): Same. * txr.1: Documented, reworded some sentences, fixed some typos.
* macro-time: special op becomes a macro.Kaz Kylheku2022-02-123-146/+135
| | | | | | | | | | | | | * eval.c (me_macro_time): New static function (do_expand): Remove handling of macro_time_s. (eval_init): Remove special operator registration of macro-time; add macro registration. * txr.1: Documentation of macro-time updated, revised and moved from the top the Macros section to be adjacent to equot. * stdlib/doc-syms.tl: Updated.
* matcher: test case for `@{nil #/regex/}`.Kaz Kylheku2022-02-091-0/+2
| | | | * tests/011/patmatch.tl: New tests for recently fixed issue.
* doc: fix references to inexistent handler macro.Paul A. Patience2022-02-091-4/+4
| | | | * txr.1: Correct "handler" to "handle".
* matcher: fix `@{nil #/regex/}` throwing exception.Paul A. Patience2022-02-091-2/+5
| | | | | | * stdlib/match.tl (expand-quasi-match): We cannot call m^$ with the @nil-bound rest of string when matching `@{nil #/regex/}`. Handle this case specially.
* doc: fix issues in arguments to .I macros.Paul A. Patience2022-02-091-11/+11
| | | | | | | * txr.1: Correct .I to .IR when the arguments include trailing punctuation. Add quotes around multiword .I and .IR arguments to be consistent everywhere. Unitalicize "de facto". Fix accidental trailing sentence.
* doc: fix pad's argument list.Paul A. Patience2022-02-091-1/+6
| | | | * txr.1: Document pad's object parameter as optional.
* getopts: fix superfluous options header.Paul A. Patience2022-02-081-24/+26
| | | | | * stdlib/getopts.tl (opthelp): Print the options header only if we have documented options.
* getopts: fix de trop descriptions of conventions.Paul A. Patience2022-02-081-18/+20
| | | | | | * stdlib/getopts.tl (opthelp-conventions): Describe the --no- prefix only if we have boolean options, and describe the long-option argument style only if we have long options.
* getopts: conform undocumented opts to documented.Paul A. Patience2022-02-081-2/+2
| | | | | | * stdlib/getopts.tl (opthelp): Indent the list of undocumented options by only two spaces, like the documented options and the other opthelp sections.
* getopts: uniformize opthelp newlines and headers.Paul A. Patience2022-02-082-7/+7
| | | | | | | | | | | | | | | | The documented options and type legend both end in a blank line, unlike the undocumented options and option conventions. * stdlib/getopts.tl (opthelp): Print a blank line after the undocumented options. (opthelp-conventions): Print a blank line after the conventions. Also, change the header from "Option Conventions" to "Option conventions" to follow the style of the undocumented options and type legend. * txr.1: Remove superfluous (as of now) put-line calls in the --extra-help example of getopts. While here, correct o.extrahelp to o.extra-help.
* doc: fix a few more typos.Paul A. Patience2022-02-071-10/+11
| | | | * txr.1: Fix typos.
* lib: fix return value of separate for nil seq.Paul A. Patience2022-02-071-1/+1
| | | | | * lib.c (separate): Return (list nil nil) instead of just nil when the sequence parameter is nil, as is documented.
* txr: -D bugfixes.Kaz Kylheku2022-02-061-12/+25
| | | | | | | * txr.c (txr_main): Don't use split_str to break -Dvar=val syntax, because that splits on all occurrences of the = character. Secondly, diagnose -Da,b,c shape: list commas occur with no = sign.
* doc: fix various typos and stylistic issues.Paul A. Patience2022-02-062-79/+87
| | | | | | * txr.1: Fix typos and stylistic issues. * stdlib/doc-syms.tl: Updated.
* Use null_string throughout code base.Kaz Kylheku2022-02-056-11/+12
| | | | | | | | | | | | | | | | * eval.c (load): Use null_string instead of lit(""). * lib.c (obj_init): Likewise. * match.c (LOG_MATCH, LOG_MISMATCH, do_txeval): Likewise. * parser.c (regex_parse, lisp_parse_impl, find_matching_syms): Likewise. * stream.c (do_parse_mode): Likewise. * txr.c (sysroot_init): Likewise. (txr_main): Replace string(L"") with null_string.
* doc: no such thing as -Da,b,cKaz Kylheku2022-02-051-2/+4
| | | | | * txr.1: Fix the example -Da,b,c to -Dvar=a,b,c. Reported by Paul A. Patience.
* txr: bind -D-valueless variables to empty string.Paul A. Patience2022-02-051-1/+1
| | | | | * txr.c (txr_main): Bind variables specified with -D but without values to the empty string, as documented in the manual.
* vim: improvement multi-line strings.Kaz Kylheku2022-02-041-5/+5
| | | | | | | | | | | | | | | | | | Vim's handling of multi-line Lisp strings is glitchy. We are contributing to it by tryign to match the backslash-newline as an escape sequence. As a result of this change, Vim is less confused. Indentation is still incorrect after some multi-line strings, but I'm not seeing the discrepancy between the behavior of the visual parentheses matching, and the % parentheses jump. I'm able to navigate around in the stdlib/getopts.tl code. * genvim.txr (chesc): Remove the backslash-newline from the list of character escapes. (txr_string, txr_quasilit, txr_regex, tx_regex): Use skip= to recognize the backslash-newline sequence as part of the literal.
* getopt: opthelp: bind *stdout* to remove stream repetition.Kaz Kylheku2022-02-041-15/+15
| | | | | | | * stdlib/getopts.tl (opthelp, opthelp-conventions, opthelp-types): Use *stdout* as the optional stream argument, defaulting to *stdout*. Now we no longer have to explicitly pass the stream to put-line.
* matcher: bug: quasiliteral allowing prefix matches.Kaz Kylheku2022-02-042-4/+8
| | | | | | | | * stdlib/match.tl (expand-quasi-match): When matching `text` or `@var`, which are matching in the final position of the specimen, it is not good enough that match-str returns true; we must check that the entire string was matched. Reported by Paul A. Patience.
* getopts: break up help into three functions.Kaz Kylheku2022-02-034-92/+143
| | | | | | | | | | | | | | | | * lisplib.c (getopts_set_entries): Autoload for opthelp-conventions and opthelp-types. * stdlib/getopts.tl (opthelp): Remove incnotes parameter. Entirely trim out the code for notes about conventions and use of types. (opthel-conventions, opthelp-types): New functions. (option-base opthelp-conventions, option-base opthelp-types): New methods. * txr.1: Documented. * stdlib/doc-syms.tl: Updated.
* getopts: make detailed help notes optional.Joe Bloggs2022-02-032-74/+79
| | | | | | | | | | * stdlib/getopts.tl (opthelp): New incnotes parameter. If specified as false, disables the detailed Notes and Type legend. (sys:option-base opthelp): Same new parameter on this method, passed down to opthelp. * txr.1: Documented.
* doc: fix in amb macro.Kaz Kylheku2022-02-031-2/+3
| | | | | | | | | | | | | | * txr.1: when the amb macro detects that the continuation has succeeded, it should return that successful value from the amb-scope, rather than returning the local successful argument a from the amb function. Although it works both ways, it is inefficient when it returns from the function. The reason is that each call to amb executes the successful future twice: once via (call cont a) and then again by returning the a value. This then causes an exponential cascade in calls: each successive amb call sthe successful future twice, so for instance if the solution has a sequence of 8 amb calls, the successful case is reached 256 times.
* quip: joke about dark mode.Kaz Kylheku2022-02-031-0/+1
| | | | * quips.tl (%quips%): New one.
* doc: window-mappend typo.Kaz Kylheku2022-02-021-1/+1
| | | | | * txr.1: The window-mapdo function is analogous to mapdo, not window-mappend. Reported by vapnik spaknik.
* getopts: fix display of overlong-option help text.Paul A. Patience2022-02-021-1/+3
| | | | | | | | * stdlib/getopts.tl (opthelp): If the long/short part of an option description is 34 characters long or more, print the help text starting on the next line, lest it be glued to the long/short part (i.e., without an intervening space) and extend too far to the right.
* getopts: fix ignored stream parameter in opthelp.Paul A. Patience2022-02-021-14/+13
| | | | | * stdlib/getopts.tl (opthelp): Actually use the function's stream parameter in the put-line calls.
* cadr: re-running gencadr.txr.Kaz Kylheku2022-01-303-36/+39
| | | | | | | * cadr.c, cadr.h, stdlib/cadr.tl: Regenerated. All that changes is the formatting of the copyright block, since now it is scraped from files that reformatted it to 80 columns half a year ago.
* conv: extra blank line removed.Kaz Kylheku2022-01-301-1/+0
| | | | | * stdlib/conv.tl: Extra blank line after copyright header removed.
* stdlib: missing blank line after copyright header.Kaz Kylheku2022-01-3036-0/+36
| | | | | | | | | | | | | | | Commit 93edcde038209335122964432bd35dee0c2ecb04, made in August 2021, accidentally removed the blank line after the copyright header in most stdlib files. stdlib{asm.tl, awk.tl, build.tl, compiler.tl, copy-file.tl, debugger.tl, doloop.tl, each-prod.tl, error.tl, except.tl, ffi.tl, getopts.tl, getput.tl, hash.tl, ifa.tl, match.tl, op.tl, package.tl, param.tl, path-test.tl, pic.tl, place.tl, pmac.tl, quips.tl, save-exe.tl, socket.tl, stream-wrap.tl, tagbody.tl, termios.tl, trace.tl, txr-case.tl, type.tl, vm-param.tl, with-resources.tl, with-stream.tl, yield.tl}: Ensure there is a blank line after the copyright header.