The tree functions are more widely available. Signed-off-by: Ulf Hermann <ulf.herm...@qt.io> --- src/ChangeLog | 4 ++++ src/ar.c | 77 ++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog index 332b07c..32cd0c3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2017-05-04 Ulf Hermann <ulf.herm...@qt.io> + * ar.c: Use trees rather than hashes. + +2017-05-04 Ulf Hermann <ulf.herm...@qt.io> + * ar.c: Use octal numbers instead of permission macros. * elfcompress.c: Likewise. * ranlib.c: Likewise. diff --git a/src/ar.c b/src/ar.c index cc47f10..a13420c 100644 --- a/src/ar.c +++ b/src/ar.c @@ -439,6 +439,20 @@ copy_content (Elf *elf, int newfd, off_t off, size_t n) static int +string_compare (const void *a, const void *b) +{ + return strcmp((const char *)a, (const char *)b); +} + + +void +free_node (void *node) +{ + (void) node; +} + + +static int do_oper_extract (int oper, const char *arfname, char **argv, int argc, long int instance) { @@ -469,13 +483,11 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, Elf *elf; int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, &elf, NULL, false); - if (hcreate (2 * argc) == 0) - error (EXIT_FAILURE, errno, gettext ("cannot create hash table")); + void *root = NULL; for (int cnt = 0; cnt < argc; ++cnt) { - ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] }; - if (hsearch (entry, ENTER) == NULL) + if (tsearch (argv[cnt], &root, &string_compare) == NULL) error (EXIT_FAILURE, errno, gettext ("cannot insert into hash table")); } @@ -517,12 +529,10 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, bool do_extract = argc <= 0; if (!do_extract) { - ENTRY entry; - entry.key = arhdr->ar_name; - ENTRY *res = hsearch (entry, FIND); + void *res = tfind (arhdr->ar_name, &root, &string_compare); if (res != NULL && (instance < 0 || instance-- == 0) - && !found[(char **) res->data - argv]) - found[(char **) res->data - argv] = do_extract = true; + && !found[(char **) res - argv]) + found[(char **) res - argv] = do_extract = true; } if (do_extract) @@ -741,7 +751,8 @@ cannot rename temporary file to %.*s"), error (1, 0, "%s: %s", arfname, elf_errmsg (-1)); } - hdestroy (); + tdestroy(root, &free_node); + root = NULL; if (force_symtab) { @@ -921,13 +932,11 @@ do_oper_delete (const char *arfname, char **argv, int argc, struct stat st; int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, &elf, &st, false); - if (hcreate (2 * argc) == 0) - error (EXIT_FAILURE, errno, gettext ("cannot create hash table")); + void *root = NULL; for (int cnt = 0; cnt < argc; ++cnt) { - ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] }; - if (hsearch (entry, ENTER) == NULL) + if (tsearch (argv[cnt], &root, &string_compare) == NULL) error (EXIT_FAILURE, errno, gettext ("cannot insert into hash table")); } @@ -949,12 +958,10 @@ do_oper_delete (const char *arfname, char **argv, int argc, bool do_delete = argc <= 0; if (!do_delete) { - ENTRY entry; - entry.key = arhdr->ar_name; - ENTRY *res = hsearch (entry, FIND); + void *res = tfind (arhdr->ar_name, &root, &string_compare); if (res != NULL && (instance < 0 || instance-- == 0) - && !found[(char **) res->data - argv]) - found[(char **) res->data - argv] = do_delete = true; + && !found[(char **) res - argv]) + found[(char **) res - argv] = do_delete = true; } if (do_delete) @@ -995,7 +1002,8 @@ do_oper_delete (const char *arfname, char **argv, int argc, arlib_finalize (); - hdestroy (); + tdestroy (root, &free_node); + root = NULL; /* Create a new, temporary file in the same directory as the original file. */ @@ -1093,6 +1101,13 @@ no0print (bool ofmt, char *buf, int bufsize, long int val) static int +basename_compare(const void *a, const void *b) +{ + return strcmp(basename((const char *)a), basename((const char *)b)); +} + + +static int do_oper_insert (int oper, const char *arfname, char **argv, int argc, const char *member) { @@ -1100,6 +1115,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, Elf *elf; struct stat st; int fd = open_archive (arfname, O_RDONLY | O_BINARY, 0, &elf, &st, oper != oper_move); + void *root = NULL; /* List of the files we keep. */ struct armem *all = NULL; @@ -1127,15 +1143,9 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, index. */ if (oper != oper_qappend) { - if (hcreate (2 * argc) == 0) - error (EXIT_FAILURE, errno, gettext ("cannot create hash table")); - for (int cnt = 0; cnt < argc; ++cnt) { - ENTRY entry; - entry.key = full_path ? argv[cnt] : basename (argv[cnt]); - entry.data = &argv[cnt]; - if (hsearch (entry, ENTER) == NULL) + if (tsearch (argv[cnt], &root, full_path ? &basename_compare : &string_compare) == NULL) error (EXIT_FAILURE, errno, gettext ("cannot insert into hash table")); } @@ -1178,12 +1188,10 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, member = NULL; } - ENTRY entry; - entry.key = arhdr->ar_name; - ENTRY *res = hsearch (entry, FIND); - if (res != NULL && found[(char **) res->data - argv] == NULL) + void *res = tfind(arhdr->ar_name, &root, full_path ? &basename_compare : &string_compare); + if (res != NULL && found[(char **) res - argv] == NULL) { - found[(char **) res->data - argv] = newp; + found[(char **) res - argv] = newp; /* If we insert before or after a certain element move all files to a special list. */ @@ -1215,7 +1223,10 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, } if (oper != oper_qappend) - hdestroy (); + { + tdestroy(root, &free_node); + root = NULL; + } no_old: if (member != NULL) -- 2.1.4