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 /* 236725Sjacobs * 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> 386725Sjacobs #include <ctype.h> 392264Sjacobs #include <alloca.h> 402264Sjacobs #include <papi.h> 416725Sjacobs #include <regex.h> 422264Sjacobs 43*7154Ssg223391 #define MAX_PAGES 32767 44*7154Ssg223391 /* 45*7154Ssg223391 * Assuming the maximum number of pages in 46*7154Ssg223391 * a document to be 32767 47*7154Ssg223391 */ 48*7154Ssg223391 492264Sjacobs static void papiAttributeFree(papi_attribute_t *attribute); 502264Sjacobs 512264Sjacobs static void 522264Sjacobs papiAttributeValueFree(papi_attribute_value_type_t type, 532264Sjacobs papi_attribute_value_t *value) 542264Sjacobs { 552264Sjacobs if (value != NULL) { 562264Sjacobs switch (type) { 572264Sjacobs case PAPI_STRING: 582264Sjacobs if (value->string != NULL) 592264Sjacobs free(value->string); 602264Sjacobs break; 612264Sjacobs case PAPI_COLLECTION: 622264Sjacobs if (value->collection != NULL) { 632264Sjacobs int i; 642264Sjacobs 652264Sjacobs for (i = 0; value->collection[i] != NULL; i++) 662264Sjacobs papiAttributeFree(value->collection[i]); 672264Sjacobs 682264Sjacobs free(value->collection); 692264Sjacobs } 702264Sjacobs break; 712264Sjacobs default: /* don't need to free anything extra */ 722264Sjacobs break; 732264Sjacobs } 742264Sjacobs 752264Sjacobs free(value); 762264Sjacobs } 772264Sjacobs } 782264Sjacobs 792264Sjacobs static void 802264Sjacobs papiAttributeValuesFree(papi_attribute_value_type_t type, 812264Sjacobs papi_attribute_value_t **values) 822264Sjacobs { 832264Sjacobs if (values != NULL) { 842264Sjacobs int i; 852264Sjacobs 862264Sjacobs for (i = 0; values[i] != NULL; i++) 872264Sjacobs papiAttributeValueFree(type, values[i]); 882264Sjacobs 892264Sjacobs free(values); 902264Sjacobs } 912264Sjacobs } 922264Sjacobs 932264Sjacobs static void 942264Sjacobs papiAttributeFree(papi_attribute_t *attribute) 952264Sjacobs { 962264Sjacobs if (attribute != NULL) { 972264Sjacobs if (attribute->name != NULL) 982264Sjacobs free(attribute->name); 992264Sjacobs if (attribute->values != NULL) 1002264Sjacobs papiAttributeValuesFree(attribute->type, 1012264Sjacobs attribute->values); 1022264Sjacobs free(attribute); 1032264Sjacobs } 1042264Sjacobs } 1052264Sjacobs 1062264Sjacobs void 1072264Sjacobs papiAttributeListFree(papi_attribute_t **list) 1082264Sjacobs { 1092264Sjacobs if (list != NULL) { 1102264Sjacobs int i; 1112264Sjacobs 1122264Sjacobs for (i = 0; list[i] != NULL; i++) 1132264Sjacobs papiAttributeFree(list[i]); 1142264Sjacobs 1152264Sjacobs free(list); 1162264Sjacobs } 1172264Sjacobs } 1182264Sjacobs 1192264Sjacobs static papi_attribute_t ** 1202264Sjacobs collection_dup(papi_attribute_t **collection) 1212264Sjacobs { 1222264Sjacobs papi_attribute_t **result = NULL; 1232264Sjacobs 1242264Sjacobs /* allows a NULL collection that is "empty" or "no value" */ 1252264Sjacobs if (collection != NULL) { 1262264Sjacobs papi_status_t status = PAPI_OK; 1272264Sjacobs int i; 1282264Sjacobs 1292264Sjacobs for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); 1302264Sjacobs i++) { 1312264Sjacobs papi_attribute_t *a = collection[i]; 1322264Sjacobs 1332264Sjacobs status = papiAttributeListAddValue(&result, 1342264Sjacobs PAPI_ATTR_APPEND, a->name, a->type, 1352264Sjacobs NULL); 1362264Sjacobs if ((status == PAPI_OK) && (a->values != NULL)) { 1372264Sjacobs int j; 1382264Sjacobs 1392264Sjacobs for (j = 0; ((a->values[j] != NULL) && 1402264Sjacobs (status == PAPI_OK)); j++) 1412264Sjacobs status = papiAttributeListAddValue( 1422264Sjacobs &result, 1432264Sjacobs PAPI_ATTR_APPEND, 1442264Sjacobs a->name, a->type, 1452264Sjacobs a->values[j]); 1462264Sjacobs } 1472264Sjacobs } 1482264Sjacobs if (status != PAPI_OK) { 1492264Sjacobs papiAttributeListFree(result); 1502264Sjacobs result = NULL; 1512264Sjacobs } 1522264Sjacobs } 1532264Sjacobs 1542264Sjacobs return (result); 1552264Sjacobs } 1562264Sjacobs 1572264Sjacobs static papi_attribute_value_t * 1582264Sjacobs papiAttributeValueDup(papi_attribute_value_type_t type, 1592264Sjacobs papi_attribute_value_t *v) 1602264Sjacobs { 1612264Sjacobs papi_attribute_value_t *result = NULL; 1622264Sjacobs 1632264Sjacobs if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) { 1642264Sjacobs switch (type) { 1652264Sjacobs case PAPI_STRING: 1662264Sjacobs if (v->string == NULL) { 1672264Sjacobs free(result); 1682264Sjacobs result = NULL; 1692264Sjacobs } else 1702264Sjacobs result->string = strdup(v->string); 1712264Sjacobs break; 1722264Sjacobs case PAPI_INTEGER: 1732264Sjacobs result->integer = v->integer; 1742264Sjacobs break; 1752264Sjacobs case PAPI_BOOLEAN: 1762264Sjacobs result->boolean = v->boolean; 1772264Sjacobs break; 1782264Sjacobs case PAPI_RANGE: 1792264Sjacobs result->range.lower = v->range.lower; 1802264Sjacobs result->range.upper = v->range.upper; 1812264Sjacobs break; 1822264Sjacobs case PAPI_RESOLUTION: 1832264Sjacobs result->resolution.xres = v->resolution.xres; 1842264Sjacobs result->resolution.yres = v->resolution.yres; 1852264Sjacobs result->resolution.units = v->resolution.units; 1862264Sjacobs break; 1872264Sjacobs case PAPI_DATETIME: 1882264Sjacobs result->datetime = v->datetime; 1892264Sjacobs break; 1902264Sjacobs case PAPI_COLLECTION: 1912264Sjacobs result->collection = collection_dup(v->collection); 1922264Sjacobs break; 1932264Sjacobs case PAPI_METADATA: 1942264Sjacobs result->metadata = v->metadata; 1952264Sjacobs break; 1962264Sjacobs default: /* unknown type, fail to duplicate */ 1972264Sjacobs free(result); 1982264Sjacobs result = NULL; 1992264Sjacobs } 2002264Sjacobs } 2012264Sjacobs 2022264Sjacobs return (result); 2032264Sjacobs } 2042264Sjacobs 2052264Sjacobs static papi_attribute_t * 2062264Sjacobs papiAttributeAlloc(char *name, papi_attribute_value_type_t type) 2072264Sjacobs { 2082264Sjacobs papi_attribute_t *result = NULL; 2092264Sjacobs 2102264Sjacobs if ((result = calloc(1, sizeof (*result))) != NULL) { 2112264Sjacobs result->name = strdup(name); 2122264Sjacobs result->type = type; 2132264Sjacobs } 2142264Sjacobs 2152264Sjacobs return (result); 2162264Sjacobs } 2172264Sjacobs 2182264Sjacobs static papi_status_t 2192264Sjacobs papiAttributeListAppendValue(papi_attribute_value_t ***values, 2202264Sjacobs papi_attribute_value_type_t type, 2212264Sjacobs papi_attribute_value_t *value) 2222264Sjacobs { 2232264Sjacobs 2242264Sjacobs if (values == NULL) 2252264Sjacobs return (PAPI_BAD_ARGUMENT); 2262264Sjacobs 2272264Sjacobs if (value != NULL) { /* this allows "empty" attributes */ 2282264Sjacobs papi_attribute_value_t *tmp = NULL; 2292264Sjacobs 2302264Sjacobs if ((tmp = papiAttributeValueDup(type, value)) == NULL) 2312264Sjacobs return (PAPI_TEMPORARY_ERROR); 2322264Sjacobs 2332264Sjacobs list_append(values, tmp); 2342264Sjacobs } 2352264Sjacobs 2362264Sjacobs return (PAPI_OK); 2372264Sjacobs } 2382264Sjacobs 2392264Sjacobs papi_status_t 2402264Sjacobs papiAttributeListAddValue(papi_attribute_t ***list, int flgs, 2412264Sjacobs char *name, papi_attribute_value_type_t type, 2422264Sjacobs papi_attribute_value_t *value) 2432264Sjacobs { 2442264Sjacobs papi_status_t result; 2452264Sjacobs int flags = flgs; 2462264Sjacobs papi_attribute_t *attribute = NULL; 2472264Sjacobs papi_attribute_value_t **values = NULL; 2482264Sjacobs 2492264Sjacobs if ((list == NULL) || (name == NULL)) 2502264Sjacobs return (PAPI_BAD_ARGUMENT); 2512264Sjacobs 2522264Sjacobs if ((type == PAPI_RANGE) && (value != NULL) && 2532264Sjacobs (value->range.lower > value->range.upper)) 2542264Sjacobs return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */ 2552264Sjacobs 2562264Sjacobs if (flags == 0) /* if it wasn't set, set a default behaviour */ 2572264Sjacobs flags = PAPI_ATTR_APPEND; 2582264Sjacobs 2592264Sjacobs /* look for an existing one */ 2602264Sjacobs attribute = papiAttributeListFind(*list, name); 2612264Sjacobs 2622264Sjacobs if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL)) 2632264Sjacobs return (PAPI_CONFLICT); /* EXISTS */ 2642264Sjacobs 2652264Sjacobs if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) && 2662264Sjacobs (attribute->type != type)) 2672264Sjacobs return (PAPI_CONFLICT); /* TYPE CONFLICT */ 2682264Sjacobs 2692264Sjacobs /* if we don't have one, create it and add it to the list */ 2702264Sjacobs if ((attribute == NULL) && 2712264Sjacobs ((attribute = papiAttributeAlloc(name, type)) != NULL)) 2722264Sjacobs list_append(list, attribute); 2732264Sjacobs 2742264Sjacobs /* if we don't have one by now, it's most likely an alloc fail */ 2752264Sjacobs if (attribute == NULL) 2762264Sjacobs return (PAPI_TEMPORARY_ERROR); 2772264Sjacobs 2782264Sjacobs /* 2792264Sjacobs * if we are replacing, clear any existing values, but don't free 2802264Sjacobs * until after we have replaced the values, in case we are replacing 2812264Sjacobs * a collection with a relocated version of the original collection. 2822264Sjacobs */ 2832264Sjacobs if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) { 2842264Sjacobs values = attribute->values; 2852264Sjacobs attribute->values = NULL; 2862264Sjacobs } 2872264Sjacobs 2882264Sjacobs attribute->type = type; 2892264Sjacobs 2902264Sjacobs result = papiAttributeListAppendValue(&attribute->values, type, value); 2912264Sjacobs 2922264Sjacobs /* free old values if we replaced them */ 2932264Sjacobs if (values != NULL) 2942264Sjacobs papiAttributeValuesFree(type, values); 2952264Sjacobs 2962264Sjacobs return (result); 2972264Sjacobs } 2982264Sjacobs 2992264Sjacobs papi_status_t 3002264Sjacobs papiAttributeListAddString(papi_attribute_t ***list, int flags, 3012264Sjacobs char *name, char *string) 3022264Sjacobs { 3032264Sjacobs papi_attribute_value_t v; 3042264Sjacobs 3052264Sjacobs v.string = (char *)string; 3062264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); 3072264Sjacobs } 3082264Sjacobs 3092264Sjacobs papi_status_t 3102264Sjacobs papiAttributeListAddInteger(papi_attribute_t ***list, int flags, 3112264Sjacobs char *name, int integer) 3122264Sjacobs { 3132264Sjacobs papi_attribute_value_t v; 3142264Sjacobs 3152264Sjacobs v.integer = integer; 3162264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); 3172264Sjacobs } 3182264Sjacobs 3192264Sjacobs papi_status_t 3202264Sjacobs papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, 3212264Sjacobs char *name, char boolean) 3222264Sjacobs { 3232264Sjacobs papi_attribute_value_t v; 3242264Sjacobs 3252264Sjacobs v.boolean = boolean; 3262264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); 3272264Sjacobs } 3282264Sjacobs 3292264Sjacobs papi_status_t 3302264Sjacobs papiAttributeListAddRange(papi_attribute_t ***list, int flags, 3312264Sjacobs char *name, int lower, int upper) 3322264Sjacobs { 3332264Sjacobs papi_attribute_value_t v; 3342264Sjacobs 3352264Sjacobs v.range.lower = lower; 3362264Sjacobs v.range.upper = upper; 3372264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); 3382264Sjacobs } 3392264Sjacobs 3402264Sjacobs papi_status_t 3412264Sjacobs papiAttributeListAddResolution(papi_attribute_t ***list, int flags, 3422264Sjacobs char *name, int xres, int yres, 3432264Sjacobs papi_resolution_unit_t units) 3442264Sjacobs { 3452264Sjacobs papi_attribute_value_t v; 3462264Sjacobs 3472264Sjacobs v.resolution.xres = xres; 3482264Sjacobs v.resolution.yres = yres; 3492264Sjacobs v.resolution.units = units; 3502264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3512264Sjacobs PAPI_RESOLUTION, &v)); 3522264Sjacobs } 3532264Sjacobs 3542264Sjacobs papi_status_t 3552264Sjacobs papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, 3562264Sjacobs char *name, time_t datetime) 3572264Sjacobs { 3582264Sjacobs papi_attribute_value_t v; 3592264Sjacobs 3602264Sjacobs v.datetime = datetime; 3612264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3622264Sjacobs PAPI_DATETIME, &v)); 3632264Sjacobs } 3642264Sjacobs 3652264Sjacobs papi_status_t 3662264Sjacobs papiAttributeListAddCollection(papi_attribute_t ***list, int flags, 3672264Sjacobs char *name, papi_attribute_t **collection) 3682264Sjacobs { 3692264Sjacobs papi_attribute_value_t v; 3702264Sjacobs 3712264Sjacobs v.collection = (papi_attribute_t **)collection; 3722264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3732264Sjacobs PAPI_COLLECTION, &v)); 3742264Sjacobs } 3752264Sjacobs 3762264Sjacobs papi_status_t 3772264Sjacobs papiAttributeListAddMetadata(papi_attribute_t ***list, int flags, 3782264Sjacobs char *name, papi_metadata_t metadata) 3792264Sjacobs { 3802264Sjacobs papi_attribute_value_t v; 3812264Sjacobs 3822264Sjacobs v.metadata = metadata; 3832264Sjacobs return (papiAttributeListAddValue(list, flags, name, 3842264Sjacobs PAPI_METADATA, &v)); 3852264Sjacobs } 3862264Sjacobs 3872264Sjacobs papi_status_t 3882264Sjacobs papiAttributeListDelete(papi_attribute_t ***list, char *name) 3892264Sjacobs { 3902264Sjacobs papi_attribute_t *attribute; 3912264Sjacobs 3922264Sjacobs if ((list == NULL) || (name == NULL)) 3932264Sjacobs return (PAPI_BAD_ARGUMENT); 3942264Sjacobs 3952264Sjacobs if ((attribute = papiAttributeListFind(*list, name)) == NULL) 3962264Sjacobs return (PAPI_NOT_FOUND); 3972264Sjacobs 3983125Sjacobs list_remove(list, attribute); 3992264Sjacobs papiAttributeFree(attribute); 4002264Sjacobs 4012264Sjacobs return (PAPI_OK); 4022264Sjacobs } 4032264Sjacobs 4042264Sjacobs papi_attribute_t * 4052264Sjacobs papiAttributeListFind(papi_attribute_t **list, char *name) 4062264Sjacobs { 4072264Sjacobs int i; 4082264Sjacobs if ((list == NULL) || (name == NULL)) 4092264Sjacobs return (NULL); 4102264Sjacobs 4112264Sjacobs for (i = 0; list[i] != NULL; i++) 4122264Sjacobs if (strcasecmp(list[i]->name, name) == 0) 4132264Sjacobs return ((papi_attribute_t *)list[i]); 4142264Sjacobs 4152264Sjacobs return (NULL); 4162264Sjacobs } 4172264Sjacobs 4182264Sjacobs papi_attribute_t * 4192264Sjacobs papiAttributeListGetNext(papi_attribute_t **list, void **iter) 4202264Sjacobs { 4212264Sjacobs papi_attribute_t **tmp, *result; 4222264Sjacobs 4232264Sjacobs if ((list == NULL) && (iter == NULL)) 4242264Sjacobs return (NULL); 4252264Sjacobs 4262264Sjacobs if (*iter == NULL) 4272264Sjacobs *iter = list; 4282264Sjacobs 4292264Sjacobs tmp = *iter; 4302264Sjacobs result = *tmp; 4312264Sjacobs *iter = ++tmp; 4322264Sjacobs 4332264Sjacobs return (result); 4342264Sjacobs } 4352264Sjacobs 4362264Sjacobs papi_status_t 4372264Sjacobs papiAttributeListGetValue(papi_attribute_t **list, void **iter, 4382264Sjacobs char *name, papi_attribute_value_type_t type, 4392264Sjacobs papi_attribute_value_t **value) 4402264Sjacobs { 4412264Sjacobs papi_attribute_value_t **tmp; 4422264Sjacobs void *fodder = NULL; 4432264Sjacobs 4442264Sjacobs if ((list == NULL) || ((name == NULL) && (iter == NULL)) || 4452264Sjacobs (value == NULL)) 4462264Sjacobs return (PAPI_BAD_ARGUMENT); 4472264Sjacobs 4482264Sjacobs if (iter == NULL) 4492264Sjacobs iter = &fodder; 4502264Sjacobs 4512264Sjacobs if ((iter == NULL) || (*iter == NULL)) { 4522264Sjacobs papi_attribute_t *attr = papiAttributeListFind(list, name); 4532264Sjacobs 4542264Sjacobs if (attr == NULL) 4552264Sjacobs return (PAPI_NOT_FOUND); 4562264Sjacobs 4572264Sjacobs if (attr->type != type) 4582264Sjacobs return (PAPI_NOT_POSSIBLE); 4592264Sjacobs 4602264Sjacobs tmp = attr->values; 4612264Sjacobs } else 4622264Sjacobs tmp = *iter; 4632264Sjacobs 4642264Sjacobs if (tmp == NULL) 4652264Sjacobs return (PAPI_NOT_FOUND); 4662264Sjacobs 4672264Sjacobs *value = *tmp; 4682264Sjacobs *iter = ++tmp; 4692264Sjacobs 4702264Sjacobs if (*value == NULL) 4712264Sjacobs return (PAPI_GONE); 4722264Sjacobs 4732264Sjacobs return (PAPI_OK); 4742264Sjacobs } 4752264Sjacobs 4762264Sjacobs papi_status_t 4772264Sjacobs papiAttributeListGetString(papi_attribute_t **list, void **iter, 4782264Sjacobs char *name, char **vptr) 4792264Sjacobs { 4802264Sjacobs papi_status_t status; 4812264Sjacobs papi_attribute_value_t *value = NULL; 4822264Sjacobs 4832264Sjacobs if (vptr == NULL) 4842264Sjacobs return (PAPI_BAD_ARGUMENT); 4852264Sjacobs 4862264Sjacobs status = papiAttributeListGetValue(list, iter, name, 4872264Sjacobs PAPI_STRING, &value); 4882264Sjacobs if (status == PAPI_OK) 4892264Sjacobs *vptr = value->string; 4902264Sjacobs 4912264Sjacobs return (status); 4922264Sjacobs } 4932264Sjacobs 4942264Sjacobs papi_status_t 4952264Sjacobs papiAttributeListGetInteger(papi_attribute_t **list, void **iter, 4962264Sjacobs char *name, int *vptr) 4972264Sjacobs { 4982264Sjacobs papi_status_t status; 4992264Sjacobs papi_attribute_value_t *value = NULL; 5002264Sjacobs 5012264Sjacobs if (vptr == NULL) 5022264Sjacobs return (PAPI_BAD_ARGUMENT); 5032264Sjacobs 5042264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5052264Sjacobs PAPI_INTEGER, &value); 5062264Sjacobs if (status == PAPI_OK) 5072264Sjacobs *vptr = value->integer; 5082264Sjacobs 5092264Sjacobs return (status); 5102264Sjacobs } 5112264Sjacobs 5122264Sjacobs papi_status_t 5132264Sjacobs papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, 5142264Sjacobs char *name, char *vptr) 5152264Sjacobs { 5162264Sjacobs papi_status_t status; 5172264Sjacobs papi_attribute_value_t *value = NULL; 5182264Sjacobs 5192264Sjacobs if (vptr == NULL) 5202264Sjacobs return (PAPI_BAD_ARGUMENT); 5212264Sjacobs 5222264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5232264Sjacobs PAPI_BOOLEAN, &value); 5242264Sjacobs if (status == PAPI_OK) 5252264Sjacobs *vptr = value->boolean; 5262264Sjacobs 5272264Sjacobs return (status); 5282264Sjacobs } 5292264Sjacobs 5302264Sjacobs papi_status_t 5312264Sjacobs papiAttributeListGetRange(papi_attribute_t **list, void **iter, 5322264Sjacobs char *name, int *min, int *max) 5332264Sjacobs { 5342264Sjacobs papi_status_t status; 5352264Sjacobs papi_attribute_value_t *value = NULL; 5362264Sjacobs 5372264Sjacobs if ((min == NULL) || (max == NULL)) 5382264Sjacobs return (PAPI_BAD_ARGUMENT); 5392264Sjacobs 5402264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5412264Sjacobs PAPI_RANGE, &value); 5422264Sjacobs if (status == PAPI_OK) { 5432264Sjacobs *min = value->range.lower; 5442264Sjacobs *max = value->range.upper; 5452264Sjacobs } 5462264Sjacobs 5472264Sjacobs return (status); 5482264Sjacobs } 5492264Sjacobs 5502264Sjacobs papi_status_t 5512264Sjacobs papiAttributeListGetResolution(papi_attribute_t **list, void **iter, 5522264Sjacobs char *name, int *x, int *y, 5532264Sjacobs papi_resolution_unit_t *units) 5542264Sjacobs { 5552264Sjacobs papi_status_t status; 5562264Sjacobs papi_attribute_value_t *value = NULL; 5572264Sjacobs 5582264Sjacobs if ((x == NULL) || (y == NULL) || (units == NULL)) 5592264Sjacobs return (PAPI_BAD_ARGUMENT); 5602264Sjacobs 5612264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5622264Sjacobs PAPI_RESOLUTION, &value); 5632264Sjacobs if (status == PAPI_OK) { 5642264Sjacobs *x = value->resolution.xres; 5652264Sjacobs *y = value->resolution.yres; 5662264Sjacobs *units = value->resolution.units; 5672264Sjacobs } 5682264Sjacobs 5692264Sjacobs return (status); 5702264Sjacobs } 5712264Sjacobs 5722264Sjacobs papi_status_t 5732264Sjacobs papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, 5742264Sjacobs char *name, time_t *dt) 5752264Sjacobs { 5762264Sjacobs papi_status_t status; 5772264Sjacobs papi_attribute_value_t *value = NULL; 5782264Sjacobs 5792264Sjacobs if (dt == NULL) 5802264Sjacobs return (PAPI_BAD_ARGUMENT); 5812264Sjacobs 5822264Sjacobs status = papiAttributeListGetValue(list, iter, name, 5832264Sjacobs PAPI_DATETIME, &value); 5842264Sjacobs if (status == PAPI_OK) { 5852264Sjacobs *dt = value->datetime; 5862264Sjacobs } 5872264Sjacobs 5882264Sjacobs return (status); 5892264Sjacobs } 5902264Sjacobs 5912264Sjacobs papi_status_t 5922264Sjacobs papiAttributeListGetCollection(papi_attribute_t **list, void **iter, 5932264Sjacobs char *name, papi_attribute_t ***collection) 5942264Sjacobs { 5952264Sjacobs papi_status_t status; 5962264Sjacobs papi_attribute_value_t *value = NULL; 5972264Sjacobs 5982264Sjacobs if (collection == NULL) 5992264Sjacobs return (PAPI_BAD_ARGUMENT); 6002264Sjacobs 6012264Sjacobs status = papiAttributeListGetValue(list, iter, name, 6022264Sjacobs PAPI_COLLECTION, &value); 6032264Sjacobs if (status == PAPI_OK) { 6042264Sjacobs *collection = value->collection; 6052264Sjacobs } 6062264Sjacobs 6072264Sjacobs return (status); 6082264Sjacobs } 6092264Sjacobs 6102264Sjacobs papi_status_t 6112264Sjacobs papiAttributeListGetMetadata(papi_attribute_t **list, void **iter, 6122264Sjacobs char *name, papi_metadata_t *vptr) 6132264Sjacobs { 6142264Sjacobs papi_status_t status; 6152264Sjacobs papi_attribute_value_t *value = NULL; 6162264Sjacobs 6172264Sjacobs if (vptr == NULL) 6182264Sjacobs return (PAPI_BAD_ARGUMENT); 6192264Sjacobs 6202264Sjacobs status = papiAttributeListGetValue(list, iter, name, 6212264Sjacobs PAPI_METADATA, &value); 6222264Sjacobs if (status == PAPI_OK) 6232264Sjacobs *vptr = value->metadata; 6242264Sjacobs 6252264Sjacobs return (status); 6262264Sjacobs } 6272264Sjacobs 6282264Sjacobs 6296725Sjacobs /* The string is modified by this call */ 6302264Sjacobs static char * 6316725Sjacobs regvalue(regmatch_t match, char *string) 6322264Sjacobs { 6332264Sjacobs char *result = NULL; 6346725Sjacobs if (match.rm_so != match.rm_eo) { 6356725Sjacobs result = string + match.rm_so; 6366725Sjacobs *(result + (match.rm_eo - match.rm_so)) = '\0'; 6376725Sjacobs } 6386725Sjacobs return (result); 6396725Sjacobs } 6402264Sjacobs 6416725Sjacobs static papi_attribute_value_type_t 6426725Sjacobs _process_value(char *string, char ***parts) 6436725Sjacobs { 6446725Sjacobs int i; 6456725Sjacobs static struct { 6466725Sjacobs papi_attribute_value_type_t type; 6476725Sjacobs size_t vals; 6486725Sjacobs char *expression; 6496725Sjacobs int compiled; 6506725Sjacobs regex_t re; 6516725Sjacobs } types[] = { 6526725Sjacobs { PAPI_BOOLEAN, 1, "^(true|false|yes|no)$", 0 }, 6536725Sjacobs { PAPI_COLLECTION, 1, "^\\{(.+)\\}$", 0 }, 6546725Sjacobs /* PAPI_DATETIME is unsupported, too much like an integer */ 6556725Sjacobs { PAPI_INTEGER, 1, "^([+-]{0,1}[[:digit:]]+)$", 0 }, 656*7154Ssg223391 { PAPI_RANGE, 3, "^([[:digit:]]*)-([[:digit:]]*)$", 0 }, 6576725Sjacobs { PAPI_RESOLUTION, 4, "^([[:digit:]]+)x([[:digit:]]+)dp(i|c)$", 6586725Sjacobs 0 }, 6596725Sjacobs NULL 6606725Sjacobs }; 6616725Sjacobs regmatch_t matches[4]; 6626725Sjacobs 6636725Sjacobs for (i = 0; i < 5; i++) { 6646725Sjacobs int j; 6656725Sjacobs 6666725Sjacobs if (types[i].compiled == 0) { 6676725Sjacobs (void) regcomp(&(types[i].re), types[i].expression, 6686725Sjacobs REG_EXTENDED|REG_ICASE); 6696725Sjacobs types[i].compiled = 1; 6702264Sjacobs } 6716725Sjacobs if (regexec(&(types[i].re), string, (size_t)types[i].vals, 6726725Sjacobs matches, 0) == REG_NOMATCH) 6736725Sjacobs continue; 6746725Sjacobs 6756725Sjacobs for (j = 0 ; j < types[i].vals; j++) 6766725Sjacobs list_append(parts, regvalue(matches[j], string)); 6776725Sjacobs return (types[i].type); 6786725Sjacobs } 6792264Sjacobs 6806725Sjacobs list_append(parts, string); 6816725Sjacobs return (PAPI_STRING); 6826725Sjacobs } 6836725Sjacobs 6846725Sjacobs static void 6856725Sjacobs _add_attribute_value(papi_attribute_value_t ***list, 6866725Sjacobs papi_attribute_value_type_t type, 6876725Sjacobs papi_attribute_value_type_t dtype, char **parts) 6886725Sjacobs { 6896725Sjacobs papi_attribute_value_t *value = calloc(1, sizeof (*value)); 6902264Sjacobs 6916725Sjacobs switch(type) { 6926725Sjacobs case PAPI_STRING: 6936725Sjacobs value->string = strdup(parts[0]); 6946725Sjacobs list_append(list, value); 6956725Sjacobs break; 6966725Sjacobs case PAPI_BOOLEAN: 6976725Sjacobs value->boolean = PAPI_TRUE; 6986725Sjacobs if ((strcasecmp(parts[0], "false") == 0) || 6996725Sjacobs (strcasecmp(parts[0], "no") == 0)) 7006725Sjacobs value->boolean = PAPI_FALSE; 7016725Sjacobs list_append(list, value); 7026725Sjacobs break; 7036725Sjacobs case PAPI_INTEGER: 7046725Sjacobs value->integer = atoi(parts[0]); 7056725Sjacobs list_append(list, value); 7066725Sjacobs break; 7076725Sjacobs case PAPI_RANGE: 708*7154Ssg223391 if (dtype == PAPI_INTEGER) { 709*7154Ssg223391 if (atoi(parts[0]) < 0) { 710*7154Ssg223391 /* 711*7154Ssg223391 * Handles -P -x case 712*7154Ssg223391 * which prints from page number 1 713*7154Ssg223391 * till page number x 714*7154Ssg223391 */ 715*7154Ssg223391 value->range.lower = 1; 716*7154Ssg223391 value->range.upper = 0 - (atoi(parts[0])); 717*7154Ssg223391 } else { 718*7154Ssg223391 value->range.lower = value->range.upper 719*7154Ssg223391 = atoi(parts[0]); 720*7154Ssg223391 } 721*7154Ssg223391 } else if (dtype == PAPI_RANGE) { 722*7154Ssg223391 if (parts[2] == NULL) { 723*7154Ssg223391 value->range.lower = atoi(parts[1]); 724*7154Ssg223391 /* 725*7154Ssg223391 * Imposing an artificial limit on 726*7154Ssg223391 * the upper bound for page range. 727*7154Ssg223391 */ 728*7154Ssg223391 value->range.upper = MAX_PAGES; 729*7154Ssg223391 } else if ((parts[1] != NULL) && (parts[2] != NULL)) { 730*7154Ssg223391 value->range.lower = atoi(parts[1]); 731*7154Ssg223391 value->range.upper = atoi(parts[2]); 732*7154Ssg223391 } 7332264Sjacobs } 7346725Sjacobs list_append(list, value); 7356725Sjacobs break; 7366725Sjacobs case PAPI_RESOLUTION: 7376725Sjacobs value->resolution.xres = atoi(parts[1]); 7386725Sjacobs value->resolution.yres = atoi(parts[2]); 7396725Sjacobs if (parts[3][0] == 'i') 7406725Sjacobs value->resolution.units = PAPI_RES_PER_INCH; 7416725Sjacobs else 7426725Sjacobs value->resolution.units = PAPI_RES_PER_CM; 7436725Sjacobs list_append(list, value); 7446725Sjacobs break; 7456725Sjacobs case PAPI_COLLECTION: 7466725Sjacobs papiAttributeListFromString(&(value->collection), 0, parts[0]); 7476725Sjacobs list_append(list, value); 7486725Sjacobs break; 7496725Sjacobs } 7506725Sjacobs } 7512264Sjacobs 7526725Sjacobs static papi_status_t 7536725Sjacobs _papiAttributeFromStrings(papi_attribute_t ***list, int flags, 7546725Sjacobs char *key, char **values) 7556725Sjacobs { 7566725Sjacobs int i; 7576725Sjacobs papi_status_t result = PAPI_OK; 7586725Sjacobs papi_attribute_t *attr = calloc(1, sizeof (*attr)); 7596725Sjacobs 7606725Sjacobs /* these are specified in the papi spec as ranges */ 7616725Sjacobs char *ranges[] = { "copies-supported", "job-impressions-supported", 7626725Sjacobs "job-k-octets-supported", 7636725Sjacobs "job-media-sheets-supported", "page-ranges", 7646725Sjacobs NULL }; 7656725Sjacobs 7666725Sjacobs if ((attr == NULL) || ((attr->name = strdup(key)) == NULL)) 7676725Sjacobs return (PAPI_TEMPORARY_ERROR); 7686725Sjacobs 7696725Sjacobs attr->type = PAPI_METADATA; 7706725Sjacobs /* these are known ranges */ 7716725Sjacobs for (i = 0; ranges[i] != NULL; i++) 7726725Sjacobs if (strcasecmp(attr->name, ranges[i]) == 0) { 7736725Sjacobs attr->type = PAPI_RANGE; 7746725Sjacobs break; 7756725Sjacobs } 7766725Sjacobs 7776725Sjacobs if (values != NULL) { 7786725Sjacobs papi_attribute_value_t **vals = NULL; 7796725Sjacobs 7806725Sjacobs for (i = 0; values[i] != NULL; i++) { 7816725Sjacobs papi_attribute_value_type_t dtype; 7826725Sjacobs char **parts = NULL; 7836725Sjacobs 7846725Sjacobs dtype = _process_value(values[i], &parts); 7856725Sjacobs if (attr->type == PAPI_METADATA) 7866725Sjacobs attr->type = dtype; 7876725Sjacobs _add_attribute_value(&vals, attr->type, dtype, parts); 7886725Sjacobs free(parts); 7892264Sjacobs } 7906725Sjacobs attr->values = vals; 7916725Sjacobs } 7926725Sjacobs 7936725Sjacobs list_append(list, attr); 7946725Sjacobs 7956725Sjacobs return (result); 7966725Sjacobs } 7972264Sjacobs 7986725Sjacobs static papi_status_t 7996725Sjacobs _parse_attribute_list(papi_attribute_t ***list, int flags, char *string) 8006725Sjacobs { 8016725Sjacobs papi_status_t result = PAPI_OK; 8026725Sjacobs char *ptr; 8036725Sjacobs 8046725Sjacobs if ((list == NULL) || (string == NULL)) 8056725Sjacobs return (PAPI_BAD_ARGUMENT); 8066725Sjacobs 8076725Sjacobs if ((ptr = strdup(string)) == NULL) 8086725Sjacobs return (PAPI_TEMPORARY_ERROR); 8096725Sjacobs 8106725Sjacobs while ((*ptr != '\0') && (result == PAPI_OK)) { 8116725Sjacobs char *key, **values = NULL; 8126725Sjacobs 8136725Sjacobs /* strip any leading whitespace */ 8146725Sjacobs while (isspace(*ptr) != 0) 8156725Sjacobs ptr++; 8166725Sjacobs 8176725Sjacobs /* Get the name: name[=value] */ 8186725Sjacobs key = ptr; 8196725Sjacobs while ((*ptr != '\0') && (*ptr != '=') && (isspace(*ptr) == 0)) 8206725Sjacobs ptr++; 8216725Sjacobs 8226725Sjacobs if (*ptr == '=') { 8236725Sjacobs *ptr++ = '\0'; 8246725Sjacobs 8256725Sjacobs while ((*ptr != '\0') && (isspace(*ptr) == 0)) { 8266725Sjacobs char *value = ptr; 8276725Sjacobs 8286725Sjacobs if ((*ptr == '\'') || (*ptr == '"')) { 8296725Sjacobs char q = *ptr++; 8302264Sjacobs 8316725Sjacobs /* quoted string value */ 8326725Sjacobs while ((*ptr != '\0') && (*ptr != q)) 8336725Sjacobs ptr++; 8346725Sjacobs if (*ptr == q) 8356725Sjacobs ptr++; 8366725Sjacobs } else if (*ptr == '{') { 8376725Sjacobs /* collection */ 8386725Sjacobs while ((*ptr != '\0') && (*ptr != '}')) 8396725Sjacobs ptr++; 8406725Sjacobs if (*ptr == '}') 8416725Sjacobs ptr++; 8426725Sjacobs } else { 8436725Sjacobs /* value */ 8446725Sjacobs while ((*ptr != '\0') && 8456725Sjacobs (*ptr != ',') && 8466725Sjacobs (isspace(*ptr) == 0)) 8476725Sjacobs ptr++; 8486725Sjacobs } 8496725Sjacobs if (*ptr == ',') 8506725Sjacobs *ptr++ = '\0'; 8516725Sjacobs list_append(&values, value); 8522264Sjacobs } 8536725Sjacobs } else { /* boolean "[no]key" */ 8546725Sjacobs char *value = "true"; 8556725Sjacobs 8566725Sjacobs if (strncasecmp(key, "no", 2) == 0) { 8576725Sjacobs key += 2; 8586725Sjacobs value = "false"; 8596725Sjacobs } 8606725Sjacobs list_append(&values, value); 8612264Sjacobs } 8626725Sjacobs if (*ptr != '\0') 8636725Sjacobs *ptr++ = '\0'; 8646725Sjacobs 8656725Sjacobs result = _papiAttributeFromStrings(list, flags, key, values); 8666725Sjacobs free(values); 8672264Sjacobs } 8682264Sjacobs 8692264Sjacobs return (result); 8706725Sjacobs } 8712264Sjacobs 8722264Sjacobs papi_status_t 8732264Sjacobs papiAttributeListFromString(papi_attribute_t ***attrs, 8742264Sjacobs int flags, char *string) 8752264Sjacobs { 8762264Sjacobs papi_status_t result = PAPI_OK; 8772264Sjacobs 8782264Sjacobs if ((attrs != NULL) && (string != NULL) && 8792264Sjacobs ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) 8802264Sjacobs == 0)) { 8816725Sjacobs result = _parse_attribute_list(attrs, flags, string); 8826725Sjacobs } else { 8832264Sjacobs result = PAPI_BAD_ARGUMENT; 8842264Sjacobs } 8852264Sjacobs 8862264Sjacobs return (result); 8872264Sjacobs } 8882264Sjacobs 8892264Sjacobs static papi_status_t 8902264Sjacobs papiAttributeToString(papi_attribute_t *attribute, char *delim, 8912264Sjacobs char *buffer, size_t buflen) 8922264Sjacobs { 8932264Sjacobs papi_attribute_value_t **values = attribute->values; 8942264Sjacobs int rc, i; 8952264Sjacobs 8966725Sjacobs if ((attribute->type == PAPI_BOOLEAN) && (values[1] == NULL)) { 8976725Sjacobs if (values[0]->boolean == PAPI_FALSE) { 8986725Sjacobs if (isupper(attribute->name[0]) == 0) 8996725Sjacobs strlcat(buffer, "no", buflen); 9006725Sjacobs else 9016725Sjacobs strlcat(buffer, "No", buflen); 9026725Sjacobs } 9036725Sjacobs rc = strlcat(buffer, attribute->name, buflen); 9046725Sjacobs } else { 9056725Sjacobs strlcat(buffer, attribute->name, buflen); 9066725Sjacobs rc = strlcat(buffer, "=", buflen); 9076725Sjacobs } 9082264Sjacobs 9092264Sjacobs if (values == NULL) 9102264Sjacobs return (PAPI_OK); 9112264Sjacobs 9122264Sjacobs for (i = 0; values[i] != NULL; i++) { 9132264Sjacobs switch (attribute->type) { 9142264Sjacobs case PAPI_STRING: 9152264Sjacobs rc = strlcat(buffer, values[i]->string, buflen); 9162264Sjacobs break; 9172264Sjacobs case PAPI_INTEGER: { 9182264Sjacobs char string[24]; 9192264Sjacobs 9202264Sjacobs snprintf(string, sizeof (string), "%d", 9212264Sjacobs values[i]->integer); 9222264Sjacobs rc = strlcat(buffer, string, buflen); 9232264Sjacobs } 9242264Sjacobs break; 9252264Sjacobs case PAPI_BOOLEAN: 9266725Sjacobs if (values[1] != NULL) 9276725Sjacobs rc = strlcat(buffer, (values[i]->boolean ? 9286725Sjacobs "true" : "false"), buflen); 9292264Sjacobs break; 9302264Sjacobs case PAPI_RANGE: { 9312264Sjacobs char string[24]; 9322264Sjacobs 9336725Sjacobs if (values[i]->range.lower == values[i]->range.upper) 9346725Sjacobs snprintf(string, sizeof (string), "%d", 9356725Sjacobs values[i]->range.lower); 9366725Sjacobs else 9376725Sjacobs snprintf(string, sizeof (string), "%d-%d", 9386725Sjacobs values[i]->range.lower, 9396725Sjacobs values[i]->range.upper); 9402264Sjacobs rc = strlcat(buffer, string, buflen); 9412264Sjacobs } 9422264Sjacobs break; 9432264Sjacobs case PAPI_RESOLUTION: { 9442264Sjacobs char string[24]; 9452264Sjacobs 9462264Sjacobs snprintf(string, sizeof (string), "%dx%ddp%c", 9472264Sjacobs values[i]->resolution.xres, 9482264Sjacobs values[i]->resolution.yres, 9492264Sjacobs (values[i]->resolution.units == PAPI_RES_PER_CM 9502264Sjacobs ? 'c' : 'i')); 9512264Sjacobs rc = strlcat(buffer, string, buflen); 9522264Sjacobs } 9532264Sjacobs break; 9542264Sjacobs case PAPI_DATETIME: { 9552264Sjacobs struct tm *tm = localtime(&values[i]->datetime); 9562264Sjacobs 9572264Sjacobs if (tm != NULL) { 9582264Sjacobs char string[64]; 9592264Sjacobs 9602264Sjacobs strftime(string, sizeof (string), "%C", tm); 9612264Sjacobs rc = strlcat(buffer, string, buflen); 9622264Sjacobs }} 9632264Sjacobs break; 9642264Sjacobs case PAPI_COLLECTION: { 9652264Sjacobs char *string = alloca(buflen); 9662264Sjacobs 9672264Sjacobs papiAttributeListToString(values[i]->collection, 9682264Sjacobs delim, string, buflen); 9692264Sjacobs rc = strlcat(buffer, string, buflen); 9702264Sjacobs } 9712264Sjacobs break; 9722264Sjacobs default: { 9732264Sjacobs char string[32]; 9742264Sjacobs 9752264Sjacobs snprintf(string, sizeof (string), "unknown-type-0x%x", 9762264Sjacobs attribute->type); 9772264Sjacobs rc = strlcat(buffer, string, buflen); 9782264Sjacobs } 9792264Sjacobs } 9802264Sjacobs if (values[i+1] != NULL) 9812264Sjacobs rc = strlcat(buffer, ",", buflen); 9822264Sjacobs 9832264Sjacobs if (rc >= buflen) 9842264Sjacobs return (PAPI_NOT_POSSIBLE); 9852264Sjacobs 9862264Sjacobs } 9872264Sjacobs 9882264Sjacobs return (PAPI_OK); 9892264Sjacobs } 9902264Sjacobs 9912264Sjacobs papi_status_t 9922264Sjacobs papiAttributeListToString(papi_attribute_t **attrs, 9932264Sjacobs char *delim, char *buffer, size_t buflen) 9942264Sjacobs { 9952264Sjacobs papi_status_t status = PAPI_OK; 9962264Sjacobs int i; 9972264Sjacobs 9982264Sjacobs if ((attrs == NULL) || (buffer == NULL)) 9992264Sjacobs return (PAPI_BAD_ARGUMENT); 10002264Sjacobs 10012264Sjacobs buffer[0] = '\0'; 10022264Sjacobs if (!delim) 10032264Sjacobs delim = " "; 10042264Sjacobs 10052264Sjacobs for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) { 10062264Sjacobs status = papiAttributeToString(attrs[i], delim, buffer, buflen); 10072264Sjacobs if (attrs[i+1] != NULL) 10082264Sjacobs strlcat(buffer, delim, buflen); 10092264Sjacobs } 10102264Sjacobs 10112264Sjacobs return (status); 10122264Sjacobs } 10132264Sjacobs 10142264Sjacobs static int 10152264Sjacobs is_in_list(char *value, char **list) 10162264Sjacobs { 10172264Sjacobs if ((list != NULL) && (value != NULL)) { 10182264Sjacobs int i; 10192264Sjacobs 10202264Sjacobs for (i = 0; list[i] != NULL; i++) 10212264Sjacobs if (strcasecmp(value, list[i]) == 0) 10222264Sjacobs return (0); 10232264Sjacobs } 10242264Sjacobs 10252264Sjacobs return (1); 10262264Sjacobs } 10272264Sjacobs 10282264Sjacobs static papi_status_t 10292264Sjacobs copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute) 10302264Sjacobs { 10312264Sjacobs papi_status_t status; 10322264Sjacobs int i = 0; 10332264Sjacobs 10342264Sjacobs if ((list == NULL) || (attribute == NULL) || 10352264Sjacobs (attribute->values == NULL)) 10362264Sjacobs return (PAPI_BAD_ARGUMENT); 10372264Sjacobs 10382264Sjacobs for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL, 10392264Sjacobs attribute->name, attribute->type, 10402264Sjacobs attribute->values[i]); 10412264Sjacobs ((status == PAPI_OK) && (attribute->values[i] != NULL)); 10422264Sjacobs status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND, 10432264Sjacobs attribute->name, attribute->type, 10442264Sjacobs attribute->values[i])) 10452264Sjacobs i++; 10462264Sjacobs 10472264Sjacobs return (status); 10482264Sjacobs } 10492264Sjacobs 10502264Sjacobs void 10512264Sjacobs copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes) 10522264Sjacobs { 10532264Sjacobs int i; 10542264Sjacobs 10552264Sjacobs if ((result == NULL) || (attributes == NULL)) 10562264Sjacobs return; 10572264Sjacobs 10582264Sjacobs for (i = 0; attributes[i] != NULL; i++) 10592264Sjacobs copy_attribute(result, attributes[i]); 10602264Sjacobs } 10612264Sjacobs 10622264Sjacobs void 10632264Sjacobs split_and_copy_attributes(char **list, papi_attribute_t **attributes, 10642264Sjacobs papi_attribute_t ***in, papi_attribute_t ***out) 10652264Sjacobs { 10662264Sjacobs int i; 10672264Sjacobs 10682264Sjacobs if ((list == NULL) || (attributes == NULL)) 10692264Sjacobs return; 10702264Sjacobs 10712264Sjacobs for (i = 0; attributes[i] != NULL; i++) 10722264Sjacobs if (is_in_list(attributes[i]->name, list) == 0) 10732264Sjacobs copy_attribute(in, attributes[i]); 10742264Sjacobs else 10752264Sjacobs copy_attribute(out, attributes[i]); 10762264Sjacobs } 10772264Sjacobs 10782264Sjacobs void 10792264Sjacobs papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes, 10802264Sjacobs char *prefix_fmt, ...) 10812264Sjacobs { 10822264Sjacobs char *prefix = NULL; 10832264Sjacobs char *buffer = NULL; 10842264Sjacobs char *newfmt = NULL; 10852264Sjacobs void *mem; 10862264Sjacobs ssize_t size = 0; 10872264Sjacobs va_list ap; 10882264Sjacobs 10892264Sjacobs newfmt = malloc(strlen(prefix_fmt) + 2); 10902264Sjacobs sprintf(newfmt, "\n%s", prefix_fmt); 10912264Sjacobs 10922264Sjacobs va_start(ap, prefix_fmt); 10932264Sjacobs while (vsnprintf(prefix, size, newfmt, ap) > size) { 10942264Sjacobs size += 1024; 10952264Sjacobs mem = realloc(prefix, size); 10962264Sjacobs if (!mem) goto error; 10972264Sjacobs prefix = mem; 10982264Sjacobs } 10992264Sjacobs va_end(ap); 11002264Sjacobs 11012264Sjacobs if (attributes) { 11022264Sjacobs size = 0; 11032264Sjacobs while (papiAttributeListToString(attributes, prefix, buffer, 11042264Sjacobs size) != PAPI_OK) { 11052264Sjacobs size += 1024; 11062264Sjacobs mem = realloc(buffer, size); 11072264Sjacobs if (!mem) goto error; 11082264Sjacobs buffer = mem; 11092264Sjacobs } 11102264Sjacobs } 11112264Sjacobs 11122264Sjacobs fprintf(fp, "%s%s\n", prefix, buffer ? buffer : ""); 11132264Sjacobs fflush(fp); 11142264Sjacobs 11152264Sjacobs error: 11162264Sjacobs free(newfmt); 11172264Sjacobs free(prefix); 11182264Sjacobs free(buffer); 11192264Sjacobs } 1120