Teach groveler cstruct :count :auto to work on arrays anywhere in the struct.
authorJoshua Elsasser <joshua@elsasser.org>
Thu, 22 Nov 2012 18:08:17 +0000 (13:08 -0500)
committerLuís Oliveira <loliveira@common-lisp.net>
Sun, 6 Jan 2013 20:53:17 +0000 (20:53 +0000)
The :count :auto logic assumed the struct member was an array which
filled the remainder of the struct, and would generate incorrect cffi
cstruct forms when any other struct members followed one declared
:count :auto.

The following C struct definition and groveler cstruct form
demonstrate this:

struct charbuf {
char three_chars[3];
int clobbered_int
};

(cstruct charbuf "struct charbuf"
  (three-chars "three_chars" :type :char :count :auto)
  (clobbered-int "clobbered_int" :type :int))

grovel/common.h
grovel/grovel.lisp

index 4ea2aac..b44b0c2 100644 (file)
@@ -7,7 +7,10 @@
 #ifndef offsetof
 #define offsetof(type, slot) ((long) ((char *) &(((type *) 0)->slot)))
 #endif
-#define sizeofslot(type, slot) (sizeof(((type *) 0)->slot))
+#define getslot(type, slot) (((type *) 0)->slot)
+#define sizeofslot(type, slot) (sizeof(getslot(type, slot)))
+#define countofslot(type, slot) \
+  (sizeof(getslot(type, slot)) / sizeof(getslot(type, slot)[0]))
 #define stringify(x) #x
 #define indirect_stringify(x) stringify(x)
 
index 62cf046..b7d2579 100644 (file)
@@ -501,8 +501,7 @@ int main(int argc, char**argv) {
            (c-format out " :count ~D" count))
           ((eql :auto)
            (c-printf out " :count %i"
-                     (format nil "sizeof(~A) - offsetof(~A, ~A)"
-                             struct-c-name
+                     (format nil "countofslot(~A, ~A)"
                              struct-c-name
                              slot-c-name)))
           ((or symbol string)