aboutsummaryrefslogtreecommitdiff
path: root/pathologist/src/struct_parse/p.c
diff options
context:
space:
mode:
Diffstat (limited to 'pathologist/src/struct_parse/p.c')
-rw-r--r--pathologist/src/struct_parse/p.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/pathologist/src/struct_parse/p.c b/pathologist/src/struct_parse/p.c
new file mode 100644
index 0000000..c99a654
--- /dev/null
+++ b/pathologist/src/struct_parse/p.c
@@ -0,0 +1,147 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5char* parse(char* str, int indent);
6
7// parses one pair of curly braces recursively.
8// expects first char to be the opening '{'
9// returns pointer to the next char after the closing '}' or NULL on error
10char* parse(char* str, int indent) {
11 int is_struct = 0, is_array = 0, had_equals = 0, had_children = 0, had_end = 0;
12 char* first = NULL;
13 char* second = NULL;
14 char* ws = NULL;
15 char* count = NULL;
16
17 if(*str++ != '{') return NULL;
18 while(*str == ' ') str++;
19 if(!*str) return NULL;
20 while(*str) {
21 first = str;
22 second = NULL;
23 had_equals = 0;
24 had_children = 0;
25 had_end = 0;
26 count = NULL;
27 while(*str) {
28 if(*str == '{') {
29 if( (is_struct && !had_equals) ||
30 (str != first && str != second) ) return NULL;
31 if(str == second) {
32 printf("%*s<expression name=\"%s\">\n", 2*indent, "", first);
33 had_children = 1;
34 }
35 str = parse(str, indent+1);
36 //continue; // have to check this char => no str++ at end of loop.
37 } else if(*str == '=') {
38 if(had_equals || is_array) return NULL;
39 had_equals = 1;
40 if(!is_struct && !is_array)
41 is_struct = 1;
42 for(ws = str-1; *ws == ' '; ws--)
43 *ws = '\0';
44 *str = '\0';
45 while(*++str == ' ');
46 second = str;
47 continue; // have to check this char => no str++ at end of loop.
48 } else if(*str == '\'' || *str == '"') {
49 char end_char = *str;
50 if(had_equals) second = str;
51 else first = str;
52 for(str++; *str != end_char; str++) {
53 if(!*str) return NULL;
54 if(*str == '\\') {
55 if(!*(str+1)) return NULL;
56 else str++;
57 }
58 }
59 } else if(*str == '<') {
60 for(ws = str-1; *ws == ' '; ws--)
61 *ws = '\0';
62 if(!(str = strpbrk(str+1, "0123456789>"))) return NULL;
63 if(*str == '>') continue;
64 count = str;
65 if(!(str = strpbrk(str+1, " >"))) return NULL;
66 if(*str == ' ')
67 *str = '\0';
68 else {
69 *str = '\0';
70 if(!(str = strchr(str+1, '>'))) return NULL;
71 }
72 } else if(*str == ',') {
73 if(is_struct && !had_equals) return NULL;
74 is_array = !is_struct;
75 is_struct = !is_array;
76 break;
77 } else if(*str == '}') {
78 had_end = 1;
79 break;
80 }
81 str++;
82 }
83 for(ws = str-1; *ws == ' '; ws--)
84 *ws = '\0';
85 *str = '\0';
86 if(had_children)
87 printf("%*s</expression>\n", 2*indent, "");
88 else if(is_array)
89 if(count)
90 printf("%*s<element count=\"%s\">%s</element>\n", 2*indent, "", count, first);
91 else
92 printf("%*s<element>%s</element>\n", 2*indent, "", first);
93 else
94 printf("%*s<expression name=\"%s\">%s</expression>\n", 2*indent, "", first, second);
95 if(had_end) return str;
96 str++;
97 while(*str == ' ') str++;
98 }
99 return NULL;
100}
101
102
103char * getl(void) {
104 char * line = malloc(128), * linep = line;
105 size_t lenmax = 128, len = lenmax;
106 int c;
107
108 if(line == NULL)
109 return NULL;
110
111 for(;;) {
112 c = fgetc(stdin);
113 if(c == EOF)
114 break;
115
116 if(--len == 0) {
117 len = lenmax;
118 char * linen = realloc(linep, lenmax *= 2);
119
120 if(linen == NULL) {
121 free(linep);
122 return NULL;
123 }
124 line = linen + (line - linep);
125 linep = linen;
126 }
127
128 if((*line = c) == '\n')
129 break;
130 line++;
131 }
132 *line = '\0';
133 return linep;
134}
135
136
137int main(int argc, char* argv[]) {
138 char* line;
139 while(line = getl()) {
140 if(*line == '\0') break;
141 if(!parse(line, 1))
142 printf("=====FAILED!=====\n\n");
143 free(line);
144 }
145 if(line) free(line);
146 return 0;
147}