source: mainline/uspace/app/sbi/src/rdata.c

Last change on this file was 09ab0a9a, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix vertical spacing with new Ccheck revision.

  • 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/** Copy boolean.
739 *
740 * @param src Source boolean
741 * @param dest Place to store pointer to new boolean
742 */
743static void rdata_bool_copy(rdata_bool_t *src, rdata_bool_t **dest)
744{
745 *dest = rdata_bool_new();
746 (*dest)->value = src->value;
747}
748
749/** Copy character.
750 *
751 * @param src Source character
752 * @param dest Place to store pointer to new character
753 */
754static void rdata_char_copy(rdata_char_t *src, rdata_char_t **dest)
755{
756 *dest = rdata_char_new();
757 bigint_clone(&src->value, &(*dest)->value);
758}
759
760/** Copy integer.
761 *
762 * @param src Source integer
763 * @param dest Place to store pointer to new integer
764 */
765static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest)
766{
767 *dest = rdata_int_new();
768 bigint_clone(&src->value, &(*dest)->value);
769}
770
771/** Copy string.
772 *
773 * @param src Source string.
774 * @param dest Place to store pointer to new string.
775 */
776static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest)
777{
778 *dest = rdata_string_new();
779 (*dest)->value = src->value;
780}
781
782/** Copy reference.
783 *
784 * @param src Source reference.
785 * @param dest Place to store pointer to new reference.
786 */
787static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest)
788{
789 *dest = rdata_ref_new();
790 (*dest)->vref = src->vref;
791}
792
793/** Copy delegate.
794 *
795 * @param src Source delegate.
796 * @param dest Place to store pointer to new delegate.
797 */
798static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
799{
800 *dest = rdata_deleg_new();
801 (*dest)->obj = src->obj;
802 (*dest)->sym = src->sym;
803}
804
805/** Copy enum value.
806 *
807 * @param src Source enum value.
808 * @param dest Place to store pointer to new enum value.
809 */
810static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest)
811{
812 *dest = rdata_enum_new();
813 (*dest)->value = src->value;
814}
815
816/** Copy array.
817 *
818 * @param src Source array.
819 * @param dest Place to store pointer to new array.
820 */
821static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
822{
823 (void) src;
824 (void) dest;
825 printf("Unimplemented: Copy array.\n");
826 exit(1);
827}
828
829/** Copy object.
830 *
831 * @param src Source object.
832 * @param dest Place to store pointer to new object.
833 */
834static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest)
835{
836 (void) src;
837 (void) dest;
838 printf("Unimplemented: Copy object.\n");
839 abort();
840}
841
842/** Copy resource.
843 *
844 * @param src Source resource.
845 * @param dest Place to store pointer to new resource.
846 */
847static void rdata_resource_copy(rdata_resource_t *src, rdata_resource_t **dest)
848{
849 *dest = rdata_resource_new();
850 (*dest)->data = src->data;
851}
852
853/** Copy symbol.
854 *
855 * @param src Source symbol.
856 * @param dest Place to store pointer to new symbol.
857 */
858static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest)
859{
860 *dest = rdata_symbol_new();
861 (*dest)->sym = src->sym;
862}
863
864/** Destroy var node.
865 *
866 * @param var Var node
867 */
868void rdata_var_destroy(rdata_var_t *var)
869{
870 /* First destroy class-specific part */
871 rdata_var_destroy_inner(var);
872
873 /* Deallocate var node */
874 rdata_var_delete(var);
875}
876
877/** Destroy inside of var node.
878 *
879 * Destroy content of var node, but do not deallocate the var node
880 * itself.
881 *
882 * @param var Var node
883 */
884static void rdata_var_destroy_inner(rdata_var_t *var)
885{
886 /* First destroy class-specific part */
887
888 switch (var->vc) {
889 case vc_bool:
890 rdata_bool_destroy(var->u.bool_v);
891 break;
892 case vc_char:
893 rdata_char_destroy(var->u.char_v);
894 break;
895 case vc_int:
896 rdata_int_destroy(var->u.int_v);
897 break;
898 case vc_string:
899 rdata_string_destroy(var->u.string_v);
900 break;
901 case vc_ref:
902 rdata_ref_destroy(var->u.ref_v);
903 break;
904 case vc_deleg:
905 rdata_deleg_destroy(var->u.deleg_v);
906 break;
907 case vc_enum:
908 rdata_enum_destroy(var->u.enum_v);
909 break;
910 case vc_array:
911 rdata_array_destroy(var->u.array_v);
912 break;
913 case vc_object:
914 rdata_object_destroy(var->u.object_v);
915 break;
916 case vc_resource:
917 rdata_resource_destroy(var->u.resource_v);
918 break;
919 case vc_symbol:
920 rdata_symbol_destroy(var->u.symbol_v);
921 break;
922 }
923}
924
925/** Destroy item.
926 *
927 * Destroy an item including the value or address within.
928 *
929 * @param item Item
930 */
931void rdata_item_destroy(rdata_item_t *item)
932{
933 /* First destroy class-specific part */
934
935 switch (item->ic) {
936 case ic_address:
937 rdata_address_destroy(item->u.address);
938 break;
939 case ic_value:
940 rdata_value_destroy(item->u.value);
941 break;
942 }
943
944 /* Deallocate item node */
945 rdata_item_delete(item);
946}
947
948/** Destroy address.
949 *
950 * Destroy an address node.
951 *
952 * @param address Address
953 */
954void rdata_address_destroy(rdata_address_t *address)
955{
956 switch (address->ac) {
957 case ac_var:
958 rdata_addr_var_destroy(address->u.var_a);
959 break;
960 case ac_prop:
961 rdata_addr_prop_destroy(address->u.prop_a);
962 break;
963 }
964
965 /* Deallocate address node */
966 rdata_address_delete(address);
967}
968
969/** Destroy variable address.
970 *
971 * Destroy a variable address node.
972 *
973 * @param addr_var Variable address
974 */
975void rdata_addr_var_destroy(rdata_addr_var_t *addr_var)
976{
977 addr_var->vref = NULL;
978
979 /* Deallocate variable address node */
980 rdata_addr_var_delete(addr_var);
981}
982
983/** Destroy property address.
984 *
985 * Destroy a property address node.
986 *
987 * @param addr_prop Property address
988 */
989void rdata_addr_prop_destroy(rdata_addr_prop_t *addr_prop)
990{
991 switch (addr_prop->apc) {
992 case apc_named:
993 rdata_aprop_named_destroy(addr_prop->u.named);
994 break;
995 case apc_indexed:
996 rdata_aprop_indexed_destroy(addr_prop->u.indexed);
997 break;
998 }
999
1000 if (addr_prop->tvalue != NULL) {
1001 rdata_value_destroy(addr_prop->tvalue);
1002 addr_prop->tvalue = NULL;
1003 }
1004
1005 addr_prop->tpos = NULL;
1006
1007 /* Deallocate property address node */
1008 rdata_addr_prop_delete(addr_prop);
1009}
1010
1011/** Destroy named property address.
1012 *
1013 * Destroy a named property address node.
1014 *
1015 * @param aprop_named Named property address
1016 */
1017void rdata_aprop_named_destroy(rdata_aprop_named_t *aprop_named)
1018{
1019 rdata_deleg_destroy(aprop_named->prop_d);
1020
1021 /* Deallocate named property address node */
1022 rdata_aprop_named_delete(aprop_named);
1023}
1024
1025/** Destroy indexed property address.
1026 *
1027 * Destroy a indexed property address node.
1028 *
1029 * @param aprop_indexed Indexed property address
1030 */
1031void rdata_aprop_indexed_destroy(rdata_aprop_indexed_t *aprop_indexed)
1032{
1033 list_node_t *arg_node;
1034 rdata_item_t *arg_i;
1035
1036 /* Destroy the object delegate. */
1037 rdata_deleg_destroy(aprop_indexed->object_d);
1038
1039 /*
1040 * Walk through all argument items (indices) and destroy them,
1041 * removing them from the list as well.
1042 */
1043 while (!list_is_empty(&aprop_indexed->args)) {
1044 arg_node = list_first(&aprop_indexed->args);
1045 arg_i = list_node_data(arg_node, rdata_item_t *);
1046
1047 rdata_item_destroy(arg_i);
1048 list_remove(&aprop_indexed->args, arg_node);
1049 }
1050
1051 /* Destroy the now empty list */
1052 list_fini(&aprop_indexed->args);
1053
1054 /* Deallocate indexed property address node */
1055 rdata_aprop_indexed_delete(aprop_indexed);
1056}
1057
1058/** Destroy value.
1059 *
1060 * Destroy a value node.
1061 *
1062 * @param value Value
1063 */
1064void rdata_value_destroy(rdata_value_t *value)
1065{
1066 /* Assumption: Var nodes in values are not shared. */
1067 rdata_var_destroy(value->var);
1068
1069 /* Deallocate value node */
1070 rdata_value_delete(value);
1071}
1072
1073/** Destroy boolean.
1074 *
1075 * @param bool_v Boolean
1076 */
1077static void rdata_bool_destroy(rdata_bool_t *bool_v)
1078{
1079 rdata_bool_delete(bool_v);
1080}
1081
1082/** Destroy character.
1083 *
1084 * @param char_v Character
1085 */
1086static void rdata_char_destroy(rdata_char_t *char_v)
1087{
1088 bigint_destroy(&char_v->value);
1089 rdata_char_delete(char_v);
1090}
1091
1092/** Destroy integer.
1093 *
1094 * @param int_v Integer
1095 */
1096static void rdata_int_destroy(rdata_int_t *int_v)
1097{
1098 bigint_destroy(&int_v->value);
1099 rdata_int_delete(int_v);
1100}
1101
1102/** Destroy string.
1103 *
1104 * @param string_v String
1105 */
1106static void rdata_string_destroy(rdata_string_t *string_v)
1107{
1108 /*
1109 * String values are shared so we cannot free them. Just deallocate
1110 * the node.
1111 */
1112 rdata_string_delete(string_v);
1113}
1114
1115/** Destroy reference.
1116 *
1117 * @param ref_v Reference
1118 */
1119static void rdata_ref_destroy(rdata_ref_t *ref_v)
1120{
1121 ref_v->vref = NULL;
1122 rdata_ref_delete(ref_v);
1123}
1124
1125/** Destroy delegate.
1126 *
1127 * @param deleg_v Reference
1128 */
1129static void rdata_deleg_destroy(rdata_deleg_t *deleg_v)
1130{
1131 deleg_v->obj = NULL;
1132 deleg_v->sym = NULL;
1133 rdata_deleg_delete(deleg_v);
1134}
1135
1136/** Destroy enum.
1137 *
1138 * @param enum_v Reference
1139 */
1140static void rdata_enum_destroy(rdata_enum_t *enum_v)
1141{
1142 enum_v->value = NULL;
1143 rdata_enum_delete(enum_v);
1144}
1145
1146/** Destroy array.
1147 *
1148 * @param array_v Array
1149 */
1150static void rdata_array_destroy(rdata_array_t *array_v)
1151{
1152 int d;
1153 size_t n_elems, p;
1154
1155 /*
1156 * Compute total number of elements in array.
1157 * At the same time zero out the extent array.
1158 */
1159 n_elems = 1;
1160 for (d = 0; d < array_v->rank; d++) {
1161 n_elems = n_elems * array_v->extent[d];
1162 array_v->extent[d] = 0;
1163 }
1164
1165 /* Destroy all elements and zero out the array */
1166 for (p = 0; p < n_elems; p++) {
1167 rdata_var_delete(array_v->element[p]);
1168 array_v->element[p] = NULL;
1169 }
1170
1171 /* Free the arrays */
1172 free(array_v->element);
1173 free(array_v->extent);
1174
1175 array_v->rank = 0;
1176
1177 /* Deallocate the node */
1178 rdata_array_delete(array_v);
1179}
1180
1181/** Destroy object.
1182 *
1183 * @param object_v Object
1184 */
1185static void rdata_object_destroy(rdata_object_t *object_v)
1186{
1187 /* XXX TODO */
1188 rdata_object_delete(object_v);
1189}
1190
1191/** Destroy resource.
1192 *
1193 * @param resource_v Resource
1194 */
1195static void rdata_resource_destroy(rdata_resource_t *resource_v)
1196{
1197 /*
1198 * XXX Presumably this should be handled by the appropriate
1199 * built-in module, so, some call-back function would be required.
1200 */
1201 resource_v->data = NULL;
1202 rdata_resource_delete(resource_v);
1203}
1204
1205/** Destroy symbol.
1206 *
1207 * @param symbol_v Symbol
1208 */
1209static void rdata_symbol_destroy(rdata_symbol_t *symbol_v)
1210{
1211 symbol_v->sym = NULL;
1212 rdata_symbol_delete(symbol_v);
1213}
1214
1215/** Read data from a variable.
1216 *
1217 * This copies data from the variable to a value item. Ideally any read access
1218 * to a program variable should go through this function. (Keep in mind
1219 * that although values are composed of var nodes internally, but are not
1220 * variables per se. Therefore this function is not used to read from values)
1221 *
1222 * @param var Variable to read from (var node where it is stored).
1223 * @param ritem Place to store pointer to new value item read from
1224 * the variable.
1225 */
1226void rdata_var_read(rdata_var_t *var, rdata_item_t **ritem)
1227{
1228 rdata_value_t *value;
1229 rdata_var_t *rvar;
1230
1231 /* Perform a shallow copy of @a var. */
1232 rdata_var_copy(var, &rvar);
1233
1234 value = rdata_value_new();
1235 value->var = rvar;
1236 *ritem = rdata_item_new(ic_value);
1237 (*ritem)->u.value = value;
1238}
1239
1240/** Write data to a variable.
1241 *
1242 * This copies data to the variable from a value. Ideally any write access
1243 * to a program variable should go through this function. (Keep in mind
1244 * that even though values are composed of var nodes internally, but are not
1245 * variables per se. Therefore this function is not used to write to values)
1246 *
1247 * @param var Variable to write to (var node where it is stored).
1248 * @param value The value to write.
1249 */
1250void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
1251{
1252 /* Free old content of var->u */
1253 rdata_var_destroy_inner(var);
1254
1255 /* Perform a shallow copy of @c value->var. */
1256 rdata_var_copy_to(value->var, var);
1257}
1258
1259/** Print data item in human-readable form.
1260 *
1261 * @param item Item to print.
1262 */
1263void rdata_item_print(rdata_item_t *item)
1264{
1265 if (item == NULL) {
1266 printf("none");
1267 return;
1268 }
1269
1270 switch (item->ic) {
1271 case ic_address:
1272 printf("address:");
1273 rdata_address_print(item->u.address);
1274 break;
1275 case ic_value:
1276 printf("value:");
1277 rdata_value_print(item->u.value);
1278 break;
1279 }
1280}
1281
1282/** Print address in human-readable form.
1283 *
1284 * Actually this displays contents of the var node that is being addressed.
1285 *
1286 * XXX Maybe we should really rather print the address and not the data
1287 * it is pointing to?
1288 *
1289 * @param item Address to print.
1290 */
1291static void rdata_address_print(rdata_address_t *address)
1292{
1293 switch (address->ac) {
1294 case ac_var:
1295 rdata_var_print(address->u.var_a->vref);
1296 break;
1297 case ac_prop:
1298 printf("Warning: Unimplemented: Print property address.\n");
1299 break;
1300 }
1301}
1302
1303/** Print value in human-readable form.
1304 *
1305 * @param value Value to print.
1306 */
1307void rdata_value_print(rdata_value_t *value)
1308{
1309 rdata_var_print(value->var);
1310}
1311
1312/** Print contents of var node in human-readable form.
1313 *
1314 * @param item Var node to print.
1315 */
1316static void rdata_var_print(rdata_var_t *var)
1317{
1318 int val;
1319
1320 switch (var->vc) {
1321 case vc_bool:
1322 printf("bool(%s)", var->u.bool_v->value ? "true" : "false");
1323 break;
1324 case vc_char:
1325 printf("char(");
1326 if (bigint_get_value_int(&var->u.char_v->value, &val) == EOK)
1327 printf("'%c'", val);
1328 else
1329 printf("???:x%x\n", (unsigned) val);
1330 printf(")");
1331 break;
1332 case vc_int:
1333 printf("int(");
1334 bigint_print(&var->u.int_v->value);
1335 printf(")");
1336 break;
1337 case vc_string:
1338 printf("string(\"%s\")", var->u.string_v->value);
1339 break;
1340 case vc_ref:
1341 if (var->u.ref_v->vref != NULL) {
1342 printf("ref(");
1343 rdata_var_print(var->u.ref_v->vref);
1344 printf(")");
1345 } else {
1346 printf("nil");
1347 }
1348 break;
1349 case vc_deleg:
1350 printf("deleg(");
1351 if (var->u.deleg_v->sym != NULL) {
1352 if (var->u.deleg_v->obj != NULL) {
1353 rdata_var_print(var->u.deleg_v->obj);
1354 printf(",");
1355 }
1356 symbol_print_fqn(var->u.deleg_v->sym);
1357 } else {
1358 printf("nil");
1359 }
1360 printf(")");
1361 break;
1362 case vc_enum:
1363 symbol_print_fqn(
1364 enum_to_symbol(var->u.enum_v->value->outer_enum));
1365 printf(".%s",
1366 strtab_get_str(var->u.enum_v->value->name->sid));
1367 break;
1368 case vc_array:
1369 printf("array");
1370 break;
1371 case vc_object:
1372 printf("object");
1373 break;
1374 case vc_resource:
1375 printf("resource(%p)", var->u.resource_v->data);
1376 break;
1377 case vc_symbol:
1378 printf("symbol(");
1379 if (var->u.symbol_v->sym != NULL) {
1380 symbol_print_fqn(var->u.symbol_v->sym);
1381 } else {
1382 printf("nil");
1383 }
1384 printf(")");
1385 break;
1386 }
1387}
Note: See TracBrowser for help on using the repository browser.