syscalls: Add 'c-struct-field-offset'.

* guix/build/syscalls.scm (define-c-struct-macro): New macro.
(define-c-struct): Use it.
(c-struct-field-offset): New macro.
This commit is contained in:
Ludovic Courtès 2016-11-20 23:34:36 +01:00
parent 1845c2a436
commit 8eb790f368
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
1 changed files with 31 additions and 0 deletions

View File

@ -267,6 +267,29 @@ result is the alignment of the \"most strictly aligned component\"."
(align offset type0)
type0))))))
(define-syntax define-c-struct-macro
(syntax-rules ()
"Define NAME as a macro that can be queried to get information about the C
struct it represents. In particular:
(NAME field-offset FIELD)
returns the offset in bytes of FIELD within the C struct represented by NAME."
((_ name ((fields types) ...))
(define-c-struct-macro name
(fields ...) 0 ()
((fields types) ...)))
((_ name (fields ...) offset (clauses ...) ((field type) rest ...))
(define-c-struct-macro name
(fields ...)
(+ (align offset type) (type-size type))
(clauses ... ((_ field-offset field) (align offset type)))
(rest ...)))
((_ name (fields ...) offset (clauses ...) ())
(define-syntax name
(syntax-rules (field-offset fields ...)
clauses ...)))))
(define-syntax define-c-struct
(syntax-rules ()
"Define SIZE as the size in bytes of the C structure made of FIELDS. READ
@ -274,6 +297,8 @@ as a deserializer and WRITE! as a serializer for the C structure with the
given TYPES. READ uses WRAP-FIELDS to return its value."
((_ name size wrap-fields read write! (fields types) ...)
(begin
(define-c-struct-macro name
((fields types) ...))
(define size
(struct-size 0 () types ...))
(define (write! bv offset fields ...)
@ -281,6 +306,12 @@ given TYPES. READ uses WRAP-FIELDS to return its value."
(define* (read bv #:optional (offset 0))
(read-types wrap-fields bv offset (types ...) ()))))))
(define-syntax-rule (c-struct-field-offset type field)
"Return the offset in BYTES of FIELD within TYPE, where TYPE is a C struct
defined with 'define-c-struct' and FIELD is a field identifier. An
expansion-time error is raised if FIELD does not exist in TYPE."
(type field-offset field))
;;;
;;; FFI.