4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2014 Gary Mills
25 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
41 #define MAX_PAGES 32767
43 * Assuming the maximum number of pages in
44 * a document to be 32767
47 static void papiAttributeFree(papi_attribute_t
*attribute
);
50 papiAttributeValueFree(papi_attribute_value_type_t type
,
51 papi_attribute_value_t
*value
)
56 if (value
->string
!= NULL
)
60 if (value
->collection
!= NULL
) {
63 for (i
= 0; value
->collection
[i
] != NULL
; i
++)
64 papiAttributeFree(value
->collection
[i
]);
66 free(value
->collection
);
69 default: /* don't need to free anything extra */
78 papiAttributeValuesFree(papi_attribute_value_type_t type
,
79 papi_attribute_value_t
**values
)
84 for (i
= 0; values
[i
] != NULL
; i
++)
85 papiAttributeValueFree(type
, values
[i
]);
92 papiAttributeFree(papi_attribute_t
*attribute
)
94 if (attribute
!= NULL
) {
95 free(attribute
->name
);
96 if (attribute
->values
!= NULL
)
97 papiAttributeValuesFree(attribute
->type
,
104 papiAttributeListFree(papi_attribute_t
**list
)
109 for (i
= 0; list
[i
] != NULL
; i
++)
110 papiAttributeFree(list
[i
]);
116 static papi_attribute_t
**
117 collection_dup(papi_attribute_t
**collection
)
119 papi_attribute_t
**result
= NULL
;
121 /* allows a NULL collection that is "empty" or "no value" */
122 if (collection
!= NULL
) {
123 papi_status_t status
= PAPI_OK
;
126 for (i
= 0; ((collection
[i
] != NULL
) && (status
== PAPI_OK
));
128 papi_attribute_t
*a
= collection
[i
];
130 status
= papiAttributeListAddValue(&result
,
131 PAPI_ATTR_APPEND
, a
->name
, a
->type
, NULL
);
132 if ((status
== PAPI_OK
) && (a
->values
!= NULL
)) {
135 for (j
= 0; ((a
->values
[j
] != NULL
) &&
136 (status
== PAPI_OK
)); j
++)
137 status
= papiAttributeListAddValue(
138 &result
, PAPI_ATTR_APPEND
,
139 a
->name
, a
->type
, a
->values
[j
]);
142 if (status
!= PAPI_OK
) {
143 papiAttributeListFree(result
);
151 static papi_attribute_value_t
*
152 papiAttributeValueDup(papi_attribute_value_type_t type
,
153 papi_attribute_value_t
*v
)
155 papi_attribute_value_t
*result
= NULL
;
157 if ((v
!= NULL
) && ((result
= calloc(1, sizeof (*result
))) != NULL
)) {
160 if (v
->string
== NULL
) {
164 result
->string
= strdup(v
->string
);
167 result
->integer
= v
->integer
;
170 result
->boolean
= v
->boolean
;
173 result
->range
.lower
= v
->range
.lower
;
174 result
->range
.upper
= v
->range
.upper
;
176 case PAPI_RESOLUTION
:
177 result
->resolution
.xres
= v
->resolution
.xres
;
178 result
->resolution
.yres
= v
->resolution
.yres
;
179 result
->resolution
.units
= v
->resolution
.units
;
182 result
->datetime
= v
->datetime
;
184 case PAPI_COLLECTION
:
185 result
->collection
= collection_dup(v
->collection
);
188 result
->metadata
= v
->metadata
;
190 default: /* unknown type, fail to duplicate */
199 static papi_attribute_t
*
200 papiAttributeAlloc(char *name
, papi_attribute_value_type_t type
)
202 papi_attribute_t
*result
= NULL
;
204 if ((result
= calloc(1, sizeof (*result
))) != NULL
) {
205 result
->name
= strdup(name
);
213 papiAttributeListAppendValue(papi_attribute_value_t
***values
,
214 papi_attribute_value_type_t type
,
215 papi_attribute_value_t
*value
)
219 return (PAPI_BAD_ARGUMENT
);
221 if (value
!= NULL
) { /* this allows "empty" attributes */
222 papi_attribute_value_t
*tmp
= NULL
;
224 if ((tmp
= papiAttributeValueDup(type
, value
)) == NULL
)
225 return (PAPI_TEMPORARY_ERROR
);
227 list_append(values
, tmp
);
234 papiAttributeListAddValue(papi_attribute_t
***list
, int flgs
,
235 char *name
, papi_attribute_value_type_t type
,
236 papi_attribute_value_t
*value
)
238 papi_status_t result
;
240 papi_attribute_t
*attribute
= NULL
;
241 papi_attribute_value_t
**values
= NULL
;
243 if ((list
== NULL
) || (name
== NULL
))
244 return (PAPI_BAD_ARGUMENT
);
246 if ((type
== PAPI_RANGE
) && (value
!= NULL
) &&
247 (value
->range
.lower
> value
->range
.upper
))
248 return (PAPI_BAD_ARGUMENT
); /* RANGE must have min <= max */
250 if (flags
== 0) /* if it wasn't set, set a default behaviour */
251 flags
= PAPI_ATTR_APPEND
;
253 /* look for an existing one */
254 attribute
= papiAttributeListFind(*list
, name
);
256 if (((flags
& PAPI_ATTR_EXCL
) != 0) && (attribute
!= NULL
))
257 return (PAPI_CONFLICT
); /* EXISTS */
259 if (((flags
& PAPI_ATTR_REPLACE
) == 0) && (attribute
!= NULL
) &&
260 (attribute
->type
!= type
))
261 return (PAPI_CONFLICT
); /* TYPE CONFLICT */
263 /* if we don't have one, create it and add it to the list */
264 if ((attribute
== NULL
) &&
265 ((attribute
= papiAttributeAlloc(name
, type
)) != NULL
))
266 list_append(list
, attribute
);
268 /* if we don't have one by now, it's most likely an alloc fail */
269 if (attribute
== NULL
)
270 return (PAPI_TEMPORARY_ERROR
);
273 * if we are replacing, clear any existing values, but don't free
274 * until after we have replaced the values, in case we are replacing
275 * a collection with a relocated version of the original collection.
277 if (((flags
& PAPI_ATTR_REPLACE
) != 0) && (attribute
->values
!= NULL
)) {
278 values
= attribute
->values
;
279 attribute
->values
= NULL
;
282 attribute
->type
= type
;
284 result
= papiAttributeListAppendValue(&attribute
->values
, type
, value
);
286 /* free old values if we replaced them */
288 papiAttributeValuesFree(type
, values
);
294 papiAttributeListAddString(papi_attribute_t
***list
, int flags
,
295 char *name
, char *string
)
297 papi_attribute_value_t v
;
299 v
.string
= (char *)string
;
300 return (papiAttributeListAddValue(list
, flags
, name
, PAPI_STRING
, &v
));
304 papiAttributeListAddInteger(papi_attribute_t
***list
, int flags
,
305 char *name
, int integer
)
307 papi_attribute_value_t v
;
310 return (papiAttributeListAddValue(list
, flags
, name
, PAPI_INTEGER
, &v
));
314 papiAttributeListAddBoolean(papi_attribute_t
***list
, int flags
,
315 char *name
, char boolean
)
317 papi_attribute_value_t v
;
320 return (papiAttributeListAddValue(list
, flags
, name
, PAPI_BOOLEAN
, &v
));
324 papiAttributeListAddRange(papi_attribute_t
***list
, int flags
,
325 char *name
, int lower
, int upper
)
327 papi_attribute_value_t v
;
329 v
.range
.lower
= lower
;
330 v
.range
.upper
= upper
;
331 return (papiAttributeListAddValue(list
, flags
, name
, PAPI_RANGE
, &v
));
335 papiAttributeListAddResolution(papi_attribute_t
***list
, int flags
,
336 char *name
, int xres
, int yres
, papi_resolution_unit_t units
)
338 papi_attribute_value_t v
;
340 v
.resolution
.xres
= xres
;
341 v
.resolution
.yres
= yres
;
342 v
.resolution
.units
= units
;
343 return (papiAttributeListAddValue(list
, flags
, name
,
344 PAPI_RESOLUTION
, &v
));
348 papiAttributeListAddDatetime(papi_attribute_t
***list
, int flags
,
349 char *name
, time_t datetime
)
351 papi_attribute_value_t v
;
353 v
.datetime
= datetime
;
354 return (papiAttributeListAddValue(list
, flags
, name
,
359 papiAttributeListAddCollection(papi_attribute_t
***list
, int flags
,
360 char *name
, papi_attribute_t
**collection
)
362 papi_attribute_value_t v
;
364 v
.collection
= (papi_attribute_t
**)collection
;
365 return (papiAttributeListAddValue(list
, flags
, name
,
366 PAPI_COLLECTION
, &v
));
370 papiAttributeListAddMetadata(papi_attribute_t
***list
, int flags
,
371 char *name
, papi_metadata_t metadata
)
373 papi_attribute_value_t v
;
375 v
.metadata
= metadata
;
376 return (papiAttributeListAddValue(list
, flags
, name
,
381 papiAttributeListDelete(papi_attribute_t
***list
, char *name
)
383 papi_attribute_t
*attribute
;
385 if ((list
== NULL
) || (name
== NULL
))
386 return (PAPI_BAD_ARGUMENT
);
388 if ((attribute
= papiAttributeListFind(*list
, name
)) == NULL
)
389 return (PAPI_NOT_FOUND
);
391 list_remove(list
, attribute
);
392 papiAttributeFree(attribute
);
398 papiAttributeListFind(papi_attribute_t
**list
, char *name
)
401 if ((list
== NULL
) || (name
== NULL
))
404 for (i
= 0; list
[i
] != NULL
; i
++)
405 if (strcasecmp(list
[i
]->name
, name
) == 0)
406 return ((papi_attribute_t
*)list
[i
]);
412 papiAttributeListGetNext(papi_attribute_t
**list
, void **iter
)
414 papi_attribute_t
**tmp
, *result
;
416 if ((list
== NULL
) && (iter
== NULL
))
430 papiAttributeListGetValue(papi_attribute_t
**list
, void **iter
,
431 char *name
, papi_attribute_value_type_t type
,
432 papi_attribute_value_t
**value
)
434 papi_attribute_value_t
**tmp
;
437 if ((list
== NULL
) || ((name
== NULL
) && (iter
== NULL
)) ||
439 return (PAPI_BAD_ARGUMENT
);
444 if ((iter
== NULL
) || (*iter
== NULL
)) {
445 papi_attribute_t
*attr
= papiAttributeListFind(list
, name
);
448 return (PAPI_NOT_FOUND
);
450 if (attr
->type
!= type
)
451 return (PAPI_NOT_POSSIBLE
);
458 return (PAPI_NOT_FOUND
);
470 papiAttributeListGetString(papi_attribute_t
**list
, void **iter
,
471 char *name
, char **vptr
)
473 papi_status_t status
;
474 papi_attribute_value_t
*value
= NULL
;
477 return (PAPI_BAD_ARGUMENT
);
479 status
= papiAttributeListGetValue(list
, iter
, name
,
480 PAPI_STRING
, &value
);
481 if (status
== PAPI_OK
)
482 *vptr
= value
->string
;
488 papiAttributeListGetInteger(papi_attribute_t
**list
, void **iter
,
489 char *name
, int *vptr
)
491 papi_status_t status
;
492 papi_attribute_value_t
*value
= NULL
;
495 return (PAPI_BAD_ARGUMENT
);
497 status
= papiAttributeListGetValue(list
, iter
, name
,
498 PAPI_INTEGER
, &value
);
499 if (status
== PAPI_OK
)
500 *vptr
= value
->integer
;
506 papiAttributeListGetBoolean(papi_attribute_t
**list
, void **iter
,
507 char *name
, char *vptr
)
509 papi_status_t status
;
510 papi_attribute_value_t
*value
= NULL
;
513 return (PAPI_BAD_ARGUMENT
);
515 status
= papiAttributeListGetValue(list
, iter
, name
,
516 PAPI_BOOLEAN
, &value
);
517 if (status
== PAPI_OK
)
518 *vptr
= value
->boolean
;
524 papiAttributeListGetRange(papi_attribute_t
**list
, void **iter
,
525 char *name
, int *min
, int *max
)
527 papi_status_t status
;
528 papi_attribute_value_t
*value
= NULL
;
530 if ((min
== NULL
) || (max
== NULL
))
531 return (PAPI_BAD_ARGUMENT
);
533 status
= papiAttributeListGetValue(list
, iter
, name
,
535 if (status
== PAPI_OK
) {
536 *min
= value
->range
.lower
;
537 *max
= value
->range
.upper
;
544 papiAttributeListGetResolution(papi_attribute_t
**list
, void **iter
,
545 char *name
, int *x
, int *y
, papi_resolution_unit_t
*units
)
547 papi_status_t status
;
548 papi_attribute_value_t
*value
= NULL
;
550 if ((x
== NULL
) || (y
== NULL
) || (units
== NULL
))
551 return (PAPI_BAD_ARGUMENT
);
553 status
= papiAttributeListGetValue(list
, iter
, name
,
554 PAPI_RESOLUTION
, &value
);
555 if (status
== PAPI_OK
) {
556 *x
= value
->resolution
.xres
;
557 *y
= value
->resolution
.yres
;
558 *units
= value
->resolution
.units
;
565 papiAttributeListGetDatetime(papi_attribute_t
**list
, void **iter
,
566 char *name
, time_t *dt
)
568 papi_status_t status
;
569 papi_attribute_value_t
*value
= NULL
;
572 return (PAPI_BAD_ARGUMENT
);
574 status
= papiAttributeListGetValue(list
, iter
, name
,
575 PAPI_DATETIME
, &value
);
576 if (status
== PAPI_OK
) {
577 *dt
= value
->datetime
;
584 papiAttributeListGetCollection(papi_attribute_t
**list
, void **iter
,
585 char *name
, papi_attribute_t
***collection
)
587 papi_status_t status
;
588 papi_attribute_value_t
*value
= NULL
;
590 if (collection
== NULL
)
591 return (PAPI_BAD_ARGUMENT
);
593 status
= papiAttributeListGetValue(list
, iter
, name
,
594 PAPI_COLLECTION
, &value
);
595 if (status
== PAPI_OK
) {
596 *collection
= value
->collection
;
603 papiAttributeListGetMetadata(papi_attribute_t
**list
, void **iter
,
604 char *name
, papi_metadata_t
*vptr
)
606 papi_status_t status
;
607 papi_attribute_value_t
*value
= NULL
;
610 return (PAPI_BAD_ARGUMENT
);
612 status
= papiAttributeListGetValue(list
, iter
, name
,
613 PAPI_METADATA
, &value
);
614 if (status
== PAPI_OK
)
615 *vptr
= value
->metadata
;
621 /* The string is modified by this call */
623 regvalue(regmatch_t match
, char *string
)
626 if (match
.rm_so
!= match
.rm_eo
) {
627 result
= string
+ match
.rm_so
;
628 *(result
+ (match
.rm_eo
- match
.rm_so
)) = '\0';
633 static papi_attribute_value_type_t
634 _process_value(char *string
, char ***parts
)
638 papi_attribute_value_type_t type
;
644 { PAPI_BOOLEAN
, 1, "^(true|false|yes|no)$", 0 },
645 { PAPI_COLLECTION
, 1, "^\\{(.+)\\}$", 0 },
646 /* PAPI_DATETIME is unsupported, too much like an integer */
647 { PAPI_INTEGER
, 1, "^([+-]{0,1}[[:digit:]]+)$", 0 },
648 { PAPI_RANGE
, 3, "^([[:digit:]]*)-([[:digit:]]*)$", 0 },
649 { PAPI_RESOLUTION
, 4, "^([[:digit:]]+)x([[:digit:]]+)dp(i|c)$",
653 regmatch_t matches
[4];
655 for (i
= 0; i
< 5; i
++) {
658 if (types
[i
].compiled
== 0) {
659 (void) regcomp(&(types
[i
].re
), types
[i
].expression
,
660 REG_EXTENDED
|REG_ICASE
);
661 types
[i
].compiled
= 1;
663 if (regexec(&(types
[i
].re
), string
, (size_t)types
[i
].vals
,
664 matches
, 0) == REG_NOMATCH
)
667 for (j
= 0; j
< types
[i
].vals
; j
++)
668 list_append(parts
, regvalue(matches
[j
], string
));
669 return (types
[i
].type
);
672 list_append(parts
, string
);
673 return (PAPI_STRING
);
677 _add_attribute_value(papi_attribute_value_t
***list
,
678 papi_attribute_value_type_t type
,
679 papi_attribute_value_type_t dtype
, char **parts
)
681 papi_attribute_value_t
*value
= calloc(1, sizeof (*value
));
685 value
->string
= strdup(parts
[0]);
686 list_append(list
, value
);
689 value
->boolean
= PAPI_TRUE
;
690 if ((strcasecmp(parts
[0], "false") == 0) ||
691 (strcasecmp(parts
[0], "no") == 0))
692 value
->boolean
= PAPI_FALSE
;
693 list_append(list
, value
);
696 value
->integer
= atoi(parts
[0]);
697 list_append(list
, value
);
700 if (dtype
== PAPI_INTEGER
) {
701 if (atoi(parts
[0]) < 0) {
704 * which prints from page number 1
707 value
->range
.lower
= 1;
708 value
->range
.upper
= 0 - (atoi(parts
[0]));
710 value
->range
.lower
= value
->range
.upper
713 } else if (dtype
== PAPI_RANGE
) {
714 if (parts
[2] == NULL
) {
715 value
->range
.lower
= atoi(parts
[1]);
717 * Imposing an artificial limit on
718 * the upper bound for page range.
720 value
->range
.upper
= MAX_PAGES
;
721 } else if ((parts
[1] != NULL
) && (parts
[2] != NULL
)) {
722 value
->range
.lower
= atoi(parts
[1]);
723 value
->range
.upper
= atoi(parts
[2]);
726 list_append(list
, value
);
728 case PAPI_RESOLUTION
:
729 value
->resolution
.xres
= atoi(parts
[1]);
730 value
->resolution
.yres
= atoi(parts
[2]);
731 if (parts
[3][0] == 'i')
732 value
->resolution
.units
= PAPI_RES_PER_INCH
;
734 value
->resolution
.units
= PAPI_RES_PER_CM
;
735 list_append(list
, value
);
737 case PAPI_COLLECTION
:
738 papiAttributeListFromString(&(value
->collection
), 0, parts
[0]);
739 list_append(list
, value
);
745 _papiAttributeFromStrings(papi_attribute_t
***list
, int flags
,
746 char *key
, char **values
)
749 papi_status_t result
= PAPI_OK
;
750 papi_attribute_t
*attr
= calloc(1, sizeof (*attr
));
752 /* these are specified in the papi spec as ranges */
753 char *ranges
[] = { "copies-supported", "job-impressions-supported",
754 "job-k-octets-supported",
755 "job-media-sheets-supported", "page-ranges",
758 if ((attr
== NULL
) || ((attr
->name
= strdup(key
)) == NULL
))
759 return (PAPI_TEMPORARY_ERROR
);
761 attr
->type
= PAPI_METADATA
;
762 /* these are known ranges */
763 for (i
= 0; ranges
[i
] != NULL
; i
++)
764 if (strcasecmp(attr
->name
, ranges
[i
]) == 0) {
765 attr
->type
= PAPI_RANGE
;
769 if (values
!= NULL
) {
770 papi_attribute_value_t
**vals
= NULL
;
772 for (i
= 0; values
[i
] != NULL
; i
++) {
773 papi_attribute_value_type_t dtype
;
776 dtype
= _process_value(values
[i
], &parts
);
777 if (attr
->type
== PAPI_METADATA
)
779 _add_attribute_value(&vals
, attr
->type
, dtype
, parts
);
785 list_append(list
, attr
);
791 _parse_attribute_list(papi_attribute_t
***list
, int flags
, char *string
)
793 papi_status_t result
= PAPI_OK
;
796 if ((list
== NULL
) || (string
== NULL
))
797 return (PAPI_BAD_ARGUMENT
);
799 if ((ptr
= strdup(string
)) == NULL
)
800 return (PAPI_TEMPORARY_ERROR
);
802 while ((*ptr
!= '\0') && (result
== PAPI_OK
)) {
803 char *key
, **values
= NULL
;
805 /* strip any leading whitespace */
806 while (isspace(*ptr
) != 0)
809 /* Get the name: name[=value] */
811 while ((*ptr
!= '\0') && (*ptr
!= '=') && (isspace(*ptr
) == 0))
817 while ((*ptr
!= '\0') && (isspace(*ptr
) == 0)) {
820 if ((*ptr
== '\'') || (*ptr
== '"')) {
823 /* quoted string value */
824 while ((*ptr
!= '\0') && (*ptr
!= q
))
828 } else if (*ptr
== '{') {
830 while ((*ptr
!= '\0') && (*ptr
!= '}'))
836 while ((*ptr
!= '\0') &&
838 (isspace(*ptr
) == 0))
843 list_append(&values
, value
);
845 } else { /* boolean "[no]key" */
846 char *value
= "true";
848 if (strncasecmp(key
, "no", 2) == 0) {
852 list_append(&values
, value
);
857 result
= _papiAttributeFromStrings(list
, flags
, key
, values
);
865 papiAttributeListFromString(papi_attribute_t
***attrs
, int flags
, char *string
)
867 papi_status_t result
= PAPI_OK
;
869 if ((attrs
!= NULL
) && (string
!= NULL
) &&
870 ((flags
& ~(PAPI_ATTR_APPEND
+PAPI_ATTR_REPLACE
+PAPI_ATTR_EXCL
))
872 result
= _parse_attribute_list(attrs
, flags
, string
);
874 result
= PAPI_BAD_ARGUMENT
;
881 papiAttributeToString(papi_attribute_t
*attribute
, char *delim
,
882 char *buffer
, size_t buflen
)
884 papi_attribute_value_t
**values
= attribute
->values
;
887 if ((attribute
->type
== PAPI_BOOLEAN
) && (values
[1] == NULL
)) {
888 if (values
[0]->boolean
== PAPI_FALSE
) {
889 if (isupper(attribute
->name
[0]) == 0)
890 strlcat(buffer
, "no", buflen
);
892 strlcat(buffer
, "No", buflen
);
894 rc
= strlcat(buffer
, attribute
->name
, buflen
);
896 strlcat(buffer
, attribute
->name
, buflen
);
897 rc
= strlcat(buffer
, "=", buflen
);
903 for (i
= 0; values
[i
] != NULL
; i
++) {
904 switch (attribute
->type
) {
906 rc
= strlcat(buffer
, values
[i
]->string
, buflen
);
911 snprintf(string
, sizeof (string
), "%d",
913 rc
= strlcat(buffer
, string
, buflen
);
917 if (values
[1] != NULL
)
918 rc
= strlcat(buffer
, values
[i
]->boolean
?
919 "true" : "false", buflen
);
924 if (values
[i
]->range
.lower
== values
[i
]->range
.upper
)
925 snprintf(string
, sizeof (string
), "%d",
926 values
[i
]->range
.lower
);
928 snprintf(string
, sizeof (string
), "%d-%d",
929 values
[i
]->range
.lower
,
930 values
[i
]->range
.upper
);
931 rc
= strlcat(buffer
, string
, buflen
);
934 case PAPI_RESOLUTION
: {
937 snprintf(string
, sizeof (string
), "%dx%ddp%c",
938 values
[i
]->resolution
.xres
,
939 values
[i
]->resolution
.yres
,
940 values
[i
]->resolution
.units
== PAPI_RES_PER_CM
?
942 rc
= strlcat(buffer
, string
, buflen
);
945 case PAPI_DATETIME
: {
946 struct tm
*tm
= localtime(&values
[i
]->datetime
);
951 strftime(string
, sizeof (string
), "%c", tm
);
952 rc
= strlcat(buffer
, string
, buflen
);
955 case PAPI_COLLECTION
: {
956 char *string
= alloca(buflen
);
958 papiAttributeListToString(values
[i
]->collection
,
959 delim
, string
, buflen
);
960 rc
= strlcat(buffer
, string
, buflen
);
966 snprintf(string
, sizeof (string
), "unknown-type-0x%x",
968 rc
= strlcat(buffer
, string
, buflen
);
971 if (values
[i
+1] != NULL
)
972 rc
= strlcat(buffer
, ",", buflen
);
975 return (PAPI_NOT_POSSIBLE
);
983 papiAttributeListToString(papi_attribute_t
**attrs
,
984 char *delim
, char *buffer
, size_t buflen
)
986 papi_status_t status
= PAPI_OK
;
989 if ((attrs
== NULL
) || (buffer
== NULL
))
990 return (PAPI_BAD_ARGUMENT
);
996 for (i
= 0; ((attrs
[i
] != NULL
) && (status
== PAPI_OK
)); i
++) {
997 status
= papiAttributeToString(attrs
[i
], delim
, buffer
, buflen
);
998 if (attrs
[i
+1] != NULL
)
999 strlcat(buffer
, delim
, buflen
);
1006 is_in_list(char *value
, char **list
)
1008 if ((list
!= NULL
) && (value
!= NULL
)) {
1011 for (i
= 0; list
[i
] != NULL
; i
++)
1012 if (strcasecmp(value
, list
[i
]) == 0)
1019 static papi_status_t
1020 copy_attribute(papi_attribute_t
***list
, papi_attribute_t
*attribute
)
1022 papi_status_t status
;
1025 if ((list
== NULL
) || (attribute
== NULL
) ||
1026 (attribute
->values
== NULL
))
1027 return (PAPI_BAD_ARGUMENT
);
1029 for (status
= papiAttributeListAddValue(list
, PAPI_ATTR_EXCL
,
1030 attribute
->name
, attribute
->type
, attribute
->values
[i
]);
1031 ((status
== PAPI_OK
) && (attribute
->values
[i
] != NULL
));
1032 status
= papiAttributeListAddValue(list
, PAPI_ATTR_APPEND
,
1033 attribute
->name
, attribute
->type
, attribute
->values
[i
]))
1040 copy_attributes(papi_attribute_t
***result
, papi_attribute_t
**attributes
)
1044 if ((result
== NULL
) || (attributes
== NULL
))
1047 for (i
= 0; attributes
[i
] != NULL
; i
++)
1048 copy_attribute(result
, attributes
[i
]);
1052 split_and_copy_attributes(char **list
, papi_attribute_t
**attributes
,
1053 papi_attribute_t
***in
, papi_attribute_t
***out
)
1057 if ((list
== NULL
) || (attributes
== NULL
))
1060 for (i
= 0; attributes
[i
] != NULL
; i
++)
1061 if (is_in_list(attributes
[i
]->name
, list
) == 0)
1062 copy_attribute(in
, attributes
[i
]);
1064 copy_attribute(out
, attributes
[i
]);
1068 papiAttributeListPrint(FILE *fp
, papi_attribute_t
**attributes
,
1069 char *prefix_fmt
, ...)
1071 char *prefix
= NULL
;
1072 char *buffer
= NULL
;
1073 char *newfmt
= NULL
;
1078 newfmt
= malloc(strlen(prefix_fmt
) + 2);
1079 sprintf(newfmt
, "\n%s", prefix_fmt
);
1081 va_start(ap
, prefix_fmt
);
1082 while (vsnprintf(prefix
, size
, newfmt
, ap
) > size
) {
1084 mem
= realloc(prefix
, size
);
1085 if (!mem
) goto error
;
1092 while (papiAttributeListToString(attributes
, prefix
, buffer
,
1095 mem
= realloc(buffer
, size
);
1096 if (!mem
) goto error
;
1101 fprintf(fp
, "%s%s\n", prefix
, buffer
? buffer
: "");