BadVPN – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /** |
2 | * @file NCDAst.c |
||
3 | * @author Ambroz Bizjak <ambrop7@gmail.com> |
||
4 | * |
||
5 | * @section LICENSE |
||
6 | * |
||
7 | * Redistribution and use in source and binary forms, with or without |
||
8 | * modification, are permitted provided that the following conditions are met: |
||
9 | * 1. Redistributions of source code must retain the above copyright |
||
10 | * notice, this list of conditions and the following disclaimer. |
||
11 | * 2. Redistributions in binary form must reproduce the above copyright |
||
12 | * notice, this list of conditions and the following disclaimer in the |
||
13 | * documentation and/or other materials provided with the distribution. |
||
14 | * 3. Neither the name of the author nor the |
||
15 | * names of its contributors may be used to endorse or promote products |
||
16 | * derived from this software without specific prior written permission. |
||
17 | * |
||
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
21 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
28 | */ |
||
29 | |||
30 | #include <stdlib.h> |
||
31 | #include <limits.h> |
||
32 | #include <string.h> |
||
33 | |||
34 | #include <misc/offset.h> |
||
35 | #include <misc/strdup.h> |
||
36 | |||
37 | #include "NCDAst.h" |
||
38 | |||
39 | struct NCDValue__list_element { |
||
40 | LinkedList1Node list_node; |
||
41 | NCDValue v; |
||
42 | }; |
||
43 | |||
44 | struct NCDValue__map_element { |
||
45 | LinkedList1Node list_node; |
||
46 | NCDValue key; |
||
47 | NCDValue val; |
||
48 | }; |
||
49 | |||
50 | struct ProgramElem { |
||
51 | LinkedList1Node elems_list_node; |
||
52 | NCDProgramElem elem; |
||
53 | }; |
||
54 | |||
55 | struct BlockStatement { |
||
56 | LinkedList1Node statements_list_node; |
||
57 | NCDStatement s; |
||
58 | }; |
||
59 | |||
60 | struct IfBlockIf { |
||
61 | LinkedList1Node ifs_list_node; |
||
62 | NCDIf ifc; |
||
63 | }; |
||
64 | |||
65 | static void value_assert (NCDValue *o) |
||
66 | { |
||
67 | switch (o->type) { |
||
68 | case NCDVALUE_STRING: |
||
69 | case NCDVALUE_LIST: |
||
70 | case NCDVALUE_MAP: |
||
71 | case NCDVALUE_VAR: |
||
72 | case NCDVALUE_INVOC: |
||
73 | return; |
||
74 | default: |
||
75 | ASSERT(0); |
||
76 | } |
||
77 | } |
||
78 | |||
79 | void NCDValue_Free (NCDValue *o) |
||
80 | { |
||
81 | switch (o->type) { |
||
82 | case NCDVALUE_STRING: { |
||
83 | free(o->string); |
||
84 | } break; |
||
85 | |||
86 | case NCDVALUE_LIST: { |
||
87 | LinkedList1Node *n; |
||
88 | while (n = LinkedList1_GetFirst(&o->list)) { |
||
89 | struct NCDValue__list_element *e = UPPER_OBJECT(n, struct NCDValue__list_element, list_node); |
||
90 | |||
91 | NCDValue_Free(&e->v); |
||
92 | LinkedList1_Remove(&o->list, &e->list_node); |
||
93 | free(e); |
||
94 | } |
||
95 | } break; |
||
96 | |||
97 | case NCDVALUE_MAP: { |
||
98 | LinkedList1Node *n; |
||
99 | while (n = LinkedList1_GetFirst(&o->map_list)) { |
||
100 | struct NCDValue__map_element *e = UPPER_OBJECT(n, struct NCDValue__map_element, list_node); |
||
101 | |||
102 | LinkedList1_Remove(&o->map_list, &e->list_node); |
||
103 | NCDValue_Free(&e->key); |
||
104 | NCDValue_Free(&e->val); |
||
105 | free(e); |
||
106 | } |
||
107 | } break; |
||
108 | |||
109 | case NCDVALUE_VAR: { |
||
110 | free(o->var_name); |
||
111 | } break; |
||
112 | |||
113 | case NCDVALUE_INVOC: { |
||
114 | NCDValue_Free(o->invoc_arg); |
||
115 | NCDValue_Free(o->invoc_func); |
||
116 | free(o->invoc_arg); |
||
117 | free(o->invoc_func); |
||
118 | } break; |
||
119 | |||
120 | default: |
||
121 | ASSERT(0); |
||
122 | } |
||
123 | } |
||
124 | |||
125 | int NCDValue_Type (NCDValue *o) |
||
126 | { |
||
127 | value_assert(o); |
||
128 | |||
129 | return o->type; |
||
130 | } |
||
131 | |||
132 | int NCDValue_InitString (NCDValue *o, const char *str) |
||
133 | { |
||
134 | return NCDValue_InitStringBin(o, (const uint8_t *)str, strlen(str)); |
||
135 | } |
||
136 | |||
137 | int NCDValue_InitStringBin (NCDValue *o, const uint8_t *str, size_t len) |
||
138 | { |
||
139 | if (len == SIZE_MAX) { |
||
140 | return 0; |
||
141 | } |
||
142 | |||
143 | if (!(o->string = malloc(len + 1))) { |
||
144 | return 0; |
||
145 | } |
||
146 | |||
147 | memcpy(o->string, str, len); |
||
148 | o->string[len] = '\0'; |
||
149 | o->string_len = len; |
||
150 | |||
151 | o->type = NCDVALUE_STRING; |
||
152 | |||
153 | return 1; |
||
154 | } |
||
155 | |||
156 | const char * NCDValue_StringValue (NCDValue *o) |
||
157 | { |
||
158 | ASSERT(o->type == NCDVALUE_STRING) |
||
159 | |||
160 | return (char *)o->string; |
||
161 | } |
||
162 | |||
163 | size_t NCDValue_StringLength (NCDValue *o) |
||
164 | { |
||
165 | ASSERT(o->type == NCDVALUE_STRING) |
||
166 | |||
167 | return o->string_len; |
||
168 | } |
||
169 | |||
170 | void NCDValue_InitList (NCDValue *o) |
||
171 | { |
||
172 | o->type = NCDVALUE_LIST; |
||
173 | LinkedList1_Init(&o->list); |
||
174 | o->list_count = 0; |
||
175 | } |
||
176 | |||
177 | size_t NCDValue_ListCount (NCDValue *o) |
||
178 | { |
||
179 | value_assert(o); |
||
180 | ASSERT(o->type == NCDVALUE_LIST) |
||
181 | |||
182 | return o->list_count; |
||
183 | } |
||
184 | |||
185 | int NCDValue_ListAppend (NCDValue *o, NCDValue v) |
||
186 | { |
||
187 | value_assert(o); |
||
188 | ASSERT(o->type == NCDVALUE_LIST) |
||
189 | value_assert(&v); |
||
190 | |||
191 | if (o->list_count == SIZE_MAX) { |
||
192 | return 0; |
||
193 | } |
||
194 | |||
195 | struct NCDValue__list_element *e = malloc(sizeof(*e)); |
||
196 | if (!e) { |
||
197 | return 0; |
||
198 | } |
||
199 | |||
200 | e->v = v; |
||
201 | LinkedList1_Append(&o->list, &e->list_node); |
||
202 | |||
203 | o->list_count++; |
||
204 | |||
205 | return 1; |
||
206 | } |
||
207 | |||
208 | int NCDValue_ListPrepend (NCDValue *o, NCDValue v) |
||
209 | { |
||
210 | value_assert(o); |
||
211 | ASSERT(o->type == NCDVALUE_LIST) |
||
212 | value_assert(&v); |
||
213 | |||
214 | if (o->list_count == SIZE_MAX) { |
||
215 | return 0; |
||
216 | } |
||
217 | |||
218 | struct NCDValue__list_element *e = malloc(sizeof(*e)); |
||
219 | if (!e) { |
||
220 | return 0; |
||
221 | } |
||
222 | |||
223 | e->v = v; |
||
224 | LinkedList1_Prepend(&o->list, &e->list_node); |
||
225 | |||
226 | o->list_count++; |
||
227 | |||
228 | return 1; |
||
229 | } |
||
230 | |||
231 | NCDValue * NCDValue_ListFirst (NCDValue *o) |
||
232 | { |
||
233 | value_assert(o); |
||
234 | ASSERT(o->type == NCDVALUE_LIST) |
||
235 | |||
236 | LinkedList1Node *ln = LinkedList1_GetFirst(&o->list); |
||
237 | |||
238 | if (!ln) { |
||
239 | return NULL; |
||
240 | } |
||
241 | |||
242 | struct NCDValue__list_element *e = UPPER_OBJECT(ln, struct NCDValue__list_element, list_node); |
||
243 | |||
244 | return &e->v; |
||
245 | } |
||
246 | |||
247 | NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev) |
||
248 | { |
||
249 | value_assert(o); |
||
250 | ASSERT(o->type == NCDVALUE_LIST) |
||
251 | |||
252 | struct NCDValue__list_element *cur_e = UPPER_OBJECT(ev, struct NCDValue__list_element, v); |
||
253 | LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->list_node); |
||
254 | |||
255 | if (!ln) { |
||
256 | return NULL; |
||
257 | } |
||
258 | |||
259 | struct NCDValue__list_element *e = UPPER_OBJECT(ln, struct NCDValue__list_element, list_node); |
||
260 | |||
261 | return &e->v; |
||
262 | } |
||
263 | |||
264 | void NCDValue_InitMap (NCDValue *o) |
||
265 | { |
||
266 | o->type = NCDVALUE_MAP; |
||
267 | LinkedList1_Init(&o->map_list); |
||
268 | o->map_count = 0; |
||
269 | } |
||
270 | |||
271 | size_t NCDValue_MapCount (NCDValue *o) |
||
272 | { |
||
273 | value_assert(o); |
||
274 | ASSERT(o->type == NCDVALUE_MAP) |
||
275 | |||
276 | return o->map_count; |
||
277 | } |
||
278 | |||
279 | int NCDValue_MapPrepend (NCDValue *o, NCDValue key, NCDValue val) |
||
280 | { |
||
281 | value_assert(o); |
||
282 | ASSERT(o->type == NCDVALUE_MAP) |
||
283 | value_assert(&key); |
||
284 | value_assert(&val); |
||
285 | |||
286 | if (o->map_count == SIZE_MAX) { |
||
287 | return 0; |
||
288 | } |
||
289 | |||
290 | struct NCDValue__map_element *e = malloc(sizeof(*e)); |
||
291 | if (!e) { |
||
292 | return 0; |
||
293 | } |
||
294 | |||
295 | e->key = key; |
||
296 | e->val = val; |
||
297 | LinkedList1_Prepend(&o->map_list, &e->list_node); |
||
298 | |||
299 | o->map_count++; |
||
300 | |||
301 | return 1; |
||
302 | } |
||
303 | |||
304 | NCDValue * NCDValue_MapFirstKey (NCDValue *o) |
||
305 | { |
||
306 | value_assert(o); |
||
307 | ASSERT(o->type == NCDVALUE_MAP) |
||
308 | |||
309 | LinkedList1Node *ln = LinkedList1_GetFirst(&o->map_list); |
||
310 | |||
311 | if (!ln) { |
||
312 | return NULL; |
||
313 | } |
||
314 | |||
315 | struct NCDValue__map_element *e = UPPER_OBJECT(ln, struct NCDValue__map_element, list_node); |
||
316 | |||
317 | value_assert(&e->key); |
||
318 | value_assert(&e->val); |
||
319 | |||
320 | return &e->key; |
||
321 | } |
||
322 | |||
323 | NCDValue * NCDValue_MapNextKey (NCDValue *o, NCDValue *ekey) |
||
324 | { |
||
325 | value_assert(o); |
||
326 | ASSERT(o->type == NCDVALUE_MAP) |
||
327 | |||
328 | struct NCDValue__map_element *e0 = UPPER_OBJECT(ekey, struct NCDValue__map_element, key); |
||
329 | value_assert(&e0->key); |
||
330 | value_assert(&e0->val); |
||
331 | |||
332 | LinkedList1Node *ln = LinkedList1Node_Next(&e0->list_node); |
||
333 | |||
334 | if (!ln) { |
||
335 | return NULL; |
||
336 | } |
||
337 | |||
338 | struct NCDValue__map_element *e = UPPER_OBJECT(ln, struct NCDValue__map_element, list_node); |
||
339 | |||
340 | value_assert(&e->key); |
||
341 | value_assert(&e->val); |
||
342 | |||
343 | return &e->key; |
||
344 | } |
||
345 | |||
346 | NCDValue * NCDValue_MapKeyValue (NCDValue *o, NCDValue *ekey) |
||
347 | { |
||
348 | value_assert(o); |
||
349 | ASSERT(o->type == NCDVALUE_MAP) |
||
350 | |||
351 | struct NCDValue__map_element *e = UPPER_OBJECT(ekey, struct NCDValue__map_element, key); |
||
352 | value_assert(&e->key); |
||
353 | value_assert(&e->val); |
||
354 | |||
355 | return &e->val; |
||
356 | } |
||
357 | |||
358 | int NCDValue_InitVar (NCDValue *o, const char *var_name) |
||
359 | { |
||
360 | ASSERT(var_name) |
||
361 | |||
362 | if (!(o->var_name = strdup(var_name))) { |
||
363 | return 0; |
||
364 | } |
||
365 | |||
366 | o->type = NCDVALUE_VAR; |
||
367 | |||
368 | return 1; |
||
369 | } |
||
370 | |||
371 | const char * NCDValue_VarName (NCDValue *o) |
||
372 | { |
||
373 | value_assert(o); |
||
374 | ASSERT(o->type == NCDVALUE_VAR) |
||
375 | |||
376 | return o->var_name; |
||
377 | } |
||
378 | |||
379 | int NCDValue_InitInvoc (NCDValue *o, NCDValue func, NCDValue arg) |
||
380 | { |
||
381 | value_assert(&func); |
||
382 | value_assert(&arg); |
||
383 | |||
384 | if (!(o->invoc_func = malloc(sizeof(*o->invoc_func)))) { |
||
385 | goto fail0; |
||
386 | } |
||
387 | if (!(o->invoc_arg = malloc(sizeof(*o->invoc_arg)))) { |
||
388 | goto fail1; |
||
389 | } |
||
390 | |||
391 | *o->invoc_func = func; |
||
392 | *o->invoc_arg = arg; |
||
393 | |||
394 | o->type = NCDVALUE_INVOC; |
||
395 | |||
396 | return 1; |
||
397 | |||
398 | fail1: |
||
399 | free(o->invoc_func); |
||
400 | fail0: |
||
401 | return 0; |
||
402 | } |
||
403 | |||
404 | NCDValue * NCDValue_InvocFunc (NCDValue *o) |
||
405 | { |
||
406 | value_assert(o); |
||
407 | ASSERT(o->type == NCDVALUE_INVOC) |
||
408 | |||
409 | return o->invoc_func; |
||
410 | } |
||
411 | |||
412 | NCDValue * NCDValue_InvocArg (NCDValue *o) |
||
413 | { |
||
414 | value_assert(o); |
||
415 | ASSERT(o->type == NCDVALUE_INVOC) |
||
416 | |||
417 | return o->invoc_arg; |
||
418 | } |
||
419 | |||
420 | void NCDProgram_Init (NCDProgram *o) |
||
421 | { |
||
422 | LinkedList1_Init(&o->elems_list); |
||
423 | o->num_elems = 0; |
||
424 | } |
||
425 | |||
426 | void NCDProgram_Free (NCDProgram *o) |
||
427 | { |
||
428 | LinkedList1Node *ln; |
||
429 | while (ln = LinkedList1_GetFirst(&o->elems_list)) { |
||
430 | struct ProgramElem *e = UPPER_OBJECT(ln, struct ProgramElem, elems_list_node); |
||
431 | NCDProgramElem_Free(&e->elem); |
||
432 | LinkedList1_Remove(&o->elems_list, &e->elems_list_node); |
||
433 | free(e); |
||
434 | } |
||
435 | } |
||
436 | |||
437 | NCDProgramElem * NCDProgram_PrependElem (NCDProgram *o, NCDProgramElem elem) |
||
438 | { |
||
439 | if (o->num_elems == SIZE_MAX) { |
||
440 | return NULL; |
||
441 | } |
||
442 | |||
443 | struct ProgramElem *e = malloc(sizeof(*e)); |
||
444 | if (!e) { |
||
445 | return NULL; |
||
446 | } |
||
447 | |||
448 | LinkedList1_Prepend(&o->elems_list, &e->elems_list_node); |
||
449 | e->elem = elem; |
||
450 | |||
451 | o->num_elems++; |
||
452 | |||
453 | return &e->elem; |
||
454 | } |
||
455 | |||
456 | NCDProgramElem * NCDProgram_FirstElem (NCDProgram *o) |
||
457 | { |
||
458 | LinkedList1Node *ln = LinkedList1_GetFirst(&o->elems_list); |
||
459 | if (!ln) { |
||
460 | return NULL; |
||
461 | } |
||
462 | |||
463 | struct ProgramElem *e = UPPER_OBJECT(ln, struct ProgramElem, elems_list_node); |
||
464 | |||
465 | return &e->elem; |
||
466 | } |
||
467 | |||
468 | NCDProgramElem * NCDProgram_NextElem (NCDProgram *o, NCDProgramElem *ee) |
||
469 | { |
||
470 | ASSERT(ee) |
||
471 | |||
472 | struct ProgramElem *cur_e = UPPER_OBJECT(ee, struct ProgramElem, elem); |
||
473 | |||
474 | LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->elems_list_node); |
||
475 | if (!ln) { |
||
476 | return NULL; |
||
477 | } |
||
478 | |||
479 | struct ProgramElem *e = UPPER_OBJECT(ln, struct ProgramElem, elems_list_node); |
||
480 | |||
481 | return &e->elem; |
||
482 | } |
||
483 | |||
484 | size_t NCDProgram_NumElems (NCDProgram *o) |
||
485 | { |
||
486 | return o->num_elems; |
||
487 | } |
||
488 | |||
489 | int NCDProgram_ContainsElemType (NCDProgram *o, int elem_type) |
||
490 | { |
||
491 | for (NCDProgramElem *elem = NCDProgram_FirstElem(o); elem; elem = NCDProgram_NextElem(o, elem)) { |
||
492 | if (NCDProgramElem_Type(elem) == elem_type) { |
||
493 | return 1; |
||
494 | } |
||
495 | } |
||
496 | |||
497 | return 0; |
||
498 | } |
||
499 | |||
500 | void NCDProgram_RemoveElem (NCDProgram *o, NCDProgramElem *ee) |
||
501 | { |
||
502 | ASSERT(ee) |
||
503 | |||
504 | struct ProgramElem *e = UPPER_OBJECT(ee, struct ProgramElem, elem); |
||
505 | NCDProgramElem_Free(&e->elem); |
||
506 | LinkedList1_Remove(&o->elems_list, &e->elems_list_node); |
||
507 | free(e); |
||
508 | |||
509 | ASSERT(o->num_elems > 0) |
||
510 | o->num_elems--; |
||
511 | } |
||
512 | |||
513 | int NCDProgram_ReplaceElemWithProgram (NCDProgram *o, NCDProgramElem *ee, NCDProgram replace_prog) |
||
514 | { |
||
515 | ASSERT(ee) |
||
516 | |||
517 | if (replace_prog.num_elems > SIZE_MAX - o->num_elems) { |
||
518 | return 0; |
||
519 | } |
||
520 | |||
521 | struct ProgramElem *e = UPPER_OBJECT(ee, struct ProgramElem, elem); |
||
522 | |||
523 | LinkedList1_InsertListAfter(&o->elems_list, replace_prog.elems_list, &e->elems_list_node); |
||
524 | o->num_elems += replace_prog.num_elems; |
||
525 | |||
526 | NCDProgram_RemoveElem(o, ee); |
||
527 | |||
528 | return 1; |
||
529 | } |
||
530 | |||
531 | void NCDProgramElem_InitProcess (NCDProgramElem *o, NCDProcess process) |
||
532 | { |
||
533 | o->type = NCDPROGRAMELEM_PROCESS; |
||
534 | o->process = process; |
||
535 | } |
||
536 | |||
537 | int NCDProgramElem_InitInclude (NCDProgramElem *o, const char *path_data, size_t path_length) |
||
538 | { |
||
539 | if (!(o->include.path_data = b_strdup_bin(path_data, path_length))) { |
||
540 | return 0; |
||
541 | } |
||
542 | |||
543 | o->type = NCDPROGRAMELEM_INCLUDE; |
||
544 | o->include.path_length = path_length; |
||
545 | |||
546 | return 1; |
||
547 | } |
||
548 | |||
549 | int NCDProgramElem_InitIncludeGuard (NCDProgramElem *o, const char *id_data, size_t id_length) |
||
550 | { |
||
551 | if (!(o->include_guard.id_data = b_strdup_bin(id_data, id_length))) { |
||
552 | return 0; |
||
553 | } |
||
554 | |||
555 | o->type = NCDPROGRAMELEM_INCLUDE_GUARD; |
||
556 | o->include_guard.id_length = id_length; |
||
557 | |||
558 | return 1; |
||
559 | } |
||
560 | |||
561 | |||
562 | void NCDProgramElem_Free (NCDProgramElem *o) |
||
563 | { |
||
564 | switch (o->type) { |
||
565 | case NCDPROGRAMELEM_PROCESS: { |
||
566 | NCDProcess_Free(&o->process); |
||
567 | } break; |
||
568 | |||
569 | case NCDPROGRAMELEM_INCLUDE: { |
||
570 | free(o->include.path_data); |
||
571 | } break; |
||
572 | |||
573 | case NCDPROGRAMELEM_INCLUDE_GUARD: { |
||
574 | free(o->include_guard.id_data); |
||
575 | } break; |
||
576 | |||
577 | default: ASSERT(0); |
||
578 | } |
||
579 | } |
||
580 | |||
581 | int NCDProgramElem_Type (NCDProgramElem *o) |
||
582 | { |
||
583 | return o->type; |
||
584 | } |
||
585 | |||
586 | NCDProcess * NCDProgramElem_Process (NCDProgramElem *o) |
||
587 | { |
||
588 | ASSERT(o->type == NCDPROGRAMELEM_PROCESS) |
||
589 | |||
590 | return &o->process; |
||
591 | } |
||
592 | |||
593 | const char * NCDProgramElem_IncludePathData (NCDProgramElem *o) |
||
594 | { |
||
595 | ASSERT(o->type == NCDPROGRAMELEM_INCLUDE) |
||
596 | |||
597 | return o->include.path_data; |
||
598 | } |
||
599 | |||
600 | size_t NCDProgramElem_IncludePathLength (NCDProgramElem *o) |
||
601 | { |
||
602 | ASSERT(o->type == NCDPROGRAMELEM_INCLUDE) |
||
603 | |||
604 | return o->include.path_length; |
||
605 | } |
||
606 | |||
607 | const char * NCDProgramElem_IncludeGuardIdData (NCDProgramElem *o) |
||
608 | { |
||
609 | ASSERT(o->type == NCDPROGRAMELEM_INCLUDE_GUARD) |
||
610 | |||
611 | return o->include_guard.id_data; |
||
612 | } |
||
613 | |||
614 | size_t NCDProgramElem_IncludeGuardIdLength (NCDProgramElem *o) |
||
615 | { |
||
616 | ASSERT(o->type == NCDPROGRAMELEM_INCLUDE_GUARD) |
||
617 | |||
618 | return o->include_guard.id_length; |
||
619 | } |
||
620 | |||
621 | int NCDProcess_Init (NCDProcess *o, int is_template, const char *name, NCDBlock block) |
||
622 | { |
||
623 | ASSERT(is_template == !!is_template) |
||
624 | ASSERT(name) |
||
625 | |||
626 | if (!(o->name = strdup(name))) { |
||
627 | return 0; |
||
628 | } |
||
629 | |||
630 | o->is_template = is_template; |
||
631 | o->block = block; |
||
632 | |||
633 | return 1; |
||
634 | } |
||
635 | |||
636 | void NCDProcess_Free (NCDProcess *o) |
||
637 | { |
||
638 | NCDBlock_Free(&o->block); |
||
639 | free(o->name); |
||
640 | } |
||
641 | |||
642 | int NCDProcess_IsTemplate (NCDProcess *o) |
||
643 | { |
||
644 | return o->is_template; |
||
645 | } |
||
646 | |||
647 | const char * NCDProcess_Name (NCDProcess *o) |
||
648 | { |
||
649 | return o->name; |
||
650 | } |
||
651 | |||
652 | NCDBlock * NCDProcess_Block (NCDProcess *o) |
||
653 | { |
||
654 | return &o->block; |
||
655 | } |
||
656 | |||
657 | void NCDBlock_Init (NCDBlock *o) |
||
658 | { |
||
659 | LinkedList1_Init(&o->statements_list); |
||
660 | o->count = 0; |
||
661 | } |
||
662 | |||
663 | void NCDBlock_Free (NCDBlock *o) |
||
664 | { |
||
665 | LinkedList1Node *ln; |
||
666 | while (ln = LinkedList1_GetFirst(&o->statements_list)) { |
||
667 | struct BlockStatement *e = UPPER_OBJECT(ln, struct BlockStatement, statements_list_node); |
||
668 | NCDStatement_Free(&e->s); |
||
669 | LinkedList1_Remove(&o->statements_list, &e->statements_list_node); |
||
670 | free(e); |
||
671 | } |
||
672 | } |
||
673 | |||
674 | int NCDBlock_PrependStatement (NCDBlock *o, NCDStatement s) |
||
675 | { |
||
676 | return NCDBlock_InsertStatementAfter(o, NULL, s); |
||
677 | } |
||
678 | |||
679 | int NCDBlock_InsertStatementAfter (NCDBlock *o, NCDStatement *after, NCDStatement s) |
||
680 | { |
||
681 | struct BlockStatement *after_e = NULL; |
||
682 | if (after) { |
||
683 | after_e = UPPER_OBJECT(after, struct BlockStatement, s); |
||
684 | } |
||
685 | |||
686 | if (o->count == SIZE_MAX) { |
||
687 | return 0; |
||
688 | } |
||
689 | |||
690 | struct BlockStatement *e = malloc(sizeof(*e)); |
||
691 | if (!e) { |
||
692 | return 0; |
||
693 | } |
||
694 | |||
695 | if (after_e) { |
||
696 | LinkedList1_InsertAfter(&o->statements_list, &e->statements_list_node, &after_e->statements_list_node); |
||
697 | } else { |
||
698 | LinkedList1_Prepend(&o->statements_list, &e->statements_list_node); |
||
699 | } |
||
700 | e->s = s; |
||
701 | |||
702 | o->count++; |
||
703 | |||
704 | return 1; |
||
705 | } |
||
706 | |||
707 | NCDStatement * NCDBlock_ReplaceStatement (NCDBlock *o, NCDStatement *es, NCDStatement s) |
||
708 | { |
||
709 | ASSERT(es) |
||
710 | |||
711 | struct BlockStatement *e = UPPER_OBJECT(es, struct BlockStatement, s); |
||
712 | |||
713 | NCDStatement_Free(&e->s); |
||
714 | e->s = s; |
||
715 | |||
716 | return &e->s; |
||
717 | } |
||
718 | |||
719 | NCDStatement * NCDBlock_FirstStatement (NCDBlock *o) |
||
720 | { |
||
721 | LinkedList1Node *ln = LinkedList1_GetFirst(&o->statements_list); |
||
722 | if (!ln) { |
||
723 | return NULL; |
||
724 | } |
||
725 | |||
726 | struct BlockStatement *e = UPPER_OBJECT(ln, struct BlockStatement, statements_list_node); |
||
727 | |||
728 | return &e->s; |
||
729 | } |
||
730 | |||
731 | NCDStatement * NCDBlock_NextStatement (NCDBlock *o, NCDStatement *es) |
||
732 | { |
||
733 | ASSERT(es) |
||
734 | |||
735 | struct BlockStatement *cur_e = UPPER_OBJECT(es, struct BlockStatement, s); |
||
736 | |||
737 | LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->statements_list_node); |
||
738 | if (!ln) { |
||
739 | return NULL; |
||
740 | } |
||
741 | |||
742 | struct BlockStatement *e = UPPER_OBJECT(ln, struct BlockStatement, statements_list_node); |
||
743 | |||
744 | return &e->s; |
||
745 | } |
||
746 | |||
747 | size_t NCDBlock_NumStatements (NCDBlock *o) |
||
748 | { |
||
749 | return o->count; |
||
750 | } |
||
751 | |||
752 | int NCDStatement_InitReg (NCDStatement *o, const char *name, const char *objname, const char *cmdname, NCDValue args) |
||
753 | { |
||
754 | ASSERT(cmdname) |
||
755 | ASSERT(NCDValue_Type(&args) == NCDVALUE_LIST) |
||
756 | |||
757 | o->name = NULL; |
||
758 | o->reg.objname = NULL; |
||
759 | o->reg.cmdname = NULL; |
||
760 | |||
761 | if (name && !(o->name = strdup(name))) { |
||
762 | goto fail; |
||
763 | } |
||
764 | |||
765 | if (objname && !(o->reg.objname = strdup(objname))) { |
||
766 | goto fail; |
||
767 | } |
||
768 | |||
769 | if (!(o->reg.cmdname = strdup(cmdname))) { |
||
770 | goto fail; |
||
771 | } |
||
772 | |||
773 | o->type = NCDSTATEMENT_REG; |
||
774 | o->reg.args = args; |
||
775 | |||
776 | return 1; |
||
777 | |||
778 | fail: |
||
779 | free(o->name); |
||
780 | free(o->reg.objname); |
||
781 | free(o->reg.cmdname); |
||
782 | return 0; |
||
783 | } |
||
784 | |||
785 | int NCDStatement_InitIf (NCDStatement *o, const char *name, NCDIfBlock ifblock, int iftype) |
||
786 | { |
||
787 | o->name = NULL; |
||
788 | |||
789 | if (name && !(o->name = strdup(name))) { |
||
790 | return 0; |
||
791 | } |
||
792 | |||
793 | o->type = NCDSTATEMENT_IF; |
||
794 | o->ifc.ifblock = ifblock; |
||
795 | o->ifc.have_else = 0; |
||
796 | o->ifc.iftype = iftype; |
||
797 | |||
798 | return 1; |
||
799 | } |
||
800 | |||
801 | int NCDStatement_InitForeach (NCDStatement *o, const char *name, NCDValue collection, const char *name1, const char *name2, NCDBlock block) |
||
802 | { |
||
803 | ASSERT(name1) |
||
804 | |||
805 | o->name = NULL; |
||
806 | o->foreach.name1 = NULL; |
||
807 | o->foreach.name2 = NULL; |
||
808 | |||
809 | if (name && !(o->name = strdup(name))) { |
||
810 | goto fail; |
||
811 | } |
||
812 | |||
813 | if (!(o->foreach.name1 = strdup(name1))) { |
||
814 | goto fail; |
||
815 | } |
||
816 | |||
817 | if (name2 && !(o->foreach.name2 = strdup(name2))) { |
||
818 | goto fail; |
||
819 | } |
||
820 | |||
821 | o->type = NCDSTATEMENT_FOREACH; |
||
822 | o->foreach.collection = collection; |
||
823 | o->foreach.block = block; |
||
824 | o->foreach.is_grabbed = 0; |
||
825 | |||
826 | return 1; |
||
827 | |||
828 | fail: |
||
829 | free(o->name); |
||
830 | free(o->foreach.name1); |
||
831 | free(o->foreach.name2); |
||
832 | return 0; |
||
833 | } |
||
834 | |||
835 | int NCDStatement_InitBlock (NCDStatement *o, const char *name, NCDBlock block) |
||
836 | { |
||
837 | o->name = NULL; |
||
838 | |||
839 | if (name && !(o->name = strdup(name))) { |
||
840 | return 0; |
||
841 | } |
||
842 | |||
843 | o->type = NCDSTATEMENT_BLOCK; |
||
844 | o->block.block = block; |
||
845 | o->block.is_grabbed = 0; |
||
846 | |||
847 | return 1; |
||
848 | } |
||
849 | |||
850 | void NCDStatement_Free (NCDStatement *o) |
||
851 | { |
||
852 | switch (o->type) { |
||
853 | case NCDSTATEMENT_REG: { |
||
854 | NCDValue_Free(&o->reg.args); |
||
855 | free(o->reg.cmdname); |
||
856 | free(o->reg.objname); |
||
857 | } break; |
||
858 | |||
859 | case NCDSTATEMENT_IF: { |
||
860 | if (o->ifc.have_else) { |
||
861 | NCDBlock_Free(&o->ifc.else_block); |
||
862 | } |
||
863 | |||
864 | NCDIfBlock_Free(&o->ifc.ifblock); |
||
865 | } break; |
||
866 | |||
867 | case NCDSTATEMENT_FOREACH: { |
||
868 | if (!o->foreach.is_grabbed) { |
||
869 | NCDBlock_Free(&o->foreach.block); |
||
870 | NCDValue_Free(&o->foreach.collection); |
||
871 | } |
||
872 | free(o->foreach.name2); |
||
873 | free(o->foreach.name1); |
||
874 | } break; |
||
875 | |||
876 | case NCDSTATEMENT_BLOCK: { |
||
877 | if (!o->block.is_grabbed) { |
||
878 | NCDBlock_Free(&o->block.block); |
||
879 | } |
||
880 | } break; |
||
881 | |||
882 | default: ASSERT(0); |
||
883 | } |
||
884 | |||
885 | free(o->name); |
||
886 | } |
||
887 | |||
888 | int NCDStatement_Type (NCDStatement *o) |
||
889 | { |
||
890 | return o->type; |
||
891 | } |
||
892 | |||
893 | const char * NCDStatement_Name (NCDStatement *o) |
||
894 | { |
||
895 | return o->name; |
||
896 | } |
||
897 | |||
898 | const char * NCDStatement_RegObjName (NCDStatement *o) |
||
899 | { |
||
900 | ASSERT(o->type == NCDSTATEMENT_REG) |
||
901 | |||
902 | return o->reg.objname; |
||
903 | } |
||
904 | |||
905 | const char * NCDStatement_RegCmdName (NCDStatement *o) |
||
906 | { |
||
907 | ASSERT(o->type == NCDSTATEMENT_REG) |
||
908 | |||
909 | return o->reg.cmdname; |
||
910 | } |
||
911 | |||
912 | NCDValue * NCDStatement_RegArgs (NCDStatement *o) |
||
913 | { |
||
914 | ASSERT(o->type == NCDSTATEMENT_REG) |
||
915 | |||
916 | return &o->reg.args; |
||
917 | } |
||
918 | |||
919 | int NCDStatement_IfType (NCDStatement *o) |
||
920 | { |
||
921 | ASSERT(o->type == NCDSTATEMENT_IF) |
||
922 | |||
923 | return o->ifc.iftype; |
||
924 | } |
||
925 | |||
926 | NCDIfBlock * NCDStatement_IfBlock (NCDStatement *o) |
||
927 | { |
||
928 | ASSERT(o->type == NCDSTATEMENT_IF) |
||
929 | |||
930 | return &o->ifc.ifblock; |
||
931 | } |
||
932 | |||
933 | void NCDStatement_IfAddElse (NCDStatement *o, NCDBlock else_block) |
||
934 | { |
||
935 | ASSERT(o->type == NCDSTATEMENT_IF) |
||
936 | ASSERT(!o->ifc.have_else) |
||
937 | |||
938 | o->ifc.have_else = 1; |
||
939 | o->ifc.else_block = else_block; |
||
940 | } |
||
941 | |||
942 | NCDBlock * NCDStatement_IfElse (NCDStatement *o) |
||
943 | { |
||
944 | ASSERT(o->type == NCDSTATEMENT_IF) |
||
945 | |||
946 | if (!o->ifc.have_else) { |
||
947 | return NULL; |
||
948 | } |
||
949 | |||
950 | return &o->ifc.else_block; |
||
951 | } |
||
952 | |||
953 | NCDBlock NCDStatement_IfGrabElse (NCDStatement *o) |
||
954 | { |
||
955 | ASSERT(o->type == NCDSTATEMENT_IF) |
||
956 | ASSERT(o->ifc.have_else) |
||
957 | |||
958 | o->ifc.have_else = 0; |
||
959 | |||
960 | return o->ifc.else_block; |
||
961 | } |
||
962 | |||
963 | NCDValue * NCDStatement_ForeachCollection (NCDStatement *o) |
||
964 | { |
||
965 | ASSERT(o->type == NCDSTATEMENT_FOREACH) |
||
966 | ASSERT(!o->foreach.is_grabbed) |
||
967 | |||
968 | return &o->foreach.collection; |
||
969 | } |
||
970 | |||
971 | const char * NCDStatement_ForeachName1 (NCDStatement *o) |
||
972 | { |
||
973 | ASSERT(o->type == NCDSTATEMENT_FOREACH) |
||
974 | |||
975 | return o->foreach.name1; |
||
976 | } |
||
977 | |||
978 | const char * NCDStatement_ForeachName2 (NCDStatement *o) |
||
979 | { |
||
980 | ASSERT(o->type == NCDSTATEMENT_FOREACH) |
||
981 | |||
982 | return o->foreach.name2; |
||
983 | } |
||
984 | |||
985 | NCDBlock * NCDStatement_ForeachBlock (NCDStatement *o) |
||
986 | { |
||
987 | ASSERT(o->type == NCDSTATEMENT_FOREACH) |
||
988 | ASSERT(!o->foreach.is_grabbed) |
||
989 | |||
990 | return &o->foreach.block; |
||
991 | } |
||
992 | |||
993 | void NCDStatement_ForeachGrab (NCDStatement *o, NCDValue *out_collection, NCDBlock *out_block) |
||
994 | { |
||
995 | ASSERT(o->type == NCDSTATEMENT_FOREACH) |
||
996 | ASSERT(!o->foreach.is_grabbed) |
||
997 | |||
998 | *out_collection = o->foreach.collection; |
||
999 | *out_block = o->foreach.block; |
||
1000 | o->foreach.is_grabbed = 1; |
||
1001 | } |
||
1002 | |||
1003 | NCDBlock * NCDStatement_BlockBlock (NCDStatement *o) |
||
1004 | { |
||
1005 | ASSERT(o->type == NCDSTATEMENT_BLOCK) |
||
1006 | ASSERT(!o->block.is_grabbed) |
||
1007 | |||
1008 | return &o->block.block; |
||
1009 | } |
||
1010 | |||
1011 | NCDBlock NCDStatement_BlockGrabBlock (NCDStatement *o) |
||
1012 | { |
||
1013 | ASSERT(o->type == NCDSTATEMENT_BLOCK) |
||
1014 | ASSERT(!o->block.is_grabbed) |
||
1015 | |||
1016 | o->block.is_grabbed = 1; |
||
1017 | return o->block.block; |
||
1018 | } |
||
1019 | |||
1020 | void NCDIfBlock_Init (NCDIfBlock *o) |
||
1021 | { |
||
1022 | LinkedList1_Init(&o->ifs_list); |
||
1023 | } |
||
1024 | |||
1025 | void NCDIfBlock_Free (NCDIfBlock *o) |
||
1026 | { |
||
1027 | LinkedList1Node *ln; |
||
1028 | while (ln = LinkedList1_GetFirst(&o->ifs_list)) { |
||
1029 | struct IfBlockIf *e = UPPER_OBJECT(ln, struct IfBlockIf, ifs_list_node); |
||
1030 | NCDIf_Free(&e->ifc); |
||
1031 | LinkedList1_Remove(&o->ifs_list, &e->ifs_list_node); |
||
1032 | free(e); |
||
1033 | } |
||
1034 | } |
||
1035 | |||
1036 | int NCDIfBlock_PrependIf (NCDIfBlock *o, NCDIf ifc) |
||
1037 | { |
||
1038 | struct IfBlockIf *e = malloc(sizeof(*e)); |
||
1039 | if (!e) { |
||
1040 | return 0; |
||
1041 | } |
||
1042 | |||
1043 | LinkedList1_Prepend(&o->ifs_list, &e->ifs_list_node); |
||
1044 | e->ifc = ifc; |
||
1045 | |||
1046 | return 1; |
||
1047 | } |
||
1048 | |||
1049 | NCDIf * NCDIfBlock_FirstIf (NCDIfBlock *o) |
||
1050 | { |
||
1051 | LinkedList1Node *ln = LinkedList1_GetFirst(&o->ifs_list); |
||
1052 | if (!ln) { |
||
1053 | return NULL; |
||
1054 | } |
||
1055 | |||
1056 | struct IfBlockIf *e = UPPER_OBJECT(ln, struct IfBlockIf, ifs_list_node); |
||
1057 | |||
1058 | return &e->ifc; |
||
1059 | } |
||
1060 | |||
1061 | NCDIf * NCDIfBlock_NextIf (NCDIfBlock *o, NCDIf *ei) |
||
1062 | { |
||
1063 | ASSERT(ei) |
||
1064 | |||
1065 | struct IfBlockIf *cur_e = UPPER_OBJECT(ei, struct IfBlockIf, ifc); |
||
1066 | |||
1067 | LinkedList1Node *ln = LinkedList1Node_Next(&cur_e->ifs_list_node); |
||
1068 | if (!ln) { |
||
1069 | return NULL; |
||
1070 | } |
||
1071 | |||
1072 | struct IfBlockIf *e = UPPER_OBJECT(ln, struct IfBlockIf, ifs_list_node); |
||
1073 | |||
1074 | return &e->ifc; |
||
1075 | } |
||
1076 | |||
1077 | NCDIf NCDIfBlock_GrabIf (NCDIfBlock *o, NCDIf *ei) |
||
1078 | { |
||
1079 | ASSERT(ei) |
||
1080 | |||
1081 | struct IfBlockIf *e = UPPER_OBJECT(ei, struct IfBlockIf, ifc); |
||
1082 | |||
1083 | NCDIf old_ifc = e->ifc; |
||
1084 | |||
1085 | LinkedList1_Remove(&o->ifs_list, &e->ifs_list_node); |
||
1086 | free(e); |
||
1087 | |||
1088 | return old_ifc; |
||
1089 | } |
||
1090 | |||
1091 | void NCDIf_Init (NCDIf *o, NCDValue cond, NCDBlock block) |
||
1092 | { |
||
1093 | o->cond = cond; |
||
1094 | o->block = block; |
||
1095 | } |
||
1096 | |||
1097 | void NCDIf_InitBlock (NCDIf *o, NCDBlock block) |
||
1098 | { |
||
1099 | NCDValue_InitList(&o->cond); |
||
1100 | o->block = block; |
||
1101 | } |
||
1102 | |||
1103 | void NCDIf_Free (NCDIf *o) |
||
1104 | { |
||
1105 | NCDValue_Free(&o->cond); |
||
1106 | NCDBlock_Free(&o->block); |
||
1107 | } |
||
1108 | |||
1109 | void NCDIf_FreeGrab (NCDIf *o, NCDValue *out_cond, NCDBlock *out_block) |
||
1110 | { |
||
1111 | *out_cond = o->cond; |
||
1112 | *out_block = o->block; |
||
1113 | } |
||
1114 | |||
1115 | NCDBlock NCDIf_FreeGrabBlock (NCDIf *o) |
||
1116 | { |
||
1117 | NCDValue_Free(&o->cond); |
||
1118 | return o->block; |
||
1119 | } |
||
1120 | |||
1121 | NCDValue * NCDIf_Cond (NCDIf *o) |
||
1122 | { |
||
1123 | return &o->cond; |
||
1124 | } |
||
1125 | |||
1126 | NCDBlock * NCDIf_Block (NCDIf *o) |
||
1127 | { |
||
1128 | return &o->block; |
||
1129 | } |