source: mainline/uspace/app/sbi/src/rdata.c@ 1433ecda

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1433ecda was 1433ecda, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix cstyle: make ccheck-fix and commit only files where all the changes are good.

  • Property mode set to 100644
File size: 28.6 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file Run-time data representation.
30 *
31 * At run time SBI represents all data as a graph of interconnected @c var
32 * nodes (variable nodes). Any piece of memory addressable by the program
33 * (i.e. all variables) are stored in var nodes. However, var nodes are also
34 * used internally to implement value items. (I.e. values in value items
35 * have exactly the same structure as program variables).
36 *
37 * Unlike byte- or word-oriented memory on a real machine, var nodes provide
38 * structured and typed storage. (This typing is dynamic, however and has
39 * nothing to do with the static type system).
40 *
41 * There are several types of var nodes, one for each primitive type,
42 * reference, delegate, array, and object. A reference var node contains
43 * a pointer to another var node. Delegate var node points to some stree
44 * declaration. Array and object var nodes refer to a collection of child
45 * nodes (fields, elements).
46 */
47
48#include <stdlib.h>
49#include <assert.h>
50#include "bigint.h"
51#include "list.h"
52#include "mytypes.h"
53#include "stree.h"
54#include "symbol.h"
55#include "strtab.h"
56
57#include "rdata.h"
58
59static void rdata_bool_copy(rdata_bool_t *src, rdata_bool_t **dest);
60static void rdata_char_copy(rdata_char_t *src, rdata_char_t **dest);
61static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest);
62static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest);
63static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest);
64static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest);
65static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest);
66static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest);
67static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest);
68static void rdata_resource_copy(rdata_resource_t *src,
69 rdata_resource_t **dest);
70static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest);
71
72static void rdata_var_destroy_inner(rdata_var_t *var);
73
74static void rdata_bool_destroy(rdata_bool_t *bool_v);
75static void rdata_char_destroy(rdata_char_t *char_v);
76static void rdata_int_destroy(rdata_int_t *int_v);
77static void rdata_string_destroy(rdata_string_t *string_v);
78static void rdata_ref_destroy(rdata_ref_t *ref_v);
79static void rdata_deleg_destroy(rdata_deleg_t *deleg_v);
80static void rdata_enum_destroy(rdata_enum_t *enum_v);
81static void rdata_array_destroy(rdata_array_t *array_v);
82static void rdata_object_destroy(rdata_object_t *object_v);
83static void rdata_resource_destroy(rdata_resource_t *resource_v);
84static void rdata_symbol_destroy(rdata_symbol_t *symbol_v);
85
86static int rdata_array_get_dim(rdata_array_t *array);
87static void rdata_var_copy_to(rdata_var_t *src, rdata_var_t *dest);
88
89static void rdata_address_print(rdata_address_t *address);
90static void rdata_var_print(rdata_var_t *var);
91
92/** Allocate new data item.
93 *
94 * @param ic Item class.
95 * @return New item.
96 */
97rdata_item_t *rdata_item_new(item_class_t ic)
98{
99 rdata_item_t *item;
100
101 item = calloc(1, sizeof(rdata_item_t));
102 if (item == NULL) {
103 printf("Memory allocation failed.\n");
104 exit(1);
105 }
106
107 item->ic = ic;
108 return item;
109}
110
111/** Allocate new address.
112 *
113 * @return New address.
114 */
115rdata_addr_var_t *rdata_addr_var_new(void)
116{
117 rdata_addr_var_t *addr_var;
118
119 addr_var = calloc(1, sizeof(rdata_addr_var_t));
120 if (addr_var == NULL) {
121 printf("Memory allocation failed.\n");
122 exit(1);
123 }
124
125 return addr_var;
126}
127
128/** Allocate new named property address.
129 *
130 * @return New named property address.
131 */
132rdata_aprop_named_t *rdata_aprop_named_new(void)
133{
134 rdata_aprop_named_t *aprop_named;
135
136 aprop_named = calloc(1, sizeof(rdata_aprop_named_t));
137 if (aprop_named == NULL) {
138 printf("Memory allocation failed.\n");
139 exit(1);
140 }
141
142 return aprop_named;
143}
144
145/** Allocate new indexed property address.
146 *
147 * @return New indexed property address.
148 */
149rdata_aprop_indexed_t *rdata_aprop_indexed_new(void)
150{
151 rdata_aprop_indexed_t *aprop_indexed;
152
153 aprop_indexed = calloc(1, sizeof(rdata_aprop_indexed_t));
154 if (aprop_indexed == NULL) {
155 printf("Memory allocation failed.\n");
156 exit(1);
157 }
158
159 return aprop_indexed;
160}
161
162/** Allocate new property address.
163 *
164 * @param apc Property address class.
165 * @return New property address.
166 */
167rdata_addr_prop_t *rdata_addr_prop_new(aprop_class_t apc)
168{
169 rdata_addr_prop_t *addr_prop;
170
171 addr_prop = calloc(1, sizeof(rdata_addr_prop_t));
172 if (addr_prop == NULL) {
173 printf("Memory allocation failed.\n");
174 exit(1);
175 }
176
177 addr_prop->apc = apc;
178 return addr_prop;
179}
180
181/** Allocate new address.
182 *
183 * @param ac Address class.
184 * @return New address.
185 */
186rdata_address_t *rdata_address_new(address_class_t ac)
187{
188 rdata_address_t *address;
189
190 address = calloc(1, sizeof(rdata_address_t));
191 if (address == NULL) {
192 printf("Memory allocation failed.\n");
193 exit(1);
194 }
195
196 address->ac = ac;
197 return address;
198}
199
200/** Allocate new value.
201 *
202 * @return New value.
203 */
204rdata_value_t *rdata_value_new(void)
205{
206 rdata_value_t *value;
207
208 value = calloc(1, sizeof(rdata_value_t));
209 if (value == NULL) {
210 printf("Memory allocation failed.\n");
211 exit(1);
212 }
213
214 return value;
215}
216
217/** Allocate new var node.
218 *
219 * @param vc Var node class (varclass).
220 * @return New var node.
221 */
222rdata_var_t *rdata_var_new(var_class_t vc)
223{
224 rdata_var_t *var;
225
226 var = calloc(1, sizeof(rdata_var_t));
227 if (var == NULL) {
228 printf("Memory allocation failed.\n");
229 exit(1);
230 }
231
232 var->vc = vc;
233 return var;
234}
235
236/** Allocate new reference.
237 *
238 * @return New reference.
239 */
240rdata_ref_t *rdata_ref_new(void)
241{
242 rdata_ref_t *ref;
243
244 ref = calloc(1, sizeof(rdata_ref_t));
245 if (ref == NULL) {
246 printf("Memory allocation failed.\n");
247 exit(1);
248 }
249
250 return ref;
251}
252
253/** Allocate new delegate.
254 *
255 * @return New delegate.
256 */
257rdata_deleg_t *rdata_deleg_new(void)
258{
259 rdata_deleg_t *deleg;
260
261 deleg = calloc(1, sizeof(rdata_deleg_t));
262 if (deleg == NULL) {
263 printf("Memory allocation failed.\n");
264 exit(1);
265 }
266
267 return deleg;
268}
269
270/** Allocate new enum value.
271 *
272 * @return New enum value.
273 */
274rdata_enum_t *rdata_enum_new(void)
275{
276 rdata_enum_t *enum_v;
277
278 enum_v = calloc(1, sizeof(rdata_enum_t));
279 if (enum_v == NULL) {
280 printf("Memory allocation failed.\n");
281 exit(1);
282 }
283
284 return enum_v;
285}
286
287/** Allocate new array.
288 *
289 * @return New array.
290 */
291rdata_array_t *rdata_array_new(int rank)
292{
293 rdata_array_t *array;
294
295 array = calloc(1, sizeof(rdata_array_t));
296 if (array == NULL) {
297 printf("Memory allocation failed.\n");
298 exit(1);
299 }
300
301 array->rank = rank;
302 array->extent = calloc(rank, sizeof(int));
303 if (array == NULL) {
304 printf("Memory allocation failed.\n");
305 exit(1);
306 }
307
308 return array;
309}
310
311/** Allocate new object.
312 *
313 * @return New object.
314 */
315rdata_object_t *rdata_object_new(void)
316{
317 rdata_object_t *object;
318
319 object = calloc(1, sizeof(rdata_object_t));
320 if (object == NULL) {
321 printf("Memory allocation failed.\n");
322 exit(1);
323 }
324
325 return object;
326}
327
328/** Allocate new boolean.
329 *
330 * @return New boolean.
331 */
332rdata_bool_t *rdata_bool_new(void)
333{
334 rdata_bool_t *bool_v;
335
336 bool_v = calloc(1, sizeof(rdata_bool_t));
337 if (bool_v == NULL) {
338 printf("Memory allocation failed.\n");
339 exit(1);
340 }
341
342 return bool_v;
343}
344
345/** Allocate new character.
346 *
347 * @return New character.
348 */
349rdata_char_t *rdata_char_new(void)
350{
351 rdata_char_t *char_v;
352
353 char_v = calloc(1, sizeof(rdata_char_t));
354 if (char_v == NULL) {
355 printf("Memory allocation failed.\n");
356 exit(1);
357 }
358
359 return char_v;
360}
361
362/** Allocate new integer.
363 *
364 * @return New integer.
365 */
366rdata_int_t *rdata_int_new(void)
367{
368 rdata_int_t *int_v;
369
370 int_v = calloc(1, sizeof(rdata_int_t));
371 if (int_v == NULL) {
372 printf("Memory allocation failed.\n");
373 exit(1);
374 }
375
376 return int_v;
377}
378
379/** Allocate new string.
380 *
381 * @return New string.
382 */
383rdata_string_t *rdata_string_new(void)
384{
385 rdata_string_t *string_v;
386
387 string_v = calloc(1, sizeof(rdata_string_t));
388 if (string_v == NULL) {
389 printf("Memory allocation failed.\n");
390 exit(1);
391 }
392
393 return string_v;
394}
395
396/** Allocate new resource.
397 *
398 * @return New resource.
399 */
400rdata_resource_t *rdata_resource_new(void)
401{
402 rdata_resource_t *resource_v;
403
404 resource_v = calloc(1, sizeof(rdata_resource_t));
405 if (resource_v == NULL) {
406 printf("Memory allocation failed.\n");
407 exit(1);
408 }
409
410 return resource_v;
411}
412
413/** Allocate new symbol reference.
414 *
415 * @return New symbol reference.
416 */
417rdata_symbol_t *rdata_symbol_new(void)
418{
419 rdata_symbol_t *symbol_v;
420
421 symbol_v = calloc(1, sizeof(rdata_symbol_t));
422 if (symbol_v == NULL) {
423 printf("Memory allocation failed.\n");
424 exit(1);
425 }
426
427 return symbol_v;
428}
429
430/** Allocate array elements.
431 *
432 * Allocates element array of @a array.
433 *
434 * @param array Array.
435 */
436void rdata_array_alloc_element(rdata_array_t *array)
437{
438 int dim;
439
440 dim = rdata_array_get_dim(array);
441
442 array->element = calloc(dim, sizeof(rdata_var_t *));
443 if (array->element == NULL) {
444 printf("Memory allocation failed.\n");
445 exit(1);
446 }
447}
448
449/** Get array dimension.
450 *
451 * Dimension is the total number of elements in an array, in other words,
452 * the product of all extents.
453 *
454 * @param array Array.
455 */
456static int rdata_array_get_dim(rdata_array_t *array)
457{
458 int didx, dim;
459
460 dim = 1;
461 for (didx = 0; didx < array->rank; ++didx)
462 dim = dim * array->extent[didx];
463
464 return dim;
465}
466
467/** Deallocate item.
468 *
469 * @param item Item node
470 */
471void rdata_item_delete(rdata_item_t *item)
472{
473 assert(item != NULL);
474 free(item);
475}
476
477/** Deallocate variable address.
478 *
479 * @param addr_var Variable address node
480 */
481void rdata_addr_var_delete(rdata_addr_var_t *addr_var)
482{
483 assert(addr_var != NULL);
484 free(addr_var);
485}
486
487/** Deallocate property address.
488 *
489 * @param addr_prop Variable address node
490 */
491void rdata_addr_prop_delete(rdata_addr_prop_t *addr_prop)
492{
493 assert(addr_prop != NULL);
494 free(addr_prop);
495}
496
497/** Deallocate named property address.
498 *
499 * @param aprop_named Variable address node
500 */
501void rdata_aprop_named_delete(rdata_aprop_named_t *aprop_named)
502{
503 assert(aprop_named != NULL);
504 free(aprop_named);
505}
506
507/** Deallocate indexed property address.
508 *
509 * @param aprop_indexed Variable address node
510 */
511void rdata_aprop_indexed_delete(rdata_aprop_indexed_t *aprop_indexed)
512{
513 assert(aprop_indexed != NULL);
514 free(aprop_indexed);
515}
516
517/** Deallocate address.
518 *
519 * @param address Address node
520 */
521void rdata_address_delete(rdata_address_t *address)
522{
523 assert(address != NULL);
524 free(address);
525}
526
527/** Deallocate value.
528 *
529 * @param value Value node
530 */
531void rdata_value_delete(rdata_value_t *value)
532{
533 assert(value != NULL);
534 free(value);
535}
536
537/** Deallocate var node.
538 *
539 * @param var Var node
540 */
541void rdata_var_delete(rdata_var_t *var)
542{
543 assert(var != NULL);
544 free(var);
545}
546
547/** Deallocate boolean.
548 *
549 * @param bool_v Boolean
550 */
551void rdata_bool_delete(rdata_bool_t *bool_v)
552{
553 assert(bool_v != NULL);
554 free(bool_v);
555}
556
557/** Deallocate character.
558 *
559 * @param char_v Character
560 */
561void rdata_char_delete(rdata_char_t *char_v)
562{
563 assert(char_v != NULL);
564 free(char_v);
565}
566
567/** Deallocate integer.
568 *
569 * @param int_v Integer
570 */
571void rdata_int_delete(rdata_int_t *int_v)
572{
573 assert(int_v != NULL);
574 free(int_v);
575}
576
577/** Deallocate string.
578 *
579 * @param string_v String
580 */
581void rdata_string_delete(rdata_string_t *string_v)
582{
583 assert(string_v != NULL);
584 free(string_v);
585}
586
587/** Deallocate reference.
588 *
589 * @param ref_v Reference
590 */
591void rdata_ref_delete(rdata_ref_t *ref_v)
592{
593 assert(ref_v != NULL);
594 free(ref_v);
595}
596
597/** Deallocate delegate.
598 *
599 * @param deleg_v Reference
600 */
601void rdata_deleg_delete(rdata_deleg_t *deleg_v)
602{
603 assert(deleg_v != NULL);
604 free(deleg_v);
605}
606
607/** Deallocate enum.
608 *
609 * @param enum_v Reference
610 */
611void rdata_enum_delete(rdata_enum_t *enum_v)
612{
613 assert(enum_v != NULL);
614 free(enum_v);
615}
616
617/** Deallocate array.
618 *
619 * @param array_v Array
620 */
621void rdata_array_delete(rdata_array_t *array_v)
622{
623 assert(array_v != NULL);
624 free(array_v);
625}
626
627/** Deallocate object.
628 *
629 * @param object_v Object
630 */
631void rdata_object_delete(rdata_object_t *object_v)
632{
633 assert(object_v != NULL);
634 free(object_v);
635}
636
637/** Deallocate resource.
638 *
639 * @param resource_v Resource
640 */
641void rdata_resource_delete(rdata_resource_t *resource_v)
642{
643 assert(resource_v != NULL);
644 free(resource_v);
645}
646
647/** Deallocate symbol.
648 *
649 * @param symbol_v Symbol
650 */
651void rdata_symbol_delete(rdata_symbol_t *symbol_v)
652{
653 assert(symbol_v != NULL);
654 free(symbol_v);
655}
656
657/** Copy value.
658 *
659 * @param src Input value
660 * @param dest Place to store pointer to new value
661 */
662void rdata_value_copy(rdata_value_t *src, rdata_value_t **dest)
663{
664 assert(src != NULL);
665
666 *dest = rdata_value_new();
667 rdata_var_copy(src->var, &(*dest)->var);
668}
669
670/** Make copy of a variable.
671 *
672 * Creates a new var node that is an exact copy of an existing var node.
673 * This can be thought of as a shallow copy.
674 *
675 * @param src Source var node.
676 * @param dest Place to store pointer to new var node.
677 */
678void rdata_var_copy(rdata_var_t *src, rdata_var_t **dest)
679{
680 rdata_var_t *nvar;
681
682 nvar = rdata_var_new(src->vc);
683 rdata_var_copy_to(src, nvar);
684
685 *dest = nvar;
686}
687
688/** Copy variable content to another variable.
689 *
690 * Writes an exact copy of an existing var node to another var node.
691 * The varclass of @a src and @a dest must match. The content of
692 * @a dest.u must be invalid.
693 *
694 * @param src Source var node.
695 * @param dest Destination var node.
696 */
697static void rdata_var_copy_to(rdata_var_t *src, rdata_var_t *dest)
698{
699 dest->vc = src->vc;
700
701 switch (src->vc) {
702 case vc_bool:
703 rdata_bool_copy(src->u.bool_v, &dest->u.bool_v);
704 break;
705 case vc_char:
706 rdata_char_copy(src->u.char_v, &dest->u.char_v);
707 break;
708 case vc_int:
709 rdata_int_copy(src->u.int_v, &dest->u.int_v);
710 break;
711 case vc_string:
712 rdata_string_copy(src->u.string_v, &dest->u.string_v);
713 break;
714 case vc_ref:
715 rdata_ref_copy(src->u.ref_v, &dest->u.ref_v);
716 break;
717 case vc_deleg:
718 rdata_deleg_copy(src->u.deleg_v, &dest->u.deleg_v);
719 break;
720 case vc_enum:
721 rdata_enum_copy(src->u.enum_v, &dest->u.enum_v);
722 break;
723 case vc_array:
724 rdata_array_copy(src->u.array_v, &dest->u.array_v);
725 break;
726 case vc_object:
727 rdata_object_copy(src->u.object_v, &dest->u.object_v);
728 break;
729 case vc_resource:
730 rdata_resource_copy(src->u.resource_v, &dest->u.resource_v);
731 break;
732 case vc_symbol:
733 rdata_symbol_copy(src->u.symbol_v, &dest->u.symbol_v);
734 break;
735 }
736}
737
738
739/** Copy boolean.
740 *
741 * @param src Source boolean
742 * @param dest Place to store pointer to new boolean
743 */
744static void rdata_bool_copy(rdata_bool_t *src, rdata_bool_t **dest)
745{
746 *dest = rdata_bool_new();
747 (*dest)->value = src->value;
748}
749
750/** Copy character.
751 *
752 * @param src Source character
753 * @param dest Place to store pointer to new character
754 */
755static void rdata_char_copy(rdata_char_t *src, rdata_char_t **dest)
756{
757 *dest = rdata_char_new();
758 bigint_clone(&src->value, &(*dest)->value);
759}
760
761/** Copy integer.
762 *
763 * @param src Source integer
764 * @param dest Place to store pointer to new integer
765 */
766static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest)
767{
768 *dest = rdata_int_new();
769 bigint_clone(&src->value, &(*dest)->value);
770}
771
772/** Copy string.
773 *
774 * @param src Source string.
775 * @param dest Place to store pointer to new string.
776 */
777static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest)
778{
779 *dest = rdata_string_new();
780 (*dest)->value = src->value;
781}
782
783/** Copy reference.
784 *
785 * @param src Source reference.
786 * @param dest Place to store pointer to new reference.
787 */
788static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest)
789{
790 *dest = rdata_ref_new();
791 (*dest)->vref = src->vref;
792}
793
794/** Copy delegate.
795 *
796 * @param src Source delegate.
797 * @param dest Place to store pointer to new delegate.
798 */
799static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
800{
801 *dest = rdata_deleg_new();
802 (*dest)->obj = src->obj;
803 (*dest)->sym = src->sym;
804}
805
806/** Copy enum value.
807 *
808 * @param src Source enum value.
809 * @param dest Place to store pointer to new enum value.
810 */
811static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest)
812{
813 *dest = rdata_enum_new();
814 (*dest)->value = src->value;
815}
816
817/** Copy array.
818 *
819 * @param src Source array.
820 * @param dest Place to store pointer to new array.
821 */
822static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
823{
824 (void) src;
825 (void) dest;
826 printf("Unimplemented: Copy array.\n");
827 exit(1);
828}
829
830/** Copy object.
831 *
832 * @param src Source object.
833 * @param dest Place to store pointer to new object.
834 */
835static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest)
836{
837 (void) src;
838 (void) dest;
839 printf("Unimplemented: Copy object.\n");
840 abort();
841}
842
843/** Copy resource.
844 *
845 * @param src Source resource.
846 * @param dest Place to store pointer to new resource.
847 */
848static void rdata_resource_copy(rdata_resource_t *src, rdata_resource_t **dest)
849{
850 *dest = rdata_resource_new();
851 (*dest)->data = src->data;
852}
853
854/** Copy symbol.
855 *
856 * @param src Source symbol.
857 * @param dest Place to store pointer to new symbol.
858 */
859static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest)
860{
861 *dest = rdata_symbol_new();
862 (*dest)->sym = src->sym;
863}
864
865/** Destroy var node.
866 *
867 * @param var Var node
868 */
869void rdata_var_destroy(rdata_var_t *var)
870{
871 /* First destroy class-specific part */
872 rdata_var_destroy_inner(var);
873
874 /* Deallocate var node */
875 rdata_var_delete(var);
876}
877
878/** Destroy inside of var node.
879 *
880 * Destroy content of var node, but do not deallocate the var node
881 * itself.
882 *
883 * @param var Var node
884 */
885static void rdata_var_destroy_inner(rdata_var_t *var)
886{
887 /* First destroy class-specific part */
888
889 switch (var->vc) {
890 case vc_bool:
891 rdata_bool_destroy(var->u.bool_v);
892 break;
893 case vc_char:
894 rdata_char_destroy(var->u.char_v);
895 break;
896 case vc_int:
897 rdata_int_destroy(var->u.int_v);
898 break;
899 case vc_string:
900 rdata_string_destroy(var->u.string_v);
901 break;
902 case vc_ref:
903 rdata_ref_destroy(var->u.ref_v);
904 break;
905 case vc_deleg:
906 rdata_deleg_destroy(var->u.deleg_v);
907 break;
908 case vc_enum:
909 rdata_enum_destroy(var->u.enum_v);
910 break;
911 case vc_array:
912 rdata_array_destroy(var->u.array_v);
913 break;
914 case vc_object:
915 rdata_object_destroy(var->u.object_v);
916 break;
917 case vc_resource:
918 rdata_resource_destroy(var->u.resource_v);
919 break;
920 case vc_symbol:
921 rdata_symbol_destroy(var->u.symbol_v);
922 break;
923 }
924}
925
926/** Destroy item.
927 *
928 * Destroy an item including the value or address within.
929 *
930 * @param item Item
931 */
932void rdata_item_destroy(rdata_item_t *item)
933{
934 /* First destroy class-specific part */
935
936 switch (item->ic) {
937 case ic_address:
938 rdata_address_destroy(item->u.address);
939 break;
940 case ic_value:
941 rdata_value_destroy(item->u.value);
942 break;
943 }
944
945 /* Deallocate item node */
946 rdata_item_delete(item);
947}
948
949/** Destroy address.
950 *
951 * Destroy an address node.
952 *
953 * @param address Address
954 */
955void rdata_address_destroy(rdata_address_t *address)
956{
957 switch (address->ac) {
958 case ac_var:
959 rdata_addr_var_destroy(address->u.var_a);
960 break;
961 case ac_prop:
962 rdata_addr_prop_destroy(address->u.prop_a);
963 break;
964 }
965
966 /* Deallocate address node */
967 rdata_address_delete(address);
968}
969
970/** Destroy variable address.
971 *
972 * Destroy a variable address node.
973 *
974 * @param addr_var Variable address
975 */
976void rdata_addr_var_destroy(rdata_addr_var_t *addr_var)
977{
978 addr_var->vref = NULL;
979
980 /* Deallocate variable address node */
981 rdata_addr_var_delete(addr_var);
982}
983
984/** Destroy property address.
985 *
986 * Destroy a property address node.
987 *
988 * @param addr_prop Property address
989 */
990void rdata_addr_prop_destroy(rdata_addr_prop_t *addr_prop)
991{
992 switch (addr_prop->apc) {
993 case apc_named:
994 rdata_aprop_named_destroy(addr_prop->u.named);
995 break;
996 case apc_indexed:
997 rdata_aprop_indexed_destroy(addr_prop->u.indexed);
998 break;
999 }
1000
1001 if (addr_prop->tvalue != NULL) {
1002 rdata_value_destroy(addr_prop->tvalue);
1003 addr_prop->tvalue = NULL;
1004 }
1005
1006 addr_prop->tpos = NULL;
1007
1008 /* Deallocate property address node */
1009 rdata_addr_prop_delete(addr_prop);
1010}
1011
1012/** Destroy named property address.
1013 *
1014 * Destroy a named property address node.
1015 *
1016 * @param aprop_named Named property address
1017 */
1018void rdata_aprop_named_destroy(rdata_aprop_named_t *aprop_named)
1019{
1020 rdata_deleg_destroy(aprop_named->prop_d);
1021
1022 /* Deallocate named property address node */
1023 rdata_aprop_named_delete(aprop_named);
1024}
1025
1026/** Destroy indexed property address.
1027 *
1028 * Destroy a indexed property address node.
1029 *
1030 * @param aprop_indexed Indexed property address
1031 */
1032void rdata_aprop_indexed_destroy(rdata_aprop_indexed_t *aprop_indexed)
1033{
1034 list_node_t *arg_node;
1035 rdata_item_t *arg_i;
1036
1037 /* Destroy the object delegate. */
1038 rdata_deleg_destroy(aprop_indexed->object_d);
1039
1040 /*
1041 * Walk through all argument items (indices) and destroy them,
1042 * removing them from the list as well.
1043 */
1044 while (!list_is_empty(&aprop_indexed->args)) {
1045 arg_node = list_first(&aprop_indexed->args);
1046 arg_i = list_node_data(arg_node, rdata_item_t *);
1047
1048 rdata_item_destroy(arg_i);
1049 list_remove(&aprop_indexed->args, arg_node);
1050 }
1051
1052 /* Destroy the now empty list */
1053 list_fini(&aprop_indexed->args);
1054
1055 /* Deallocate indexed property address node */
1056 rdata_aprop_indexed_delete(aprop_indexed);
1057}
1058
1059/** Destroy value.
1060 *
1061 * Destroy a value node.
1062 *
1063 * @param value Value
1064 */
1065void rdata_value_destroy(rdata_value_t *value)
1066{
1067 /* Assumption: Var nodes in values are not shared. */
1068 rdata_var_destroy(value->var);
1069
1070 /* Deallocate value node */
1071 rdata_value_delete(value);
1072}
1073
1074/** Destroy boolean.
1075 *
1076 * @param bool_v Boolean
1077 */
1078static void rdata_bool_destroy(rdata_bool_t *bool_v)
1079{
1080 rdata_bool_delete(bool_v);
1081}
1082
1083/** Destroy character.
1084 *
1085 * @param char_v Character
1086 */
1087static void rdata_char_destroy(rdata_char_t *char_v)
1088{
1089 bigint_destroy(&char_v->value);
1090 rdata_char_delete(char_v);
1091}
1092
1093/** Destroy integer.
1094 *
1095 * @param int_v Integer
1096 */
1097static void rdata_int_destroy(rdata_int_t *int_v)
1098{
1099 bigint_destroy(&int_v->value);
1100 rdata_int_delete(int_v);
1101}
1102
1103/** Destroy string.
1104 *
1105 * @param string_v String
1106 */
1107static void rdata_string_destroy(rdata_string_t *string_v)
1108{
1109 /*
1110 * String values are shared so we cannot free them. Just deallocate
1111 * the node.
1112 */
1113 rdata_string_delete(string_v);
1114}
1115
1116/** Destroy reference.
1117 *
1118 * @param ref_v Reference
1119 */
1120static void rdata_ref_destroy(rdata_ref_t *ref_v)
1121{
1122 ref_v->vref = NULL;
1123 rdata_ref_delete(ref_v);
1124}
1125
1126/** Destroy delegate.
1127 *
1128 * @param deleg_v Reference
1129 */
1130static void rdata_deleg_destroy(rdata_deleg_t *deleg_v)
1131{
1132 deleg_v->obj = NULL;
1133 deleg_v->sym = NULL;
1134 rdata_deleg_delete(deleg_v);
1135}
1136
1137/** Destroy enum.
1138 *
1139 * @param enum_v Reference
1140 */
1141static void rdata_enum_destroy(rdata_enum_t *enum_v)
1142{
1143 enum_v->value = NULL;
1144 rdata_enum_delete(enum_v);
1145}
1146
1147/** Destroy array.
1148 *
1149 * @param array_v Array
1150 */
1151static void rdata_array_destroy(rdata_array_t *array_v)
1152{
1153 int d;
1154 size_t n_elems, p;
1155
1156 /*
1157 * Compute total number of elements in array.
1158 * At the same time zero out the extent array.
1159 */
1160 n_elems = 1;
1161 for (d = 0; d < array_v->rank; d++) {
1162 n_elems = n_elems * array_v->extent[d];
1163 array_v->extent[d] = 0;
1164 }
1165
1166 /* Destroy all elements and zero out the array */
1167 for (p = 0; p < n_elems; p++) {
1168 rdata_var_delete(array_v->element[p]);
1169 array_v->element[p] = NULL;
1170 }
1171
1172 /* Free the arrays */
1173 free(array_v->element);
1174 free(array_v->extent);
1175
1176 array_v->rank = 0;
1177
1178 /* Deallocate the node */
1179 rdata_array_delete(array_v);
1180}
1181
1182/** Destroy object.
1183 *
1184 * @param object_v Object
1185 */
1186static void rdata_object_destroy(rdata_object_t *object_v)
1187{
1188 /* XXX TODO */
1189 rdata_object_delete(object_v);
1190}
1191
1192/** Destroy resource.
1193 *
1194 * @param resource_v Resource
1195 */
1196static void rdata_resource_destroy(rdata_resource_t *resource_v)
1197{
1198 /*
1199 * XXX Presumably this should be handled by the appropriate
1200 * built-in module, so, some call-back function would be required.
1201 */
1202 resource_v->data = NULL;
1203 rdata_resource_delete(resource_v);
1204}
1205
1206/** Destroy symbol.
1207 *
1208 * @param symbol_v Symbol
1209 */
1210static void rdata_symbol_destroy(rdata_symbol_t *symbol_v)
1211{
1212 symbol_v->sym = NULL;
1213 rdata_symbol_delete(symbol_v);
1214}
1215
1216/** Read data from a variable.
1217 *
1218 * This copies data from the variable to a value item. Ideally any read access
1219 * to a program variable should go through this function. (Keep in mind
1220 * that although values are composed of var nodes internally, but are not
1221 * variables per se. Therefore this function is not used to read from values)
1222 *
1223 * @param var Variable to read from (var node where it is stored).
1224 * @param ritem Place to store pointer to new value item read from
1225 * the variable.
1226 */
1227void rdata_var_read(rdata_var_t *var, rdata_item_t **ritem)
1228{
1229 rdata_value_t *value;
1230 rdata_var_t *rvar;
1231
1232 /* Perform a shallow copy of @a var. */
1233 rdata_var_copy(var, &rvar);
1234
1235 value = rdata_value_new();
1236 value->var = rvar;
1237 *ritem = rdata_item_new(ic_value);
1238 (*ritem)->u.value = value;
1239}
1240
1241/** Write data to a variable.
1242 *
1243 * This copies data to the variable from a value. Ideally any write access
1244 * to a program variable should go through this function. (Keep in mind
1245 * that even though values are composed of var nodes internally, but are not
1246 * variables per se. Therefore this function is not used to write to values)
1247 *
1248 * @param var Variable to write to (var node where it is stored).
1249 * @param value The value to write.
1250 */
1251void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
1252{
1253 /* Free old content of var->u */
1254 rdata_var_destroy_inner(var);
1255
1256 /* Perform a shallow copy of @c value->var. */
1257 rdata_var_copy_to(value->var, var);
1258}
1259
1260/** Print data item in human-readable form.
1261 *
1262 * @param item Item to print.
1263 */
1264void rdata_item_print(rdata_item_t *item)
1265{
1266 if (item == NULL) {
1267 printf("none");
1268 return;
1269 }
1270
1271 switch (item->ic) {
1272 case ic_address:
1273 printf("address:");
1274 rdata_address_print(item->u.address);
1275 break;
1276 case ic_value:
1277 printf("value:");
1278 rdata_value_print(item->u.value);
1279 break;
1280 }
1281}
1282
1283/** Print address in human-readable form.
1284 *
1285 * Actually this displays contents of the var node that is being addressed.
1286 *
1287 * XXX Maybe we should really rather print the address and not the data
1288 * it is pointing to?
1289 *
1290 * @param item Address to print.
1291 */
1292static void rdata_address_print(rdata_address_t *address)
1293{
1294 switch (address->ac) {
1295 case ac_var:
1296 rdata_var_print(address->u.var_a->vref);
1297 break;
1298 case ac_prop:
1299 printf("Warning: Unimplemented: Print property address.\n");
1300 break;
1301 }
1302}
1303
1304/** Print value in human-readable form.
1305 *
1306 * @param value Value to print.
1307 */
1308void rdata_value_print(rdata_value_t *value)
1309{
1310 rdata_var_print(value->var);
1311}
1312
1313/** Print contents of var node in human-readable form.
1314 *
1315 * @param item Var node to print.
1316 */
1317static void rdata_var_print(rdata_var_t *var)
1318{
1319 int val;
1320
1321 switch (var->vc) {
1322 case vc_bool:
1323 printf("bool(%s)", var->u.bool_v->value ? "true" : "false");
1324 break;
1325 case vc_char:
1326 printf("char(");
1327 if (bigint_get_value_int(&var->u.char_v->value, &val) == EOK)
1328 printf("'%c'", val);
1329 else
1330 printf("???:x%x\n", (unsigned) val);
1331 printf(")");
1332 break;
1333 case vc_int:
1334 printf("int(");
1335 bigint_print(&var->u.int_v->value);
1336 printf(")");
1337 break;
1338 case vc_string:
1339 printf("string(\"%s\")", var->u.string_v->value);
1340 break;
1341 case vc_ref:
1342 if (var->u.ref_v->vref != NULL) {
1343 printf("ref(");
1344 rdata_var_print(var->u.ref_v->vref);
1345 printf(")");
1346 } else {
1347 printf("nil");
1348 }
1349 break;
1350 case vc_deleg:
1351 printf("deleg(");
1352 if (var->u.deleg_v->sym != NULL) {
1353 if (var->u.deleg_v->obj != NULL) {
1354 rdata_var_print(var->u.deleg_v->obj);
1355 printf(",");
1356 }
1357 symbol_print_fqn(var->u.deleg_v->sym);
1358 } else {
1359 printf("nil");
1360 }
1361 printf(")");
1362 break;
1363 case vc_enum:
1364 symbol_print_fqn(
1365 enum_to_symbol(var->u.enum_v->value->outer_enum));
1366 printf(".%s",
1367 strtab_get_str(var->u.enum_v->value->name->sid));
1368 break;
1369 case vc_array:
1370 printf("array");
1371 break;
1372 case vc_object:
1373 printf("object");
1374 break;
1375 case vc_resource:
1376 printf("resource(%p)", var->u.resource_v->data);
1377 break;
1378 case vc_symbol:
1379 printf("symbol(");
1380 if (var->u.symbol_v->sym != NULL) {
1381 symbol_print_fqn(var->u.symbol_v->sym);
1382 } else {
1383 printf("nil");
1384 }
1385 printf(")");
1386 break;
1387 }
1388}
Note: See TracBrowser for help on using the repository browser.