mescc: Add 70-array-in-struct-init.c test with fix.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 20 Jul 2019 15:14:55 +0000 (17:14 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 20 Jul 2019 15:14:55 +0000 (17:14 +0200)
* lib/tests/scaffold/70-array-in-struct-init.c: New file.
* lib/tests/scaffold/70-array-in-struct-init.stdout: New file.
* build-aux/check-mescc.sh (TESTS): Add test.
* module/mescc/compile.scm (array-init-element->data): Recurse for
elements instead of using init->data.  Support array fields.

build-aux/check-mescc.sh
lib/tests/scaffold/70-array-in-struct-init.c [new file with mode: 0644]
lib/tests/scaffold/70-array-in-struct-init.stdout [new file with mode: 0644]
module/mescc/compile.scm

index 522ed775566ddcb7a6f5bfc54f4943c24b49464c..c745b33f6de91054fd414e5a19aa6faeac849b10 100755 (executable)
@@ -180,6 +180,7 @@ lib/tests/scaffold/7u-inc-byte-word.c
 lib/tests/scaffold/7u-struct-func.c
 lib/tests/scaffold/7u-struct-size10.c
 lib/tests/scaffold/7u-vstack.c
+lib/tests/scaffold/70-array-in-struct-init.c
 lib/tests/setjmp/80-setjmp.c
 lib/tests/stdio/80-sscanf.c
 lib/tests/stdlib/80-qsort.c
diff --git a/lib/tests/scaffold/70-array-in-struct-init.c b/lib/tests/scaffold/70-array-in-struct-init.c
new file mode 100644 (file)
index 0000000..08767a3
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * GNU Mes --- Maxwell Equations of Software
+ * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of GNU Mes.
+ *
+ * GNU Mes is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * GNU Mes is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <mes/lib.h>
+
+struct foo
+{
+  int field;
+  int array[3];
+};
+
+struct foo foes[] =
+  {
+   {10, {11, 12, 13}},
+   {20, {21, 22}},
+   {30, {31}},
+   {40, {41}},
+   {0}
+  };
+
+int
+main ()
+{
+  for (struct foo *p = foes; p->field; p++)
+    {
+      oputs ("{");
+      oputs (itoa (p->field)); oputs (",");
+      oputs ("{");
+      oputs (itoa (p->array[0])); oputs (",");
+      oputs (itoa (p->array[1])); oputs (",");
+      oputs (itoa (p->array[2]));
+      oputs ("}");
+      oputs ("},\n");
+    }
+  oputs ("{0}\n");
+  oputs ("};\n");
+
+  return 0;
+}
diff --git a/lib/tests/scaffold/70-array-in-struct-init.stdout b/lib/tests/scaffold/70-array-in-struct-init.stdout
new file mode 100644 (file)
index 0000000..a2ec8dc
--- /dev/null
@@ -0,0 +1,6 @@
+{10,{11,12,13}},
+{20,{21,22,0}},
+{30,{31,0,0}},
+{40,{41,0,0}},
+{0}
+};
index 5118ff51ad11ef7fc2d5452b9dc189cbb7c9fc40..a7362f77fcb8c8b7734f1740d9e2ccde64917c86 100644 (file)
     ((bits . ,bits) bits)
     (_ (list o))))
 
-(define (struct->init-fields o)
+(define (struct->init-fields o) ;; FIXME REMOVEME: non-recursive unroll
   (pmatch o
     (_ (guard (and (type? o) (eq? (type:type o) 'struct)))
        (append-map struct->init-fields (type:description o)))
            (int->bv type (expr->number info fixed) info))
          (int->bv type (expr->number info fixed) info)))
     ((initzer (initzer-list . ,inits))
-     (if (structured-type? type)
-         (let* ((fields (map cdr (struct->init-fields type)))
-                (missing (max 0 (- (length fields) (length inits))))
-                (inits (append inits
-                               (map (const '(fixed "0")) (iota missing)))))
-           (map (cut init->data <> <> info) fields inits))
-         (begin
-           (stderr "array-init-element->data: oops:~s\n" o)
-           (stderr "type:~s\n" type)
-           (error "array-init-element->data: unstructured not supported: " o))))
+     (cond ((structured-type? type)
+            (let* ((fields (map cdr (struct->init-fields type)))
+                   (missing (max 0 (- (length fields) (length inits))))
+                   (inits (append inits
+                                  (map (const '(fixed "0")) (iota missing)))))
+              (map (cut array-init-element->data <> <> info) fields inits)))
+           ((c-array? type)
+            (let* ((missing (max 0 (- (c-array:count type) (length inits))))
+                   (inits (append inits
+                                  (map (const '(fixed "0")) (iota missing)))))
+              (map (cut array-init-element->data (c-array:type type) <> info) inits)))
+         (else
+          (stderr "array-init-element->data: oops:~s\n" o)
+          (stderr "type:~s\n" type)
+          (error "array-init-element->data: not supported: " o))))
     (_ (init->data type o info))
     (_ (error "array-init-element->data: not supported: " o))))
 
     ((initzer (initzer-list . ,inits))
      (let ((type (c-array:type type)))
        (if (structured-type? type)
-           (let* ((fields (length (struct->init-fields type))))
+           (let* ((init-fields (struct->init-fields type)) ;; FIXME
+                  (count (length init-fields)))
              (let loop ((inits inits))
                (if (null? inits) '()
                    (let ((init (car inits)))
                        ((initzer (initzer-list . ,car-inits))
                         (append (array-init-element->data type init info)
                                 (loop (cdr inits))))
-                       (_ (let* ((count (min (length inits) fields))
+                       (_
+                        (let* ((count (min (length inits) (length init-fields)))
                                  (field-inits (list-head inits count)))
-                            (append (array-init-element->data type `(initzer-list ,@field-inits) info)
-                                    (loop (list-tail inits count))))))))))
+                          (append (array-init-element->data type `(initzer-list ,@field-inits) info)
+                           (loop (list-tail inits count))))))))))
            (map (cut array-init-element->data type <> info) inits))))
 
     (((initzer (initzer-list . ,inits)))