1 /* parsing_functions.c - Functions for parsing markdown and
2  * freeing element lists. */
3 
4 /* These yy_* functions come from markdown_parser.c which is
5  * generated from markdown_parser.leg
6  * */
7 typedef int (*yyrule)();
8 
9 extern int yyparse();
10 extern int yyparsefrom(yyrule);
11 extern int yy_References();
12 extern int yy_Notes();
13 extern int yy_Doc();
14 
15 #include "utility_functions.h"
16 #include "parsing_functions.h"
17 #include "markdown_peg.h"
18 
19 static void free_element_contents(element elt);
20 
21 /* free_element_list - free list of elements recursively */
free_element_list(element * elt)22 void free_element_list(element * elt) {
23     element * next = NULL;
24     while (elt != NULL) {
25         next = elt->next;
26         free_element_contents(*elt);
27         if (elt->children != NULL) {
28             free_element_list(elt->children);
29             elt->children = NULL;
30         }
31         free(elt);
32         elt = next;
33     }
34 }
35 
36 /* free_element_contents - free element contents depending on type */
free_element_contents(element elt)37 static void free_element_contents(element elt) {
38     switch (elt.key) {
39       case STR:
40       case SPACE:
41       case RAW:
42       case HTMLBLOCK:
43       case HTML:
44       case VERBATIM:
45       case CODE:
46       case NOTE:
47         free(elt.contents.str);
48         elt.contents.str = NULL;
49         break;
50       case LINK:
51       case IMAGE:
52       case REFERENCE:
53         free(elt.contents.link->url);
54         elt.contents.link->url = NULL;
55         free(elt.contents.link->title);
56         elt.contents.link->title = NULL;
57         free_element_list(elt.contents.link->label);
58         free(elt.contents.link);
59         elt.contents.link = NULL;
60         break;
61       default:
62         ;
63     }
64 }
65 
66 /* free_element - free element and contents */
free_element(element * elt)67 void free_element(element *elt) {
68     free_element_contents(*elt);
69     free(elt);
70 }
71 
parse_references(char * string,int extensions)72 element * parse_references(char *string, int extensions) {
73 
74     char *oldcharbuf;
75     syntax_extensions = extensions;
76 
77     oldcharbuf = charbuf;
78     charbuf = string;
79     yyparsefrom(yy_References);    /* first pass, just to collect references */
80     charbuf = oldcharbuf;
81 
82     return references;
83 }
84 
parse_notes(char * string,int extensions,element * reference_list)85 element * parse_notes(char *string, int extensions, element *reference_list) {
86 
87     char *oldcharbuf;
88     notes = NULL;
89     syntax_extensions = extensions;
90 
91     if (extension(EXT_NOTES)) {
92         references = reference_list;
93         oldcharbuf = charbuf;
94         charbuf = string;
95         yyparsefrom(yy_Notes);     /* second pass for notes */
96         charbuf = oldcharbuf;
97     }
98 
99     return notes;
100 }
101 
parse_markdown(char * string,int extensions,element * reference_list,element * note_list)102 element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list) {
103 
104     char *oldcharbuf;
105     syntax_extensions = extensions;
106     references = reference_list;
107     notes = note_list;
108 
109     oldcharbuf = charbuf;
110     charbuf = string;
111 
112     yyparsefrom(yy_Doc);
113 
114     charbuf = oldcharbuf;          /* restore charbuf to original value */
115     return parse_result;
116 
117 }
118