Commit 3d6fe839 authored by Rusty Russell's avatar Rusty Russell

cdump: handle multi-line preprocessor directives.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 1e5f5ecc
......@@ -16,6 +16,16 @@ static void add_token(struct token **toks, const char *p, size_t len)
(*toks)[n].len = len;
}
static size_t to_eol(const char *p)
{
size_t len = strcspn(p, "\n");
/* And any \ continuations. */
while (p[len] && p[len-1] == '\\')
len += strcspn(p+len+1, "\n") + 1;
return len;
}
/* Simplified tokenizer: comments and preproc directives removed,
identifiers are a token, others are single char tokens. */
static struct token *tokenize(const void *ctx, const char *code)
......@@ -27,10 +37,10 @@ static struct token *tokenize(const void *ctx, const char *code)
for (i = 0; code[i]; i += len) {
if (code[i] == '#' && start_of_line) {
/* Preprocessor line. */
len = strcspn(code+i, "\n");
len = to_eol(code + i);
} else if (code[i] == '/' && code[i+1] == '/') {
/* One line comment. */
len = strcspn(code+i, "\n");
len = to_eol(code + i);
if (tok_start != -1U) {
add_token(&toks, code+tok_start, i - tok_start);
tok_start = -1U;
......
#include <ccan/cdump/cdump.h>
/* Include the C files directly. */
#include <ccan/cdump/cdump.c>
#include <ccan/tap/tap.h>
int main(void)
{
struct cdump_definitions *defs;
const struct cdump_type *t;
char *ctx = tal(NULL, char), *problems;
/* This is how many tests you plan to run */
plan_tests(30);
/* Multi-line preprocessor statement. */
defs = cdump_extract(ctx,
"#if \\\n"
"SOME\\\n"
"THING\n"
"enum foo { BAR };", &problems);
ok1(defs);
ok1(tal_parent(defs) == ctx);
ok1(strmap_empty(&defs->structs));
ok1(strmap_empty(&defs->unions));
t = strmap_get(&defs->enums, "foo");
ok1(t);
ok1(t->kind == CDUMP_ENUM);
ok1(streq(t->name, "foo"));
ok1(tal_count(t->u.enum_vals) == 1);
ok1(streq(t->u.enum_vals[0].name, "BAR"));
ok1(!t->u.enum_vals[0].value);
defs = cdump_extract(ctx,
"enum foo {\n"
"#if \\\n"
"SOME\\\n"
"THING\n"
" BAR };", &problems);
ok1(defs);
ok1(tal_parent(defs) == ctx);
ok1(strmap_empty(&defs->structs));
ok1(strmap_empty(&defs->unions));
t = strmap_get(&defs->enums, "foo");
ok1(t);
ok1(t->kind == CDUMP_ENUM);
ok1(streq(t->name, "foo"));
ok1(tal_count(t->u.enum_vals) == 1);
ok1(streq(t->u.enum_vals[0].name, "BAR"));
ok1(!t->u.enum_vals[0].value);
/* Multi-line "one-line" comment. */
defs = cdump_extract(ctx,
"enum foo {\n"
"// Comment \\\n"
"SOME\\\n"
"THING\n"
" BAR };", &problems);
ok1(defs);
ok1(tal_parent(defs) == ctx);
ok1(strmap_empty(&defs->structs));
ok1(strmap_empty(&defs->unions));
t = strmap_get(&defs->enums, "foo");
ok1(t);
ok1(t->kind == CDUMP_ENUM);
ok1(streq(t->name, "foo"));
ok1(tal_count(t->u.enum_vals) == 1);
ok1(streq(t->u.enum_vals[0].name, "BAR"));
ok1(!t->u.enum_vals[0].value);
/* This exits depending on whether all tests passed */
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment