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