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