fmt-c structure type issue (bug?)
Alexey Egorov via Chicken-users <[email protected]>
| Newsgroups | gmane.lisp.scheme.chicken |
|---|---|
| Message-ID | <CALf3tGF3C+78xTYF_-M-TBhfaGYrisAt1t-Zbj_f_8rBB6KbVw@mail.gmail.com> |
Hi. I'm new user of Scheme, Chicken and fmt library. I use a relatively
small program to output C code from S-expression form.
During my interactions with fmt-c, I found that I don't have a way to have
struct type produced correctly in a struct field, typedef, or as function
argument:
(fmt #t (c-expr
'(struct foo
((int a)
((struct bar) b)))))
Error: (car) bad argument type: ()
Call history:
<stdin>:1031 (fmt #t (c-expr (quote (struct foo ((int a) ((struct bar)
b))))))
<stdin>:1031 (c-expr (quote (struct foo ((int a) ((struct bar) b)))))
<stdin>:1032 (quote (struct foo ((int a) ((struct bar) b))))
<stdin>:1032 (##core#quote (struct foo ((int a) ((struct bar) b))))
<stdin>:1031 (fmt #t (c-expr (quote (struct foo ((int a) ((struct bar)
b))))))
<stdin>:1031 (c-expr (quote (struct foo ((int a) ((struct bar) b))))) <--
It should be noted that other kinds of such compound types work all right,
even with `struct' in it, if it is not the first symbol in the type form:
(fmt #t (c-expr
'(struct foo
((int a)
((const float *) b)
((const struct bar) c)))))
struct foo {
int a;
const float * b;
const struct bar c;
};
As I undestand, this is the effect of the ability to have anonymous structs
as struct fields:
(fmt #t (c-expr
'(struct foo
((int a)
((struct ((float x)
(float y))) b)))))
struct foo {
int a;
struct {
float x;
float y;
} b;
};
It also does make sense in typedef forms, but doesn't in function arguments.
I investigated source code and found possible culprit as well as an obvious
solution.
I also added a couple of tests, which seem to work. Patches are in
attachments.
Now time for questions.
1. Did I miss something obvious, which could have solved the original issue
without patching the source?
2. I probably should contact Alex Shinn, the original author of the fmt
lib, but I cannot find his contacts anywhere, or a contribution guide. Does
anyone have them?
3. If the previous is not possible, or not the preferred way, will the Trac
ticket suffice for patch to be accepted to the Chicken egg itself?
Best regrads,
Alex Egorov.
test-fmt-c.scm.patch
(text/x-patch, 647 B)
Index: tests/test-fmt-c.scm
===================================================================
--- tests/test-fmt-c.scm (revision 44317)
+++ tests/test-fmt-c.scm (working copy)
@@ -490,4 +451,15 @@
(test "static int i;\n"
(fmt #f (c-expr '(static (%var int i)))))
+(test "struct foo;\n"
+ (fmt #f (c-expr '(struct foo))))
+
+(test "typedef struct bar bar;\n"
+ (fmt #f (c-expr '(typedef (struct bar) bar))))
+
+(test "int foo (struct bar b, const struct baz * a);\n"
+ (fmt #f (c-expr
+ '(%prototype int foo (((struct bar) b)
+ ((const (struct baz) *) a))))))
+
(test-end)
fmt-c.scm.patch
(text/x-patch, 1.4 KB)
Index: fmt-c.scm
===================================================================
--- fmt-c.scm (revision 44317)
+++ fmt-c.scm (working copy)
@@ -548,15 +548,18 @@
(define (c-struct/aux type x . o)
(let* ((name (if (null? o) (if (or (symbol? x) (string? x)) x #f) x))
- (body (if name (car o) x))
+ (body (if name (if (not (null? o)) (car o) '()) x))
(o (if (null? o) o (cdr o))))
- (c-wrap-stmt
- (cat
- (c-braced-block
- (cat type (if (and name (not (equal? name ""))) (cat " " name) ""))
- (cat
- (c-in-stmt
- (if (list? body)
- (apply c-begin (map c-wrap-stmt (map c-param body)))
- (c-wrap-stmt (c-expr body))))))
- (if (pair? o) (cat " " (apply c-begin o)) (dsp ""))))))
+ (if (not (null? body))
+ (c-wrap-stmt
+ (cat
+ (c-braced-block
+ (cat type (if (and name (not (equal? name ""))) (cat " " name) ""))
+ (cat
+ (c-in-stmt
+ (if (list? body)
+ (apply c-begin (map c-wrap-stmt (map c-param body)))
+ (c-wrap-stmt (c-expr body))))))
+ (if (pair? o) (cat " " (apply c-begin o)) (dsp ""))))
+ (c-wrap-stmt
+ (cat type (if (and name (not (equal? name ""))) (cat " " name) ""))))))
(define (c-struct . args) (apply c-struct/aux "struct" args))
(define (c-union . args) (apply c-struct/aux "union" args))