1*2264Sjacobs /* 2*2264Sjacobs * CDDL HEADER START 3*2264Sjacobs * 4*2264Sjacobs * The contents of this file are subject to the terms of the 5*2264Sjacobs * Common Development and Distribution License (the "License"). 6*2264Sjacobs * You may not use this file except in compliance with the License. 7*2264Sjacobs * 8*2264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2264Sjacobs * or http://www.opensolaris.org/os/licensing. 10*2264Sjacobs * See the License for the specific language governing permissions 11*2264Sjacobs * and limitations under the License. 12*2264Sjacobs * 13*2264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14*2264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16*2264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17*2264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18*2264Sjacobs * 19*2264Sjacobs * CDDL HEADER END 20*2264Sjacobs */ 21*2264Sjacobs 22*2264Sjacobs /* 23*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*2264Sjacobs * Use is subject to license terms. 25*2264Sjacobs * 26*2264Sjacobs */ 27*2264Sjacobs 28*2264Sjacobs /* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */ 29*2264Sjacobs 30*2264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 31*2264Sjacobs 32*2264Sjacobs /*LINTLIBRARY*/ 33*2264Sjacobs 34*2264Sjacobs #include <stdio.h> 35*2264Sjacobs #include <stdlib.h> 36*2264Sjacobs #include <stdarg.h> 37*2264Sjacobs #include <string.h> 38*2264Sjacobs #include <alloca.h> 39*2264Sjacobs #include <papi.h> 40*2264Sjacobs 41*2264Sjacobs static void papiAttributeFree(papi_attribute_t *attribute); 42*2264Sjacobs 43*2264Sjacobs static void 44*2264Sjacobs papiAttributeValueFree(papi_attribute_value_type_t type, 45*2264Sjacobs papi_attribute_value_t *value) 46*2264Sjacobs { 47*2264Sjacobs if (value != NULL) { 48*2264Sjacobs switch (type) { 49*2264Sjacobs case PAPI_STRING: 50*2264Sjacobs if (value->string != NULL) 51*2264Sjacobs free(value->string); 52*2264Sjacobs break; 53*2264Sjacobs case PAPI_COLLECTION: 54*2264Sjacobs if (value->collection != NULL) { 55*2264Sjacobs int i; 56*2264Sjacobs 57*2264Sjacobs for (i = 0; value->collection[i] != NULL; i++) 58*2264Sjacobs papiAttributeFree(value->collection[i]); 59*2264Sjacobs 60*2264Sjacobs free(value->collection); 61*2264Sjacobs } 62*2264Sjacobs break; 63*2264Sjacobs default: /* don't need to free anything extra */ 64*2264Sjacobs break; 65*2264Sjacobs } 66*2264Sjacobs 67*2264Sjacobs free(value); 68*2264Sjacobs } 69*2264Sjacobs } 70*2264Sjacobs 71*2264Sjacobs static void 72*2264Sjacobs papiAttributeValuesFree(papi_attribute_value_type_t type, 73*2264Sjacobs papi_attribute_value_t **values) 74*2264Sjacobs { 75*2264Sjacobs if (values != NULL) { 76*2264Sjacobs int i; 77*2264Sjacobs 78*2264Sjacobs for (i = 0; values[i] != NULL; i++) 79*2264Sjacobs papiAttributeValueFree(type, values[i]); 80*2264Sjacobs 81*2264Sjacobs free(values); 82*2264Sjacobs } 83*2264Sjacobs } 84*2264Sjacobs 85*2264Sjacobs static void 86*2264Sjacobs papiAttributeFree(papi_attribute_t *attribute) 87*2264Sjacobs { 88*2264Sjacobs if (attribute != NULL) { 89*2264Sjacobs if (attribute->name != NULL) 90*2264Sjacobs free(attribute->name); 91*2264Sjacobs if (attribute->values != NULL) 92*2264Sjacobs papiAttributeValuesFree(attribute->type, 93*2264Sjacobs attribute->values); 94*2264Sjacobs free(attribute); 95*2264Sjacobs } 96*2264Sjacobs } 97*2264Sjacobs 98*2264Sjacobs void 99*2264Sjacobs papiAttributeListFree(papi_attribute_t **list) 100*2264Sjacobs { 101*2264Sjacobs if (list != NULL) { 102*2264Sjacobs int i; 103*2264Sjacobs 104*2264Sjacobs for (i = 0; list[i] != NULL; i++) 105*2264Sjacobs papiAttributeFree(list[i]); 106*2264Sjacobs 107*2264Sjacobs free(list); 108*2264Sjacobs } 109*2264Sjacobs } 110*2264Sjacobs 111*2264Sjacobs static papi_attribute_t ** 112*2264Sjacobs collection_dup(papi_attribute_t **collection) 113*2264Sjacobs { 114*2264Sjacobs papi_attribute_t **result = NULL; 115*2264Sjacobs 116*2264Sjacobs /* allows a NULL collection that is "empty" or "no value" */ 117*2264Sjacobs if (collection != NULL) { 118*2264Sjacobs papi_status_t status = PAPI_OK; 119*2264Sjacobs int i; 120*2264Sjacobs 121*2264Sjacobs for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); 122*2264Sjacobs i++) { 123*2264Sjacobs papi_attribute_t *a = collection[i]; 124*2264Sjacobs 125*2264Sjacobs status = papiAttributeListAddValue(&result, 126*2264Sjacobs PAPI_ATTR_APPEND, a->name, a->type, 127*2264Sjacobs NULL); 128*2264Sjacobs if ((status == PAPI_OK) && (a->values != NULL)) { 129*2264Sjacobs int j; 130*2264Sjacobs 131*2264Sjacobs for (j = 0; ((a->values[j] != NULL) && 132*2264Sjacobs (status == PAPI_OK)); j++) 133*2264Sjacobs status = papiAttributeListAddValue( 134*2264Sjacobs &result, 135*2264Sjacobs PAPI_ATTR_APPEND, 136*2264Sjacobs a->name, a->type, 137*2264Sjacobs a->values[j]); 138*2264Sjacobs } 139*2264Sjacobs } 140*2264Sjacobs if (status != PAPI_OK) { 141*2264Sjacobs papiAttributeListFree(result); 142*2264Sjacobs result = NULL; 143*2264Sjacobs } 144*2264Sjacobs } 145*2264Sjacobs 146*2264Sjacobs return (result); 147*2264Sjacobs } 148*2264Sjacobs 149*2264Sjacobs static papi_attribute_value_t * 150*2264Sjacobs papiAttributeValueDup(papi_attribute_value_type_t type, 151*2264Sjacobs papi_attribute_value_t *v) 152*2264Sjacobs { 153*2264Sjacobs papi_attribute_value_t *result = NULL; 154*2264Sjacobs 155*2264Sjacobs if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) { 156*2264Sjacobs switch (type) { 157*2264Sjacobs case PAPI_STRING: 158*2264Sjacobs if (v->string == NULL) { 159*2264Sjacobs free(result); 160*2264Sjacobs result = NULL; 161*2264Sjacobs } else 162*2264Sjacobs result->string = strdup(v->string); 163*2264Sjacobs break; 164*2264Sjacobs case PAPI_INTEGER: 165*2264Sjacobs result->integer = v->integer; 166*2264Sjacobs break; 167*2264Sjacobs case PAPI_BOOLEAN: 168*2264Sjacobs result->boolean = v->boolean; 169*2264Sjacobs break; 170*2264Sjacobs case PAPI_RANGE: 171*2264Sjacobs result->range.lower = v->range.lower; 172*2264Sjacobs result->range.upper = v->range.upper; 173*2264Sjacobs break; 174*2264Sjacobs case PAPI_RESOLUTION: 175*2264Sjacobs result->resolution.xres = v->resolution.xres; 176*2264Sjacobs result->resolution.yres = v->resolution.yres; 177*2264Sjacobs result->resolution.units = v->resolution.units; 178*2264Sjacobs break; 179*2264Sjacobs case PAPI_DATETIME: 180*2264Sjacobs result->datetime = v->datetime; 181*2264Sjacobs break; 182*2264Sjacobs case PAPI_COLLECTION: 183*2264Sjacobs result->collection = collection_dup(v->collection); 184*2264Sjacobs break; 185*2264Sjacobs case PAPI_METADATA: 186*2264Sjacobs result->metadata = v->metadata; 187*2264Sjacobs break; 188*2264Sjacobs default: /* unknown type, fail to duplicate */ 189*2264Sjacobs free(result); 190*2264Sjacobs result = NULL; 191*2264Sjacobs } 192*2264Sjacobs } 193*2264Sjacobs 194*2264Sjacobs return (result); 195*2264Sjacobs } 196*2264Sjacobs 197*2264Sjacobs static papi_attribute_t * 198*2264Sjacobs papiAttributeAlloc(char *name, papi_attribute_value_type_t type) 199*2264Sjacobs { 200*2264Sjacobs papi_attribute_t *result = NULL; 201*2264Sjacobs 202*2264Sjacobs if ((result = calloc(1, sizeof (*result))) != NULL) { 203*2264Sjacobs result->name = strdup(name); 204*2264Sjacobs result->type = type; 205*2264Sjacobs } 206*2264Sjacobs 207*2264Sjacobs return (result); 208*2264Sjacobs } 209*2264Sjacobs 210*2264Sjacobs static papi_status_t 211*2264Sjacobs papiAttributeListAppendValue(papi_attribute_value_t ***values, 212*2264Sjacobs papi_attribute_value_type_t type, 213*2264Sjacobs papi_attribute_value_t *value) 214*2264Sjacobs { 215*2264Sjacobs 216*2264Sjacobs if (values == NULL) 217*2264Sjacobs return (PAPI_BAD_ARGUMENT); 218*2264Sjacobs 219*2264Sjacobs if (value != NULL) { /* this allows "empty" attributes */ 220*2264Sjacobs papi_attribute_value_t *tmp = NULL; 221*2264Sjacobs 222*2264Sjacobs if ((tmp = papiAttributeValueDup(type, value)) == NULL) 223*2264Sjacobs return (PAPI_TEMPORARY_ERROR); 224*2264Sjacobs 225*2264Sjacobs list_append(values, tmp); 226*2264Sjacobs } 227*2264Sjacobs 228*2264Sjacobs return (PAPI_OK); 229*2264Sjacobs } 230*2264Sjacobs 231*2264Sjacobs papi_status_t 232*2264Sjacobs papiAttributeListAddValue(papi_attribute_t ***list, int flgs, 233*2264Sjacobs char *name, papi_attribute_value_type_t type, 234*2264Sjacobs papi_attribute_value_t *value) 235*2264Sjacobs { 236*2264Sjacobs papi_status_t result; 237*2264Sjacobs int flags = flgs; 238*2264Sjacobs papi_attribute_t *attribute = NULL; 239*2264Sjacobs papi_attribute_value_t **values = NULL; 240*2264Sjacobs 241*2264Sjacobs if ((list == NULL) || (name == NULL)) 242*2264Sjacobs return (PAPI_BAD_ARGUMENT); 243*2264Sjacobs 244*2264Sjacobs if ((type == PAPI_RANGE) && (value != NULL) && 245*2264Sjacobs (value->range.lower > value->range.upper)) 246*2264Sjacobs return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */ 247*2264Sjacobs 248*2264Sjacobs if (flags == 0) /* if it wasn't set, set a default behaviour */ 249*2264Sjacobs flags = PAPI_ATTR_APPEND; 250*2264Sjacobs 251*2264Sjacobs /* look for an existing one */ 252*2264Sjacobs attribute = papiAttributeListFind(*list, name); 253*2264Sjacobs 254*2264Sjacobs if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL)) 255*2264Sjacobs return (PAPI_CONFLICT); /* EXISTS */ 256*2264Sjacobs 257*2264Sjacobs if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) && 258*2264Sjacobs (attribute->type != type)) 259*2264Sjacobs return (PAPI_CONFLICT); /* TYPE CONFLICT */ 260*2264Sjacobs 261*2264Sjacobs /* if we don't have one, create it and add it to the list */ 262*2264Sjacobs if ((attribute == NULL) && 263*2264Sjacobs ((attribute = papiAttributeAlloc(name, type)) != NULL)) 264*2264Sjacobs list_append(list, attribute); 265*2264Sjacobs 266*2264Sjacobs /* if we don't have one by now, it's most likely an alloc fail */ 267*2264Sjacobs if (attribute == NULL) 268*2264Sjacobs return (PAPI_TEMPORARY_ERROR); 269*2264Sjacobs 270*2264Sjacobs /* 271*2264Sjacobs * if we are replacing, clear any existing values, but don't free 272*2264Sjacobs * until after we have replaced the values, in case we are replacing 273*2264Sjacobs * a collection with a relocated version of the original collection. 274*2264Sjacobs */ 275*2264Sjacobs if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) { 276*2264Sjacobs values = attribute->values; 277*2264Sjacobs attribute->values = NULL; 278*2264Sjacobs } 279*2264Sjacobs 280*2264Sjacobs attribute->type = type; 281*2264Sjacobs 282*2264Sjacobs result = papiAttributeListAppendValue(&attribute->values, type, value); 283*2264Sjacobs 284*2264Sjacobs /* free old values if we replaced them */ 285*2264Sjacobs if (values != NULL) 286*2264Sjacobs papiAttributeValuesFree(type, values); 287*2264Sjacobs 288*2264Sjacobs return (result); 289*2264Sjacobs } 290*2264Sjacobs 291*2264Sjacobs papi_status_t 292*2264Sjacobs papiAttributeListAddString(papi_attribute_t ***list, int flags, 293*2264Sjacobs char *name, char *string) 294*2264Sjacobs { 295*2264Sjacobs papi_attribute_value_t v; 296*2264Sjacobs 297*2264Sjacobs v.string = (char *)string; 298*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); 299*2264Sjacobs } 300*2264Sjacobs 301*2264Sjacobs papi_status_t 302*2264Sjacobs papiAttributeListAddInteger(papi_attribute_t ***list, int flags, 303*2264Sjacobs char *name, int integer) 304*2264Sjacobs { 305*2264Sjacobs papi_attribute_value_t v; 306*2264Sjacobs 307*2264Sjacobs v.integer = integer; 308*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); 309*2264Sjacobs } 310*2264Sjacobs 311*2264Sjacobs papi_status_t 312*2264Sjacobs papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, 313*2264Sjacobs char *name, char boolean) 314*2264Sjacobs { 315*2264Sjacobs papi_attribute_value_t v; 316*2264Sjacobs 317*2264Sjacobs v.boolean = boolean; 318*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); 319*2264Sjacobs } 320*2264Sjacobs 321*2264Sjacobs papi_status_t 322*2264Sjacobs papiAttributeListAddRange(papi_attribute_t ***list, int flags, 323*2264Sjacobs char *name, int lower, int upper) 324*2264Sjacobs { 325*2264Sjacobs papi_attribute_value_t v; 326*2264Sjacobs 327*2264Sjacobs v.range.lower = lower; 328*2264Sjacobs v.range.upper = upper; 329*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); 330*2264Sjacobs } 331*2264Sjacobs 332*2264Sjacobs papi_status_t 333*2264Sjacobs papiAttributeListAddResolution(papi_attribute_t ***list, int flags, 334*2264Sjacobs char *name, int xres, int yres, 335*2264Sjacobs papi_resolution_unit_t units) 336*2264Sjacobs { 337*2264Sjacobs papi_attribute_value_t v; 338*2264Sjacobs 339*2264Sjacobs v.resolution.xres = xres; 340*2264Sjacobs v.resolution.yres = yres; 341*2264Sjacobs v.resolution.units = units; 342*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, 343*2264Sjacobs PAPI_RESOLUTION, &v)); 344*2264Sjacobs } 345*2264Sjacobs 346*2264Sjacobs papi_status_t 347*2264Sjacobs papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, 348*2264Sjacobs char *name, time_t datetime) 349*2264Sjacobs { 350*2264Sjacobs papi_attribute_value_t v; 351*2264Sjacobs 352*2264Sjacobs v.datetime = datetime; 353*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, 354*2264Sjacobs PAPI_DATETIME, &v)); 355*2264Sjacobs } 356*2264Sjacobs 357*2264Sjacobs papi_status_t 358*2264Sjacobs papiAttributeListAddCollection(papi_attribute_t ***list, int flags, 359*2264Sjacobs char *name, papi_attribute_t **collection) 360*2264Sjacobs { 361*2264Sjacobs papi_attribute_value_t v; 362*2264Sjacobs 363*2264Sjacobs v.collection = (papi_attribute_t **)collection; 364*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, 365*2264Sjacobs PAPI_COLLECTION, &v)); 366*2264Sjacobs } 367*2264Sjacobs 368*2264Sjacobs papi_status_t 369*2264Sjacobs papiAttributeListAddMetadata(papi_attribute_t ***list, int flags, 370*2264Sjacobs char *name, papi_metadata_t metadata) 371*2264Sjacobs { 372*2264Sjacobs papi_attribute_value_t v; 373*2264Sjacobs 374*2264Sjacobs v.metadata = metadata; 375*2264Sjacobs return (papiAttributeListAddValue(list, flags, name, 376*2264Sjacobs PAPI_METADATA, &v)); 377*2264Sjacobs } 378*2264Sjacobs 379*2264Sjacobs papi_status_t 380*2264Sjacobs papiAttributeListDelete(papi_attribute_t ***list, char *name) 381*2264Sjacobs { 382*2264Sjacobs papi_attribute_t *attribute; 383*2264Sjacobs 384*2264Sjacobs if ((list == NULL) || (name == NULL)) 385*2264Sjacobs return (PAPI_BAD_ARGUMENT); 386*2264Sjacobs 387*2264Sjacobs if ((attribute = papiAttributeListFind(*list, name)) == NULL) 388*2264Sjacobs return (PAPI_NOT_FOUND); 389*2264Sjacobs 390*2264Sjacobs list_remove(*list, attribute); 391*2264Sjacobs papiAttributeFree(attribute); 392*2264Sjacobs 393*2264Sjacobs return (PAPI_OK); 394*2264Sjacobs } 395*2264Sjacobs 396*2264Sjacobs papi_attribute_t * 397*2264Sjacobs papiAttributeListFind(papi_attribute_t **list, char *name) 398*2264Sjacobs { 399*2264Sjacobs int i; 400*2264Sjacobs if ((list == NULL) || (name == NULL)) 401*2264Sjacobs return (NULL); 402*2264Sjacobs 403*2264Sjacobs for (i = 0; list[i] != NULL; i++) 404*2264Sjacobs if (strcasecmp(list[i]->name, name) == 0) 405*2264Sjacobs return ((papi_attribute_t *)list[i]); 406*2264Sjacobs 407*2264Sjacobs return (NULL); 408*2264Sjacobs } 409*2264Sjacobs 410*2264Sjacobs papi_attribute_t * 411*2264Sjacobs papiAttributeListGetNext(papi_attribute_t **list, void **iter) 412*2264Sjacobs { 413*2264Sjacobs papi_attribute_t **tmp, *result; 414*2264Sjacobs 415*2264Sjacobs if ((list == NULL) && (iter == NULL)) 416*2264Sjacobs return (NULL); 417*2264Sjacobs 418*2264Sjacobs if (*iter == NULL) 419*2264Sjacobs *iter = list; 420*2264Sjacobs 421*2264Sjacobs tmp = *iter; 422*2264Sjacobs result = *tmp; 423*2264Sjacobs *iter = ++tmp; 424*2264Sjacobs 425*2264Sjacobs return (result); 426*2264Sjacobs } 427*2264Sjacobs 428*2264Sjacobs papi_status_t 429*2264Sjacobs papiAttributeListGetValue(papi_attribute_t **list, void **iter, 430*2264Sjacobs char *name, papi_attribute_value_type_t type, 431*2264Sjacobs papi_attribute_value_t **value) 432*2264Sjacobs { 433*2264Sjacobs papi_attribute_value_t **tmp; 434*2264Sjacobs void *fodder = NULL; 435*2264Sjacobs 436*2264Sjacobs if ((list == NULL) || ((name == NULL) && (iter == NULL)) || 437*2264Sjacobs (value == NULL)) 438*2264Sjacobs return (PAPI_BAD_ARGUMENT); 439*2264Sjacobs 440*2264Sjacobs if (iter == NULL) 441*2264Sjacobs iter = &fodder; 442*2264Sjacobs 443*2264Sjacobs if ((iter == NULL) || (*iter == NULL)) { 444*2264Sjacobs papi_attribute_t *attr = papiAttributeListFind(list, name); 445*2264Sjacobs 446*2264Sjacobs if (attr == NULL) 447*2264Sjacobs return (PAPI_NOT_FOUND); 448*2264Sjacobs 449*2264Sjacobs if (attr->type != type) 450*2264Sjacobs return (PAPI_NOT_POSSIBLE); 451*2264Sjacobs 452*2264Sjacobs tmp = attr->values; 453*2264Sjacobs } else 454*2264Sjacobs tmp = *iter; 455*2264Sjacobs 456*2264Sjacobs if (tmp == NULL) 457*2264Sjacobs return (PAPI_NOT_FOUND); 458*2264Sjacobs 459*2264Sjacobs *value = *tmp; 460*2264Sjacobs *iter = ++tmp; 461*2264Sjacobs 462*2264Sjacobs if (*value == NULL) 463*2264Sjacobs return (PAPI_GONE); 464*2264Sjacobs 465*2264Sjacobs return (PAPI_OK); 466*2264Sjacobs } 467*2264Sjacobs 468*2264Sjacobs papi_status_t 469*2264Sjacobs papiAttributeListGetString(papi_attribute_t **list, void **iter, 470*2264Sjacobs char *name, char **vptr) 471*2264Sjacobs { 472*2264Sjacobs papi_status_t status; 473*2264Sjacobs papi_attribute_value_t *value = NULL; 474*2264Sjacobs 475*2264Sjacobs if (vptr == NULL) 476*2264Sjacobs return (PAPI_BAD_ARGUMENT); 477*2264Sjacobs 478*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 479*2264Sjacobs PAPI_STRING, &value); 480*2264Sjacobs if (status == PAPI_OK) 481*2264Sjacobs *vptr = value->string; 482*2264Sjacobs 483*2264Sjacobs return (status); 484*2264Sjacobs } 485*2264Sjacobs 486*2264Sjacobs papi_status_t 487*2264Sjacobs papiAttributeListGetInteger(papi_attribute_t **list, void **iter, 488*2264Sjacobs char *name, int *vptr) 489*2264Sjacobs { 490*2264Sjacobs papi_status_t status; 491*2264Sjacobs papi_attribute_value_t *value = NULL; 492*2264Sjacobs 493*2264Sjacobs if (vptr == NULL) 494*2264Sjacobs return (PAPI_BAD_ARGUMENT); 495*2264Sjacobs 496*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 497*2264Sjacobs PAPI_INTEGER, &value); 498*2264Sjacobs if (status == PAPI_OK) 499*2264Sjacobs *vptr = value->integer; 500*2264Sjacobs 501*2264Sjacobs return (status); 502*2264Sjacobs } 503*2264Sjacobs 504*2264Sjacobs papi_status_t 505*2264Sjacobs papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, 506*2264Sjacobs char *name, char *vptr) 507*2264Sjacobs { 508*2264Sjacobs papi_status_t status; 509*2264Sjacobs papi_attribute_value_t *value = NULL; 510*2264Sjacobs 511*2264Sjacobs if (vptr == NULL) 512*2264Sjacobs return (PAPI_BAD_ARGUMENT); 513*2264Sjacobs 514*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 515*2264Sjacobs PAPI_BOOLEAN, &value); 516*2264Sjacobs if (status == PAPI_OK) 517*2264Sjacobs *vptr = value->boolean; 518*2264Sjacobs 519*2264Sjacobs return (status); 520*2264Sjacobs } 521*2264Sjacobs 522*2264Sjacobs papi_status_t 523*2264Sjacobs papiAttributeListGetRange(papi_attribute_t **list, void **iter, 524*2264Sjacobs char *name, int *min, int *max) 525*2264Sjacobs { 526*2264Sjacobs papi_status_t status; 527*2264Sjacobs papi_attribute_value_t *value = NULL; 528*2264Sjacobs 529*2264Sjacobs if ((min == NULL) || (max == NULL)) 530*2264Sjacobs return (PAPI_BAD_ARGUMENT); 531*2264Sjacobs 532*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 533*2264Sjacobs PAPI_RANGE, &value); 534*2264Sjacobs if (status == PAPI_OK) { 535*2264Sjacobs *min = value->range.lower; 536*2264Sjacobs *max = value->range.upper; 537*2264Sjacobs } 538*2264Sjacobs 539*2264Sjacobs return (status); 540*2264Sjacobs } 541*2264Sjacobs 542*2264Sjacobs papi_status_t 543*2264Sjacobs papiAttributeListGetResolution(papi_attribute_t **list, void **iter, 544*2264Sjacobs char *name, int *x, int *y, 545*2264Sjacobs papi_resolution_unit_t *units) 546*2264Sjacobs { 547*2264Sjacobs papi_status_t status; 548*2264Sjacobs papi_attribute_value_t *value = NULL; 549*2264Sjacobs 550*2264Sjacobs if ((x == NULL) || (y == NULL) || (units == NULL)) 551*2264Sjacobs return (PAPI_BAD_ARGUMENT); 552*2264Sjacobs 553*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 554*2264Sjacobs PAPI_RESOLUTION, &value); 555*2264Sjacobs if (status == PAPI_OK) { 556*2264Sjacobs *x = value->resolution.xres; 557*2264Sjacobs *y = value->resolution.yres; 558*2264Sjacobs *units = value->resolution.units; 559*2264Sjacobs } 560*2264Sjacobs 561*2264Sjacobs return (status); 562*2264Sjacobs } 563*2264Sjacobs 564*2264Sjacobs papi_status_t 565*2264Sjacobs papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, 566*2264Sjacobs char *name, time_t *dt) 567*2264Sjacobs { 568*2264Sjacobs papi_status_t status; 569*2264Sjacobs papi_attribute_value_t *value = NULL; 570*2264Sjacobs 571*2264Sjacobs if (dt == NULL) 572*2264Sjacobs return (PAPI_BAD_ARGUMENT); 573*2264Sjacobs 574*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 575*2264Sjacobs PAPI_DATETIME, &value); 576*2264Sjacobs if (status == PAPI_OK) { 577*2264Sjacobs *dt = value->datetime; 578*2264Sjacobs } 579*2264Sjacobs 580*2264Sjacobs return (status); 581*2264Sjacobs } 582*2264Sjacobs 583*2264Sjacobs papi_status_t 584*2264Sjacobs papiAttributeListGetCollection(papi_attribute_t **list, void **iter, 585*2264Sjacobs char *name, papi_attribute_t ***collection) 586*2264Sjacobs { 587*2264Sjacobs papi_status_t status; 588*2264Sjacobs papi_attribute_value_t *value = NULL; 589*2264Sjacobs 590*2264Sjacobs if (collection == NULL) 591*2264Sjacobs return (PAPI_BAD_ARGUMENT); 592*2264Sjacobs 593*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 594*2264Sjacobs PAPI_COLLECTION, &value); 595*2264Sjacobs if (status == PAPI_OK) { 596*2264Sjacobs *collection = value->collection; 597*2264Sjacobs } 598*2264Sjacobs 599*2264Sjacobs return (status); 600*2264Sjacobs } 601*2264Sjacobs 602*2264Sjacobs papi_status_t 603*2264Sjacobs papiAttributeListGetMetadata(papi_attribute_t **list, void **iter, 604*2264Sjacobs char *name, papi_metadata_t *vptr) 605*2264Sjacobs { 606*2264Sjacobs papi_status_t status; 607*2264Sjacobs papi_attribute_value_t *value = NULL; 608*2264Sjacobs 609*2264Sjacobs if (vptr == NULL) 610*2264Sjacobs return (PAPI_BAD_ARGUMENT); 611*2264Sjacobs 612*2264Sjacobs status = papiAttributeListGetValue(list, iter, name, 613*2264Sjacobs PAPI_METADATA, &value); 614*2264Sjacobs if (status == PAPI_OK) 615*2264Sjacobs *vptr = value->metadata; 616*2264Sjacobs 617*2264Sjacobs return (status); 618*2264Sjacobs } 619*2264Sjacobs 620*2264Sjacobs /* 621*2264Sjacobs * Description: The given string contains one or more attributes, in the 622*2264Sjacobs * following form: 623*2264Sjacobs * "aaaa=true bbbbb=1 ccccc=abcd" 624*2264Sjacobs * extract the next attribute from that string; the 'next' 625*2264Sjacobs * parameter should be set to zero to extract the first attribute 626*2264Sjacobs * in the string. 627*2264Sjacobs * 628*2264Sjacobs */ 629*2264Sjacobs 630*2264Sjacobs static char * 631*2264Sjacobs _getNextAttr(char *string, int *next) 632*2264Sjacobs 633*2264Sjacobs { 634*2264Sjacobs char *result = NULL; 635*2264Sjacobs char *start = (char *)string + *next; 636*2264Sjacobs char *nl = NULL; 637*2264Sjacobs char *sp = NULL; 638*2264Sjacobs char *tab = NULL; 639*2264Sjacobs char *val = NULL; 640*2264Sjacobs int len = 0; 641*2264Sjacobs 642*2264Sjacobs if ((string != NULL) && (*start != '\0')) { 643*2264Sjacobs while ((*start == ' ') || (*start == '\t') || (*start == '\n')) 644*2264Sjacobs { 645*2264Sjacobs start++; 646*2264Sjacobs } 647*2264Sjacobs nl = strchr(start, '\n'); 648*2264Sjacobs sp = strchr(start, ' '); 649*2264Sjacobs tab = strchr(start, '\t'); 650*2264Sjacobs 651*2264Sjacobs val = strchr(start, '='); 652*2264Sjacobs 653*2264Sjacobs if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) { 654*2264Sjacobs val = strchr(&val[2], val[1]); 655*2264Sjacobs if (val != NULL) { 656*2264Sjacobs nl = strchr(&val[1], '\n'); 657*2264Sjacobs sp = strchr(&val[1], ' '); 658*2264Sjacobs tab = strchr(&val[1], '\t'); 659*2264Sjacobs } 660*2264Sjacobs } 661*2264Sjacobs 662*2264Sjacobs if ((nl != NULL) && 663*2264Sjacobs ((sp == NULL) || ((sp != NULL) && (nl < sp))) && 664*2264Sjacobs ((tab == NULL) || ((tab != NULL) && (nl < tab)))) { 665*2264Sjacobs len = nl-start; 666*2264Sjacobs } else if ((sp != NULL) && (tab != NULL) && (sp > tab)) { 667*2264Sjacobs len = tab-start; 668*2264Sjacobs } else if ((sp != NULL) && (sp != NULL)) { 669*2264Sjacobs len = sp-start; 670*2264Sjacobs } else if ((tab != NULL) && (tab != NULL)) { 671*2264Sjacobs len = tab-start; 672*2264Sjacobs } 673*2264Sjacobs 674*2264Sjacobs if (len == 0) { 675*2264Sjacobs len = strlen(start); 676*2264Sjacobs } 677*2264Sjacobs 678*2264Sjacobs if (len > 0) { 679*2264Sjacobs result = (char *)malloc(len+1); 680*2264Sjacobs if (result != NULL) { 681*2264Sjacobs strncpy(result, start, len); 682*2264Sjacobs result[len] = '\0'; 683*2264Sjacobs *next = (start-string)+len; 684*2264Sjacobs } 685*2264Sjacobs } 686*2264Sjacobs } 687*2264Sjacobs 688*2264Sjacobs return (result); 689*2264Sjacobs } /* _getNextAttr() */ 690*2264Sjacobs 691*2264Sjacobs 692*2264Sjacobs /* 693*2264Sjacobs * Description: Parse the given attribute string value and transform it into 694*2264Sjacobs * the papi_attribute_value_t in the papi_attribute_t structure. 695*2264Sjacobs * 696*2264Sjacobs */ 697*2264Sjacobs 698*2264Sjacobs static papi_status_t 699*2264Sjacobs _parseAttrValue(char *value, papi_attribute_t *attr) 700*2264Sjacobs 701*2264Sjacobs { 702*2264Sjacobs papi_status_t result = PAPI_OK; 703*2264Sjacobs int len = 0; 704*2264Sjacobs int i = 0; 705*2264Sjacobs char *papiString = NULL; 706*2264Sjacobs char *tmp1 = NULL; 707*2264Sjacobs char *tmp2 = NULL; 708*2264Sjacobs char *tmp3 = NULL; 709*2264Sjacobs papi_attribute_value_t **avalues = NULL; 710*2264Sjacobs 711*2264Sjacobs avalues = malloc(sizeof (papi_attribute_value_t *) * 2); 712*2264Sjacobs if (avalues == NULL) { 713*2264Sjacobs result = PAPI_TEMPORARY_ERROR; 714*2264Sjacobs return (result); 715*2264Sjacobs } 716*2264Sjacobs avalues[0] = malloc(sizeof (papi_attribute_value_t)); 717*2264Sjacobs avalues[1] = NULL; 718*2264Sjacobs if (avalues[0] == NULL) { 719*2264Sjacobs free(avalues); 720*2264Sjacobs result = PAPI_TEMPORARY_ERROR; 721*2264Sjacobs return (result); 722*2264Sjacobs } 723*2264Sjacobs 724*2264Sjacobs 725*2264Sjacobs /* 726*2264Sjacobs * TODO - need to sort out 'resolution', 'dateandtime' & 'collection' values 727*2264Sjacobs */ 728*2264Sjacobs if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) { 729*2264Sjacobs 730*2264Sjacobs len = strlen(value); 731*2264Sjacobs if ((len >= 2) && (((value[0] == '"') && 732*2264Sjacobs (value[len-1] == '"')) || ((value[0] == '\'') && 733*2264Sjacobs (value[len-1] == '\'')))) { 734*2264Sjacobs /* string value */ 735*2264Sjacobs attr->type = PAPI_STRING; 736*2264Sjacobs 737*2264Sjacobs papiString = strdup(value+1); 738*2264Sjacobs if (papiString != NULL) { 739*2264Sjacobs papiString[strlen(papiString)-1] = '\0'; 740*2264Sjacobs avalues[0]->string = papiString; 741*2264Sjacobs } else { 742*2264Sjacobs result = PAPI_TEMPORARY_ERROR; 743*2264Sjacobs } 744*2264Sjacobs } else if ((strcasecmp(value, "true") == 0) || 745*2264Sjacobs (strcasecmp(value, "YES") == 0)) { 746*2264Sjacobs /* boolean = true */ 747*2264Sjacobs attr->type = PAPI_BOOLEAN; 748*2264Sjacobs avalues[0]->boolean = PAPI_TRUE; 749*2264Sjacobs } else if ((strcasecmp(value, "false") == 0) || 750*2264Sjacobs (strcasecmp(value, "NO") == 0)) { 751*2264Sjacobs /* boolean = false */ 752*2264Sjacobs attr->type = PAPI_BOOLEAN; 753*2264Sjacobs avalues[0]->boolean = PAPI_FALSE; 754*2264Sjacobs } else { 755*2264Sjacobs /* is value an integer or a range ? */ 756*2264Sjacobs 757*2264Sjacobs i = 0; 758*2264Sjacobs attr->type = PAPI_INTEGER; 759*2264Sjacobs tmp1 = strdup(value); 760*2264Sjacobs while (((value[i] >= '0') && (value[i] <= '9')) || 761*2264Sjacobs (value[i] == '-')) { 762*2264Sjacobs if (value[i] == '-') { 763*2264Sjacobs tmp1[i] = '\0'; 764*2264Sjacobs tmp2 = &tmp1[i+1]; 765*2264Sjacobs attr->type = PAPI_RANGE; 766*2264Sjacobs } 767*2264Sjacobs 768*2264Sjacobs i++; 769*2264Sjacobs } 770*2264Sjacobs 771*2264Sjacobs if (strlen(value) == i) { 772*2264Sjacobs if (attr->type == PAPI_RANGE) { 773*2264Sjacobs avalues[0]->range.lower = atoi(tmp1); 774*2264Sjacobs avalues[0]->range.upper = atoi(tmp2); 775*2264Sjacobs } else { 776*2264Sjacobs avalues[0]->integer = atoi(value); 777*2264Sjacobs } 778*2264Sjacobs } else { 779*2264Sjacobs /* is value a resolution ? */ 780*2264Sjacobs i = 0; 781*2264Sjacobs attr->type = PAPI_INTEGER; 782*2264Sjacobs tmp1 = strdup(value); 783*2264Sjacobs while (((value[i] >= '0') && 784*2264Sjacobs (value[i] <= '9')) || 785*2264Sjacobs (value[i] == 'x')) { 786*2264Sjacobs if (value[i] == 'x') { 787*2264Sjacobs tmp1[i] = '\0'; 788*2264Sjacobs if (attr->type == PAPI_INTEGER) 789*2264Sjacobs { 790*2264Sjacobs tmp2 = &tmp1[i+1]; 791*2264Sjacobs attr->type = 792*2264Sjacobs PAPI_RESOLUTION; 793*2264Sjacobs } else { 794*2264Sjacobs tmp3 = &tmp1[i+1]; 795*2264Sjacobs } 796*2264Sjacobs } 797*2264Sjacobs 798*2264Sjacobs i++; 799*2264Sjacobs } 800*2264Sjacobs 801*2264Sjacobs if (strlen(value) == i) { 802*2264Sjacobs if (attr->type == PAPI_RESOLUTION) { 803*2264Sjacobs avalues[0]->resolution.xres = 804*2264Sjacobs atoi(tmp1); 805*2264Sjacobs avalues[0]->resolution.yres = 806*2264Sjacobs atoi(tmp2); 807*2264Sjacobs if (tmp3 != NULL) { 808*2264Sjacobs avalues[0]-> 809*2264Sjacobs resolution.units = 810*2264Sjacobs atoi(tmp3); 811*2264Sjacobs } else { 812*2264Sjacobs avalues[0]-> 813*2264Sjacobs resolution.units = 0; 814*2264Sjacobs } 815*2264Sjacobs } 816*2264Sjacobs } 817*2264Sjacobs 818*2264Sjacobs if (attr->type != PAPI_RESOLUTION) { 819*2264Sjacobs attr->type = PAPI_STRING; 820*2264Sjacobs avalues[0]->string = strdup(value); 821*2264Sjacobs if (avalues[0]->string == NULL) { 822*2264Sjacobs result = PAPI_TEMPORARY_ERROR; 823*2264Sjacobs } 824*2264Sjacobs } 825*2264Sjacobs } 826*2264Sjacobs free(tmp1); 827*2264Sjacobs } 828*2264Sjacobs 829*2264Sjacobs } else { 830*2264Sjacobs result = PAPI_BAD_ARGUMENT; 831*2264Sjacobs } 832*2264Sjacobs 833*2264Sjacobs if (result != PAPI_OK) { 834*2264Sjacobs i = 0; 835*2264Sjacobs while (avalues[i] != NULL) { 836*2264Sjacobs free(avalues[i]); 837*2264Sjacobs i++; 838*2264Sjacobs } 839*2264Sjacobs free(avalues); 840*2264Sjacobs } else { 841*2264Sjacobs attr->values = avalues; 842*2264Sjacobs } 843*2264Sjacobs 844*2264Sjacobs return (result); 845*2264Sjacobs } /* _parseAttrValue() */ 846*2264Sjacobs 847*2264Sjacobs 848*2264Sjacobs /* 849*2264Sjacobs * Description: Parse the given attribute string and transform it into the 850*2264Sjacobs * papi_attribute_t structure. 851*2264Sjacobs * 852*2264Sjacobs */ 853*2264Sjacobs 854*2264Sjacobs static papi_status_t 855*2264Sjacobs _parseAttributeString(char *attrString, papi_attribute_t *attr) 856*2264Sjacobs 857*2264Sjacobs { 858*2264Sjacobs papi_status_t result = PAPI_OK; 859*2264Sjacobs char *string = NULL; 860*2264Sjacobs char *p = NULL; 861*2264Sjacobs papi_attribute_value_t **avalues = NULL; 862*2264Sjacobs 863*2264Sjacobs if ((attrString != NULL) && (strlen(attrString) >= 3) && 864*2264Sjacobs (attr != NULL)) { 865*2264Sjacobs attr->name = NULL; 866*2264Sjacobs string = strdup(attrString); 867*2264Sjacobs if (string != NULL) { 868*2264Sjacobs p = strchr(string, '='); 869*2264Sjacobs if (p != NULL) { 870*2264Sjacobs *p = '\0'; 871*2264Sjacobs attr->name = string; 872*2264Sjacobs p++; /* pointer to value */ 873*2264Sjacobs 874*2264Sjacobs result = _parseAttrValue(p, attr); 875*2264Sjacobs } else { 876*2264Sjacobs char value; 877*2264Sjacobs /* boolean - no value so assume 'true' */ 878*2264Sjacobs if (strncasecmp(string, "no", 2) == 0) { 879*2264Sjacobs string += 2; 880*2264Sjacobs value = PAPI_FALSE; 881*2264Sjacobs } else 882*2264Sjacobs value = PAPI_TRUE; 883*2264Sjacobs 884*2264Sjacobs attr->name = string; 885*2264Sjacobs attr->type = PAPI_BOOLEAN; 886*2264Sjacobs 887*2264Sjacobs avalues = malloc( 888*2264Sjacobs sizeof (papi_attribute_value_t *) * 2); 889*2264Sjacobs if (avalues == NULL) { 890*2264Sjacobs result = PAPI_TEMPORARY_ERROR; 891*2264Sjacobs } else { 892*2264Sjacobs avalues[0] = malloc( 893*2264Sjacobs sizeof (papi_attribute_value_t)); 894*2264Sjacobs avalues[1] = NULL; 895*2264Sjacobs if (avalues[0] == NULL) { 896*2264Sjacobs free(avalues); 897*2264Sjacobs result = PAPI_TEMPORARY_ERROR; 898*2264Sjacobs } else { 899*2264Sjacobs avalues[0]->boolean = value; 900*2264Sjacobs attr->values = avalues; 901*2264Sjacobs } 902*2264Sjacobs } 903*2264Sjacobs } 904*2264Sjacobs } 905*2264Sjacobs } else { 906*2264Sjacobs result = PAPI_BAD_ARGUMENT; 907*2264Sjacobs } 908*2264Sjacobs 909*2264Sjacobs return (result); 910*2264Sjacobs } /* _parseAttributeString() */ 911*2264Sjacobs 912*2264Sjacobs 913*2264Sjacobs papi_status_t 914*2264Sjacobs papiAttributeListFromString(papi_attribute_t ***attrs, 915*2264Sjacobs int flags, char *string) 916*2264Sjacobs { 917*2264Sjacobs papi_status_t result = PAPI_OK; 918*2264Sjacobs int next = 0; 919*2264Sjacobs char *attrString = NULL; 920*2264Sjacobs papi_attribute_t attr; 921*2264Sjacobs 922*2264Sjacobs if ((attrs != NULL) && (string != NULL) && 923*2264Sjacobs ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) 924*2264Sjacobs == 0)) { 925*2264Sjacobs attrString = _getNextAttr(string, &next); 926*2264Sjacobs while ((result == PAPI_OK) && (attrString != NULL)) { 927*2264Sjacobs result = _parseAttributeString(attrString, &attr); 928*2264Sjacobs if ((result == PAPI_OK) && (attr.name != NULL)) { 929*2264Sjacobs /* add this attribute to the list */ 930*2264Sjacobs if ((attr.values != NULL) && 931*2264Sjacobs (attr.values[0] != NULL)) { 932*2264Sjacobs result = papiAttributeListAddValue( 933*2264Sjacobs attrs, PAPI_ATTR_APPEND, 934*2264Sjacobs attr.name, attr.type, 935*2264Sjacobs attr.values[0]); 936*2264Sjacobs free(attr.values[0]); 937*2264Sjacobs free(attr.values); 938*2264Sjacobs } else { 939*2264Sjacobs result = PAPI_TEMPORARY_ERROR; 940*2264Sjacobs } 941*2264Sjacobs } 942*2264Sjacobs free(attrString); 943*2264Sjacobs 944*2264Sjacobs attrString = _getNextAttr(string, &next); 945*2264Sjacobs } 946*2264Sjacobs } 947*2264Sjacobs else 948*2264Sjacobs { 949*2264Sjacobs result = PAPI_BAD_ARGUMENT; 950*2264Sjacobs } 951*2264Sjacobs 952*2264Sjacobs return (result); 953*2264Sjacobs } 954*2264Sjacobs 955*2264Sjacobs static papi_status_t 956*2264Sjacobs papiAttributeToString(papi_attribute_t *attribute, char *delim, 957*2264Sjacobs char *buffer, size_t buflen) 958*2264Sjacobs { 959*2264Sjacobs papi_attribute_value_t **values = attribute->values; 960*2264Sjacobs int rc, i; 961*2264Sjacobs 962*2264Sjacobs strlcat(buffer, attribute->name, buflen); 963*2264Sjacobs strlcat(buffer, "=", buflen); 964*2264Sjacobs 965*2264Sjacobs if (values == NULL) 966*2264Sjacobs return (PAPI_OK); 967*2264Sjacobs 968*2264Sjacobs for (i = 0; values[i] != NULL; i++) { 969*2264Sjacobs switch (attribute->type) { 970*2264Sjacobs case PAPI_STRING: 971*2264Sjacobs rc = strlcat(buffer, values[i]->string, buflen); 972*2264Sjacobs break; 973*2264Sjacobs case PAPI_INTEGER: { 974*2264Sjacobs char string[24]; 975*2264Sjacobs 976*2264Sjacobs snprintf(string, sizeof (string), "%d", 977*2264Sjacobs values[i]->integer); 978*2264Sjacobs rc = strlcat(buffer, string, buflen); 979*2264Sjacobs } 980*2264Sjacobs break; 981*2264Sjacobs case PAPI_BOOLEAN: 982*2264Sjacobs rc = strlcat(buffer, (values[i]->boolean ? "true" : 983*2264Sjacobs "false"), buflen); 984*2264Sjacobs break; 985*2264Sjacobs case PAPI_RANGE: { 986*2264Sjacobs char string[24]; 987*2264Sjacobs 988*2264Sjacobs snprintf(string, sizeof (string), "%d-%d", 989*2264Sjacobs values[i]->range.lower, values[i]->range.upper); 990*2264Sjacobs rc = strlcat(buffer, string, buflen); 991*2264Sjacobs } 992*2264Sjacobs break; 993*2264Sjacobs case PAPI_RESOLUTION: { 994*2264Sjacobs char string[24]; 995*2264Sjacobs 996*2264Sjacobs snprintf(string, sizeof (string), "%dx%ddp%c", 997*2264Sjacobs values[i]->resolution.xres, 998*2264Sjacobs values[i]->resolution.yres, 999*2264Sjacobs (values[i]->resolution.units == PAPI_RES_PER_CM 1000*2264Sjacobs ? 'c' : 'i')); 1001*2264Sjacobs rc = strlcat(buffer, string, buflen); 1002*2264Sjacobs } 1003*2264Sjacobs break; 1004*2264Sjacobs case PAPI_DATETIME: { 1005*2264Sjacobs struct tm *tm = localtime(&values[i]->datetime); 1006*2264Sjacobs 1007*2264Sjacobs if (tm != NULL) { 1008*2264Sjacobs char string[64]; 1009*2264Sjacobs 1010*2264Sjacobs strftime(string, sizeof (string), "%C", tm); 1011*2264Sjacobs rc = strlcat(buffer, string, buflen); 1012*2264Sjacobs }} 1013*2264Sjacobs break; 1014*2264Sjacobs case PAPI_COLLECTION: { 1015*2264Sjacobs char *string = alloca(buflen); 1016*2264Sjacobs #ifdef DEBUG 1017*2264Sjacobs char prefix[256]; 1018*2264Sjacobs 1019*2264Sjacobs snprintf(prefix, sizeof (prefix), "%s %s(%d) ", delim, 1020*2264Sjacobs attribute->name, i); 1021*2264Sjacobs 1022*2264Sjacobs papiAttributeListToString(values[i]->collection, 1023*2264Sjacobs prefix, string, buflen); 1024*2264Sjacobs #else 1025*2264Sjacobs papiAttributeListToString(values[i]->collection, 1026*2264Sjacobs delim, string, buflen); 1027*2264Sjacobs #endif 1028*2264Sjacobs rc = strlcat(buffer, string, buflen); 1029*2264Sjacobs } 1030*2264Sjacobs break; 1031*2264Sjacobs default: { 1032*2264Sjacobs char string[32]; 1033*2264Sjacobs 1034*2264Sjacobs snprintf(string, sizeof (string), "unknown-type-0x%x", 1035*2264Sjacobs attribute->type); 1036*2264Sjacobs rc = strlcat(buffer, string, buflen); 1037*2264Sjacobs } 1038*2264Sjacobs } 1039*2264Sjacobs if (values[i+1] != NULL) 1040*2264Sjacobs rc = strlcat(buffer, ",", buflen); 1041*2264Sjacobs 1042*2264Sjacobs if (rc >= buflen) 1043*2264Sjacobs return (PAPI_NOT_POSSIBLE); 1044*2264Sjacobs 1045*2264Sjacobs } 1046*2264Sjacobs 1047*2264Sjacobs return (PAPI_OK); 1048*2264Sjacobs } 1049*2264Sjacobs 1050*2264Sjacobs papi_status_t 1051*2264Sjacobs papiAttributeListToString(papi_attribute_t **attrs, 1052*2264Sjacobs char *delim, char *buffer, size_t buflen) 1053*2264Sjacobs { 1054*2264Sjacobs papi_status_t status = PAPI_OK; 1055*2264Sjacobs int i; 1056*2264Sjacobs 1057*2264Sjacobs if ((attrs == NULL) || (buffer == NULL)) 1058*2264Sjacobs return (PAPI_BAD_ARGUMENT); 1059*2264Sjacobs 1060*2264Sjacobs buffer[0] = '\0'; 1061*2264Sjacobs if (!delim) 1062*2264Sjacobs delim = " "; 1063*2264Sjacobs 1064*2264Sjacobs #ifdef DEBUG 1065*2264Sjacobs strlcat(buffer, delim, buflen); 1066*2264Sjacobs #endif 1067*2264Sjacobs for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) { 1068*2264Sjacobs status = papiAttributeToString(attrs[i], delim, buffer, buflen); 1069*2264Sjacobs if (attrs[i+1] != NULL) 1070*2264Sjacobs strlcat(buffer, delim, buflen); 1071*2264Sjacobs } 1072*2264Sjacobs 1073*2264Sjacobs return (status); 1074*2264Sjacobs } 1075*2264Sjacobs 1076*2264Sjacobs static int 1077*2264Sjacobs is_in_list(char *value, char **list) 1078*2264Sjacobs { 1079*2264Sjacobs if ((list != NULL) && (value != NULL)) { 1080*2264Sjacobs int i; 1081*2264Sjacobs 1082*2264Sjacobs for (i = 0; list[i] != NULL; i++) 1083*2264Sjacobs if (strcasecmp(value, list[i]) == 0) 1084*2264Sjacobs return (0); 1085*2264Sjacobs } 1086*2264Sjacobs 1087*2264Sjacobs return (1); 1088*2264Sjacobs } 1089*2264Sjacobs 1090*2264Sjacobs static papi_status_t 1091*2264Sjacobs copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute) 1092*2264Sjacobs { 1093*2264Sjacobs papi_status_t status; 1094*2264Sjacobs int i = 0; 1095*2264Sjacobs 1096*2264Sjacobs if ((list == NULL) || (attribute == NULL) || 1097*2264Sjacobs (attribute->values == NULL)) 1098*2264Sjacobs return (PAPI_BAD_ARGUMENT); 1099*2264Sjacobs 1100*2264Sjacobs for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL, 1101*2264Sjacobs attribute->name, attribute->type, 1102*2264Sjacobs attribute->values[i]); 1103*2264Sjacobs ((status == PAPI_OK) && (attribute->values[i] != NULL)); 1104*2264Sjacobs status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND, 1105*2264Sjacobs attribute->name, attribute->type, 1106*2264Sjacobs attribute->values[i])) 1107*2264Sjacobs i++; 1108*2264Sjacobs 1109*2264Sjacobs return (status); 1110*2264Sjacobs } 1111*2264Sjacobs 1112*2264Sjacobs void 1113*2264Sjacobs copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes) 1114*2264Sjacobs { 1115*2264Sjacobs int i; 1116*2264Sjacobs 1117*2264Sjacobs if ((result == NULL) || (attributes == NULL)) 1118*2264Sjacobs return; 1119*2264Sjacobs 1120*2264Sjacobs for (i = 0; attributes[i] != NULL; i++) 1121*2264Sjacobs copy_attribute(result, attributes[i]); 1122*2264Sjacobs } 1123*2264Sjacobs 1124*2264Sjacobs void 1125*2264Sjacobs split_and_copy_attributes(char **list, papi_attribute_t **attributes, 1126*2264Sjacobs papi_attribute_t ***in, papi_attribute_t ***out) 1127*2264Sjacobs { 1128*2264Sjacobs int i; 1129*2264Sjacobs 1130*2264Sjacobs if ((list == NULL) || (attributes == NULL)) 1131*2264Sjacobs return; 1132*2264Sjacobs 1133*2264Sjacobs for (i = 0; attributes[i] != NULL; i++) 1134*2264Sjacobs if (is_in_list(attributes[i]->name, list) == 0) 1135*2264Sjacobs copy_attribute(in, attributes[i]); 1136*2264Sjacobs else 1137*2264Sjacobs copy_attribute(out, attributes[i]); 1138*2264Sjacobs } 1139*2264Sjacobs 1140*2264Sjacobs void 1141*2264Sjacobs papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes, 1142*2264Sjacobs char *prefix_fmt, ...) 1143*2264Sjacobs { 1144*2264Sjacobs char *prefix = NULL; 1145*2264Sjacobs char *buffer = NULL; 1146*2264Sjacobs char *newfmt = NULL; 1147*2264Sjacobs void *mem; 1148*2264Sjacobs ssize_t size = 0; 1149*2264Sjacobs va_list ap; 1150*2264Sjacobs 1151*2264Sjacobs newfmt = malloc(strlen(prefix_fmt) + 2); 1152*2264Sjacobs sprintf(newfmt, "\n%s", prefix_fmt); 1153*2264Sjacobs 1154*2264Sjacobs va_start(ap, prefix_fmt); 1155*2264Sjacobs while (vsnprintf(prefix, size, newfmt, ap) > size) { 1156*2264Sjacobs size += 1024; 1157*2264Sjacobs mem = realloc(prefix, size); 1158*2264Sjacobs if (!mem) goto error; 1159*2264Sjacobs prefix = mem; 1160*2264Sjacobs } 1161*2264Sjacobs va_end(ap); 1162*2264Sjacobs 1163*2264Sjacobs if (attributes) { 1164*2264Sjacobs size = 0; 1165*2264Sjacobs while (papiAttributeListToString(attributes, prefix, buffer, 1166*2264Sjacobs size) != PAPI_OK) { 1167*2264Sjacobs size += 1024; 1168*2264Sjacobs mem = realloc(buffer, size); 1169*2264Sjacobs if (!mem) goto error; 1170*2264Sjacobs buffer = mem; 1171*2264Sjacobs } 1172*2264Sjacobs } 1173*2264Sjacobs 1174*2264Sjacobs fprintf(fp, "%s%s\n", prefix, buffer ? buffer : ""); 1175*2264Sjacobs fflush(fp); 1176*2264Sjacobs 1177*2264Sjacobs error: 1178*2264Sjacobs free(newfmt); 1179*2264Sjacobs free(prefix); 1180*2264Sjacobs free(buffer); 1181*2264Sjacobs } 1182