From 3a43995fb5039a692f7a311ee870cbe1b571ad54 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 1 Sep 2024 18:37:47 +0200 Subject: [PATCH] =?UTF-8?q?Made=20ECMA-119=20tree=20sorting=20deterministi?= =?UTF-8?q?c=20with=20different=20qsort=20implementations.=20By=20Henrik?= =?UTF-8?q?=20Lindstr=C3=B6m.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libisofs/ecma119_tree.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/libisofs/ecma119_tree.c b/libisofs/ecma119_tree.c index 825c68b..2798d9e 100644 --- a/libisofs/ecma119_tree.c +++ b/libisofs/ecma119_tree.c @@ -595,6 +595,28 @@ int cmp_node_name(const void *f1, const void *f2) return strcmp(f->iso_name, g->iso_name); } +/** + * Compare the iso name of two ECMA-119 nodes, without equivalences. + * Nodes with equal iso names are instead ordered by their real names. + * + * This is used to make the initial tree sort deterministic, before + * iso names are mangled to become unique. + */ +static +int cmp_node_name_tiebreak(const void *f1, const void *f2) +{ + Ecma119Node *f, *g; + int cmp; + + cmp = cmp_node_name(f1, f2); + if (cmp) + return cmp; + + f = *((Ecma119Node**)f1); + g = *((Ecma119Node**)f2); + return strcmp(f->node->name, g->node->name); +} + /** * Sorts a the children of each directory in the ECMA-119 tree represented * by \p root, according to the order specified in ECMA-119, section 9.3. @@ -607,7 +629,7 @@ void sort_tree(Ecma119Node *root) if (root->info.dir->children == NULL) return; qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*), - cmp_node_name); + cmp_node_name_tiebreak); for (i = 0; i < root->info.dir->nchildren; i++) { if (root->info.dir->children[i]->type == ECMA119_DIR) sort_tree(root->info.dir->children[i]);