summaryrefslogtreecommitdiffstats
path: root/tests
Commit message (Collapse)AuthorAgeFilesLines
* @(rebind): bugfix: don't clobber right side variable.Kaz Kylheku2021-01-302-0/+11
| | | | | | | | | | | | | | | | | | | | | * Makefile (tst/tests/000/binding.ok): Pass -B to txr for this new test. * match.c (v_rebind): Fix gaping copy-and-paste bug here, which causes rebind to take on the behavior of local/forget; it takes all symbols that appear as its arguments from the environment and produces an environment in which they don't exist. What we want is to remove the left variables from the environment, and since that is a nested pattern, the right way to do that is to flatten it. Bug reported by Frank Schwidom. * tests/000/binding.txr: New file. * tests/000/binding.expected: New file. * txr.1: Improve documentation of @(rebind), also making improvements in @(set) documentation.
* matcher: bugfix: @nil isn't trivial.Kaz Kylheku2021-01-291-0/+1
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (non-triv-pat-p): Extend sys:var match so (sys:var nil) is identified as trivial. * tests/011/patmatch.tl: Add broken test case fixed by this. This doesn't show up when @nil is used as the only match. It also doesn't show up if @nil is used in a vector or list in a mixture with other operators, because those other ones identify the overall list pattern as non-trivial. None of the occurrences of @nil in the existing test suite, like (@nil @nil @x) tickle the bug.
* matcher: restructuring to fix new broken case.Kaz Kylheku2021-01-281-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This one test case requires restructuring. The handling for the @(or ...) operator is now very different. To support @(or ...), there is now a new variant of the match-guard object called guard disjunction, which contains multiple match-guard chains. Furthermore, the separation between both guard-chain lists and compiled-match having a test expression and variables is being obliterated. For now, what we do is in a :postinit handler on compiled-match, we immediately convert the test-expr, vars and var-exprs slots into a match-guard object, which is placed into the guard-chain, and then we clear these slots. They are now vestigial only and will be removed. * tests/011/patmatch.tl: New test case which shows that (@(or foo bar) ...) does not short immediately short circuit to a failure when the corresponding element is neither foo nor bar. Matching proceeds to the right, wasting cycles and possibly causing errors. * share/txr/stdlib/match.tl (*match-var*): Move to top, above structs. There are some methods which refer to this variable now for throwing internal errors. (guard-disjunction): New object that is compatible with a match-guard, and placed into guard-lists as if it were a match-guard. This handles the bifurcation logic of an OR match. (compiled-match): New :postinit handler converts local vars, var-exprs and test-expr into a match-guard placed into the chain, and then clears these values. The compilation of code is done purely from the guard-chain. (compiled-match get-vars): This method is now complicated due to the guard-disjunction objects, and so uses a helper function called get-guard-values. (compiled-match get-var-exprs): New method accompanying get-vars to get the accompanying init expressions. (compiled-match wrap-guards): Two changes are going on here. One is that the funccion takes on more of the responsibility which was previously carried out by the callers. The callers were interpolating the test-expr and vars from a compiled-match into a piece of code, which was then passed to wrap-guards. Hence the naming: the job was just to wrap some guards. Now, wrap-guards is called just with the body forms, and does all of the work. Secondly, wrap-guards is complicated due to the handling of the guard-disjunction items. Also, there is some case handling to generate better code; we avoid generating an empty (let () ...) and (alet () ...). (compiled-match add-guard-pre, compiled-match add-guards-pre, compiled-match add-guards-post): New methods for adding guards after construction. These interfaces replace hacks of pushing new variables, tweaking the test-expr, or explicitly pushing guards onto the list. (get-guard-values): New function for iterating over a guard-chain, including match-guard and guard-disjunction items, retrieving a particular list-valued slot from each one using the fun argument, and returning a list of all those lists catenated together. (compile-struct-match, compile-vec-match, compile-range-match): Eliminate test-expr, replacing it with the harmless t. (compile-op-match): We don't try to extend the test-expr of the compiled var. Rather we add our guard expressin using the add-guard-pre interface. (compile-dwim-predicate-match): Likewise, and also, we do not calculate the test-expr for the output compiled-match from the constituent match test-exprs. We ignore those and just set the test-expr pat-match.obj-var. The constituent test-exprs have been converted to guard-chain items already, so there is no point in referring to them. (compile-predicate-match): Use add-guard-pre method to add guard instead of pushing it on list. (compile-cons-structure): Eliminate test-expr being calculated from constituent test-exprs, and just stub it out to t. (compile-require-match): Use add-guards-post to push match-guard onto compiled child mach, instead of tweaking its test-expr. (compile-let-match): Oblierate calculation of test-expr from child test-exprs, replacing with t stub. (compile-loop-match): Call wrap-guards in the new way, without generating assignments or test-expr. (compile-parallel-match): This method is removed; there are now separate compile-or-match and compile-and-match methods. (compile-or-match): New method: compiles consitituent expressions, and converts them into multiple guard-chains for a guard-disjunction object. Then wrap-guards will finish the job of emitting the or logic out of those chains. (compile-and-match): This shares some common logic with compile-or-match, but is substantially simpler. Pattern matching is implicitly AND-based: in a pattern, all the sub-patterns have to match. So there isn't much to do beyond just evaluating all the patterns against the same object. They can all be thrown into one combined flat guard chain. (compile-not-match): Adjust to new wrap-guards interface. Nothing left to do here but pass the expression t to it. (copmile-hash-mach): The post-constructon manipulations of the child compiled matches are done with the appropriate add-guards-pre. The test-expr is eliminated, replaced with t. (compile-match): Wire or and and to the new separate methods compile-or-match and compile-and-match. (when-match, if-match, match-case): Simplified due to when-match interface change. The macros depend on a lot less implementation detail now: they bind the required vars and generate the code.
* mather: new bad (@(predicate) @(all ...)) test case.Kaz Kylheku2021-01-271-0/+2
| | | | | * tests/011/patmatch.tl: Predicates must also be tested earlier, as guard conditions.
* matcher: new broken test case: bad order of checks.Kaz Kylheku2021-01-271-0/+2
| | | | | | | * tests/011/patmatch.tl: Even though bar mismatches foo, the second element @(all) is processed and tries to collect the list. This results in an error due to the list being improper.
* matcher: add failing @(or @(and ...)) test.Kaz Kylheku2021-01-271-0/+2
| | | | | | * tests/011/patmatch.tl: It looks like there is still a problem with scoping. An inner x is assigned the correct value, leaving the outer x nil.
* matcher: add failing @(all (@or ...)) test.Kaz Kylheku2021-01-271-0/+3
| | | | | The matcher has a bug: the loop patterns are not collecting the variables from enclosed parallel patterns.
* matcher: allow pat/var argument: @[expr var pat]Kaz Kylheku2021-01-261-0/+8
| | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-dwim-predicate-match): Drop redundant bindable check of sym, since compile-var-match checks this. Support third argument which gives a pattern or variable which captures the value from the predicate function, which might be interesting (not just true/false). * tests/011/patmatch.tl: New tests. * txr.1: Documented.
* lazy-sub-str: bugfix: invalid substructure sharing.Kaz Kylheku2021-01-252-0/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | This addresses a bug manifesting itself as a regression in the behavior of @(freeform), which was reported by Frank Schwidom. The sub_str operation calls lazy_subs_str for a lazy string. But lazy_sub_str again relies on sub_str for extracting part of the lazy string prefix. But sub_str can potentially return the whole object rather than a copy of a substring of it. In this case, lazy_sub_str produces a new lazy string object which shares the prefix string object with the original lazy string. This is incorrect because the lazy string data type destructively manipulates the prefix. It means that operations one one lazy string are mucking with the prefix of another lazy string. * lib.c (lazy_sub_str): When creating the new lazy string object, make a copy of the prefix string pulled from the original. We do the carefully: the copy of the prefix is made before the make_obj call which allocates the new lazy string, otherwise we create a wrong-way assignment from the perspective of generational GC. * tests/006/freeform-4.txr: New test case, from Frank. * tests/006/freeform-4.expected: Expected output of test case.
* doc: add back discussion about (rcons ...) pattern.Kaz Kylheku2021-01-241-0/+3
| | | | | | | * txr.1: Add anote that a pattern a..b matches rcons syntax, and add examples. * tests/011/patmatch.tl: new examples from doc added as tests.
* matcher: rescind support for @(rcons ...) patterns.Kaz Kylheku2021-01-241-0/+9
| | | | | | | | | | | | | | | | | | | | | There is no longer any way to write a @(rcons ...) pattern using the range syntax, so there is no point in supporting that operator. The silly syntax @@a..@b which previously worked was actually due to a mistaken requirement in the parser. * share/txr/stdlib/match.tl (compile-range-match): Function moved closer to compile-atom-match, below compile-vec-match. The argument is now a range object containing patterns, so we pull it apart with from and to. (compile-atom-match): Pass range directly to compile-range-match; no need to construct (rcons ...) syntax. * tests/011/patmatch.tl: Add range tests from documentation and a few others. * txr.1: References to @(rcons ...) pattern scrubbed. One wrong #R pattern example corrected.
* matcher: add optimized special case to hash pattern.Kaz Kylheku2021-01-221-0/+3
| | | | | | | | | | | | | | | | | | This change causes a key-value pattern like (@a @b) to be treated specially when @a already has a binding from a previous pattern. In this case, it behaves like the trivial key case: the value of @a is looked up to try to find a single value. If @a is not bound, then the exhaustive search takes place, using equal equality. * share/txr/stdlib/match.tl (compile-hash-match): Implement special case. (var-pat-p): New function. * tests/011/patmatch.tl: Existing test case now changes value. New test case added. * txr.1: Documented.
* matcher: document hash and some fixes.Kaz Kylheku2021-01-221-0/+3
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-hash-match): Follow rename of is-pattern function to non-triv-pat-p. (is-pattern): Renamed to non-triv-pat-p, to follow terminology in the reference manual. A bug is fixed here: we must recognize cons patterns with operators and variables in the dotted position as non-trivial. * tests/011/patmatch.tl: New hash test case, from doc. * txr.1: Documented hash pattern operator.
* matcher: existing variables in @(all) now backref.Kaz Kylheku2021-01-221-0/+4
| | | | | | | | | | | | | | | | | | This commit fixes the inadequacy that all variables occurring in a pattern under @(all ...) or @(coll ...) are blindly collated into lists, ignoring the fact that they may be previously bound variables that must back-reference and not be colleced into lists (just like in the TXR Pattern language!) * share/txr/stdlib/match.tl (compile-loop-match): Calculate the subset of variables in the pattern that have been freshly bound. Only generate the collection gensyms for those variables and only collect and nreverse those variables. * tests/011/patmatch.tl: Some test cases that backreference into an @(all). * txr.1: Documented.
* matcher: new @(coll) operator.Kaz Kylheku2021-01-211-0/+4
| | | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-loop-match): Implement coll semantics. coll fails if it collects nothing, which uses common logic with all*. We just have to move the flipping of the loop-iterated-var into the match, and not do it unconditionally for every iteration. (compile-match): Hook in the coll operator. * tests/011/patmatch.tl: Test case copied from doc example. * txr.1: Documented.
* matcher: more test cases.Kaz Kylheku2021-01-211-0/+29
| | | | | | * tests/011/patmatch.tl: Add test case matching with two structures in circular relationship, and a loop around match case for various cases involving backreference.
* matcher: matcher: fix broken @(let @a @(some @a)).Kaz Kylheku2021-01-211-0/+2
| | | | | | | | | | | | * share/txr/stdlib/match.tl (compile-parallel-match): Just like what was done in compile-loop-match in the prior commit, we fix the situation here. guard1's guard-expr, in which the matching logic actually happens, becomes the main test-expr. Thus guard1 disappears and guard0 is renamed to the one and only guard. * tests/011/patmatch.tl: Added test case which is fixed by this.
* matcher: fix broken @(let @a @(some @a)) test case.Kaz Kylheku2021-01-211-0/+2
| | | | | | | | | | | | | | | | | | | | | This is caused by the way the loop match compiler moves the matching logic into a guard, which causes a re-ordering of the variable assignments which interferes with backreferencing when @(some) is embedded into a @(let), and probably other situations. The issues is that the backreferencing equal tests can be reordered to occur before the assignment which sets the intial value of the backreferenced variable: cart before the horse kind of thing. * share/txr/stdlib/match.tl (compile-loop-match): Do not add the submatch into the guard sequence. Thus guard1's vars and var-exprs, move into into the main compiled-match, and guard1's guard-expr moves into guard0. Thus guard1 disappears, guard0 becomes guard. * tests/011/patmatch.tl: New test case that is also fixed, and which was not fixed by a different approach to the problem that I scrapped.
* matcher: add failing circular backreferencing test.Kaz Kylheku2021-01-211-0/+4
| | | | | | * tests/011/patmatch.tl: New test showing breakage whereby a variable inside the @(some ...) operator is not able to unify against a surrounding let variable.
* matcher: add another broken test case.Kaz Kylheku2021-01-191-0/+2
| | | | | * tests/011/patmatch.tl: Breaking test case added. The @(some) pattern match has the same vars misalignment problem.
* matcher: add failing test case.Kaz Kylheku2021-01-191-0/+2
| | | | | | * tests/011/patmatch.tl: New weirdly failing test case. The @(and @a @b) is important; if that term is replaced by a simple @a, then the correct datum is bound to c.
* doc: document when-match, if-match and match-case.Kaz Kylheku2021-01-181-0/+14
| | | | | | * tests/011/patmatch.tl: Add match-case test. * txr.1: Document when-match, if-match and match-case.
* matcher: add tests from documentation.Kaz Kylheku2021-01-182-0/+68
| | | | | | * tests/011/patmatch.tl: New file. * tests/011/patmatch.expected: Likewise.
* mapcar: add test covering recent regression.Kaz Kylheku2021-01-181-0/+3
| | | | | * test/012/seq.tl: New test with multiple lambda arguments and variadic function.
* awk: tests for fconv.Kaz Kylheku2020-12-312-0/+21
| | | | | * tests/015/awk-fconv.tl, * tests/015/awk-fconv.expected: New files.
* chmod: disable some chmod tests on Cygwin.Kaz Kylheku2020-12-241-21/+26
| | | | | | | * tests/018/chmod.tl: Certain chmod test cases no longer work on Cygwin. The issue is the chmod system call. It produces completely nonsensical results in some cases. We disable these test cases on Cygwin.
* android: fix socket module, failing tests.Kaz Kylheku2020-12-234-15/+17
| | | | | | | | | | | | | * socket.c: Add missing #include <netinet/in.h>. * tests/017/glob-carray.tl, tests/017/glob-zarray.tl: Use same definition for struct glob as Cygwin. Both are of BSD origin. * tests/017/realpath.tl: Do not test on Android. * tests/common.tl (os-symbol): Detect Android and return :android. (libc): Handle :android.
* random: add tests validating WELL512a.Kaz Kylheku2020-10-072-0/+24
| | | | | | * tests/013/well512a.tl: New file. * tests/013/well512a.expected: New file.
* random: bugfix: incorrect WELL512a.Kaz Kylheku2020-10-071-59/+59
| | | | | | | | | | | | | | | | | | | * rand.c (rand32_bug): New static function formed by renaming the original buggy rand32. (rand32_good): Copy of rand32 with two bugfixes. The term involving variable r2 must be only left shifted by 28 bits, and not xor-ed with the original value. The order of operations is wrong in the term that contains the & operation. (rand32): New static function pointer variable, serving as the rand32 function. Points to rand32_good by default. (rand_compat_fixup): Test for 243 or lower compatibility, under which rand32 is made point to rand32_bug. This is done before the call to make_random_state for replacing *random-state*, which has to use the old function. * txr.1: compat note added. * tests/013/maze.expected: Updated.
* New functions trim-left and trim-right.Kaz Kylheku2020-10-052-0/+41
| | | | | | | | | * regex.c (trim_left, trim_right): New static functions. (regex_init): New intrinsics registered. * tests/015/trim.tl, tests/015/trim.expected: New files. * txr.1: Documented.
* oop: add tests for diamond problem.Kaz Kylheku2020-09-012-2/+23
| | | | | | | | * tests/012/oop-mi.tl (grand, base1, base2): Add list slot li to grand, targeted by :init and :fini handlers in all three structs. Added test case which triggers finalization. * tests/012/oop-mi.expected: Updated.
* New inaddr-str and in6addr-str functions.Kaz Kylheku2020-07-244-0/+198
| | | | | | | | | | | | | | | | | * lisplib.c (sock_set_entries): Register autoload entries for inaddr-str and in6addr-str. Register prefix symbol to be interned. * share/txr/stdlib/socket.tl (sockaddr-in, sockaddr-in6): Both structs get a new member, prefix, defaulting to the respective number of bits in the address. (inaddr-str, in6addr-str): New functions. * tests/014/iaddr-str, tests/014/inaddr-str.expected, tests/014/in6addr-str.tl, tests/014/in6addr-str.expected: New files * txr.1: Documented.
* New: protocol for iteration with structs.Kaz Kylheku2020-07-072-0/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * lib.c (seq_iterable): Return t if argument is a structure supporting the iter-begin method. (seq_iter_get_oop, seq_iter_peek_oop, seq_iter_get_fast_oop, seq_iter_peek_fast_oop): New static functions. (seq_iter_init_with_info): Handle COBJ case. If the COBJ is a structure which suports the iter-begin method, then retrieve the iterator object by calling it, and then prepare the iterator structure for either the fast or the canonical protocol based on whether the iterator supports iter-more. (seq_iter_mark): Mark the iter member if the iterator is a struct object. (iter_begin): Rearrange tests here to check object type first before sequence kind. If the object is a structure supporting the iter-begin method, then call it and return its value. (iter_more, iter_step): Check for struct object with corresponding special methods and return. (iter_reset): Similar change like in iter_begin. We check for the iter-reset special method and try to use it, otherwise fall back on the regular iter_begin logic. * lib.h (struct seq_iter): New member next of the ul union for caching the result of a peek operation. * struct.c (iter_begin_s, iter_more_s, iter_item_s, iter_step_s, iter_reset_s): New symbol variables; (special_sym): Pointers to new symbol variables added to array. (struct_init): New symbol variables initialized. (get_special_required_slot): New function. * struct.h (iter_begin_s, iter_more_s, iter_item_s, iter_step_s, iter_reset_s): Declared. (enum special_slot): New enum members iter_begin_m, iter_more_m, iter_item_m, iter_step_m, iter_reset_m. (get_special_required_slot): Declared. * txr.1: Documented. * tests/012/oop-seq.expected: New file. * tests/012/oop-seq.tl: New file.
* lib: sort becomes non-destructive; nsort introduced.Kaz Kylheku2020-05-131-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I'm fixing a historic mistake copied from ANSI Lisp, which trips up language newcomers and sometimes even experienced users. The function innocently named sort will now return newly allocated structure. The function previously called sort will be available as nsort (non-consing/allocating sort). The shuffle function also becomes pure, and is accompanied by nshuffle. * eval (me_op): Continue to use destructive sort in this legacy code that is only triggered in very old compat mode. (eval_init): Registered nsort and nshuffle. * lib.c (nsort, nshuffle): New functions introduced, closely based on sort and shuffle. (sort, shuffle): Rewritten to avoid destructive behavior: work by copying the input and calling destructive counterparts. (sort_group): Continue to use destructive sort, which is safe; the structure is locally allocated. The sort_group function has pure semantics. (grade): Likewise. * lib.h (nsort, nshuffle): Declared. * share/txr/stdlib/getopts.tl (opthelp): Replace an instance of the (sort (copy-list ...)) pattern with just (sort ...). * tags.tl (toplevel): Continue to use destructive sort to sort tags before writing the tag file; the lifetime of the tags list ends when the file is written. * tests/010/seq.txr: Switch some sort calls to nsort to keep test case working. * txr.1: Documented.
* ifa: fix broken/invalid test case.Kaz Kylheku2020-04-232-4/+7
| | | | | | | | | | | | | | | | | | * tests/012/ifa.tl: The "ambiguous" test case is not ambiguous at all. The reason it was yielding :error previously was not due to the ifa macro identifying an ambiguity but due to the funcion < not accepting nil arguments. Since < now does accept nil arguments, this test broke. Fixing this test, and adding one that tests for the ambiguous case: multiple it-candidates being rejected by ifa at expansion time. * tests/common.tl (vtest): This macro requires maintenance. To test for expansion-time failure, we must use expand, not just macroexpand. In this case, the (ifa ...) macro call is wrapped in a (let ...) so macroexpand won't do it. Secondly, the expected value is an quote expression that must be evaluated if we need its value in vtest itself. Otherwise it won't compare equal to :error, since it is actually (quote :error).
* New function: assq and rassq.Kaz Kyheku2020-02-242-0/+8
| | | | | | | | | | | | | | | | | | | | | TXR Lisp is henceforth a dialect in which (cdr (assq key a-list)) works exactly as shown, without substitution of assql or assoc. * eval.c (eval_init): Register assq and rassq intrinsics. * lib.c (assq, rassq): New functions. * lib.h (assq, rassq): Declared. * txr.1: Documented. * tests/012/ashwin.tl: New file. * tests/012/ashwin.expected: New file.
* chmod tests: avoid sticky bit when not available.Kaz Kylheku2020-02-101-18/+25
| | | | | | | | | | | | | On Solaris, we can't set the sticky bit on a non-directory without special privilege. Let's detect whether we can set the sticky bit on our test object. If we can't, then we avoid executing tests that involve the sticky bit. * tests/018/chmod.tl (test-sticky): New variable. (cht): If test-sticky is false, only run the test if none of the inputs contain a 't'.
* chmod tests: use macro.Kaz Kylheku2020-02-101-3/+3
| | | | | | * tests/018/chmod.tl (mode-bits): Change body to correct quasiquote. (cht): Use previously unreferenced mode-bits macro.
* chmod: ugo perms sees effects from same clause.Kaz Kylheku2020-02-081-0/+1
| | | | | | | | | This is Coreutils chmod behavior. * sysif.c (chmod_wrap): Sample cmode into oldm at the start of every assigment before punching the masked hole into cmode. * tests/018/chmod.tl: Breaking test case added.
* chmod: ugo must refer to unaltered perms.Kaz Kylheku2020-02-081-0/+5
| | | | | | | | | | | | | | | | | | | Within the same clause, permissions given by ugo must refer to the unaltered permissions, before the target bits were masked out, otherwise self-assignment like o=o just clears the permissions. The other self-referential perm is X: it checks for existing x permissions. That works with the current value. * sysif.c (chmod_wrap): Keep the old permissions in a new loop variable called oldm. The u, g and o perms refer to oldm rather than to the updated value in cmode. When we hit a comma, we update oldm to the current value. The code for this is now in one place with a goto. * tests/018/chmod.tl: New test case that fails in the absence of this fix. Test cases confirming that X refers to the current permissions.
* chmod: bug handling comma after right hand ugo.Kaz Kylheku2020-02-071-0/+1
| | | | | | | | | | | | * sysif.c (chmod_wrap): The chm_comma state is transitioned to after seeing a right hand side u, g or o. These do not combine with other letters, so ch_comma expects a comma after which a new permission clause we start,. Therefore the srcm and who variables must be rest. It's also a good idea to continue the loop. * tests/018/chmod.tl: New test case which exposed the above issue.
* chmod: setuid/setgid bit bugfix and new tests.Kaz Kyheku2020-02-071-5/+6
| | | | | | | | | | | | | | | | | | * sysif.c (chmod_wrap): Again, related to the = operator, we must not punch a hole in the suid and sgid bits for all non-directory objects. This was based on a misinterpretation of some coreutils documentation, and doesn't match the actual behavior. Rather, if the owner is a target (including implicitly) then we mask out suid; and if the group owner is a targe, then we mask out sgid. Thus when we are doing a permission set not targetting the owner we don't touch suid, and similarly for the group owner and setgid. * tests/018/chmod.tl: Failed test diagnostics now identify which mode string was used. Some existing tests involving the suid/sgid bits have to be revised because this commit reflects a correction in the requirements. One new test is added.
* chmod: bugfix and new tests.Kaz Kyheku2020-02-071-0/+7
| | | | | | | | | | | | * sysif.c (chmod_wrap): When processing set (=), only punch a hole in the target permission area once per clause, so as not to clobber previously set modes. We do this by checking for the chm_perm state. Whenever '=' is processed, the state machine enters into that state; when any permission letter is then processed, it transitions out of that state. This gets the "u=rwsx" test to pass. * tests/018/chmod.tl: New tests.
* New tests for chmod.Kaz Kyheku2020-02-073-0/+45
| | | | | | | | | | | | | | | | The chmod fixes in the previous several commits were caught by this. * Makefile (tst/tests/018/chmod.ok): Set up TXR_ARGS for this test to give it the location of the temporary file to use as the object for testing permissions. (tst/tests/018): Disable TXR_DBG_OPTS for new directory. * tests/018/chmod.tl: New file. * tests/018/chmod.expected: Likewise. * tests/perm.tl: Likewise.
* ffi: fix broken char handling in undimensioned arrays.Kaz Kylheku2020-01-172-0/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | The undimensioned (array <type>) and (zarray <type>) types are not doing UTF-8 conversion when <type> is char or zchar, or doing what they are supposed to with the FFI character types, which is inconsistent from their dimensioned counterparts. * ffi.c (ffi_varray_dynsize): if the element type is marked for character conversion, then do the size calculation for char and zchar by measuring the UTF-8 coded size. (ffi_varray_alloc): Call ffi_varray_dynsize to get the size, to benefit from the char handling. Thus when FFI allocates buffers for a variable length array, it will allocate correct size required for the UTF-8 encoded string. (ffi_varray_put, ffi_varray_in): Here we must call ffi_varray_dynsize and divide by the element type to get the proper numer of elements. Then we must check for character conversion and handle the cases. (ffi_varray_null_term_in): Check for character conversion cases and route those through ffi_varray_in, which handles null-terminated strings. * tests/017/ffi-misc.tl: New file. * tests/017/ffi-misc.expected: New file.
* tests: broken glob test cases crash under musl.Kaz Kylheku2020-01-083-7/+21
| | | | | | | | | | | | | | | | | | | | | | Among several issues, the main one is that these test cases use the str-d FFI type for strings. This type means that TXR will take ownership of the memory; it creates the Lisp strings for the Lisp array, and then assuming that it has owership of the C strings, it will free them. On musl, this causes an instant crash, probably because the strings might not be individually coming from malloc. The only documented interface for freing glob resources is globfree; programs cannot assume that the strings can be freed. * tests/017/glob-carray.expected: Updated. * tests/017/glob-carray.tl (glob-t): Add missing flags member of type int. Change the array element string type from str-d to str. * tests/017/glob-zarray.tl: Likewise, and also add a comment to explain why we are not calling globfree in this test case.
* multiple-inheritance: test static-slot-home.Kaz Kylheku2019-12-132-1/+6
| | | | | | | * tests/012/oop-mi.tl: Add some coverage for static-slot-home function. * tests/012/oop-mi.expected: Updated.
* multiple-inheritance: super-method loose ends.Kaz Kylheku2019-12-132-4/+26
| | | | | | | | | | | | | | | | | * struct.c (do_super): New function. Now the common implementation for call_super_method, call_super_fun and super_method. (call_super_method, call_super_fun): Reduced to small wrappers around do_super. (super_method): Drill into the object to geet the struct_type handle, and then use do_super to get the method. * tests/012/oop-mi.tl: New tests for call-super-fun and call-super-method. * tests/012/oop-mi.expected: Updated. * txr.1: Updated.
* OOP: implementing multiple inheritance.Kaz Kylheku2019-12-112-0/+55
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Multiple inheritance is too useful to ignore any longer. * lib.c (subtypep): Perform subtypep calculation between two struct types via the new struct_subtype_p function. It's too complicated now to do with ad hoc code outside of struct.c. * share/txr/stdlib/struct.tl (defstruct): This macro now needs to deal with the super argument being possibly a list of base types instead of a single one. * strut.c (struct struct_type): Member super and super_handle are removed. New member nsupers, supers, and sus. (struct_init): The super function re-registered; it has an optional argument. (call_stinitfun_chain): The compat code here must now access the supertype differently. We don't bother dealing with multiple inheritance in the compat case; programs requesting compatibility with TXR 151 shoudn't be trying to use multiple inheritance. (get_struct_handles, count_super_stslots, get_super_slots, find_super_for_slot): New static functions, to off-load some new complexity from make_struct_type. (make_struct_type): Handle the increased complexity due to multiple inheritance. (super): Takes an additional argument now, to request which supertype to retrieve. Defaults to zero: the first one. (struct_type_destroy): Free the sus array. (struct_type_mark): Mark the supers slot. (call_initfun_chain): Call init functions of all bases, in right-to-left order. (call_postinitfun_chain): Likewise for postinit functions. (call_super_method, call_super_fun, super_method): Use the first base as the supertype. This requirement feels bad; it needs to be revisited. (do_struct_subtype_p): New static function. (struct_subtype_p): New function. (ancestor_with_static_slot): New static function. (method_name): Revised for multiple inheritance; now relies on ancestor_with_static_slot to find the original ancestor that has brought in a method, so we can use that type in the method name. * struct.h (super): Declaration updated. (struct_subtype_p): Declared. * tests/012/oop-mi.expected: New file. * tests/012/oop-mi.tl: New test cases. * txr.1: Revised in order to document multiple inheritance.
* bracket: bug: wrong result when function is applied.Kaz Kylheku2019-09-101-0/+14
| | | | | | | | | | | | Reported by user vapnik spaknik. * lib.c (bracket): Don't rely on the index variable to step through the arguments, because it only counts fixed arguments. The args_get function doesn't increment the index beyond args->fill; when popping arguments from args->list, index stays unmodified. * tests/016/arith.tl: Tests for bracket added.