In case anyone's interested, here is function 'pack-length-bytes' to compute and return the number of bytes that a proper 'pack' format string would produce. It works by cleverly replacing the elements of the format string with the number of bytes for each element, then summing those numbers.
;; pack-length-bytes
;; return the number of bytes defined by a well-formed
;; 'pack' format string
;;
;; e.g.,
;; (pack-length-bytes ">ucc c s27 s4 n1 s3 n22 n2") --> 64
;; (pack-length-bytes "cccccs27s4n1s3n22n2") --> 64
;;
;; Knowing that 'replace' is destructive is the key to
;; understanding this function.
;;
;; The (cons 0 (map ...)) hack returns 0 for the
;; legal "" str-format.
;;
(define (pack-length-bytes str-format)
(let
( TABLE '((">" "" ) ;order of table entries matters
("<" "" )
("ld" "4 ") ;"ld" must precede "d"
("lf" "8 ") ;"lf" must precede "f"
("lu" "4 ") ;"lu" must precede "u"
("b" "1 ")
("c" "1 ")
("d" "2 ")
("f" "4 ")
("u" "2 ")
("s" " " )
("n" " " ))
)
;body of let
(map (fn (x) (replace (x 0) str-format (x 1))) TABLE)
(apply + (cons 0 (map integer (parse str-format)))) ))