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

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

Update SBI to rev. 344 from upstream. What's new:

  • Builtin.WriteLine() renamed to Console.WriteLine()
  • Implemented 'switch' statement
  • Significantly reduced memory consumption (also increases execution speed in some cases)
  • Properties can be accessed via unqualified names
  • Exceptions raised during property accesses are now handled correctly
  • Some missing checks against expressions returning no value added
  • Property mode set to 100644
File size: 28.6 KB
RevLine 
[09ababb7]1/*
[051b3db8]2 * Copyright (c) 2011 Jiri Svoboda
[09ababb7]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
[23de644]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 */
[09ababb7]47
48#include <stdlib.h>
49#include <assert.h>
[23de644]50#include "bigint.h"
[051b3db8]51#include "list.h"
[09ababb7]52#include "mytypes.h"
[94d484a]53#include "stree.h"
[074444f]54#include "symbol.h"
[051bc69a]55#include "strtab.h"
[09ababb7]56
57#include "rdata.h"
58
[074444f]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);
[09ababb7]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);
[051bc69a]65static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest);
[94d484a]66static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest);
[09ababb7]67static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest);
[37f527b]68static void rdata_resource_copy(rdata_resource_t *src,
69 rdata_resource_t **dest);
[051bc69a]70static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest);
[09ababb7]71
[051b3db8]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
[94d484a]86static int rdata_array_get_dim(rdata_array_t *array);
[051b3db8]87static void rdata_var_copy_to(rdata_var_t *src, rdata_var_t *dest);
[94d484a]88
[09ababb7]89static void rdata_address_print(rdata_address_t *address);
90static void rdata_var_print(rdata_var_t *var);
91
[23de644]92/** Allocate new data item.
93 *
94 * @param ic Item class.
95 * @return New item.
96 */
[09ababb7]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
[23de644]111/** Allocate new address.
112 *
113 * @return New address.
114 */
[d0febca]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
[23de644]128/** Allocate new named property address.
129 *
130 * @return New named property address.
131 */
[d0febca]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
[23de644]145/** Allocate new indexed property address.
146 *
147 * @return New indexed property address.
148 */
[d0febca]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
[23de644]162/** Allocate new property address.
163 *
164 * @param apc Property address class.
165 * @return New property address.
166 */
[d0febca]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
[23de644]181/** Allocate new address.
182 *
183 * @param ac Address class.
184 * @return New address.
185 */
[d0febca]186rdata_address_t *rdata_address_new(address_class_t ac)
[09ababb7]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
[d0febca]196 address->ac = ac;
[09ababb7]197 return address;
198}
199
[23de644]200/** Allocate new value.
201 *
202 * @return New value.
203 */
[09ababb7]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
[23de644]217/** Allocate new var node.
218 *
219 * @param vc Var node class (varclass).
220 * @return New var node.
221 */
[09ababb7]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
[23de644]236/** Allocate new reference.
237 *
238 * @return New reference.
239 */
[fa36f29]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
[23de644]253/** Allocate new delegate.
254 *
255 * @return New delegate.
256 */
[09ababb7]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
[051bc69a]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
[23de644]287/** Allocate new array.
288 *
289 * @return New array.
290 */
[94d484a]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
[23de644]311/** Allocate new object.
312 *
313 * @return New object.
314 */
[fa36f29]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
[074444f]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
[23de644]362/** Allocate new integer.
363 *
364 * @return New integer.
365 */
[09ababb7]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
[23de644]379/** Allocate new string.
380 *
381 * @return New string.
382 */
[09ababb7]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
[23de644]396/** Allocate new resource.
397 *
398 * @return New resource.
399 */
[37f527b]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
[051bc69a]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
[23de644]430/** Allocate array elements.
431 *
[051b3db8]432 * Allocates element array of @a array.
[23de644]433 *
434 * @param array Array.
435 */
[94d484a]436void rdata_array_alloc_element(rdata_array_t *array)
437{
[051b3db8]438 int dim;
[94d484a]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.
[23de644]453 *
454 * @param array Array.
[94d484a]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
[051b3db8]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
[23de644]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 */
[09ababb7]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);
[051b3db8]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;
[09ababb7]700
701 switch (src->vc) {
[074444f]702 case vc_bool:
[051b3db8]703 rdata_bool_copy(src->u.bool_v, &dest->u.bool_v);
[074444f]704 break;
705 case vc_char:
[051b3db8]706 rdata_char_copy(src->u.char_v, &dest->u.char_v);
[074444f]707 break;
[09ababb7]708 case vc_int:
[051b3db8]709 rdata_int_copy(src->u.int_v, &dest->u.int_v);
[09ababb7]710 break;
711 case vc_string:
[051b3db8]712 rdata_string_copy(src->u.string_v, &dest->u.string_v);
[09ababb7]713 break;
714 case vc_ref:
[051b3db8]715 rdata_ref_copy(src->u.ref_v, &dest->u.ref_v);
[09ababb7]716 break;
717 case vc_deleg:
[051b3db8]718 rdata_deleg_copy(src->u.deleg_v, &dest->u.deleg_v);
[09ababb7]719 break;
[051bc69a]720 case vc_enum:
[051b3db8]721 rdata_enum_copy(src->u.enum_v, &dest->u.enum_v);
[051bc69a]722 break;
[94d484a]723 case vc_array:
[051b3db8]724 rdata_array_copy(src->u.array_v, &dest->u.array_v);
[94d484a]725 break;
[09ababb7]726 case vc_object:
[051b3db8]727 rdata_object_copy(src->u.object_v, &dest->u.object_v);
[09ababb7]728 break;
[37f527b]729 case vc_resource:
[051b3db8]730 rdata_resource_copy(src->u.resource_v, &dest->u.resource_v);
[37f527b]731 break;
[051bc69a]732 case vc_symbol:
[051b3db8]733 rdata_symbol_copy(src->u.symbol_v, &dest->u.symbol_v);
[051bc69a]734 break;
[09ababb7]735 }
736}
737
[051b3db8]738
[074444f]739/** Copy boolean.
740 *
[051b3db8]741 * @param src Source boolean
742 * @param dest Place to store pointer to new boolean
[074444f]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 *
[051b3db8]752 * @param src Source character
753 * @param dest Place to store pointer to new character
[074444f]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
[23de644]761/** Copy integer.
762 *
[051b3db8]763 * @param src Source integer
764 * @param dest Place to store pointer to new integer
[23de644]765 */
[09ababb7]766static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest)
767{
768 *dest = rdata_int_new();
[23de644]769 bigint_clone(&src->value, &(*dest)->value);
[09ababb7]770}
771
[23de644]772/** Copy string.
773 *
774 * @param src Source string.
775 * @param dest Place to store pointer to new string.
776 */
[09ababb7]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
[23de644]783/** Copy reference.
784 *
785 * @param src Source reference.
786 * @param dest Place to store pointer to new reference.
787 */
[09ababb7]788static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest)
789{
[fa36f29]790 *dest = rdata_ref_new();
791 (*dest)->vref = src->vref;
[09ababb7]792}
793
[23de644]794/** Copy delegate.
795 *
796 * @param src Source delegate.
797 * @param dest Place to store pointer to new delegate.
798 */
[09ababb7]799static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
800{
[38aaacc2]801 *dest = rdata_deleg_new();
802 (*dest)->obj = src->obj;
803 (*dest)->sym = src->sym;
[09ababb7]804}
805
[051bc69a]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
[23de644]817/** Copy array.
818 *
819 * @param src Source array.
820 * @param dest Place to store pointer to new array.
821 */
[94d484a]822static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
823{
824 (void) src; (void) dest;
825 printf("Unimplemented: Copy array.\n");
826 exit(1);
827}
828
[23de644]829/** Copy object.
830 *
831 * @param src Source object.
832 * @param dest Place to store pointer to new object.
833 */
[09ababb7]834static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest)
835{
[fa36f29]836 (void) src; (void) dest;
[09ababb7]837 printf("Unimplemented: Copy object.\n");
[c5cb943d]838 abort();
[09ababb7]839}
840
[23de644]841/** Copy resource.
842 *
843 * @param src Source resource.
844 * @param dest Place to store pointer to new resource.
845 */
[37f527b]846static void rdata_resource_copy(rdata_resource_t *src, rdata_resource_t **dest)
847{
848 *dest = rdata_resource_new();
849 (*dest)->data = src->data;
850}
851
[051bc69a]852/** Copy symbol.
853 *
854 * @param src Source symbol.
855 * @param dest Place to store pointer to new symbol.
856 */
857static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest)
858{
859 *dest = rdata_symbol_new();
860 (*dest)->sym = src->sym;
861}
862
[051b3db8]863/** Destroy var node.
864 *
865 * @param var Var node
866 */
867void rdata_var_destroy(rdata_var_t *var)
868{
869 /* First destroy class-specific part */
870 rdata_var_destroy_inner(var);
871
872 /* Deallocate var node */
873 rdata_var_delete(var);
874}
875
876/** Destroy inside of var node.
877 *
878 * Destroy content of var node, but do not deallocate the var node
879 * itself.
880 *
881 * @param var Var node
882 */
883static void rdata_var_destroy_inner(rdata_var_t *var)
884{
885 /* First destroy class-specific part */
886
887 switch (var->vc) {
888 case vc_bool:
889 rdata_bool_destroy(var->u.bool_v);
890 break;
891 case vc_char:
892 rdata_char_destroy(var->u.char_v);
893 break;
894 case vc_int:
895 rdata_int_destroy(var->u.int_v);
896 break;
897 case vc_string:
898 rdata_string_destroy(var->u.string_v);
899 break;
900 case vc_ref:
901 rdata_ref_destroy(var->u.ref_v);
902 break;
903 case vc_deleg:
904 rdata_deleg_destroy(var->u.deleg_v);
905 break;
906 case vc_enum:
907 rdata_enum_destroy(var->u.enum_v);
908 break;
909 case vc_array:
910 rdata_array_destroy(var->u.array_v);
911 break;
912 case vc_object:
913 rdata_object_destroy(var->u.object_v);
914 break;
915 case vc_resource:
916 rdata_resource_destroy(var->u.resource_v);
917 break;
918 case vc_symbol:
919 rdata_symbol_destroy(var->u.symbol_v);
920 break;
921 }
922}
923
924/** Destroy item.
925 *
926 * Destroy an item including the value or address within.
927 *
928 * @param item Item
929 */
930void rdata_item_destroy(rdata_item_t *item)
931{
932 /* First destroy class-specific part */
933
934 switch (item->ic) {
935 case ic_address:
936 rdata_address_destroy(item->u.address);
937 break;
938 case ic_value:
939 rdata_value_destroy(item->u.value);
940 break;
941 }
942
943 /* Deallocate item node */
944 rdata_item_delete(item);
945}
946
947/** Destroy address.
948 *
949 * Destroy an address node.
950 *
951 * @param address Address
952 */
953void rdata_address_destroy(rdata_address_t *address)
954{
955 switch (address->ac) {
956 case ac_var:
957 rdata_addr_var_destroy(address->u.var_a);
958 break;
959 case ac_prop:
960 rdata_addr_prop_destroy(address->u.prop_a);
961 break;
962 }
963
964 /* Deallocate address node */
965 rdata_address_delete(address);
966}
967
968/** Destroy variable address.
969 *
970 * Destroy a variable address node.
971 *
972 * @param addr_var Variable address
973 */
974void rdata_addr_var_destroy(rdata_addr_var_t *addr_var)
975{
976 addr_var->vref = NULL;
977
978 /* Deallocate variable address node */
979 rdata_addr_var_delete(addr_var);
980}
981
982/** Destroy property address.
983 *
984 * Destroy a property address node.
985 *
986 * @param addr_prop Property address
987 */
988void rdata_addr_prop_destroy(rdata_addr_prop_t *addr_prop)
989{
990 switch (addr_prop->apc) {
991 case apc_named:
992 rdata_aprop_named_destroy(addr_prop->u.named);
993 break;
994 case apc_indexed:
995 rdata_aprop_indexed_destroy(addr_prop->u.indexed);
996 break;
997 }
998
999 if (addr_prop->tvalue != NULL) {
1000 rdata_value_destroy(addr_prop->tvalue);
1001 addr_prop->tvalue = NULL;
1002 }
1003
1004 addr_prop->tpos = NULL;
1005
1006 /* Deallocate property address node */
1007 rdata_addr_prop_delete(addr_prop);
1008}
1009
1010/** Destroy named property address.
1011 *
1012 * Destroy a named property address node.
1013 *
1014 * @param aprop_named Named property address
1015 */
1016void rdata_aprop_named_destroy(rdata_aprop_named_t *aprop_named)
1017{
1018 rdata_deleg_destroy(aprop_named->prop_d);
1019
1020 /* Deallocate named property address node */
1021 rdata_aprop_named_delete(aprop_named);
1022}
1023
1024/** Destroy indexed property address.
1025 *
1026 * Destroy a indexed property address node.
1027 *
1028 * @param aprop_indexed Indexed property address
1029 */
1030void rdata_aprop_indexed_destroy(rdata_aprop_indexed_t *aprop_indexed)
1031{
1032 list_node_t *arg_node;
1033 rdata_item_t *arg_i;
1034
1035 /* Destroy the object delegate. */
1036 rdata_deleg_destroy(aprop_indexed->object_d);
1037
1038 /*
1039 * Walk through all argument items (indices) and destroy them,
1040 * removing them from the list as well.
1041 */
1042 while (!list_is_empty(&aprop_indexed->args)) {
1043 arg_node = list_first(&aprop_indexed->args);
1044 arg_i = list_node_data(arg_node, rdata_item_t *);
1045
1046 rdata_item_destroy(arg_i);
1047 list_remove(&aprop_indexed->args, arg_node);
1048 }
1049
1050 /* Destroy the now empty list */
1051 list_fini(&aprop_indexed->args);
1052
1053 /* Deallocate indexed property address node */
1054 rdata_aprop_indexed_delete(aprop_indexed);
1055}
1056
1057/** Destroy value.
1058 *
1059 * Destroy a value node.
1060 *
1061 * @param value Value
1062 */
1063void rdata_value_destroy(rdata_value_t *value)
1064{
1065 /* Assumption: Var nodes in values are not shared. */
1066 rdata_var_destroy(value->var);
1067
1068 /* Deallocate value node */
1069 rdata_value_delete(value);
1070}
1071
1072/** Destroy boolean.
1073 *
1074 * @param bool_v Boolean
1075 */
1076static void rdata_bool_destroy(rdata_bool_t *bool_v)
1077{
1078 rdata_bool_delete(bool_v);
1079}
1080
1081/** Destroy character.
1082 *
1083 * @param char_v Character
1084 */
1085static void rdata_char_destroy(rdata_char_t *char_v)
1086{
1087 bigint_destroy(&char_v->value);
1088 rdata_char_delete(char_v);
1089}
1090
1091/** Destroy integer.
1092 *
1093 * @param int_v Integer
1094 */
1095static void rdata_int_destroy(rdata_int_t *int_v)
1096{
1097 bigint_destroy(&int_v->value);
1098 rdata_int_delete(int_v);
1099}
1100
1101/** Destroy string.
1102 *
1103 * @param string_v String
1104 */
1105static void rdata_string_destroy(rdata_string_t *string_v)
1106{
1107 /*
1108 * String values are shared so we cannot free them. Just deallocate
1109 * the node.
1110 */
1111 rdata_string_delete(string_v);
1112}
1113
1114/** Destroy reference.
1115 *
1116 * @param ref_v Reference
1117 */
1118static void rdata_ref_destroy(rdata_ref_t *ref_v)
1119{
1120 ref_v->vref = NULL;
1121 rdata_ref_delete(ref_v);
1122}
1123
1124/** Destroy delegate.
1125 *
1126 * @param deleg_v Reference
1127 */
1128static void rdata_deleg_destroy(rdata_deleg_t *deleg_v)
1129{
1130 deleg_v->obj = NULL;
1131 deleg_v->sym = NULL;
1132 rdata_deleg_delete(deleg_v);
1133}
1134
1135/** Destroy enum.
1136 *
1137 * @param enum_v Reference
1138 */
1139static void rdata_enum_destroy(rdata_enum_t *enum_v)
1140{
1141 enum_v->value = NULL;
1142 rdata_enum_delete(enum_v);
1143}
1144
1145/** Destroy array.
1146 *
1147 * @param array_v Array
1148 */
1149static void rdata_array_destroy(rdata_array_t *array_v)
1150{
1151 int d;
1152 size_t n_elems, p;
1153
1154 /*
1155 * Compute total number of elements in array.
1156 * At the same time zero out the extent array.
1157 */
1158 n_elems = 1;
1159 for (d = 0; d < array_v->rank; d++) {
1160 n_elems = n_elems * array_v->extent[d];
1161 array_v->extent[d] = 0;
1162 }
1163
1164 /* Destroy all elements and zero out the array */
1165 for (p = 0; p < n_elems; p++) {
1166 rdata_var_delete(array_v->element[p]);
1167 array_v->element[p] = NULL;
1168 }
1169
1170 /* Free the arrays */
1171 free(array_v->element);
1172 free(array_v->extent);
1173
1174 array_v->rank = 0;
1175
1176 /* Deallocate the node */
1177 rdata_array_delete(array_v);
1178}
1179
1180/** Destroy object.
1181 *
1182 * @param object_v Object
1183 */
1184static void rdata_object_destroy(rdata_object_t *object_v)
1185{
1186 /* XXX TODO */
1187 rdata_object_delete(object_v);
1188}
1189
1190/** Destroy resource.
1191 *
1192 * @param resource_v Resource
1193 */
1194static void rdata_resource_destroy(rdata_resource_t *resource_v)
1195{
1196 /*
1197 * XXX Presumably this should be handled by the appropriate
1198 * built-in module, so, some call-back function would be required.
1199 */
1200 resource_v->data = NULL;
1201 rdata_resource_delete(resource_v);
1202}
1203
1204/** Destroy symbol.
1205 *
1206 * @param symbol_v Symbol
1207 */
1208static void rdata_symbol_destroy(rdata_symbol_t *symbol_v)
1209{
1210 symbol_v->sym = NULL;
1211 rdata_symbol_delete(symbol_v);
1212}
1213
[d0febca]1214/** Read data from a variable.
[fa36f29]1215 *
[23de644]1216 * This copies data from the variable to a value item. Ideally any read access
1217 * to a program variable should go through this function. (Keep in mind
1218 * that although values are composed of var nodes internally, but are not
1219 * variables per se. Therefore this function is not used to read from values)
1220 *
1221 * @param var Variable to read from (var node where it is stored).
1222 * @param ritem Place to store pointer to new value item read from
1223 * the variable.
[fa36f29]1224 */
[d0febca]1225void rdata_var_read(rdata_var_t *var, rdata_item_t **ritem)
[fa36f29]1226{
1227 rdata_value_t *value;
1228 rdata_var_t *rvar;
1229
[d0febca]1230 /* Perform a shallow copy of @a var. */
1231 rdata_var_copy(var, &rvar);
[fa36f29]1232
1233 value = rdata_value_new();
1234 value->var = rvar;
1235 *ritem = rdata_item_new(ic_value);
1236 (*ritem)->u.value = value;
1237}
1238
[94d484a]1239/** Write data to a variable.
1240 *
[23de644]1241 * This copies data to the variable from a value. Ideally any write access
1242 * to a program variable should go through this function. (Keep in mind
1243 * that even though values are composed of var nodes internally, but are not
1244 * variables per se. Therefore this function is not used to write to values)
1245 *
1246 * @param var Variable to write to (var node where it is stored).
1247 * @param value The value to write.
[94d484a]1248 */
1249void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
[fa36f29]1250{
[051b3db8]1251 /* Free old content of var->u */
1252 rdata_var_destroy_inner(var);
[fa36f29]1253
1254 /* Perform a shallow copy of @c value->var. */
[051b3db8]1255 rdata_var_copy_to(value->var, var);
[fa36f29]1256}
1257
[23de644]1258/** Print data item in human-readable form.
1259 *
1260 * @param item Item to print.
1261 */
[09ababb7]1262void rdata_item_print(rdata_item_t *item)
1263{
1264 if (item == NULL) {
1265 printf("none");
1266 return;
1267 }
1268
1269 switch (item->ic) {
1270 case ic_address:
1271 printf("address:");
1272 rdata_address_print(item->u.address);
1273 break;
1274 case ic_value:
1275 printf("value:");
1276 rdata_value_print(item->u.value);
1277 break;
1278 }
1279}
1280
[23de644]1281/** Print address in human-readable form.
1282 *
1283 * Actually this displays contents of the var node that is being addressed.
1284 *
1285 * XXX Maybe we should really rather print the address and not the data
1286 * it is pointing to?
1287 *
1288 * @param item Address to print.
1289 */
[09ababb7]1290static void rdata_address_print(rdata_address_t *address)
1291{
[d0febca]1292 switch (address->ac) {
1293 case ac_var:
1294 rdata_var_print(address->u.var_a->vref);
1295 break;
1296 case ac_prop:
1297 printf("Warning: Unimplemented: Print property address.\n");
1298 break;
1299 }
[09ababb7]1300}
1301
[23de644]1302/** Print value in human-readable form.
1303 *
1304 * @param value Value to print.
1305 */
[1ebc1a62]1306void rdata_value_print(rdata_value_t *value)
[09ababb7]1307{
1308 rdata_var_print(value->var);
1309}
1310
[23de644]1311/** Print contents of var node in human-readable form.
1312 *
1313 * @param item Var node to print.
1314 */
[09ababb7]1315static void rdata_var_print(rdata_var_t *var)
1316{
[074444f]1317 int val;
1318
[09ababb7]1319 switch (var->vc) {
[074444f]1320 case vc_bool:
1321 printf("bool(%s)", var->u.bool_v->value ? "true" : "false");
1322 break;
1323 case vc_char:
1324 printf("char(");
1325 if (bigint_get_value_int(&var->u.char_v->value, &val) == EOK)
1326 printf("'%c'", val);
1327 else
1328 printf("???:x%x\n", (unsigned) val);
1329 printf(")");
1330 break;
[09ababb7]1331 case vc_int:
[23de644]1332 printf("int(");
1333 bigint_print(&var->u.int_v->value);
1334 printf(")");
[09ababb7]1335 break;
[fa36f29]1336 case vc_string:
1337 printf("string(\"%s\")", var->u.string_v->value);
1338 break;
[09ababb7]1339 case vc_ref:
[38aaacc2]1340 if (var->u.ref_v->vref != NULL) {
1341 printf("ref(");
1342 rdata_var_print(var->u.ref_v->vref);
1343 printf(")");
1344 } else {
1345 printf("nil");
1346 }
[09ababb7]1347 break;
1348 case vc_deleg:
[074444f]1349 printf("deleg(");
[38aaacc2]1350 if (var->u.deleg_v->sym != NULL) {
1351 if (var->u.deleg_v->obj != NULL) {
1352 rdata_var_print(var->u.deleg_v->obj);
1353 printf(",");
1354 }
1355 symbol_print_fqn(var->u.deleg_v->sym);
1356 } else {
1357 printf("nil");
[074444f]1358 }
1359 printf(")");
1360 break;
[051bc69a]1361 case vc_enum:
1362 symbol_print_fqn(
1363 enum_to_symbol(var->u.enum_v->value->outer_enum));
1364 printf(".%s",
1365 strtab_get_str(var->u.enum_v->value->name->sid));
1366 break;
[074444f]1367 case vc_array:
1368 printf("array");
[09ababb7]1369 break;
1370 case vc_object:
1371 printf("object");
1372 break;
[074444f]1373 case vc_resource:
1374 printf("resource(%p)", var->u.resource_v->data);
1375 break;
[051bc69a]1376 case vc_symbol:
1377 printf("symbol(");
1378 if (var->u.symbol_v->sym != NULL) {
1379 symbol_print_fqn(var->u.symbol_v->sym);
1380 } else {
1381 printf("nil");
1382 }
1383 printf(")");
1384 break;
[09ababb7]1385 }
1386}
Note: See TracBrowser for help on using the repository browser.