17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5355b4669Sjacobs * Common Development and Distribution License (the "License"). 6355b4669Sjacobs * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21355b4669Sjacobs 227c478bd9Sstevel@tonic-gate /* 23355b4669Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25355b4669Sjacobs * 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 28355b4669Sjacobs /* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */ 29355b4669Sjacobs 307c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <stdio.h> 357c478bd9Sstevel@tonic-gate #include <stdlib.h> 36355b4669Sjacobs #include <stdarg.h> 377c478bd9Sstevel@tonic-gate #include <string.h> 38355b4669Sjacobs #include <alloca.h> 39355b4669Sjacobs #include <papi.h> 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate static void papiAttributeFree(papi_attribute_t *attribute); 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate static void 447c478bd9Sstevel@tonic-gate papiAttributeValueFree(papi_attribute_value_type_t type, 457c478bd9Sstevel@tonic-gate papi_attribute_value_t *value) 467c478bd9Sstevel@tonic-gate { 477c478bd9Sstevel@tonic-gate if (value != NULL) { 487c478bd9Sstevel@tonic-gate switch (type) { 497c478bd9Sstevel@tonic-gate case PAPI_STRING: 507c478bd9Sstevel@tonic-gate if (value->string != NULL) 517c478bd9Sstevel@tonic-gate free(value->string); 527c478bd9Sstevel@tonic-gate break; 537c478bd9Sstevel@tonic-gate case PAPI_COLLECTION: 547c478bd9Sstevel@tonic-gate if (value->collection != NULL) { 557c478bd9Sstevel@tonic-gate int i; 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate for (i = 0; value->collection[i] != NULL; i++) 587c478bd9Sstevel@tonic-gate papiAttributeFree(value->collection[i]); 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate free(value->collection); 617c478bd9Sstevel@tonic-gate } 627c478bd9Sstevel@tonic-gate break; 637c478bd9Sstevel@tonic-gate default: /* don't need to free anything extra */ 647c478bd9Sstevel@tonic-gate break; 657c478bd9Sstevel@tonic-gate } 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate free(value); 687c478bd9Sstevel@tonic-gate } 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate static void 727c478bd9Sstevel@tonic-gate papiAttributeValuesFree(papi_attribute_value_type_t type, 737c478bd9Sstevel@tonic-gate papi_attribute_value_t **values) 747c478bd9Sstevel@tonic-gate { 757c478bd9Sstevel@tonic-gate if (values != NULL) { 767c478bd9Sstevel@tonic-gate int i; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate for (i = 0; values[i] != NULL; i++) 797c478bd9Sstevel@tonic-gate papiAttributeValueFree(type, values[i]); 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate free(values); 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate static void 867c478bd9Sstevel@tonic-gate papiAttributeFree(papi_attribute_t *attribute) 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate if (attribute != NULL) { 897c478bd9Sstevel@tonic-gate if (attribute->name != NULL) 907c478bd9Sstevel@tonic-gate free(attribute->name); 917c478bd9Sstevel@tonic-gate if (attribute->values != NULL) 927c478bd9Sstevel@tonic-gate papiAttributeValuesFree(attribute->type, 937c478bd9Sstevel@tonic-gate attribute->values); 947c478bd9Sstevel@tonic-gate free(attribute); 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate void 997c478bd9Sstevel@tonic-gate papiAttributeListFree(papi_attribute_t **list) 1007c478bd9Sstevel@tonic-gate { 1017c478bd9Sstevel@tonic-gate if (list != NULL) { 1027c478bd9Sstevel@tonic-gate int i; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate for (i = 0; list[i] != NULL; i++) 1057c478bd9Sstevel@tonic-gate papiAttributeFree(list[i]); 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate free(list); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate static papi_attribute_t ** 1127c478bd9Sstevel@tonic-gate collection_dup(papi_attribute_t **collection) 1137c478bd9Sstevel@tonic-gate { 1147c478bd9Sstevel@tonic-gate papi_attribute_t **result = NULL; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate /* allows a NULL collection that is "empty" or "no value" */ 1177c478bd9Sstevel@tonic-gate if (collection != NULL) { 118355b4669Sjacobs papi_status_t status = PAPI_OK; 1197c478bd9Sstevel@tonic-gate int i; 1207c478bd9Sstevel@tonic-gate 121355b4669Sjacobs for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); 122355b4669Sjacobs i++) { 1237c478bd9Sstevel@tonic-gate papi_attribute_t *a = collection[i]; 1247c478bd9Sstevel@tonic-gate 125355b4669Sjacobs status = papiAttributeListAddValue(&result, 126355b4669Sjacobs PAPI_ATTR_APPEND, a->name, a->type, 127355b4669Sjacobs NULL); 128355b4669Sjacobs if ((status == PAPI_OK) && (a->values != NULL)) { 1297c478bd9Sstevel@tonic-gate int j; 1307c478bd9Sstevel@tonic-gate 131355b4669Sjacobs for (j = 0; ((a->values[j] != NULL) && 132355b4669Sjacobs (status == PAPI_OK)); j++) 133355b4669Sjacobs status = papiAttributeListAddValue( 134355b4669Sjacobs &result, 1357c478bd9Sstevel@tonic-gate PAPI_ATTR_APPEND, 1367c478bd9Sstevel@tonic-gate a->name, a->type, 1377c478bd9Sstevel@tonic-gate a->values[j]); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate } 140355b4669Sjacobs if (status != PAPI_OK) { 141355b4669Sjacobs papiAttributeListFree(result); 142355b4669Sjacobs result = NULL; 143355b4669Sjacobs } 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate return (result); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate static papi_attribute_value_t * 150355b4669Sjacobs papiAttributeValueDup(papi_attribute_value_type_t type, 151355b4669Sjacobs papi_attribute_value_t *v) 1527c478bd9Sstevel@tonic-gate { 1537c478bd9Sstevel@tonic-gate papi_attribute_value_t *result = NULL; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) { 1567c478bd9Sstevel@tonic-gate switch (type) { 1577c478bd9Sstevel@tonic-gate case PAPI_STRING: 1587c478bd9Sstevel@tonic-gate if (v->string == NULL) { 1597c478bd9Sstevel@tonic-gate free(result); 1607c478bd9Sstevel@tonic-gate result = NULL; 1617c478bd9Sstevel@tonic-gate } else 1627c478bd9Sstevel@tonic-gate result->string = strdup(v->string); 1637c478bd9Sstevel@tonic-gate break; 1647c478bd9Sstevel@tonic-gate case PAPI_INTEGER: 1657c478bd9Sstevel@tonic-gate result->integer = v->integer; 1667c478bd9Sstevel@tonic-gate break; 1677c478bd9Sstevel@tonic-gate case PAPI_BOOLEAN: 1687c478bd9Sstevel@tonic-gate result->boolean = v->boolean; 1697c478bd9Sstevel@tonic-gate break; 1707c478bd9Sstevel@tonic-gate case PAPI_RANGE: 1717c478bd9Sstevel@tonic-gate result->range.lower = v->range.lower; 1727c478bd9Sstevel@tonic-gate result->range.upper = v->range.upper; 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate case PAPI_RESOLUTION: 1757c478bd9Sstevel@tonic-gate result->resolution.xres = v->resolution.xres; 1767c478bd9Sstevel@tonic-gate result->resolution.yres = v->resolution.yres; 1777c478bd9Sstevel@tonic-gate result->resolution.units = v->resolution.units; 1787c478bd9Sstevel@tonic-gate break; 1797c478bd9Sstevel@tonic-gate case PAPI_DATETIME: 1807c478bd9Sstevel@tonic-gate result->datetime = v->datetime; 1817c478bd9Sstevel@tonic-gate break; 1827c478bd9Sstevel@tonic-gate case PAPI_COLLECTION: 1837c478bd9Sstevel@tonic-gate result->collection = collection_dup(v->collection); 1847c478bd9Sstevel@tonic-gate break; 185355b4669Sjacobs case PAPI_METADATA: 186355b4669Sjacobs result->metadata = v->metadata; 187355b4669Sjacobs break; 1887c478bd9Sstevel@tonic-gate default: /* unknown type, fail to duplicate */ 1897c478bd9Sstevel@tonic-gate free(result); 1907c478bd9Sstevel@tonic-gate result = NULL; 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate return (result); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate static papi_attribute_t * 198355b4669Sjacobs papiAttributeAlloc(char *name, papi_attribute_value_type_t type) 1997c478bd9Sstevel@tonic-gate { 2007c478bd9Sstevel@tonic-gate papi_attribute_t *result = NULL; 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate if ((result = calloc(1, sizeof (*result))) != NULL) { 2037c478bd9Sstevel@tonic-gate result->name = strdup(name); 2047c478bd9Sstevel@tonic-gate result->type = type; 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate return (result); 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate static papi_status_t 211355b4669Sjacobs papiAttributeListAppendValue(papi_attribute_value_t ***values, 212355b4669Sjacobs papi_attribute_value_type_t type, 213355b4669Sjacobs papi_attribute_value_t *value) 2147c478bd9Sstevel@tonic-gate { 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate if (values == NULL) 2177c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate if (value != NULL) { /* this allows "empty" attributes */ 2207c478bd9Sstevel@tonic-gate papi_attribute_value_t *tmp = NULL; 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate if ((tmp = papiAttributeValueDup(type, value)) == NULL) 2237c478bd9Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate list_append(values, tmp); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate return (PAPI_OK); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate papi_status_t 232355b4669Sjacobs papiAttributeListAddValue(papi_attribute_t ***list, int flgs, 233355b4669Sjacobs char *name, papi_attribute_value_type_t type, 234355b4669Sjacobs papi_attribute_value_t *value) 2357c478bd9Sstevel@tonic-gate { 2367c478bd9Sstevel@tonic-gate papi_status_t result; 2377c478bd9Sstevel@tonic-gate int flags = flgs; 2387c478bd9Sstevel@tonic-gate papi_attribute_t *attribute = NULL; 2397c478bd9Sstevel@tonic-gate papi_attribute_value_t **values = NULL; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate if ((list == NULL) || (name == NULL)) 2427c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate if ((type == PAPI_RANGE) && (value != NULL) && 2457c478bd9Sstevel@tonic-gate (value->range.lower > value->range.upper)) 2467c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */ 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate if (flags == 0) /* if it wasn't set, set a default behaviour */ 2497c478bd9Sstevel@tonic-gate flags = PAPI_ATTR_APPEND; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* look for an existing one */ 2527c478bd9Sstevel@tonic-gate attribute = papiAttributeListFind(*list, name); 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL)) 2557c478bd9Sstevel@tonic-gate return (PAPI_CONFLICT); /* EXISTS */ 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) && 2587c478bd9Sstevel@tonic-gate (attribute->type != type)) 2597c478bd9Sstevel@tonic-gate return (PAPI_CONFLICT); /* TYPE CONFLICT */ 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate /* if we don't have one, create it and add it to the list */ 2627c478bd9Sstevel@tonic-gate if ((attribute == NULL) && 2637c478bd9Sstevel@tonic-gate ((attribute = papiAttributeAlloc(name, type)) != NULL)) 2647c478bd9Sstevel@tonic-gate list_append(list, attribute); 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate /* if we don't have one by now, it's most likely an alloc fail */ 2677c478bd9Sstevel@tonic-gate if (attribute == NULL) 2687c478bd9Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate /* 2717c478bd9Sstevel@tonic-gate * if we are replacing, clear any existing values, but don't free 2727c478bd9Sstevel@tonic-gate * until after we have replaced the values, in case we are replacing 2737c478bd9Sstevel@tonic-gate * a collection with a relocated version of the original collection. 2747c478bd9Sstevel@tonic-gate */ 2757c478bd9Sstevel@tonic-gate if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) { 2767c478bd9Sstevel@tonic-gate values = attribute->values; 2777c478bd9Sstevel@tonic-gate attribute->values = NULL; 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate attribute->type = type; 2817c478bd9Sstevel@tonic-gate 282355b4669Sjacobs result = papiAttributeListAppendValue(&attribute->values, type, value); 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate /* free old values if we replaced them */ 2857c478bd9Sstevel@tonic-gate if (values != NULL) 2867c478bd9Sstevel@tonic-gate papiAttributeValuesFree(type, values); 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate return (result); 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate papi_status_t 292355b4669Sjacobs papiAttributeListAddString(papi_attribute_t ***list, int flags, 293355b4669Sjacobs char *name, char *string) 2947c478bd9Sstevel@tonic-gate { 2957c478bd9Sstevel@tonic-gate papi_attribute_value_t v; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate v.string = (char *)string; 298355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate papi_status_t 302355b4669Sjacobs papiAttributeListAddInteger(papi_attribute_t ***list, int flags, 303355b4669Sjacobs char *name, int integer) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate papi_attribute_value_t v; 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate v.integer = integer; 308355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate papi_status_t 312355b4669Sjacobs papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, 313355b4669Sjacobs char *name, char boolean) 3147c478bd9Sstevel@tonic-gate { 3157c478bd9Sstevel@tonic-gate papi_attribute_value_t v; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate v.boolean = boolean; 318355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate papi_status_t 322355b4669Sjacobs papiAttributeListAddRange(papi_attribute_t ***list, int flags, 323355b4669Sjacobs char *name, int lower, int upper) 3247c478bd9Sstevel@tonic-gate { 3257c478bd9Sstevel@tonic-gate papi_attribute_value_t v; 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate v.range.lower = lower; 3287c478bd9Sstevel@tonic-gate v.range.upper = upper; 329355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate papi_status_t 333355b4669Sjacobs papiAttributeListAddResolution(papi_attribute_t ***list, int flags, 334355b4669Sjacobs char *name, int xres, int yres, 335355b4669Sjacobs papi_resolution_unit_t units) 3367c478bd9Sstevel@tonic-gate { 3377c478bd9Sstevel@tonic-gate papi_attribute_value_t v; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate v.resolution.xres = xres; 3407c478bd9Sstevel@tonic-gate v.resolution.yres = yres; 3417c478bd9Sstevel@tonic-gate v.resolution.units = units; 342355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, 343355b4669Sjacobs PAPI_RESOLUTION, &v)); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate papi_status_t 347355b4669Sjacobs papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, 348355b4669Sjacobs char *name, time_t datetime) 3497c478bd9Sstevel@tonic-gate { 3507c478bd9Sstevel@tonic-gate papi_attribute_value_t v; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate v.datetime = datetime; 353355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, 354355b4669Sjacobs PAPI_DATETIME, &v)); 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate papi_status_t 358355b4669Sjacobs papiAttributeListAddCollection(papi_attribute_t ***list, int flags, 359355b4669Sjacobs char *name, papi_attribute_t **collection) 3607c478bd9Sstevel@tonic-gate { 3617c478bd9Sstevel@tonic-gate papi_attribute_value_t v; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate v.collection = (papi_attribute_t **)collection; 364355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, 365355b4669Sjacobs PAPI_COLLECTION, &v)); 366355b4669Sjacobs } 367355b4669Sjacobs 368355b4669Sjacobs papi_status_t 369355b4669Sjacobs papiAttributeListAddMetadata(papi_attribute_t ***list, int flags, 370355b4669Sjacobs char *name, papi_metadata_t metadata) 371355b4669Sjacobs { 372355b4669Sjacobs papi_attribute_value_t v; 373355b4669Sjacobs 374355b4669Sjacobs v.metadata = metadata; 375355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, 376355b4669Sjacobs PAPI_METADATA, &v)); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate papi_status_t 380355b4669Sjacobs papiAttributeListDelete(papi_attribute_t ***list, char *name) 3817c478bd9Sstevel@tonic-gate { 3827c478bd9Sstevel@tonic-gate papi_attribute_t *attribute; 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate if ((list == NULL) || (name == NULL)) 3857c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate if ((attribute = papiAttributeListFind(*list, name)) == NULL) 3887c478bd9Sstevel@tonic-gate return (PAPI_NOT_FOUND); 3897c478bd9Sstevel@tonic-gate 390*0a44ef6dSjacobs list_remove(list, attribute); 3917c478bd9Sstevel@tonic-gate papiAttributeFree(attribute); 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate return (PAPI_OK); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate papi_attribute_t * 397355b4669Sjacobs papiAttributeListFind(papi_attribute_t **list, char *name) 3987c478bd9Sstevel@tonic-gate { 399355b4669Sjacobs int i; 400355b4669Sjacobs if ((list == NULL) || (name == NULL)) 401355b4669Sjacobs return (NULL); 4027c478bd9Sstevel@tonic-gate 403355b4669Sjacobs for (i = 0; list[i] != NULL; i++) 404355b4669Sjacobs if (strcasecmp(list[i]->name, name) == 0) 405355b4669Sjacobs return ((papi_attribute_t *)list[i]); 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate return (NULL); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate papi_attribute_t * 4117c478bd9Sstevel@tonic-gate papiAttributeListGetNext(papi_attribute_t **list, void **iter) 4127c478bd9Sstevel@tonic-gate { 4137c478bd9Sstevel@tonic-gate papi_attribute_t **tmp, *result; 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate if ((list == NULL) && (iter == NULL)) 4167c478bd9Sstevel@tonic-gate return (NULL); 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate if (*iter == NULL) 4197c478bd9Sstevel@tonic-gate *iter = list; 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate tmp = *iter; 4227c478bd9Sstevel@tonic-gate result = *tmp; 4237c478bd9Sstevel@tonic-gate *iter = ++tmp; 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate return (result); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate papi_status_t 4297c478bd9Sstevel@tonic-gate papiAttributeListGetValue(papi_attribute_t **list, void **iter, 430355b4669Sjacobs char *name, papi_attribute_value_type_t type, 4317c478bd9Sstevel@tonic-gate papi_attribute_value_t **value) 4327c478bd9Sstevel@tonic-gate { 4337c478bd9Sstevel@tonic-gate papi_attribute_value_t **tmp; 4347c478bd9Sstevel@tonic-gate void *fodder = NULL; 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate if ((list == NULL) || ((name == NULL) && (iter == NULL)) || 4377c478bd9Sstevel@tonic-gate (value == NULL)) 4387c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate if (iter == NULL) 4417c478bd9Sstevel@tonic-gate iter = &fodder; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if ((iter == NULL) || (*iter == NULL)) { 4447c478bd9Sstevel@tonic-gate papi_attribute_t *attr = papiAttributeListFind(list, name); 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate if (attr == NULL) 4477c478bd9Sstevel@tonic-gate return (PAPI_NOT_FOUND); 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate if (attr->type != type) 4507c478bd9Sstevel@tonic-gate return (PAPI_NOT_POSSIBLE); 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate tmp = attr->values; 4537c478bd9Sstevel@tonic-gate } else 4547c478bd9Sstevel@tonic-gate tmp = *iter; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate if (tmp == NULL) 4577c478bd9Sstevel@tonic-gate return (PAPI_NOT_FOUND); 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate *value = *tmp; 4607c478bd9Sstevel@tonic-gate *iter = ++tmp; 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate if (*value == NULL) 4637c478bd9Sstevel@tonic-gate return (PAPI_GONE); 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate return (PAPI_OK); 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate papi_status_t 4697c478bd9Sstevel@tonic-gate papiAttributeListGetString(papi_attribute_t **list, void **iter, 470355b4669Sjacobs char *name, char **vptr) 4717c478bd9Sstevel@tonic-gate { 4727c478bd9Sstevel@tonic-gate papi_status_t status; 4737c478bd9Sstevel@tonic-gate papi_attribute_value_t *value = NULL; 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate if (vptr == NULL) 4767c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate status = papiAttributeListGetValue(list, iter, name, 4797c478bd9Sstevel@tonic-gate PAPI_STRING, &value); 4807c478bd9Sstevel@tonic-gate if (status == PAPI_OK) 4817c478bd9Sstevel@tonic-gate *vptr = value->string; 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate return (status); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate papi_status_t 4877c478bd9Sstevel@tonic-gate papiAttributeListGetInteger(papi_attribute_t **list, void **iter, 488355b4669Sjacobs char *name, int *vptr) 4897c478bd9Sstevel@tonic-gate { 4907c478bd9Sstevel@tonic-gate papi_status_t status; 4917c478bd9Sstevel@tonic-gate papi_attribute_value_t *value = NULL; 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate if (vptr == NULL) 4947c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate status = papiAttributeListGetValue(list, iter, name, 4977c478bd9Sstevel@tonic-gate PAPI_INTEGER, &value); 4987c478bd9Sstevel@tonic-gate if (status == PAPI_OK) 4997c478bd9Sstevel@tonic-gate *vptr = value->integer; 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate return (status); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate papi_status_t 5057c478bd9Sstevel@tonic-gate papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, 506355b4669Sjacobs char *name, char *vptr) 5077c478bd9Sstevel@tonic-gate { 5087c478bd9Sstevel@tonic-gate papi_status_t status; 5097c478bd9Sstevel@tonic-gate papi_attribute_value_t *value = NULL; 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate if (vptr == NULL) 5127c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate status = papiAttributeListGetValue(list, iter, name, 5157c478bd9Sstevel@tonic-gate PAPI_BOOLEAN, &value); 5167c478bd9Sstevel@tonic-gate if (status == PAPI_OK) 5177c478bd9Sstevel@tonic-gate *vptr = value->boolean; 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate return (status); 5207c478bd9Sstevel@tonic-gate } 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate papi_status_t 5237c478bd9Sstevel@tonic-gate papiAttributeListGetRange(papi_attribute_t **list, void **iter, 524355b4669Sjacobs char *name, int *min, int *max) 5257c478bd9Sstevel@tonic-gate { 5267c478bd9Sstevel@tonic-gate papi_status_t status; 5277c478bd9Sstevel@tonic-gate papi_attribute_value_t *value = NULL; 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate if ((min == NULL) || (max == NULL)) 5307c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate status = papiAttributeListGetValue(list, iter, name, 5337c478bd9Sstevel@tonic-gate PAPI_RANGE, &value); 5347c478bd9Sstevel@tonic-gate if (status == PAPI_OK) { 5357c478bd9Sstevel@tonic-gate *min = value->range.lower; 5367c478bd9Sstevel@tonic-gate *max = value->range.upper; 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate return (status); 5407c478bd9Sstevel@tonic-gate } 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate papi_status_t 5437c478bd9Sstevel@tonic-gate papiAttributeListGetResolution(papi_attribute_t **list, void **iter, 544355b4669Sjacobs char *name, int *x, int *y, 5457c478bd9Sstevel@tonic-gate papi_resolution_unit_t *units) 5467c478bd9Sstevel@tonic-gate { 5477c478bd9Sstevel@tonic-gate papi_status_t status; 5487c478bd9Sstevel@tonic-gate papi_attribute_value_t *value = NULL; 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate if ((x == NULL) || (y == NULL) || (units == NULL)) 5517c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate status = papiAttributeListGetValue(list, iter, name, 5547c478bd9Sstevel@tonic-gate PAPI_RESOLUTION, &value); 5557c478bd9Sstevel@tonic-gate if (status == PAPI_OK) { 5567c478bd9Sstevel@tonic-gate *x = value->resolution.xres; 5577c478bd9Sstevel@tonic-gate *y = value->resolution.yres; 5587c478bd9Sstevel@tonic-gate *units = value->resolution.units; 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate return (status); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate papi_status_t 5657c478bd9Sstevel@tonic-gate papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, 566355b4669Sjacobs char *name, time_t *dt) 5677c478bd9Sstevel@tonic-gate { 5687c478bd9Sstevel@tonic-gate papi_status_t status; 5697c478bd9Sstevel@tonic-gate papi_attribute_value_t *value = NULL; 5707c478bd9Sstevel@tonic-gate 5717c478bd9Sstevel@tonic-gate if (dt == NULL) 5727c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate status = papiAttributeListGetValue(list, iter, name, 5757c478bd9Sstevel@tonic-gate PAPI_DATETIME, &value); 5767c478bd9Sstevel@tonic-gate if (status == PAPI_OK) { 5777c478bd9Sstevel@tonic-gate *dt = value->datetime; 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate return (status); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate papi_status_t 5847c478bd9Sstevel@tonic-gate papiAttributeListGetCollection(papi_attribute_t **list, void **iter, 585355b4669Sjacobs char *name, papi_attribute_t ***collection) 5867c478bd9Sstevel@tonic-gate { 5877c478bd9Sstevel@tonic-gate papi_status_t status; 5887c478bd9Sstevel@tonic-gate papi_attribute_value_t *value = NULL; 5897c478bd9Sstevel@tonic-gate 5907c478bd9Sstevel@tonic-gate if (collection == NULL) 5917c478bd9Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate status = papiAttributeListGetValue(list, iter, name, 5947c478bd9Sstevel@tonic-gate PAPI_COLLECTION, &value); 5957c478bd9Sstevel@tonic-gate if (status == PAPI_OK) { 5967c478bd9Sstevel@tonic-gate *collection = value->collection; 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate return (status); 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate 602355b4669Sjacobs papi_status_t 603355b4669Sjacobs papiAttributeListGetMetadata(papi_attribute_t **list, void **iter, 604355b4669Sjacobs char *name, papi_metadata_t *vptr) 605355b4669Sjacobs { 606355b4669Sjacobs papi_status_t status; 607355b4669Sjacobs papi_attribute_value_t *value = NULL; 608355b4669Sjacobs 609355b4669Sjacobs if (vptr == NULL) 610355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 611355b4669Sjacobs 612355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 613355b4669Sjacobs PAPI_METADATA, &value); 614355b4669Sjacobs if (status == PAPI_OK) 615355b4669Sjacobs *vptr = value->metadata; 616355b4669Sjacobs 617355b4669Sjacobs return (status); 618355b4669Sjacobs } 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate /* 6217c478bd9Sstevel@tonic-gate * Description: The given string contains one or more attributes, in the 622355b4669Sjacobs * following form: 623355b4669Sjacobs * "aaaa=true bbbbb=1 ccccc=abcd" 624355b4669Sjacobs * extract the next attribute from that string; the 'next' 625355b4669Sjacobs * parameter should be set to zero to extract the first attribute 626355b4669Sjacobs * in the string. 6277c478bd9Sstevel@tonic-gate * 6287c478bd9Sstevel@tonic-gate */ 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate static char * 631355b4669Sjacobs _getNextAttr(char *string, int *next) 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate { 6347c478bd9Sstevel@tonic-gate char *result = NULL; 6357c478bd9Sstevel@tonic-gate char *start = (char *)string + *next; 6367c478bd9Sstevel@tonic-gate char *nl = NULL; 6377c478bd9Sstevel@tonic-gate char *sp = NULL; 6387c478bd9Sstevel@tonic-gate char *tab = NULL; 6397c478bd9Sstevel@tonic-gate char *val = NULL; 6407c478bd9Sstevel@tonic-gate int len = 0; 6417c478bd9Sstevel@tonic-gate 642355b4669Sjacobs if ((string != NULL) && (*start != '\0')) { 6437c478bd9Sstevel@tonic-gate while ((*start == ' ') || (*start == '\t') || (*start == '\n')) 6447c478bd9Sstevel@tonic-gate { 6457c478bd9Sstevel@tonic-gate start++; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate nl = strchr(start, '\n'); 6487c478bd9Sstevel@tonic-gate sp = strchr(start, ' '); 6497c478bd9Sstevel@tonic-gate tab = strchr(start, '\t'); 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate val = strchr(start, '='); 6527c478bd9Sstevel@tonic-gate 653355b4669Sjacobs if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) { 6547c478bd9Sstevel@tonic-gate val = strchr(&val[2], val[1]); 655355b4669Sjacobs if (val != NULL) { 6567c478bd9Sstevel@tonic-gate nl = strchr(&val[1], '\n'); 6577c478bd9Sstevel@tonic-gate sp = strchr(&val[1], ' '); 6587c478bd9Sstevel@tonic-gate tab = strchr(&val[1], '\t'); 6597c478bd9Sstevel@tonic-gate } 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate if ((nl != NULL) && 6637c478bd9Sstevel@tonic-gate ((sp == NULL) || ((sp != NULL) && (nl < sp))) && 664355b4669Sjacobs ((tab == NULL) || ((tab != NULL) && (nl < tab)))) { 6657c478bd9Sstevel@tonic-gate len = nl-start; 666355b4669Sjacobs } else if ((sp != NULL) && (tab != NULL) && (sp > tab)) { 6677c478bd9Sstevel@tonic-gate len = tab-start; 668355b4669Sjacobs } else if ((sp != NULL) && (sp != NULL)) { 6697c478bd9Sstevel@tonic-gate len = sp-start; 670355b4669Sjacobs } else if ((tab != NULL) && (tab != NULL)) { 6717c478bd9Sstevel@tonic-gate len = tab-start; 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate 674355b4669Sjacobs if (len == 0) { 6757c478bd9Sstevel@tonic-gate len = strlen(start); 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate 678355b4669Sjacobs if (len > 0) { 6797c478bd9Sstevel@tonic-gate result = (char *)malloc(len+1); 680355b4669Sjacobs if (result != NULL) { 6817c478bd9Sstevel@tonic-gate strncpy(result, start, len); 6827c478bd9Sstevel@tonic-gate result[len] = '\0'; 6837c478bd9Sstevel@tonic-gate *next = (start-string)+len; 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate return (result); 6897c478bd9Sstevel@tonic-gate } /* _getNextAttr() */ 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate /* 6937c478bd9Sstevel@tonic-gate * Description: Parse the given attribute string value and transform it into 694355b4669Sjacobs * the papi_attribute_value_t in the papi_attribute_t structure. 6957c478bd9Sstevel@tonic-gate * 6967c478bd9Sstevel@tonic-gate */ 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate static papi_status_t 6997c478bd9Sstevel@tonic-gate _parseAttrValue(char *value, papi_attribute_t *attr) 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate { 7027c478bd9Sstevel@tonic-gate papi_status_t result = PAPI_OK; 7037c478bd9Sstevel@tonic-gate int len = 0; 7047c478bd9Sstevel@tonic-gate int i = 0; 7057c478bd9Sstevel@tonic-gate char *papiString = NULL; 7067c478bd9Sstevel@tonic-gate char *tmp1 = NULL; 7077c478bd9Sstevel@tonic-gate char *tmp2 = NULL; 7087c478bd9Sstevel@tonic-gate char *tmp3 = NULL; 7097c478bd9Sstevel@tonic-gate papi_attribute_value_t **avalues = NULL; 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate avalues = malloc(sizeof (papi_attribute_value_t *) * 2); 712355b4669Sjacobs if (avalues == NULL) { 7137c478bd9Sstevel@tonic-gate result = PAPI_TEMPORARY_ERROR; 7147c478bd9Sstevel@tonic-gate return (result); 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate avalues[0] = malloc(sizeof (papi_attribute_value_t)); 7177c478bd9Sstevel@tonic-gate avalues[1] = NULL; 718355b4669Sjacobs if (avalues[0] == NULL) { 7197c478bd9Sstevel@tonic-gate free(avalues); 7207c478bd9Sstevel@tonic-gate result = PAPI_TEMPORARY_ERROR; 7217c478bd9Sstevel@tonic-gate return (result); 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate /* 7267c478bd9Sstevel@tonic-gate * TODO - need to sort out 'resolution', 'dateandtime' & 'collection' values 7277c478bd9Sstevel@tonic-gate */ 728355b4669Sjacobs if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) { 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate len = strlen(value); 731355b4669Sjacobs if ((len >= 2) && (((value[0] == '"') && 732355b4669Sjacobs (value[len-1] == '"')) || ((value[0] == '\'') && 733355b4669Sjacobs (value[len-1] == '\'')))) { 7347c478bd9Sstevel@tonic-gate /* string value */ 7357c478bd9Sstevel@tonic-gate attr->type = PAPI_STRING; 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate papiString = strdup(value+1); 738355b4669Sjacobs if (papiString != NULL) { 7397c478bd9Sstevel@tonic-gate papiString[strlen(papiString)-1] = '\0'; 7407c478bd9Sstevel@tonic-gate avalues[0]->string = papiString; 741355b4669Sjacobs } else { 7427c478bd9Sstevel@tonic-gate result = PAPI_TEMPORARY_ERROR; 7437c478bd9Sstevel@tonic-gate } 744355b4669Sjacobs } else if ((strcasecmp(value, "true") == 0) || 745355b4669Sjacobs (strcasecmp(value, "YES") == 0)) { 7467c478bd9Sstevel@tonic-gate /* boolean = true */ 7477c478bd9Sstevel@tonic-gate attr->type = PAPI_BOOLEAN; 7487c478bd9Sstevel@tonic-gate avalues[0]->boolean = PAPI_TRUE; 749355b4669Sjacobs } else if ((strcasecmp(value, "false") == 0) || 750355b4669Sjacobs (strcasecmp(value, "NO") == 0)) { 7517c478bd9Sstevel@tonic-gate /* boolean = false */ 7527c478bd9Sstevel@tonic-gate attr->type = PAPI_BOOLEAN; 7537c478bd9Sstevel@tonic-gate avalues[0]->boolean = PAPI_FALSE; 754355b4669Sjacobs } else { 755355b4669Sjacobs /* is value an integer or a range ? */ 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate i = 0; 7587c478bd9Sstevel@tonic-gate attr->type = PAPI_INTEGER; 7597c478bd9Sstevel@tonic-gate tmp1 = strdup(value); 7607c478bd9Sstevel@tonic-gate while (((value[i] >= '0') && (value[i] <= '9')) || 761355b4669Sjacobs (value[i] == '-')) { 762355b4669Sjacobs if (value[i] == '-') { 7637c478bd9Sstevel@tonic-gate tmp1[i] = '\0'; 7647c478bd9Sstevel@tonic-gate tmp2 = &tmp1[i+1]; 7657c478bd9Sstevel@tonic-gate attr->type = PAPI_RANGE; 7667c478bd9Sstevel@tonic-gate } 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate i++; 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate 771355b4669Sjacobs if (strlen(value) == i) { 772355b4669Sjacobs if (attr->type == PAPI_RANGE) { 7737c478bd9Sstevel@tonic-gate avalues[0]->range.lower = atoi(tmp1); 7747c478bd9Sstevel@tonic-gate avalues[0]->range.upper = atoi(tmp2); 775355b4669Sjacobs } else { 7767c478bd9Sstevel@tonic-gate avalues[0]->integer = atoi(value); 7777c478bd9Sstevel@tonic-gate } 778355b4669Sjacobs } else { 779355b4669Sjacobs /* is value a resolution ? */ 7807c478bd9Sstevel@tonic-gate i = 0; 7817c478bd9Sstevel@tonic-gate attr->type = PAPI_INTEGER; 7827c478bd9Sstevel@tonic-gate tmp1 = strdup(value); 7837c478bd9Sstevel@tonic-gate while (((value[i] >= '0') && 7847c478bd9Sstevel@tonic-gate (value[i] <= '9')) || 785355b4669Sjacobs (value[i] == 'x')) { 786355b4669Sjacobs if (value[i] == 'x') { 7877c478bd9Sstevel@tonic-gate tmp1[i] = '\0'; 7887c478bd9Sstevel@tonic-gate if (attr->type == PAPI_INTEGER) 7897c478bd9Sstevel@tonic-gate { 7907c478bd9Sstevel@tonic-gate tmp2 = &tmp1[i+1]; 7917c478bd9Sstevel@tonic-gate attr->type = 7927c478bd9Sstevel@tonic-gate PAPI_RESOLUTION; 793355b4669Sjacobs } else { 7947c478bd9Sstevel@tonic-gate tmp3 = &tmp1[i+1]; 7957c478bd9Sstevel@tonic-gate } 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate i++; 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate 801355b4669Sjacobs if (strlen(value) == i) { 802355b4669Sjacobs if (attr->type == PAPI_RESOLUTION) { 8037c478bd9Sstevel@tonic-gate avalues[0]->resolution.xres = 8047c478bd9Sstevel@tonic-gate atoi(tmp1); 8057c478bd9Sstevel@tonic-gate avalues[0]->resolution.yres = 8067c478bd9Sstevel@tonic-gate atoi(tmp2); 807355b4669Sjacobs if (tmp3 != NULL) { 8087c478bd9Sstevel@tonic-gate avalues[0]-> 809355b4669Sjacobs resolution.units = 8107c478bd9Sstevel@tonic-gate atoi(tmp3); 811355b4669Sjacobs } else { 8127c478bd9Sstevel@tonic-gate avalues[0]-> 813355b4669Sjacobs resolution.units = 0; 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate } 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate 818355b4669Sjacobs if (attr->type != PAPI_RESOLUTION) { 8197c478bd9Sstevel@tonic-gate attr->type = PAPI_STRING; 8207c478bd9Sstevel@tonic-gate avalues[0]->string = strdup(value); 821355b4669Sjacobs if (avalues[0]->string == NULL) { 8227c478bd9Sstevel@tonic-gate result = PAPI_TEMPORARY_ERROR; 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate } 8257c478bd9Sstevel@tonic-gate } 8267c478bd9Sstevel@tonic-gate free(tmp1); 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate 829355b4669Sjacobs } else { 8307c478bd9Sstevel@tonic-gate result = PAPI_BAD_ARGUMENT; 8317c478bd9Sstevel@tonic-gate } 8327c478bd9Sstevel@tonic-gate 833355b4669Sjacobs if (result != PAPI_OK) { 8347c478bd9Sstevel@tonic-gate i = 0; 835355b4669Sjacobs while (avalues[i] != NULL) { 8367c478bd9Sstevel@tonic-gate free(avalues[i]); 8377c478bd9Sstevel@tonic-gate i++; 8387c478bd9Sstevel@tonic-gate } 8397c478bd9Sstevel@tonic-gate free(avalues); 840355b4669Sjacobs } else { 8417c478bd9Sstevel@tonic-gate attr->values = avalues; 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate return (result); 8457c478bd9Sstevel@tonic-gate } /* _parseAttrValue() */ 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate /* 8497c478bd9Sstevel@tonic-gate * Description: Parse the given attribute string and transform it into the 850355b4669Sjacobs * papi_attribute_t structure. 8517c478bd9Sstevel@tonic-gate * 8527c478bd9Sstevel@tonic-gate */ 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate static papi_status_t 8557c478bd9Sstevel@tonic-gate _parseAttributeString(char *attrString, papi_attribute_t *attr) 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate { 8587c478bd9Sstevel@tonic-gate papi_status_t result = PAPI_OK; 8597c478bd9Sstevel@tonic-gate char *string = NULL; 8607c478bd9Sstevel@tonic-gate char *p = NULL; 8617c478bd9Sstevel@tonic-gate papi_attribute_value_t **avalues = NULL; 8627c478bd9Sstevel@tonic-gate 863355b4669Sjacobs if ((attrString != NULL) && (strlen(attrString) >= 3) && 864355b4669Sjacobs (attr != NULL)) { 8657c478bd9Sstevel@tonic-gate attr->name = NULL; 8667c478bd9Sstevel@tonic-gate string = strdup(attrString); 867355b4669Sjacobs if (string != NULL) { 8687c478bd9Sstevel@tonic-gate p = strchr(string, '='); 869355b4669Sjacobs if (p != NULL) { 8707c478bd9Sstevel@tonic-gate *p = '\0'; 8717c478bd9Sstevel@tonic-gate attr->name = string; 8727c478bd9Sstevel@tonic-gate p++; /* pointer to value */ 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate result = _parseAttrValue(p, attr); 875355b4669Sjacobs } else { 876355b4669Sjacobs char value; 8777c478bd9Sstevel@tonic-gate /* boolean - no value so assume 'true' */ 878355b4669Sjacobs if (strncasecmp(string, "no", 2) == 0) { 879355b4669Sjacobs string += 2; 880355b4669Sjacobs value = PAPI_FALSE; 881355b4669Sjacobs } else 882355b4669Sjacobs value = PAPI_TRUE; 883355b4669Sjacobs 8847c478bd9Sstevel@tonic-gate attr->name = string; 8857c478bd9Sstevel@tonic-gate attr->type = PAPI_BOOLEAN; 8867c478bd9Sstevel@tonic-gate 887355b4669Sjacobs avalues = malloc( 8887c478bd9Sstevel@tonic-gate sizeof (papi_attribute_value_t *) * 2); 889355b4669Sjacobs if (avalues == NULL) { 8907c478bd9Sstevel@tonic-gate result = PAPI_TEMPORARY_ERROR; 891355b4669Sjacobs } else { 892355b4669Sjacobs avalues[0] = malloc( 893355b4669Sjacobs sizeof (papi_attribute_value_t)); 8947c478bd9Sstevel@tonic-gate avalues[1] = NULL; 895355b4669Sjacobs if (avalues[0] == NULL) { 8967c478bd9Sstevel@tonic-gate free(avalues); 8977c478bd9Sstevel@tonic-gate result = PAPI_TEMPORARY_ERROR; 898355b4669Sjacobs } else { 899355b4669Sjacobs avalues[0]->boolean = value; 9007c478bd9Sstevel@tonic-gate attr->values = avalues; 9017c478bd9Sstevel@tonic-gate } 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate } 9047c478bd9Sstevel@tonic-gate } 905355b4669Sjacobs } else { 9067c478bd9Sstevel@tonic-gate result = PAPI_BAD_ARGUMENT; 9077c478bd9Sstevel@tonic-gate } 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate return (result); 9107c478bd9Sstevel@tonic-gate } /* _parseAttributeString() */ 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate papi_status_t 9147c478bd9Sstevel@tonic-gate papiAttributeListFromString(papi_attribute_t ***attrs, 915355b4669Sjacobs int flags, char *string) 9167c478bd9Sstevel@tonic-gate { 9177c478bd9Sstevel@tonic-gate papi_status_t result = PAPI_OK; 918355b4669Sjacobs int next = 0; 919355b4669Sjacobs char *attrString = NULL; 9207c478bd9Sstevel@tonic-gate papi_attribute_t attr; 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate if ((attrs != NULL) && (string != NULL) && 923355b4669Sjacobs ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) 924355b4669Sjacobs == 0)) { 9257c478bd9Sstevel@tonic-gate attrString = _getNextAttr(string, &next); 9267c478bd9Sstevel@tonic-gate while ((result == PAPI_OK) && (attrString != NULL)) { 9277c478bd9Sstevel@tonic-gate result = _parseAttributeString(attrString, &attr); 9287c478bd9Sstevel@tonic-gate if ((result == PAPI_OK) && (attr.name != NULL)) { 9297c478bd9Sstevel@tonic-gate /* add this attribute to the list */ 9307c478bd9Sstevel@tonic-gate if ((attr.values != NULL) && 9317c478bd9Sstevel@tonic-gate (attr.values[0] != NULL)) { 932355b4669Sjacobs result = papiAttributeListAddValue( 9337c478bd9Sstevel@tonic-gate attrs, PAPI_ATTR_APPEND, 9347c478bd9Sstevel@tonic-gate attr.name, attr.type, 9357c478bd9Sstevel@tonic-gate attr.values[0]); 9367c478bd9Sstevel@tonic-gate free(attr.values[0]); 9377c478bd9Sstevel@tonic-gate free(attr.values); 9387c478bd9Sstevel@tonic-gate } else { 9397c478bd9Sstevel@tonic-gate result = PAPI_TEMPORARY_ERROR; 9407c478bd9Sstevel@tonic-gate } 9417c478bd9Sstevel@tonic-gate } 9427c478bd9Sstevel@tonic-gate free(attrString); 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate attrString = _getNextAttr(string, &next); 9457c478bd9Sstevel@tonic-gate } 9467c478bd9Sstevel@tonic-gate } 9477c478bd9Sstevel@tonic-gate else 9487c478bd9Sstevel@tonic-gate { 9497c478bd9Sstevel@tonic-gate result = PAPI_BAD_ARGUMENT; 9507c478bd9Sstevel@tonic-gate } 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate return (result); 9537c478bd9Sstevel@tonic-gate } 9547c478bd9Sstevel@tonic-gate 955355b4669Sjacobs static papi_status_t 956355b4669Sjacobs papiAttributeToString(papi_attribute_t *attribute, char *delim, 957355b4669Sjacobs char *buffer, size_t buflen) 9587c478bd9Sstevel@tonic-gate { 959355b4669Sjacobs papi_attribute_value_t **values = attribute->values; 960355b4669Sjacobs int rc, i; 961355b4669Sjacobs 962355b4669Sjacobs strlcat(buffer, attribute->name, buflen); 963355b4669Sjacobs strlcat(buffer, "=", buflen); 964355b4669Sjacobs 965355b4669Sjacobs if (values == NULL) 966355b4669Sjacobs return (PAPI_OK); 967355b4669Sjacobs 968355b4669Sjacobs for (i = 0; values[i] != NULL; i++) { 969355b4669Sjacobs switch (attribute->type) { 970355b4669Sjacobs case PAPI_STRING: 971355b4669Sjacobs rc = strlcat(buffer, values[i]->string, buflen); 972355b4669Sjacobs break; 973355b4669Sjacobs case PAPI_INTEGER: { 974355b4669Sjacobs char string[24]; 975355b4669Sjacobs 976355b4669Sjacobs snprintf(string, sizeof (string), "%d", 977355b4669Sjacobs values[i]->integer); 978355b4669Sjacobs rc = strlcat(buffer, string, buflen); 979355b4669Sjacobs } 980355b4669Sjacobs break; 981355b4669Sjacobs case PAPI_BOOLEAN: 982355b4669Sjacobs rc = strlcat(buffer, (values[i]->boolean ? "true" : 983355b4669Sjacobs "false"), buflen); 984355b4669Sjacobs break; 985355b4669Sjacobs case PAPI_RANGE: { 986355b4669Sjacobs char string[24]; 987355b4669Sjacobs 988355b4669Sjacobs snprintf(string, sizeof (string), "%d-%d", 989355b4669Sjacobs values[i]->range.lower, values[i]->range.upper); 990355b4669Sjacobs rc = strlcat(buffer, string, buflen); 991355b4669Sjacobs } 992355b4669Sjacobs break; 993355b4669Sjacobs case PAPI_RESOLUTION: { 994355b4669Sjacobs char string[24]; 995355b4669Sjacobs 996355b4669Sjacobs snprintf(string, sizeof (string), "%dx%ddp%c", 997355b4669Sjacobs values[i]->resolution.xres, 998355b4669Sjacobs values[i]->resolution.yres, 999355b4669Sjacobs (values[i]->resolution.units == PAPI_RES_PER_CM 1000355b4669Sjacobs ? 'c' : 'i')); 1001355b4669Sjacobs rc = strlcat(buffer, string, buflen); 1002355b4669Sjacobs } 1003355b4669Sjacobs break; 1004355b4669Sjacobs case PAPI_DATETIME: { 1005355b4669Sjacobs struct tm *tm = localtime(&values[i]->datetime); 1006355b4669Sjacobs 1007355b4669Sjacobs if (tm != NULL) { 1008355b4669Sjacobs char string[64]; 1009355b4669Sjacobs 1010355b4669Sjacobs strftime(string, sizeof (string), "%C", tm); 1011355b4669Sjacobs rc = strlcat(buffer, string, buflen); 1012355b4669Sjacobs }} 1013355b4669Sjacobs break; 1014355b4669Sjacobs case PAPI_COLLECTION: { 1015355b4669Sjacobs char *string = alloca(buflen); 1016355b4669Sjacobs #ifdef DEBUG 1017355b4669Sjacobs char prefix[256]; 1018355b4669Sjacobs 1019355b4669Sjacobs snprintf(prefix, sizeof (prefix), "%s %s(%d) ", delim, 1020355b4669Sjacobs attribute->name, i); 1021355b4669Sjacobs 1022355b4669Sjacobs papiAttributeListToString(values[i]->collection, 1023355b4669Sjacobs prefix, string, buflen); 1024355b4669Sjacobs #else 1025355b4669Sjacobs papiAttributeListToString(values[i]->collection, 1026355b4669Sjacobs delim, string, buflen); 1027355b4669Sjacobs #endif 1028355b4669Sjacobs rc = strlcat(buffer, string, buflen); 1029355b4669Sjacobs } 1030355b4669Sjacobs break; 1031355b4669Sjacobs default: { 1032355b4669Sjacobs char string[32]; 1033355b4669Sjacobs 1034355b4669Sjacobs snprintf(string, sizeof (string), "unknown-type-0x%x", 1035355b4669Sjacobs attribute->type); 1036355b4669Sjacobs rc = strlcat(buffer, string, buflen); 1037355b4669Sjacobs } 1038355b4669Sjacobs } 1039355b4669Sjacobs if (values[i+1] != NULL) 1040355b4669Sjacobs rc = strlcat(buffer, ",", buflen); 1041355b4669Sjacobs 1042355b4669Sjacobs if (rc >= buflen) 1043355b4669Sjacobs return (PAPI_NOT_POSSIBLE); 1044355b4669Sjacobs 1045355b4669Sjacobs } 1046355b4669Sjacobs 1047355b4669Sjacobs return (PAPI_OK); 10487c478bd9Sstevel@tonic-gate } 10497c478bd9Sstevel@tonic-gate 1050355b4669Sjacobs papi_status_t 1051355b4669Sjacobs papiAttributeListToString(papi_attribute_t **attrs, 1052355b4669Sjacobs char *delim, char *buffer, size_t buflen) 10537c478bd9Sstevel@tonic-gate { 1054355b4669Sjacobs papi_status_t status = PAPI_OK; 1055355b4669Sjacobs int i; 1056355b4669Sjacobs 1057355b4669Sjacobs if ((attrs == NULL) || (buffer == NULL)) 1058355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 1059355b4669Sjacobs 1060355b4669Sjacobs buffer[0] = '\0'; 1061355b4669Sjacobs if (!delim) 1062355b4669Sjacobs delim = " "; 1063355b4669Sjacobs 1064355b4669Sjacobs #ifdef DEBUG 1065355b4669Sjacobs strlcat(buffer, delim, buflen); 1066355b4669Sjacobs #endif 1067355b4669Sjacobs for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) { 1068355b4669Sjacobs status = papiAttributeToString(attrs[i], delim, buffer, buflen); 1069355b4669Sjacobs if (attrs[i+1] != NULL) 1070355b4669Sjacobs strlcat(buffer, delim, buflen); 10717c478bd9Sstevel@tonic-gate } 10727c478bd9Sstevel@tonic-gate 1073355b4669Sjacobs return (status); 10747c478bd9Sstevel@tonic-gate } 10757c478bd9Sstevel@tonic-gate 1076355b4669Sjacobs static int 1077355b4669Sjacobs is_in_list(char *value, char **list) 1078355b4669Sjacobs { 1079355b4669Sjacobs if ((list != NULL) && (value != NULL)) { 1080355b4669Sjacobs int i; 10817c478bd9Sstevel@tonic-gate 1082355b4669Sjacobs for (i = 0; list[i] != NULL; i++) 1083355b4669Sjacobs if (strcasecmp(value, list[i]) == 0) 1084355b4669Sjacobs return (0); 1085355b4669Sjacobs } 1086355b4669Sjacobs 1087355b4669Sjacobs return (1); 1088355b4669Sjacobs } 1089355b4669Sjacobs 1090355b4669Sjacobs static papi_status_t 1091355b4669Sjacobs copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute) 10927c478bd9Sstevel@tonic-gate { 1093355b4669Sjacobs papi_status_t status; 1094355b4669Sjacobs int i = 0; 10957c478bd9Sstevel@tonic-gate 1096355b4669Sjacobs if ((list == NULL) || (attribute == NULL) || 1097355b4669Sjacobs (attribute->values == NULL)) 1098355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 10997c478bd9Sstevel@tonic-gate 1100355b4669Sjacobs for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL, 1101355b4669Sjacobs attribute->name, attribute->type, 1102355b4669Sjacobs attribute->values[i]); 1103355b4669Sjacobs ((status == PAPI_OK) && (attribute->values[i] != NULL)); 1104355b4669Sjacobs status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND, 1105355b4669Sjacobs attribute->name, attribute->type, 1106355b4669Sjacobs attribute->values[i])) 1107355b4669Sjacobs i++; 11087c478bd9Sstevel@tonic-gate 1109355b4669Sjacobs return (status); 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate 1112355b4669Sjacobs void 1113355b4669Sjacobs copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes) 1114355b4669Sjacobs { 1115355b4669Sjacobs int i; 1116355b4669Sjacobs 1117355b4669Sjacobs if ((result == NULL) || (attributes == NULL)) 1118355b4669Sjacobs return; 1119355b4669Sjacobs 1120355b4669Sjacobs for (i = 0; attributes[i] != NULL; i++) 1121355b4669Sjacobs copy_attribute(result, attributes[i]); 1122355b4669Sjacobs } 11237c478bd9Sstevel@tonic-gate 11247c478bd9Sstevel@tonic-gate void 1125355b4669Sjacobs split_and_copy_attributes(char **list, papi_attribute_t **attributes, 1126355b4669Sjacobs papi_attribute_t ***in, papi_attribute_t ***out) 11277c478bd9Sstevel@tonic-gate { 1128355b4669Sjacobs int i; 11297c478bd9Sstevel@tonic-gate 1130355b4669Sjacobs if ((list == NULL) || (attributes == NULL)) 1131355b4669Sjacobs return; 1132355b4669Sjacobs 1133355b4669Sjacobs for (i = 0; attributes[i] != NULL; i++) 1134355b4669Sjacobs if (is_in_list(attributes[i]->name, list) == 0) 1135355b4669Sjacobs copy_attribute(in, attributes[i]); 1136355b4669Sjacobs else 1137355b4669Sjacobs copy_attribute(out, attributes[i]); 1138355b4669Sjacobs } 1139355b4669Sjacobs 1140355b4669Sjacobs void 1141355b4669Sjacobs papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes, 1142355b4669Sjacobs char *prefix_fmt, ...) 1143355b4669Sjacobs { 1144355b4669Sjacobs char *prefix = NULL; 1145355b4669Sjacobs char *buffer = NULL; 1146355b4669Sjacobs char *newfmt = NULL; 1147355b4669Sjacobs void *mem; 1148355b4669Sjacobs ssize_t size = 0; 1149355b4669Sjacobs va_list ap; 1150355b4669Sjacobs 1151355b4669Sjacobs newfmt = malloc(strlen(prefix_fmt) + 2); 1152355b4669Sjacobs sprintf(newfmt, "\n%s", prefix_fmt); 1153355b4669Sjacobs 1154355b4669Sjacobs va_start(ap, prefix_fmt); 1155355b4669Sjacobs while (vsnprintf(prefix, size, newfmt, ap) > size) { 1156355b4669Sjacobs size += 1024; 1157355b4669Sjacobs mem = realloc(prefix, size); 1158355b4669Sjacobs if (!mem) goto error; 1159355b4669Sjacobs prefix = mem; 1160355b4669Sjacobs } 1161355b4669Sjacobs va_end(ap); 1162355b4669Sjacobs 1163355b4669Sjacobs if (attributes) { 1164355b4669Sjacobs size = 0; 1165355b4669Sjacobs while (papiAttributeListToString(attributes, prefix, buffer, 1166355b4669Sjacobs size) != PAPI_OK) { 1167355b4669Sjacobs size += 1024; 1168355b4669Sjacobs mem = realloc(buffer, size); 1169355b4669Sjacobs if (!mem) goto error; 1170355b4669Sjacobs buffer = mem; 1171355b4669Sjacobs } 11727c478bd9Sstevel@tonic-gate } 1173355b4669Sjacobs 1174355b4669Sjacobs fprintf(fp, "%s%s\n", prefix, buffer ? buffer : ""); 1175355b4669Sjacobs fflush(fp); 1176355b4669Sjacobs 1177355b4669Sjacobs error: 1178355b4669Sjacobs free(newfmt); 1179355b4669Sjacobs free(prefix); 1180355b4669Sjacobs free(buffer); 11817c478bd9Sstevel@tonic-gate } 1182