b46f2955404ca7b5d376392e66c50aa796274f8a
[deliverable/binutils-gdb.git] / sim / common / hw-properties.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #include "sim-main.h"
22 #include "hw-base.h"
23
24 #include "sim-assert.h"
25
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #else
29 #ifdef HAVE_STRINGS_H
30 #include <strings.h>
31 #endif
32 #endif
33
34 #define TRACE(A,B)
35
36 /* property entries */
37
38 struct hw_property_data {
39 struct hw_property_data *next;
40 struct hw_property *property;
41 const void *init_array;
42 unsigned sizeof_init_array;
43 };
44
45 /* Device Properties: */
46
47 static struct hw_property_data *
48 find_property_data (struct hw *me,
49 const char *property)
50 {
51 struct hw_property_data *entry;
52 ASSERT (property != NULL);
53 entry = me->properties_of_hw;
54 while (entry != NULL)
55 {
56 if (strcmp (entry->property->name, property) == 0)
57 return entry;
58 entry = entry->next;
59 }
60 return NULL;
61 }
62
63
64 static void
65 hw_add_property (struct hw *me,
66 const char *property,
67 hw_property_type type,
68 const void *init_array,
69 unsigned sizeof_init_array,
70 const void *array,
71 unsigned sizeof_array,
72 const struct hw_property *original,
73 object_disposition disposition)
74 {
75 struct hw_property_data *new_entry = NULL;
76 struct hw_property *new_value = NULL;
77
78 /* find the list end */
79 struct hw_property_data **insertion_point = &me->properties_of_hw;
80 while (*insertion_point != NULL)
81 {
82 if (strcmp ((*insertion_point)->property->name, property) == 0)
83 return;
84 insertion_point = &(*insertion_point)->next;
85 }
86
87 /* create a new value */
88 new_value = HW_ZALLOC (me, struct hw_property);
89 new_value->name = (char *) strdup (property);
90 new_value->type = type;
91 if (sizeof_array > 0)
92 {
93 void *new_array = hw_zalloc (me, sizeof_array);
94 memcpy (new_array, array, sizeof_array);
95 new_value->array = new_array;
96 new_value->sizeof_array = sizeof_array;
97 }
98 new_value->owner = me;
99 new_value->original = original;
100 new_value->disposition = disposition;
101
102 /* insert the value into the list */
103 new_entry = HW_ZALLOC (me, struct hw_property_data);
104 *insertion_point = new_entry;
105 if (sizeof_init_array > 0)
106 {
107 void *new_init_array = hw_zalloc (me, sizeof_init_array);
108 memcpy (new_init_array, init_array, sizeof_init_array);
109 new_entry->init_array = new_init_array;
110 new_entry->sizeof_init_array = sizeof_init_array;
111 }
112 new_entry->property = new_value;
113 }
114
115
116 static void
117 hw_set_property (struct hw *me,
118 const char *property,
119 hw_property_type type,
120 const void *array,
121 int sizeof_array)
122 {
123 /* find the property */
124 struct hw_property_data *entry = find_property_data (me, property);
125 if (entry != NULL)
126 {
127 /* existing property - update it */
128 void *new_array = 0;
129 struct hw_property *value = entry->property;
130 /* check the type matches */
131 if (value->type != type)
132 hw_abort (me, "conflict between type of new and old value for property %s", property);
133 /* replace its value */
134 if (value->array != NULL)
135 hw_free (me, (void*)value->array);
136 new_array = (sizeof_array > 0
137 ? hw_zalloc (me, sizeof_array)
138 : (void*)0);
139 value->array = new_array;
140 value->sizeof_array = sizeof_array;
141 if (sizeof_array > 0)
142 memcpy (new_array, array, sizeof_array);
143 return;
144 }
145 else
146 {
147 /* new property - create it */
148 hw_add_property (me, property, type,
149 NULL, 0, array, sizeof_array,
150 NULL, temporary_object);
151 }
152 }
153
154
155 #if 0
156 static void
157 clean_hw_properties (struct hw *me)
158 {
159 struct hw_property_data **delete_point = &me->properties_of_hw;
160 while (*delete_point != NULL)
161 {
162 struct hw_property_data *current = *delete_point;
163 switch (current->property->disposition)
164 {
165 case permenant_object:
166 /* zap the current value, will be initialized later */
167 ASSERT (current->init_array != NULL);
168 if (current->property->array != NULL)
169 {
170 hw_free (me, (void*)current->property->array);
171 current->property->array = NULL;
172 }
173 delete_point = &(*delete_point)->next;
174 break;
175 case temporary_object:
176 /* zap the actual property, was created during simulation run */
177 ASSERT (current->init_array == NULL);
178 *delete_point = current->next;
179 if (current->property->array != NULL)
180 hw_free (me, (void*)current->property->array);
181 hw_free (me, current->property);
182 hw_free (me, current);
183 break;
184 }
185 }
186 }
187 #endif
188
189 #if 0
190 void
191 hw_init_static_properties (SIM_DESC sd,
192 struct hw *me,
193 void *data)
194 {
195 struct hw_property_data *property;
196 for (property = me->properties_of_hw;
197 property != NULL;
198 property = property->next)
199 {
200 ASSERT (property->init_array != NULL);
201 ASSERT (property->property->array == NULL);
202 ASSERT(property->property->disposition == permenant_object);
203 switch (property->property->type)
204 {
205 case array_property:
206 case boolean_property:
207 case range_array_property:
208 case reg_array_property:
209 case string_property:
210 case string_array_property:
211 case integer_property:
212 /* delete the property, and replace it with the original */
213 hw_set_property (me, property->property->name,
214 property->property->type,
215 property->init_array,
216 property->sizeof_init_array);
217 break;
218 #if 0
219 case ihandle_property:
220 break;
221 #endif
222 }
223 }
224 }
225 #endif
226
227
228 #if 0
229 void
230 hw_init_runtime_properties (SIM_DESC sd,
231 struct hw *me,
232 void *data)
233 {
234 struct hw_property_data *property;
235 for (property = me->properties_of_hw;
236 property != NULL;
237 property = property->next)
238 {
239 switch (property->property->disposition)
240 {
241 case permenant_object:
242 switch (property->property->type)
243 {
244 #if 0
245 case ihandle_property:
246 {
247 struct hw_instance *ihandle;
248 ihandle_runtime_property_spec spec;
249 ASSERT (property->init_array != NULL);
250 ASSERT (property->property->array == NULL);
251 hw_find_ihandle_runtime_property (me, property->property->name, &spec);
252 ihandle = tree_instance (me, spec.full_path);
253 hw_set_ihandle_property (me, property->property->name, ihandle);
254 break;
255 }
256 #endif
257 case array_property:
258 case boolean_property:
259 case range_array_property:
260 case integer_property:
261 case reg_array_property:
262 case string_property:
263 case string_array_property:
264 ASSERT (property->init_array != NULL);
265 ASSERT (property->property->array != NULL);
266 break;
267 }
268 break;
269 case temporary_object:
270 ASSERT (property->init_array == NULL);
271 ASSERT (property->property->array != NULL);
272 break;
273 }
274 }
275 }
276 #endif
277
278
279
280 const struct hw_property *
281 hw_next_property (const struct hw_property *property)
282 {
283 /* find the property in the list */
284 struct hw *owner = property->owner;
285 struct hw_property_data *entry = owner->properties_of_hw;
286 while (entry != NULL && entry->property != property)
287 entry = entry->next;
288 /* now return the following property */
289 ASSERT (entry != NULL); /* must be a member! */
290 if (entry->next != NULL)
291 return entry->next->property;
292 else
293 return NULL;
294 }
295
296
297 const struct hw_property *
298 hw_find_property (struct hw *me,
299 const char *property)
300 {
301 if (me == NULL)
302 {
303 return NULL;
304 }
305 else if (property == NULL || strcmp (property, "") == 0)
306 {
307 if (me->properties_of_hw == NULL)
308 return NULL;
309 else
310 return me->properties_of_hw->property;
311 }
312 else
313 {
314 struct hw_property_data *entry = find_property_data (me, property);
315 if (entry != NULL)
316 return entry->property;
317 }
318 return NULL;
319 }
320
321
322 void
323 hw_add_array_property (struct hw *me,
324 const char *property,
325 const void *array,
326 int sizeof_array)
327 {
328 hw_add_property (me, property, array_property,
329 array, sizeof_array, array, sizeof_array,
330 NULL, permenant_object);
331 }
332
333 void
334 hw_set_array_property (struct hw *me,
335 const char *property,
336 const void *array,
337 int sizeof_array)
338 {
339 hw_set_property (me, property, array_property, array, sizeof_array);
340 }
341
342 const struct hw_property *
343 hw_find_array_property (struct hw *me,
344 const char *property)
345 {
346 const struct hw_property *node;
347 node = hw_find_property (me, property);
348 if (node == NULL)
349 hw_abort (me, "property \"%s\" not found", property);
350 if (node->type != array_property)
351 hw_abort (me, "property \"%s\" of wrong type (array)", property);
352 return node;
353 }
354
355
356
357 void
358 hw_add_boolean_property (struct hw *me,
359 const char *property,
360 int boolean)
361 {
362 signed32 new_boolean = (boolean ? -1 : 0);
363 hw_add_property (me, property, boolean_property,
364 &new_boolean, sizeof(new_boolean),
365 &new_boolean, sizeof(new_boolean),
366 NULL, permenant_object);
367 }
368
369 int
370 hw_find_boolean_property (struct hw *me,
371 const char *property)
372 {
373 const struct hw_property *node;
374 unsigned_cell boolean;
375 node = hw_find_property (me, property);
376 if (node == NULL)
377 hw_abort (me, "property \"%s\" not found", property);
378 if (node->type != boolean_property)
379 hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
380 ASSERT (sizeof (boolean) == node->sizeof_array);
381 memcpy (&boolean, node->array, sizeof (boolean));
382 return boolean;
383 }
384
385
386
387 #if 0
388 void
389 hw_add_ihandle_runtime_property (struct hw *me,
390 const char *property,
391 const ihandle_runtime_property_spec *ihandle)
392 {
393 /* enter the full path as the init array */
394 hw_add_property (me, property, ihandle_property,
395 ihandle->full_path, strlen(ihandle->full_path) + 1,
396 NULL, 0,
397 NULL, permenant_object);
398 }
399 #endif
400
401 #if 0
402 void
403 hw_find_ihandle_runtime_property (struct hw *me,
404 const char *property,
405 ihandle_runtime_property_spec *ihandle)
406 {
407 struct hw_property_data *entry = find_property_data (me, property);
408 TRACE (trace_devices,
409 ("hw_find_ihandle_runtime_property(me=0x%lx, property=%s)\n",
410 (long)me, property));
411 if (entry == NULL)
412 hw_abort (me, "property \"%s\" not found", property);
413 if (entry->property->type != ihandle_property
414 || entry->property->disposition != permenant_object)
415 hw_abort (me, "property \"%s\" of wrong type", property);
416 ASSERT (entry->init_array != NULL);
417 /* the full path */
418 ihandle->full_path = entry->init_array;
419 }
420 #endif
421
422
423
424 #if 0
425 void
426 hw_set_ihandle_property (struct hw *me,
427 const char *property,
428 hw_instance *ihandle)
429 {
430 unsigned_cell cells;
431 cells = H2BE_cell (hw_instance_to_external (ihandle));
432 hw_set_property (me, property, ihandle_property,
433 &cells, sizeof (cells));
434
435 }
436 #endif
437
438 #if 0
439 hw_instance *
440 hw_find_ihandle_property (struct hw *me,
441 const char *property)
442 {
443 const hw_property_data *node;
444 unsigned_cell ihandle;
445 hw_instance *instance;
446
447 node = hw_find_property (me, property);
448 if (node == NULL)
449 hw_abort (me, "property \"%s\" not found", property);
450 if (node->type != ihandle_property)
451 hw_abort(me, "property \"%s\" of wrong type (ihandle)", property);
452 if (node->array == NULL)
453 hw_abort(me, "runtime property \"%s\" not yet initialized", property);
454
455 ASSERT (sizeof(ihandle) == node->sizeof_array);
456 memcpy (&ihandle, node->array, sizeof(ihandle));
457 instance = external_to_hw_instance (me, BE2H_cell(ihandle));
458 ASSERT (instance != NULL);
459 return instance;
460 }
461 #endif
462
463
464 void
465 hw_add_integer_property (struct hw *me,
466 const char *property,
467 signed_cell integer)
468 {
469 H2BE (integer);
470 hw_add_property (me, property, integer_property,
471 &integer, sizeof(integer),
472 &integer, sizeof(integer),
473 NULL, permenant_object);
474 }
475
476 signed_cell
477 hw_find_integer_property (struct hw *me,
478 const char *property)
479 {
480 const struct hw_property *node;
481 signed_cell integer;
482 TRACE (trace_devices,
483 ("hw_find_integer(me=0x%lx, property=%s)\n",
484 (long)me, property));
485 node = hw_find_property (me, property);
486 if (node == NULL)
487 hw_abort (me, "property \"%s\" not found", property);
488 if (node->type != integer_property)
489 hw_abort (me, "property \"%s\" of wrong type (integer)", property);
490 ASSERT (sizeof(integer) == node->sizeof_array);
491 memcpy (&integer, node->array, sizeof (integer));
492 return BE2H_cell (integer);
493 }
494
495 int
496 hw_find_integer_array_property (struct hw *me,
497 const char *property,
498 unsigned index,
499 signed_cell *integer)
500 {
501 const struct hw_property *node;
502 int sizeof_integer = sizeof (*integer);
503 signed_cell *cell;
504 TRACE (trace_devices,
505 ("hw_find_integer(me=0x%lx, property=%s)\n",
506 (long)me, property));
507
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;
519
520 /* Find and convert the value */
521 cell = ((signed_cell*)node->array) + index;
522 *integer = BE2H_cell (*cell);
523
524 return node->sizeof_array / sizeof_integer;
525 }
526
527
528 static unsigned_cell *
529 unit_address_to_cells (const hw_unit *unit,
530 unsigned_cell *cell,
531 int nr_cells)
532 {
533 int i;
534 ASSERT(nr_cells == unit->nr_cells);
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
544 static const unsigned_cell *
545 cells_to_unit_address (const unsigned_cell *cell,
546 hw_unit *unit,
547 int nr_cells)
548 {
549 int i;
550 memset(unit, 0, sizeof(*unit));
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
561 static unsigned
562 nr_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
571 void
572 hw_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;
582
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 */
592 cell = unit_address_to_cells (&range->parent_address, cell,
593 hw_unit_nr_address_cells (hw_parent (me)));
594 /* copy the size */
595 cell = unit_address_to_cells (&range->size, cell,
596 hw_unit_nr_size_cells (me));
597 }
598 ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
599
600 /* add it */
601 hw_add_property (me, property, range_array_property,
602 cells, sizeof_cells,
603 cells, sizeof_cells,
604 NULL, permenant_object);
605
606 hw_free (me, cells);
607 }
608
609 int
610 hw_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;
619
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);
626
627 /* aligned ? */
628 if ((node->sizeof_array % sizeof_entry) != 0)
629 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
630 property);
631
632 /* within bounds? */
633 if (node->sizeof_array < sizeof_entry * (index + 1))
634 return 0;
635
636 /* find the range of interest */
637 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
638
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));
642
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)));
646
647 /* copy the size - converting as we go */
648 cells = cells_to_unit_address (cells, &range->size,
649 hw_unit_nr_size_cells (me));
650
651 return node->sizeof_array / sizeof_entry;
652 }
653
654
655 static unsigned
656 nr_reg_property_cells (struct hw *me,
657 int nr_regs)
658 {
659 return (hw_unit_nr_address_cells (hw_parent(me))
660 + hw_unit_nr_size_cells (hw_parent(me))
661 ) * nr_regs;
662 }
663
664 void
665 hw_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;
675
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)]);
689
690 /* add it */
691 hw_add_property (me, property, reg_array_property,
692 cells, sizeof_cells,
693 cells, sizeof_cells,
694 NULL, permenant_object);
695
696 hw_free (me, cells);
697 }
698
699 int
700 hw_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;
709
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);
716
717 /* aligned ? */
718 if ((node->sizeof_array % sizeof_entry) != 0)
719 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
720 property);
721
722 /* within bounds? */
723 if (node->sizeof_array < sizeof_entry * (index + 1))
724 return 0;
725
726 /* find the range of interest */
727 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
728
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)));
732
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)));
736
737 return node->sizeof_array / sizeof_entry;
738 }
739
740
741 void
742 hw_add_string_property (struct hw *me,
743 const char *property,
744 const char *string)
745 {
746 hw_add_property (me, property, string_property,
747 string, strlen(string) + 1,
748 string, strlen(string) + 1,
749 NULL, permenant_object);
750 }
751
752 const char *
753 hw_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;
764 ASSERT (strlen(string) + 1 == node->sizeof_array);
765 return string;
766 }
767
768 void
769 hw_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
805 int
806 hw_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;
824 ASSERT (strlen(*string) + 1 == node->sizeof_array);
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
870 void
871 hw_add_duplicate_property (struct hw *me,
872 const char *property,
873 const struct hw_property *original)
874 {
875 struct hw_property_data *master;
876 TRACE (trace_devices,
877 ("hw_add_duplicate_property(me=0x%lx, property=%s, ...)\n",
878 (long)me, property));
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;
886 ASSERT(master != NULL);
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 0.049816 seconds and 4 git commands to generate.