summaryrefslogtreecommitdiff
path: root/usr/src/lib/print/libpapi-common/common/attribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/print/libpapi-common/common/attribute.c')
-rw-r--r--usr/src/lib/print/libpapi-common/common/attribute.c1119
1 files changed, 0 insertions, 1119 deletions
diff --git a/usr/src/lib/print/libpapi-common/common/attribute.c b/usr/src/lib/print/libpapi-common/common/attribute.c
deleted file mode 100644
index 244e54555d..0000000000
--- a/usr/src/lib/print/libpapi-common/common/attribute.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- *
- */
-
-/* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*LINTLIBRARY*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <alloca.h>
-#include <papi.h>
-#include <regex.h>
-
-#define MAX_PAGES 32767
-/*
- * Assuming the maximum number of pages in
- * a document to be 32767
- */
-
-static void papiAttributeFree(papi_attribute_t *attribute);
-
-static void
-papiAttributeValueFree(papi_attribute_value_type_t type,
- papi_attribute_value_t *value)
-{
- if (value != NULL) {
- switch (type) {
- case PAPI_STRING:
- if (value->string != NULL)
- free(value->string);
- break;
- case PAPI_COLLECTION:
- if (value->collection != NULL) {
- int i;
-
- for (i = 0; value->collection[i] != NULL; i++)
- papiAttributeFree(value->collection[i]);
-
- free(value->collection);
- }
- break;
- default: /* don't need to free anything extra */
- break;
- }
-
- free(value);
- }
-}
-
-static void
-papiAttributeValuesFree(papi_attribute_value_type_t type,
- papi_attribute_value_t **values)
-{
- if (values != NULL) {
- int i;
-
- for (i = 0; values[i] != NULL; i++)
- papiAttributeValueFree(type, values[i]);
-
- free(values);
- }
-}
-
-static void
-papiAttributeFree(papi_attribute_t *attribute)
-{
- if (attribute != NULL) {
- if (attribute->name != NULL)
- free(attribute->name);
- if (attribute->values != NULL)
- papiAttributeValuesFree(attribute->type,
- attribute->values);
- free(attribute);
- }
-}
-
-void
-papiAttributeListFree(papi_attribute_t **list)
-{
- if (list != NULL) {
- int i;
-
- for (i = 0; list[i] != NULL; i++)
- papiAttributeFree(list[i]);
-
- free(list);
- }
-}
-
-static papi_attribute_t **
-collection_dup(papi_attribute_t **collection)
-{
- papi_attribute_t **result = NULL;
-
- /* allows a NULL collection that is "empty" or "no value" */
- if (collection != NULL) {
- papi_status_t status = PAPI_OK;
- int i;
-
- for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK));
- i++) {
- papi_attribute_t *a = collection[i];
-
- status = papiAttributeListAddValue(&result,
- PAPI_ATTR_APPEND, a->name, a->type,
- NULL);
- if ((status == PAPI_OK) && (a->values != NULL)) {
- int j;
-
- for (j = 0; ((a->values[j] != NULL) &&
- (status == PAPI_OK)); j++)
- status = papiAttributeListAddValue(
- &result,
- PAPI_ATTR_APPEND,
- a->name, a->type,
- a->values[j]);
- }
- }
- if (status != PAPI_OK) {
- papiAttributeListFree(result);
- result = NULL;
- }
- }
-
- return (result);
-}
-
-static papi_attribute_value_t *
-papiAttributeValueDup(papi_attribute_value_type_t type,
- papi_attribute_value_t *v)
-{
- papi_attribute_value_t *result = NULL;
-
- if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) {
- switch (type) {
- case PAPI_STRING:
- if (v->string == NULL) {
- free(result);
- result = NULL;
- } else
- result->string = strdup(v->string);
- break;
- case PAPI_INTEGER:
- result->integer = v->integer;
- break;
- case PAPI_BOOLEAN:
- result->boolean = v->boolean;
- break;
- case PAPI_RANGE:
- result->range.lower = v->range.lower;
- result->range.upper = v->range.upper;
- break;
- case PAPI_RESOLUTION:
- result->resolution.xres = v->resolution.xres;
- result->resolution.yres = v->resolution.yres;
- result->resolution.units = v->resolution.units;
- break;
- case PAPI_DATETIME:
- result->datetime = v->datetime;
- break;
- case PAPI_COLLECTION:
- result->collection = collection_dup(v->collection);
- break;
- case PAPI_METADATA:
- result->metadata = v->metadata;
- break;
- default: /* unknown type, fail to duplicate */
- free(result);
- result = NULL;
- }
- }
-
- return (result);
-}
-
-static papi_attribute_t *
-papiAttributeAlloc(char *name, papi_attribute_value_type_t type)
-{
- papi_attribute_t *result = NULL;
-
- if ((result = calloc(1, sizeof (*result))) != NULL) {
- result->name = strdup(name);
- result->type = type;
- }
-
- return (result);
-}
-
-static papi_status_t
-papiAttributeListAppendValue(papi_attribute_value_t ***values,
- papi_attribute_value_type_t type,
- papi_attribute_value_t *value)
-{
-
- if (values == NULL)
- return (PAPI_BAD_ARGUMENT);
-
- if (value != NULL) { /* this allows "empty" attributes */
- papi_attribute_value_t *tmp = NULL;
-
- if ((tmp = papiAttributeValueDup(type, value)) == NULL)
- return (PAPI_TEMPORARY_ERROR);
-
- list_append(values, tmp);
- }
-
- return (PAPI_OK);
-}
-
-papi_status_t
-papiAttributeListAddValue(papi_attribute_t ***list, int flgs,
- char *name, papi_attribute_value_type_t type,
- papi_attribute_value_t *value)
-{
- papi_status_t result;
- int flags = flgs;
- papi_attribute_t *attribute = NULL;
- papi_attribute_value_t **values = NULL;
-
- if ((list == NULL) || (name == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- if ((type == PAPI_RANGE) && (value != NULL) &&
- (value->range.lower > value->range.upper))
- return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */
-
- if (flags == 0) /* if it wasn't set, set a default behaviour */
- flags = PAPI_ATTR_APPEND;
-
- /* look for an existing one */
- attribute = papiAttributeListFind(*list, name);
-
- if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL))
- return (PAPI_CONFLICT); /* EXISTS */
-
- if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) &&
- (attribute->type != type))
- return (PAPI_CONFLICT); /* TYPE CONFLICT */
-
- /* if we don't have one, create it and add it to the list */
- if ((attribute == NULL) &&
- ((attribute = papiAttributeAlloc(name, type)) != NULL))
- list_append(list, attribute);
-
- /* if we don't have one by now, it's most likely an alloc fail */
- if (attribute == NULL)
- return (PAPI_TEMPORARY_ERROR);
-
- /*
- * if we are replacing, clear any existing values, but don't free
- * until after we have replaced the values, in case we are replacing
- * a collection with a relocated version of the original collection.
- */
- if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) {
- values = attribute->values;
- attribute->values = NULL;
- }
-
- attribute->type = type;
-
- result = papiAttributeListAppendValue(&attribute->values, type, value);
-
- /* free old values if we replaced them */
- if (values != NULL)
- papiAttributeValuesFree(type, values);
-
- return (result);
-}
-
-papi_status_t
-papiAttributeListAddString(papi_attribute_t ***list, int flags,
- char *name, char *string)
-{
- papi_attribute_value_t v;
-
- v.string = (char *)string;
- return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v));
-}
-
-papi_status_t
-papiAttributeListAddInteger(papi_attribute_t ***list, int flags,
- char *name, int integer)
-{
- papi_attribute_value_t v;
-
- v.integer = integer;
- return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v));
-}
-
-papi_status_t
-papiAttributeListAddBoolean(papi_attribute_t ***list, int flags,
- char *name, char boolean)
-{
- papi_attribute_value_t v;
-
- v.boolean = boolean;
- return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v));
-}
-
-papi_status_t
-papiAttributeListAddRange(papi_attribute_t ***list, int flags,
- char *name, int lower, int upper)
-{
- papi_attribute_value_t v;
-
- v.range.lower = lower;
- v.range.upper = upper;
- return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v));
-}
-
-papi_status_t
-papiAttributeListAddResolution(papi_attribute_t ***list, int flags,
- char *name, int xres, int yres,
- papi_resolution_unit_t units)
-{
- papi_attribute_value_t v;
-
- v.resolution.xres = xres;
- v.resolution.yres = yres;
- v.resolution.units = units;
- return (papiAttributeListAddValue(list, flags, name,
- PAPI_RESOLUTION, &v));
-}
-
-papi_status_t
-papiAttributeListAddDatetime(papi_attribute_t ***list, int flags,
- char *name, time_t datetime)
-{
- papi_attribute_value_t v;
-
- v.datetime = datetime;
- return (papiAttributeListAddValue(list, flags, name,
- PAPI_DATETIME, &v));
-}
-
-papi_status_t
-papiAttributeListAddCollection(papi_attribute_t ***list, int flags,
- char *name, papi_attribute_t **collection)
-{
- papi_attribute_value_t v;
-
- v.collection = (papi_attribute_t **)collection;
- return (papiAttributeListAddValue(list, flags, name,
- PAPI_COLLECTION, &v));
-}
-
-papi_status_t
-papiAttributeListAddMetadata(papi_attribute_t ***list, int flags,
- char *name, papi_metadata_t metadata)
-{
- papi_attribute_value_t v;
-
- v.metadata = metadata;
- return (papiAttributeListAddValue(list, flags, name,
- PAPI_METADATA, &v));
-}
-
-papi_status_t
-papiAttributeListDelete(papi_attribute_t ***list, char *name)
-{
- papi_attribute_t *attribute;
-
- if ((list == NULL) || (name == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- if ((attribute = papiAttributeListFind(*list, name)) == NULL)
- return (PAPI_NOT_FOUND);
-
- list_remove(list, attribute);
- papiAttributeFree(attribute);
-
- return (PAPI_OK);
-}
-
-papi_attribute_t *
-papiAttributeListFind(papi_attribute_t **list, char *name)
-{
- int i;
- if ((list == NULL) || (name == NULL))
- return (NULL);
-
- for (i = 0; list[i] != NULL; i++)
- if (strcasecmp(list[i]->name, name) == 0)
- return ((papi_attribute_t *)list[i]);
-
- return (NULL);
-}
-
-papi_attribute_t *
-papiAttributeListGetNext(papi_attribute_t **list, void **iter)
-{
- papi_attribute_t **tmp, *result;
-
- if ((list == NULL) && (iter == NULL))
- return (NULL);
-
- if (*iter == NULL)
- *iter = list;
-
- tmp = *iter;
- result = *tmp;
- *iter = ++tmp;
-
- return (result);
-}
-
-papi_status_t
-papiAttributeListGetValue(papi_attribute_t **list, void **iter,
- char *name, papi_attribute_value_type_t type,
- papi_attribute_value_t **value)
-{
- papi_attribute_value_t **tmp;
- void *fodder = NULL;
-
- if ((list == NULL) || ((name == NULL) && (iter == NULL)) ||
- (value == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- if (iter == NULL)
- iter = &fodder;
-
- if ((iter == NULL) || (*iter == NULL)) {
- papi_attribute_t *attr = papiAttributeListFind(list, name);
-
- if (attr == NULL)
- return (PAPI_NOT_FOUND);
-
- if (attr->type != type)
- return (PAPI_NOT_POSSIBLE);
-
- tmp = attr->values;
- } else
- tmp = *iter;
-
- if (tmp == NULL)
- return (PAPI_NOT_FOUND);
-
- *value = *tmp;
- *iter = ++tmp;
-
- if (*value == NULL)
- return (PAPI_GONE);
-
- return (PAPI_OK);
-}
-
-papi_status_t
-papiAttributeListGetString(papi_attribute_t **list, void **iter,
- char *name, char **vptr)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if (vptr == NULL)
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_STRING, &value);
- if (status == PAPI_OK)
- *vptr = value->string;
-
- return (status);
-}
-
-papi_status_t
-papiAttributeListGetInteger(papi_attribute_t **list, void **iter,
- char *name, int *vptr)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if (vptr == NULL)
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_INTEGER, &value);
- if (status == PAPI_OK)
- *vptr = value->integer;
-
- return (status);
-}
-
-papi_status_t
-papiAttributeListGetBoolean(papi_attribute_t **list, void **iter,
- char *name, char *vptr)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if (vptr == NULL)
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_BOOLEAN, &value);
- if (status == PAPI_OK)
- *vptr = value->boolean;
-
- return (status);
-}
-
-papi_status_t
-papiAttributeListGetRange(papi_attribute_t **list, void **iter,
- char *name, int *min, int *max)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if ((min == NULL) || (max == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_RANGE, &value);
- if (status == PAPI_OK) {
- *min = value->range.lower;
- *max = value->range.upper;
- }
-
- return (status);
-}
-
-papi_status_t
-papiAttributeListGetResolution(papi_attribute_t **list, void **iter,
- char *name, int *x, int *y,
- papi_resolution_unit_t *units)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if ((x == NULL) || (y == NULL) || (units == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_RESOLUTION, &value);
- if (status == PAPI_OK) {
- *x = value->resolution.xres;
- *y = value->resolution.yres;
- *units = value->resolution.units;
- }
-
- return (status);
-}
-
-papi_status_t
-papiAttributeListGetDatetime(papi_attribute_t **list, void **iter,
- char *name, time_t *dt)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if (dt == NULL)
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_DATETIME, &value);
- if (status == PAPI_OK) {
- *dt = value->datetime;
- }
-
- return (status);
-}
-
-papi_status_t
-papiAttributeListGetCollection(papi_attribute_t **list, void **iter,
- char *name, papi_attribute_t ***collection)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if (collection == NULL)
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_COLLECTION, &value);
- if (status == PAPI_OK) {
- *collection = value->collection;
- }
-
- return (status);
-}
-
-papi_status_t
-papiAttributeListGetMetadata(papi_attribute_t **list, void **iter,
- char *name, papi_metadata_t *vptr)
-{
- papi_status_t status;
- papi_attribute_value_t *value = NULL;
-
- if (vptr == NULL)
- return (PAPI_BAD_ARGUMENT);
-
- status = papiAttributeListGetValue(list, iter, name,
- PAPI_METADATA, &value);
- if (status == PAPI_OK)
- *vptr = value->metadata;
-
- return (status);
-}
-
-
-/* The string is modified by this call */
-static char *
-regvalue(regmatch_t match, char *string)
-{
- char *result = NULL;
- if (match.rm_so != match.rm_eo) {
- result = string + match.rm_so;
- *(result + (match.rm_eo - match.rm_so)) = '\0';
- }
- return (result);
-}
-
-static papi_attribute_value_type_t
-_process_value(char *string, char ***parts)
-{
- int i;
- static struct {
- papi_attribute_value_type_t type;
- size_t vals;
- char *expression;
- int compiled;
- regex_t re;
- } types[] = {
- { PAPI_BOOLEAN, 1, "^(true|false|yes|no)$", 0 },
- { PAPI_COLLECTION, 1, "^\\{(.+)\\}$", 0 },
- /* PAPI_DATETIME is unsupported, too much like an integer */
- { PAPI_INTEGER, 1, "^([+-]{0,1}[[:digit:]]+)$", 0 },
- { PAPI_RANGE, 3, "^([[:digit:]]*)-([[:digit:]]*)$", 0 },
- { PAPI_RESOLUTION, 4, "^([[:digit:]]+)x([[:digit:]]+)dp(i|c)$",
- 0 },
- NULL
- };
- regmatch_t matches[4];
-
- for (i = 0; i < 5; i++) {
- int j;
-
- if (types[i].compiled == 0) {
- (void) regcomp(&(types[i].re), types[i].expression,
- REG_EXTENDED|REG_ICASE);
- types[i].compiled = 1;
- }
- if (regexec(&(types[i].re), string, (size_t)types[i].vals,
- matches, 0) == REG_NOMATCH)
- continue;
-
- for (j = 0 ; j < types[i].vals; j++)
- list_append(parts, regvalue(matches[j], string));
- return (types[i].type);
- }
-
- list_append(parts, string);
- return (PAPI_STRING);
-}
-
-static void
-_add_attribute_value(papi_attribute_value_t ***list,
- papi_attribute_value_type_t type,
- papi_attribute_value_type_t dtype, char **parts)
-{
- papi_attribute_value_t *value = calloc(1, sizeof (*value));
-
- switch(type) {
- case PAPI_STRING:
- value->string = strdup(parts[0]);
- list_append(list, value);
- break;
- case PAPI_BOOLEAN:
- value->boolean = PAPI_TRUE;
- if ((strcasecmp(parts[0], "false") == 0) ||
- (strcasecmp(parts[0], "no") == 0))
- value->boolean = PAPI_FALSE;
- list_append(list, value);
- break;
- case PAPI_INTEGER:
- value->integer = atoi(parts[0]);
- list_append(list, value);
- break;
- case PAPI_RANGE:
- if (dtype == PAPI_INTEGER) {
- if (atoi(parts[0]) < 0) {
- /*
- * Handles -P -x case
- * which prints from page number 1
- * till page number x
- */
- value->range.lower = 1;
- value->range.upper = 0 - (atoi(parts[0]));
- } else {
- value->range.lower = value->range.upper
- = atoi(parts[0]);
- }
- } else if (dtype == PAPI_RANGE) {
- if (parts[2] == NULL) {
- value->range.lower = atoi(parts[1]);
- /*
- * Imposing an artificial limit on
- * the upper bound for page range.
- */
- value->range.upper = MAX_PAGES;
- } else if ((parts[1] != NULL) && (parts[2] != NULL)) {
- value->range.lower = atoi(parts[1]);
- value->range.upper = atoi(parts[2]);
- }
- }
- list_append(list, value);
- break;
- case PAPI_RESOLUTION:
- value->resolution.xres = atoi(parts[1]);
- value->resolution.yres = atoi(parts[2]);
- if (parts[3][0] == 'i')
- value->resolution.units = PAPI_RES_PER_INCH;
- else
- value->resolution.units = PAPI_RES_PER_CM;
- list_append(list, value);
- break;
- case PAPI_COLLECTION:
- papiAttributeListFromString(&(value->collection), 0, parts[0]);
- list_append(list, value);
- break;
- }
-}
-
-static papi_status_t
-_papiAttributeFromStrings(papi_attribute_t ***list, int flags,
- char *key, char **values)
-{
- int i;
- papi_status_t result = PAPI_OK;
- papi_attribute_t *attr = calloc(1, sizeof (*attr));
-
- /* these are specified in the papi spec as ranges */
- char *ranges[] = { "copies-supported", "job-impressions-supported",
- "job-k-octets-supported",
- "job-media-sheets-supported", "page-ranges",
- NULL };
-
- if ((attr == NULL) || ((attr->name = strdup(key)) == NULL))
- return (PAPI_TEMPORARY_ERROR);
-
- attr->type = PAPI_METADATA;
- /* these are known ranges */
- for (i = 0; ranges[i] != NULL; i++)
- if (strcasecmp(attr->name, ranges[i]) == 0) {
- attr->type = PAPI_RANGE;
- break;
- }
-
- if (values != NULL) {
- papi_attribute_value_t **vals = NULL;
-
- for (i = 0; values[i] != NULL; i++) {
- papi_attribute_value_type_t dtype;
- char **parts = NULL;
-
- dtype = _process_value(values[i], &parts);
- if (attr->type == PAPI_METADATA)
- attr->type = dtype;
- _add_attribute_value(&vals, attr->type, dtype, parts);
- free(parts);
- }
- attr->values = vals;
- }
-
- list_append(list, attr);
-
- return (result);
-}
-
-static papi_status_t
-_parse_attribute_list(papi_attribute_t ***list, int flags, char *string)
-{
- papi_status_t result = PAPI_OK;
- char *ptr;
-
- if ((list == NULL) || (string == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- if ((ptr = strdup(string)) == NULL)
- return (PAPI_TEMPORARY_ERROR);
-
- while ((*ptr != '\0') && (result == PAPI_OK)) {
- char *key, **values = NULL;
-
- /* strip any leading whitespace */
- while (isspace(*ptr) != 0)
- ptr++;
-
- /* Get the name: name[=value] */
- key = ptr;
- while ((*ptr != '\0') && (*ptr != '=') && (isspace(*ptr) == 0))
- ptr++;
-
- if (*ptr == '=') {
- *ptr++ = '\0';
-
- while ((*ptr != '\0') && (isspace(*ptr) == 0)) {
- char *value = ptr;
-
- if ((*ptr == '\'') || (*ptr == '"')) {
- char q = *ptr++;
-
- /* quoted string value */
- while ((*ptr != '\0') && (*ptr != q))
- ptr++;
- if (*ptr == q)
- ptr++;
- } else if (*ptr == '{') {
- /* collection */
- while ((*ptr != '\0') && (*ptr != '}'))
- ptr++;
- if (*ptr == '}')
- ptr++;
- } else {
- /* value */
- while ((*ptr != '\0') &&
- (*ptr != ',') &&
- (isspace(*ptr) == 0))
- ptr++;
- }
- if (*ptr == ',')
- *ptr++ = '\0';
- list_append(&values, value);
- }
- } else { /* boolean "[no]key" */
- char *value = "true";
-
- if (strncasecmp(key, "no", 2) == 0) {
- key += 2;
- value = "false";
- }
- list_append(&values, value);
- }
- if (*ptr != '\0')
- *ptr++ = '\0';
-
- result = _papiAttributeFromStrings(list, flags, key, values);
- free(values);
- }
-
- return (result);
-}
-
-papi_status_t
-papiAttributeListFromString(papi_attribute_t ***attrs,
- int flags, char *string)
-{
- papi_status_t result = PAPI_OK;
-
- if ((attrs != NULL) && (string != NULL) &&
- ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL))
- == 0)) {
- result = _parse_attribute_list(attrs, flags, string);
- } else {
- result = PAPI_BAD_ARGUMENT;
- }
-
- return (result);
-}
-
-static papi_status_t
-papiAttributeToString(papi_attribute_t *attribute, char *delim,
- char *buffer, size_t buflen)
-{
- papi_attribute_value_t **values = attribute->values;
- int rc, i;
-
- if ((attribute->type == PAPI_BOOLEAN) && (values[1] == NULL)) {
- if (values[0]->boolean == PAPI_FALSE) {
- if (isupper(attribute->name[0]) == 0)
- strlcat(buffer, "no", buflen);
- else
- strlcat(buffer, "No", buflen);
- }
- rc = strlcat(buffer, attribute->name, buflen);
- } else {
- strlcat(buffer, attribute->name, buflen);
- rc = strlcat(buffer, "=", buflen);
- }
-
- if (values == NULL)
- return (PAPI_OK);
-
- for (i = 0; values[i] != NULL; i++) {
- switch (attribute->type) {
- case PAPI_STRING:
- rc = strlcat(buffer, values[i]->string, buflen);
- break;
- case PAPI_INTEGER: {
- char string[24];
-
- snprintf(string, sizeof (string), "%d",
- values[i]->integer);
- rc = strlcat(buffer, string, buflen);
- }
- break;
- case PAPI_BOOLEAN:
- if (values[1] != NULL)
- rc = strlcat(buffer, (values[i]->boolean ?
- "true" : "false"), buflen);
- break;
- case PAPI_RANGE: {
- char string[24];
-
- if (values[i]->range.lower == values[i]->range.upper)
- snprintf(string, sizeof (string), "%d",
- values[i]->range.lower);
- else
- snprintf(string, sizeof (string), "%d-%d",
- values[i]->range.lower,
- values[i]->range.upper);
- rc = strlcat(buffer, string, buflen);
- }
- break;
- case PAPI_RESOLUTION: {
- char string[24];
-
- snprintf(string, sizeof (string), "%dx%ddp%c",
- values[i]->resolution.xres,
- values[i]->resolution.yres,
- (values[i]->resolution.units == PAPI_RES_PER_CM
- ? 'c' : 'i'));
- rc = strlcat(buffer, string, buflen);
- }
- break;
- case PAPI_DATETIME: {
- struct tm *tm = localtime(&values[i]->datetime);
-
- if (tm != NULL) {
- char string[64];
-
- strftime(string, sizeof (string), "%C", tm);
- rc = strlcat(buffer, string, buflen);
- }}
- break;
- case PAPI_COLLECTION: {
- char *string = alloca(buflen);
-
- papiAttributeListToString(values[i]->collection,
- delim, string, buflen);
- rc = strlcat(buffer, string, buflen);
- }
- break;
- default: {
- char string[32];
-
- snprintf(string, sizeof (string), "unknown-type-0x%x",
- attribute->type);
- rc = strlcat(buffer, string, buflen);
- }
- }
- if (values[i+1] != NULL)
- rc = strlcat(buffer, ",", buflen);
-
- if (rc >= buflen)
- return (PAPI_NOT_POSSIBLE);
-
- }
-
- return (PAPI_OK);
-}
-
-papi_status_t
-papiAttributeListToString(papi_attribute_t **attrs,
- char *delim, char *buffer, size_t buflen)
-{
- papi_status_t status = PAPI_OK;
- int i;
-
- if ((attrs == NULL) || (buffer == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- buffer[0] = '\0';
- if (!delim)
- delim = " ";
-
- for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) {
- status = papiAttributeToString(attrs[i], delim, buffer, buflen);
- if (attrs[i+1] != NULL)
- strlcat(buffer, delim, buflen);
- }
-
- return (status);
-}
-
-static int
-is_in_list(char *value, char **list)
-{
- if ((list != NULL) && (value != NULL)) {
- int i;
-
- for (i = 0; list[i] != NULL; i++)
- if (strcasecmp(value, list[i]) == 0)
- return (0);
- }
-
- return (1);
-}
-
-static papi_status_t
-copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute)
-{
- papi_status_t status;
- int i = 0;
-
- if ((list == NULL) || (attribute == NULL) ||
- (attribute->values == NULL))
- return (PAPI_BAD_ARGUMENT);
-
- for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL,
- attribute->name, attribute->type,
- attribute->values[i]);
- ((status == PAPI_OK) && (attribute->values[i] != NULL));
- status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND,
- attribute->name, attribute->type,
- attribute->values[i]))
- i++;
-
- return (status);
-}
-
-void
-copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes)
-{
- int i;
-
- if ((result == NULL) || (attributes == NULL))
- return;
-
- for (i = 0; attributes[i] != NULL; i++)
- copy_attribute(result, attributes[i]);
-}
-
-void
-split_and_copy_attributes(char **list, papi_attribute_t **attributes,
- papi_attribute_t ***in, papi_attribute_t ***out)
-{
- int i;
-
- if ((list == NULL) || (attributes == NULL))
- return;
-
- for (i = 0; attributes[i] != NULL; i++)
- if (is_in_list(attributes[i]->name, list) == 0)
- copy_attribute(in, attributes[i]);
- else
- copy_attribute(out, attributes[i]);
-}
-
-void
-papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes,
- char *prefix_fmt, ...)
-{
- char *prefix = NULL;
- char *buffer = NULL;
- char *newfmt = NULL;
- void *mem;
- ssize_t size = 0;
- va_list ap;
-
- newfmt = malloc(strlen(prefix_fmt) + 2);
- sprintf(newfmt, "\n%s", prefix_fmt);
-
- va_start(ap, prefix_fmt);
- while (vsnprintf(prefix, size, newfmt, ap) > size) {
- size += 1024;
- mem = realloc(prefix, size);
- if (!mem) goto error;
- prefix = mem;
- }
- va_end(ap);
-
- if (attributes) {
- size = 0;
- while (papiAttributeListToString(attributes, prefix, buffer,
- size) != PAPI_OK) {
- size += 1024;
- mem = realloc(buffer, size);
- if (!mem) goto error;
- buffer = mem;
- }
- }
-
- fprintf(fp, "%s%s\n", prefix, buffer ? buffer : "");
- fflush(fp);
-
- error:
- free(newfmt);
- free(prefix);
- free(buffer);
-}