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