12264Sjacobs /* 22264Sjacobs * CDDL HEADER START 32264Sjacobs * 42264Sjacobs * The contents of this file are subject to the terms of the 52264Sjacobs * Common Development and Distribution License (the "License"). 62264Sjacobs * You may not use this file except in compliance with the License. 72264Sjacobs * 82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92264Sjacobs * or http://www.opensolaris.org/os/licensing. 102264Sjacobs * See the License for the specific language governing permissions 112264Sjacobs * and limitations under the License. 122264Sjacobs * 132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 182264Sjacobs * 192264Sjacobs * CDDL HEADER END 202264Sjacobs */ 212264Sjacobs 222264Sjacobs /* 232264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 242264Sjacobs * Use is subject to license terms. 252264Sjacobs * 262264Sjacobs */ 272264Sjacobs 282264Sjacobs /* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */ 292264Sjacobs 302264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 312264Sjacobs 322264Sjacobs /*LINTLIBRARY*/ 332264Sjacobs 342264Sjacobs #include <stdio.h> 352264Sjacobs #include <stdlib.h> 362264Sjacobs #include <stdarg.h> 372264Sjacobs #include <string.h> 382264Sjacobs #include <alloca.h> 392264Sjacobs #include <papi.h> 402264Sjacobs 412264Sjacobs static void papiAttributeFree(papi_attribute_t *attribute); 422264Sjacobs 432264Sjacobs static void 442264Sjacobs papiAttributeValueFree(papi_attribute_value_type_t type, 452264Sjacobs papi_attribute_value_t *value) 462264Sjacobs { 472264Sjacobs if (value != NULL) { 482264Sjacobs switch (type) { 492264Sjacobs case PAPI_STRING: 502264Sjacobs if (value->string != NULL) 512264Sjacobs free(value->string); 522264Sjacobs break; 532264Sjacobs case PAPI_COLLECTION: 542264Sjacobs if (value->collection != NULL) { 552264Sjacobs int i; 562264Sjacobs 572264Sjacobs for (i = 0; value->collection[i] != NULL; i++) 582264Sjacobs papiAttributeFree(value->collection[i]); 592264Sjacobs 602264Sjacobs free(value->collection); 612264Sjacobs } 622264Sjacobs break; 632264Sjacobs default: /* don't need to free anything extra */ 642264Sjacobs break; 652264Sjacobs } 662264Sjacobs 672264Sjacobs free(value); 682264Sjacobs } 692264Sjacobs } 702264Sjacobs 712264Sjacobs static void 722264Sjacobs papiAttributeValuesFree(papi_attribute_value_type_t type, 732264Sjacobs papi_attribute_value_t **values) 742264Sjacobs { 752264Sjacobs if (values != NULL) { 762264Sjacobs int i; 772264Sjacobs 782264Sjacobs for (i = 0; values[i] != NULL; i++) 792264Sjacobs papiAttributeValueFree(type, values[i]); 802264Sjacobs 812264Sjacobs free(values); 822264Sjacobs } 832264Sjacobs } 842264Sjacobs 852264Sjacobs static void 862264Sjacobs papiAttributeFree(papi_attribute_t *attribute) 872264Sjacobs { 882264Sjacobs if (attribute != NULL) { 892264Sjacobs if (attribute->name != NULL) 902264Sjacobs free(attribute->name); 912264Sjacobs if (attribute->values != NULL) 922264Sjacobs papiAttributeValuesFree(attribute->type, 932264Sjacobs attribute->values); 942264Sjacobs free(attribute); 952264Sjacobs } 962264Sjacobs } 972264Sjacobs 982264Sjacobs void 992264Sjacobs papiAttributeListFree(papi_attribute_t **list) 1002264Sjacobs { 1012264Sjacobs if (list != NULL) { 1022264Sjacobs int i; 1032264Sjacobs 1042264Sjacobs for (i = 0; list[i] != NULL; i++) 1052264Sjacobs papiAttributeFree(list[i]); 1062264Sjacobs 1072264Sjacobs free(list); 1082264Sjacobs } 1092264Sjacobs } 1102264Sjacobs 1112264Sjacobs static papi_attribute_t ** 1122264Sjacobs collection_dup(papi_attribute_t **collection) 1132264Sjacobs { 1142264Sjacobs papi_attribute_t **result = NULL; 1152264Sjacobs 1162264Sjacobs /* allows a NULL collection that is "empty" or "no value" */ 1172264Sjacobs if (collection != NULL) { 1182264Sjacobs papi_status_t status = PAPI_OK; 1192264Sjacobs int i; 1202264Sjacobs 1212264Sjacobs for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); 1222264Sjacobs i++) { 1232264Sjacobs papi_attribute_t *a = collection[i]; 1242264Sjacobs 1252264Sjacobs status = papiAttributeListAddValue(&result, 1262264Sjacobs PAPI_ATTR_APPEND, a->name, a->type, 1272264Sjacobs NULL); 1282264Sjacobs if ((status == PAPI_OK) && (a->values != NULL)) { 1292264Sjacobs int j; 1302264Sjacobs 1312264Sjacobs for (j = 0; ((a->values[j] != NULL) && 1322264Sjacobs (status == PAPI_OK)); j++) 1332264Sjacobs status = papiAttributeListAddValue( 1342264Sjacobs &result, 1352264Sjacobs PAPI_ATTR_APPEND, 1362264Sjacobs a->name, a->type, 1372264Sjacobs a->values[j]); 1382264Sjacobs } 1392264Sjacobs } 1402264Sjacobs if (status != PAPI_OK) { 1412264Sjacobs papiAttributeListFree(result); 1422264Sjacobs result = NULL; 1432264Sjacobs } 1442264Sjacobs } 1452264Sjacobs 1462264Sjacobs return (result); 1472264Sjacobs } 1482264Sjacobs 1492264Sjacobs static papi_attribute_value_t * 1502264Sjacobs papiAttributeValueDup(papi_attribute_value_type_t type, 1512264Sjacobs papi_attribute_value_t *v) 1522264Sjacobs { 1532264Sjacobs papi_attribute_value_t *result = NULL; 1542264Sjacobs 1552264Sjacobs if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) { 1562264Sjacobs switch (type) { 1572264Sjacobs case PAPI_STRING: 1582264Sjacobs if (v->string == NULL) { 1592264Sjacobs free(result); 1602264Sjacobs result = NULL; 1612264Sjacobs } else 1622264Sjacobs result->string = strdup(v->string); 1632264Sjacobs break; 1642264Sjacobs case PAPI_INTEGER: 1652264Sjacobs result->integer = v->integer; 1662264Sjacobs break; 1672264Sjacobs case PAPI_BOOLEAN: 1682264Sjacobs result->boolean = v->boolean; 1692264Sjacobs break; 1702264Sjacobs case PAPI_RANGE: 1712264Sjacobs result->range.lower = v->range.lower; 1722264Sjacobs result->range.upper = v->range.upper; 1732264Sjacobs break; 1742264Sjacobs case PAPI_RESOLUTION: 1752264Sjacobs result->resolution.xres = v->resolution.xres; 1762264Sjacobs result->resolution.yres = v->resolution.yres; 1772264Sjacobs result->resolution.units = v->resolution.units; 1782264Sjacobs break; 1792264Sjacobs case PAPI_DATETIME: 1802264Sjacobs result->datetime = v->datetime; 1812264Sjacobs break; 1822264Sjacobs case PAPI_COLLECTION: 1832264Sjacobs result->collection = collection_dup(v->collection); 1842264Sjacobs break; 1852264Sjacobs case PAPI_METADATA: 1862264Sjacobs result->metadata = v->metadata; 1872264Sjacobs break; 1882264Sjacobs default: /* unknown type, fail to duplicate */ 1892264Sjacobs free(result); 1902264Sjacobs result = NULL; 1912264Sjacobs } 1922264Sjacobs } 1932264Sjacobs 1942264Sjacobs return (result); 1952264Sjacobs } 1962264Sjacobs 1972264Sjacobs static papi_attribute_t * 1982264Sjacobs papiAttributeAlloc(char *name, papi_attribute_value_type_t type) 1992264Sjacobs { 2002264Sjacobs papi_attribute_t *result = NULL; 2012264Sjacobs 2022264Sjacobs if ((result = calloc(1, sizeof (*result))) != NULL) { 2032264Sjacobs result->name = strdup(name); 2042264Sjacobs result->type = type; 2052264Sjacobs } 2062264Sjacobs 2072264Sjacobs return (result); 2082264Sjacobs } 2092264Sjacobs 2102264Sjacobs static papi_status_t 2112264Sjacobs papiAttributeListAppendValue(papi_attribute_value_t ***values, 2122264Sjacobs papi_attribute_value_type_t type, 2132264Sjacobs papi_attribute_value_t *value) 2142264Sjacobs { 2152264Sjacobs 2162264Sjacobs if (values == NULL) 2172264Sjacobs return (PAPI_BAD_ARGUMENT); 2182264Sjacobs 2192264Sjacobs if (value != NULL) { /* this allows "empty" attributes */ 2202264Sjacobs papi_attribute_value_t *tmp = NULL; 2212264Sjacobs 2222264Sjacobs if ((tmp = papiAttributeValueDup(type, value)) == NULL) 2232264Sjacobs return (PAPI_TEMPORARY_ERROR); 2242264Sjacobs 2252264Sjacobs list_append(values, tmp); 2262264Sjacobs } 2272264Sjacobs 2282264Sjacobs return (PAPI_OK); 2292264Sjacobs } 2302264Sjacobs 2312264Sjacobs papi_status_t 2322264Sjacobs papiAttributeListAddValue(papi_attribute_t ***list, int flgs, 2332264Sjacobs char *name, papi_attribute_value_type_t type, 2342264Sjacobs papi_attribute_value_t *value) 2352264Sjacobs { 2362264Sjacobs papi_status_t result; 2372264Sjacobs int flags = flgs; 2382264Sjacobs papi_attribute_t *attribute = NULL; 2392264Sjacobs papi_attribute_value_t **values = NULL; 2402264Sjacobs 2412264Sjacobs if ((list == NULL) || (name == NULL)) 2422264Sjacobs return (PAPI_BAD_ARGUMENT); 2432264Sjacobs 2442264Sjacobs if ((type == PAPI_RANGE) && (value != NULL) && 2452264Sjacobs (value->range.lower > value->range.upper)) 2462264Sjacobs return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */ 2472264Sjacobs 2482264Sjacobs if (flags == 0) /* if it wasn't set, set a default behaviour */ 2492264Sjacobs flags = PAPI_ATTR_APPEND; 2502264Sjacobs 2512264Sjacobs /* look for an existing one */ 2522264Sjacobs attribute = papiAttributeListFind(*list, name); 2532264Sjacobs 2542264Sjacobs if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL)) 2552264Sjacobs return (PAPI_CONFLICT); /* EXISTS */ 2562264Sjacobs 2572264Sjacobs if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) && 2582264Sjacobs (attribute->type != type)) 2592264Sjacobs return (PAPI_CONFLICT); /* TYPE CONFLICT */ 2602264Sjacobs 2612264Sjacobs /* if we don't have one, create it and add it to the list */ 2622264Sjacobs if ((attribute == NULL) && 2632264Sjacobs ((attribute = papiAttributeAlloc(name, type)) != NULL)) 2642264Sjacobs list_append(list, attribute); 2652264Sjacobs 2662264Sjacobs /* if we don't have one by now, it's most likely an alloc fail */ 2672264Sjacobs if (attribute == NULL) 2682264Sjacobs return (PAPI_TEMPORARY_ERROR); 2692264Sjacobs 2702264Sjacobs /* 2712264Sjacobs * if we are replacing, clear any existing values, but don't free 2722264Sjacobs * until after we have replaced the values, in case we are replacing 2732264Sjacobs * a collection with a relocated version of the original collection. 2742264Sjacobs */ 2752264Sjacobs if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) { 2762264Sjacobs values = attribute->values; 2772264Sjacobs attribute->values = NULL; 2782264Sjacobs } 2792264Sjacobs 2802264Sjacobs attribute->type = type; 2812264Sjacobs 2822264Sjacobs result = papiAttributeListAppendValue(&attribute->values, type, value); 2832264Sjacobs 2842264Sjacobs /* free old values if we replaced them */ 2852264Sjacobs if (values != NULL) 2862264Sjacobs papiAttributeValuesFree(type, values); 2872264Sjacobs 2882264Sjacobs return (result); 2892264Sjacobs } 2902264Sjacobs 2912264Sjacobs papi_status_t 2922264Sjacobs papiAttributeListAddString(papi_attribute_t ***list, int flags, 2932264Sjacobs char *name, char *string) 2942264Sjacobs { 2952264Sjacobs papi_attribute_value_t v; 2962264Sjacobs 2972264Sjacobs v.string = (char *)string; 2982264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); 2992264Sjacobs } 3002264Sjacobs 3012264Sjacobs papi_status_t 3022264Sjacobs papiAttributeListAddInteger(papi_attribute_t ***list, int flags, 3032264Sjacobs char *name, int integer) 3042264Sjacobs { 3052264Sjacobs papi_attribute_value_t v; 3062264Sjacobs 3072264Sjacobs v.integer = integer; 3082264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); 3092264Sjacobs } 3102264Sjacobs 3112264Sjacobs papi_status_t 3122264Sjacobs papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, 3132264Sjacobs char *name, char boolean) 3142264Sjacobs { 3152264Sjacobs papi_attribute_value_t v; 3162264Sjacobs 3172264Sjacobs v.boolean = boolean; 3182264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); 3192264Sjacobs } 3202264Sjacobs 3212264Sjacobs papi_status_t 3222264Sjacobs papiAttributeListAddRange(papi_attribute_t ***list, int flags, 3232264Sjacobs char *name, int lower, int upper) 3242264Sjacobs { 3252264Sjacobs papi_attribute_value_t v; 3262264Sjacobs 3272264Sjacobs v.range.lower = lower; 3282264Sjacobs v.range.upper = upper; 3292264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); 3302264Sjacobs } 3312264Sjacobs 3322264Sjacobs papi_status_t 3332264Sjacobs papiAttributeListAddResolution(papi_attribute_t ***list, int flags, 3342264Sjacobs char *name, int xres, int yres, 3352264Sjacobs papi_resolution_unit_t units) 3362264Sjacobs { 3372264Sjacobs papi_attribute_value_t v; 3382264Sjacobs 3392264Sjacobs v.resolution.xres = xres; 3402264Sjacobs v.resolution.yres = yres; 3412264Sjacobs v.resolution.units = units; 3422264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3432264Sjacobs PAPI_RESOLUTION, &v)); 3442264Sjacobs } 3452264Sjacobs 3462264Sjacobs papi_status_t 3472264Sjacobs papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, 3482264Sjacobs char *name, time_t datetime) 3492264Sjacobs { 3502264Sjacobs papi_attribute_value_t v; 3512264Sjacobs 3522264Sjacobs v.datetime = datetime; 3532264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3542264Sjacobs PAPI_DATETIME, &v)); 3552264Sjacobs } 3562264Sjacobs 3572264Sjacobs papi_status_t 3582264Sjacobs papiAttributeListAddCollection(papi_attribute_t ***list, int flags, 3592264Sjacobs char *name, papi_attribute_t **collection) 3602264Sjacobs { 3612264Sjacobs papi_attribute_value_t v; 3622264Sjacobs 3632264Sjacobs v.collection = (papi_attribute_t **)collection; 3642264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3652264Sjacobs PAPI_COLLECTION, &v)); 3662264Sjacobs } 3672264Sjacobs 3682264Sjacobs papi_status_t 3692264Sjacobs papiAttributeListAddMetadata(papi_attribute_t ***list, int flags, 3702264Sjacobs char *name, papi_metadata_t metadata) 3712264Sjacobs { 3722264Sjacobs papi_attribute_value_t v; 3732264Sjacobs 3742264Sjacobs v.metadata = metadata; 3752264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3762264Sjacobs PAPI_METADATA, &v)); 3772264Sjacobs } 3782264Sjacobs 3792264Sjacobs papi_status_t 3802264Sjacobs papiAttributeListDelete(papi_attribute_t ***list, char *name) 3812264Sjacobs { 3822264Sjacobs papi_attribute_t *attribute; 3832264Sjacobs 3842264Sjacobs if ((list == NULL) || (name == NULL)) 3852264Sjacobs return (PAPI_BAD_ARGUMENT); 3862264Sjacobs 3872264Sjacobs if ((attribute = papiAttributeListFind(*list, name)) == NULL) 3882264Sjacobs return (PAPI_NOT_FOUND); 3892264Sjacobs 390*3125Sjacobs list_remove(list, attribute); 3912264Sjacobs papiAttributeFree(attribute); 3922264Sjacobs 3932264Sjacobs return (PAPI_OK); 3942264Sjacobs } 3952264Sjacobs 3962264Sjacobs papi_attribute_t * 3972264Sjacobs papiAttributeListFind(papi_attribute_t **list, char *name) 3982264Sjacobs { 3992264Sjacobs int i; 4002264Sjacobs if ((list == NULL) || (name == NULL)) 4012264Sjacobs return (NULL); 4022264Sjacobs 4032264Sjacobs for (i = 0; list[i] != NULL; i++) 4042264Sjacobs if (strcasecmp(list[i]->name, name) == 0) 4052264Sjacobs return ((papi_attribute_t *)list[i]); 4062264Sjacobs 4072264Sjacobs return (NULL); 4082264Sjacobs } 4092264Sjacobs 4102264Sjacobs papi_attribute_t * 4112264Sjacobs papiAttributeListGetNext(papi_attribute_t **list, void **iter) 4122264Sjacobs { 4132264Sjacobs papi_attribute_t **tmp, *result; 4142264Sjacobs 4152264Sjacobs if ((list == NULL) && (iter == NULL)) 4162264Sjacobs return (NULL); 4172264Sjacobs 4182264Sjacobs if (*iter == NULL) 4192264Sjacobs *iter = list; 4202264Sjacobs 4212264Sjacobs tmp = *iter; 4222264Sjacobs result = *tmp; 4232264Sjacobs *iter = ++tmp; 4242264Sjacobs 4252264Sjacobs return (result); 4262264Sjacobs } 4272264Sjacobs 4282264Sjacobs papi_status_t 4292264Sjacobs papiAttributeListGetValue(papi_attribute_t **list, void **iter, 4302264Sjacobs char *name, papi_attribute_value_type_t type, 4312264Sjacobs papi_attribute_value_t **value) 4322264Sjacobs { 4332264Sjacobs papi_attribute_value_t **tmp; 4342264Sjacobs void *fodder = NULL; 4352264Sjacobs 4362264Sjacobs if ((list == NULL) || ((name == NULL) && (iter == NULL)) || 4372264Sjacobs (value == NULL)) 4382264Sjacobs return (PAPI_BAD_ARGUMENT); 4392264Sjacobs 4402264Sjacobs if (iter == NULL) 4412264Sjacobs iter = &fodder; 4422264Sjacobs 4432264Sjacobs if ((iter == NULL) || (*iter == NULL)) { 4442264Sjacobs papi_attribute_t *attr = papiAttributeListFind(list, name); 4452264Sjacobs 4462264Sjacobs if (attr == NULL) 4472264Sjacobs return (PAPI_NOT_FOUND); 4482264Sjacobs 4492264Sjacobs if (attr->type != type) 4502264Sjacobs return (PAPI_NOT_POSSIBLE); 4512264Sjacobs 4522264Sjacobs tmp = attr->values; 4532264Sjacobs } else 4542264Sjacobs tmp = *iter; 4552264Sjacobs 4562264Sjacobs if (tmp == NULL) 4572264Sjacobs return (PAPI_NOT_FOUND); 4582264Sjacobs 4592264Sjacobs *value = *tmp; 4602264Sjacobs *iter = ++tmp; 4612264Sjacobs 4622264Sjacobs if (*value == NULL) 4632264Sjacobs return (PAPI_GONE); 4642264Sjacobs 4652264Sjacobs return (PAPI_OK); 4662264Sjacobs } 4672264Sjacobs 4682264Sjacobs papi_status_t 4692264Sjacobs papiAttributeListGetString(papi_attribute_t **list, void **iter, 4702264Sjacobs char *name, char **vptr) 4712264Sjacobs { 4722264Sjacobs papi_status_t status; 4732264Sjacobs papi_attribute_value_t *value = NULL; 4742264Sjacobs 4752264Sjacobs if (vptr == NULL) 4762264Sjacobs return (PAPI_BAD_ARGUMENT); 4772264Sjacobs 4782264Sjacobs status = papiAttributeListGetValue(list, iter, name, 4792264Sjacobs PAPI_STRING, &value); 4802264Sjacobs if (status == PAPI_OK) 4812264Sjacobs *vptr = value->string; 4822264Sjacobs 4832264Sjacobs return (status); 4842264Sjacobs } 4852264Sjacobs 4862264Sjacobs papi_status_t 4872264Sjacobs papiAttributeListGetInteger(papi_attribute_t **list, void **iter, 4882264Sjacobs char *name, int *vptr) 4892264Sjacobs { 4902264Sjacobs papi_status_t status; 4912264Sjacobs papi_attribute_value_t *value = NULL; 4922264Sjacobs 4932264Sjacobs if (vptr == NULL) 4942264Sjacobs return (PAPI_BAD_ARGUMENT); 4952264Sjacobs 4962264Sjacobs status = papiAttributeListGetValue(list, iter, name, 4972264Sjacobs PAPI_INTEGER, &value); 4982264Sjacobs if (status == PAPI_OK) 4992264Sjacobs *vptr = value->integer; 5002264Sjacobs 5012264Sjacobs return (status); 5022264Sjacobs } 5032264Sjacobs 5042264Sjacobs papi_status_t 5052264Sjacobs papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, 5062264Sjacobs char *name, char *vptr) 5072264Sjacobs { 5082264Sjacobs papi_status_t status; 5092264Sjacobs papi_attribute_value_t *value = NULL; 5102264Sjacobs 5112264Sjacobs if (vptr == NULL) 5122264Sjacobs return (PAPI_BAD_ARGUMENT); 5132264Sjacobs 5142264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5152264Sjacobs PAPI_BOOLEAN, &value); 5162264Sjacobs if (status == PAPI_OK) 5172264Sjacobs *vptr = value->boolean; 5182264Sjacobs 5192264Sjacobs return (status); 5202264Sjacobs } 5212264Sjacobs 5222264Sjacobs papi_status_t 5232264Sjacobs papiAttributeListGetRange(papi_attribute_t **list, void **iter, 5242264Sjacobs char *name, int *min, int *max) 5252264Sjacobs { 5262264Sjacobs papi_status_t status; 5272264Sjacobs papi_attribute_value_t *value = NULL; 5282264Sjacobs 5292264Sjacobs if ((min == NULL) || (max == NULL)) 5302264Sjacobs return (PAPI_BAD_ARGUMENT); 5312264Sjacobs 5322264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5332264Sjacobs PAPI_RANGE, &value); 5342264Sjacobs if (status == PAPI_OK) { 5352264Sjacobs *min = value->range.lower; 5362264Sjacobs *max = value->range.upper; 5372264Sjacobs } 5382264Sjacobs 5392264Sjacobs return (status); 5402264Sjacobs } 5412264Sjacobs 5422264Sjacobs papi_status_t 5432264Sjacobs papiAttributeListGetResolution(papi_attribute_t **list, void **iter, 5442264Sjacobs char *name, int *x, int *y, 5452264Sjacobs papi_resolution_unit_t *units) 5462264Sjacobs { 5472264Sjacobs papi_status_t status; 5482264Sjacobs papi_attribute_value_t *value = NULL; 5492264Sjacobs 5502264Sjacobs if ((x == NULL) || (y == NULL) || (units == NULL)) 5512264Sjacobs return (PAPI_BAD_ARGUMENT); 5522264Sjacobs 5532264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5542264Sjacobs PAPI_RESOLUTION, &value); 5552264Sjacobs if (status == PAPI_OK) { 5562264Sjacobs *x = value->resolution.xres; 5572264Sjacobs *y = value->resolution.yres; 5582264Sjacobs *units = value->resolution.units; 5592264Sjacobs } 5602264Sjacobs 5612264Sjacobs return (status); 5622264Sjacobs } 5632264Sjacobs 5642264Sjacobs papi_status_t 5652264Sjacobs papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, 5662264Sjacobs char *name, time_t *dt) 5672264Sjacobs { 5682264Sjacobs papi_status_t status; 5692264Sjacobs papi_attribute_value_t *value = NULL; 5702264Sjacobs 5712264Sjacobs if (dt == NULL) 5722264Sjacobs return (PAPI_BAD_ARGUMENT); 5732264Sjacobs 5742264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5752264Sjacobs PAPI_DATETIME, &value); 5762264Sjacobs if (status == PAPI_OK) { 5772264Sjacobs *dt = value->datetime; 5782264Sjacobs } 5792264Sjacobs 5802264Sjacobs return (status); 5812264Sjacobs } 5822264Sjacobs 5832264Sjacobs papi_status_t 5842264Sjacobs papiAttributeListGetCollection(papi_attribute_t **list, void **iter, 5852264Sjacobs char *name, papi_attribute_t ***collection) 5862264Sjacobs { 5872264Sjacobs papi_status_t status; 5882264Sjacobs papi_attribute_value_t *value = NULL; 5892264Sjacobs 5902264Sjacobs if (collection == NULL) 5912264Sjacobs return (PAPI_BAD_ARGUMENT); 5922264Sjacobs 5932264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5942264Sjacobs PAPI_COLLECTION, &value); 5952264Sjacobs if (status == PAPI_OK) { 5962264Sjacobs *collection = value->collection; 5972264Sjacobs } 5982264Sjacobs 5992264Sjacobs return (status); 6002264Sjacobs } 6012264Sjacobs 6022264Sjacobs papi_status_t 6032264Sjacobs papiAttributeListGetMetadata(papi_attribute_t **list, void **iter, 6042264Sjacobs char *name, papi_metadata_t *vptr) 6052264Sjacobs { 6062264Sjacobs papi_status_t status; 6072264Sjacobs papi_attribute_value_t *value = NULL; 6082264Sjacobs 6092264Sjacobs if (vptr == NULL) 6102264Sjacobs return (PAPI_BAD_ARGUMENT); 6112264Sjacobs 6122264Sjacobs status = papiAttributeListGetValue(list, iter, name, 6132264Sjacobs PAPI_METADATA, &value); 6142264Sjacobs if (status == PAPI_OK) 6152264Sjacobs *vptr = value->metadata; 6162264Sjacobs 6172264Sjacobs return (status); 6182264Sjacobs } 6192264Sjacobs 6202264Sjacobs /* 6212264Sjacobs * Description: The given string contains one or more attributes, in the 6222264Sjacobs * following form: 6232264Sjacobs * "aaaa=true bbbbb=1 ccccc=abcd" 6242264Sjacobs * extract the next attribute from that string; the 'next' 6252264Sjacobs * parameter should be set to zero to extract the first attribute 6262264Sjacobs * in the string. 6272264Sjacobs * 6282264Sjacobs */ 6292264Sjacobs 6302264Sjacobs static char * 6312264Sjacobs _getNextAttr(char *string, int *next) 6322264Sjacobs 6332264Sjacobs { 6342264Sjacobs char *result = NULL; 6352264Sjacobs char *start = (char *)string + *next; 6362264Sjacobs char *nl = NULL; 6372264Sjacobs char *sp = NULL; 6382264Sjacobs char *tab = NULL; 6392264Sjacobs char *val = NULL; 6402264Sjacobs int len = 0; 6412264Sjacobs 6422264Sjacobs if ((string != NULL) && (*start != '\0')) { 6432264Sjacobs while ((*start == ' ') || (*start == '\t') || (*start == '\n')) 6442264Sjacobs { 6452264Sjacobs start++; 6462264Sjacobs } 6472264Sjacobs nl = strchr(start, '\n'); 6482264Sjacobs sp = strchr(start, ' '); 6492264Sjacobs tab = strchr(start, '\t'); 6502264Sjacobs 6512264Sjacobs val = strchr(start, '='); 6522264Sjacobs 6532264Sjacobs if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) { 6542264Sjacobs val = strchr(&val[2], val[1]); 6552264Sjacobs if (val != NULL) { 6562264Sjacobs nl = strchr(&val[1], '\n'); 6572264Sjacobs sp = strchr(&val[1], ' '); 6582264Sjacobs tab = strchr(&val[1], '\t'); 6592264Sjacobs } 6602264Sjacobs } 6612264Sjacobs 6622264Sjacobs if ((nl != NULL) && 6632264Sjacobs ((sp == NULL) || ((sp != NULL) && (nl < sp))) && 6642264Sjacobs ((tab == NULL) || ((tab != NULL) && (nl < tab)))) { 6652264Sjacobs len = nl-start; 6662264Sjacobs } else if ((sp != NULL) && (tab != NULL) && (sp > tab)) { 6672264Sjacobs len = tab-start; 6682264Sjacobs } else if ((sp != NULL) && (sp != NULL)) { 6692264Sjacobs len = sp-start; 6702264Sjacobs } else if ((tab != NULL) && (tab != NULL)) { 6712264Sjacobs len = tab-start; 6722264Sjacobs } 6732264Sjacobs 6742264Sjacobs if (len == 0) { 6752264Sjacobs len = strlen(start); 6762264Sjacobs } 6772264Sjacobs 6782264Sjacobs if (len > 0) { 6792264Sjacobs result = (char *)malloc(len+1); 6802264Sjacobs if (result != NULL) { 6812264Sjacobs strncpy(result, start, len); 6822264Sjacobs result[len] = '\0'; 6832264Sjacobs *next = (start-string)+len; 6842264Sjacobs } 6852264Sjacobs } 6862264Sjacobs } 6872264Sjacobs 6882264Sjacobs return (result); 6892264Sjacobs } /* _getNextAttr() */ 6902264Sjacobs 6912264Sjacobs 6922264Sjacobs /* 6932264Sjacobs * Description: Parse the given attribute string value and transform it into 6942264Sjacobs * the papi_attribute_value_t in the papi_attribute_t structure. 6952264Sjacobs * 6962264Sjacobs */ 6972264Sjacobs 6982264Sjacobs static papi_status_t 6992264Sjacobs _parseAttrValue(char *value, papi_attribute_t *attr) 7002264Sjacobs 7012264Sjacobs { 7022264Sjacobs papi_status_t result = PAPI_OK; 7032264Sjacobs int len = 0; 7042264Sjacobs int i = 0; 7052264Sjacobs char *papiString = NULL; 7062264Sjacobs char *tmp1 = NULL; 7072264Sjacobs char *tmp2 = NULL; 7082264Sjacobs char *tmp3 = NULL; 7092264Sjacobs papi_attribute_value_t **avalues = NULL; 7102264Sjacobs 7112264Sjacobs avalues = malloc(sizeof (papi_attribute_value_t *) * 2); 7122264Sjacobs if (avalues == NULL) { 7132264Sjacobs result = PAPI_TEMPORARY_ERROR; 7142264Sjacobs return (result); 7152264Sjacobs } 7162264Sjacobs avalues[0] = malloc(sizeof (papi_attribute_value_t)); 7172264Sjacobs avalues[1] = NULL; 7182264Sjacobs if (avalues[0] == NULL) { 7192264Sjacobs free(avalues); 7202264Sjacobs result = PAPI_TEMPORARY_ERROR; 7212264Sjacobs return (result); 7222264Sjacobs } 7232264Sjacobs 7242264Sjacobs 7252264Sjacobs /* 7262264Sjacobs * TODO - need to sort out 'resolution', 'dateandtime' & 'collection' values 7272264Sjacobs */ 7282264Sjacobs if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) { 7292264Sjacobs 7302264Sjacobs len = strlen(value); 7312264Sjacobs if ((len >= 2) && (((value[0] == '"') && 7322264Sjacobs (value[len-1] == '"')) || ((value[0] == '\'') && 7332264Sjacobs (value[len-1] == '\'')))) { 7342264Sjacobs /* string value */ 7352264Sjacobs attr->type = PAPI_STRING; 7362264Sjacobs 7372264Sjacobs papiString = strdup(value+1); 7382264Sjacobs if (papiString != NULL) { 7392264Sjacobs papiString[strlen(papiString)-1] = '\0'; 7402264Sjacobs avalues[0]->string = papiString; 7412264Sjacobs } else { 7422264Sjacobs result = PAPI_TEMPORARY_ERROR; 7432264Sjacobs } 7442264Sjacobs } else if ((strcasecmp(value, "true") == 0) || 7452264Sjacobs (strcasecmp(value, "YES") == 0)) { 7462264Sjacobs /* boolean = true */ 7472264Sjacobs attr->type = PAPI_BOOLEAN; 7482264Sjacobs avalues[0]->boolean = PAPI_TRUE; 7492264Sjacobs } else if ((strcasecmp(value, "false") == 0) || 7502264Sjacobs (strcasecmp(value, "NO") == 0)) { 7512264Sjacobs /* boolean = false */ 7522264Sjacobs attr->type = PAPI_BOOLEAN; 7532264Sjacobs avalues[0]->boolean = PAPI_FALSE; 7542264Sjacobs } else { 7552264Sjacobs /* is value an integer or a range ? */ 7562264Sjacobs 7572264Sjacobs i = 0; 7582264Sjacobs attr->type = PAPI_INTEGER; 7592264Sjacobs tmp1 = strdup(value); 7602264Sjacobs while (((value[i] >= '0') && (value[i] <= '9')) || 7612264Sjacobs (value[i] == '-')) { 7622264Sjacobs if (value[i] == '-') { 7632264Sjacobs tmp1[i] = '\0'; 7642264Sjacobs tmp2 = &tmp1[i+1]; 7652264Sjacobs attr->type = PAPI_RANGE; 7662264Sjacobs } 7672264Sjacobs 7682264Sjacobs i++; 7692264Sjacobs } 7702264Sjacobs 7712264Sjacobs if (strlen(value) == i) { 7722264Sjacobs if (attr->type == PAPI_RANGE) { 7732264Sjacobs avalues[0]->range.lower = atoi(tmp1); 7742264Sjacobs avalues[0]->range.upper = atoi(tmp2); 7752264Sjacobs } else { 7762264Sjacobs avalues[0]->integer = atoi(value); 7772264Sjacobs } 7782264Sjacobs } else { 7792264Sjacobs /* is value a resolution ? */ 7802264Sjacobs i = 0; 7812264Sjacobs attr->type = PAPI_INTEGER; 7822264Sjacobs tmp1 = strdup(value); 7832264Sjacobs while (((value[i] >= '0') && 7842264Sjacobs (value[i] <= '9')) || 7852264Sjacobs (value[i] == 'x')) { 7862264Sjacobs if (value[i] == 'x') { 7872264Sjacobs tmp1[i] = '\0'; 7882264Sjacobs if (attr->type == PAPI_INTEGER) 7892264Sjacobs { 7902264Sjacobs tmp2 = &tmp1[i+1]; 7912264Sjacobs attr->type = 7922264Sjacobs PAPI_RESOLUTION; 7932264Sjacobs } else { 7942264Sjacobs tmp3 = &tmp1[i+1]; 7952264Sjacobs } 7962264Sjacobs } 7972264Sjacobs 7982264Sjacobs i++; 7992264Sjacobs } 8002264Sjacobs 8012264Sjacobs if (strlen(value) == i) { 8022264Sjacobs if (attr->type == PAPI_RESOLUTION) { 8032264Sjacobs avalues[0]->resolution.xres = 8042264Sjacobs atoi(tmp1); 8052264Sjacobs avalues[0]->resolution.yres = 8062264Sjacobs atoi(tmp2); 8072264Sjacobs if (tmp3 != NULL) { 8082264Sjacobs avalues[0]-> 8092264Sjacobs resolution.units = 8102264Sjacobs atoi(tmp3); 8112264Sjacobs } else { 8122264Sjacobs avalues[0]-> 8132264Sjacobs resolution.units = 0; 8142264Sjacobs } 8152264Sjacobs } 8162264Sjacobs } 8172264Sjacobs 8182264Sjacobs if (attr->type != PAPI_RESOLUTION) { 8192264Sjacobs attr->type = PAPI_STRING; 8202264Sjacobs avalues[0]->string = strdup(value); 8212264Sjacobs if (avalues[0]->string == NULL) { 8222264Sjacobs result = PAPI_TEMPORARY_ERROR; 8232264Sjacobs } 8242264Sjacobs } 8252264Sjacobs } 8262264Sjacobs free(tmp1); 8272264Sjacobs } 8282264Sjacobs 8292264Sjacobs } else { 8302264Sjacobs result = PAPI_BAD_ARGUMENT; 8312264Sjacobs } 8322264Sjacobs 8332264Sjacobs if (result != PAPI_OK) { 8342264Sjacobs i = 0; 8352264Sjacobs while (avalues[i] != NULL) { 8362264Sjacobs free(avalues[i]); 8372264Sjacobs i++; 8382264Sjacobs } 8392264Sjacobs free(avalues); 8402264Sjacobs } else { 8412264Sjacobs attr->values = avalues; 8422264Sjacobs } 8432264Sjacobs 8442264Sjacobs return (result); 8452264Sjacobs } /* _parseAttrValue() */ 8462264Sjacobs 8472264Sjacobs 8482264Sjacobs /* 8492264Sjacobs * Description: Parse the given attribute string and transform it into the 8502264Sjacobs * papi_attribute_t structure. 8512264Sjacobs * 8522264Sjacobs */ 8532264Sjacobs 8542264Sjacobs static papi_status_t 8552264Sjacobs _parseAttributeString(char *attrString, papi_attribute_t *attr) 8562264Sjacobs 8572264Sjacobs { 8582264Sjacobs papi_status_t result = PAPI_OK; 8592264Sjacobs char *string = NULL; 8602264Sjacobs char *p = NULL; 8612264Sjacobs papi_attribute_value_t **avalues = NULL; 8622264Sjacobs 8632264Sjacobs if ((attrString != NULL) && (strlen(attrString) >= 3) && 8642264Sjacobs (attr != NULL)) { 8652264Sjacobs attr->name = NULL; 8662264Sjacobs string = strdup(attrString); 8672264Sjacobs if (string != NULL) { 8682264Sjacobs p = strchr(string, '='); 8692264Sjacobs if (p != NULL) { 8702264Sjacobs *p = '\0'; 8712264Sjacobs attr->name = string; 8722264Sjacobs p++; /* pointer to value */ 8732264Sjacobs 8742264Sjacobs result = _parseAttrValue(p, attr); 8752264Sjacobs } else { 8762264Sjacobs char value; 8772264Sjacobs /* boolean - no value so assume 'true' */ 8782264Sjacobs if (strncasecmp(string, "no", 2) == 0) { 8792264Sjacobs string += 2; 8802264Sjacobs value = PAPI_FALSE; 8812264Sjacobs } else 8822264Sjacobs value = PAPI_TRUE; 8832264Sjacobs 8842264Sjacobs attr->name = string; 8852264Sjacobs attr->type = PAPI_BOOLEAN; 8862264Sjacobs 8872264Sjacobs avalues = malloc( 8882264Sjacobs sizeof (papi_attribute_value_t *) * 2); 8892264Sjacobs if (avalues == NULL) { 8902264Sjacobs result = PAPI_TEMPORARY_ERROR; 8912264Sjacobs } else { 8922264Sjacobs avalues[0] = malloc( 8932264Sjacobs sizeof (papi_attribute_value_t)); 8942264Sjacobs avalues[1] = NULL; 8952264Sjacobs if (avalues[0] == NULL) { 8962264Sjacobs free(avalues); 8972264Sjacobs result = PAPI_TEMPORARY_ERROR; 8982264Sjacobs } else { 8992264Sjacobs avalues[0]->boolean = value; 9002264Sjacobs attr->values = avalues; 9012264Sjacobs } 9022264Sjacobs } 9032264Sjacobs } 9042264Sjacobs } 9052264Sjacobs } else { 9062264Sjacobs result = PAPI_BAD_ARGUMENT; 9072264Sjacobs } 9082264Sjacobs 9092264Sjacobs return (result); 9102264Sjacobs } /* _parseAttributeString() */ 9112264Sjacobs 9122264Sjacobs 9132264Sjacobs papi_status_t 9142264Sjacobs papiAttributeListFromString(papi_attribute_t ***attrs, 9152264Sjacobs int flags, char *string) 9162264Sjacobs { 9172264Sjacobs papi_status_t result = PAPI_OK; 9182264Sjacobs int next = 0; 9192264Sjacobs char *attrString = NULL; 9202264Sjacobs papi_attribute_t attr; 9212264Sjacobs 9222264Sjacobs if ((attrs != NULL) && (string != NULL) && 9232264Sjacobs ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) 9242264Sjacobs == 0)) { 9252264Sjacobs attrString = _getNextAttr(string, &next); 9262264Sjacobs while ((result == PAPI_OK) && (attrString != NULL)) { 9272264Sjacobs result = _parseAttributeString(attrString, &attr); 9282264Sjacobs if ((result == PAPI_OK) && (attr.name != NULL)) { 9292264Sjacobs /* add this attribute to the list */ 9302264Sjacobs if ((attr.values != NULL) && 9312264Sjacobs (attr.values[0] != NULL)) { 9322264Sjacobs result = papiAttributeListAddValue( 9332264Sjacobs attrs, PAPI_ATTR_APPEND, 9342264Sjacobs attr.name, attr.type, 9352264Sjacobs attr.values[0]); 9362264Sjacobs free(attr.values[0]); 9372264Sjacobs free(attr.values); 9382264Sjacobs } else { 9392264Sjacobs result = PAPI_TEMPORARY_ERROR; 9402264Sjacobs } 9412264Sjacobs } 9422264Sjacobs free(attrString); 9432264Sjacobs 9442264Sjacobs attrString = _getNextAttr(string, &next); 9452264Sjacobs } 9462264Sjacobs } 9472264Sjacobs else 9482264Sjacobs { 9492264Sjacobs result = PAPI_BAD_ARGUMENT; 9502264Sjacobs } 9512264Sjacobs 9522264Sjacobs return (result); 9532264Sjacobs } 9542264Sjacobs 9552264Sjacobs static papi_status_t 9562264Sjacobs papiAttributeToString(papi_attribute_t *attribute, char *delim, 9572264Sjacobs char *buffer, size_t buflen) 9582264Sjacobs { 9592264Sjacobs papi_attribute_value_t **values = attribute->values; 9602264Sjacobs int rc, i; 9612264Sjacobs 9622264Sjacobs strlcat(buffer, attribute->name, buflen); 9632264Sjacobs strlcat(buffer, "=", buflen); 9642264Sjacobs 9652264Sjacobs if (values == NULL) 9662264Sjacobs return (PAPI_OK); 9672264Sjacobs 9682264Sjacobs for (i = 0; values[i] != NULL; i++) { 9692264Sjacobs switch (attribute->type) { 9702264Sjacobs case PAPI_STRING: 9712264Sjacobs rc = strlcat(buffer, values[i]->string, buflen); 9722264Sjacobs break; 9732264Sjacobs case PAPI_INTEGER: { 9742264Sjacobs char string[24]; 9752264Sjacobs 9762264Sjacobs snprintf(string, sizeof (string), "%d", 9772264Sjacobs values[i]->integer); 9782264Sjacobs rc = strlcat(buffer, string, buflen); 9792264Sjacobs } 9802264Sjacobs break; 9812264Sjacobs case PAPI_BOOLEAN: 9822264Sjacobs rc = strlcat(buffer, (values[i]->boolean ? "true" : 9832264Sjacobs "false"), buflen); 9842264Sjacobs break; 9852264Sjacobs case PAPI_RANGE: { 9862264Sjacobs char string[24]; 9872264Sjacobs 9882264Sjacobs snprintf(string, sizeof (string), "%d-%d", 9892264Sjacobs values[i]->range.lower, values[i]->range.upper); 9902264Sjacobs rc = strlcat(buffer, string, buflen); 9912264Sjacobs } 9922264Sjacobs break; 9932264Sjacobs case PAPI_RESOLUTION: { 9942264Sjacobs char string[24]; 9952264Sjacobs 9962264Sjacobs snprintf(string, sizeof (string), "%dx%ddp%c", 9972264Sjacobs values[i]->resolution.xres, 9982264Sjacobs values[i]->resolution.yres, 9992264Sjacobs (values[i]->resolution.units == PAPI_RES_PER_CM 10002264Sjacobs ? 'c' : 'i')); 10012264Sjacobs rc = strlcat(buffer, string, buflen); 10022264Sjacobs } 10032264Sjacobs break; 10042264Sjacobs case PAPI_DATETIME: { 10052264Sjacobs struct tm *tm = localtime(&values[i]->datetime); 10062264Sjacobs 10072264Sjacobs if (tm != NULL) { 10082264Sjacobs char string[64]; 10092264Sjacobs 10102264Sjacobs strftime(string, sizeof (string), "%C", tm); 10112264Sjacobs rc = strlcat(buffer, string, buflen); 10122264Sjacobs }} 10132264Sjacobs break; 10142264Sjacobs case PAPI_COLLECTION: { 10152264Sjacobs char *string = alloca(buflen); 10162264Sjacobs #ifdef DEBUG 10172264Sjacobs char prefix[256]; 10182264Sjacobs 10192264Sjacobs snprintf(prefix, sizeof (prefix), "%s %s(%d) ", delim, 10202264Sjacobs attribute->name, i); 10212264Sjacobs 10222264Sjacobs papiAttributeListToString(values[i]->collection, 10232264Sjacobs prefix, string, buflen); 10242264Sjacobs #else 10252264Sjacobs papiAttributeListToString(values[i]->collection, 10262264Sjacobs delim, string, buflen); 10272264Sjacobs #endif 10282264Sjacobs rc = strlcat(buffer, string, buflen); 10292264Sjacobs } 10302264Sjacobs break; 10312264Sjacobs default: { 10322264Sjacobs char string[32]; 10332264Sjacobs 10342264Sjacobs snprintf(string, sizeof (string), "unknown-type-0x%x", 10352264Sjacobs attribute->type); 10362264Sjacobs rc = strlcat(buffer, string, buflen); 10372264Sjacobs } 10382264Sjacobs } 10392264Sjacobs if (values[i+1] != NULL) 10402264Sjacobs rc = strlcat(buffer, ",", buflen); 10412264Sjacobs 10422264Sjacobs if (rc >= buflen) 10432264Sjacobs return (PAPI_NOT_POSSIBLE); 10442264Sjacobs 10452264Sjacobs } 10462264Sjacobs 10472264Sjacobs return (PAPI_OK); 10482264Sjacobs } 10492264Sjacobs 10502264Sjacobs papi_status_t 10512264Sjacobs papiAttributeListToString(papi_attribute_t **attrs, 10522264Sjacobs char *delim, char *buffer, size_t buflen) 10532264Sjacobs { 10542264Sjacobs papi_status_t status = PAPI_OK; 10552264Sjacobs int i; 10562264Sjacobs 10572264Sjacobs if ((attrs == NULL) || (buffer == NULL)) 10582264Sjacobs return (PAPI_BAD_ARGUMENT); 10592264Sjacobs 10602264Sjacobs buffer[0] = '\0'; 10612264Sjacobs if (!delim) 10622264Sjacobs delim = " "; 10632264Sjacobs 10642264Sjacobs #ifdef DEBUG 10652264Sjacobs strlcat(buffer, delim, buflen); 10662264Sjacobs #endif 10672264Sjacobs for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) { 10682264Sjacobs status = papiAttributeToString(attrs[i], delim, buffer, buflen); 10692264Sjacobs if (attrs[i+1] != NULL) 10702264Sjacobs strlcat(buffer, delim, buflen); 10712264Sjacobs } 10722264Sjacobs 10732264Sjacobs return (status); 10742264Sjacobs } 10752264Sjacobs 10762264Sjacobs static int 10772264Sjacobs is_in_list(char *value, char **list) 10782264Sjacobs { 10792264Sjacobs if ((list != NULL) && (value != NULL)) { 10802264Sjacobs int i; 10812264Sjacobs 10822264Sjacobs for (i = 0; list[i] != NULL; i++) 10832264Sjacobs if (strcasecmp(value, list[i]) == 0) 10842264Sjacobs return (0); 10852264Sjacobs } 10862264Sjacobs 10872264Sjacobs return (1); 10882264Sjacobs } 10892264Sjacobs 10902264Sjacobs static papi_status_t 10912264Sjacobs copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute) 10922264Sjacobs { 10932264Sjacobs papi_status_t status; 10942264Sjacobs int i = 0; 10952264Sjacobs 10962264Sjacobs if ((list == NULL) || (attribute == NULL) || 10972264Sjacobs (attribute->values == NULL)) 10982264Sjacobs return (PAPI_BAD_ARGUMENT); 10992264Sjacobs 11002264Sjacobs for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL, 11012264Sjacobs attribute->name, attribute->type, 11022264Sjacobs attribute->values[i]); 11032264Sjacobs ((status == PAPI_OK) && (attribute->values[i] != NULL)); 11042264Sjacobs status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND, 11052264Sjacobs attribute->name, attribute->type, 11062264Sjacobs attribute->values[i])) 11072264Sjacobs i++; 11082264Sjacobs 11092264Sjacobs return (status); 11102264Sjacobs } 11112264Sjacobs 11122264Sjacobs void 11132264Sjacobs copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes) 11142264Sjacobs { 11152264Sjacobs int i; 11162264Sjacobs 11172264Sjacobs if ((result == NULL) || (attributes == NULL)) 11182264Sjacobs return; 11192264Sjacobs 11202264Sjacobs for (i = 0; attributes[i] != NULL; i++) 11212264Sjacobs copy_attribute(result, attributes[i]); 11222264Sjacobs } 11232264Sjacobs 11242264Sjacobs void 11252264Sjacobs split_and_copy_attributes(char **list, papi_attribute_t **attributes, 11262264Sjacobs papi_attribute_t ***in, papi_attribute_t ***out) 11272264Sjacobs { 11282264Sjacobs int i; 11292264Sjacobs 11302264Sjacobs if ((list == NULL) || (attributes == NULL)) 11312264Sjacobs return; 11322264Sjacobs 11332264Sjacobs for (i = 0; attributes[i] != NULL; i++) 11342264Sjacobs if (is_in_list(attributes[i]->name, list) == 0) 11352264Sjacobs copy_attribute(in, attributes[i]); 11362264Sjacobs else 11372264Sjacobs copy_attribute(out, attributes[i]); 11382264Sjacobs } 11392264Sjacobs 11402264Sjacobs void 11412264Sjacobs papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes, 11422264Sjacobs char *prefix_fmt, ...) 11432264Sjacobs { 11442264Sjacobs char *prefix = NULL; 11452264Sjacobs char *buffer = NULL; 11462264Sjacobs char *newfmt = NULL; 11472264Sjacobs void *mem; 11482264Sjacobs ssize_t size = 0; 11492264Sjacobs va_list ap; 11502264Sjacobs 11512264Sjacobs newfmt = malloc(strlen(prefix_fmt) + 2); 11522264Sjacobs sprintf(newfmt, "\n%s", prefix_fmt); 11532264Sjacobs 11542264Sjacobs va_start(ap, prefix_fmt); 11552264Sjacobs while (vsnprintf(prefix, size, newfmt, ap) > size) { 11562264Sjacobs size += 1024; 11572264Sjacobs mem = realloc(prefix, size); 11582264Sjacobs if (!mem) goto error; 11592264Sjacobs prefix = mem; 11602264Sjacobs } 11612264Sjacobs va_end(ap); 11622264Sjacobs 11632264Sjacobs if (attributes) { 11642264Sjacobs size = 0; 11652264Sjacobs while (papiAttributeListToString(attributes, prefix, buffer, 11662264Sjacobs size) != PAPI_OK) { 11672264Sjacobs size += 1024; 11682264Sjacobs mem = realloc(buffer, size); 11692264Sjacobs if (!mem) goto error; 11702264Sjacobs buffer = mem; 11712264Sjacobs } 11722264Sjacobs } 11732264Sjacobs 11742264Sjacobs fprintf(fp, "%s%s\n", prefix, buffer ? buffer : ""); 11752264Sjacobs fflush(fp); 11762264Sjacobs 11772264Sjacobs error: 11782264Sjacobs free(newfmt); 11792264Sjacobs free(prefix); 11802264Sjacobs free(buffer); 11812264Sjacobs } 1182