diff options
author | Ludovic Courtès <ludo@gnu.org> | 2016-11-20 23:34:36 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2016-11-21 00:34:48 +0100 |
commit | 8eb790f368be5d7beac728e55093b6a3ea22328b (patch) | |
tree | 417159a7d780fd54850b78131f2c55a98d332b50 | |
parent | 1845c2a4362c96d7feea3132f21aec34a607f855 (diff) | |
download | guix-8eb790f368be5d7beac728e55093b6a3ea22328b.tar.gz guix-8eb790f368be5d7beac728e55093b6a3ea22328b.zip |
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.
-rw-r--r-- | guix/build/syscalls.scm | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm index c3832f6d48..85de47d26e 100644 --- a/guix/build/syscalls.scm +++ b/guix/build/syscalls.scm @@ -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. |