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 /* 23*6725Sjacobs * Copyright 2008 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> 38*6725Sjacobs #include <ctype.h> 392264Sjacobs #include <alloca.h> 402264Sjacobs #include <papi.h> 41*6725Sjacobs #include <regex.h> 422264Sjacobs 432264Sjacobs static void papiAttributeFree(papi_attribute_t *attribute); 442264Sjacobs 452264Sjacobs static void 462264Sjacobs papiAttributeValueFree(papi_attribute_value_type_t type, 472264Sjacobs papi_attribute_value_t *value) 482264Sjacobs { 492264Sjacobs if (value != NULL) { 502264Sjacobs switch (type) { 512264Sjacobs case PAPI_STRING: 522264Sjacobs if (value->string != NULL) 532264Sjacobs free(value->string); 542264Sjacobs break; 552264Sjacobs case PAPI_COLLECTION: 562264Sjacobs if (value->collection != NULL) { 572264Sjacobs int i; 582264Sjacobs 592264Sjacobs for (i = 0; value->collection[i] != NULL; i++) 602264Sjacobs papiAttributeFree(value->collection[i]); 612264Sjacobs 622264Sjacobs free(value->collection); 632264Sjacobs } 642264Sjacobs break; 652264Sjacobs default: /* don't need to free anything extra */ 662264Sjacobs break; 672264Sjacobs } 682264Sjacobs 692264Sjacobs free(value); 702264Sjacobs } 712264Sjacobs } 722264Sjacobs 732264Sjacobs static void 742264Sjacobs papiAttributeValuesFree(papi_attribute_value_type_t type, 752264Sjacobs papi_attribute_value_t **values) 762264Sjacobs { 772264Sjacobs if (values != NULL) { 782264Sjacobs int i; 792264Sjacobs 802264Sjacobs for (i = 0; values[i] != NULL; i++) 812264Sjacobs papiAttributeValueFree(type, values[i]); 822264Sjacobs 832264Sjacobs free(values); 842264Sjacobs } 852264Sjacobs } 862264Sjacobs 872264Sjacobs static void 882264Sjacobs papiAttributeFree(papi_attribute_t *attribute) 892264Sjacobs { 902264Sjacobs if (attribute != NULL) { 912264Sjacobs if (attribute->name != NULL) 922264Sjacobs free(attribute->name); 932264Sjacobs if (attribute->values != NULL) 942264Sjacobs papiAttributeValuesFree(attribute->type, 952264Sjacobs attribute->values); 962264Sjacobs free(attribute); 972264Sjacobs } 982264Sjacobs } 992264Sjacobs 1002264Sjacobs void 1012264Sjacobs papiAttributeListFree(papi_attribute_t **list) 1022264Sjacobs { 1032264Sjacobs if (list != NULL) { 1042264Sjacobs int i; 1052264Sjacobs 1062264Sjacobs for (i = 0; list[i] != NULL; i++) 1072264Sjacobs papiAttributeFree(list[i]); 1082264Sjacobs 1092264Sjacobs free(list); 1102264Sjacobs } 1112264Sjacobs } 1122264Sjacobs 1132264Sjacobs static papi_attribute_t ** 1142264Sjacobs collection_dup(papi_attribute_t **collection) 1152264Sjacobs { 1162264Sjacobs papi_attribute_t **result = NULL; 1172264Sjacobs 1182264Sjacobs /* allows a NULL collection that is "empty" or "no value" */ 1192264Sjacobs if (collection != NULL) { 1202264Sjacobs papi_status_t status = PAPI_OK; 1212264Sjacobs int i; 1222264Sjacobs 1232264Sjacobs for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); 1242264Sjacobs i++) { 1252264Sjacobs papi_attribute_t *a = collection[i]; 1262264Sjacobs 1272264Sjacobs status = papiAttributeListAddValue(&result, 1282264Sjacobs PAPI_ATTR_APPEND, a->name, a->type, 1292264Sjacobs NULL); 1302264Sjacobs if ((status == PAPI_OK) && (a->values != NULL)) { 1312264Sjacobs int j; 1322264Sjacobs 1332264Sjacobs for (j = 0; ((a->values[j] != NULL) && 1342264Sjacobs (status == PAPI_OK)); j++) 1352264Sjacobs status = papiAttributeListAddValue( 1362264Sjacobs &result, 1372264Sjacobs PAPI_ATTR_APPEND, 1382264Sjacobs a->name, a->type, 1392264Sjacobs a->values[j]); 1402264Sjacobs } 1412264Sjacobs } 1422264Sjacobs if (status != PAPI_OK) { 1432264Sjacobs papiAttributeListFree(result); 1442264Sjacobs result = NULL; 1452264Sjacobs } 1462264Sjacobs } 1472264Sjacobs 1482264Sjacobs return (result); 1492264Sjacobs } 1502264Sjacobs 1512264Sjacobs static papi_attribute_value_t * 1522264Sjacobs papiAttributeValueDup(papi_attribute_value_type_t type, 1532264Sjacobs papi_attribute_value_t *v) 1542264Sjacobs { 1552264Sjacobs papi_attribute_value_t *result = NULL; 1562264Sjacobs 1572264Sjacobs if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) { 1582264Sjacobs switch (type) { 1592264Sjacobs case PAPI_STRING: 1602264Sjacobs if (v->string == NULL) { 1612264Sjacobs free(result); 1622264Sjacobs result = NULL; 1632264Sjacobs } else 1642264Sjacobs result->string = strdup(v->string); 1652264Sjacobs break; 1662264Sjacobs case PAPI_INTEGER: 1672264Sjacobs result->integer = v->integer; 1682264Sjacobs break; 1692264Sjacobs case PAPI_BOOLEAN: 1702264Sjacobs result->boolean = v->boolean; 1712264Sjacobs break; 1722264Sjacobs case PAPI_RANGE: 1732264Sjacobs result->range.lower = v->range.lower; 1742264Sjacobs result->range.upper = v->range.upper; 1752264Sjacobs break; 1762264Sjacobs case PAPI_RESOLUTION: 1772264Sjacobs result->resolution.xres = v->resolution.xres; 1782264Sjacobs result->resolution.yres = v->resolution.yres; 1792264Sjacobs result->resolution.units = v->resolution.units; 1802264Sjacobs break; 1812264Sjacobs case PAPI_DATETIME: 1822264Sjacobs result->datetime = v->datetime; 1832264Sjacobs break; 1842264Sjacobs case PAPI_COLLECTION: 1852264Sjacobs result->collection = collection_dup(v->collection); 1862264Sjacobs break; 1872264Sjacobs case PAPI_METADATA: 1882264Sjacobs result->metadata = v->metadata; 1892264Sjacobs break; 1902264Sjacobs default: /* unknown type, fail to duplicate */ 1912264Sjacobs free(result); 1922264Sjacobs result = NULL; 1932264Sjacobs } 1942264Sjacobs } 1952264Sjacobs 1962264Sjacobs return (result); 1972264Sjacobs } 1982264Sjacobs 1992264Sjacobs static papi_attribute_t * 2002264Sjacobs papiAttributeAlloc(char *name, papi_attribute_value_type_t type) 2012264Sjacobs { 2022264Sjacobs papi_attribute_t *result = NULL; 2032264Sjacobs 2042264Sjacobs if ((result = calloc(1, sizeof (*result))) != NULL) { 2052264Sjacobs result->name = strdup(name); 2062264Sjacobs result->type = type; 2072264Sjacobs } 2082264Sjacobs 2092264Sjacobs return (result); 2102264Sjacobs } 2112264Sjacobs 2122264Sjacobs static papi_status_t 2132264Sjacobs papiAttributeListAppendValue(papi_attribute_value_t ***values, 2142264Sjacobs papi_attribute_value_type_t type, 2152264Sjacobs papi_attribute_value_t *value) 2162264Sjacobs { 2172264Sjacobs 2182264Sjacobs if (values == NULL) 2192264Sjacobs return (PAPI_BAD_ARGUMENT); 2202264Sjacobs 2212264Sjacobs if (value != NULL) { /* this allows "empty" attributes */ 2222264Sjacobs papi_attribute_value_t *tmp = NULL; 2232264Sjacobs 2242264Sjacobs if ((tmp = papiAttributeValueDup(type, value)) == NULL) 2252264Sjacobs return (PAPI_TEMPORARY_ERROR); 2262264Sjacobs 2272264Sjacobs list_append(values, tmp); 2282264Sjacobs } 2292264Sjacobs 2302264Sjacobs return (PAPI_OK); 2312264Sjacobs } 2322264Sjacobs 2332264Sjacobs papi_status_t 2342264Sjacobs papiAttributeListAddValue(papi_attribute_t ***list, int flgs, 2352264Sjacobs char *name, papi_attribute_value_type_t type, 2362264Sjacobs papi_attribute_value_t *value) 2372264Sjacobs { 2382264Sjacobs papi_status_t result; 2392264Sjacobs int flags = flgs; 2402264Sjacobs papi_attribute_t *attribute = NULL; 2412264Sjacobs papi_attribute_value_t **values = NULL; 2422264Sjacobs 2432264Sjacobs if ((list == NULL) || (name == NULL)) 2442264Sjacobs return (PAPI_BAD_ARGUMENT); 2452264Sjacobs 2462264Sjacobs if ((type == PAPI_RANGE) && (value != NULL) && 2472264Sjacobs (value->range.lower > value->range.upper)) 2482264Sjacobs return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */ 2492264Sjacobs 2502264Sjacobs if (flags == 0) /* if it wasn't set, set a default behaviour */ 2512264Sjacobs flags = PAPI_ATTR_APPEND; 2522264Sjacobs 2532264Sjacobs /* look for an existing one */ 2542264Sjacobs attribute = papiAttributeListFind(*list, name); 2552264Sjacobs 2562264Sjacobs if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL)) 2572264Sjacobs return (PAPI_CONFLICT); /* EXISTS */ 2582264Sjacobs 2592264Sjacobs if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) && 2602264Sjacobs (attribute->type != type)) 2612264Sjacobs return (PAPI_CONFLICT); /* TYPE CONFLICT */ 2622264Sjacobs 2632264Sjacobs /* if we don't have one, create it and add it to the list */ 2642264Sjacobs if ((attribute == NULL) && 2652264Sjacobs ((attribute = papiAttributeAlloc(name, type)) != NULL)) 2662264Sjacobs list_append(list, attribute); 2672264Sjacobs 2682264Sjacobs /* if we don't have one by now, it's most likely an alloc fail */ 2692264Sjacobs if (attribute == NULL) 2702264Sjacobs return (PAPI_TEMPORARY_ERROR); 2712264Sjacobs 2722264Sjacobs /* 2732264Sjacobs * if we are replacing, clear any existing values, but don't free 2742264Sjacobs * until after we have replaced the values, in case we are replacing 2752264Sjacobs * a collection with a relocated version of the original collection. 2762264Sjacobs */ 2772264Sjacobs if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) { 2782264Sjacobs values = attribute->values; 2792264Sjacobs attribute->values = NULL; 2802264Sjacobs } 2812264Sjacobs 2822264Sjacobs attribute->type = type; 2832264Sjacobs 2842264Sjacobs result = papiAttributeListAppendValue(&attribute->values, type, value); 2852264Sjacobs 2862264Sjacobs /* free old values if we replaced them */ 2872264Sjacobs if (values != NULL) 2882264Sjacobs papiAttributeValuesFree(type, values); 2892264Sjacobs 2902264Sjacobs return (result); 2912264Sjacobs } 2922264Sjacobs 2932264Sjacobs papi_status_t 2942264Sjacobs papiAttributeListAddString(papi_attribute_t ***list, int flags, 2952264Sjacobs char *name, char *string) 2962264Sjacobs { 2972264Sjacobs papi_attribute_value_t v; 2982264Sjacobs 2992264Sjacobs v.string = (char *)string; 3002264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); 3012264Sjacobs } 3022264Sjacobs 3032264Sjacobs papi_status_t 3042264Sjacobs papiAttributeListAddInteger(papi_attribute_t ***list, int flags, 3052264Sjacobs char *name, int integer) 3062264Sjacobs { 3072264Sjacobs papi_attribute_value_t v; 3082264Sjacobs 3092264Sjacobs v.integer = integer; 3102264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); 3112264Sjacobs } 3122264Sjacobs 3132264Sjacobs papi_status_t 3142264Sjacobs papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, 3152264Sjacobs char *name, char boolean) 3162264Sjacobs { 3172264Sjacobs papi_attribute_value_t v; 3182264Sjacobs 3192264Sjacobs v.boolean = boolean; 3202264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); 3212264Sjacobs } 3222264Sjacobs 3232264Sjacobs papi_status_t 3242264Sjacobs papiAttributeListAddRange(papi_attribute_t ***list, int flags, 3252264Sjacobs char *name, int lower, int upper) 3262264Sjacobs { 3272264Sjacobs papi_attribute_value_t v; 3282264Sjacobs 3292264Sjacobs v.range.lower = lower; 3302264Sjacobs v.range.upper = upper; 3312264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); 3322264Sjacobs } 3332264Sjacobs 3342264Sjacobs papi_status_t 3352264Sjacobs papiAttributeListAddResolution(papi_attribute_t ***list, int flags, 3362264Sjacobs char *name, int xres, int yres, 3372264Sjacobs papi_resolution_unit_t units) 3382264Sjacobs { 3392264Sjacobs papi_attribute_value_t v; 3402264Sjacobs 3412264Sjacobs v.resolution.xres = xres; 3422264Sjacobs v.resolution.yres = yres; 3432264Sjacobs v.resolution.units = units; 3442264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3452264Sjacobs PAPI_RESOLUTION, &v)); 3462264Sjacobs } 3472264Sjacobs 3482264Sjacobs papi_status_t 3492264Sjacobs papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, 3502264Sjacobs char *name, time_t datetime) 3512264Sjacobs { 3522264Sjacobs papi_attribute_value_t v; 3532264Sjacobs 3542264Sjacobs v.datetime = datetime; 3552264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3562264Sjacobs PAPI_DATETIME, &v)); 3572264Sjacobs } 3582264Sjacobs 3592264Sjacobs papi_status_t 3602264Sjacobs papiAttributeListAddCollection(papi_attribute_t ***list, int flags, 3612264Sjacobs char *name, papi_attribute_t **collection) 3622264Sjacobs { 3632264Sjacobs papi_attribute_value_t v; 3642264Sjacobs 3652264Sjacobs v.collection = (papi_attribute_t **)collection; 3662264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3672264Sjacobs PAPI_COLLECTION, &v)); 3682264Sjacobs } 3692264Sjacobs 3702264Sjacobs papi_status_t 3712264Sjacobs papiAttributeListAddMetadata(papi_attribute_t ***list, int flags, 3722264Sjacobs char *name, papi_metadata_t metadata) 3732264Sjacobs { 3742264Sjacobs papi_attribute_value_t v; 3752264Sjacobs 3762264Sjacobs v.metadata = metadata; 3772264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3782264Sjacobs PAPI_METADATA, &v)); 3792264Sjacobs } 3802264Sjacobs 3812264Sjacobs papi_status_t 3822264Sjacobs papiAttributeListDelete(papi_attribute_t ***list, char *name) 3832264Sjacobs { 3842264Sjacobs papi_attribute_t *attribute; 3852264Sjacobs 3862264Sjacobs if ((list == NULL) || (name == NULL)) 3872264Sjacobs return (PAPI_BAD_ARGUMENT); 3882264Sjacobs 3892264Sjacobs if ((attribute = papiAttributeListFind(*list, name)) == NULL) 3902264Sjacobs return (PAPI_NOT_FOUND); 3912264Sjacobs 3923125Sjacobs list_remove(list, attribute); 3932264Sjacobs papiAttributeFree(attribute); 3942264Sjacobs 3952264Sjacobs return (PAPI_OK); 3962264Sjacobs } 3972264Sjacobs 3982264Sjacobs papi_attribute_t * 3992264Sjacobs papiAttributeListFind(papi_attribute_t **list, char *name) 4002264Sjacobs { 4012264Sjacobs int i; 4022264Sjacobs if ((list == NULL) || (name == NULL)) 4032264Sjacobs return (NULL); 4042264Sjacobs 4052264Sjacobs for (i = 0; list[i] != NULL; i++) 4062264Sjacobs if (strcasecmp(list[i]->name, name) == 0) 4072264Sjacobs return ((papi_attribute_t *)list[i]); 4082264Sjacobs 4092264Sjacobs return (NULL); 4102264Sjacobs } 4112264Sjacobs 4122264Sjacobs papi_attribute_t * 4132264Sjacobs papiAttributeListGetNext(papi_attribute_t **list, void **iter) 4142264Sjacobs { 4152264Sjacobs papi_attribute_t **tmp, *result; 4162264Sjacobs 4172264Sjacobs if ((list == NULL) && (iter == NULL)) 4182264Sjacobs return (NULL); 4192264Sjacobs 4202264Sjacobs if (*iter == NULL) 4212264Sjacobs *iter = list; 4222264Sjacobs 4232264Sjacobs tmp = *iter; 4242264Sjacobs result = *tmp; 4252264Sjacobs *iter = ++tmp; 4262264Sjacobs 4272264Sjacobs return (result); 4282264Sjacobs } 4292264Sjacobs 4302264Sjacobs papi_status_t 4312264Sjacobs papiAttributeListGetValue(papi_attribute_t **list, void **iter, 4322264Sjacobs char *name, papi_attribute_value_type_t type, 4332264Sjacobs papi_attribute_value_t **value) 4342264Sjacobs { 4352264Sjacobs papi_attribute_value_t **tmp; 4362264Sjacobs void *fodder = NULL; 4372264Sjacobs 4382264Sjacobs if ((list == NULL) || ((name == NULL) && (iter == NULL)) || 4392264Sjacobs (value == NULL)) 4402264Sjacobs return (PAPI_BAD_ARGUMENT); 4412264Sjacobs 4422264Sjacobs if (iter == NULL) 4432264Sjacobs iter = &fodder; 4442264Sjacobs 4452264Sjacobs if ((iter == NULL) || (*iter == NULL)) { 4462264Sjacobs papi_attribute_t *attr = papiAttributeListFind(list, name); 4472264Sjacobs 4482264Sjacobs if (attr == NULL) 4492264Sjacobs return (PAPI_NOT_FOUND); 4502264Sjacobs 4512264Sjacobs if (attr->type != type) 4522264Sjacobs return (PAPI_NOT_POSSIBLE); 4532264Sjacobs 4542264Sjacobs tmp = attr->values; 4552264Sjacobs } else 4562264Sjacobs tmp = *iter; 4572264Sjacobs 4582264Sjacobs if (tmp == NULL) 4592264Sjacobs return (PAPI_NOT_FOUND); 4602264Sjacobs 4612264Sjacobs *value = *tmp; 4622264Sjacobs *iter = ++tmp; 4632264Sjacobs 4642264Sjacobs if (*value == NULL) 4652264Sjacobs return (PAPI_GONE); 4662264Sjacobs 4672264Sjacobs return (PAPI_OK); 4682264Sjacobs } 4692264Sjacobs 4702264Sjacobs papi_status_t 4712264Sjacobs papiAttributeListGetString(papi_attribute_t **list, void **iter, 4722264Sjacobs char *name, char **vptr) 4732264Sjacobs { 4742264Sjacobs papi_status_t status; 4752264Sjacobs papi_attribute_value_t *value = NULL; 4762264Sjacobs 4772264Sjacobs if (vptr == NULL) 4782264Sjacobs return (PAPI_BAD_ARGUMENT); 4792264Sjacobs 4802264Sjacobs status = papiAttributeListGetValue(list, iter, name, 4812264Sjacobs PAPI_STRING, &value); 4822264Sjacobs if (status == PAPI_OK) 4832264Sjacobs *vptr = value->string; 4842264Sjacobs 4852264Sjacobs return (status); 4862264Sjacobs } 4872264Sjacobs 4882264Sjacobs papi_status_t 4892264Sjacobs papiAttributeListGetInteger(papi_attribute_t **list, void **iter, 4902264Sjacobs char *name, int *vptr) 4912264Sjacobs { 4922264Sjacobs papi_status_t status; 4932264Sjacobs papi_attribute_value_t *value = NULL; 4942264Sjacobs 4952264Sjacobs if (vptr == NULL) 4962264Sjacobs return (PAPI_BAD_ARGUMENT); 4972264Sjacobs 4982264Sjacobs status = papiAttributeListGetValue(list, iter, name, 4992264Sjacobs PAPI_INTEGER, &value); 5002264Sjacobs if (status == PAPI_OK) 5012264Sjacobs *vptr = value->integer; 5022264Sjacobs 5032264Sjacobs return (status); 5042264Sjacobs } 5052264Sjacobs 5062264Sjacobs papi_status_t 5072264Sjacobs papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, 5082264Sjacobs char *name, char *vptr) 5092264Sjacobs { 5102264Sjacobs papi_status_t status; 5112264Sjacobs papi_attribute_value_t *value = NULL; 5122264Sjacobs 5132264Sjacobs if (vptr == NULL) 5142264Sjacobs return (PAPI_BAD_ARGUMENT); 5152264Sjacobs 5162264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5172264Sjacobs PAPI_BOOLEAN, &value); 5182264Sjacobs if (status == PAPI_OK) 5192264Sjacobs *vptr = value->boolean; 5202264Sjacobs 5212264Sjacobs return (status); 5222264Sjacobs } 5232264Sjacobs 5242264Sjacobs papi_status_t 5252264Sjacobs papiAttributeListGetRange(papi_attribute_t **list, void **iter, 5262264Sjacobs char *name, int *min, int *max) 5272264Sjacobs { 5282264Sjacobs papi_status_t status; 5292264Sjacobs papi_attribute_value_t *value = NULL; 5302264Sjacobs 5312264Sjacobs if ((min == NULL) || (max == NULL)) 5322264Sjacobs return (PAPI_BAD_ARGUMENT); 5332264Sjacobs 5342264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5352264Sjacobs PAPI_RANGE, &value); 5362264Sjacobs if (status == PAPI_OK) { 5372264Sjacobs *min = value->range.lower; 5382264Sjacobs *max = value->range.upper; 5392264Sjacobs } 5402264Sjacobs 5412264Sjacobs return (status); 5422264Sjacobs } 5432264Sjacobs 5442264Sjacobs papi_status_t 5452264Sjacobs papiAttributeListGetResolution(papi_attribute_t **list, void **iter, 5462264Sjacobs char *name, int *x, int *y, 5472264Sjacobs papi_resolution_unit_t *units) 5482264Sjacobs { 5492264Sjacobs papi_status_t status; 5502264Sjacobs papi_attribute_value_t *value = NULL; 5512264Sjacobs 5522264Sjacobs if ((x == NULL) || (y == NULL) || (units == NULL)) 5532264Sjacobs return (PAPI_BAD_ARGUMENT); 5542264Sjacobs 5552264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5562264Sjacobs PAPI_RESOLUTION, &value); 5572264Sjacobs if (status == PAPI_OK) { 5582264Sjacobs *x = value->resolution.xres; 5592264Sjacobs *y = value->resolution.yres; 5602264Sjacobs *units = value->resolution.units; 5612264Sjacobs } 5622264Sjacobs 5632264Sjacobs return (status); 5642264Sjacobs } 5652264Sjacobs 5662264Sjacobs papi_status_t 5672264Sjacobs papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, 5682264Sjacobs char *name, time_t *dt) 5692264Sjacobs { 5702264Sjacobs papi_status_t status; 5712264Sjacobs papi_attribute_value_t *value = NULL; 5722264Sjacobs 5732264Sjacobs if (dt == NULL) 5742264Sjacobs return (PAPI_BAD_ARGUMENT); 5752264Sjacobs 5762264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5772264Sjacobs PAPI_DATETIME, &value); 5782264Sjacobs if (status == PAPI_OK) { 5792264Sjacobs *dt = value->datetime; 5802264Sjacobs } 5812264Sjacobs 5822264Sjacobs return (status); 5832264Sjacobs } 5842264Sjacobs 5852264Sjacobs papi_status_t 5862264Sjacobs papiAttributeListGetCollection(papi_attribute_t **list, void **iter, 5872264Sjacobs char *name, papi_attribute_t ***collection) 5882264Sjacobs { 5892264Sjacobs papi_status_t status; 5902264Sjacobs papi_attribute_value_t *value = NULL; 5912264Sjacobs 5922264Sjacobs if (collection == NULL) 5932264Sjacobs return (PAPI_BAD_ARGUMENT); 5942264Sjacobs 5952264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5962264Sjacobs PAPI_COLLECTION, &value); 5972264Sjacobs if (status == PAPI_OK) { 5982264Sjacobs *collection = value->collection; 5992264Sjacobs } 6002264Sjacobs 6012264Sjacobs return (status); 6022264Sjacobs } 6032264Sjacobs 6042264Sjacobs papi_status_t 6052264Sjacobs papiAttributeListGetMetadata(papi_attribute_t **list, void **iter, 6062264Sjacobs char *name, papi_metadata_t *vptr) 6072264Sjacobs { 6082264Sjacobs papi_status_t status; 6092264Sjacobs papi_attribute_value_t *value = NULL; 6102264Sjacobs 6112264Sjacobs if (vptr == NULL) 6122264Sjacobs return (PAPI_BAD_ARGUMENT); 6132264Sjacobs 6142264Sjacobs status = papiAttributeListGetValue(list, iter, name, 6152264Sjacobs PAPI_METADATA, &value); 6162264Sjacobs if (status == PAPI_OK) 6172264Sjacobs *vptr = value->metadata; 6182264Sjacobs 6192264Sjacobs return (status); 6202264Sjacobs } 6212264Sjacobs 6222264Sjacobs 623*6725Sjacobs /* The string is modified by this call */ 6242264Sjacobs static char * 625*6725Sjacobs regvalue(regmatch_t match, char *string) 6262264Sjacobs { 6272264Sjacobs char *result = NULL; 628*6725Sjacobs if (match.rm_so != match.rm_eo) { 629*6725Sjacobs result = string + match.rm_so; 630*6725Sjacobs *(result + (match.rm_eo - match.rm_so)) = '\0'; 631*6725Sjacobs } 632*6725Sjacobs return (result); 633*6725Sjacobs } 6342264Sjacobs 635*6725Sjacobs static papi_attribute_value_type_t 636*6725Sjacobs _process_value(char *string, char ***parts) 637*6725Sjacobs { 638*6725Sjacobs int i; 639*6725Sjacobs static struct { 640*6725Sjacobs papi_attribute_value_type_t type; 641*6725Sjacobs size_t vals; 642*6725Sjacobs char *expression; 643*6725Sjacobs int compiled; 644*6725Sjacobs regex_t re; 645*6725Sjacobs } types[] = { 646*6725Sjacobs { PAPI_BOOLEAN, 1, "^(true|false|yes|no)$", 0 }, 647*6725Sjacobs { PAPI_COLLECTION, 1, "^\\{(.+)\\}$", 0 }, 648*6725Sjacobs /* PAPI_DATETIME is unsupported, too much like an integer */ 649*6725Sjacobs { PAPI_INTEGER, 1, "^([+-]{0,1}[[:digit:]]+)$", 0 }, 650*6725Sjacobs { PAPI_RANGE, 3, "^([[:digit:]]+)-([[:digit:]]+)$", 0 }, 651*6725Sjacobs { PAPI_RESOLUTION, 4, "^([[:digit:]]+)x([[:digit:]]+)dp(i|c)$", 652*6725Sjacobs 0 }, 653*6725Sjacobs NULL 654*6725Sjacobs }; 655*6725Sjacobs regmatch_t matches[4]; 656*6725Sjacobs 657*6725Sjacobs for (i = 0; i < 5; i++) { 658*6725Sjacobs int j; 659*6725Sjacobs 660*6725Sjacobs if (types[i].compiled == 0) { 661*6725Sjacobs (void) regcomp(&(types[i].re), types[i].expression, 662*6725Sjacobs REG_EXTENDED|REG_ICASE); 663*6725Sjacobs types[i].compiled = 1; 6642264Sjacobs } 665*6725Sjacobs if (regexec(&(types[i].re), string, (size_t)types[i].vals, 666*6725Sjacobs matches, 0) == REG_NOMATCH) 667*6725Sjacobs continue; 668*6725Sjacobs 669*6725Sjacobs for (j = 0 ; j < types[i].vals; j++) 670*6725Sjacobs list_append(parts, regvalue(matches[j], string)); 671*6725Sjacobs return (types[i].type); 672*6725Sjacobs } 6732264Sjacobs 674*6725Sjacobs list_append(parts, string); 675*6725Sjacobs return (PAPI_STRING); 676*6725Sjacobs } 677*6725Sjacobs 678*6725Sjacobs static void 679*6725Sjacobs _add_attribute_value(papi_attribute_value_t ***list, 680*6725Sjacobs papi_attribute_value_type_t type, 681*6725Sjacobs papi_attribute_value_type_t dtype, char **parts) 682*6725Sjacobs { 683*6725Sjacobs papi_attribute_value_t *value = calloc(1, sizeof (*value)); 6842264Sjacobs 685*6725Sjacobs switch(type) { 686*6725Sjacobs case PAPI_STRING: 687*6725Sjacobs value->string = strdup(parts[0]); 688*6725Sjacobs list_append(list, value); 689*6725Sjacobs break; 690*6725Sjacobs case PAPI_BOOLEAN: 691*6725Sjacobs value->boolean = PAPI_TRUE; 692*6725Sjacobs if ((strcasecmp(parts[0], "false") == 0) || 693*6725Sjacobs (strcasecmp(parts[0], "no") == 0)) 694*6725Sjacobs value->boolean = PAPI_FALSE; 695*6725Sjacobs list_append(list, value); 696*6725Sjacobs break; 697*6725Sjacobs case PAPI_INTEGER: 698*6725Sjacobs value->integer = atoi(parts[0]); 699*6725Sjacobs list_append(list, value); 700*6725Sjacobs break; 701*6725Sjacobs case PAPI_RANGE: 702*6725Sjacobs if (dtype == PAPI_INTEGER) 703*6725Sjacobs value->range.lower = value->range.upper 704*6725Sjacobs = atoi(parts[0]); 705*6725Sjacobs else if (dtype == PAPI_RANGE) { 706*6725Sjacobs value->range.lower = atoi(parts[1]); 707*6725Sjacobs value->range.upper = atoi(parts[2]); 7082264Sjacobs } 709*6725Sjacobs list_append(list, value); 710*6725Sjacobs break; 711*6725Sjacobs case PAPI_RESOLUTION: 712*6725Sjacobs value->resolution.xres = atoi(parts[1]); 713*6725Sjacobs value->resolution.yres = atoi(parts[2]); 714*6725Sjacobs if (parts[3][0] == 'i') 715*6725Sjacobs value->resolution.units = PAPI_RES_PER_INCH; 716*6725Sjacobs else 717*6725Sjacobs value->resolution.units = PAPI_RES_PER_CM; 718*6725Sjacobs list_append(list, value); 719*6725Sjacobs break; 720*6725Sjacobs case PAPI_COLLECTION: 721*6725Sjacobs papiAttributeListFromString(&(value->collection), 0, parts[0]); 722*6725Sjacobs list_append(list, value); 723*6725Sjacobs break; 724*6725Sjacobs } 725*6725Sjacobs } 7262264Sjacobs 727*6725Sjacobs static papi_status_t 728*6725Sjacobs _papiAttributeFromStrings(papi_attribute_t ***list, int flags, 729*6725Sjacobs char *key, char **values) 730*6725Sjacobs { 731*6725Sjacobs int i; 732*6725Sjacobs papi_status_t result = PAPI_OK; 733*6725Sjacobs papi_attribute_t *attr = calloc(1, sizeof (*attr)); 734*6725Sjacobs 735*6725Sjacobs /* these are specified in the papi spec as ranges */ 736*6725Sjacobs char *ranges[] = { "copies-supported", "job-impressions-supported", 737*6725Sjacobs "job-k-octets-supported", 738*6725Sjacobs "job-media-sheets-supported", "page-ranges", 739*6725Sjacobs NULL }; 740*6725Sjacobs 741*6725Sjacobs if ((attr == NULL) || ((attr->name = strdup(key)) == NULL)) 742*6725Sjacobs return (PAPI_TEMPORARY_ERROR); 743*6725Sjacobs 744*6725Sjacobs attr->type = PAPI_METADATA; 745*6725Sjacobs /* these are known ranges */ 746*6725Sjacobs for (i = 0; ranges[i] != NULL; i++) 747*6725Sjacobs if (strcasecmp(attr->name, ranges[i]) == 0) { 748*6725Sjacobs attr->type = PAPI_RANGE; 749*6725Sjacobs break; 750*6725Sjacobs } 751*6725Sjacobs 752*6725Sjacobs if (values != NULL) { 753*6725Sjacobs papi_attribute_value_t **vals = NULL; 754*6725Sjacobs 755*6725Sjacobs for (i = 0; values[i] != NULL; i++) { 756*6725Sjacobs papi_attribute_value_type_t dtype; 757*6725Sjacobs char **parts = NULL; 758*6725Sjacobs 759*6725Sjacobs dtype = _process_value(values[i], &parts); 760*6725Sjacobs if (attr->type == PAPI_METADATA) 761*6725Sjacobs attr->type = dtype; 762*6725Sjacobs _add_attribute_value(&vals, attr->type, dtype, parts); 763*6725Sjacobs free(parts); 7642264Sjacobs } 765*6725Sjacobs attr->values = vals; 766*6725Sjacobs } 767*6725Sjacobs 768*6725Sjacobs list_append(list, attr); 769*6725Sjacobs 770*6725Sjacobs return (result); 771*6725Sjacobs } 7722264Sjacobs 773*6725Sjacobs static papi_status_t 774*6725Sjacobs _parse_attribute_list(papi_attribute_t ***list, int flags, char *string) 775*6725Sjacobs { 776*6725Sjacobs papi_status_t result = PAPI_OK; 777*6725Sjacobs char *ptr; 778*6725Sjacobs 779*6725Sjacobs if ((list == NULL) || (string == NULL)) 780*6725Sjacobs return (PAPI_BAD_ARGUMENT); 781*6725Sjacobs 782*6725Sjacobs if ((ptr = strdup(string)) == NULL) 783*6725Sjacobs return (PAPI_TEMPORARY_ERROR); 784*6725Sjacobs 785*6725Sjacobs while ((*ptr != '\0') && (result == PAPI_OK)) { 786*6725Sjacobs char *key, **values = NULL; 787*6725Sjacobs 788*6725Sjacobs /* strip any leading whitespace */ 789*6725Sjacobs while (isspace(*ptr) != 0) 790*6725Sjacobs ptr++; 791*6725Sjacobs 792*6725Sjacobs /* Get the name: name[=value] */ 793*6725Sjacobs key = ptr; 794*6725Sjacobs while ((*ptr != '\0') && (*ptr != '=') && (isspace(*ptr) == 0)) 795*6725Sjacobs ptr++; 796*6725Sjacobs 797*6725Sjacobs if (*ptr == '=') { 798*6725Sjacobs *ptr++ = '\0'; 799*6725Sjacobs 800*6725Sjacobs while ((*ptr != '\0') && (isspace(*ptr) == 0)) { 801*6725Sjacobs char *value = ptr; 802*6725Sjacobs 803*6725Sjacobs if ((*ptr == '\'') || (*ptr == '"')) { 804*6725Sjacobs char q = *ptr++; 8052264Sjacobs 806*6725Sjacobs /* quoted string value */ 807*6725Sjacobs while ((*ptr != '\0') && (*ptr != q)) 808*6725Sjacobs ptr++; 809*6725Sjacobs if (*ptr == q) 810*6725Sjacobs ptr++; 811*6725Sjacobs } else if (*ptr == '{') { 812*6725Sjacobs /* collection */ 813*6725Sjacobs while ((*ptr != '\0') && (*ptr != '}')) 814*6725Sjacobs ptr++; 815*6725Sjacobs if (*ptr == '}') 816*6725Sjacobs ptr++; 817*6725Sjacobs } else { 818*6725Sjacobs /* value */ 819*6725Sjacobs while ((*ptr != '\0') && 820*6725Sjacobs (*ptr != ',') && 821*6725Sjacobs (isspace(*ptr) == 0)) 822*6725Sjacobs ptr++; 823*6725Sjacobs } 824*6725Sjacobs if (*ptr == ',') 825*6725Sjacobs *ptr++ = '\0'; 826*6725Sjacobs list_append(&values, value); 8272264Sjacobs } 828*6725Sjacobs } else { /* boolean "[no]key" */ 829*6725Sjacobs char *value = "true"; 830*6725Sjacobs 831*6725Sjacobs if (strncasecmp(key, "no", 2) == 0) { 832*6725Sjacobs key += 2; 833*6725Sjacobs value = "false"; 834*6725Sjacobs } 835*6725Sjacobs list_append(&values, value); 8362264Sjacobs } 837*6725Sjacobs if (*ptr != '\0') 838*6725Sjacobs *ptr++ = '\0'; 839*6725Sjacobs 840*6725Sjacobs result = _papiAttributeFromStrings(list, flags, key, values); 841*6725Sjacobs free(values); 8422264Sjacobs } 8432264Sjacobs 8442264Sjacobs return (result); 845*6725Sjacobs } 8462264Sjacobs 8472264Sjacobs papi_status_t 8482264Sjacobs papiAttributeListFromString(papi_attribute_t ***attrs, 8492264Sjacobs int flags, char *string) 8502264Sjacobs { 8512264Sjacobs papi_status_t result = PAPI_OK; 8522264Sjacobs 8532264Sjacobs if ((attrs != NULL) && (string != NULL) && 8542264Sjacobs ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) 8552264Sjacobs == 0)) { 856*6725Sjacobs result = _parse_attribute_list(attrs, flags, string); 857*6725Sjacobs } else { 8582264Sjacobs result = PAPI_BAD_ARGUMENT; 8592264Sjacobs } 8602264Sjacobs 8612264Sjacobs return (result); 8622264Sjacobs } 8632264Sjacobs 8642264Sjacobs static papi_status_t 8652264Sjacobs papiAttributeToString(papi_attribute_t *attribute, char *delim, 8662264Sjacobs char *buffer, size_t buflen) 8672264Sjacobs { 8682264Sjacobs papi_attribute_value_t **values = attribute->values; 8692264Sjacobs int rc, i; 8702264Sjacobs 871*6725Sjacobs if ((attribute->type == PAPI_BOOLEAN) && (values[1] == NULL)) { 872*6725Sjacobs if (values[0]->boolean == PAPI_FALSE) { 873*6725Sjacobs if (isupper(attribute->name[0]) == 0) 874*6725Sjacobs strlcat(buffer, "no", buflen); 875*6725Sjacobs else 876*6725Sjacobs strlcat(buffer, "No", buflen); 877*6725Sjacobs } 878*6725Sjacobs rc = strlcat(buffer, attribute->name, buflen); 879*6725Sjacobs } else { 880*6725Sjacobs strlcat(buffer, attribute->name, buflen); 881*6725Sjacobs rc = strlcat(buffer, "=", buflen); 882*6725Sjacobs } 8832264Sjacobs 8842264Sjacobs if (values == NULL) 8852264Sjacobs return (PAPI_OK); 8862264Sjacobs 8872264Sjacobs for (i = 0; values[i] != NULL; i++) { 8882264Sjacobs switch (attribute->type) { 8892264Sjacobs case PAPI_STRING: 8902264Sjacobs rc = strlcat(buffer, values[i]->string, buflen); 8912264Sjacobs break; 8922264Sjacobs case PAPI_INTEGER: { 8932264Sjacobs char string[24]; 8942264Sjacobs 8952264Sjacobs snprintf(string, sizeof (string), "%d", 8962264Sjacobs values[i]->integer); 8972264Sjacobs rc = strlcat(buffer, string, buflen); 8982264Sjacobs } 8992264Sjacobs break; 9002264Sjacobs case PAPI_BOOLEAN: 901*6725Sjacobs if (values[1] != NULL) 902*6725Sjacobs rc = strlcat(buffer, (values[i]->boolean ? 903*6725Sjacobs "true" : "false"), buflen); 9042264Sjacobs break; 9052264Sjacobs case PAPI_RANGE: { 9062264Sjacobs char string[24]; 9072264Sjacobs 908*6725Sjacobs if (values[i]->range.lower == values[i]->range.upper) 909*6725Sjacobs snprintf(string, sizeof (string), "%d", 910*6725Sjacobs values[i]->range.lower); 911*6725Sjacobs else 912*6725Sjacobs snprintf(string, sizeof (string), "%d-%d", 913*6725Sjacobs values[i]->range.lower, 914*6725Sjacobs values[i]->range.upper); 9152264Sjacobs rc = strlcat(buffer, string, buflen); 9162264Sjacobs } 9172264Sjacobs break; 9182264Sjacobs case PAPI_RESOLUTION: { 9192264Sjacobs char string[24]; 9202264Sjacobs 9212264Sjacobs snprintf(string, sizeof (string), "%dx%ddp%c", 9222264Sjacobs values[i]->resolution.xres, 9232264Sjacobs values[i]->resolution.yres, 9242264Sjacobs (values[i]->resolution.units == PAPI_RES_PER_CM 9252264Sjacobs ? 'c' : 'i')); 9262264Sjacobs rc = strlcat(buffer, string, buflen); 9272264Sjacobs } 9282264Sjacobs break; 9292264Sjacobs case PAPI_DATETIME: { 9302264Sjacobs struct tm *tm = localtime(&values[i]->datetime); 9312264Sjacobs 9322264Sjacobs if (tm != NULL) { 9332264Sjacobs char string[64]; 9342264Sjacobs 9352264Sjacobs strftime(string, sizeof (string), "%C", tm); 9362264Sjacobs rc = strlcat(buffer, string, buflen); 9372264Sjacobs }} 9382264Sjacobs break; 9392264Sjacobs case PAPI_COLLECTION: { 9402264Sjacobs char *string = alloca(buflen); 9412264Sjacobs 9422264Sjacobs papiAttributeListToString(values[i]->collection, 9432264Sjacobs delim, string, buflen); 9442264Sjacobs rc = strlcat(buffer, string, buflen); 9452264Sjacobs } 9462264Sjacobs break; 9472264Sjacobs default: { 9482264Sjacobs char string[32]; 9492264Sjacobs 9502264Sjacobs snprintf(string, sizeof (string), "unknown-type-0x%x", 9512264Sjacobs attribute->type); 9522264Sjacobs rc = strlcat(buffer, string, buflen); 9532264Sjacobs } 9542264Sjacobs } 9552264Sjacobs if (values[i+1] != NULL) 9562264Sjacobs rc = strlcat(buffer, ",", buflen); 9572264Sjacobs 9582264Sjacobs if (rc >= buflen) 9592264Sjacobs return (PAPI_NOT_POSSIBLE); 9602264Sjacobs 9612264Sjacobs } 9622264Sjacobs 9632264Sjacobs return (PAPI_OK); 9642264Sjacobs } 9652264Sjacobs 9662264Sjacobs papi_status_t 9672264Sjacobs papiAttributeListToString(papi_attribute_t **attrs, 9682264Sjacobs char *delim, char *buffer, size_t buflen) 9692264Sjacobs { 9702264Sjacobs papi_status_t status = PAPI_OK; 9712264Sjacobs int i; 9722264Sjacobs 9732264Sjacobs if ((attrs == NULL) || (buffer == NULL)) 9742264Sjacobs return (PAPI_BAD_ARGUMENT); 9752264Sjacobs 9762264Sjacobs buffer[0] = '\0'; 9772264Sjacobs if (!delim) 9782264Sjacobs delim = " "; 9792264Sjacobs 9802264Sjacobs for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) { 9812264Sjacobs status = papiAttributeToString(attrs[i], delim, buffer, buflen); 9822264Sjacobs if (attrs[i+1] != NULL) 9832264Sjacobs strlcat(buffer, delim, buflen); 9842264Sjacobs } 9852264Sjacobs 9862264Sjacobs return (status); 9872264Sjacobs } 9882264Sjacobs 9892264Sjacobs static int 9902264Sjacobs is_in_list(char *value, char **list) 9912264Sjacobs { 9922264Sjacobs if ((list != NULL) && (value != NULL)) { 9932264Sjacobs int i; 9942264Sjacobs 9952264Sjacobs for (i = 0; list[i] != NULL; i++) 9962264Sjacobs if (strcasecmp(value, list[i]) == 0) 9972264Sjacobs return (0); 9982264Sjacobs } 9992264Sjacobs 10002264Sjacobs return (1); 10012264Sjacobs } 10022264Sjacobs 10032264Sjacobs static papi_status_t 10042264Sjacobs copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute) 10052264Sjacobs { 10062264Sjacobs papi_status_t status; 10072264Sjacobs int i = 0; 10082264Sjacobs 10092264Sjacobs if ((list == NULL) || (attribute == NULL) || 10102264Sjacobs (attribute->values == NULL)) 10112264Sjacobs return (PAPI_BAD_ARGUMENT); 10122264Sjacobs 10132264Sjacobs for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL, 10142264Sjacobs attribute->name, attribute->type, 10152264Sjacobs attribute->values[i]); 10162264Sjacobs ((status == PAPI_OK) && (attribute->values[i] != NULL)); 10172264Sjacobs status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND, 10182264Sjacobs attribute->name, attribute->type, 10192264Sjacobs attribute->values[i])) 10202264Sjacobs i++; 10212264Sjacobs 10222264Sjacobs return (status); 10232264Sjacobs } 10242264Sjacobs 10252264Sjacobs void 10262264Sjacobs copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes) 10272264Sjacobs { 10282264Sjacobs int i; 10292264Sjacobs 10302264Sjacobs if ((result == NULL) || (attributes == NULL)) 10312264Sjacobs return; 10322264Sjacobs 10332264Sjacobs for (i = 0; attributes[i] != NULL; i++) 10342264Sjacobs copy_attribute(result, attributes[i]); 10352264Sjacobs } 10362264Sjacobs 10372264Sjacobs void 10382264Sjacobs split_and_copy_attributes(char **list, papi_attribute_t **attributes, 10392264Sjacobs papi_attribute_t ***in, papi_attribute_t ***out) 10402264Sjacobs { 10412264Sjacobs int i; 10422264Sjacobs 10432264Sjacobs if ((list == NULL) || (attributes == NULL)) 10442264Sjacobs return; 10452264Sjacobs 10462264Sjacobs for (i = 0; attributes[i] != NULL; i++) 10472264Sjacobs if (is_in_list(attributes[i]->name, list) == 0) 10482264Sjacobs copy_attribute(in, attributes[i]); 10492264Sjacobs else 10502264Sjacobs copy_attribute(out, attributes[i]); 10512264Sjacobs } 10522264Sjacobs 10532264Sjacobs void 10542264Sjacobs papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes, 10552264Sjacobs char *prefix_fmt, ...) 10562264Sjacobs { 10572264Sjacobs char *prefix = NULL; 10582264Sjacobs char *buffer = NULL; 10592264Sjacobs char *newfmt = NULL; 10602264Sjacobs void *mem; 10612264Sjacobs ssize_t size = 0; 10622264Sjacobs va_list ap; 10632264Sjacobs 10642264Sjacobs newfmt = malloc(strlen(prefix_fmt) + 2); 10652264Sjacobs sprintf(newfmt, "\n%s", prefix_fmt); 10662264Sjacobs 10672264Sjacobs va_start(ap, prefix_fmt); 10682264Sjacobs while (vsnprintf(prefix, size, newfmt, ap) > size) { 10692264Sjacobs size += 1024; 10702264Sjacobs mem = realloc(prefix, size); 10712264Sjacobs if (!mem) goto error; 10722264Sjacobs prefix = mem; 10732264Sjacobs } 10742264Sjacobs va_end(ap); 10752264Sjacobs 10762264Sjacobs if (attributes) { 10772264Sjacobs size = 0; 10782264Sjacobs while (papiAttributeListToString(attributes, prefix, buffer, 10792264Sjacobs size) != PAPI_OK) { 10802264Sjacobs size += 1024; 10812264Sjacobs mem = realloc(buffer, size); 10822264Sjacobs if (!mem) goto error; 10832264Sjacobs buffer = mem; 10842264Sjacobs } 10852264Sjacobs } 10862264Sjacobs 10872264Sjacobs fprintf(fp, "%s%s\n", prefix, buffer ? buffer : ""); 10882264Sjacobs fflush(fp); 10892264Sjacobs 10902264Sjacobs error: 10912264Sjacobs free(newfmt); 10922264Sjacobs free(prefix); 10932264Sjacobs free(buffer); 10942264Sjacobs } 1095