summaryrefslogtreecommitdiffstats
path: root/src/oplist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/oplist.c')
-rw-r--r--src/oplist.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/oplist.c b/src/oplist.c
index 277693f..680873c 100644
--- a/src/oplist.c
+++ b/src/oplist.c
@@ -37,6 +37,7 @@
37 37
38#include "plist.h" 38#include "plist.h"
39#include "strbuf.h" 39#include "strbuf.h"
40#include "hashtable.h"
40 41
41#ifdef DEBUG 42#ifdef DEBUG
42static int plist_ostep_debug = 0; 43static int plist_ostep_debug = 0;
@@ -359,18 +360,27 @@ static int num_digits_u(uint64_t i)
359 return n; 360 return n;
360} 361}
361 362
362static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify) 363static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify, hashtable_t *visited)
363{ 364{
364 plist_data_t data; 365 plist_data_t data;
365 if (!node) { 366 if (!node) {
366 return PLIST_ERR_INVALID_ARG; 367 return PLIST_ERR_INVALID_ARG;
367 } 368 }
369
370 if (hash_table_lookup(visited, node)) {
371 PLIST_OSTEP_WRITE_ERR("circular reference detected\n");
372 return PLIST_ERR_CIRCULAR_REF;
373 }
374
375 // mark as visited
376 hash_table_insert(visited, node, (void*)1);
377
368 data = plist_get_data(node); 378 data = plist_get_data(node);
369 if (node->children) { 379 if (node->children) {
370 node_t ch; 380 node_t ch;
371 unsigned int n_children = node_n_children(node); 381 unsigned int n_children = node_n_children(node);
372 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) { 382 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
373 plist_err_t res = node_estimate_size(ch, size, depth + 1, prettify); 383 plist_err_t res = _node_estimate_size(ch, size, depth + 1, prettify, visited);
374 if (res < 0) { 384 if (res < 0) {
375 return res; 385 return res;
376 } 386 }
@@ -446,6 +456,15 @@ static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t dept
446 return PLIST_ERR_SUCCESS; 456 return PLIST_ERR_SUCCESS;
447} 457}
448 458
459static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t depth, int prettify)
460{
461 hashtable_t *visited = hash_table_new(plist_node_ptr_hash, plist_node_ptr_compare, NULL);
462 if (!visited) return PLIST_ERR_NO_MEM;
463 plist_err_t err = _node_estimate_size(node, size, depth, prettify, visited);
464 hash_table_destroy(visited);
465 return err;
466}
467
449plist_err_t plist_to_openstep(plist_t plist, char **openstep, uint32_t* length, int prettify) 468plist_err_t plist_to_openstep(plist_t plist, char **openstep, uint32_t* length, int prettify)
450{ 469{
451 uint64_t size = 0; 470 uint64_t size = 0;