]> git.ozlabs.org Git - ccan-lca-2011.git/commitdiff
cdump: features which weren't in genparser
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 21 Jan 2011 03:36:26 +0000 (14:06 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 21 Jan 2011 03:36:26 +0000 (14:06 +1030)
1) size_t bundling an unbundling.
2) CDUMP_IGNORE to avoid saving struct members.
3) const handling (ie. ignore the keyword).

ccan/cdump/cdump.c
ccan/cdump/cdump.h
ccan/cdump/cdump_internal.h
ccan/cdump/cdump_parse.c
ccan/cdump/test/example_generated-advanced-decls.h [new file with mode: 0644]
ccan/cdump/test/example_generated-advanced-defs.h [new file with mode: 0644]
ccan/cdump/test/run-03-advanced-parse.c [new file with mode: 0644]
ccan/cdump/test/test_header_advanced.h [new file with mode: 0644]

index f151cbffdaf4d30a646887b98bb196faee1114ef..a1b55195aa1b0159034ef48ad4fe4586b966eb64 100644 (file)
@@ -725,6 +725,12 @@ bool cdump_unbundle_float(const void *ctx, void *ptr, const char *str)
        return true;
 }
 
+bool cdump_unbundle_size_t(const void *ctx, void *ptr, const char *str)
+{
+       *(size_t *)ptr = strtoul(str, NULL, 10);
+       return true;
+}
+
 bool cdump_bundle_char(struct cdump_string *p, const void *ptr, unsigned indent)
 {
        return addshort(p, "%u", *(unsigned char *)ptr);
@@ -754,3 +760,8 @@ bool cdump_bundle_float(struct cdump_string *p, const void *ptr, unsigned indent
 {
        return addshort(p, "%g", *(float *)ptr);
 }
+
+bool cdump_bundle_size_t(struct cdump_string *p, const void *ptr, unsigned indent)
+{
+       return addshort(p, "%zu", *(size_t *)ptr);
+}
index 70def6915091ec84a45a5b0f342bed17619128d8..05d5321eec0efe79b26b79d50799871c82ca3173 100644 (file)
  *     };
  */
 #define CDUMP_ZEROTERM
-#endif
+
+/**
+ * CDUMP_IGNORE - annotation for telling cdump_parse to ignore a member.
+ *
+ * This means it won't be bundled (and thus doesn't need to be understood) so
+ * on unbundling it will be all zero.
+ *
+ * Example:
+ *     CDUMP_SAVED struct baz {
+ *             char *p CDUMP_IGNORE;
+ *     };
+ */
+#define CDUMP_IGNORE
+#endif /* CDUMP_PARSING */
 
 struct cdump_desc;
 
index 7e85f5f17ee9ad62980c54b58a4a0987947bfbee..eb50ff4c99125ca43317c2fff89bfaea198f2293 100644 (file)
@@ -67,6 +67,7 @@ bool cdump_bundle_unsigned(struct cdump_string *p, const void *ptr, unsigned);
 bool cdump_bundle_time_t(struct cdump_string *p, const void *ptr, unsigned ind);
 bool cdump_bundle_double(struct cdump_string *p, const void *ptr, unsigned ind);
 bool cdump_bundle_float(struct cdump_string *p, const void *ptr, unsigned ind);
+bool cdump_bundle_size_t(struct cdump_string *p, const void *ptr, unsigned ind);
 
 bool cdump_unbundle_char(const void *ctx, void *ptr, const char *str);
 bool cdump_unbundle_int(const void *ctx, void *ptr, const char *str);
@@ -74,8 +75,11 @@ bool cdump_unbundle_unsigned(const void *ctx, void *ptr, const char *str);
 bool cdump_unbundle_time_t(const void *ctx, void *ptr, const char *str);
 bool cdump_unbundle_double(const void *ctx, void *ptr, const char *str);
 bool cdump_unbundle_float(const void *ctx, void *ptr, const char *str);
+bool cdump_unbundle_size_t(const void *ctx, void *ptr, const char *str);
 
 #define cdump_bundle_unsigned_char cdump_bundle_char
 #define cdump_unbundle_unsigned_char cdump_unbundle_char
+#define cdump_bundle_unsigned_int cdump_bundle_int
+#define cdump_unbundle_unsigned_int cdump_unbundle_int
 
 #endif /* CCAN_CDUMP_INTERNAL */
index fea7df141486276e8197854ed0bbe93018f7377b..41fd5c510ffc70981345dfa222faf65074607c36 100644 (file)
@@ -127,6 +127,9 @@ static size_t parse_one(const void *ctx, const char *outer_struct_name,
        unbundle = talloc_strdup(ctx, "cdump_unbundle");
        size = talloc_strdup(ctx, "sizeof(");
        for (i = 0; i < typelen; i++) {
+               /* Const is irrelevant for bundling. */
+               if (streq(type[i], "const"))
+                       continue;
                bundle = talloc_asprintf_append(bundle, "_%s", type[i]);
                unbundle = talloc_asprintf_append(unbundle, "_%s", type[i]);
                size = talloc_asprintf_append(size, "%s ", type[i]);
@@ -177,6 +180,8 @@ static size_t parse_element(const void *ctx, const char *outer_struct_name,
                                typelen = i - 1;
                        }
                }
+               if (streq(tok[i], "CDUMP_IGNORE"))
+                       goto skip;
        }
        i = typelen;
 
@@ -188,6 +193,7 @@ static size_t parse_element(const void *ctx, const char *outer_struct_name,
                        i++;
        } while (tok[i] && !streq(tok[i], ";") && !strstarts(tok[i], "CDUMP_"));
 
+skip:
        while (tok[i] && !streq(tok[i], ";"))
                i++;
 
diff --git a/ccan/cdump/test/example_generated-advanced-decls.h b/ccan/cdump/test/example_generated-advanced-decls.h
new file mode 100644 (file)
index 0000000..7ec57f9
--- /dev/null
@@ -0,0 +1,6 @@
+bool cdump_bundle_enum_state(struct cdump_string *, const void *, unsigned);
+bool cdump_unbundle_enum_state(const void *, void *, const char *);
+extern const struct cdump_enum cdump_enum_state[];
+bool cdump_bundle_struct_client(struct cdump_string *, const void *, unsigned);
+bool cdump_unbundle_struct_client(const void *, void *, const char *);
+extern const struct cdump_desc cdump_struct_client[];
diff --git a/ccan/cdump/test/example_generated-advanced-defs.h b/ccan/cdump/test/example_generated-advanced-defs.h
new file mode 100644 (file)
index 0000000..7a704af
--- /dev/null
@@ -0,0 +1,38 @@
+const struct cdump_enum cdump_enum_state[] = {
+       { "SENDING_GREETING", SENDING_GREETING },
+       { "RECEIVING_USER_QUESTION", RECEIVING_USER_QUESTION },
+       { "SENDING_OTHER_QUESTION_PREFIX", SENDING_OTHER_QUESTION_PREFIX },
+       { "SENDING_OTHER_QUESTION", SENDING_OTHER_QUESTION },
+       { "RECEIVING_OTHER_ANSWER", RECEIVING_OTHER_ANSWER },
+       { "SENDING_ANSWER_PREFIX", SENDING_ANSWER_PREFIX },
+       { "SENDING_ANSWER", SENDING_ANSWER },
+       { "FINISHED", FINISHED },
+       { NULL, 0 } };
+bool cdump_bundle_enum_state(struct cdump_string *p, const void *ptr, unsigned indent)
+{
+       return cdump_bundle_enum(cdump_enum_state, p, ptr, indent);
+}
+bool cdump_unbundle_enum_state(const void *ctx, void *ptr, const char *str)
+{
+       return cdump_unbundle_enum(cdump_enum_state, ptr, str);
+}
+
+const struct cdump_desc cdump_struct_client[] = {
+       { "node", 0, sizeof(struct list_node), offsetof(struct client, node), 0, NULL, 0, cdump_bundle_struct_list_node, cdump_unbundle_struct_list_node },
+       { "state", 0, sizeof(enum state), offsetof(struct client, state), 0, NULL, CDUMP_FLAG_ALWAYS, cdump_bundle_enum_state, cdump_unbundle_enum_state },
+       { "bytes_sent", 0, sizeof(size_t), offsetof(struct client, bytes_sent), 0, NULL, 0, cdump_bundle_size_t, cdump_unbundle_size_t },
+       { "fd", 0, sizeof(int), offsetof(struct client, fd), 0, NULL, 0, cdump_bundle_int, cdump_unbundle_int },
+       { "question", 1, sizeof(char), offsetof(struct client, question), 0, NULL, 0, cdump_bundle_char, cdump_unbundle_char },
+       { "subclient", 1, sizeof(struct client), offsetof(struct client, subclient), 0, NULL, 0, cdump_bundle_struct_client, cdump_unbundle_struct_client },
+       { "oracle", 1, sizeof(struct client), offsetof(struct client, oracle), 0, NULL, 0, cdump_bundle_struct_client, cdump_unbundle_struct_client },
+       { "answer", 1, sizeof(char), offsetof(struct client, answer), 0, NULL, 0, cdump_bundle_char, cdump_unbundle_char },
+       { NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL } };
+bool cdump_bundle_struct_client(struct cdump_string *p, const void *ptr, unsigned indent)
+{
+       return cdump_bundle_struct(cdump_struct_client, p, ptr, indent);
+}
+bool cdump_unbundle_struct_client(const void *ctx, void *ptr, const char *str)
+{
+       return cdump_unbundle_struct(ctx, cdump_struct_client, ptr, str);
+}
+
diff --git a/ccan/cdump/test/run-03-advanced-parse.c b/ccan/cdump/test/run-03-advanced-parse.c
new file mode 100644 (file)
index 0000000..7471d7d
--- /dev/null
@@ -0,0 +1,59 @@
+#include <ccan/cdump/cdump_parse.c>
+#include <ccan/tap/tap.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static size_t diffoff(const char *a, const char *b)
+{
+       size_t i;
+
+       for (i = 0; a[i]; i++)
+               if (b[i] != a[i])
+                       break;
+       return i;
+}
+
+static char *read_file(const void *ctx, const char *fname)
+{
+       int fd = open(fname, O_RDONLY);
+       off_t len = lseek(fd, 0, SEEK_END);
+       char *ret = talloc_array(ctx, char, len + 1);
+       lseek(fd, 0, SEEK_SET);
+       read(fd, ret, len);
+       ret[len] = '\0';
+       close(fd);
+       return ret;
+}
+
+int main(int argc, char *argv[])
+{
+       char *ret, *decls, *defs;
+       char *toplevel = talloc_strdup(NULL, "toplevel");
+       char *header, *definitions, *declarations;
+
+       plan_tests(5);
+       header = read_file(toplevel, "test/test_header_advanced.h");
+       declarations = read_file(toplevel, "test/example_generated-advanced-decls.h");
+       definitions = read_file(toplevel, "test/example_generated-advanced-defs.h");
+
+       ret = cdump_parse(toplevel, header, &decls, &defs);
+       ok1(ret == NULL);
+       ok(streq(decls, declarations),
+          "Declarations differ at %zu: ...'%.*s' vs ...'%.*s'",
+          diffoff(decls, declarations),
+          30, decls + diffoff(decls, declarations),
+          30, declarations + diffoff(decls, declarations));
+       ok(streq(defs, definitions),
+          "Definitions differ at %zu: ...'%.*s' vs ...'%.*s'",
+          diffoff(defs, definitions),
+          30, defs + diffoff(defs, definitions),
+          30, definitions + diffoff(defs, definitions));
+
+       ok1(talloc_find_parent_byname(decls, "toplevel") == toplevel);
+       ok1(talloc_find_parent_byname(defs, "toplevel") == toplevel);
+
+       talloc_free(toplevel);
+       return exit_status();
+}
diff --git a/ccan/cdump/test/test_header_advanced.h b/ccan/cdump/test/test_header_advanced.h
new file mode 100644 (file)
index 0000000..7cd47f5
--- /dev/null
@@ -0,0 +1,31 @@
+/* This tests new features in cdump which weren't in genparser.pl */
+CDUMP_SAVED enum state {
+       SENDING_GREETING,
+       RECEIVING_USER_QUESTION,
+       SENDING_OTHER_QUESTION_PREFIX,
+       SENDING_OTHER_QUESTION,
+       RECEIVING_OTHER_ANSWER,
+       SENDING_ANSWER_PREFIX,
+       SENDING_ANSWER,
+       FINISHED
+};
+
+CDUMP_SAVED struct client {
+       /* In linked list clients */
+       struct list_node node;
+       /* What are we doing today, brain? */
+       enum state state;
+       /* How many bytes of the current string we sent so far. */
+       size_t bytes_sent;
+       /* Our event info, and the file descriptor. */
+       struct tevent_fd *fde CDUMP_IGNORE;
+       int fd;
+       /* The question we read from client. */
+       const char *question;
+       /* Whose question this client is answering. */
+       struct client *subclient;
+       /* Who is answering our question. */
+       struct client *oracle;
+       /* The answer we send. */
+       char *answer;
+};