diff options
| -rw-r--r-- | docs/plistutil.1 | 11 | ||||
| -rw-r--r-- | include/plist/plist.h | 24 | ||||
| -rw-r--r-- | src/oplist.c | 143 | ||||
| -rw-r--r-- | src/plist.c | 4 | ||||
| -rw-r--r-- | tools/plistutil.c | 17 |
5 files changed, 164 insertions, 35 deletions
diff --git a/docs/plistutil.1 b/docs/plistutil.1 index f322bab..64373b3 100644 --- a/docs/plistutil.1 +++ b/docs/plistutil.1 | |||
| @@ -79,6 +79,17 @@ A nodepath of: | |||
| 79 | JSON and OpenStep only: Print output in compact form. By default, the output | 79 | JSON and OpenStep only: Print output in compact form. By default, the output |
| 80 | will be pretty-printed. | 80 | will be pretty-printed. |
| 81 | .TP | 81 | .TP |
| 82 | .B \-C, \-\-coerce | ||
| 83 | JSON and OpenStep only: Coerce non-compatible plist types to JSON/OpenStep | ||
| 84 | compatible representations. | ||
| 85 | Date values become ISO 8601 strings, | ||
| 86 | data values become Base64-encoded strings (JSON), | ||
| 87 | UID values become integers, | ||
| 88 | boolean becomes 1 or 0 (OpenStep), | ||
| 89 | and NULL becomes a string 'NULL' (OpenStep) | ||
| 90 | |||
| 91 | This options is implied when invoked as plist2json. | ||
| 92 | .TP | ||
| 82 | .B \-s, \-\-sort | 93 | .B \-s, \-\-sort |
| 83 | Sort all dictionary nodes lexicographically by key before converting to the output format. | 94 | Sort all dictionary nodes lexicographically by key before converting to the output format. |
| 84 | .TP | 95 | .TP |
diff --git a/include/plist/plist.h b/include/plist/plist.h index bd35c53..94930b8 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h | |||
| @@ -978,6 +978,30 @@ extern "C" | |||
| 978 | */ | 978 | */ |
| 979 | PLIST_API plist_err_t plist_to_openstep(plist_t plist, char **plist_openstep, uint32_t* length, int prettify); | 979 | PLIST_API plist_err_t plist_to_openstep(plist_t plist, char **plist_openstep, uint32_t* length, int prettify); |
| 980 | 980 | ||
| 981 | /** | ||
| 982 | * Export the #plist_t structure to OpenStep format with extended options. | ||
| 983 | * | ||
| 984 | * When \a PLIST_OPT_COMPACT is set in \a options, the resulting OpenStep output | ||
| 985 | * will be non-prettified. | ||
| 986 | * | ||
| 987 | * When \a PLIST_OPT_COERCE is set in \a options, plist types that have | ||
| 988 | * no native OpenStep representation are converted to OpenStep-compatible types | ||
| 989 | * instead of returning #PLIST_ERR_FORMAT: | ||
| 990 | * - #PLIST_BOOLEAN is serialized as a 1 or 0 | ||
| 991 | * - #PLIST_DATE is serialized as an ISO 8601 date string | ||
| 992 | * - #PLIST_NULL is serialized as string 'NULL' | ||
| 993 | * - #PLIST_UID is serialized as an integer | ||
| 994 | * | ||
| 995 | * @param plist the root node to export | ||
| 996 | * @param plist_openstep a pointer to a char* buffer. This function allocates the memory, | ||
| 997 | * caller is responsible for freeing it. | ||
| 998 | * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. | ||
| 999 | * @param options One or more bitwise ORed values of #plist_write_options_t. | ||
| 1000 | * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure | ||
| 1001 | * @note Use plist_mem_free() to free the allocated memory. | ||
| 1002 | */ | ||
| 1003 | PLIST_API plist_err_t plist_to_openstep_with_options(plist_t plist, char **plist_openstep, uint32_t* length, plist_write_options_t options); | ||
| 1004 | |||
| 981 | 1005 | ||
| 982 | /** | 1006 | /** |
| 983 | * Import the #plist_t structure from XML format. | 1007 | * Import the #plist_t structure from XML format. |
diff --git a/src/oplist.c b/src/oplist.c index 0eea27a..3c48b3a 100644 --- a/src/oplist.c +++ b/src/oplist.c | |||
| @@ -37,8 +37,11 @@ | |||
| 37 | 37 | ||
| 38 | #include "plist.h" | 38 | #include "plist.h" |
| 39 | #include "strbuf.h" | 39 | #include "strbuf.h" |
| 40 | #include "time64.h" | ||
| 40 | #include "hashtable.h" | 41 | #include "hashtable.h" |
| 41 | 42 | ||
| 43 | #define MAC_EPOCH 978307200 | ||
| 44 | |||
| 42 | #ifdef DEBUG | 45 | #ifdef DEBUG |
| 43 | static int plist_ostep_debug = 0; | 46 | static int plist_ostep_debug = 0; |
| 44 | #define PLIST_OSTEP_ERR(...) if (plist_ostep_debug) { fprintf(stderr, "libplist[ostepparser] ERROR: " __VA_ARGS__); } | 47 | #define PLIST_OSTEP_ERR(...) if (plist_ostep_debug) { fprintf(stderr, "libplist[ostepparser] ERROR: " __VA_ARGS__); } |
| @@ -144,7 +147,7 @@ static int str_needs_quotes(const char* str, size_t len) | |||
| 144 | return 0; | 147 | return 0; |
| 145 | } | 148 | } |
| 146 | 149 | ||
| 147 | static plist_err_t node_to_openstep(node_t node, bytearray_t **outbuf, uint32_t depth, int prettify) | 150 | static plist_err_t node_to_openstep(node_t node, bytearray_t **outbuf, uint32_t depth, int prettify, int coerce) |
| 148 | { | 151 | { |
| 149 | plist_data_t node_data = NULL; | 152 | plist_data_t node_data = NULL; |
| 150 | 153 | ||
| @@ -235,7 +238,7 @@ static plist_err_t node_to_openstep(node_t node, bytearray_t **outbuf, uint32_t | |||
| 235 | str_buf_append(*outbuf, " ", 2); | 238 | str_buf_append(*outbuf, " ", 2); |
| 236 | } | 239 | } |
| 237 | } | 240 | } |
| 238 | plist_err_t res = node_to_openstep(ch, outbuf, depth+1, prettify); | 241 | plist_err_t res = node_to_openstep(ch, outbuf, depth+1, prettify, coerce); |
| 239 | if (res < 0) { | 242 | if (res < 0) { |
| 240 | return res; | 243 | return res; |
| 241 | } | 244 | } |
| @@ -263,7 +266,7 @@ static plist_err_t node_to_openstep(node_t node, bytearray_t **outbuf, uint32_t | |||
| 263 | str_buf_append(*outbuf, " ", 2); | 266 | str_buf_append(*outbuf, " ", 2); |
| 264 | } | 267 | } |
| 265 | } | 268 | } |
| 266 | plist_err_t res = node_to_openstep(ch, outbuf, depth+1, prettify); | 269 | plist_err_t res = node_to_openstep(ch, outbuf, depth+1, prettify, coerce); |
| 267 | if (res < 0) { | 270 | if (res < 0) { |
| 268 | return res; | 271 | return res; |
| 269 | } | 272 | } |
| @@ -302,19 +305,65 @@ static plist_err_t node_to_openstep(node_t node, bytearray_t **outbuf, uint32_t | |||
| 302 | str_buf_append(*outbuf, ">", 1); | 305 | str_buf_append(*outbuf, ">", 1); |
| 303 | } break; | 306 | } break; |
| 304 | case PLIST_BOOLEAN: | 307 | case PLIST_BOOLEAN: |
| 305 | PLIST_OSTEP_WRITE_ERR("PLIST_BOOLEAN type is not valid for OpenStep format\n"); | 308 | if (coerce) { |
| 306 | return PLIST_ERR_FORMAT; | 309 | if (node_data->boolval) { |
| 310 | str_buf_append(*outbuf, "1", 1); | ||
| 311 | } else { | ||
| 312 | str_buf_append(*outbuf, "0", 1); | ||
| 313 | } | ||
| 314 | } else { | ||
| 315 | PLIST_OSTEP_WRITE_ERR("PLIST_BOOLEAN type is not valid for OpenStep format\n"); | ||
| 316 | return PLIST_ERR_FORMAT; | ||
| 317 | } | ||
| 318 | break; | ||
| 307 | case PLIST_NULL: | 319 | case PLIST_NULL: |
| 308 | PLIST_OSTEP_WRITE_ERR("PLIST_NULL type is not valid for OpenStep format\n"); | 320 | if (coerce) { |
| 309 | return PLIST_ERR_FORMAT; | 321 | str_buf_append(*outbuf, "NULL", 4); |
| 322 | } else { | ||
| 323 | PLIST_OSTEP_WRITE_ERR("PLIST_NULL type is not valid for OpenStep format\n"); | ||
| 324 | return PLIST_ERR_FORMAT; | ||
| 325 | } | ||
| 326 | break; | ||
| 310 | case PLIST_DATE: | 327 | case PLIST_DATE: |
| 311 | // NOT VALID FOR OPENSTEP | 328 | if (coerce) { |
| 312 | PLIST_OSTEP_WRITE_ERR("PLIST_DATE type is not valid for OpenStep format\n"); | 329 | Time64_T timev = (Time64_T)node_data->realval + MAC_EPOCH; |
| 313 | return PLIST_ERR_FORMAT; | 330 | struct TM _btime; |
| 331 | struct TM *btime = gmtime64_r(&timev, &_btime); | ||
| 332 | char datebuf[32]; | ||
| 333 | size_t datelen = 0; | ||
| 334 | if (btime) { | ||
| 335 | struct tm _tmcopy; | ||
| 336 | copy_TM64_to_tm(btime, &_tmcopy); | ||
| 337 | datelen = strftime(datebuf, sizeof(datebuf), "%Y-%m-%dT%H:%M:%SZ", &_tmcopy); | ||
| 338 | } | ||
| 339 | if (datelen <= 0) { | ||
| 340 | datelen = snprintf(datebuf, sizeof(datebuf), "1970-01-01T00:00:00Z"); | ||
| 341 | } | ||
| 342 | str_buf_append(*outbuf, "\"", 1); | ||
| 343 | str_buf_append(*outbuf, datebuf, datelen); | ||
| 344 | str_buf_append(*outbuf, "\"", 1); | ||
| 345 | } else { | ||
| 346 | // NOT VALID FOR OPENSTEP | ||
| 347 | PLIST_OSTEP_WRITE_ERR("PLIST_DATE type is not valid for OpenStep format\n"); | ||
| 348 | return PLIST_ERR_FORMAT; | ||
| 349 | } | ||
| 350 | break; | ||
| 314 | case PLIST_UID: | 351 | case PLIST_UID: |
| 315 | // NOT VALID FOR OPENSTEP | 352 | if (coerce) { |
| 316 | PLIST_OSTEP_WRITE_ERR("PLIST_UID type is not valid for OpenStep format\n"); | 353 | val = (char*)malloc(64); |
| 317 | return PLIST_ERR_FORMAT; | 354 | if (node_data->length == 16) { |
| 355 | val_len = snprintf(val, 64, "%" PRIu64, node_data->intval); | ||
| 356 | } else { | ||
| 357 | val_len = snprintf(val, 64, "%" PRIi64, node_data->intval); | ||
| 358 | } | ||
| 359 | str_buf_append(*outbuf, val, val_len); | ||
| 360 | free(val); | ||
| 361 | } else { | ||
| 362 | // NOT VALID FOR OPENSTEP | ||
| 363 | PLIST_OSTEP_WRITE_ERR("PLIST_UID type is not valid for OpenStep format\n"); | ||
| 364 | return PLIST_ERR_FORMAT; | ||
| 365 | } | ||
| 366 | break; | ||
| 318 | default: | 367 | default: |
| 319 | return PLIST_ERR_UNKNOWN; | 368 | return PLIST_ERR_UNKNOWN; |
| 320 | } | 369 | } |
| @@ -360,7 +409,7 @@ static int num_digits_u(uint64_t i) | |||
| 360 | return n; | 409 | return n; |
| 361 | } | 410 | } |
| 362 | 411 | ||
| 363 | static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify, hashtable_t *visited) | 412 | static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify, int coerce, hashtable_t *visited) |
| 364 | { | 413 | { |
| 365 | plist_data_t data; | 414 | plist_data_t data; |
| 366 | if (!node) { | 415 | if (!node) { |
| @@ -385,7 +434,7 @@ static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t dep | |||
| 385 | node_t ch; | 434 | node_t ch; |
| 386 | unsigned int n_children = node_n_children(node); | 435 | unsigned int n_children = node_n_children(node); |
| 387 | for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { | 436 | for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { |
| 388 | plist_err_t res = _node_estimate_size(ch, size, depth + 1, prettify, visited); | 437 | plist_err_t res = _node_estimate_size(ch, size, depth + 1, prettify, coerce, visited); |
| 389 | if (res < 0) { | 438 | if (res < 0) { |
| 390 | return res; | 439 | return res; |
| 391 | } | 440 | } |
| @@ -442,17 +491,46 @@ static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t dep | |||
| 442 | *size += data->length/4; | 491 | *size += data->length/4; |
| 443 | break; | 492 | break; |
| 444 | case PLIST_BOOLEAN: | 493 | case PLIST_BOOLEAN: |
| 445 | // NOT VALID FOR OPENSTEP | 494 | if (coerce) { |
| 446 | PLIST_OSTEP_WRITE_ERR("PLIST_BOOLEAN type is not valid for OpenStep format\n"); | 495 | *size += 1; |
| 447 | return PLIST_ERR_FORMAT; | 496 | } else { |
| 497 | // NOT VALID FOR OPENSTEP | ||
| 498 | PLIST_OSTEP_WRITE_ERR("PLIST_BOOLEAN type is not valid for OpenStep format\n"); | ||
| 499 | return PLIST_ERR_FORMAT; | ||
| 500 | } | ||
| 501 | break; | ||
| 448 | case PLIST_DATE: | 502 | case PLIST_DATE: |
| 449 | // NOT VALID FOR OPENSTEP | 503 | if (coerce) { |
| 450 | PLIST_OSTEP_WRITE_ERR("PLIST_DATE type is not valid for OpenStep format\n"); | 504 | // ISO 8601 string: "YYYY-MM-DDTHH:MM:SSZ" = 22 chars max |
| 451 | return PLIST_ERR_FORMAT; | 505 | *size += 24; |
| 506 | } else { | ||
| 507 | // NOT VALID FOR OPENSTEP | ||
| 508 | PLIST_OSTEP_WRITE_ERR("PLIST_DATE type is not valid for OpenStep format\n"); | ||
| 509 | return PLIST_ERR_FORMAT; | ||
| 510 | } | ||
| 511 | break; | ||
| 452 | case PLIST_UID: | 512 | case PLIST_UID: |
| 453 | // NOT VALID FOR OPENSTEP | 513 | if (coerce) { |
| 454 | PLIST_OSTEP_WRITE_ERR("PLIST_UID type is not valid for OpenStep format\n"); | 514 | if (data->length == 16) { |
| 455 | return PLIST_ERR_FORMAT; | 515 | *size += num_digits_u(data->intval); |
| 516 | } else { | ||
| 517 | *size += num_digits_i((int64_t)data->intval); | ||
| 518 | } | ||
| 519 | } else { | ||
| 520 | // NOT VALID FOR OPENSTEP | ||
| 521 | PLIST_OSTEP_WRITE_ERR("PLIST_UID type is not valid for OpenStep format\n"); | ||
| 522 | return PLIST_ERR_FORMAT; | ||
| 523 | } | ||
| 524 | break; | ||
| 525 | case PLIST_NULL: | ||
| 526 | if (coerce) { | ||
| 527 | *size += 4; | ||
| 528 | } else { | ||
| 529 | // NOT VALID FOR OPENSTEP | ||
| 530 | PLIST_OSTEP_WRITE_ERR("PLIST_NULL type is not valid for OpenStep format\n"); | ||
| 531 | return PLIST_ERR_FORMAT; | ||
| 532 | } | ||
| 533 | break; | ||
| 456 | default: | 534 | default: |
| 457 | PLIST_OSTEP_WRITE_ERR("invalid node type encountered\n"); | 535 | PLIST_OSTEP_WRITE_ERR("invalid node type encountered\n"); |
| 458 | return PLIST_ERR_UNKNOWN; | 536 | return PLIST_ERR_UNKNOWN; |
| @@ -461,17 +539,23 @@ static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t dep | |||
| 461 | return PLIST_ERR_SUCCESS; | 539 | return PLIST_ERR_SUCCESS; |
| 462 | } | 540 | } |
| 463 | 541 | ||
| 464 | static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify) | 542 | static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify, int coerce) |
| 465 | { | 543 | { |
| 466 | hashtable_t *visited = hash_table_new(plist_node_ptr_hash, plist_node_ptr_compare, NULL); | 544 | hashtable_t *visited = hash_table_new(plist_node_ptr_hash, plist_node_ptr_compare, NULL); |
| 467 | if (!visited) return PLIST_ERR_NO_MEM; | 545 | if (!visited) return PLIST_ERR_NO_MEM; |
| 468 | plist_err_t err = _node_estimate_size(node, size, depth, prettify, visited); | 546 | plist_err_t err = _node_estimate_size(node, size, depth, prettify, coerce, visited); |
| 469 | hash_table_destroy(visited); | 547 | hash_table_destroy(visited); |
| 470 | return err; | 548 | return err; |
| 471 | } | 549 | } |
| 472 | 550 | ||
| 473 | plist_err_t plist_to_openstep(plist_t plist, char **openstep, uint32_t* length, int prettify) | 551 | plist_err_t plist_to_openstep(plist_t plist, char **openstep, uint32_t* length, int prettify) |
| 474 | { | 552 | { |
| 553 | plist_write_options_t opts = prettify ? PLIST_OPT_NONE : PLIST_OPT_COMPACT; | ||
| 554 | return plist_to_openstep_with_options(plist, openstep, length, opts); | ||
| 555 | } | ||
| 556 | |||
| 557 | plist_err_t plist_to_openstep_with_options(plist_t plist, char **openstep, uint32_t* length, plist_write_options_t options) | ||
| 558 | { | ||
| 475 | uint64_t size = 0; | 559 | uint64_t size = 0; |
| 476 | plist_err_t res; | 560 | plist_err_t res; |
| 477 | 561 | ||
| @@ -479,7 +563,10 @@ plist_err_t plist_to_openstep(plist_t plist, char **openstep, uint32_t* length, | |||
| 479 | return PLIST_ERR_INVALID_ARG; | 563 | return PLIST_ERR_INVALID_ARG; |
| 480 | } | 564 | } |
| 481 | 565 | ||
| 482 | res = node_estimate_size((node_t)plist, &size, 0, prettify); | 566 | int prettify = !(options & PLIST_OPT_COMPACT); |
| 567 | int coerce = options & PLIST_OPT_COERCE; | ||
| 568 | |||
| 569 | res = node_estimate_size((node_t)plist, &size, 0, prettify, coerce); | ||
| 483 | if (res < 0) { | 570 | if (res < 0) { |
| 484 | return res; | 571 | return res; |
| 485 | } | 572 | } |
| @@ -490,7 +577,7 @@ plist_err_t plist_to_openstep(plist_t plist, char **openstep, uint32_t* length, | |||
| 490 | return PLIST_ERR_NO_MEM; | 577 | return PLIST_ERR_NO_MEM; |
| 491 | } | 578 | } |
| 492 | 579 | ||
| 493 | res = node_to_openstep((node_t)plist, &outbuf, 0, prettify); | 580 | res = node_to_openstep((node_t)plist, &outbuf, 0, prettify, coerce); |
| 494 | if (res < 0) { | 581 | if (res < 0) { |
| 495 | str_buf_free(outbuf); | 582 | str_buf_free(outbuf); |
| 496 | *openstep = NULL; | 583 | *openstep = NULL; |
diff --git a/src/plist.c b/src/plist.c index a6d3547..2ad1b0a 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -2407,7 +2407,7 @@ plist_err_t plist_write_to_string(plist_t plist, char **output, uint32_t* length | |||
| 2407 | err = plist_to_json_with_options(plist, output, length, options); | 2407 | err = plist_to_json_with_options(plist, output, length, options); |
| 2408 | break; | 2408 | break; |
| 2409 | case PLIST_FORMAT_OSTEP: | 2409 | case PLIST_FORMAT_OSTEP: |
| 2410 | err = plist_to_openstep(plist, output, length, ((options & PLIST_OPT_COMPACT) == 0)); | 2410 | err = plist_to_openstep_with_options(plist, output, length, options); |
| 2411 | break; | 2411 | break; |
| 2412 | case PLIST_FORMAT_PRINT: | 2412 | case PLIST_FORMAT_PRINT: |
| 2413 | err = plist_write_to_string_default(plist, output, length, options); | 2413 | err = plist_write_to_string_default(plist, output, length, options); |
| @@ -2445,7 +2445,7 @@ plist_err_t plist_write_to_stream(plist_t plist, FILE *stream, plist_format_t fo | |||
| 2445 | err = plist_to_json_with_options(plist, &output, &length, options); | 2445 | err = plist_to_json_with_options(plist, &output, &length, options); |
| 2446 | break; | 2446 | break; |
| 2447 | case PLIST_FORMAT_OSTEP: | 2447 | case PLIST_FORMAT_OSTEP: |
| 2448 | err = plist_to_openstep(plist, &output, &length, ((options & PLIST_OPT_COMPACT) == 0)); | 2448 | err = plist_to_openstep_with_options(plist, &output, &length, options); |
| 2449 | break; | 2449 | break; |
| 2450 | case PLIST_FORMAT_PRINT: | 2450 | case PLIST_FORMAT_PRINT: |
| 2451 | err = plist_write_to_stream_default(plist, stream, options); | 2451 | err = plist_write_to_stream_default(plist, stream, options); |
diff --git a/tools/plistutil.c b/tools/plistutil.c index fef72b7..95ec254 100644 --- a/tools/plistutil.c +++ b/tools/plistutil.c | |||
| @@ -75,10 +75,14 @@ static void print_usage(int argc, char *argv[]) | |||
| 75 | printf(" -n, --nodepath PATH Restrict output to nodepath defined by PATH.\n"); | 75 | printf(" -n, --nodepath PATH Restrict output to nodepath defined by PATH.\n"); |
| 76 | printf(" -c, --compact JSON and OpenStep only: Print output in compact form.\n"); | 76 | printf(" -c, --compact JSON and OpenStep only: Print output in compact form.\n"); |
| 77 | printf(" By default, the output will be pretty-printed.\n"); | 77 | printf(" By default, the output will be pretty-printed.\n"); |
| 78 | printf(" -C, --coerce JSON only: Coerce non-JSON plist types to JSON-compatible\n"); | 78 | printf(" -C, --coerce JSON + OpenStep only: Coerce non-compatible plist types\n"); |
| 79 | printf(" representations. Date values become ISO 8601 strings,\n"); | 79 | printf(" to JSON/OpenStep compatible representations.\n"); |
| 80 | printf(" data values become Base64-encoded strings, and UID values\n"); | 80 | printf(" Date values become ISO 8601 strings,\n"); |
| 81 | printf(" become integers. Implied when invoked as plist2json.\n"); | 81 | printf(" data values become Base64-encoded strings (JSON),\n"); |
| 82 | printf(" UID values become integers,\n"); | ||
| 83 | printf(" boolean becomes 1 or 0 (OpenStep),\n"); | ||
| 84 | printf(" and NULL becomes a string 'NULL' (OpenStep)\n"); | ||
| 85 | printf(" This options is implied when invoked as plist2json.\n"); | ||
| 82 | printf(" -s, --sort Sort all dictionary nodes lexicographically by key\n"); | 86 | printf(" -s, --sort Sort all dictionary nodes lexicographically by key\n"); |
| 83 | printf(" before converting to the output format.\n"); | 87 | printf(" before converting to the output format.\n"); |
| 84 | printf(" -d, --debug Enable extended debug output\n"); | 88 | printf(" -d, --debug Enable extended debug output\n"); |
| @@ -431,7 +435,10 @@ int main(int argc, char *argv[]) | |||
| 431 | if (options->flags & OPT_COERCE) wropts |= PLIST_OPT_COERCE; | 435 | if (options->flags & OPT_COERCE) wropts |= PLIST_OPT_COERCE; |
| 432 | output_res = plist_to_json_with_options(root_node, &plist_out, &size, wropts); | 436 | output_res = plist_to_json_with_options(root_node, &plist_out, &size, wropts); |
| 433 | } else if (options->out_fmt == PLIST_FORMAT_OSTEP) { | 437 | } else if (options->out_fmt == PLIST_FORMAT_OSTEP) { |
| 434 | output_res = plist_to_openstep(root_node, &plist_out, &size, !(options->flags & OPT_COMPACT)); | 438 | plist_write_options_t wropts = PLIST_OPT_NONE; |
| 439 | if (options->flags & OPT_COMPACT) wropts |= PLIST_OPT_COMPACT; | ||
| 440 | if (options->flags & OPT_COERCE) wropts |= PLIST_OPT_COERCE; | ||
| 441 | output_res = plist_to_openstep_with_options(root_node, &plist_out, &size, wropts); | ||
| 435 | } else { | 442 | } else { |
| 436 | plist_write_to_stream(root_node, stdout, options->out_fmt, PLIST_OPT_PARTIAL_DATA); | 443 | plist_write_to_stream(root_node, stdout, options->out_fmt, PLIST_OPT_PARTIAL_DATA); |
| 437 | plist_free(root_node); | 444 | plist_free(root_node); |
