From 0ffd7fb1f519db1b896f4863447dc182b3243a4b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 6 May 2025 17:55:20 -0700 Subject: New function: buf-test. * buf.c (buf_test): New function. (buf_init): Register buf-test intrinsic. * buf.h (buf_test): Declared. * tests/012/buf.tl: New tests. * txr.1: Documented. --- buf.c | 29 +++++++++++++++++++++++++++++ buf.h | 1 + tests/012/buf.tl | 24 ++++++++++++++++++++++++ txr.1 | 26 +++++++++++++++++++++++--- 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/buf.c b/buf.c index dd5abda9..c36d1c0c 100644 --- a/buf.c +++ b/buf.c @@ -1561,6 +1561,34 @@ val buf_and(val bufa, val bufb) } } +val buf_test(val bufa, val bufb) +{ + val self = lit("buf-test"); + struct buf *ab = buf_handle(bufa, self); + struct buf *bb = buf_handle(bufb, self); + ucnum la = c_unum(ab->len, self); + ucnum lb = c_unum(bb->len, self); + + if (la == 0 || lb == 0 ) { + return nil; + } else if (la < lb) { + return buf_test(bufb, bufa); + } else if (la == convert(ucnum, -1)) { + err_oflow(self); + abort(); + } else { + ucnum delta = la - lb; + ucnum i; + + for (i = 0; i < lb; i++) { + if ((ab->data[i + delta] & bb->data[i]) != 0) + return t; + } + + return nil; + } +} + val buf_or(val bufa, val bufb) { val self = lit("buf-or"); @@ -1843,6 +1871,7 @@ void buf_init(void) reg_fun(intern(lit("buf-ash"), user_package), func_n2(buf_ash)); reg_fun(intern(lit("buf-fash"), user_package), func_n2(buf_fash)); reg_fun(intern(lit("buf-and"), user_package), func_n2(buf_and)); + reg_fun(intern(lit("buf-test"), user_package), func_n2(buf_test)); reg_fun(intern(lit("buf-or"), user_package), func_n2(buf_or)); reg_fun(intern(lit("buf-xor"), user_package), func_n2(buf_xor)); reg_fun(intern(lit("buf-not"), user_package), func_n1(buf_not)); diff --git a/buf.h b/buf.h index c134b43b..2a599339 100644 --- a/buf.h +++ b/buf.h @@ -127,6 +127,7 @@ void buf_swap32(val buf); val buf_ash(val buf, val bits); val buf_fash(val buf, val bits); val buf_and(val bufa, val bufb); +val buf_test(val bufa, val bufb); val buf_or(val bufa, val bufb); val buf_xor(val bufa, val bufb); val buf_not(val buf); diff --git a/tests/012/buf.tl b/tests/012/buf.tl index 77018647..173522ce 100644 --- a/tests/012/buf.tl +++ b/tests/012/buf.tl @@ -274,6 +274,30 @@ (buf-xor #b'ff' #b'ffaa') #b'ff55' (buf-xor #b'ff00ff0f' #b'1baddeadbeef') #b'1bad21ad41e0') +(mtest + (buf-test #b'' #b'') nil + (buf-test #b'' #b'00') nil + (buf-test #b'' #b'11') nil + (buf-test #b'00' #b'00') nil + (buf-test #b'ff' #b'00') nil + (buf-test #b'00' #b'ff') nil + (buf-test #b'aa' #b'ff') t + (buf-test #b'ff' #b'aa') t + (buf-test #b'ff55' #b'aa') nil + (buf-test #b'ff00' #b'00') nil + (buf-test #b'ffff' #b'00') nil + (buf-test #b'ff00' #b'ff') nil + (buf-test #b'ffaa' #b'ff') t + (buf-test #b'ffff' #b'aa') t + (buf-test #b'ff55' #b'aa') nil + (buf-test #b'00' #b'ff00') nil + (buf-test #b'ff' #b'ff00') nil + (buf-test #b'00' #b'ffff') nil + (buf-test #b'aa' #b'ffff') t + (buf-test #b'ff' #b'ffaa') t + (buf-test #b'ff00ff0f' #b'1baddeadbeef') t) + + (mtest (buf-not #b'') #b'' (buf-not #b'00') #b'ff' diff --git a/txr.1 b/txr.1 index 57173cdf..df6c3aaa 100644 --- a/txr.1 +++ b/txr.1 @@ -30273,11 +30273,12 @@ length is equal to that of Shifting an empty buffer by any number of bits results in an empty buffer. -.coNP Functions @, buf-and @ buf-or and @ buf-xor +.coNP Functions @, buf-and @, buf-or @ buf-xor and @ buf-test .synb .mets (buf-and < buf1 << buf2 ) .mets (buf-or < buf1 << buf2 ) .mets (buf-xor < buf1 << buf2 ) +.mets (buf-test < buf1 << buf2 ) .syne .desc The functions @@ -30286,7 +30287,12 @@ The functions or .code buf-xor perform common bitwise Boolean operations on a pair of buffers, -returning the result as a buffer. +returning the result as a buffer. The function +.code buf-test +returns a Boolean result, +.code t +or +.codn nil . If the input operands .meta buf1 @@ -30307,7 +30313,7 @@ or then that input buffer itself may be returned. The -code buf-and +.code buf-and function calculates the bitwise Boolean "and" operation between corresponding bytes of the two operands; .code buf-or @@ -30316,6 +30322,20 @@ and .code buf-xor calculates the bitwise Boolean exclusive "or". +The +.code buf-test +calculates the bitwise Boolean "and", in the same manner as +.codn buf-and . +However, rather than returning the result of that operation, +.code buf-test +returns an indication whether any nonzero bits occur in the result. + +Thus +.code "(buf-test x y)" +is equivalent to +.code "(not (buf-zero-p (x y)))" +except that a buffer need not be calculated and separately tested for zero. + .coNP Function @ buf-not .synb .mets (buf-not << buf ) -- cgit v1.2.3