Copyright year update in most files of the GDB Project.
[deliverable/binutils-gdb.git] / sim / common / hw-properties.c
CommitLineData
b85e4829
AC
1/* The common simulator framework for GDB, the GNU Debugger.
2
c5a57081 3 Copyright 2002, 2007-2012 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);
6d519a46 420 HW_TRACE ((me, "hw_find_ihandle_runtime_property(property=%s)\n", property));
c906108c
SS
421 if (entry == NULL)
422 hw_abort (me, "property \"%s\" not found", property);
423 if (entry->property->type != ihandle_property
424 || entry->property->disposition != permenant_object)
425 hw_abort (me, "property \"%s\" of wrong type", property);
426 ASSERT (entry->init_array != NULL);
427 /* the full path */
428 ihandle->full_path = entry->init_array;
429}
430#endif
431
432
433
434#if 0
435void
436hw_set_ihandle_property (struct hw *me,
437 const char *property,
438 hw_instance *ihandle)
439{
440 unsigned_cell cells;
441 cells = H2BE_cell (hw_instance_to_external (ihandle));
442 hw_set_property (me, property, ihandle_property,
443 &cells, sizeof (cells));
028f6515 444
c906108c
SS
445}
446#endif
447
448#if 0
449hw_instance *
450hw_find_ihandle_property (struct hw *me,
451 const char *property)
452{
453 const hw_property_data *node;
454 unsigned_cell ihandle;
455 hw_instance *instance;
456
457 node = hw_find_property (me, property);
458 if (node == NULL)
459 hw_abort (me, "property \"%s\" not found", property);
460 if (node->type != ihandle_property)
34b47c38 461 hw_abort (me, "property \"%s\" of wrong type (ihandle)", property);
c906108c 462 if (node->array == NULL)
34b47c38 463 hw_abort (me, "runtime property \"%s\" not yet initialized", property);
c906108c 464
34b47c38
MF
465 ASSERT (sizeof (ihandle) == node->sizeof_array);
466 memcpy (&ihandle, node->array, sizeof (ihandle));
467 instance = external_to_hw_instance (me, BE2H_cell (ihandle));
c906108c
SS
468 ASSERT (instance != NULL);
469 return instance;
470}
471#endif
472
473
474void
475hw_add_integer_property (struct hw *me,
476 const char *property,
477 signed_cell integer)
478{
479 H2BE (integer);
480 hw_add_property (me, property, integer_property,
34b47c38
MF
481 &integer, sizeof (integer),
482 &integer, sizeof (integer),
c906108c
SS
483 NULL, permenant_object);
484}
485
486signed_cell
487hw_find_integer_property (struct hw *me,
488 const char *property)
489{
490 const struct hw_property *node;
491 signed_cell integer;
6d519a46 492 HW_TRACE ((me, "hw_find_integer(property=%s)\n", property));
c906108c
SS
493 node = hw_find_property (me, property);
494 if (node == NULL)
495 hw_abort (me, "property \"%s\" not found", property);
496 if (node->type != integer_property)
497 hw_abort (me, "property \"%s\" of wrong type (integer)", property);
34b47c38 498 ASSERT (sizeof (integer) == node->sizeof_array);
c906108c
SS
499 memcpy (&integer, node->array, sizeof (integer));
500 return BE2H_cell (integer);
501}
502
503int
504hw_find_integer_array_property (struct hw *me,
505 const char *property,
506 unsigned index,
507 signed_cell *integer)
508{
509 const struct hw_property *node;
510 int sizeof_integer = sizeof (*integer);
511 signed_cell *cell;
6d519a46 512 HW_TRACE ((me, "hw_find_integer(property=%s)\n", property));
028f6515 513
c906108c
SS
514 /* check things sane */
515 node = hw_find_property (me, property);
516 if (node == NULL)
517 hw_abort (me, "property \"%s\" not found", property);
518 if (node->type != integer_property
519 && node->type != array_property)
520 hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
521 if ((node->sizeof_array % sizeof_integer) != 0)
522 hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
523 if (node->sizeof_array <= sizeof_integer * index)
524 return 0;
028f6515 525
c906108c
SS
526 /* Find and convert the value */
527 cell = ((signed_cell*)node->array) + index;
528 *integer = BE2H_cell (*cell);
028f6515 529
c906108c
SS
530 return node->sizeof_array / sizeof_integer;
531}
532
533
534static unsigned_cell *
535unit_address_to_cells (const hw_unit *unit,
536 unsigned_cell *cell,
537 int nr_cells)
538{
539 int i;
34b47c38 540 ASSERT (nr_cells == unit->nr_cells);
c906108c
SS
541 for (i = 0; i < unit->nr_cells; i++)
542 {
543 *cell = H2BE_cell (unit->cells[i]);
544 cell += 1;
545 }
546 return cell;
547}
548
549
550static const unsigned_cell *
551cells_to_unit_address (const unsigned_cell *cell,
552 hw_unit *unit,
553 int nr_cells)
554{
555 int i;
34b47c38 556 memset (unit, 0, sizeof (*unit));
c906108c
SS
557 unit->nr_cells = nr_cells;
558 for (i = 0; i < unit->nr_cells; i++)
559 {
560 unit->cells[i] = BE2H_cell (*cell);
561 cell += 1;
562 }
563 return cell;
564}
565
566
567static unsigned
568nr_range_property_cells (struct hw *me,
569 int nr_ranges)
570{
571 return ((hw_unit_nr_address_cells (me)
572 + hw_unit_nr_address_cells (hw_parent (me))
573 + hw_unit_nr_size_cells (me))
574 ) * nr_ranges;
575}
576
577void
578hw_add_range_array_property (struct hw *me,
579 const char *property,
580 const range_property_spec *ranges,
581 unsigned nr_ranges)
582{
583 unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
584 * sizeof (unsigned_cell));
585 unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
586 unsigned_cell *cell;
587 int i;
028f6515 588
c906108c
SS
589 /* copy the property elements over */
590 cell = cells;
591 for (i = 0; i < nr_ranges; i++)
592 {
593 const range_property_spec *range = &ranges[i];
594 /* copy the child address */
595 cell = unit_address_to_cells (&range->child_address, cell,
596 hw_unit_nr_address_cells (me));
597 /* copy the parent address */
028f6515 598 cell = unit_address_to_cells (&range->parent_address, cell,
c906108c
SS
599 hw_unit_nr_address_cells (hw_parent (me)));
600 /* copy the size */
028f6515 601 cell = unit_address_to_cells (&range->size, cell,
c906108c
SS
602 hw_unit_nr_size_cells (me));
603 }
604 ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
028f6515 605
c906108c
SS
606 /* add it */
607 hw_add_property (me, property, range_array_property,
608 cells, sizeof_cells,
609 cells, sizeof_cells,
610 NULL, permenant_object);
028f6515 611
c906108c
SS
612 hw_free (me, cells);
613}
614
615int
616hw_find_range_array_property (struct hw *me,
617 const char *property,
618 unsigned index,
619 range_property_spec *range)
620{
621 const struct hw_property *node;
622 unsigned sizeof_entry = (nr_range_property_cells (me, 1)
623 * sizeof (unsigned_cell));
624 const unsigned_cell *cells;
028f6515 625
c906108c
SS
626 /* locate the property */
627 node = hw_find_property (me, property);
628 if (node == NULL)
629 hw_abort (me, "property \"%s\" not found", property);
630 if (node->type != range_array_property)
631 hw_abort (me, "property \"%s\" of wrong type (range array)", property);
028f6515 632
c906108c
SS
633 /* aligned ? */
634 if ((node->sizeof_array % sizeof_entry) != 0)
635 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
636 property);
028f6515 637
c906108c
SS
638 /* within bounds? */
639 if (node->sizeof_array < sizeof_entry * (index + 1))
640 return 0;
028f6515 641
c906108c
SS
642 /* find the range of interest */
643 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
028f6515 644
c906108c
SS
645 /* copy the child address out - converting as we go */
646 cells = cells_to_unit_address (cells, &range->child_address,
647 hw_unit_nr_address_cells (me));
028f6515 648
c906108c
SS
649 /* copy the parent address out - converting as we go */
650 cells = cells_to_unit_address (cells, &range->parent_address,
651 hw_unit_nr_address_cells (hw_parent (me)));
028f6515 652
c906108c
SS
653 /* copy the size - converting as we go */
654 cells = cells_to_unit_address (cells, &range->size,
655 hw_unit_nr_size_cells (me));
028f6515 656
c906108c
SS
657 return node->sizeof_array / sizeof_entry;
658}
659
660
661static unsigned
662nr_reg_property_cells (struct hw *me,
663 int nr_regs)
664{
34b47c38
MF
665 return (hw_unit_nr_address_cells (hw_parent (me))
666 + hw_unit_nr_size_cells (hw_parent (me))
c906108c
SS
667 ) * nr_regs;
668}
669
670void
671hw_add_reg_array_property (struct hw *me,
672 const char *property,
673 const reg_property_spec *regs,
674 unsigned nr_regs)
675{
676 unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
677 * sizeof (unsigned_cell));
678 unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
679 unsigned_cell *cell;
680 int i;
028f6515 681
c906108c
SS
682 /* copy the property elements over */
683 cell = cells;
684 for (i = 0; i < nr_regs; i++)
685 {
686 const reg_property_spec *reg = &regs[i];
687 /* copy the address */
688 cell = unit_address_to_cells (&reg->address, cell,
689 hw_unit_nr_address_cells (hw_parent (me)));
690 /* copy the size */
691 cell = unit_address_to_cells (&reg->size, cell,
692 hw_unit_nr_size_cells (hw_parent (me)));
693 }
694 ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);
028f6515 695
c906108c
SS
696 /* add it */
697 hw_add_property (me, property, reg_array_property,
698 cells, sizeof_cells,
699 cells, sizeof_cells,
700 NULL, permenant_object);
028f6515 701
c906108c
SS
702 hw_free (me, cells);
703}
704
705int
706hw_find_reg_array_property (struct hw *me,
707 const char *property,
708 unsigned index,
709 reg_property_spec *reg)
710{
711 const struct hw_property *node;
712 unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
713 * sizeof (unsigned_cell));
714 const unsigned_cell *cells;
028f6515 715
c906108c
SS
716 /* locate the property */
717 node = hw_find_property (me, property);
718 if (node == NULL)
719 hw_abort (me, "property \"%s\" not found", property);
720 if (node->type != reg_array_property)
721 hw_abort (me, "property \"%s\" of wrong type (reg array)", property);
028f6515 722
c906108c
SS
723 /* aligned ? */
724 if ((node->sizeof_array % sizeof_entry) != 0)
725 hw_abort (me, "property \"%s\" contains an incomplete number of entries",
726 property);
028f6515 727
c906108c
SS
728 /* within bounds? */
729 if (node->sizeof_array < sizeof_entry * (index + 1))
730 return 0;
028f6515 731
c906108c
SS
732 /* find the range of interest */
733 cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
028f6515 734
c906108c
SS
735 /* copy the address out - converting as we go */
736 cells = cells_to_unit_address (cells, &reg->address,
737 hw_unit_nr_address_cells (hw_parent (me)));
028f6515 738
c906108c
SS
739 /* copy the size out - converting as we go */
740 cells = cells_to_unit_address (cells, &reg->size,
741 hw_unit_nr_size_cells (hw_parent (me)));
028f6515 742
c906108c
SS
743 return node->sizeof_array / sizeof_entry;
744}
745
746
747void
748hw_add_string_property (struct hw *me,
749 const char *property,
750 const char *string)
751{
752 hw_add_property (me, property, string_property,
34b47c38
MF
753 string, strlen (string) + 1,
754 string, strlen (string) + 1,
c906108c
SS
755 NULL, permenant_object);
756}
757
758const char *
759hw_find_string_property (struct hw *me,
760 const char *property)
761{
762 const struct hw_property *node;
763 const char *string;
764 node = hw_find_property (me, property);
765 if (node == NULL)
766 hw_abort (me, "property \"%s\" not found", property);
767 if (node->type != string_property)
768 hw_abort (me, "property \"%s\" of wrong type (string)", property);
769 string = node->array;
34b47c38 770 ASSERT (strlen (string) + 1 == node->sizeof_array);
c906108c
SS
771 return string;
772}
773
774void
775hw_add_string_array_property (struct hw *me,
776 const char *property,
777 const string_property_spec *strings,
778 unsigned nr_strings)
779{
780 int sizeof_array;
781 int string_nr;
782 char *array;
783 char *chp;
784 if (nr_strings == 0)
785 hw_abort (me, "property \"%s\" must be non-null", property);
786 /* total up the size of the needed array */
787 for (sizeof_array = 0, string_nr = 0;
788 string_nr < nr_strings;
789 string_nr ++)
790 {
791 sizeof_array += strlen (strings[string_nr]) + 1;
792 }
793 /* create the array */
794 array = (char*) hw_zalloc (me, sizeof_array);
795 chp = array;
796 for (string_nr = 0;
797 string_nr < nr_strings;
798 string_nr++)
799 {
800 strcpy (chp, strings[string_nr]);
801 chp += strlen (chp) + 1;
802 }
803 ASSERT (chp == array + sizeof_array);
804 /* now enter it */
805 hw_add_property (me, property, string_array_property,
806 array, sizeof_array,
807 array, sizeof_array,
808 NULL, permenant_object);
809}
810
811int
812hw_find_string_array_property (struct hw *me,
813 const char *property,
814 unsigned index,
815 string_property_spec *string)
816{
817 const struct hw_property *node;
818 node = hw_find_property (me, property);
819 if (node == NULL)
820 hw_abort (me, "property \"%s\" not found", property);
821 switch (node->type)
822 {
823 default:
824 hw_abort (me, "property \"%s\" of wrong type", property);
825 break;
826 case string_property:
827 if (index == 0)
828 {
829 *string = node->array;
34b47c38 830 ASSERT (strlen (*string) + 1 == node->sizeof_array);
c906108c
SS
831 return 1;
832 }
833 break;
834 case array_property:
835 if (node->sizeof_array == 0
836 || ((char*)node->array)[node->sizeof_array - 1] != '\0')
837 hw_abort (me, "property \"%s\" invalid for string array", property);
838 /* FALL THROUGH */
839 case string_array_property:
840 ASSERT (node->sizeof_array > 0);
841 ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
842 {
843 const char *chp = node->array;
844 int nr_entries = 0;
845 /* count the number of strings, keeping an eye out for the one
846 we're looking for */
847 *string = chp;
848 do
849 {
850 if (*chp == '\0')
851 {
852 /* next string */
853 nr_entries++;
854 chp++;
855 if (nr_entries == index)
856 *string = chp;
857 }
858 else
859 {
860 chp++;
861 }
862 } while (chp < (char*)node->array + node->sizeof_array);
863 if (index < nr_entries)
864 return nr_entries;
865 else
866 {
867 *string = NULL;
868 return 0;
869 }
870 }
871 break;
872 }
873 return 0;
874}
875
876void
877hw_add_duplicate_property (struct hw *me,
878 const char *property,
879 const struct hw_property *original)
880{
881 struct hw_property_data *master;
6d519a46 882 HW_TRACE ((me, "hw_add_duplicate_property(property=%s, ...)\n", property));
c906108c
SS
883 if (original->disposition != permenant_object)
884 hw_abort (me, "Can only duplicate permenant objects");
885 /* find the original's master */
886 master = original->owner->properties_of_hw;
887 while (master->property != original)
888 {
889 master = master->next;
34b47c38 890 ASSERT (master != NULL);
c906108c
SS
891 }
892 /* now duplicate it */
893 hw_add_property (me, property,
894 original->type,
895 master->init_array, master->sizeof_init_array,
896 original->array, original->sizeof_array,
897 original, permenant_object);
898}
This page took 0.547914 seconds and 4 git commands to generate.