summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2014-09-07 22:48:33 +0200
committerVicent Marti <tanoku@gmail.com>2014-09-09 03:39:16 +0200
commit7426f9ae60272a19bd4611b8579647118033a1e6 (patch)
treed8265b6055052dc42fbf1a3f41454654b1199d2c
parent798f58a2b614280201141b398c8e498cecc8ab5e (diff)
Abstract the Block union
-rw-r--r--src/blocks.c94
-rw-r--r--src/html/html.c8
-rw-r--r--src/print.c11
-rw-r--r--src/stmd.h20
4 files changed, 67 insertions, 66 deletions
diff --git a/src/blocks.c b/src/blocks.c
index 8c7d49c..72b2dc2 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -18,35 +18,32 @@ static void finalize(node_block* b, int line_number);
static node_block* make_block(int tag, int start_line, int start_column)
{
node_block* e;
- e = (node_block*) malloc(sizeof(node_block));
+
+ e = malloc(sizeof(node_block));
+ memset(e, 0x0, sizeof(*e));
+
e->tag = tag;
e->open = true;
- e->last_line_blank = false;
e->start_line = start_line;
e->start_column = start_column;
e->end_line = start_line;
- e->children = NULL;
- e->last_child = NULL;
- e->parent = NULL;
- e->top = NULL;
- e->attributes.refmap = NULL;
strbuf_init(&e->string_content, 32);
- e->inline_content = NULL;
- e->next = NULL;
- e->prev = NULL;
+
return e;
}
// Create a root document node_block.
extern node_block* make_document()
{
- node_block * e = make_block(BLOCK_DOCUMENT, 1, 1);
- reference * map = NULL;
+ node_block *e = make_block(BLOCK_DOCUMENT, 1, 1);
+ reference *map = NULL;
reference ** refmap;
+
refmap = (reference**) malloc(sizeof(reference*));
*refmap = map;
- e->attributes.refmap = refmap;
+ e->as.document.refmap = refmap;
e->top = e;
+
return e;
}
@@ -128,8 +125,8 @@ static bool ends_with_blank_line(node_block* node_block)
// Break out of all containing lists
static int break_out_of_lists(node_block ** bptr, int line_number)
{
- node_block * container = *bptr;
- node_block * b = container->top;
+ node_block *container = *bptr;
+ node_block *b = container->top;
// find first containing BLOCK_LIST:
while (b && b->tag != BLOCK_LIST) {
b = b->last_child;
@@ -167,7 +164,7 @@ static void finalize(node_block* b, int line_number)
case BLOCK_PARAGRAPH:
pos = 0;
while (strbuf_at(&b->string_content, 0) == '[' &&
- (pos = parse_reference(&b->string_content, b->top->attributes.refmap))) {
+ (pos = parse_reference(&b->string_content, b->top->as.document.refmap))) {
strbuf_drop(&b->string_content, pos);
}
@@ -185,27 +182,27 @@ static void finalize(node_block* b, int line_number)
// first line of contents becomes info
firstlinelen = strbuf_strchr(&b->string_content, '\n', 0);
- strbuf_init(&b->attributes.fenced_code_data.info, 0);
+ strbuf_init(&b->as.code.info, 0);
houdini_unescape_html_f(
- &b->attributes.fenced_code_data.info,
+ &b->as.code.info,
b->string_content.ptr,
firstlinelen
);
strbuf_drop(&b->string_content, firstlinelen + 1);
- strbuf_trim(&b->attributes.fenced_code_data.info);
- unescape_buffer(&b->attributes.fenced_code_data.info);
+ strbuf_trim(&b->as.code.info);
+ unescape_buffer(&b->as.code.info);
break;
case BLOCK_LIST: // determine tight/loose status
- b->attributes.list_data.tight = true; // tight by default
+ b->as.list.tight = true; // tight by default
item = b->children;
while (item) {
// check for non-final non-empty list item ending with blank line:
if (item->last_line_blank && item->next) {
- b->attributes.list_data.tight = false;
+ b->as.list.tight = false;
break;
}
// recurse into children of list item, to see if there are
@@ -214,12 +211,12 @@ static void finalize(node_block* b, int line_number)
while (subitem) {
if (ends_with_blank_line(subitem) &&
(item->next || subitem->next)) {
- b->attributes.list_data.tight = false;
+ b->as.list.tight = false;
break;
}
subitem = subitem->next;
}
- if (!(b->attributes.list_data.tight)) {
+ if (!(b->as.list.tight)) {
break;
}
item = item->next;
@@ -269,9 +266,9 @@ extern void free_blocks(node_block* e)
free_inlines(e->inline_content);
strbuf_free(&e->string_content);
if (e->tag == BLOCK_FENCED_CODE) {
- strbuf_free(&e->attributes.fenced_code_data.info);
+ strbuf_free(&e->as.code.info);
} else if (e->tag == BLOCK_DOCUMENT) {
- free_reference_map(e->attributes.refmap);
+ free_reference_map(e->as.document.refmap);
}
free_blocks(e->children);
free(e);
@@ -362,13 +359,12 @@ static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr)
}
// Return 1 if list item belongs in list, else 0.
-static int lists_match(struct ListData list_data,
- struct ListData item_data)
+static int lists_match(struct ListData *list_data, struct ListData *item_data)
{
- return (list_data.list_type == item_data.list_type &&
- list_data.delimiter == item_data.delimiter &&
- // list_data.marker_offset == item_data.marker_offset &&
- list_data.bullet_char == item_data.bullet_char);
+ return (list_data->list_type == item_data->list_type &&
+ list_data->delimiter == item_data->delimiter &&
+ // list_data->marker_offset == item_data.marker_offset &&
+ list_data->bullet_char == item_data->bullet_char);
}
static node_block *finalize_document(node_block *document, int linenum)
@@ -379,7 +375,7 @@ static node_block *finalize_document(node_block *document, int linenum)
}
finalize(document, linenum);
- process_inlines(document, document->attributes.refmap);
+ process_inlines(document, document->as.document.refmap);
return document;
}
@@ -496,10 +492,10 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
} else if (container->tag == BLOCK_LIST_ITEM) {
- if (indent >= container->attributes.list_data.marker_offset +
- container->attributes.list_data.padding) {
- offset += container->attributes.list_data.marker_offset +
- container->attributes.list_data.padding;
+ if (indent >= container->as.list.marker_offset +
+ container->as.list.padding) {
+ offset += container->as.list.marker_offset +
+ container->as.list.padding;
} else if (blank) {
offset = first_nonspace;
} else {
@@ -525,7 +521,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
} else if (container->tag == BLOCK_FENCED_CODE) {
// skip optional spaces of fence offset
- i = container->attributes.fenced_code_data.fence_offset;
+ i = container->as.code.fence_offset;
while (i > 0 && peek_at(&input, offset) == ' ') {
offset++;
i--;
@@ -598,14 +594,14 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
level++;
hashpos++;
}
- container->attributes.header_level = level;
+ container->as.header.level = level;
} else if ((matched = scan_open_code_fence(&input, first_nonspace))) {
container = add_child(container, BLOCK_FENCED_CODE, line_number, first_nonspace + 1);
- container->attributes.fenced_code_data.fence_char = peek_at(&input, first_nonspace);
- container->attributes.fenced_code_data.fence_length = matched;
- container->attributes.fenced_code_data.fence_offset = first_nonspace - offset;
+ container->as.code.fence_char = peek_at(&input, first_nonspace);
+ container->as.code.fence_length = matched;
+ container->as.code.fence_offset = first_nonspace - offset;
offset = first_nonspace + matched;
} else if ((matched = scan_html_block_tag(&input, first_nonspace))) {
@@ -620,7 +616,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
strbuf_len(&container->string_content) - 2) < 0) {
container->tag = BLOCK_SETEXT_HEADER;
- container->attributes.header_level = lev;
+ container->as.header.level = lev;
offset = input.len - 1;
} else if (!(container->tag == BLOCK_PARAGRAPH && !all_matched) &&
@@ -657,19 +653,19 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
data->marker_offset = indent;
if (container->tag != BLOCK_LIST ||
- !lists_match(container->attributes.list_data, *data)) {
+ !lists_match(&container->as.list, data)) {
container = add_child(container, BLOCK_LIST, line_number,
first_nonspace + 1);
- container->attributes.list_data = *data;
+
+ memcpy(&container->as.list, data, sizeof(*data));
}
// add the list item
container = add_child(container, BLOCK_LIST_ITEM, line_number,
first_nonspace + 1);
/* TODO: static */
- container->attributes.list_data = *data;
+ memcpy(&container->as.list, data, sizeof(*data));
free(data);
-
} else {
break;
}
@@ -732,9 +728,9 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
matched = 0;
if (indent <= 3 &&
- peek_at(&input, first_nonspace) == container->attributes.fenced_code_data.fence_char) {
+ peek_at(&input, first_nonspace) == container->as.code.fence_char) {
int fence_len = scan_close_code_fence(&input, first_nonspace);
- if (fence_len > container->attributes.fenced_code_data.fence_length)
+ if (fence_len > container->as.code.fence_length)
matched = 1;
}
diff --git a/src/html/html.c b/src/html/html.c
index 595dfcd..129335f 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -72,7 +72,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
case BLOCK_LIST:
// make sure a list starts at the beginning of the line:
cr(html);
- data = &(b->attributes.list_data);
+ data = &(b->as.list);
if (data->start > 1) {
strbuf_printf(html, "<%s start=\"%d\">\n",
@@ -90,9 +90,9 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
case BLOCK_ATX_HEADER:
case BLOCK_SETEXT_HEADER:
cr(html);
- strbuf_printf(html, "<h%d>", b->attributes.header_level);
+ strbuf_printf(html, "<h%d>", b->as.header.level);
inlines_to_html(html, b->inline_content);
- strbuf_printf(html, "</h%d>\n", b->attributes.header_level);
+ strbuf_printf(html, "</h%d>\n", b->as.header.level);
break;
case BLOCK_INDENTED_CODE:
@@ -102,7 +102,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
strbuf_puts(html, "<pre");
if (b->tag == BLOCK_FENCED_CODE) {
- strbuf *info = &b->attributes.fenced_code_data.info;
+ strbuf *info = &b->as.code.info;
if (strbuf_len(info) > 0) {
int first_tag = strbuf_strchr(info, ' ', 0);
diff --git a/src/print.c b/src/print.c
index 9240dac..36140a8 100644
--- a/src/print.c
+++ b/src/print.c
@@ -54,12 +54,11 @@ extern void print_blocks(node_block* b, int indent)
print_blocks(b->children, indent + 2);
break;
case BLOCK_LIST_ITEM:
- data = &(b->attributes.list_data);
printf("list_item\n");
print_blocks(b->children, indent + 2);
break;
case BLOCK_LIST:
- data = &(b->attributes.list_data);
+ data = &(b->as.list);
if (data->list_type == ordered) {
printf("list (type=ordered tight=%s start=%d delim=%s)\n",
(data->tight ? "true" : "false"),
@@ -73,11 +72,11 @@ extern void print_blocks(node_block* b, int indent)
print_blocks(b->children, indent + 2);
break;
case BLOCK_ATX_HEADER:
- printf("atx_header (level=%d)\n", b->attributes.header_level);
+ printf("atx_header (level=%d)\n", b->as.header.level);
print_inlines(b->inline_content, indent + 2);
break;
case BLOCK_SETEXT_HEADER:
- printf("setext_header (level=%d)\n", b->attributes.header_level);
+ printf("setext_header (level=%d)\n", b->as.header.level);
print_inlines(b->inline_content, indent + 2);
break;
case BLOCK_PARAGRAPH:
@@ -94,8 +93,8 @@ extern void print_blocks(node_block* b, int indent)
break;
case BLOCK_FENCED_CODE:
printf("fenced_code length=%d info=",
- b->attributes.fenced_code_data.fence_length);
- print_str(b->attributes.fenced_code_data.info.ptr, -1);
+ b->as.code.fence_length);
+ print_str(b->as.code.info.ptr, -1);
putchar(' ');
print_str(b->string_content.ptr, -1);
putchar('\n');
diff --git a/src/stmd.h b/src/stmd.h
index c80eeda..21a86b0 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -96,14 +96,20 @@ struct node_block {
struct node_block* top;
strbuf string_content;
node_inl* inline_content;
+
union {
- struct ListData list_data;
- struct FencedCodeData fenced_code_data;
- int header_level;
- reference** refmap;
- } attributes;
- struct node_block * next;
- struct node_block * prev;
+ struct ListData list;
+ struct FencedCodeData code;
+ struct {
+ int level;
+ } header;
+ struct {
+ reference** refmap;
+ } document;
+ } as;
+
+ struct node_block *next;
+ struct node_block *prev;
};
typedef struct node_block node_block;