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