From ac36e134d96fa71a2f5c141058e06b57bcc72136 Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Thu, 18 Feb 2021 17:03:28 +0000 Subject: libctf: reimplement many _iter iterators in terms of _next Ever since the generator-style _next iterators were introduced, there have been separate implementations of the functional-style _iter iterators that do the same thing as _next. This is annoying and adds more dependencies on the internal guts of the file format. Rip them all out and replace them with the corresponding _next iterators. Only ctf_archive_raw_iter and ctf_label_iter survive, the former because there is no access to the raw binary data of archives via any _next iterator, and the latter because ctf_label_next hasn't been implemented (because labels are currently not used for anything). Tested by reverting the change (already applied) that reimplemented ctf_member_iter in terms of ctf_member_next, then verifying that the _iter and _next iterators produced the same results for every iterable entity within a large type archive. libctf/ChangeLog 2021-03-02 Nick Alcock * ctf-types.c (ctf_member_iter): Move 'rc' to an inner scope. (ctf_enum_iter): Reimplement in terms of ctf_enum_next. (ctf_type_iter): Reimplement in terms of ctf_type_next. (ctf_type_iter_all): Likewise. (ctf_variable_iter): Reimplement in terms of ctf_variable_next. * ctf-archive.c (ctf_archive_iter_internal): Remove. (ctf_archive_iter): Reimplement in terms of ctf_archive_next. --- libctf/ctf-archive.c | 68 ++++++++++++---------------------------------------- 1 file changed, 15 insertions(+), 53 deletions(-) (limited to 'libctf/ctf-archive.c') diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c index 6e1bf15..8b8e170 100644 --- a/libctf/ctf-archive.c +++ b/libctf/ctf-archive.c @@ -1043,70 +1043,32 @@ ctf_archive_raw_iter (const ctf_archive_t *arc, return -EINVAL; /* Not supported. */ } -/* Iterate over all CTF files in an archive. We pass all CTF files in turn to - the specified callback function. */ -static int -ctf_archive_iter_internal (const ctf_archive_t *wrapper, - const struct ctf_archive *arc, - const ctf_sect_t *symsect, - const ctf_sect_t *strsect, - ctf_archive_member_f *func, void *data) +/* Iterate over all CTF files in an archive: public entry point. We pass all + CTF files in turn to the specified callback function. */ +int +ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func, + void *data) { - int rc; - size_t i; - ctf_dict_t *f; - struct ctf_archive_modent *modent; - const char *nametbl; - - modent = (ctf_archive_modent_t *) ((char *) arc - + sizeof (struct ctf_archive)); - nametbl = (((const char *) arc) + le64toh (arc->ctfa_names)); + ctf_next_t *i = NULL; + ctf_dict_t *fp; + const char *name; + int err; - for (i = 0; i < le64toh (arc->ctfa_ndicts); i++) + while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL) { - const char *name; + int rc; - name = &nametbl[le64toh (modent[i].name_offset)]; - if ((f = ctf_dict_open_internal (arc, symsect, strsect, - name, - wrapper->ctfi_symsect_little_endian, - &rc)) == NULL) - return rc; - - f->ctf_archive = (ctf_archive_t *) wrapper; - ctf_arc_import_parent (wrapper, f); - if ((rc = func (f, name, data)) != 0) + if ((rc = func (fp, name, data)) != 0) { - ctf_dict_close (f); + ctf_dict_close (fp); + ctf_next_destroy (i); return rc; } - - ctf_dict_close (f); + ctf_dict_close (fp); } return 0; } -/* Iterate over all CTF files in an archive: public entry point. We pass all - CTF files in turn to the specified callback function. */ -int -ctf_archive_iter (const ctf_archive_t *arc, ctf_archive_member_f *func, - void *data) -{ - const ctf_sect_t *symsect = &arc->ctfi_symsect; - const ctf_sect_t *strsect = &arc->ctfi_strsect; - - if (symsect->cts_name == NULL) - symsect = NULL; - if (strsect->cts_name == NULL) - strsect = NULL; - - if (arc->ctfi_is_archive) - return ctf_archive_iter_internal (arc, arc->ctfi_archive, symsect, strsect, - func, data); - - return func (arc->ctfi_dict, _CTF_SECTION, data); -} - /* Iterate over all CTF files in an archive, returning each dict in turn as a ctf_dict_t, and NULL on error or end of iteration. It is the caller's responsibility to close it. Parent dicts may be skipped. -- cgit v1.1