aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/arm/armv7m.c10
-rw-r--r--hw/arm/exynos4210.c2
-rw-r--r--hw/arm/highbank.c2
-rw-r--r--hw/arm/integratorcp.c2
-rw-r--r--hw/arm/realview.c2
-rw-r--r--hw/arm/sbsa-ref.c2
-rw-r--r--hw/arm/versatilepb.c2
-rw-r--r--hw/arm/vexpress.c4
-rw-r--r--hw/arm/virt.c10
-rw-r--r--hw/arm/xilinx_zynq.c2
-rw-r--r--hw/core/qdev-properties-system.c2
-rw-r--r--hw/core/sysbus.c2
-rw-r--r--hw/cpu/a15mpcore.c4
-rw-r--r--hw/cpu/a9mpcore.c2
-rw-r--r--hw/misc/iotkit-sysctl.c2
-rw-r--r--hw/pci/pci.c2
-rw-r--r--hw/scsi/scsi-bus.c4
-rw-r--r--include/qom/object.h48
-rw-r--r--qom/object.c60
-rw-r--r--target/arm/monitor.c2
-rw-r--r--target/i386/cpu.c2
-rw-r--r--target/ppc/translate_init.c.inc2
22 files changed, 109 insertions, 61 deletions
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index aa831d6..0e5997d 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -169,28 +169,28 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
object_property_set_link(OBJECT(s->cpu), "memory", OBJECT(&s->container),
&error_abort);
- if (object_property_find(OBJECT(s->cpu), "idau", NULL)) {
+ if (object_property_find(OBJECT(s->cpu), "idau")) {
object_property_set_link(OBJECT(s->cpu), "idau", s->idau,
&error_abort);
}
- if (object_property_find(OBJECT(s->cpu), "init-svtor", NULL)) {
+ if (object_property_find(OBJECT(s->cpu), "init-svtor")) {
if (!object_property_set_uint(OBJECT(s->cpu), "init-svtor",
s->init_svtor, errp)) {
return;
}
}
- if (object_property_find(OBJECT(s->cpu), "start-powered-off", NULL)) {
+ if (object_property_find(OBJECT(s->cpu), "start-powered-off")) {
if (!object_property_set_bool(OBJECT(s->cpu), "start-powered-off",
s->start_powered_off, errp)) {
return;
}
}
- if (object_property_find(OBJECT(s->cpu), "vfp", NULL)) {
+ if (object_property_find(OBJECT(s->cpu), "vfp")) {
if (!object_property_set_bool(OBJECT(s->cpu), "vfp", s->vfp, errp)) {
return;
}
}
- if (object_property_find(OBJECT(s->cpu), "dsp", NULL)) {
+ if (object_property_find(OBJECT(s->cpu), "dsp")) {
if (!object_property_set_bool(OBJECT(s->cpu), "dsp", s->dsp, errp)) {
return;
}
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 081bbff..ced2769 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -214,7 +214,7 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
/* By default A9 CPUs have EL3 enabled. This board does not currently
* support EL3 so the CPU EL3 property is disabled before realization.
*/
- if (object_property_find(cpuobj, "has_el3", NULL)) {
+ if (object_property_find(cpuobj, "has_el3")) {
object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
}
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 7da9841..da0510d 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -276,7 +276,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
&error_abort);
}
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
+ if (object_property_find(cpuobj, "reset-cbar")) {
object_property_set_int(cpuobj, "reset-cbar", MPCORE_PERIPHBASE,
&error_abort);
}
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index de670b0..16e8985 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -603,7 +603,7 @@ static void integratorcp_init(MachineState *machine)
* currently support EL3 so the CPU EL3 property is disabled before
* realization.
*/
- if (object_property_find(cpuobj, "has_el3", NULL)) {
+ if (object_property_find(cpuobj, "has_el3")) {
object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
}
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 5f1f36b..0831159 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -108,7 +108,7 @@ static void realview_init(MachineState *machine,
* does not currently support EL3 so the CPU EL3 property is disabled
* before realization.
*/
- if (object_property_find(cpuobj, "has_el3", NULL)) {
+ if (object_property_find(cpuobj, "has_el3")) {
object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
}
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index bcb2cb4..257ada9 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -703,7 +703,7 @@ static void sbsa_ref_init(MachineState *machine)
numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj),
&error_fatal);
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
+ if (object_property_find(cpuobj, "reset-cbar")) {
object_property_set_int(cpuobj, "reset-cbar",
sbsa_ref_memmap[SBSA_CPUPERIPHS].base,
&error_abort);
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 84d4677..1ea5534 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -213,7 +213,7 @@ static void versatile_init(MachineState *machine, int board_id)
* currently support EL3 so the CPU EL3 property is disabled before
* realization.
*/
- if (object_property_find(cpuobj, "has_el3", NULL)) {
+ if (object_property_find(cpuobj, "has_el3")) {
object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
}
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 94ff094..531f3a1 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -218,12 +218,12 @@ static void init_cpus(MachineState *ms, const char *cpu_type,
object_property_set_bool(cpuobj, "has_el3", false, NULL);
}
if (!virt) {
- if (object_property_find(cpuobj, "has_el2", NULL)) {
+ if (object_property_find(cpuobj, "has_el2")) {
object_property_set_bool(cpuobj, "has_el2", false, NULL);
}
}
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
+ if (object_property_find(cpuobj, "reset-cbar")) {
object_property_set_int(cpuobj, "reset-cbar", periphbase,
&error_abort);
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index acf9bfb..1231a19 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1806,7 +1806,7 @@ static void machvirt_init(MachineState *machine)
object_property_set_bool(cpuobj, "has_el3", false, NULL);
}
- if (!vms->virt && object_property_find(cpuobj, "has_el2", NULL)) {
+ if (!vms->virt && object_property_find(cpuobj, "has_el2")) {
object_property_set_bool(cpuobj, "has_el2", false, NULL);
}
@@ -1822,15 +1822,15 @@ static void machvirt_init(MachineState *machine)
}
if (vmc->kvm_no_adjvtime &&
- object_property_find(cpuobj, "kvm-no-adjvtime", NULL)) {
+ object_property_find(cpuobj, "kvm-no-adjvtime")) {
object_property_set_bool(cpuobj, "kvm-no-adjvtime", true, NULL);
}
- if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
+ if (vmc->no_pmu && object_property_find(cpuobj, "pmu")) {
object_property_set_bool(cpuobj, "pmu", false, NULL);
}
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
+ if (object_property_find(cpuobj, "reset-cbar")) {
object_property_set_int(cpuobj, "reset-cbar",
vms->memmap[VIRT_CPUPERIPHS].base,
&error_abort);
@@ -1850,7 +1850,7 @@ static void machvirt_init(MachineState *machine)
* The property exists only if MemTag is supported.
* If it is, we must allocate the ram to back that up.
*/
- if (!object_property_find(cpuobj, "tag-memory", NULL)) {
+ if (!object_property_find(cpuobj, "tag-memory")) {
error_report("MTE requested, but not supported "
"by the guest CPU");
exit(1);
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 2c0bff4..b72772b 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -196,7 +196,7 @@ static void zynq_init(MachineState *machine)
* currently support EL3 so the CPU EL3 property is disabled before
* realization.
*/
- if (object_property_find(OBJECT(cpu), "has_el3", NULL)) {
+ if (object_property_find(OBJECT(cpu), "has_el3")) {
object_property_set_bool(OBJECT(cpu), "has_el3", false, &error_fatal);
}
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 3e4f16f..b29daf4 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -460,7 +460,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
qdev_prop_set_netdev(dev, "netdev", nd->netdev);
}
if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
- object_property_find(OBJECT(dev), "vectors", NULL)) {
+ object_property_find(OBJECT(dev), "vectors")) {
qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
}
nd->instantiated = 1;
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 294f90b..68e8dc8 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -93,7 +93,7 @@ bool sysbus_has_irq(SysBusDevice *dev, int n)
char *prop = g_strdup_printf("%s[%d]", SYSBUS_DEVICE_GPIO_IRQ, n);
ObjectProperty *r;
- r = object_property_find(OBJECT(dev), prop, NULL);
+ r = object_property_find(OBJECT(dev), prop);
g_free(prop);
return (r != NULL);
diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index c377be3..774ca99 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -66,11 +66,11 @@ static void a15mp_priv_realize(DeviceState *dev, Error **errp)
* either all the CPUs have TZ, or none do.
*/
cpuobj = OBJECT(qemu_get_cpu(0));
- has_el3 = object_property_find(cpuobj, "has_el3", NULL) &&
+ has_el3 = object_property_find(cpuobj, "has_el3") &&
object_property_get_bool(cpuobj, "has_el3", &error_abort);
qdev_prop_set_bit(gicdev, "has-security-extensions", has_el3);
/* Similarly for virtualization support */
- has_el2 = object_property_find(cpuobj, "has_el2", NULL) &&
+ has_el2 = object_property_find(cpuobj, "has_el2") &&
object_property_get_bool(cpuobj, "has_el2", &error_abort);
qdev_prop_set_bit(gicdev, "has-virtualization-extensions", has_el2);
}
diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index ec186d4..d03f57e 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -81,7 +81,7 @@ static void a9mp_priv_realize(DeviceState *dev, Error **errp)
/* Make the GIC's TZ support match the CPUs. We assume that
* either all the CPUs have TZ, or none do.
*/
- has_el3 = object_property_find(cpuobj, "has_el3", NULL) &&
+ has_el3 = object_property_find(cpuobj, "has_el3") &&
object_property_get_bool(cpuobj, "has_el3", &error_abort);
qdev_prop_set_bit(gicdev, "has-security-extensions", has_el3);
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
index 2697833..964b48c 100644
--- a/hw/misc/iotkit-sysctl.c
+++ b/hw/misc/iotkit-sysctl.c
@@ -83,7 +83,7 @@ static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
if (cpuobj) {
- if (object_property_find(cpuobj, "init-svtor", NULL)) {
+ if (object_property_find(cpuobj, "init-svtor")) {
object_property_set_uint(cpuobj, "init-svtor", vtor, &error_abort);
}
}
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index de0fae1..fce7254 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1900,7 +1900,7 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
* a temporary instance here to be able to check it.
*/
Object *obj = object_new_with_class(OBJECT_CLASS(dc));
- if (object_property_find(obj, "netdev", NULL)) {
+ if (object_property_find(obj, "netdev")) {
g_ptr_array_add(pci_nic_models, (gpointer)name);
}
object_unref(obj);
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index df65cc2..3284a5d 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -270,10 +270,10 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,
object_property_set_int(OBJECT(dev), "bootindex", bootindex,
&error_abort);
}
- if (object_property_find(OBJECT(dev), "removable", NULL)) {
+ if (object_property_find(OBJECT(dev), "removable")) {
qdev_prop_set_bit(dev, "removable", removable);
}
- if (serial && object_property_find(OBJECT(dev), "serial", NULL)) {
+ if (serial && object_property_find(OBJECT(dev), "serial")) {
qdev_prop_set_string(dev, "serial", serial);
}
if (!qdev_prop_set_drive_err(dev, "drive", blk, errp)) {
diff --git a/include/qom/object.h b/include/qom/object.h
index 19cccd3..9b01888 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1463,14 +1463,52 @@ void object_property_set_default_uint(ObjectProperty *prop, uint64_t value);
* object_property_find:
* @obj: the object
* @name: the name of the property
+ *
+ * Look up a property for an object.
+ *
+ * Return its #ObjectProperty if found, or NULL.
+ */
+ObjectProperty *object_property_find(Object *obj, const char *name);
+
+/**
+ * object_property_find_err:
+ * @obj: the object
+ * @name: the name of the property
* @errp: returns an error if this function fails
*
- * Look up a property for an object and return its #ObjectProperty if found.
+ * Look up a property for an object.
+ *
+ * Return its #ObjectProperty if found, or NULL.
*/
-ObjectProperty *object_property_find(Object *obj, const char *name,
- Error **errp);
-ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
- Error **errp);
+ObjectProperty *object_property_find_err(Object *obj,
+ const char *name,
+ Error **errp);
+
+/**
+ * object_class_property_find:
+ * @klass: the object class
+ * @name: the name of the property
+ *
+ * Look up a property for an object class.
+ *
+ * Return its #ObjectProperty if found, or NULL.
+ */
+ObjectProperty *object_class_property_find(ObjectClass *klass,
+ const char *name);
+
+/**
+ * object_class_property_find_err:
+ * @klass: the object class
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Look up a property for an object class.
+ *
+ * Return its #ObjectProperty if found, or NULL.
+ */
+ObjectProperty *object_class_property_find_err(ObjectClass *klass,
+ const char *name,
+ Error **errp);
typedef struct ObjectPropertyIterator {
ObjectClass *nextclass;
diff --git a/qom/object.c b/qom/object.c
index a91a6a5..a1ab9a7 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -403,7 +403,7 @@ bool object_apply_global_props(Object *obj, const GPtrArray *props,
if (object_dynamic_cast(obj, p->driver) == NULL) {
continue;
}
- if (p->optional && !object_property_find(obj, p->property, NULL)) {
+ if (p->optional && !object_property_find(obj, p->property)) {
continue;
}
p->used = true;
@@ -1214,7 +1214,7 @@ object_property_try_add(Object *obj, const char *name, const char *type,
return ret;
}
- if (object_property_find(obj, name, NULL) != NULL) {
+ if (object_property_find(obj, name) != NULL) {
error_setg(errp, "attempt to add duplicate property '%s' to object (type '%s')",
name, object_get_typename(obj));
return NULL;
@@ -1256,7 +1256,7 @@ object_class_property_add(ObjectClass *klass,
{
ObjectProperty *prop;
- assert(!object_class_property_find(klass, name, NULL));
+ assert(!object_class_property_find(klass, name));
prop = g_malloc0(sizeof(*prop));
@@ -1273,24 +1273,27 @@ object_class_property_add(ObjectClass *klass,
return prop;
}
-ObjectProperty *object_property_find(Object *obj, const char *name,
- Error **errp)
+ObjectProperty *object_property_find(Object *obj, const char *name)
{
ObjectProperty *prop;
ObjectClass *klass = object_get_class(obj);
- prop = object_class_property_find(klass, name, NULL);
+ prop = object_class_property_find(klass, name);
if (prop) {
return prop;
}
- prop = g_hash_table_lookup(obj->properties, name);
- if (prop) {
- return prop;
- }
+ return g_hash_table_lookup(obj->properties, name);
+}
- error_setg(errp, "Property '.%s' not found", name);
- return NULL;
+ObjectProperty *object_property_find_err(Object *obj, const char *name,
+ Error **errp)
+{
+ ObjectProperty *prop = object_property_find(obj, name);
+ if (!prop) {
+ error_setg(errp, "Property '.%s' not found", name);
+ }
+ return prop;
}
void object_property_iter_init(ObjectPropertyIterator *iter,
@@ -1320,27 +1323,34 @@ void object_class_property_iter_init(ObjectPropertyIterator *iter,
iter->nextclass = object_class_get_parent(klass);
}
-ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
- Error **errp)
+ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name)
{
- ObjectProperty *prop;
ObjectClass *parent_klass;
parent_klass = object_class_get_parent(klass);
if (parent_klass) {
- prop = object_class_property_find(parent_klass, name, NULL);
+ ObjectProperty *prop =
+ object_class_property_find(parent_klass, name);
if (prop) {
return prop;
}
}
- prop = g_hash_table_lookup(klass->properties, name);
+ return g_hash_table_lookup(klass->properties, name);
+}
+
+ObjectProperty *object_class_property_find_err(ObjectClass *klass,
+ const char *name,
+ Error **errp)
+{
+ ObjectProperty *prop = object_class_property_find(klass, name);
if (!prop) {
error_setg(errp, "Property '.%s' not found", name);
}
return prop;
}
+
void object_property_del(Object *obj, const char *name)
{
ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
@@ -1355,7 +1365,7 @@ bool object_property_get(Object *obj, const char *name, Visitor *v,
Error **errp)
{
Error *err = NULL;
- ObjectProperty *prop = object_property_find(obj, name, errp);
+ ObjectProperty *prop = object_property_find_err(obj, name, errp);
if (prop == NULL) {
return false;
@@ -1374,7 +1384,7 @@ bool object_property_set(Object *obj, const char *name, Visitor *v,
Error **errp)
{
Error *err = NULL;
- ObjectProperty *prop = object_property_find(obj, name, errp);
+ ObjectProperty *prop = object_property_find_err(obj, name, errp);
if (prop == NULL) {
return false;
@@ -1590,7 +1600,7 @@ int object_property_get_enum(Object *obj, const char *name,
{
char *str;
int ret;
- ObjectProperty *prop = object_property_find(obj, name, errp);
+ ObjectProperty *prop = object_property_find_err(obj, name, errp);
EnumProperty *enumprop;
if (prop == NULL) {
@@ -1647,7 +1657,7 @@ out:
const char *object_property_get_type(Object *obj, const char *name, Error **errp)
{
- ObjectProperty *prop = object_property_find(obj, name, errp);
+ ObjectProperty *prop = object_property_find_err(obj, name, errp);
if (prop == NULL) {
return NULL;
}
@@ -2025,7 +2035,7 @@ char *object_get_canonical_path(const Object *obj)
Object *object_resolve_path_component(Object *parent, const char *part)
{
- ObjectProperty *prop = object_property_find(parent, part, NULL);
+ ObjectProperty *prop = object_property_find(parent, part);
if (prop == NULL) {
return NULL;
}
@@ -2724,8 +2734,8 @@ object_property_add_alias(Object *obj, const char *name,
ObjectProperty *target_prop;
g_autofree char *prop_type = NULL;
- target_prop = object_property_find(target_obj, target_name,
- &error_abort);
+ target_prop = object_property_find_err(target_obj, target_name,
+ &error_abort);
if (object_property_is_child(target_prop)) {
prop_type = g_strdup_printf("link%s",
@@ -2758,7 +2768,7 @@ void object_property_set_description(Object *obj, const char *name,
{
ObjectProperty *op;
- op = object_property_find(obj, name, &error_abort);
+ op = object_property_find_err(obj, name, &error_abort);
g_free(op->description);
op->description = g_strdup(description);
}
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
index ba6e01a..375f34b 100644
--- a/target/arm/monitor.c
+++ b/target/arm/monitor.c
@@ -214,7 +214,7 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
i = 0;
while ((name = cpu_model_advertised_features[i++]) != NULL) {
- ObjectProperty *prop = object_property_find(obj, name, NULL);
+ ObjectProperty *prop = object_property_find(obj, name);
if (prop) {
QObject *value;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 1c58f76..3ffd877d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6828,7 +6828,7 @@ static void x86_cpu_register_bit_prop(X86CPU *cpu,
ObjectProperty *op;
uint64_t mask = (1ULL << bitnr);
- op = object_property_find(OBJECT(cpu), prop_name, NULL);
+ op = object_property_find(OBJECT(cpu), prop_name);
if (op) {
fp = op->opaque;
assert(fp->w == w);
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index accb4f2..bb66526 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -10478,7 +10478,7 @@ static void ppc_cpu_parse_featurestr(const char *type, char *features,
return;
}
- if (object_property_find(machine, "max-cpu-compat", NULL)) {
+ if (object_property_find(machine, "max-cpu-compat")) {
int i;
char **inpieces;
char *s = features;