diff options
Diffstat (limited to 'pathologist/src/struct_parse/p.c')
-rw-r--r-- | pathologist/src/struct_parse/p.c | 147 |
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 | |||
5 | char* 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 | ||
10 | char* 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 | |||
103 | char * 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 | |||
137 | int 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 | } | ||