aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2022-06-11 11:55:27 -0400
committerStefan Monnier2022-06-11 11:55:27 -0400
commit51def94e9c0ce81511ce1364c9adf2cd047a38bc (patch)
tree6069b254dec8f20279080ae803b755c4e0c271aa
parentb591a041e37f1a58d8a248f00b7adbf19ed4fa84 (diff)
downloademacs-51def94e9c0ce81511ce1364c9adf2cd047a38bc.tar.gz
emacs-51def94e9c0ce81511ce1364c9adf2cd047a38bc.zip
Bindat: Document `sint`; add `le` arg to `uint`; deprecate `uintr`
* lisp/emacs-lisp/bindat.el (bindat--type) <uint>: Add `le` optional arg. (bindat--type) <uintr>: Delete method. (uintr): Re-define as a bindat-macro instead. (bindat-type): Update docstring accordingly. (bindat--primitives): Update. (sint): Simplify. * doc/lispref/processes.texi (Bindat Types): Update `uint`, add `sint`, and remove `uintr`. * test/lisp/emacs-lisp/bindat-tests.el (data-bindat-spec): Use the new `le` arg of `uint` instead of `uintr`.
-rw-r--r--doc/lispref/processes.texi10
-rw-r--r--lisp/emacs-lisp/bindat.el37
-rw-r--r--test/lisp/emacs-lisp/bindat-tests.el19
3 files changed, 33 insertions, 33 deletions
diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index 55fb93ec5a8..aa4d0e3ee4f 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -3470,13 +3470,15 @@ type values:
3470@itemx byte 3470@itemx byte
3471Unsigned byte, with length 1. 3471Unsigned byte, with length 1.
3472 3472
3473@item uint @var{bitlen} 3473@item uint @var{bitlen} &optional @var{le}
3474Unsigned integer in network byte order, with @var{bitlen} bits. 3474Unsigned integer in network byte order (big-endian), with @var{bitlen} bits.
3475@var{bitlen} has to be a multiple of 8. 3475@var{bitlen} has to be a multiple of 8.
3476If @var{le} is non-@code{nil}, then use little-endian byte order.
3476 3477
3477@item uintr @var{bitlen} 3478@item sint @var{bitlen} @var{le}
3478Unsigned integer in little endian order, with @var{bitlen} bits. 3479Signed integer in network byte order (big-endian), with @var{bitlen} bits.
3479@var{bitlen} has to be a multiple of 8. 3480@var{bitlen} has to be a multiple of 8.
3481If @var{le} is non-@code{nil}, then use little-endian byte order.
3480 3482
3481@item str @var{len} 3483@item str @var{len}
3482Unibyte string (@pxref{Text Representations}) of length @var{len} bytes. 3484Unibyte string (@pxref{Text Representations}) of length @var{len} bytes.
diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el
index 5f3c772983a..84d5ea1e3b3 100644
--- a/lisp/emacs-lisp/bindat.el
+++ b/lisp/emacs-lisp/bindat.el
@@ -77,7 +77,7 @@
77;; (bindat-type 77;; (bindat-type
78;; (type u8) 78;; (type u8)
79;; (opcode u8) 79;; (opcode u8)
80;; (length uintr 32) ;; little endian order 80;; (length uint 32 t) ;; little endian order
81;; (id strz 8) 81;; (id strz 8)
82;; (data vec length) 82;; (data vec length)
83;; (_ align 4))) 83;; (_ align 4)))
@@ -663,19 +663,15 @@ is the name of a variable that will hold the value we need to pack.")
663 (`(length . ,_) `(cl-incf bindat-idx 1)) 663 (`(length . ,_) `(cl-incf bindat-idx 1))
664 (`(pack . ,args) `(bindat--pack-u8 . ,args)))) 664 (`(pack . ,args) `(bindat--pack-u8 . ,args))))
665 665
666(cl-defmethod bindat--type (op (_ (eql 'uint)) n) 666(cl-defmethod bindat--type (op (_ (eql 'uint)) n &optional le)
667 (if (eq n 8) (bindat--type op 'byte) 667 (if (eq n 8) (bindat--type op 'byte)
668 (bindat--pcase op 668 (bindat--pcase op
669 ('unpack `(bindat--unpack-uint ,n)) 669 ('unpack
670 (`(length . ,_) `(cl-incf bindat-idx (/ ,n 8))) 670 `(if ,le (bindat--unpack-uintr ,n) (bindat--unpack-uint ,n)))
671 (`(pack . ,args) `(bindat--pack-uint ,n . ,args)))))
672
673(cl-defmethod bindat--type (op (_ (eql 'uintr)) n)
674 (if (eq n 8) (bindat--type op 'byte)
675 (bindat--pcase op
676 ('unpack `(bindat--unpack-uintr ,n))
677 (`(length . ,_) `(cl-incf bindat-idx (/ ,n 8))) 671 (`(length . ,_) `(cl-incf bindat-idx (/ ,n 8)))
678 (`(pack . ,args) `(bindat--pack-uintr ,n . ,args))))) 672 (`(pack . ,args)
673 `(if ,le (bindat--pack-uintr ,n . ,args)
674 (bindat--pack-uint ,n . ,args))))))
679 675
680(cl-defmethod bindat--type (op (_ (eql 'str)) len) 676(cl-defmethod bindat--type (op (_ (eql 'str)) len)
681 (bindat--pcase op 677 (bindat--pcase op
@@ -829,7 +825,7 @@ is the name of a variable that will hold the value we need to pack.")
829 &optional ":unpack-val" def-form)) 825 &optional ":unpack-val" def-form))
830 826
831(def-edebug-elem-spec 'bindat-type 827(def-edebug-elem-spec 'bindat-type
832 '(&or ["uint" def-form] 828 '(&or ["uint" def-form &optional def-form]
833 ["uintr" def-form] 829 ["uintr" def-form]
834 ["str" def-form] 830 ["str" def-form]
835 ["strz" &optional def-form] 831 ["strz" &optional def-form]
@@ -849,8 +845,7 @@ is the name of a variable that will hold the value we need to pack.")
849 "Return the Bindat type value to pack&unpack TYPE. 845 "Return the Bindat type value to pack&unpack TYPE.
850TYPE is a Bindat type expression. It can take the following forms: 846TYPE is a Bindat type expression. It can take the following forms:
851 847
852 uint BITLEN - Big-endian unsigned integer 848 uint BITLEN [LE] - unsigned integer (big-endian if LE is nil)
853 uintr BITLEN - Little-endian unsigned integer
854 str LEN - Byte string 849 str LEN - Byte string
855 strz [LEN] - Zero-terminated byte-string 850 strz [LEN] - Zero-terminated byte-string
856 bits LEN - Bit vector (LEN is counted in bytes) 851 bits LEN - Bit vector (LEN is counted in bytes)
@@ -877,7 +872,7 @@ controlled in the following way:
877- If the list of fields is preceded with `:pack-var VAR' then the object to 872- If the list of fields is preceded with `:pack-var VAR' then the object to
878 be packed is bound to VAR when evaluating the EXPs of `:pack-val'. 873 be packed is bound to VAR when evaluating the EXPs of `:pack-val'.
879 874
880All the above BITLEN, LEN, COUNT, and EXP are ELisp expressions evaluated 875All the above BITLEN, LEN, LE, COUNT, and EXP are ELisp expressions evaluated
881in the current lexical context extended with the previous fields. 876in the current lexical context extended with the previous fields.
882 877
883TYPE can additionally be one of the Bindat type macros defined with 878TYPE can additionally be one of the Bindat type macros defined with
@@ -891,7 +886,7 @@ a bindat type expression."
891 :pe ,(bindat--toplevel 'pack type)))) 886 :pe ,(bindat--toplevel 'pack type))))
892 887
893(eval-and-compile 888(eval-and-compile
894 (defconst bindat--primitives '(byte uint uintr str strz bits fill align 889 (defconst bindat--primitives '(byte uint str strz bits fill align
895 struct type vec unit))) 890 struct type vec unit)))
896 891
897(eval-and-compile 892(eval-and-compile
@@ -935,9 +930,9 @@ a bindat type expression."
935 (if ud (help-add-fundoc-usage combined-doc (car ud)) combined-doc))))) 930 (if ud (help-add-fundoc-usage combined-doc (car ud)) combined-doc)))))
936 931
937(bindat-defmacro u8 () "Unsigned 8bit integer." '(byte)) 932(bindat-defmacro u8 () "Unsigned 8bit integer." '(byte))
938(bindat-defmacro sint (bitlen r) 933(bindat-defmacro sint (bitlen le)
939 "Signed integer of size BITLEN. 934 "Signed integer of size BITLEN.
940Bigendian if R is nil and little endian if not." 935Big-endian if LE is nil and little-endian if not."
941 (let ((bl (make-symbol "bitlen")) 936 (let ((bl (make-symbol "bitlen"))
942 (max (make-symbol "max")) 937 (max (make-symbol "max"))
943 (wrap (make-symbol "wrap"))) 938 (wrap (make-symbol "wrap")))
@@ -945,10 +940,14 @@ Bigendian if R is nil and little endian if not."
945 (,max (ash 1 (1- ,bl))) 940 (,max (ash 1 (1- ,bl)))
946 (,wrap (+ ,max ,max))) 941 (,wrap (+ ,max ,max)))
947 (struct :pack-var v 942 (struct :pack-var v
948 (n if ,r (uintr ,bl) (uint ,bl) 943 (n uint ,bl ,le
949 :pack-val (if (< v 0) (+ v ,wrap) v)) 944 :pack-val (if (< v 0) (+ v ,wrap) v))
950 :unpack-val (if (>= n ,max) (- n ,wrap) n))))) 945 :unpack-val (if (>= n ,max) (- n ,wrap) n)))))
951 946
947(bindat-defmacro uintr (bitlen)
948 "(deprecated since Emacs-29) Little-endian unsigned integer."
949 `(uint ,bitlen t))
950
952(bindat-defmacro repeat (count &rest type) 951(bindat-defmacro repeat (count &rest type)
953 "Like `vec', but unpacks to a list rather than a vector." 952 "Like `vec', but unpacks to a list rather than a vector."
954 `(:pack-var v 953 `(:pack-var v
diff --git a/test/lisp/emacs-lisp/bindat-tests.el b/test/lisp/emacs-lisp/bindat-tests.el
index 48170727525..1ce402977f5 100644
--- a/test/lisp/emacs-lisp/bindat-tests.el
+++ b/test/lisp/emacs-lisp/bindat-tests.el
@@ -36,7 +36,7 @@
36 (bindat-type 36 (bindat-type
37 (type u8) 37 (type u8)
38 (opcode u8) 38 (opcode u8)
39 (length uintr 16) ;; little endian order 39 (length uint 16 'le) ;; little endian order
40 (id strz 8) 40 (id strz 8)
41 (data vec length) 41 (data vec length)
42 (_ align 4))) 42 (_ align 4)))
@@ -128,18 +128,17 @@
128 (r (zerop (% kind 2)))) 128 (r (zerop (% kind 2))))
129 (dotimes (_ 100) 129 (dotimes (_ 100)
130 (let* ((n (random (ash 1 bitlen))) 130 (let* ((n (random (ash 1 bitlen)))
131 (i (- n (ash 1 (1- bitlen))))) 131 (i (- n (ash 1 (1- bitlen))))
132 (stype (bindat-type sint bitlen r))
133 (utype (bindat-type if r (uintr bitlen) (uint bitlen))))
132 (should (equal (bindat-unpack 134 (should (equal (bindat-unpack
133 (bindat-type sint bitlen r) 135 stype
134 (bindat-pack (bindat-type sint bitlen r) i)) 136 (bindat-pack stype i))
135 i)) 137 i))
136 (when (>= i 0) 138 (when (>= i 0)
137 (should (equal (bindat-pack 139 (should (equal (bindat-pack utype i)
138 (bindat-type if r (uintr bitlen) (uint bitlen)) i) 140 (bindat-pack stype i)))
139 (bindat-pack (bindat-type sint bitlen r) i))) 141 (should (equal (bindat-unpack utype (bindat-pack stype i))
140 (should (equal (bindat-unpack
141 (bindat-type if r (uintr bitlen) (uint bitlen))
142 (bindat-pack (bindat-type sint bitlen r) i))
143 i)))))))) 142 i))))))))
144 143
145(defconst bindat-test--LEB128 144(defconst bindat-test--LEB128