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  <nick.alcock@oracle.com>

	* 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.
This commit is contained in:
Nick Alcock 2021-02-18 17:03:28 +00:00
parent eaa2913a7a
commit ac36e134d9
3 changed files with 70 additions and 125 deletions

View file

@ -1043,68 +1043,30 @@ 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)
{
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));
for (i = 0; i < le64toh (arc->ctfa_ndicts); i++)
{
const char *name;
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)
{
ctf_dict_close (f);
return rc;
}
ctf_dict_close (f);
}
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;
ctf_next_t *i = NULL;
ctf_dict_t *fp;
const char *name;
int err;
if (symsect->cts_name == NULL)
symsect = NULL;
if (strsect->cts_name == NULL)
strsect = NULL;
while ((fp = ctf_archive_next (arc, &i, &name, 0, &err)) != NULL)
{
int rc;
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);
if ((rc = func (fp, name, data)) != 0)
{
ctf_dict_close (fp);
ctf_next_destroy (i);
return rc;
}
ctf_dict_close (fp);
}
return 0;
}
/* Iterate over all CTF files in an archive, returning each dict in turn as a