Update copyright year range in all GDB files.
[deliverable/binutils-gdb.git] / sim / common / hw-properties.c
CommitLineData
b85e4829
AC
1/* The common simulator framework for GDB, the GNU Debugger.
2
b811d2c2 3 Copyright 2002-2020 Free Software Foundation, Inc.
b85e4829
AC
4
5 Contributed by Andrew Cagney and Red Hat.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
b85e4829
AC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "hw-main.h"
23#include "hw-base.h"
24
c2c6d25f 25#include "sim-io.h"
c906108c
SS
26#include "sim-assert.h"
27
28#ifdef HAVE_STRING_H
29#include <string.h>
30#else
31#ifdef HAVE_STRINGS_H
32#include <strings.h>
33#endif
34#endif
35
c906108c
SS
36/* property entries */
37
12c4cbd5
MF
38struct hw_property_data
39{
c906108c
SS
40 struct hw_property_data *next;
41 struct hw_property *property;
42 const void *init_array;
43 unsigned sizeof_init_array;
44};
45
46void
47create_hw_property_data (struct hw *me)
48{
49}
50
51void
52delete_hw_property_data (struct hw *me)
53{
54}
55
56
57/* Device Properties: */
58
59static struct hw_property_data *
60find_property_data (struct hw *me,
61 const char *property)
62{
63 struct hw_property_data *entry;
64 ASSERT (property != NULL);
65 entry = me->properties_of_hw;
66 while (entry != NULL)
67 {
68 if (strcmp (entry->property->name, property) == 0)
69 return entry;
70 entry = entry->next;
71 }
72 return NULL;
73}
74
75
76static void
77hw_add_property (struct hw *me,
78 const char *property,
79 hw_property_type type,
80 const void *init_array,
81 unsigned sizeof_init_array,
82 const void *array,
83 unsigned sizeof_array,
84 const struct hw_property *original,
85 object_disposition disposition)
86{
87 struct hw_property_data *new_entry = NULL;
88 struct hw_property *new_value = NULL;
028f6515 89
c906108c
SS
90 /* find the list end */
91 struct hw_property_data **insertion_point = &me->properties_of_hw;
92 while (*insertion_point != NULL)
93 {
94 if (strcmp ((*insertion_point)->property->name, property) == 0)
95 return;
96 insertion_point = &(*insertion_point)->next;
97 }
028f6515 98
c906108c
SS
99 /* create a new value */
100 new_value = HW_ZALLOC (me, struct hw_property);
101 new_value->name = (char *) strdup (property);
102 new_value->type = type;
103 if (sizeof_array > 0)
104 {
105 void *new_array = hw_zalloc (me, sizeof_array);
106 memcpy (new_array, array, sizeof_array);
107 new_value->array = new_array;
108 new_value->sizeof_array = sizeof_array;
109 }
110 new_value->owner = me;
111 new_value->original = original;
112 new_value->disposition = disposition;
028f6515 113
c906108c
SS
114 /* insert the value into the list */
115 new_entry = HW_ZALLOC (me, struct hw_property_data);
116 *insertion_point = new_entry;
117 if (sizeof_init_array > 0)
118 {
119 void *new_init_array = hw_zalloc (me, sizeof_init_array);
120 memcpy (new_init_array, init_array, sizeof_init_array);
121 new_entry->init_array = new_init_array;
122 new_entry->sizeof_init_array = sizeof_init_array;
123 }
124 new_entry->property = new_value;
125}
126
127
128static void
129hw_set_property (struct hw *me,
130 const char *property,
131 hw_property_type type,
132 const void *array,
133 int sizeof_array)
134{
135 /* find the property */
136 struct hw_property_data *entry = find_property_data (me, property);
137 if (entry != NULL)
138 {
139 /* existing property - update it */
140 void *new_array = 0;
141 struct hw_property *value = entry->property;
142 /* check the type matches */
143 if (value->type != type)
144 hw_abort (me, "conflict between type of new and old value for property %s", property);
145 /* replace its value */
146 if (value->array != NULL)
147 hw_free (me, (void*)value->array);
148 new_array = (sizeof_array > 0
149 ? hw_zalloc (me, sizeof_array)
150 : (void*)0);
151 value->array = new_array;
152 value->sizeof_array = sizeof_array;
153 if (sizeof_array > 0)
154 memcpy (new_array, array, sizeof_array);
155 return;
156 }
157 else
158 {
159 /* new property - create it */
160 hw_add_property (me, property, type,
161 NULL, 0, array, sizeof_array,
162 NULL, temporary_object);
163 }
164}
165
166
167#if 0
168static void
169clean_hw_properties (struct hw *me)
170{
171 struct hw_property_data **delete_point = &me->properties_of_hw;
172 while (*delete_point != NULL)
173 {
174 struct hw_property_data *current = *delete_point;
175 switch (current->property->disposition)
176 {
177 case permenant_object:
178 /* zap the current value, will be initialized later */
179 ASSERT (current->init_array != NULL);
180 if (current->property->array != NULL)
181 {
182 hw_free (me, (void*)current->property->array);
183 current->property->array = NULL;
184 }
185 delete_point = &(*delete_point)->next;
186 break;
187 case temporary_object:
188 /* zap the actual property, was created during simulation run */
189 ASSERT (current->init_array == NULL);
190 *delete_point = current->next;
191 if (current->property->array != NULL)
192 hw_free (me, (void*)current->property->array);
193 hw_free (me, current->property);
194 hw_free (me, current);
195 break;
196 }
197 }
198}
199#endif
200
201#if 0
202void
203hw_init_static_properties (SIM_DESC sd,
204 struct hw *me,
205 void *data)
206{
207 struct hw_property_data *property;
208 for (property = me->properties_of_hw;
209 property != NULL;
210 property = property->next)
211 {
212 ASSERT (property->init_array != NULL);
213 ASSERT (property->property->array == NULL);
34b47c38 214 ASSERT (property->property->disposition == permenant_object);
c906108c
SS
215 switch (property->property->type)
216 {
217 case array_property:
218 case boolean_property:
219 case range_array_property:
220 case reg_array_property:
221 case string_property:
222 case string_array_property:
223 case integer_property:
224 /* delete the property, and replace it with the original */
225 hw_set_property (me, property->property->name,
226 property->property->type,
227 property->init_array,
228 property->sizeof_init_array);
229 break;
230#if 0
231 case ihandle_property:
232 break;
233#endif
234 }
235 }
236}
237#endif
238
239
240#if 0
241void
242hw_init_runtime_properties (SIM_DESC sd,
243 struct hw *me,
244 void *data)
245{
246 struct hw_property_data *property;
247 for (property = me->properties_of_hw;
248 property != NULL;
249 property = property->next)
250 {
251 switch (property->property->disposition)
252 {
253 case permenant_object:
254 switch (property->property->type)
255 {
256#if 0
257 case ihandle_property:
258 {
259 struct hw_instance *ihandle;
260 ihandle_runtime_property_spec spec;
261 ASSERT (property->init_array != NULL);
262 ASSERT (property->property->array == NULL);
263 hw_find_ihandle_runtime_property (me, property->property->name, &spec);
264 ihandle = tree_instance (me, spec.full_path);
265 hw_set_ihandle_property (me, property->property->name, ihandle);
266 break;
267 }
268#endif
269 case array_property:
270 case boolean_property:
271 case range_array_property:
272 case integer_property:
273 case reg_array_property:
274 case string_property:
275 case string_array_property:
276 ASSERT (property->init_array != NULL);
277 ASSERT (property->property->array != NULL);
278 break;
279 }
280 break;
281 case temporary_object:
282 ASSERT (property->init_array == NULL);
283 ASSERT (property->property->array != NULL);
284 break;
285 }
286 }
287}
288#endif
289
290
291
292const struct hw_property *
293hw_next_property (const struct hw_property *property)
294{
295 /* find the property in the list */
296 struct hw *owner = property->owner;
297 struct hw_property_data *entry = owner->properties_of_hw;
298 while (entry != NULL && entry->property != property)
299 entry = entry->next;
300 /* now return the following property */
301 ASSERT (entry != NULL); /* must be a member! */
302 if (entry->next != NULL)
303 return entry->next->property;
304 else
305 return NULL;
306}
307
308
309const struct hw_property *
310hw_find_property (struct hw *me,
311 const char *property)
312{
313 if (me == NULL)
314 {
315 return NULL;
316 }
317 else if (property == NULL || strcmp (property, "") == 0)
318 {
319 if (me->properties_of_hw == NULL)
320 return NULL;
321 else
322 return me->properties_of_hw->property;
323 }
324 else
325 {
326 struct hw_property_data *entry = find_property_data (me, property);
327 if (entry != NULL)
328 return entry->property;
329 }
330 return NULL;
331}
332
333
334void
335hw_add_array_property (struct hw *me,
336 const char *property,
337 const void *array,
338 int sizeof_array)
339{
340 hw_add_property (me, property, array_property,
341 array, sizeof_array, array, sizeof_array,
342 NULL, permenant_object);
343}
344
345void
346hw_set_array_property (struct hw *me,
347 const char *property,
348 const void *array,
349 int sizeof_array)
350{
351 hw_set_property (me, property, array_property, array, sizeof_array);
352}
353
354const struct hw_property *
355hw_find_array_property (struct hw *me,
356 const char *property)
357{
358 const struct hw_property *node;
359 node = hw_find_property (me, property);
360 if (node == NULL)
361 hw_abort (me, "property \"%s\" not found", property);
362 if (node->type != array_property)
363 hw_abort (me, "property \"%s\" of wrong type (array)", property);
364 return node;
365}
366
367
368
369void
370hw_add_boolean_property (struct hw *me,
371 const char *property,
372 int boolean)
373{
374 signed32 new_boolean = (boolean ? -1 : 0);
375 hw_add_property (me, property, boolean_property,
34b47c38
MF
376 &new_boolean, sizeof (new_boolean),
377 &new_boolean, sizeof (new_boolean),
c906108c
SS
378 NULL, permenant_object);
379}
380
381int
382hw_find_boolean_property (struct hw *me,
383 const char *property)
384{
385 const struct hw_property *node;
386 unsigned_cell boolean;
387 node = hw_find_property (me, property);
388 if (node == NULL)
389 hw_abort (me, "property \"%s\" not found", property);
390 if (node->type != boolean_property)
391 hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
392 ASSERT (sizeof (boolean) == node->sizeof_array);
393 memcpy (&boolean, node->array, sizeof (boolean));
394 return boolean;
395}
396
397
398
399#if 0
400void
401hw_add_ihandle_runtime_property (struct hw *me,
402 const char *property,
403 const ihandle_runtime_property_spec *ihandle)
404{
405 /* enter the full path as the init array */
406 hw_add_property (me, property, ihandle_property,
34b47c38 407 ihandle->full_path, strlen (ihandle->full_path) + 1,
c906108c
SS
408 NULL, 0,
409 NULL, permenant_object);
410}
411#endif
412
413#if 0
414void
415hw_find_ihandle_runtime_property (struct hw *me,
416 const char *property,
417 ihandle_runtime_property_spec *ihandle)
418{
419 struct hw_property_data *entry = find_property_data (me, property);
c906108c
SS
420 if (entry == NULL)
421 hw_abort (me, "property \"%s\" not found", property);
422 if (entry->property->type != ihandle_property
423 || entry->property->disposition != permenant_object)
424 hw_abort (me, "property \"%s\" of wrong type", property);
425 ASSERT (entry->init_array != NULL);
426 /* the full path */
427 ihandle->full_path = entry->init_array;
428}
429#endif
430
431
432
433#if 0
434void
435hw_set_ihandle_property (struct hw *me,
436 const char *property,
437 hw_instance *ihandle)
438{
439 unsigned_cell cells;
440 cells = H2BE_cell (hw_instance_to_external (ihandle));
441 hw_set_property (me, property, ihandle_property,
442 &cells, sizeof (cells));
028f6515 443
c906108c
SS
444}
445#endif
446
447#if 0
448hw_instance *
449hw_find_ihandle_property (struct hw *me,
450 const char *property)
451{
452 const hw_property_data *node;
453 unsigned_cell ihandle;
454 hw_instance *instance;
455
456 node = hw_find_property (me, property);
457 if (node == NULL)
458 hw_abort (me, "property \"%s\" not found", property);
459 if (node->type != ihandle_property)
34b47c38 460 hw_abort (me, "property \"%s\" of wrong type (ihandle)", property);
c906108c 461 if (node->array == NULL)
34b47c38 462 hw_abort (me, "runtime property \"%s\" not yet initialized", property);
c906108c 463
34b47c38
MF
464 ASSERT (sizeof (ihandle) == node->sizeof_array);
465 memcpy (&ihandle, node->array, sizeof (ihandle));
466 instance = external_to_hw_instance (me, BE2H_cell (ihandle));
c906108c
SS
467 ASSERT (instance != NULL);
468 return instance;
469}
470#endif
471
472
473void
474hw_add_integer_property (struct hw *me,
475 const char *property,
476 signed_cell integer)
477{
478 H2BE (integer);
479 hw_add_property (me, property, integer_property,
34b47c38
MF
480 &integer, sizeof (integer),
481 &integer, sizeof (integer),
c906108c
SS
482 NULL, permenant_object);
483}
484
485signed_cell
486hw_find_integer_property (struct hw *me,
487 const char *property)
488{
489 const struct hw_property *node;
490 signed_cell integer;
c906108c
SS
491 node = hw_find_property (me, property);
492 if (node == NULL)
493 hw_abort (me, "property \"%s\" not found", property);
494 if (node->type != integer_property)
495 hw_abort (me, "property \"%s\" of wrong type (integer)", property);
34b47c38 496 ASSERT (sizeof (integer) == node->sizeof_array);
c906108c
SS
497 memcpy (&integer, node->array, sizeof (integer));
498 return BE2H_cell (integer);
499}
500
501int
502hw_find_integer_array_property (struct hw *me,
503 const char *property,
504 unsigned index,
505 signed_cell *integer)
506{
507 const struct hw_property *node;
508 int sizeof_integer = sizeof (*integer);
509 signed_cell *cell;
028f6515 510
c906108c
SS
511 /* check things sane */
512 node = hw_find_property (me, property);
513 if (node == NULL)
514 hw_abort (me, "property \"%s\" not found", property);
515 if (node->type != integer_property
516 && node->type != array_property)
517 hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
518 if ((node->sizeof_array % sizeof_integer) != 0)
519 hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
520 if (node->sizeof_array <= sizeof_integer * index)
521 return 0;
028f6515 522
c906108c
SS
523 /* Find and convert the value */
524 cell = ((signed_cell*)node->array) + index;
525 *integer = BE2H_cell (*cell);
028f6515 526
c906108c
SS
527 return node->sizeof_array / sizeof_integer;
528}
529
530
531static unsigned_cell *
532unit_address_to_cells (const hw_unit *unit,
533 unsigned_cell *cell,
534 int nr_cells)
535{
536 int i;
34b47c38 537 ASSERT (nr_cells == unit->nr_cells);
c906108c
SS
538 for (i = 0; i < unit->nr_cells; i++)
539 {
540 *cell = H2BE_cell (unit->cells[i]);
541 cell += 1;
542 }
543 return cell;
544}
545
546
547static const unsigned_cell *
548cells_to_unit_address (const unsigned_cell *cell,
549 hw_unit *unit,
550 int nr_cells)
551{
552 int i;
34b47c38 553 memset (unit, 0, sizeof (*unit));
c906108c
SS
554 unit->nr_cells = nr_cells;
555 for (i = 0; i < unit->nr_cells; i++)
556 {
557 unit->cells[i] = BE2H_cell (*cell);
558 cell += 1;
559 }
560 return cell;
561}
562
563
564static unsigned
565nr_range_property_cells (struct hw *me,
566 int nr_ranges)
567{
568 return ((hw_unit_nr_address_cells (me)
569 + hw_unit_nr_address_cells (hw_parent (me))
570 + hw_unit_nr_size_cells (me))
571 ) * nr_ranges;
572}
573
574void
575hw_add_range_array_property (struct hw *me,
576 const char *property,
577 const range_property_spec *ranges,
578 unsigned nr_ranges)
579{
580 unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
581 * sizeof (unsigned_cell));
582 unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
583 unsigned_cell *cell;
584 int i;
028f6515 585
c906108c
SS
586 /* copy the property elements over */
587 cell = cells;
588 for (i = 0; i < nr_ranges; i++)
589 {
590 const range_property_spec *range = &ranges[i];
591 /* copy the child address */
592 cell = unit_address_to_cells (&range->child_address, cell,
593 hw_unit_nr_address_cells (me));
594 /* copy the parent address */
028f6515 595 cell = unit_address_to_cells (&range->parent_address, cell,
c906108c
SS
596 hw_unit_nr_address_cells (hw_parent (me)));
597 /* copy the size */
028f6515 598 cell = unit_address_to_cells (&range->size, cell,
c906108c
SS
599 hw_unit_nr_size_cells (me));
600 }
601 ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
028f6515 602
c906108c
SS
603 /* add it */
604 hw_add_property (me, property, range_array_property,
605 cells, sizeof_cells,
606 cells, sizeof_cells,
607 NULL, permenant_object);
028f6515 608
c906108c
SS
609 hw_free (me, cells);
610}
611
612int
613hw_find_range_array_property (struct hw *me,
614 const char *property,
615 unsigned index,
616 range_property_spec *range)
617{
618 const struct hw_property *node;
619 unsigned sizeof_entry = (nr_range_property_cells (me, 1)
620 * sizeof (unsigned_cell));
621 const unsigned_cell *cells;
028f6515 622
c906108c
SS
623 /* locate the property */
624 node = hw_find_property (me, property);
625 if (node == NULL)
626 hw_abort (me, "property \"%s\" not found", property);
627 if (node->type != range_array_property)
628 hw_abort (me, "property \"%s\" of wrong type (range array)", property);
028f6515 629
c906108c
SS
630 /* aligned ? */
631 if ((node->sizeof_array % sizeof_entry) != 0)
632 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
633 property);
028f6515 634
c906108c
SS
635 /* within bounds? */
636 if (node->sizeof_array < sizeof_entry * (index + 1))
637 return 0;
028f6515 638
c906108c
SS
639 /* find the range of interest */
640 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
028f6515 641
c906108c
SS
642 /* copy the child address out - converting as we go */
643 cells = cells_to_unit_address (cells, &range->child_address,
644 hw_unit_nr_address_cells (me));
028f6515 645
c906108c
SS
646 /* copy the parent address out - converting as we go */
647 cells = cells_to_unit_address (cells, &range->parent_address,
648 hw_unit_nr_address_cells (hw_parent (me)));
028f6515 649
c906108c
SS
650 /* copy the size - converting as we go */
651 cells = cells_to_unit_address (cells, &range->size,
652 hw_unit_nr_size_cells (me));
028f6515 653
c906108c
SS
654 return node->sizeof_array / sizeof_entry;
655}
656
657
658static unsigned
659nr_reg_property_cells (struct hw *me,
660 int nr_regs)
661{
34b47c38
MF
662 return (hw_unit_nr_address_cells (hw_parent (me))
663 + hw_unit_nr_size_cells (hw_parent (me))
c906108c
SS
664 ) * nr_regs;
665}
666
667void
668hw_add_reg_array_property (struct hw *me,
669 const char *property,
670 const reg_property_spec *regs,
671 unsigned nr_regs)
672{
673 unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
674 * sizeof (unsigned_cell));
675 unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
676 unsigned_cell *cell;
677 int i;
028f6515 678
c906108c
SS
679 /* copy the property elements over */
680 cell = cells;
681 for (i = 0; i < nr_regs; i++)
682 {
683 const reg_property_spec *reg = &regs[i];
684 /* copy the address */
685 cell = unit_address_to_cells (&reg->address, cell,
686 hw_unit_nr_address_cells (hw_parent (me)));
687 /* copy the size */
688 cell = unit_address_to_cells (&reg->size, cell,
689 hw_unit_nr_size_cells (hw_parent (me)));
690 }
691 ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);
028f6515 692
c906108c
SS
693 /* add it */
694 hw_add_property (me, property, reg_array_property,
695 cells, sizeof_cells,
696 cells, sizeof_cells,
697 NULL, permenant_object);
028f6515 698
c906108c
SS
699 hw_free (me, cells);
700}
701
702int
703hw_find_reg_array_property (struct hw *me,
704 const char *property,
705 unsigned index,
706 reg_property_spec *reg)
707{
708 const struct hw_property *node;
709 unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
710 * sizeof (unsigned_cell));
711 const unsigned_cell *cells;
028f6515 712
c906108c
SS
713 /* locate the property */
714 node = hw_find_property (me, property);
715 if (node == NULL)
716 hw_abort (me, "property \"%s\" not found", property);
717 if (node->type != reg_array_property)
718 hw_abort (me, "property \"%s\" of wrong type (reg array)", property);
028f6515 719
c906108c
SS
720 /* aligned ? */
721 if ((node->sizeof_array % sizeof_entry) != 0)
722 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
723 property);
028f6515 724
c906108c
SS
725 /* within bounds? */
726 if (node->sizeof_array < sizeof_entry * (index + 1))
727 return 0;
028f6515 728
c906108c
SS
729 /* find the range of interest */
730 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
028f6515 731
c906108c
SS
732 /* copy the address out - converting as we go */
733 cells = cells_to_unit_address (cells, &reg->address,
734 hw_unit_nr_address_cells (hw_parent (me)));
028f6515 735
c906108c
SS
736 /* copy the size out - converting as we go */
737 cells = cells_to_unit_address (cells, &reg->size,
738 hw_unit_nr_size_cells (hw_parent (me)));
028f6515 739
c906108c
SS
740 return node->sizeof_array / sizeof_entry;
741}
742
743
744void
745hw_add_string_property (struct hw *me,
746 const char *property,
747 const char *string)
748{
749 hw_add_property (me, property, string_property,
34b47c38
MF
750 string, strlen (string) + 1,
751 string, strlen (string) + 1,
c906108c
SS
752 NULL, permenant_object);
753}
754
755const char *
756hw_find_string_property (struct hw *me,
757 const char *property)
758{
759 const struct hw_property *node;
760 const char *string;
761 node = hw_find_property (me, property);
762 if (node == NULL)
763 hw_abort (me, "property \"%s\" not found", property);
764 if (node->type != string_property)
765 hw_abort (me, "property \"%s\" of wrong type (string)", property);
766 string = node->array;
34b47c38 767 ASSERT (strlen (string) + 1 == node->sizeof_array);
c906108c
SS
768 return string;
769}
770
771void
772hw_add_string_array_property (struct hw *me,
773 const char *property,
774 const string_property_spec *strings,
775 unsigned nr_strings)
776{
777 int sizeof_array;
778 int string_nr;
779 char *array;
780 char *chp;
781 if (nr_strings == 0)
782 hw_abort (me, "property \"%s\" must be non-null", property);
783 /* total up the size of the needed array */
784 for (sizeof_array = 0, string_nr = 0;
785 string_nr < nr_strings;
786 string_nr ++)
787 {
788 sizeof_array += strlen (strings[string_nr]) + 1;
789 }
790 /* create the array */
791 array = (char*) hw_zalloc (me, sizeof_array);
792 chp = array;
793 for (string_nr = 0;
794 string_nr < nr_strings;
795 string_nr++)
796 {
797 strcpy (chp, strings[string_nr]);
798 chp += strlen (chp) + 1;
799 }
800 ASSERT (chp == array + sizeof_array);
801 /* now enter it */
802 hw_add_property (me, property, string_array_property,
803 array, sizeof_array,
804 array, sizeof_array,
805 NULL, permenant_object);
806}
807
808int
809hw_find_string_array_property (struct hw *me,
810 const char *property,
811 unsigned index,
812 string_property_spec *string)
813{
814 const struct hw_property *node;
815 node = hw_find_property (me, property);
816 if (node == NULL)
817 hw_abort (me, "property \"%s\" not found", property);
818 switch (node->type)
819 {
820 default:
821 hw_abort (me, "property \"%s\" of wrong type", property);
822 break;
823 case string_property:
824 if (index == 0)
825 {
826 *string = node->array;
34b47c38 827 ASSERT (strlen (*string) + 1 == node->sizeof_array);
c906108c
SS
828 return 1;
829 }
830 break;
831 case array_property:
832 if (node->sizeof_array == 0
833 || ((char*)node->array)[node->sizeof_array - 1] != '\0')
834 hw_abort (me, "property \"%s\" invalid for string array", property);
835 /* FALL THROUGH */
836 case string_array_property:
837 ASSERT (node->sizeof_array > 0);
838 ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
839 {
840 const char *chp = node->array;
841 int nr_entries = 0;
842 /* count the number of strings, keeping an eye out for the one
843 we're looking for */
844 *string = chp;
845 do
846 {
847 if (*chp == '\0')
848 {
849 /* next string */
850 nr_entries++;
851 chp++;
852 if (nr_entries == index)
853 *string = chp;
854 }
855 else
856 {
857 chp++;
858 }
859 } while (chp < (char*)node->array + node->sizeof_array);
860 if (index < nr_entries)
861 return nr_entries;
862 else
863 {
864 *string = NULL;
865 return 0;
866 }
867 }
868 break;
869 }
870 return 0;
871}
872
873void
874hw_add_duplicate_property (struct hw *me,
875 const char *property,
876 const struct hw_property *original)
877{
878 struct hw_property_data *master;
c906108c
SS
879 if (original->disposition != permenant_object)
880 hw_abort (me, "Can only duplicate permenant objects");
881 /* find the original's master */
882 master = original->owner->properties_of_hw;
883 while (master->property != original)
884 {
885 master = master->next;
34b47c38 886 ASSERT (master != NULL);
c906108c
SS
887 }
888 /* now duplicate it */
889 hw_add_property (me, property,
890 original->type,
891 master->init_array, master->sizeof_init_array,
892 original->array, original->sizeof_array,
893 original, permenant_object);
894}
This page took 1.054313 seconds and 4 git commands to generate.