123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899 |
- /* The common simulator framework for GDB, the GNU Debugger.
- Copyright 2002-2015 Free Software Foundation, Inc.
- Contributed by Andrew Cagney and Red Hat.
- This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "hw-main.h"
- #include "hw-base.h"
- #include "sim-io.h"
- #include "sim-assert.h"
- #ifdef HAVE_STRING_H
- #include <string.h>
- #else
- #ifdef HAVE_STRINGS_H
- #include <strings.h>
- #endif
- #endif
- /* property entries */
- struct hw_property_data
- {
- struct hw_property_data *next;
- struct hw_property *property;
- const void *init_array;
- unsigned sizeof_init_array;
- };
- void
- create_hw_property_data (struct hw *me)
- {
- }
- void
- delete_hw_property_data (struct hw *me)
- {
- }
- /* Device Properties: */
- static struct hw_property_data *
- find_property_data (struct hw *me,
- const char *property)
- {
- struct hw_property_data *entry;
- ASSERT (property != NULL);
- entry = me->properties_of_hw;
- while (entry != NULL)
- {
- if (strcmp (entry->property->name, property) == 0)
- return entry;
- entry = entry->next;
- }
- return NULL;
- }
- static void
- hw_add_property (struct hw *me,
- const char *property,
- hw_property_type type,
- const void *init_array,
- unsigned sizeof_init_array,
- const void *array,
- unsigned sizeof_array,
- const struct hw_property *original,
- object_disposition disposition)
- {
- struct hw_property_data *new_entry = NULL;
- struct hw_property *new_value = NULL;
- /* find the list end */
- struct hw_property_data **insertion_point = &me->properties_of_hw;
- while (*insertion_point != NULL)
- {
- if (strcmp ((*insertion_point)->property->name, property) == 0)
- return;
- insertion_point = &(*insertion_point)->next;
- }
- /* create a new value */
- new_value = HW_ZALLOC (me, struct hw_property);
- new_value->name = (char *) strdup (property);
- new_value->type = type;
- if (sizeof_array > 0)
- {
- void *new_array = hw_zalloc (me, sizeof_array);
- memcpy (new_array, array, sizeof_array);
- new_value->array = new_array;
- new_value->sizeof_array = sizeof_array;
- }
- new_value->owner = me;
- new_value->original = original;
- new_value->disposition = disposition;
- /* insert the value into the list */
- new_entry = HW_ZALLOC (me, struct hw_property_data);
- *insertion_point = new_entry;
- if (sizeof_init_array > 0)
- {
- void *new_init_array = hw_zalloc (me, sizeof_init_array);
- memcpy (new_init_array, init_array, sizeof_init_array);
- new_entry->init_array = new_init_array;
- new_entry->sizeof_init_array = sizeof_init_array;
- }
- new_entry->property = new_value;
- }
- static void
- hw_set_property (struct hw *me,
- const char *property,
- hw_property_type type,
- const void *array,
- int sizeof_array)
- {
- /* find the property */
- struct hw_property_data *entry = find_property_data (me, property);
- if (entry != NULL)
- {
- /* existing property - update it */
- void *new_array = 0;
- struct hw_property *value = entry->property;
- /* check the type matches */
- if (value->type != type)
- hw_abort (me, "conflict between type of new and old value for property %s", property);
- /* replace its value */
- if (value->array != NULL)
- hw_free (me, (void*)value->array);
- new_array = (sizeof_array > 0
- ? hw_zalloc (me, sizeof_array)
- : (void*)0);
- value->array = new_array;
- value->sizeof_array = sizeof_array;
- if (sizeof_array > 0)
- memcpy (new_array, array, sizeof_array);
- return;
- }
- else
- {
- /* new property - create it */
- hw_add_property (me, property, type,
- NULL, 0, array, sizeof_array,
- NULL, temporary_object);
- }
- }
- #if 0
- static void
- clean_hw_properties (struct hw *me)
- {
- struct hw_property_data **delete_point = &me->properties_of_hw;
- while (*delete_point != NULL)
- {
- struct hw_property_data *current = *delete_point;
- switch (current->property->disposition)
- {
- case permenant_object:
- /* zap the current value, will be initialized later */
- ASSERT (current->init_array != NULL);
- if (current->property->array != NULL)
- {
- hw_free (me, (void*)current->property->array);
- current->property->array = NULL;
- }
- delete_point = &(*delete_point)->next;
- break;
- case temporary_object:
- /* zap the actual property, was created during simulation run */
- ASSERT (current->init_array == NULL);
- *delete_point = current->next;
- if (current->property->array != NULL)
- hw_free (me, (void*)current->property->array);
- hw_free (me, current->property);
- hw_free (me, current);
- break;
- }
- }
- }
- #endif
- #if 0
- void
- hw_init_static_properties (SIM_DESC sd,
- struct hw *me,
- void *data)
- {
- struct hw_property_data *property;
- for (property = me->properties_of_hw;
- property != NULL;
- property = property->next)
- {
- ASSERT (property->init_array != NULL);
- ASSERT (property->property->array == NULL);
- ASSERT (property->property->disposition == permenant_object);
- switch (property->property->type)
- {
- case array_property:
- case boolean_property:
- case range_array_property:
- case reg_array_property:
- case string_property:
- case string_array_property:
- case integer_property:
- /* delete the property, and replace it with the original */
- hw_set_property (me, property->property->name,
- property->property->type,
- property->init_array,
- property->sizeof_init_array);
- break;
- #if 0
- case ihandle_property:
- break;
- #endif
- }
- }
- }
- #endif
- #if 0
- void
- hw_init_runtime_properties (SIM_DESC sd,
- struct hw *me,
- void *data)
- {
- struct hw_property_data *property;
- for (property = me->properties_of_hw;
- property != NULL;
- property = property->next)
- {
- switch (property->property->disposition)
- {
- case permenant_object:
- switch (property->property->type)
- {
- #if 0
- case ihandle_property:
- {
- struct hw_instance *ihandle;
- ihandle_runtime_property_spec spec;
- ASSERT (property->init_array != NULL);
- ASSERT (property->property->array == NULL);
- hw_find_ihandle_runtime_property (me, property->property->name, &spec);
- ihandle = tree_instance (me, spec.full_path);
- hw_set_ihandle_property (me, property->property->name, ihandle);
- break;
- }
- #endif
- case array_property:
- case boolean_property:
- case range_array_property:
- case integer_property:
- case reg_array_property:
- case string_property:
- case string_array_property:
- ASSERT (property->init_array != NULL);
- ASSERT (property->property->array != NULL);
- break;
- }
- break;
- case temporary_object:
- ASSERT (property->init_array == NULL);
- ASSERT (property->property->array != NULL);
- break;
- }
- }
- }
- #endif
- const struct hw_property *
- hw_next_property (const struct hw_property *property)
- {
- /* find the property in the list */
- struct hw *owner = property->owner;
- struct hw_property_data *entry = owner->properties_of_hw;
- while (entry != NULL && entry->property != property)
- entry = entry->next;
- /* now return the following property */
- ASSERT (entry != NULL); /* must be a member! */
- if (entry->next != NULL)
- return entry->next->property;
- else
- return NULL;
- }
- const struct hw_property *
- hw_find_property (struct hw *me,
- const char *property)
- {
- if (me == NULL)
- {
- return NULL;
- }
- else if (property == NULL || strcmp (property, "") == 0)
- {
- if (me->properties_of_hw == NULL)
- return NULL;
- else
- return me->properties_of_hw->property;
- }
- else
- {
- struct hw_property_data *entry = find_property_data (me, property);
- if (entry != NULL)
- return entry->property;
- }
- return NULL;
- }
- void
- hw_add_array_property (struct hw *me,
- const char *property,
- const void *array,
- int sizeof_array)
- {
- hw_add_property (me, property, array_property,
- array, sizeof_array, array, sizeof_array,
- NULL, permenant_object);
- }
- void
- hw_set_array_property (struct hw *me,
- const char *property,
- const void *array,
- int sizeof_array)
- {
- hw_set_property (me, property, array_property, array, sizeof_array);
- }
- const struct hw_property *
- hw_find_array_property (struct hw *me,
- const char *property)
- {
- const struct hw_property *node;
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != array_property)
- hw_abort (me, "property \"%s\" of wrong type (array)", property);
- return node;
- }
- void
- hw_add_boolean_property (struct hw *me,
- const char *property,
- int boolean)
- {
- signed32 new_boolean = (boolean ? -1 : 0);
- hw_add_property (me, property, boolean_property,
- &new_boolean, sizeof (new_boolean),
- &new_boolean, sizeof (new_boolean),
- NULL, permenant_object);
- }
- int
- hw_find_boolean_property (struct hw *me,
- const char *property)
- {
- const struct hw_property *node;
- unsigned_cell boolean;
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != boolean_property)
- hw_abort (me, "property \"%s\" of wrong type (boolean)", property);
- ASSERT (sizeof (boolean) == node->sizeof_array);
- memcpy (&boolean, node->array, sizeof (boolean));
- return boolean;
- }
- #if 0
- void
- hw_add_ihandle_runtime_property (struct hw *me,
- const char *property,
- const ihandle_runtime_property_spec *ihandle)
- {
- /* enter the full path as the init array */
- hw_add_property (me, property, ihandle_property,
- ihandle->full_path, strlen (ihandle->full_path) + 1,
- NULL, 0,
- NULL, permenant_object);
- }
- #endif
- #if 0
- void
- hw_find_ihandle_runtime_property (struct hw *me,
- const char *property,
- ihandle_runtime_property_spec *ihandle)
- {
- struct hw_property_data *entry = find_property_data (me, property);
- HW_TRACE ((me, "hw_find_ihandle_runtime_property(property=%s)\n", property));
- if (entry == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (entry->property->type != ihandle_property
- || entry->property->disposition != permenant_object)
- hw_abort (me, "property \"%s\" of wrong type", property);
- ASSERT (entry->init_array != NULL);
- /* the full path */
- ihandle->full_path = entry->init_array;
- }
- #endif
- #if 0
- void
- hw_set_ihandle_property (struct hw *me,
- const char *property,
- hw_instance *ihandle)
- {
- unsigned_cell cells;
- cells = H2BE_cell (hw_instance_to_external (ihandle));
- hw_set_property (me, property, ihandle_property,
- &cells, sizeof (cells));
- }
- #endif
- #if 0
- hw_instance *
- hw_find_ihandle_property (struct hw *me,
- const char *property)
- {
- const hw_property_data *node;
- unsigned_cell ihandle;
- hw_instance *instance;
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != ihandle_property)
- hw_abort (me, "property \"%s\" of wrong type (ihandle)", property);
- if (node->array == NULL)
- hw_abort (me, "runtime property \"%s\" not yet initialized", property);
- ASSERT (sizeof (ihandle) == node->sizeof_array);
- memcpy (&ihandle, node->array, sizeof (ihandle));
- instance = external_to_hw_instance (me, BE2H_cell (ihandle));
- ASSERT (instance != NULL);
- return instance;
- }
- #endif
- void
- hw_add_integer_property (struct hw *me,
- const char *property,
- signed_cell integer)
- {
- H2BE (integer);
- hw_add_property (me, property, integer_property,
- &integer, sizeof (integer),
- &integer, sizeof (integer),
- NULL, permenant_object);
- }
- signed_cell
- hw_find_integer_property (struct hw *me,
- const char *property)
- {
- const struct hw_property *node;
- signed_cell integer;
- HW_TRACE ((me, "hw_find_integer(property=%s)\n", property));
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != integer_property)
- hw_abort (me, "property \"%s\" of wrong type (integer)", property);
- ASSERT (sizeof (integer) == node->sizeof_array);
- memcpy (&integer, node->array, sizeof (integer));
- return BE2H_cell (integer);
- }
- int
- hw_find_integer_array_property (struct hw *me,
- const char *property,
- unsigned index,
- signed_cell *integer)
- {
- const struct hw_property *node;
- int sizeof_integer = sizeof (*integer);
- signed_cell *cell;
- HW_TRACE ((me, "hw_find_integer(property=%s)\n", property));
- /* check things sane */
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != integer_property
- && node->type != array_property)
- hw_abort (me, "property \"%s\" of wrong type (integer or array)", property);
- if ((node->sizeof_array % sizeof_integer) != 0)
- hw_abort (me, "property \"%s\" contains an incomplete number of cells", property);
- if (node->sizeof_array <= sizeof_integer * index)
- return 0;
- /* Find and convert the value */
- cell = ((signed_cell*)node->array) + index;
- *integer = BE2H_cell (*cell);
- return node->sizeof_array / sizeof_integer;
- }
- static unsigned_cell *
- unit_address_to_cells (const hw_unit *unit,
- unsigned_cell *cell,
- int nr_cells)
- {
- int i;
- ASSERT (nr_cells == unit->nr_cells);
- for (i = 0; i < unit->nr_cells; i++)
- {
- *cell = H2BE_cell (unit->cells[i]);
- cell += 1;
- }
- return cell;
- }
- static const unsigned_cell *
- cells_to_unit_address (const unsigned_cell *cell,
- hw_unit *unit,
- int nr_cells)
- {
- int i;
- memset (unit, 0, sizeof (*unit));
- unit->nr_cells = nr_cells;
- for (i = 0; i < unit->nr_cells; i++)
- {
- unit->cells[i] = BE2H_cell (*cell);
- cell += 1;
- }
- return cell;
- }
- static unsigned
- nr_range_property_cells (struct hw *me,
- int nr_ranges)
- {
- return ((hw_unit_nr_address_cells (me)
- + hw_unit_nr_address_cells (hw_parent (me))
- + hw_unit_nr_size_cells (me))
- ) * nr_ranges;
- }
- void
- hw_add_range_array_property (struct hw *me,
- const char *property,
- const range_property_spec *ranges,
- unsigned nr_ranges)
- {
- unsigned sizeof_cells = (nr_range_property_cells (me, nr_ranges)
- * sizeof (unsigned_cell));
- unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
- unsigned_cell *cell;
- int i;
- /* copy the property elements over */
- cell = cells;
- for (i = 0; i < nr_ranges; i++)
- {
- const range_property_spec *range = &ranges[i];
- /* copy the child address */
- cell = unit_address_to_cells (&range->child_address, cell,
- hw_unit_nr_address_cells (me));
- /* copy the parent address */
- cell = unit_address_to_cells (&range->parent_address, cell,
- hw_unit_nr_address_cells (hw_parent (me)));
- /* copy the size */
- cell = unit_address_to_cells (&range->size, cell,
- hw_unit_nr_size_cells (me));
- }
- ASSERT (cell == &cells[nr_range_property_cells (me, nr_ranges)]);
- /* add it */
- hw_add_property (me, property, range_array_property,
- cells, sizeof_cells,
- cells, sizeof_cells,
- NULL, permenant_object);
- hw_free (me, cells);
- }
- int
- hw_find_range_array_property (struct hw *me,
- const char *property,
- unsigned index,
- range_property_spec *range)
- {
- const struct hw_property *node;
- unsigned sizeof_entry = (nr_range_property_cells (me, 1)
- * sizeof (unsigned_cell));
- const unsigned_cell *cells;
- /* locate the property */
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != range_array_property)
- hw_abort (me, "property \"%s\" of wrong type (range array)", property);
- /* aligned ? */
- if ((node->sizeof_array % sizeof_entry) != 0)
- hw_abort (me, "property \"%s\" contains an incomplete number of entries",
- property);
- /* within bounds? */
- if (node->sizeof_array < sizeof_entry * (index + 1))
- return 0;
- /* find the range of interest */
- cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
- /* copy the child address out - converting as we go */
- cells = cells_to_unit_address (cells, &range->child_address,
- hw_unit_nr_address_cells (me));
- /* copy the parent address out - converting as we go */
- cells = cells_to_unit_address (cells, &range->parent_address,
- hw_unit_nr_address_cells (hw_parent (me)));
- /* copy the size - converting as we go */
- cells = cells_to_unit_address (cells, &range->size,
- hw_unit_nr_size_cells (me));
- return node->sizeof_array / sizeof_entry;
- }
- static unsigned
- nr_reg_property_cells (struct hw *me,
- int nr_regs)
- {
- return (hw_unit_nr_address_cells (hw_parent (me))
- + hw_unit_nr_size_cells (hw_parent (me))
- ) * nr_regs;
- }
- void
- hw_add_reg_array_property (struct hw *me,
- const char *property,
- const reg_property_spec *regs,
- unsigned nr_regs)
- {
- unsigned sizeof_cells = (nr_reg_property_cells (me, nr_regs)
- * sizeof (unsigned_cell));
- unsigned_cell *cells = hw_zalloc (me, sizeof_cells);
- unsigned_cell *cell;
- int i;
- /* copy the property elements over */
- cell = cells;
- for (i = 0; i < nr_regs; i++)
- {
- const reg_property_spec *reg = ®s[i];
- /* copy the address */
- cell = unit_address_to_cells (®->address, cell,
- hw_unit_nr_address_cells (hw_parent (me)));
- /* copy the size */
- cell = unit_address_to_cells (®->size, cell,
- hw_unit_nr_size_cells (hw_parent (me)));
- }
- ASSERT (cell == &cells[nr_reg_property_cells (me, nr_regs)]);
- /* add it */
- hw_add_property (me, property, reg_array_property,
- cells, sizeof_cells,
- cells, sizeof_cells,
- NULL, permenant_object);
- hw_free (me, cells);
- }
- int
- hw_find_reg_array_property (struct hw *me,
- const char *property,
- unsigned index,
- reg_property_spec *reg)
- {
- const struct hw_property *node;
- unsigned sizeof_entry = (nr_reg_property_cells (me, 1)
- * sizeof (unsigned_cell));
- const unsigned_cell *cells;
- /* locate the property */
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != reg_array_property)
- hw_abort (me, "property \"%s\" of wrong type (reg array)", property);
- /* aligned ? */
- if ((node->sizeof_array % sizeof_entry) != 0)
- hw_abort (me, "property \"%s\" contains an incomplete number of entries",
- property);
- /* within bounds? */
- if (node->sizeof_array < sizeof_entry * (index + 1))
- return 0;
- /* find the range of interest */
- cells = (unsigned_cell*)((char*)node->array + sizeof_entry * index);
- /* copy the address out - converting as we go */
- cells = cells_to_unit_address (cells, ®->address,
- hw_unit_nr_address_cells (hw_parent (me)));
- /* copy the size out - converting as we go */
- cells = cells_to_unit_address (cells, ®->size,
- hw_unit_nr_size_cells (hw_parent (me)));
- return node->sizeof_array / sizeof_entry;
- }
- void
- hw_add_string_property (struct hw *me,
- const char *property,
- const char *string)
- {
- hw_add_property (me, property, string_property,
- string, strlen (string) + 1,
- string, strlen (string) + 1,
- NULL, permenant_object);
- }
- const char *
- hw_find_string_property (struct hw *me,
- const char *property)
- {
- const struct hw_property *node;
- const char *string;
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- if (node->type != string_property)
- hw_abort (me, "property \"%s\" of wrong type (string)", property);
- string = node->array;
- ASSERT (strlen (string) + 1 == node->sizeof_array);
- return string;
- }
- void
- hw_add_string_array_property (struct hw *me,
- const char *property,
- const string_property_spec *strings,
- unsigned nr_strings)
- {
- int sizeof_array;
- int string_nr;
- char *array;
- char *chp;
- if (nr_strings == 0)
- hw_abort (me, "property \"%s\" must be non-null", property);
- /* total up the size of the needed array */
- for (sizeof_array = 0, string_nr = 0;
- string_nr < nr_strings;
- string_nr ++)
- {
- sizeof_array += strlen (strings[string_nr]) + 1;
- }
- /* create the array */
- array = (char*) hw_zalloc (me, sizeof_array);
- chp = array;
- for (string_nr = 0;
- string_nr < nr_strings;
- string_nr++)
- {
- strcpy (chp, strings[string_nr]);
- chp += strlen (chp) + 1;
- }
- ASSERT (chp == array + sizeof_array);
- /* now enter it */
- hw_add_property (me, property, string_array_property,
- array, sizeof_array,
- array, sizeof_array,
- NULL, permenant_object);
- }
- int
- hw_find_string_array_property (struct hw *me,
- const char *property,
- unsigned index,
- string_property_spec *string)
- {
- const struct hw_property *node;
- node = hw_find_property (me, property);
- if (node == NULL)
- hw_abort (me, "property \"%s\" not found", property);
- switch (node->type)
- {
- default:
- hw_abort (me, "property \"%s\" of wrong type", property);
- break;
- case string_property:
- if (index == 0)
- {
- *string = node->array;
- ASSERT (strlen (*string) + 1 == node->sizeof_array);
- return 1;
- }
- break;
- case array_property:
- if (node->sizeof_array == 0
- || ((char*)node->array)[node->sizeof_array - 1] != '\0')
- hw_abort (me, "property \"%s\" invalid for string array", property);
- /* FALL THROUGH */
- case string_array_property:
- ASSERT (node->sizeof_array > 0);
- ASSERT (((char*)node->array)[node->sizeof_array - 1] == '\0');
- {
- const char *chp = node->array;
- int nr_entries = 0;
- /* count the number of strings, keeping an eye out for the one
- we're looking for */
- *string = chp;
- do
- {
- if (*chp == '\0')
- {
- /* next string */
- nr_entries++;
- chp++;
- if (nr_entries == index)
- *string = chp;
- }
- else
- {
- chp++;
- }
- } while (chp < (char*)node->array + node->sizeof_array);
- if (index < nr_entries)
- return nr_entries;
- else
- {
- *string = NULL;
- return 0;
- }
- }
- break;
- }
- return 0;
- }
- void
- hw_add_duplicate_property (struct hw *me,
- const char *property,
- const struct hw_property *original)
- {
- struct hw_property_data *master;
- HW_TRACE ((me, "hw_add_duplicate_property(property=%s, ...)\n", property));
- if (original->disposition != permenant_object)
- hw_abort (me, "Can only duplicate permenant objects");
- /* find the original's master */
- master = original->owner->properties_of_hw;
- while (master->property != original)
- {
- master = master->next;
- ASSERT (master != NULL);
- }
- /* now duplicate it */
- hw_add_property (me, property,
- original->type,
- master->init_array, master->sizeof_init_array,
- original->array, original->sizeof_array,
- original, permenant_object);
- }
|