1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

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`.
This commit is contained in:
Stefan Monnier 2022-06-11 11:55:27 -04:00
parent b591a041e3
commit 51def94e9c
3 changed files with 33 additions and 33 deletions

View file

@ -3470,13 +3470,15 @@ type values:
@itemx byte @itemx byte
Unsigned byte, with length 1. Unsigned byte, with length 1.
@item uint @var{bitlen} @item uint @var{bitlen} &optional @var{le}
Unsigned integer in network byte order, with @var{bitlen} bits. Unsigned integer in network byte order (big-endian), with @var{bitlen} bits.
@var{bitlen} has to be a multiple of 8. @var{bitlen} has to be a multiple of 8.
If @var{le} is non-@code{nil}, then use little-endian byte order.
@item uintr @var{bitlen} @item sint @var{bitlen} @var{le}
Unsigned integer in little endian order, with @var{bitlen} bits. Signed integer in network byte order (big-endian), with @var{bitlen} bits.
@var{bitlen} has to be a multiple of 8. @var{bitlen} has to be a multiple of 8.
If @var{le} is non-@code{nil}, then use little-endian byte order.
@item str @var{len} @item str @var{len}
Unibyte string (@pxref{Text Representations}) of length @var{len} bytes. Unibyte string (@pxref{Text Representations}) of length @var{len} bytes.

View file

@ -77,7 +77,7 @@
;; (bindat-type ;; (bindat-type
;; (type u8) ;; (type u8)
;; (opcode u8) ;; (opcode u8)
;; (length uintr 32) ;; little endian order ;; (length uint 32 t) ;; little endian order
;; (id strz 8) ;; (id strz 8)
;; (data vec length) ;; (data vec length)
;; (_ align 4))) ;; (_ align 4)))
@ -663,19 +663,15 @@ is the name of a variable that will hold the value we need to pack.")
(`(length . ,_) `(cl-incf bindat-idx 1)) (`(length . ,_) `(cl-incf bindat-idx 1))
(`(pack . ,args) `(bindat--pack-u8 . ,args)))) (`(pack . ,args) `(bindat--pack-u8 . ,args))))
(cl-defmethod bindat--type (op (_ (eql 'uint)) n) (cl-defmethod bindat--type (op (_ (eql 'uint)) n &optional le)
(if (eq n 8) (bindat--type op 'byte) (if (eq n 8) (bindat--type op 'byte)
(bindat--pcase op (bindat--pcase op
('unpack `(bindat--unpack-uint ,n)) ('unpack
`(if ,le (bindat--unpack-uintr ,n) (bindat--unpack-uint ,n)))
(`(length . ,_) `(cl-incf bindat-idx (/ ,n 8))) (`(length . ,_) `(cl-incf bindat-idx (/ ,n 8)))
(`(pack . ,args) `(bindat--pack-uint ,n . ,args))))) (`(pack . ,args)
`(if ,le (bindat--pack-uintr ,n . ,args)
(cl-defmethod bindat--type (op (_ (eql 'uintr)) n) (bindat--pack-uint ,n . ,args))))))
(if (eq n 8) (bindat--type op 'byte)
(bindat--pcase op
('unpack `(bindat--unpack-uintr ,n))
(`(length . ,_) `(cl-incf bindat-idx (/ ,n 8)))
(`(pack . ,args) `(bindat--pack-uintr ,n . ,args)))))
(cl-defmethod bindat--type (op (_ (eql 'str)) len) (cl-defmethod bindat--type (op (_ (eql 'str)) len)
(bindat--pcase op (bindat--pcase op
@ -829,7 +825,7 @@ is the name of a variable that will hold the value we need to pack.")
&optional ":unpack-val" def-form)) &optional ":unpack-val" def-form))
(def-edebug-elem-spec 'bindat-type (def-edebug-elem-spec 'bindat-type
'(&or ["uint" def-form] '(&or ["uint" def-form &optional def-form]
["uintr" def-form] ["uintr" def-form]
["str" def-form] ["str" def-form]
["strz" &optional def-form] ["strz" &optional def-form]
@ -849,8 +845,7 @@ is the name of a variable that will hold the value we need to pack.")
"Return the Bindat type value to pack&unpack TYPE. "Return the Bindat type value to pack&unpack TYPE.
TYPE is a Bindat type expression. It can take the following forms: TYPE is a Bindat type expression. It can take the following forms:
uint BITLEN - Big-endian unsigned integer uint BITLEN [LE] - unsigned integer (big-endian if LE is nil)
uintr BITLEN - Little-endian unsigned integer
str LEN - Byte string str LEN - Byte string
strz [LEN] - Zero-terminated byte-string strz [LEN] - Zero-terminated byte-string
bits LEN - Bit vector (LEN is counted in bytes) bits LEN - Bit vector (LEN is counted in bytes)
@ -877,7 +872,7 @@ controlled in the following way:
- If the list of fields is preceded with `:pack-var VAR' then the object to - If the list of fields is preceded with `:pack-var VAR' then the object to
be packed is bound to VAR when evaluating the EXPs of `:pack-val'. be packed is bound to VAR when evaluating the EXPs of `:pack-val'.
All the above BITLEN, LEN, COUNT, and EXP are ELisp expressions evaluated All the above BITLEN, LEN, LE, COUNT, and EXP are ELisp expressions evaluated
in the current lexical context extended with the previous fields. in the current lexical context extended with the previous fields.
TYPE can additionally be one of the Bindat type macros defined with TYPE can additionally be one of the Bindat type macros defined with
@ -891,7 +886,7 @@ a bindat type expression."
:pe ,(bindat--toplevel 'pack type)))) :pe ,(bindat--toplevel 'pack type))))
(eval-and-compile (eval-and-compile
(defconst bindat--primitives '(byte uint uintr str strz bits fill align (defconst bindat--primitives '(byte uint str strz bits fill align
struct type vec unit))) struct type vec unit)))
(eval-and-compile (eval-and-compile
@ -935,9 +930,9 @@ a bindat type expression."
(if ud (help-add-fundoc-usage combined-doc (car ud)) combined-doc))))) (if ud (help-add-fundoc-usage combined-doc (car ud)) combined-doc)))))
(bindat-defmacro u8 () "Unsigned 8bit integer." '(byte)) (bindat-defmacro u8 () "Unsigned 8bit integer." '(byte))
(bindat-defmacro sint (bitlen r) (bindat-defmacro sint (bitlen le)
"Signed integer of size BITLEN. "Signed integer of size BITLEN.
Bigendian if R is nil and little endian if not." Big-endian if LE is nil and little-endian if not."
(let ((bl (make-symbol "bitlen")) (let ((bl (make-symbol "bitlen"))
(max (make-symbol "max")) (max (make-symbol "max"))
(wrap (make-symbol "wrap"))) (wrap (make-symbol "wrap")))
@ -945,10 +940,14 @@ Bigendian if R is nil and little endian if not."
(,max (ash 1 (1- ,bl))) (,max (ash 1 (1- ,bl)))
(,wrap (+ ,max ,max))) (,wrap (+ ,max ,max)))
(struct :pack-var v (struct :pack-var v
(n if ,r (uintr ,bl) (uint ,bl) (n uint ,bl ,le
:pack-val (if (< v 0) (+ v ,wrap) v)) :pack-val (if (< v 0) (+ v ,wrap) v))
:unpack-val (if (>= n ,max) (- n ,wrap) n))))) :unpack-val (if (>= n ,max) (- n ,wrap) n)))))
(bindat-defmacro uintr (bitlen)
"(deprecated since Emacs-29) Little-endian unsigned integer."
`(uint ,bitlen t))
(bindat-defmacro repeat (count &rest type) (bindat-defmacro repeat (count &rest type)
"Like `vec', but unpacks to a list rather than a vector." "Like `vec', but unpacks to a list rather than a vector."
`(:pack-var v `(:pack-var v

View file

@ -36,7 +36,7 @@
(bindat-type (bindat-type
(type u8) (type u8)
(opcode u8) (opcode u8)
(length uintr 16) ;; little endian order (length uint 16 'le) ;; little endian order
(id strz 8) (id strz 8)
(data vec length) (data vec length)
(_ align 4))) (_ align 4)))
@ -128,18 +128,17 @@
(r (zerop (% kind 2)))) (r (zerop (% kind 2))))
(dotimes (_ 100) (dotimes (_ 100)
(let* ((n (random (ash 1 bitlen))) (let* ((n (random (ash 1 bitlen)))
(i (- n (ash 1 (1- bitlen))))) (i (- n (ash 1 (1- bitlen))))
(stype (bindat-type sint bitlen r))
(utype (bindat-type if r (uintr bitlen) (uint bitlen))))
(should (equal (bindat-unpack (should (equal (bindat-unpack
(bindat-type sint bitlen r) stype
(bindat-pack (bindat-type sint bitlen r) i)) (bindat-pack stype i))
i)) i))
(when (>= i 0) (when (>= i 0)
(should (equal (bindat-pack (should (equal (bindat-pack utype i)
(bindat-type if r (uintr bitlen) (uint bitlen)) i) (bindat-pack stype i)))
(bindat-pack (bindat-type sint bitlen r) i))) (should (equal (bindat-unpack utype (bindat-pack stype i))
(should (equal (bindat-unpack
(bindat-type if r (uintr bitlen) (uint bitlen))
(bindat-pack (bindat-type sint bitlen r) i))
i)))))))) i))))))))
(defconst bindat-test--LEB128 (defconst bindat-test--LEB128