1355b4669Sjacobs /* 2355b4669Sjacobs * CDDL HEADER START 3355b4669Sjacobs * 4355b4669Sjacobs * 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. 7355b4669Sjacobs * 8355b4669Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9355b4669Sjacobs * or http://www.opensolaris.org/os/licensing. 10355b4669Sjacobs * See the License for the specific language governing permissions 11355b4669Sjacobs * and limitations under the License. 12355b4669Sjacobs * 13355b4669Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14355b4669Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15355b4669Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16355b4669Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17355b4669Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18355b4669Sjacobs * 19355b4669Sjacobs * CDDL HEADER END 20355b4669Sjacobs */ 21355b4669Sjacobs 22355b4669Sjacobs /* 23355b4669Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24355b4669Sjacobs * Use is subject to license terms. 25355b4669Sjacobs * 26355b4669Sjacobs */ 27355b4669Sjacobs 28355b4669Sjacobs /* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */ 29355b4669Sjacobs 30355b4669Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 31355b4669Sjacobs 32355b4669Sjacobs /*LINTLIBRARY*/ 33355b4669Sjacobs 34355b4669Sjacobs #include <stdio.h> 35355b4669Sjacobs #include <stdlib.h> 36355b4669Sjacobs #include <stdarg.h> 37355b4669Sjacobs #include <string.h> 38355b4669Sjacobs #include <alloca.h> 39355b4669Sjacobs #include <papi.h> 40355b4669Sjacobs 41355b4669Sjacobs static void papiAttributeFree(papi_attribute_t *attribute); 42355b4669Sjacobs 43355b4669Sjacobs static void 44355b4669Sjacobs papiAttributeValueFree(papi_attribute_value_type_t type, 45355b4669Sjacobs papi_attribute_value_t *value) 46355b4669Sjacobs { 47355b4669Sjacobs if (value != NULL) { 48355b4669Sjacobs switch (type) { 49355b4669Sjacobs case PAPI_STRING: 50355b4669Sjacobs if (value->string != NULL) 51355b4669Sjacobs free(value->string); 52355b4669Sjacobs break; 53355b4669Sjacobs case PAPI_COLLECTION: 54355b4669Sjacobs if (value->collection != NULL) { 55355b4669Sjacobs int i; 56355b4669Sjacobs 57355b4669Sjacobs for (i = 0; value->collection[i] != NULL; i++) 58355b4669Sjacobs papiAttributeFree(value->collection[i]); 59355b4669Sjacobs 60355b4669Sjacobs free(value->collection); 61355b4669Sjacobs } 62355b4669Sjacobs break; 63355b4669Sjacobs default: /* don't need to free anything extra */ 64355b4669Sjacobs break; 65355b4669Sjacobs } 66355b4669Sjacobs 67355b4669Sjacobs free(value); 68355b4669Sjacobs } 69355b4669Sjacobs } 70355b4669Sjacobs 71355b4669Sjacobs static void 72355b4669Sjacobs papiAttributeValuesFree(papi_attribute_value_type_t type, 73355b4669Sjacobs papi_attribute_value_t **values) 74355b4669Sjacobs { 75355b4669Sjacobs if (values != NULL) { 76355b4669Sjacobs int i; 77355b4669Sjacobs 78355b4669Sjacobs for (i = 0; values[i] != NULL; i++) 79355b4669Sjacobs papiAttributeValueFree(type, values[i]); 80355b4669Sjacobs 81355b4669Sjacobs free(values); 82355b4669Sjacobs } 83355b4669Sjacobs } 84355b4669Sjacobs 85355b4669Sjacobs static void 86355b4669Sjacobs papiAttributeFree(papi_attribute_t *attribute) 87355b4669Sjacobs { 88355b4669Sjacobs if (attribute != NULL) { 89355b4669Sjacobs if (attribute->name != NULL) 90355b4669Sjacobs free(attribute->name); 91355b4669Sjacobs if (attribute->values != NULL) 92355b4669Sjacobs papiAttributeValuesFree(attribute->type, 93355b4669Sjacobs attribute->values); 94355b4669Sjacobs free(attribute); 95355b4669Sjacobs } 96355b4669Sjacobs } 97355b4669Sjacobs 98355b4669Sjacobs void 99355b4669Sjacobs papiAttributeListFree(papi_attribute_t **list) 100355b4669Sjacobs { 101355b4669Sjacobs if (list != NULL) { 102355b4669Sjacobs int i; 103355b4669Sjacobs 104355b4669Sjacobs for (i = 0; list[i] != NULL; i++) 105355b4669Sjacobs papiAttributeFree(list[i]); 106355b4669Sjacobs 107355b4669Sjacobs free(list); 108355b4669Sjacobs } 109355b4669Sjacobs } 110355b4669Sjacobs 111355b4669Sjacobs static papi_attribute_t ** 112355b4669Sjacobs collection_dup(papi_attribute_t **collection) 113355b4669Sjacobs { 114355b4669Sjacobs papi_attribute_t **result = NULL; 115355b4669Sjacobs 116355b4669Sjacobs /* allows a NULL collection that is "empty" or "no value" */ 117355b4669Sjacobs if (collection != NULL) { 118355b4669Sjacobs papi_status_t status = PAPI_OK; 119355b4669Sjacobs int i; 120355b4669Sjacobs 121355b4669Sjacobs for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); 122355b4669Sjacobs i++) { 123355b4669Sjacobs papi_attribute_t *a = collection[i]; 124355b4669Sjacobs 125355b4669Sjacobs status = papiAttributeListAddValue(&result, 126355b4669Sjacobs PAPI_ATTR_APPEND, a->name, a->type, 127355b4669Sjacobs NULL); 128355b4669Sjacobs if ((status == PAPI_OK) && (a->values != NULL)) { 129355b4669Sjacobs int j; 130355b4669Sjacobs 131355b4669Sjacobs for (j = 0; ((a->values[j] != NULL) && 132355b4669Sjacobs (status == PAPI_OK)); j++) 133355b4669Sjacobs status = papiAttributeListAddValue( 134355b4669Sjacobs &result, 135355b4669Sjacobs PAPI_ATTR_APPEND, 136355b4669Sjacobs a->name, a->type, 137355b4669Sjacobs a->values[j]); 138355b4669Sjacobs } 139355b4669Sjacobs } 140355b4669Sjacobs if (status != PAPI_OK) { 141355b4669Sjacobs papiAttributeListFree(result); 142355b4669Sjacobs result = NULL; 143355b4669Sjacobs } 144355b4669Sjacobs } 145355b4669Sjacobs 146355b4669Sjacobs return (result); 147355b4669Sjacobs } 148355b4669Sjacobs 149355b4669Sjacobs static papi_attribute_value_t * 150355b4669Sjacobs papiAttributeValueDup(papi_attribute_value_type_t type, 151355b4669Sjacobs papi_attribute_value_t *v) 152355b4669Sjacobs { 153355b4669Sjacobs papi_attribute_value_t *result = NULL; 154355b4669Sjacobs 155355b4669Sjacobs if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) { 156355b4669Sjacobs switch (type) { 157355b4669Sjacobs case PAPI_STRING: 158355b4669Sjacobs if (v->string == NULL) { 159355b4669Sjacobs free(result); 160355b4669Sjacobs result = NULL; 161355b4669Sjacobs } else 162355b4669Sjacobs result->string = strdup(v->string); 163355b4669Sjacobs break; 164355b4669Sjacobs case PAPI_INTEGER: 165355b4669Sjacobs result->integer = v->integer; 166355b4669Sjacobs break; 167355b4669Sjacobs case PAPI_BOOLEAN: 168355b4669Sjacobs result->boolean = v->boolean; 169355b4669Sjacobs break; 170355b4669Sjacobs case PAPI_RANGE: 171355b4669Sjacobs result->range.lower = v->range.lower; 172355b4669Sjacobs result->range.upper = v->range.upper; 173355b4669Sjacobs break; 174355b4669Sjacobs case PAPI_RESOLUTION: 175355b4669Sjacobs result->resolution.xres = v->resolution.xres; 176355b4669Sjacobs result->resolution.yres = v->resolution.yres; 177355b4669Sjacobs result->resolution.units = v->resolution.units; 178355b4669Sjacobs break; 179355b4669Sjacobs case PAPI_DATETIME: 180355b4669Sjacobs result->datetime = v->datetime; 181355b4669Sjacobs break; 182355b4669Sjacobs case PAPI_COLLECTION: 183355b4669Sjacobs result->collection = collection_dup(v->collection); 184355b4669Sjacobs break; 185355b4669Sjacobs case PAPI_METADATA: 186355b4669Sjacobs result->metadata = v->metadata; 187355b4669Sjacobs break; 188355b4669Sjacobs default: /* unknown type, fail to duplicate */ 189355b4669Sjacobs free(result); 190355b4669Sjacobs result = NULL; 191355b4669Sjacobs } 192355b4669Sjacobs } 193355b4669Sjacobs 194355b4669Sjacobs return (result); 195355b4669Sjacobs } 196355b4669Sjacobs 197355b4669Sjacobs static papi_attribute_t * 198355b4669Sjacobs papiAttributeAlloc(char *name, papi_attribute_value_type_t type) 199355b4669Sjacobs { 200355b4669Sjacobs papi_attribute_t *result = NULL; 201355b4669Sjacobs 202355b4669Sjacobs if ((result = calloc(1, sizeof (*result))) != NULL) { 203355b4669Sjacobs result->name = strdup(name); 204355b4669Sjacobs result->type = type; 205355b4669Sjacobs } 206355b4669Sjacobs 207355b4669Sjacobs return (result); 208355b4669Sjacobs } 209355b4669Sjacobs 210355b4669Sjacobs static papi_status_t 211355b4669Sjacobs papiAttributeListAppendValue(papi_attribute_value_t ***values, 212355b4669Sjacobs papi_attribute_value_type_t type, 213355b4669Sjacobs papi_attribute_value_t *value) 214355b4669Sjacobs { 215355b4669Sjacobs 216355b4669Sjacobs if (values == NULL) 217355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 218355b4669Sjacobs 219355b4669Sjacobs if (value != NULL) { /* this allows "empty" attributes */ 220355b4669Sjacobs papi_attribute_value_t *tmp = NULL; 221355b4669Sjacobs 222355b4669Sjacobs if ((tmp = papiAttributeValueDup(type, value)) == NULL) 223355b4669Sjacobs return (PAPI_TEMPORARY_ERROR); 224355b4669Sjacobs 225355b4669Sjacobs list_append(values, tmp); 226355b4669Sjacobs } 227355b4669Sjacobs 228355b4669Sjacobs return (PAPI_OK); 229355b4669Sjacobs } 230355b4669Sjacobs 231355b4669Sjacobs 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) 235355b4669Sjacobs { 236355b4669Sjacobs papi_status_t result; 237355b4669Sjacobs int flags = flgs; 238355b4669Sjacobs papi_attribute_t *attribute = NULL; 239355b4669Sjacobs papi_attribute_value_t **values = NULL; 240355b4669Sjacobs 241355b4669Sjacobs if ((list == NULL) || (name == NULL)) 242355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 243355b4669Sjacobs 244355b4669Sjacobs if ((type == PAPI_RANGE) && (value != NULL) && 245355b4669Sjacobs (value->range.lower > value->range.upper)) 246355b4669Sjacobs return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */ 247355b4669Sjacobs 248355b4669Sjacobs if (flags == 0) /* if it wasn't set, set a default behaviour */ 249355b4669Sjacobs flags = PAPI_ATTR_APPEND; 250355b4669Sjacobs 251355b4669Sjacobs /* look for an existing one */ 252355b4669Sjacobs attribute = papiAttributeListFind(*list, name); 253355b4669Sjacobs 254355b4669Sjacobs if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL)) 255355b4669Sjacobs return (PAPI_CONFLICT); /* EXISTS */ 256355b4669Sjacobs 257355b4669Sjacobs if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) && 258355b4669Sjacobs (attribute->type != type)) 259355b4669Sjacobs return (PAPI_CONFLICT); /* TYPE CONFLICT */ 260355b4669Sjacobs 261355b4669Sjacobs /* if we don't have one, create it and add it to the list */ 262355b4669Sjacobs if ((attribute == NULL) && 263355b4669Sjacobs ((attribute = papiAttributeAlloc(name, type)) != NULL)) 264355b4669Sjacobs list_append(list, attribute); 265355b4669Sjacobs 266355b4669Sjacobs /* if we don't have one by now, it's most likely an alloc fail */ 267355b4669Sjacobs if (attribute == NULL) 268355b4669Sjacobs return (PAPI_TEMPORARY_ERROR); 269355b4669Sjacobs 270355b4669Sjacobs /* 271355b4669Sjacobs * if we are replacing, clear any existing values, but don't free 272355b4669Sjacobs * until after we have replaced the values, in case we are replacing 273355b4669Sjacobs * a collection with a relocated version of the original collection. 274355b4669Sjacobs */ 275355b4669Sjacobs if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) { 276355b4669Sjacobs values = attribute->values; 277355b4669Sjacobs attribute->values = NULL; 278355b4669Sjacobs } 279355b4669Sjacobs 280355b4669Sjacobs attribute->type = type; 281355b4669Sjacobs 282355b4669Sjacobs result = papiAttributeListAppendValue(&attribute->values, type, value); 283355b4669Sjacobs 284355b4669Sjacobs /* free old values if we replaced them */ 285355b4669Sjacobs if (values != NULL) 286355b4669Sjacobs papiAttributeValuesFree(type, values); 287355b4669Sjacobs 288355b4669Sjacobs return (result); 289355b4669Sjacobs } 290355b4669Sjacobs 291355b4669Sjacobs papi_status_t 292355b4669Sjacobs papiAttributeListAddString(papi_attribute_t ***list, int flags, 293355b4669Sjacobs char *name, char *string) 294355b4669Sjacobs { 295355b4669Sjacobs papi_attribute_value_t v; 296355b4669Sjacobs 297355b4669Sjacobs v.string = (char *)string; 298355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); 299355b4669Sjacobs } 300355b4669Sjacobs 301355b4669Sjacobs papi_status_t 302355b4669Sjacobs papiAttributeListAddInteger(papi_attribute_t ***list, int flags, 303355b4669Sjacobs char *name, int integer) 304355b4669Sjacobs { 305355b4669Sjacobs papi_attribute_value_t v; 306355b4669Sjacobs 307355b4669Sjacobs v.integer = integer; 308355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); 309355b4669Sjacobs } 310355b4669Sjacobs 311355b4669Sjacobs papi_status_t 312355b4669Sjacobs papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, 313355b4669Sjacobs char *name, char boolean) 314355b4669Sjacobs { 315355b4669Sjacobs papi_attribute_value_t v; 316355b4669Sjacobs 317355b4669Sjacobs v.boolean = boolean; 318355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); 319355b4669Sjacobs } 320355b4669Sjacobs 321355b4669Sjacobs papi_status_t 322355b4669Sjacobs papiAttributeListAddRange(papi_attribute_t ***list, int flags, 323355b4669Sjacobs char *name, int lower, int upper) 324355b4669Sjacobs { 325355b4669Sjacobs papi_attribute_value_t v; 326355b4669Sjacobs 327355b4669Sjacobs v.range.lower = lower; 328355b4669Sjacobs v.range.upper = upper; 329355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); 330355b4669Sjacobs } 331355b4669Sjacobs 332355b4669Sjacobs papi_status_t 333355b4669Sjacobs papiAttributeListAddResolution(papi_attribute_t ***list, int flags, 334355b4669Sjacobs char *name, int xres, int yres, 335355b4669Sjacobs papi_resolution_unit_t units) 336355b4669Sjacobs { 337355b4669Sjacobs papi_attribute_value_t v; 338355b4669Sjacobs 339355b4669Sjacobs v.resolution.xres = xres; 340355b4669Sjacobs v.resolution.yres = yres; 341355b4669Sjacobs v.resolution.units = units; 342355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, 343355b4669Sjacobs PAPI_RESOLUTION, &v)); 344355b4669Sjacobs } 345355b4669Sjacobs 346355b4669Sjacobs papi_status_t 347355b4669Sjacobs papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, 348355b4669Sjacobs char *name, time_t datetime) 349355b4669Sjacobs { 350355b4669Sjacobs papi_attribute_value_t v; 351355b4669Sjacobs 352355b4669Sjacobs v.datetime = datetime; 353355b4669Sjacobs return (papiAttributeListAddValue(list, flags, name, 354355b4669Sjacobs PAPI_DATETIME, &v)); 355355b4669Sjacobs } 356355b4669Sjacobs 357355b4669Sjacobs papi_status_t 358355b4669Sjacobs papiAttributeListAddCollection(papi_attribute_t ***list, int flags, 359355b4669Sjacobs char *name, papi_attribute_t **collection) 360355b4669Sjacobs { 361355b4669Sjacobs papi_attribute_value_t v; 362355b4669Sjacobs 363355b4669Sjacobs 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)); 377355b4669Sjacobs } 378355b4669Sjacobs 379355b4669Sjacobs papi_status_t 380355b4669Sjacobs papiAttributeListDelete(papi_attribute_t ***list, char *name) 381355b4669Sjacobs { 382355b4669Sjacobs papi_attribute_t *attribute; 383355b4669Sjacobs 384355b4669Sjacobs if ((list == NULL) || (name == NULL)) 385355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 386355b4669Sjacobs 387355b4669Sjacobs if ((attribute = papiAttributeListFind(*list, name)) == NULL) 388355b4669Sjacobs return (PAPI_NOT_FOUND); 389355b4669Sjacobs 390*0a44ef6dSjacobs list_remove(list, attribute); 391355b4669Sjacobs papiAttributeFree(attribute); 392355b4669Sjacobs 393355b4669Sjacobs return (PAPI_OK); 394355b4669Sjacobs } 395355b4669Sjacobs 396355b4669Sjacobs papi_attribute_t * 397355b4669Sjacobs papiAttributeListFind(papi_attribute_t **list, char *name) 398355b4669Sjacobs { 399355b4669Sjacobs int i; 400355b4669Sjacobs if ((list == NULL) || (name == NULL)) 401355b4669Sjacobs return (NULL); 402355b4669Sjacobs 403355b4669Sjacobs for (i = 0; list[i] != NULL; i++) 404355b4669Sjacobs if (strcasecmp(list[i]->name, name) == 0) 405355b4669Sjacobs return ((papi_attribute_t *)list[i]); 406355b4669Sjacobs 407355b4669Sjacobs return (NULL); 408355b4669Sjacobs } 409355b4669Sjacobs 410355b4669Sjacobs papi_attribute_t * 411355b4669Sjacobs papiAttributeListGetNext(papi_attribute_t **list, void **iter) 412355b4669Sjacobs { 413355b4669Sjacobs papi_attribute_t **tmp, *result; 414355b4669Sjacobs 415355b4669Sjacobs if ((list == NULL) && (iter == NULL)) 416355b4669Sjacobs return (NULL); 417355b4669Sjacobs 418355b4669Sjacobs if (*iter == NULL) 419355b4669Sjacobs *iter = list; 420355b4669Sjacobs 421355b4669Sjacobs tmp = *iter; 422355b4669Sjacobs result = *tmp; 423355b4669Sjacobs *iter = ++tmp; 424355b4669Sjacobs 425355b4669Sjacobs return (result); 426355b4669Sjacobs } 427355b4669Sjacobs 428355b4669Sjacobs papi_status_t 429355b4669Sjacobs papiAttributeListGetValue(papi_attribute_t **list, void **iter, 430355b4669Sjacobs char *name, papi_attribute_value_type_t type, 431355b4669Sjacobs papi_attribute_value_t **value) 432355b4669Sjacobs { 433355b4669Sjacobs papi_attribute_value_t **tmp; 434355b4669Sjacobs void *fodder = NULL; 435355b4669Sjacobs 436355b4669Sjacobs if ((list == NULL) || ((name == NULL) && (iter == NULL)) || 437355b4669Sjacobs (value == NULL)) 438355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 439355b4669Sjacobs 440355b4669Sjacobs if (iter == NULL) 441355b4669Sjacobs iter = &fodder; 442355b4669Sjacobs 443355b4669Sjacobs if ((iter == NULL) || (*iter == NULL)) { 444355b4669Sjacobs papi_attribute_t *attr = papiAttributeListFind(list, name); 445355b4669Sjacobs 446355b4669Sjacobs if (attr == NULL) 447355b4669Sjacobs return (PAPI_NOT_FOUND); 448355b4669Sjacobs 449355b4669Sjacobs if (attr->type != type) 450355b4669Sjacobs return (PAPI_NOT_POSSIBLE); 451355b4669Sjacobs 452355b4669Sjacobs tmp = attr->values; 453355b4669Sjacobs } else 454355b4669Sjacobs tmp = *iter; 455355b4669Sjacobs 456355b4669Sjacobs if (tmp == NULL) 457355b4669Sjacobs return (PAPI_NOT_FOUND); 458355b4669Sjacobs 459355b4669Sjacobs *value = *tmp; 460355b4669Sjacobs *iter = ++tmp; 461355b4669Sjacobs 462355b4669Sjacobs if (*value == NULL) 463355b4669Sjacobs return (PAPI_GONE); 464355b4669Sjacobs 465355b4669Sjacobs return (PAPI_OK); 466355b4669Sjacobs } 467355b4669Sjacobs 468355b4669Sjacobs papi_status_t 469355b4669Sjacobs papiAttributeListGetString(papi_attribute_t **list, void **iter, 470355b4669Sjacobs char *name, char **vptr) 471355b4669Sjacobs { 472355b4669Sjacobs papi_status_t status; 473355b4669Sjacobs papi_attribute_value_t *value = NULL; 474355b4669Sjacobs 475355b4669Sjacobs if (vptr == NULL) 476355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 477355b4669Sjacobs 478355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 479355b4669Sjacobs PAPI_STRING, &value); 480355b4669Sjacobs if (status == PAPI_OK) 481355b4669Sjacobs *vptr = value->string; 482355b4669Sjacobs 483355b4669Sjacobs return (status); 484355b4669Sjacobs } 485355b4669Sjacobs 486355b4669Sjacobs papi_status_t 487355b4669Sjacobs papiAttributeListGetInteger(papi_attribute_t **list, void **iter, 488355b4669Sjacobs char *name, int *vptr) 489355b4669Sjacobs { 490355b4669Sjacobs papi_status_t status; 491355b4669Sjacobs papi_attribute_value_t *value = NULL; 492355b4669Sjacobs 493355b4669Sjacobs if (vptr == NULL) 494355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 495355b4669Sjacobs 496355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 497355b4669Sjacobs PAPI_INTEGER, &value); 498355b4669Sjacobs if (status == PAPI_OK) 499355b4669Sjacobs *vptr = value->integer; 500355b4669Sjacobs 501355b4669Sjacobs return (status); 502355b4669Sjacobs } 503355b4669Sjacobs 504355b4669Sjacobs papi_status_t 505355b4669Sjacobs papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, 506355b4669Sjacobs char *name, char *vptr) 507355b4669Sjacobs { 508355b4669Sjacobs papi_status_t status; 509355b4669Sjacobs papi_attribute_value_t *value = NULL; 510355b4669Sjacobs 511355b4669Sjacobs if (vptr == NULL) 512355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 513355b4669Sjacobs 514355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 515355b4669Sjacobs PAPI_BOOLEAN, &value); 516355b4669Sjacobs if (status == PAPI_OK) 517355b4669Sjacobs *vptr = value->boolean; 518355b4669Sjacobs 519355b4669Sjacobs return (status); 520355b4669Sjacobs } 521355b4669Sjacobs 522355b4669Sjacobs papi_status_t 523355b4669Sjacobs papiAttributeListGetRange(papi_attribute_t **list, void **iter, 524355b4669Sjacobs char *name, int *min, int *max) 525355b4669Sjacobs { 526355b4669Sjacobs papi_status_t status; 527355b4669Sjacobs papi_attribute_value_t *value = NULL; 528355b4669Sjacobs 529355b4669Sjacobs if ((min == NULL) || (max == NULL)) 530355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 531355b4669Sjacobs 532355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 533355b4669Sjacobs PAPI_RANGE, &value); 534355b4669Sjacobs if (status == PAPI_OK) { 535355b4669Sjacobs *min = value->range.lower; 536355b4669Sjacobs *max = value->range.upper; 537355b4669Sjacobs } 538355b4669Sjacobs 539355b4669Sjacobs return (status); 540355b4669Sjacobs } 541355b4669Sjacobs 542355b4669Sjacobs papi_status_t 543355b4669Sjacobs papiAttributeListGetResolution(papi_attribute_t **list, void **iter, 544355b4669Sjacobs char *name, int *x, int *y, 545355b4669Sjacobs papi_resolution_unit_t *units) 546355b4669Sjacobs { 547355b4669Sjacobs papi_status_t status; 548355b4669Sjacobs papi_attribute_value_t *value = NULL; 549355b4669Sjacobs 550355b4669Sjacobs if ((x == NULL) || (y == NULL) || (units == NULL)) 551355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 552355b4669Sjacobs 553355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 554355b4669Sjacobs PAPI_RESOLUTION, &value); 555355b4669Sjacobs if (status == PAPI_OK) { 556355b4669Sjacobs *x = value->resolution.xres; 557355b4669Sjacobs *y = value->resolution.yres; 558355b4669Sjacobs *units = value->resolution.units; 559355b4669Sjacobs } 560355b4669Sjacobs 561355b4669Sjacobs return (status); 562355b4669Sjacobs } 563355b4669Sjacobs 564355b4669Sjacobs papi_status_t 565355b4669Sjacobs papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, 566355b4669Sjacobs char *name, time_t *dt) 567355b4669Sjacobs { 568355b4669Sjacobs papi_status_t status; 569355b4669Sjacobs papi_attribute_value_t *value = NULL; 570355b4669Sjacobs 571355b4669Sjacobs if (dt == NULL) 572355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 573355b4669Sjacobs 574355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 575355b4669Sjacobs PAPI_DATETIME, &value); 576355b4669Sjacobs if (status == PAPI_OK) { 577355b4669Sjacobs *dt = value->datetime; 578355b4669Sjacobs } 579355b4669Sjacobs 580355b4669Sjacobs return (status); 581355b4669Sjacobs } 582355b4669Sjacobs 583355b4669Sjacobs papi_status_t 584355b4669Sjacobs papiAttributeListGetCollection(papi_attribute_t **list, void **iter, 585355b4669Sjacobs char *name, papi_attribute_t ***collection) 586355b4669Sjacobs { 587355b4669Sjacobs papi_status_t status; 588355b4669Sjacobs papi_attribute_value_t *value = NULL; 589355b4669Sjacobs 590355b4669Sjacobs if (collection == NULL) 591355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 592355b4669Sjacobs 593355b4669Sjacobs status = papiAttributeListGetValue(list, iter, name, 594355b4669Sjacobs PAPI_COLLECTION, &value); 595355b4669Sjacobs if (status == PAPI_OK) { 596355b4669Sjacobs *collection = value->collection; 597355b4669Sjacobs } 598355b4669Sjacobs 599355b4669Sjacobs return (status); 600355b4669Sjacobs } 601355b4669Sjacobs 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 } 619355b4669Sjacobs 620355b4669Sjacobs /* 621355b4669Sjacobs * 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. 627355b4669Sjacobs * 628355b4669Sjacobs */ 629355b4669Sjacobs 630355b4669Sjacobs static char * 631355b4669Sjacobs _getNextAttr(char *string, int *next) 632355b4669Sjacobs 633355b4669Sjacobs { 634355b4669Sjacobs char *result = NULL; 635355b4669Sjacobs char *start = (char *)string + *next; 636355b4669Sjacobs char *nl = NULL; 637355b4669Sjacobs char *sp = NULL; 638355b4669Sjacobs char *tab = NULL; 639355b4669Sjacobs char *val = NULL; 640355b4669Sjacobs int len = 0; 641355b4669Sjacobs 642355b4669Sjacobs if ((string != NULL) && (*start != '\0')) { 643355b4669Sjacobs while ((*start == ' ') || (*start == '\t') || (*start == '\n')) 644355b4669Sjacobs { 645355b4669Sjacobs start++; 646355b4669Sjacobs } 647355b4669Sjacobs nl = strchr(start, '\n'); 648355b4669Sjacobs sp = strchr(start, ' '); 649355b4669Sjacobs tab = strchr(start, '\t'); 650355b4669Sjacobs 651355b4669Sjacobs val = strchr(start, '='); 652355b4669Sjacobs 653355b4669Sjacobs if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) { 654355b4669Sjacobs val = strchr(&val[2], val[1]); 655355b4669Sjacobs if (val != NULL) { 656355b4669Sjacobs nl = strchr(&val[1], '\n'); 657355b4669Sjacobs sp = strchr(&val[1], ' '); 658355b4669Sjacobs tab = strchr(&val[1], '\t'); 659355b4669Sjacobs } 660355b4669Sjacobs } 661355b4669Sjacobs 662355b4669Sjacobs if ((nl != NULL) && 663355b4669Sjacobs ((sp == NULL) || ((sp != NULL) && (nl < sp))) && 664355b4669Sjacobs ((tab == NULL) || ((tab != NULL) && (nl < tab)))) { 665355b4669Sjacobs len = nl-start; 666355b4669Sjacobs } else if ((sp != NULL) && (tab != NULL) && (sp > tab)) { 667355b4669Sjacobs len = tab-start; 668355b4669Sjacobs } else if ((sp != NULL) && (sp != NULL)) { 669355b4669Sjacobs len = sp-start; 670355b4669Sjacobs } else if ((tab != NULL) && (tab != NULL)) { 671355b4669Sjacobs len = tab-start; 672355b4669Sjacobs } 673355b4669Sjacobs 674355b4669Sjacobs if (len == 0) { 675355b4669Sjacobs len = strlen(start); 676355b4669Sjacobs } 677355b4669Sjacobs 678355b4669Sjacobs if (len > 0) { 679355b4669Sjacobs result = (char *)malloc(len+1); 680355b4669Sjacobs if (result != NULL) { 681355b4669Sjacobs strncpy(result, start, len); 682355b4669Sjacobs result[len] = '\0'; 683355b4669Sjacobs *next = (start-string)+len; 684355b4669Sjacobs } 685355b4669Sjacobs } 686355b4669Sjacobs } 687355b4669Sjacobs 688355b4669Sjacobs return (result); 689355b4669Sjacobs } /* _getNextAttr() */ 690355b4669Sjacobs 691355b4669Sjacobs 692355b4669Sjacobs /* 693355b4669Sjacobs * Description: Parse the given attribute string value and transform it into 694355b4669Sjacobs * the papi_attribute_value_t in the papi_attribute_t structure. 695355b4669Sjacobs * 696355b4669Sjacobs */ 697355b4669Sjacobs 698355b4669Sjacobs static papi_status_t 699355b4669Sjacobs _parseAttrValue(char *value, papi_attribute_t *attr) 700355b4669Sjacobs 701355b4669Sjacobs { 702355b4669Sjacobs papi_status_t result = PAPI_OK; 703355b4669Sjacobs int len = 0; 704355b4669Sjacobs int i = 0; 705355b4669Sjacobs char *papiString = NULL; 706355b4669Sjacobs char *tmp1 = NULL; 707355b4669Sjacobs char *tmp2 = NULL; 708355b4669Sjacobs char *tmp3 = NULL; 709355b4669Sjacobs papi_attribute_value_t **avalues = NULL; 710355b4669Sjacobs 711355b4669Sjacobs avalues = malloc(sizeof (papi_attribute_value_t *) * 2); 712355b4669Sjacobs if (avalues == NULL) { 713355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 714355b4669Sjacobs return (result); 715355b4669Sjacobs } 716355b4669Sjacobs avalues[0] = malloc(sizeof (papi_attribute_value_t)); 717355b4669Sjacobs avalues[1] = NULL; 718355b4669Sjacobs if (avalues[0] == NULL) { 719355b4669Sjacobs free(avalues); 720355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 721355b4669Sjacobs return (result); 722355b4669Sjacobs } 723355b4669Sjacobs 724355b4669Sjacobs 725355b4669Sjacobs /* 726355b4669Sjacobs * TODO - need to sort out 'resolution', 'dateandtime' & 'collection' values 727355b4669Sjacobs */ 728355b4669Sjacobs if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) { 729355b4669Sjacobs 730355b4669Sjacobs len = strlen(value); 731355b4669Sjacobs if ((len >= 2) && (((value[0] == '"') && 732355b4669Sjacobs (value[len-1] == '"')) || ((value[0] == '\'') && 733355b4669Sjacobs (value[len-1] == '\'')))) { 734355b4669Sjacobs /* string value */ 735355b4669Sjacobs attr->type = PAPI_STRING; 736355b4669Sjacobs 737355b4669Sjacobs papiString = strdup(value+1); 738355b4669Sjacobs if (papiString != NULL) { 739355b4669Sjacobs papiString[strlen(papiString)-1] = '\0'; 740355b4669Sjacobs avalues[0]->string = papiString; 741355b4669Sjacobs } else { 742355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 743355b4669Sjacobs } 744355b4669Sjacobs } else if ((strcasecmp(value, "true") == 0) || 745355b4669Sjacobs (strcasecmp(value, "YES") == 0)) { 746355b4669Sjacobs /* boolean = true */ 747355b4669Sjacobs attr->type = PAPI_BOOLEAN; 748355b4669Sjacobs avalues[0]->boolean = PAPI_TRUE; 749355b4669Sjacobs } else if ((strcasecmp(value, "false") == 0) || 750355b4669Sjacobs (strcasecmp(value, "NO") == 0)) { 751355b4669Sjacobs /* boolean = false */ 752355b4669Sjacobs attr->type = PAPI_BOOLEAN; 753355b4669Sjacobs avalues[0]->boolean = PAPI_FALSE; 754355b4669Sjacobs } else { 755355b4669Sjacobs /* is value an integer or a range ? */ 756355b4669Sjacobs 757355b4669Sjacobs i = 0; 758355b4669Sjacobs attr->type = PAPI_INTEGER; 759355b4669Sjacobs tmp1 = strdup(value); 760355b4669Sjacobs while (((value[i] >= '0') && (value[i] <= '9')) || 761355b4669Sjacobs (value[i] == '-')) { 762355b4669Sjacobs if (value[i] == '-') { 763355b4669Sjacobs tmp1[i] = '\0'; 764355b4669Sjacobs tmp2 = &tmp1[i+1]; 765355b4669Sjacobs attr->type = PAPI_RANGE; 766355b4669Sjacobs } 767355b4669Sjacobs 768355b4669Sjacobs i++; 769355b4669Sjacobs } 770355b4669Sjacobs 771355b4669Sjacobs if (strlen(value) == i) { 772355b4669Sjacobs if (attr->type == PAPI_RANGE) { 773355b4669Sjacobs avalues[0]->range.lower = atoi(tmp1); 774355b4669Sjacobs avalues[0]->range.upper = atoi(tmp2); 775355b4669Sjacobs } else { 776355b4669Sjacobs avalues[0]->integer = atoi(value); 777355b4669Sjacobs } 778355b4669Sjacobs } else { 779355b4669Sjacobs /* is value a resolution ? */ 780355b4669Sjacobs i = 0; 781355b4669Sjacobs attr->type = PAPI_INTEGER; 782355b4669Sjacobs tmp1 = strdup(value); 783355b4669Sjacobs while (((value[i] >= '0') && 784355b4669Sjacobs (value[i] <= '9')) || 785355b4669Sjacobs (value[i] == 'x')) { 786355b4669Sjacobs if (value[i] == 'x') { 787355b4669Sjacobs tmp1[i] = '\0'; 788355b4669Sjacobs if (attr->type == PAPI_INTEGER) 789355b4669Sjacobs { 790355b4669Sjacobs tmp2 = &tmp1[i+1]; 791355b4669Sjacobs attr->type = 792355b4669Sjacobs PAPI_RESOLUTION; 793355b4669Sjacobs } else { 794355b4669Sjacobs tmp3 = &tmp1[i+1]; 795355b4669Sjacobs } 796355b4669Sjacobs } 797355b4669Sjacobs 798355b4669Sjacobs i++; 799355b4669Sjacobs } 800355b4669Sjacobs 801355b4669Sjacobs if (strlen(value) == i) { 802355b4669Sjacobs if (attr->type == PAPI_RESOLUTION) { 803355b4669Sjacobs avalues[0]->resolution.xres = 804355b4669Sjacobs atoi(tmp1); 805355b4669Sjacobs avalues[0]->resolution.yres = 806355b4669Sjacobs atoi(tmp2); 807355b4669Sjacobs if (tmp3 != NULL) { 808355b4669Sjacobs avalues[0]-> 809355b4669Sjacobs resolution.units = 810355b4669Sjacobs atoi(tmp3); 811355b4669Sjacobs } else { 812355b4669Sjacobs avalues[0]-> 813355b4669Sjacobs resolution.units = 0; 814355b4669Sjacobs } 815355b4669Sjacobs } 816355b4669Sjacobs } 817355b4669Sjacobs 818355b4669Sjacobs if (attr->type != PAPI_RESOLUTION) { 819355b4669Sjacobs attr->type = PAPI_STRING; 820355b4669Sjacobs avalues[0]->string = strdup(value); 821355b4669Sjacobs if (avalues[0]->string == NULL) { 822355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 823355b4669Sjacobs } 824355b4669Sjacobs } 825355b4669Sjacobs } 826355b4669Sjacobs free(tmp1); 827355b4669Sjacobs } 828355b4669Sjacobs 829355b4669Sjacobs } else { 830355b4669Sjacobs result = PAPI_BAD_ARGUMENT; 831355b4669Sjacobs } 832355b4669Sjacobs 833355b4669Sjacobs if (result != PAPI_OK) { 834355b4669Sjacobs i = 0; 835355b4669Sjacobs while (avalues[i] != NULL) { 836355b4669Sjacobs free(avalues[i]); 837355b4669Sjacobs i++; 838355b4669Sjacobs } 839355b4669Sjacobs free(avalues); 840355b4669Sjacobs } else { 841355b4669Sjacobs attr->values = avalues; 842355b4669Sjacobs } 843355b4669Sjacobs 844355b4669Sjacobs return (result); 845355b4669Sjacobs } /* _parseAttrValue() */ 846355b4669Sjacobs 847355b4669Sjacobs 848355b4669Sjacobs /* 849355b4669Sjacobs * Description: Parse the given attribute string and transform it into the 850355b4669Sjacobs * papi_attribute_t structure. 851355b4669Sjacobs * 852355b4669Sjacobs */ 853355b4669Sjacobs 854355b4669Sjacobs static papi_status_t 855355b4669Sjacobs _parseAttributeString(char *attrString, papi_attribute_t *attr) 856355b4669Sjacobs 857355b4669Sjacobs { 858355b4669Sjacobs papi_status_t result = PAPI_OK; 859355b4669Sjacobs char *string = NULL; 860355b4669Sjacobs char *p = NULL; 861355b4669Sjacobs papi_attribute_value_t **avalues = NULL; 862355b4669Sjacobs 863355b4669Sjacobs if ((attrString != NULL) && (strlen(attrString) >= 3) && 864355b4669Sjacobs (attr != NULL)) { 865355b4669Sjacobs attr->name = NULL; 866355b4669Sjacobs string = strdup(attrString); 867355b4669Sjacobs if (string != NULL) { 868355b4669Sjacobs p = strchr(string, '='); 869355b4669Sjacobs if (p != NULL) { 870355b4669Sjacobs *p = '\0'; 871355b4669Sjacobs attr->name = string; 872355b4669Sjacobs p++; /* pointer to value */ 873355b4669Sjacobs 874355b4669Sjacobs result = _parseAttrValue(p, attr); 875355b4669Sjacobs } else { 876355b4669Sjacobs char value; 877355b4669Sjacobs /* 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 884355b4669Sjacobs attr->name = string; 885355b4669Sjacobs attr->type = PAPI_BOOLEAN; 886355b4669Sjacobs 887355b4669Sjacobs avalues = malloc( 888355b4669Sjacobs sizeof (papi_attribute_value_t *) * 2); 889355b4669Sjacobs if (avalues == NULL) { 890355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 891355b4669Sjacobs } else { 892355b4669Sjacobs avalues[0] = malloc( 893355b4669Sjacobs sizeof (papi_attribute_value_t)); 894355b4669Sjacobs avalues[1] = NULL; 895355b4669Sjacobs if (avalues[0] == NULL) { 896355b4669Sjacobs free(avalues); 897355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 898355b4669Sjacobs } else { 899355b4669Sjacobs avalues[0]->boolean = value; 900355b4669Sjacobs attr->values = avalues; 901355b4669Sjacobs } 902355b4669Sjacobs } 903355b4669Sjacobs } 904355b4669Sjacobs } 905355b4669Sjacobs } else { 906355b4669Sjacobs result = PAPI_BAD_ARGUMENT; 907355b4669Sjacobs } 908355b4669Sjacobs 909355b4669Sjacobs return (result); 910355b4669Sjacobs } /* _parseAttributeString() */ 911355b4669Sjacobs 912355b4669Sjacobs 913355b4669Sjacobs papi_status_t 914355b4669Sjacobs papiAttributeListFromString(papi_attribute_t ***attrs, 915355b4669Sjacobs int flags, char *string) 916355b4669Sjacobs { 917355b4669Sjacobs papi_status_t result = PAPI_OK; 918355b4669Sjacobs int next = 0; 919355b4669Sjacobs char *attrString = NULL; 920355b4669Sjacobs papi_attribute_t attr; 921355b4669Sjacobs 922355b4669Sjacobs if ((attrs != NULL) && (string != NULL) && 923355b4669Sjacobs ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) 924355b4669Sjacobs == 0)) { 925355b4669Sjacobs attrString = _getNextAttr(string, &next); 926355b4669Sjacobs while ((result == PAPI_OK) && (attrString != NULL)) { 927355b4669Sjacobs result = _parseAttributeString(attrString, &attr); 928355b4669Sjacobs if ((result == PAPI_OK) && (attr.name != NULL)) { 929355b4669Sjacobs /* add this attribute to the list */ 930355b4669Sjacobs if ((attr.values != NULL) && 931355b4669Sjacobs (attr.values[0] != NULL)) { 932355b4669Sjacobs result = papiAttributeListAddValue( 933355b4669Sjacobs attrs, PAPI_ATTR_APPEND, 934355b4669Sjacobs attr.name, attr.type, 935355b4669Sjacobs attr.values[0]); 936355b4669Sjacobs free(attr.values[0]); 937355b4669Sjacobs free(attr.values); 938355b4669Sjacobs } else { 939355b4669Sjacobs result = PAPI_TEMPORARY_ERROR; 940355b4669Sjacobs } 941355b4669Sjacobs } 942355b4669Sjacobs free(attrString); 943355b4669Sjacobs 944355b4669Sjacobs attrString = _getNextAttr(string, &next); 945355b4669Sjacobs } 946355b4669Sjacobs } 947355b4669Sjacobs else 948355b4669Sjacobs { 949355b4669Sjacobs result = PAPI_BAD_ARGUMENT; 950355b4669Sjacobs } 951355b4669Sjacobs 952355b4669Sjacobs return (result); 953355b4669Sjacobs } 954355b4669Sjacobs 955355b4669Sjacobs static papi_status_t 956355b4669Sjacobs papiAttributeToString(papi_attribute_t *attribute, char *delim, 957355b4669Sjacobs char *buffer, size_t buflen) 958355b4669Sjacobs { 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); 1048355b4669Sjacobs } 1049355b4669Sjacobs 1050355b4669Sjacobs papi_status_t 1051355b4669Sjacobs papiAttributeListToString(papi_attribute_t **attrs, 1052355b4669Sjacobs char *delim, char *buffer, size_t buflen) 1053355b4669Sjacobs { 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); 1071355b4669Sjacobs } 1072355b4669Sjacobs 1073355b4669Sjacobs return (status); 1074355b4669Sjacobs } 1075355b4669Sjacobs 1076355b4669Sjacobs static int 1077355b4669Sjacobs is_in_list(char *value, char **list) 1078355b4669Sjacobs { 1079355b4669Sjacobs if ((list != NULL) && (value != NULL)) { 1080355b4669Sjacobs int i; 1081355b4669Sjacobs 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) 1092355b4669Sjacobs { 1093355b4669Sjacobs papi_status_t status; 1094355b4669Sjacobs int i = 0; 1095355b4669Sjacobs 1096355b4669Sjacobs if ((list == NULL) || (attribute == NULL) || 1097355b4669Sjacobs (attribute->values == NULL)) 1098355b4669Sjacobs return (PAPI_BAD_ARGUMENT); 1099355b4669Sjacobs 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++; 1108355b4669Sjacobs 1109355b4669Sjacobs return (status); 1110355b4669Sjacobs } 1111355b4669Sjacobs 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 } 1123355b4669Sjacobs 1124355b4669Sjacobs void 1125355b4669Sjacobs split_and_copy_attributes(char **list, papi_attribute_t **attributes, 1126355b4669Sjacobs papi_attribute_t ***in, papi_attribute_t ***out) 1127355b4669Sjacobs { 1128355b4669Sjacobs int i; 1129355b4669Sjacobs 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 } 1172355b4669Sjacobs } 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); 1181355b4669Sjacobs } 1182