]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
libctf, include, gdb: API review: delete ctf_*_iter
authorNick Alcock <nick.alcock@oracle.com>
Thu, 6 Nov 2025 13:43:50 +0000 (13:43 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Tue, 9 Dec 2025 13:02:30 +0000 (13:02 +0000)
These functions are all redundant to the corresponding *_next function,
are usually less pleasant to use, and are convertible into trivial while
loops with very little effort.  It's time to drop them.

gdb/ctfread.c
include/ctf-api.h
libctf/ctf-archive.c
libctf/ctf-create.c
libctf/ctf-dump.c
libctf/ctf-types.c
libctf/libctf.ver
libctf/testsuite/libctf-lookup/enum.c

index 50ed21afe79c7d9dbe04311cf310624ed71aac8c..415d4e8c3dfddaf72866fc0e0cd9ca6bae439f07 100644 (file)
@@ -183,7 +183,8 @@ struct ctf_per_tu_data
 
 /* Local function prototypes */
 
-static int ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg);
+static void ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid,
+                            struct ctf_context *ccp);
 
 static struct type *read_array_type (struct ctf_context *cp, ctf_id_t tid);
 
@@ -316,7 +317,7 @@ ctf_init_float_type (struct objfile *objfile,
    and ARG contains the ctf_field_info.  */
 
 static int
-ctf_add_member_cb (ctf_dict_t *unused,
+ctf_add_member_cb (ctf_dict_t *dict,
                   const char *name,
                   ctf_id_t tid,
                   unsigned long offset,
@@ -333,14 +334,14 @@ ctf_add_member_cb (ctf_dict_t *unused,
   fp = &new_field.field;
   fp->set_name (name);
 
-  kind = ctf_type_kind (ccp->dict, tid);
+  kind = ctf_type_kind (dict, tid);
   t = fetch_tid_type (ccp, tid);
   if (t == nullptr)
     {
       t = read_type_record (ccp, tid);
       if (t == nullptr)
        {
-         complaint (_("ctf_add_member_cb: %s has NO type (%ld)"), name, tid);
+         complaint (_("ctf_add_member_cb: %s has no type (%ld)"), name, tid);
          t = builtin_type (ccp->of)->builtin_error;
          set_tid_type (ccp->of, tid, t);
        }
@@ -361,10 +362,9 @@ ctf_add_member_cb (ctf_dict_t *unused,
 /* Callback to add member NAME of EVAL to an enumeration type.
    ARG contains the ctf_field_info.  */
 
-static int
-ctf_add_enum_member_cb (const char *name, int64_t enum_value, void *arg)
+static void
+ctf_add_enum_member_cb (const char *name, int64_t enum_value, ctf_field_info *fip)
 {
-  struct ctf_field_info *fip = (struct ctf_field_info *) arg;
   struct ctf_nextfield new_field;
   struct field *fp;
   struct ctf_context *ccp = fip->cur_context;
@@ -389,8 +389,6 @@ ctf_add_enum_member_cb (const char *name, int64_t enum_value, void *arg)
     }
 
   fip->fields.emplace_back (new_field);
-
-  return 0;
 }
 
 /* Add a new type symbol entry, with its name from TID, its access
@@ -562,10 +560,23 @@ process_struct_members (struct ctf_context *ccp,
                        struct type *type)
 {
   struct ctf_field_info fi;
+  ctf_next_t *it = NULL;
+  const char *membname;
+  ctf_id_t membtype;
+  ssize_t offset;
+  int bit_width;
 
   fi.cur_context = ccp;
-  if (ctf_member_iter (ccp->dict, tid, ctf_add_member_cb, &fi) == CTF_ERR)
-    complaint (_("ctf_member_iter process_struct_members failed - %s"),
+  while ((offset = ctf_member_next (ccp->dict, tid, &it, &membname, &membtype,
+                                   &bit_width, 0)) >= 0)
+    {
+      if (ctf_add_member_cb (ccp->dict, membname, membtype, offset, bit_width,
+                            &fi) < 0)
+       complaint (_("ctf_add_member_cb process_struct_members failed - %s"),
+                  ctf_errmsg (ctf_errno (ccp->dict)));
+    }
+  if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+    complaint (_("process_struct_members iteration over members failed - %s"),
               ctf_errmsg (ctf_errno (ccp->dict)));
 
   /* Attach fields to the type.  */
@@ -665,13 +676,19 @@ process_enum_type (struct ctf_context *ccp, ctf_id_t tid)
 {
   struct type *type;
   struct ctf_field_info fi;
+  ctf_next_t *it = NULL;
+  const char *name;
+  int64_t value;
 
   type = read_enum_type (ccp, tid);
 
   fi.cur_context = ccp;
   fi.ptype = type;
-  if (ctf_enum_iter (ccp->dict, tid, ctf_add_enum_member_cb, &fi) == CTF_ERR)
-    complaint (_("ctf_enum_iter process_enum_type failed - %s"),
+  while ((name = ctf_enum_next (ccp->dict, tid, &it, &value)) != NULL)
+    ctf_add_enum_member_cb (name, value, &fi);
+
+  if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+    complaint (_("ctf_enum_next process_enum_type failed - %s"),
               ctf_errmsg (ctf_errno (ccp->dict)));
 
   /* Attach fields to the type.  */
@@ -968,17 +985,16 @@ read_type_record (struct ctf_context *ccp, ctf_id_t tid)
 
 /* Callback to add type TID to the symbol table.  */
 
-static int
-ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg)
+static void
+ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid, struct ctf_context *ccp)
 {
-  struct ctf_context *ccp = (struct ctf_context *) arg;
   struct type *type;
   uint32_t kind;
 
   /* Check if tid's type has already been defined.  */
   type = get_tid_type (ccp->of, tid);
   if (type != nullptr)
-    return 0;
+    return;
 
   ctf_id_t btid = ctf_type_reference (ccp->dict, tid);
   kind = ctf_type_kind (ccp->dict, tid);
@@ -1027,16 +1043,14 @@ ctf_add_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg)
       default:
        break;
     }
-
-  return 0;
 }
 
 /* Callback to add variable NAME with TID to the symbol table.  */
 
-static int
-ctf_add_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id, void *arg)
+static void
+ctf_add_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id,
+               struct ctf_context *ccp)
 {
-  struct ctf_context *ccp = (struct ctf_context *) arg;
   struct symbol *sym = nullptr;
   struct type *type;
   uint32_t kind;
@@ -1067,8 +1081,6 @@ ctf_add_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id, void *arg)
 
   add_symbol_to_list (sym, ccp->builder->get_global_symbols ());
   set_symbol_address (ccp->of, sym, name);
-
-  return 0;
 }
 
 /* Add entries in either data objects or function info section, controlled
@@ -1204,20 +1216,28 @@ void
 ctf_psymtab::expand_psymtab (struct objfile *objfile)
 {
   struct ctf_context *ccp;
+  ctf_next_t *it = NULL;
+  ctf_id_t type;
+  const char *name;
 
   gdb_assert (!readin);
 
   ccp = &context;
 
   /* Iterate over entries in data types section.  */
-  if (ctf_type_iter (ccp->dict, ctf_add_type_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_type_iter psymtab_to_symtab failed - %s"),
-              ctf_errmsg (ctf_errno (ccp->dict)));
+  while ((type = ctf_type_next (ccp->dict, &it, NULL, 0)) != CTF_ERR)
+    ctf_add_type_cb (ccp->dict, type, ccp);
 
+  if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+    complaint (_("ctf_type_next psymtab_to_symtab failed - %s"),
+              ctf_errmsg (ctf_errno (ccp->dict)));
 
   /* Iterate over entries in variable info section.  */
-  if (ctf_variable_iter (ccp->dict, ctf_add_var_cb, ccp) == CTF_ERR)
-    complaint (_("ctf_variable_iter psymtab_to_symtab failed - %s"),
+  while ((type = ctf_variable_next (ccp->dict, &it, &name)) != CTF_ERR)
+    ctf_add_var_cb (ccp->dict, name, type, ccp);
+
+  if (ctf_errno (ccp->dict) != ECTF_NEXT_END)
+    complaint (_("ctf_variable_next psymtab_to_symtab failed - %s"),
               ctf_errmsg (ctf_errno (ccp->dict)));
 
   /* Add entries in data objects and function info sections.  */
@@ -1303,15 +1323,12 @@ create_partial_symtab (const char *name,
 
 /* Callback to add type TID to partial symbol table.  */
 
-static int
-ctf_psymtab_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg)
+static void
+ctf_psymtab_type_cb (ctf_dict_t *fp, ctf_id_t tid, struct ctf_context *ccp)
 {
-  struct ctf_context *ccp;
   uint32_t kind;
   int section = -1;
 
-  ccp = (struct ctf_context *) arg;
-
   domain_enum domain = UNDEF_DOMAIN;
   location_class loc_class = LOC_UNDEF;
   kind = ctf_type_kind (ccp->dict, tid);
@@ -1339,30 +1356,28 @@ ctf_psymtab_type_cb (ctf_dict_t *fp, ctf_id_t tid, void *arg)
       loc_class = LOC_TYPEDEF;
       break;
     case CTF_K_UNKNOWN:
-      return 0;
+      return;
     }
 
   const char *name = ctf_type_name_raw (ccp->dict, tid);
   if (name == nullptr || *name == '\0')
-    return 0;
+    return;
 
   ccp->pst->add_psymbol (name, false,
                         domain, loc_class, section,
                         psymbol_placement::GLOBAL,
                         unrelocated_addr (0),
                         language_c, ccp->partial_symtabs, ccp->of);
-
-  return 0;
 }
 
 /* Callback to add variable NAME with ID to partial symbol table.  */
 
-static int
-ctf_psymtab_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id, void *arg)
+static void
+ctf_psymtab_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id,
+                   struct ctf_context *ccp)
 {
-  struct ctf_context *ccp = (struct ctf_context *) arg;
-
   uint32_t kind = ctf_type_kind (ccp->dict, id);
+
   ccp->pst->add_psymbol (name, true,
                         kind == CTF_K_FUNCTION
                         ? FUNCTION_DOMAIN
@@ -1371,7 +1386,6 @@ ctf_psymtab_var_cb (ctf_dict_t *fp, const char *name, ctf_id_t id, void *arg)
                         psymbol_placement::GLOBAL,
                         unrelocated_addr (0),
                         language_c, ccp->partial_symtabs, ccp->of);
-  return 0;
 }
 
 /* Setup partial_symtab's describing each source file for which
@@ -1383,6 +1397,9 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
 {
   struct objfile *of = tup->of;
   bool isparent = false;
+  ctf_next_t *it = NULL;
+  ctf_id_t type;
+  const char *name;
 
   if (strcmp (fname, ".ctf") == 0)
     {
@@ -1397,12 +1414,18 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
   if (isparent == false)
     ccx->pst = pst;
 
-  if (ctf_type_iter (dict, ctf_psymtab_type_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_type_iter scan_partial_symbols failed - %s"),
+  while ((type = ctf_type_next (dict, &it, NULL, 0)) != CTF_ERR)
+    ctf_psymtab_type_cb (dict, type, ccx);
+
+  if (ctf_errno (dict) != ECTF_NEXT_END)
+    complaint (_("ctf_type_next scan_partial_symbols failed - %s"),
               ctf_errmsg (ctf_errno (dict)));
 
-  if (ctf_variable_iter (dict, ctf_psymtab_var_cb, ccx) == CTF_ERR)
-    complaint (_("ctf_variable_iter scan_partial_symbols failed - %s"),
+  while ((type = ctf_variable_next (dict, &it, &name)) != CTF_ERR)
+    ctf_psymtab_var_cb (dict, name, type, ccx);
+
+  if (ctf_errno (dict) != ECTF_NEXT_END)
+    complaint (_("ctf_variable_next scan_partial_symbols failed - %s"),
               ctf_errmsg (ctf_errno (dict)));
 
   /* Scan CTF object and function sections which correspond to each
@@ -1416,10 +1439,10 @@ scan_partial_symbols (ctf_dict_t *dict, psymtab_storage *partial_symtabs,
 
 /* Callback to build the psymtab for archive member NAME.  */
 
-static int
-build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
+static void
+build_ctf_archive_member (ctf_dict_t *ctf, const char *name,
+                         struct ctf_per_tu_data *tup)
 {
-  struct ctf_per_tu_data *tup = (struct ctf_per_tu_data *) arg;
   ctf_dict_t *parent = tup->dict;
 
   if (strcmp (name, ".ctf") != 0)
@@ -1433,8 +1456,6 @@ build_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
 
   psymtab_storage *pss = tup->psf->get_partial_symtabs ().get ();
   scan_partial_symbols (ctf, pss, tup, name);
-
-  return 0;
 }
 
 /* Read CTF debugging information from a BFD section.  This is
@@ -1446,6 +1467,9 @@ elfctf_build_psymtabs (struct objfile *of)
 {
   struct ctf_per_tu_data pcu;
   bfd *abfd = of->obfd.get ();
+  ctf_next_t *it = NULL;
+  ctf_dict_t *ctf;
+  const char *name;
   ctf_error_t err;
 
   ctf_archive_t *arc = ctf_bfdopen (abfd, &err);
@@ -1467,8 +1491,13 @@ elfctf_build_psymtabs (struct objfile *of)
   of->qf.emplace_front (psf);
   pcu.psf = psf;
 
-  if (ctf_archive_iter (arc, build_ctf_archive_member, &pcu) < 0)
-    error (_("ctf_archive_iter failed in input file %s: - %s"),
+  while ((ctf = ctf_archive_next (arc, &it, &name, 0, &err)) != NULL)
+    {
+      build_ctf_archive_member (ctf, name, &pcu);
+      ctf_dict_close (ctf);
+    }
+  if (err != ECTF_NEXT_END)
+    error (_("ctf_archive_next failed in input file %s: - %s"),
           bfd_get_filename (abfd), ctf_errmsg (err));
 }
 
index 5d614439809f95418f492930015cc0ef0baa5e19..afa4e8289db7b1783f3f90f5e31bfcc3b62601bd 100644 (file)
@@ -347,18 +347,6 @@ _CTF_ERRORS
 typedef int ctf_visit_f (ctf_dict_t *, const char *name, ctf_id_t type,
                         size_t offset, int bit_width, int depth,
                         void *arg);
-typedef int ctf_member_f (ctf_dict_t *, const char *name, ctf_id_t membtype,
-                         size_t offset, int bit_width, void *arg);
-typedef int ctf_enum_f (const char *name, int64_t val, void *arg);
-typedef int ctf_unsigned_enum_f (const char *name, uint64_t val, void *arg);
-typedef int ctf_variable_f (ctf_dict_t *, const char *name, ctf_id_t type,
-                           void *arg);
-typedef int ctf_datasec_var_f (ctf_dict_t *fp, ctf_id_t type, size_t offset,
-                              size_t datasec_size, void *arg);
-typedef int ctf_type_f (ctf_dict_t *, ctf_id_t type, void *arg);
-typedef int ctf_type_all_f (ctf_dict_t *, ctf_id_t type, int flag, void *arg);
-typedef int ctf_type_kind_f (ctf_dict_t *, ctf_id_t type, int kind, void *arg);
-typedef int ctf_archive_member_f (ctf_dict_t *fp, const char *name, void *arg);
 typedef int ctf_archive_raw_member_f (const char *name, const void *content,
                                      size_t len, void *arg);
 typedef char *ctf_dump_decorate_f (ctf_sect_names_t sect,
@@ -845,14 +833,12 @@ extern ctf_id_t ctf_decl_tag (ctf_dict_t *, ctf_id_t decl_tag,
    the members of unnamed structs nested within this struct as if they were
    direct members, if CTF_MN_RECURSE is passed in the flags.  */
 
-extern int ctf_member_iter (ctf_dict_t *, ctf_id_t, ctf_member_f *, void *);
 extern ssize_t ctf_member_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
                                const char **name, ctf_id_t *membtype,
                                int *bit_width, int flags);
 
-/* Return all enumeration constants in a given enum type.  The return value, and
-   VAL argument, may need to be cast to uint64_t: see ctf_enum_unsigned().  */
-extern int64_t ctf_enum_iter (ctf_dict_t *, ctf_id_t, ctf_enum_f *, void *);
+/* Return all enumeration constants in a given enum type.  The VAL argument may
+   need to be cast to uint64_t: see ctf_enum_unsigned(). */
 extern const char *ctf_enum_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
                                  int64_t *);
 
@@ -883,50 +869,40 @@ extern ctf_id_t ctf_arc_lookup_enumerator_next (ctf_archive_t *, const char *nam
                                                ctf_next_t **, int64_t *enum_value,
                                                ctf_dict_t **dict, ctf_error_t *errp);
 
-/* Iterate over all types in a dict.  ctf_type_iter_all recurses over all types:
-   ctf_type_iter recurses only over types with user-visible names (for which
-   CTF_ADD_ROOT was passed).  All such types are returned, even if they are
-   things like pointers that intrinsically have no name: this is the only effect
-   of CTF_ADD_ROOT for such types.  ctf_type_next allows you to choose whether
-   to see non-root types or not with the want_hidden arg: if set, the flag (if
-   passed) returns the non-root state of each type in turn.  Types in parent
-   dictionaries are not returned.
+/* Iterate over all types, kinds, variables, or datasecs in a dict.
+   ctf_type_next returns all types in a dict in turn, allowing you to choose
+   whether to see conflicting types or not with the want_hidden arg: if set, the
+   flag (if passed) returns the conflicting state of each type in turn.  Types
+   in parent dictionaries are not returned.  Note that this is the opposite of
+   the convention in the old API: a true value for the flag argument used to
+   mean it is visible; now it means it is conflicting.
 
    These days, even variables are included in the things returned by ctf_type*()
    (type kind CTF_K_VAR).  */
 
-extern int ctf_type_iter (ctf_dict_t *, ctf_type_f *, void *);
-extern int ctf_type_iter_all (ctf_dict_t *, ctf_type_all_f *, void *);
-extern int ctf_type_kind_iter (ctf_dict_t *, int kind, ctf_type_kind_f *, void *);
 extern ctf_id_t ctf_type_next (ctf_dict_t *, ctf_next_t **,
                               int *flag, int want_hidden);
 extern ctf_id_t ctf_type_kind_next (ctf_dict_t *, ctf_next_t **, int kind);
-
-extern int ctf_variable_iter (ctf_dict_t *, ctf_variable_f *, void *);
 extern ctf_id_t ctf_variable_next (ctf_dict_t *, ctf_next_t **,
                                   const char **);
-
-extern int ctf_datasec_var_iter (ctf_dict_t *, ctf_id_t, ctf_datasec_var_f *,
-                                void *);
 extern ctf_id_t ctf_datasec_var_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
                                      size_t *size, size_t *offset);
 
 /* Iterate over all tags with the given TAG, returning the ID of each tag.  */
 extern ctf_id_t ctf_tag_next (ctf_dict_t *, const char *tag, ctf_next_t **);
 
-/* ctf_archive_iter and ctf_archive_next open each member dict for you,
-   automatically importing any parent dict as usual: ctf_archive_iter closes the
-   dict on return from ctf_archive_member_f, but for ctf_archive_next the caller
-   must close each dict returned.  If skip_parent is set, the parent dict is
-   skipped on the basis that it's already been seen in every child dict (but if
-   no child dicts exist, this will lead to nothing being returned).
+/* ctf_archive_next opens each member dict for you, automatically importing any
+   parent dict as usual: the caller must close each dict returned once done with
+   it, though it may outlive the loop until the archive is closed; the cost of
+   opening is amortized so that repeated calls cost almost nothing.  If
+   skip_parent is set, the parent dict is skipped on the basis that it's already
+   been seen in every child dict (but if no child dicts exist, this will lead to
+   nothing being returned).
 
-   If an open fails, ctf_archive_iter returns -1 early (losing the error), but
-   ctf_archive_next both passes back the error in the passed errp and allows you
-   to iterate past errors (until the usual ECTF_NEXT_END is returned).  */
+   If an open fails, ctf_archive_next both passes back the error in the passed
+   errp and allows you to iterate past errors (until the usual ECTF_NEXT_END is
+   returned).  */
 
-extern int ctf_archive_iter (const ctf_archive_t *, ctf_archive_member_f *,
-                            void *);
 extern ctf_dict_t *ctf_archive_next (const ctf_archive_t *, ctf_next_t **,
                                     const char **, int skip_parent, ctf_error_t *errp);
 
index d6b511f13fb5e5384fb8b25c97a9d5b4cdc73c19..1650f59172761b96fc3404153162b3305b9b9f8a 100644 (file)
@@ -1828,37 +1828,6 @@ ctf_archive_raw_iter (const struct ctf_archive_internal *arci,
   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 struct ctf_archive_internal *arci,
-                 ctf_archive_member_f *func, void *data)
-{
-  ctf_next_t *i = NULL;
-  ctf_dict_t *fp;
-  const char *name;
-  ctf_error_t err = 0;
-
-  while ((fp = ctf_archive_next (arci, &i, &name, 0, &err)) != NULL)
-    {
-      int rc;
-
-      if ((rc = func (fp, name, data)) != 0)
-       {
-         ctf_dict_close (fp);
-         ctf_next_destroy (i);
-         return rc;
-       }
-      ctf_dict_close (fp);
-    }
-  if (err != ECTF_NEXT_END && err != 0)
-    {
-      ctf_next_destroy (i);
-      return -1;
-    }
-  return 0;
-}
-
 /* 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.
index d7f53cb5578e32dbbb0b05c82a84cc75d47046ff..3437c856e9f4a028ecf65a94a851be0db2ddd90b 100644 (file)
@@ -2226,42 +2226,44 @@ typedef struct ctf_bundle
 } ctf_bundle_t;
 
 static int
-enumcmp (const char *name, int64_t value, void *arg)
+enumcmp (ctf_dict_t *fp, ctf_id_t type, ctf_bundle_t *ctb, ctf_dict_t *err_fp)
 {
-  ctf_bundle_t *ctb = arg;
+  ctf_next_t *i = NULL;
+  const char *name;
+  int64_t value;
   int64_t bvalue;
 
-  if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
+  while ((name = ctf_enum_next (fp, type, &i, &value)) != NULL)
     {
-      ctf_err_warn (ctb->ctb_dict, 0, 0,
-                   _("conflict due to enum %s iteration error"), name);
-      return 1;
+      if (ctf_enum_value (ctb->ctb_dict, ctb->ctb_type, name, &bvalue) < 0)
+       {
+         ctf_next_destroy (i);
+         ctf_err_warn (err_fp, 0, ctf_errno (ctb->ctb_dict),
+                       _("conflict due to enum %s iteration error"), name);
+         return 1;
+       }
+      if (value != bvalue)
+       {
+         ctf_next_destroy (i);
+         ctf_err_warn (err_fp, 1, ECTF_CONFLICT,
+                       _("conflict due to enum value change: %li versus %li"),
+                       value, bvalue);
+         return 1;
+       }
     }
-  if (value != bvalue)
+  if (ctf_errno (fp) != ECTF_NEXT_END)
     {
-      ctf_err_warn (ctb->ctb_dict, 1, ECTF_CONFLICT,
-                   _("conflict due to enum value change: %li versus %li"),
-                   value, bvalue);
+      ctf_err_warn (err_fp, 0, ctf_errno (fp),
+                   _("conflict due to enum %s iteration error"), name);
       return 1;
     }
-  return 0;
-}
-
-static int
-enumadd (const char *name, int64_t value, void *arg)
-{
-  ctf_bundle_t *ctb = arg;
 
-  return (ctf_add_enumerator (ctb->ctb_dict, ctb->ctb_type,
-                             name, value) < 0);
+  return 0;
 }
 
-static int
-membcmp (ctf_dict_t *src_fp _libctf_unused_, const char *name,
-        ctf_id_t type _libctf_unused_, size_t offset, int bit_width,
-        void *arg)
+static ctf_ret_t
+membcmp (const char *name, size_t offset, int bit_width, ctf_bundle_t *ctb)
 {
-  ctf_bundle_t *ctb = arg;
   ctf_membinfo_t ctm;
 
   /* Don't check nameless members (e.g. anonymous structs/unions) against each
@@ -2274,7 +2276,7 @@ membcmp (ctf_dict_t *src_fp _libctf_unused_, const char *name,
       ctf_err_warn (ctb->ctb_dict, 0, 0,
                    _("conflict due to struct member %s iteration error"),
                    name);
-      return 1;
+      return -1;
     }
   if (ctm.ctm_offset != offset)
     {
@@ -2282,7 +2284,7 @@ membcmp (ctf_dict_t *src_fp _libctf_unused_, const char *name,
                    _("conflict due to struct member %s offset change: "
                      "%zx versus %zx"),
                    name, ctm.ctm_offset, offset);
-      return 1;
+      return -1;
     }
   if (ctm.ctm_bit_width != bit_width)
     {
@@ -2290,7 +2292,7 @@ membcmp (ctf_dict_t *src_fp _libctf_unused_, const char *name,
                    _("conflict due to struct member %s bit-width change: "
                      "%i versus %i"),
                    name, ctm.ctm_bit_width, bit_width);
-      return 1;
+      return -1;
     }
   return 0;
 }
@@ -2755,13 +2757,20 @@ ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type
                return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
              }
 
-           if (ctf_member_iter (src_fp, src_type, membcmp, &dst))
+           while ((offset = ctf_member_next (src_fp, src_type, &i,
+                                             &membname, NULL, &bit_width, 0)) >= 0)
              {
-               ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
-                             _("conflict for type %s against ID %lx: members "
-                               "differ, see above"), name, dst_type);
-               return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
+               if (membcmp (membname, offset, bit_width, &dst) < 0)
+                 {
+                   ctf_next_destroy (i);
+                   ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
+                                 _("conflict for type %s against ID %lx: members "
+                                   "differ, see above"), name, dst_type);
+                   return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
+                 }
              }
+           if (ctf_errno (src_fp) != ECTF_NEXT_END)
+             return CTF_ERR;                   /* errno is set for us.  */
 
            break;
          }
@@ -2791,7 +2800,7 @@ ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type
                  {
                    if (ctf_errno (dst_fp) != ECTF_NONREPRESENTABLE)
                      {
-                       ctf_next_destroy (i);
+                       ctf_next_destroy (i);   /* errno is set for us.  */
                        break;
                      }
                  }
@@ -2800,7 +2809,7 @@ ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type
            if (ctf_add_member_bitfield (dst_fp, dst_type, membname,
                                         dst_membtype, offset, bit_width) < 0)
              {
-               ctf_next_destroy (i);
+               ctf_next_destroy (i);           /* errno is set for us.  */
                break;
              }
          }
@@ -2822,8 +2831,8 @@ ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type
                              "signedness differs"), name, dst_type);
              return (ctf_set_typed_errno (dst_fp, ECTF_CONFLICT));
            }
-         if (ctf_enum_iter (src_fp, src_type, enumcmp, &dst)
-             || ctf_enum_iter (dst_fp, dst_type, enumcmp, &src))
+         if (enumcmp (src_fp, src_type, &dst, dst_fp)
+             || enumcmp (dst_fp, dst_type, &src, dst_fp))
            {
              ctf_err_warn (dst_fp, 1, ECTF_CONFLICT,
                            _("conflict for enum %s against ID %lx: members "
@@ -2834,17 +2843,37 @@ ctf_add_type_internal (ctf_dict_t *dst_fp, ctf_dict_t *src_fp, ctf_id_t src_type
       else
        {
          ctf_snapshot_id_t snap = ctf_snapshot (dst_fp);
+         ctf_next_t *it = NULL;
+         const char *enum_name;
+         int64_t value;
 
          if (src_type == CTF_K_ENUM)
            dst_type = ctf_add_enum (dst_fp, flag, name);
          else
            dst_type = ctf_add_enum64 (dst_fp, flag, name);
-         if ((dst.ctb_type = dst_type) == CTF_ERR
-             || ctf_enum_iter (src_fp, src_type, enumadd, &dst))
+         if (dst_type == CTF_ERR)
+           goto enum_err;
+
+         while ((enum_name = ctf_enum_next (src_fp, src_type,
+                                            &it, &value)) != NULL)
            {
-             ctf_rollback (dst_fp, snap);
-             return CTF_ERR;                   /* errno is set for us */
+             if (ctf_add_enumerator (dst_fp, dst_type, enum_name, value) < 0)
+               goto enum_err;
            }
+         if (ctf_errno (src_fp) != ECTF_NEXT_END)
+           {
+             ctf_set_errno (dst_fp, ctf_errno (src_fp));
+             goto enum_err;
+           }
+
+         break;
+
+       enum_err:
+         {
+           ctf_next_destroy (it);
+           ctf_rollback (dst_fp, snap);
+           return CTF_ERR;                     /* errno is set for us.  */
+         }
        }
       break;
 
index 284ec07be4e3914248cbaa5aaf33dcba7cae1300..328e5fecf6225d193b99defd3b46868c198531bd 100644 (file)
@@ -692,6 +692,11 @@ ctf_dump_datasecs (ctf_dict_t *fp, ctf_dump_state_t *arg)
 
   while ((type = ctf_type_kind_next (fp, &next, CTF_K_DATASEC)) != CTF_ERR)
     {
+      ctf_next_t *next_var = NULL;
+      ctf_id_t var_type;
+      size_t size;
+      size_t offset;
+
       /* Dump DATASEC name.  */
 
       if (asprintf (&str, "%sSection %s:\n\n", first ? "" : "\n",
@@ -702,12 +707,28 @@ ctf_dump_datasecs (ctf_dict_t *fp, ctf_dump_state_t *arg)
       first = 0;
 
       /* Dump all variables in the datasec.  */
-      if (ctf_datasec_var_iter (fp, type, ctf_dump_var, state) < 0)
-        goto err;
+
+      while ((var_type = ctf_datasec_var_next (fp, type, &next_var, &size,
+                                              &offset)) != CTF_ERR)
+       {
+         if (ctf_dump_var (fp, type, offset, size, state) < 0)
+           {
+             ctf_err_warn (fp, 1, 0, _("cannot dump var %s (%lx) in datasec %s (%lx)\n"),
+                           ctf_type_name_raw (fp, var_type), var_type,
+                           ctf_type_name_raw (fp, type), type);
+             goto err;
+           }
+       }
+      if (ctf_errno (fp) != ECTF_NEXT_END)
+       {
+         ctf_err_warn (fp, 1, 0, _("cannot iterate over vars in datasec %s (%lx)\n"),
+                       ctf_type_name_raw (fp, type), type);
+         goto err;
+       }
     }
   if (ctf_errno (fp) != ECTF_NEXT_END)
     {
-      ctf_err_warn (fp, 1, ctf_errno (fp), _("cannot visit datasecs\n"));
+      ctf_err_warn (fp, 1, ctf_errno (fp), _("cannot iterate over datasecs\n"));
       goto err;
     }
 
@@ -789,13 +810,17 @@ type_hex_digits (ctf_id_t id)
 
 /* Dump a single type into the cds_items.  */
 static int
-ctf_dump_type (ctf_dict_t *fp, ctf_id_t id, int flag, void *arg)
+ctf_dump_type (ctf_dict_t *fp, ctf_id_t id, int hidden,
+              ctf_dump_state_t *state)
 {
   char *str;
   char *indent;
-  ctf_dump_state_t *state = arg;
+  int flag = CTF_ADD_ROOT;
   ctf_dump_membstate_t membstate = { &str, NULL };
 
+  if (hidden)
+    flag = CTF_ADD_NONROOT;
+
   /* Indent neatly.  */
   if (asprintf (&indent, "    %*s", type_hex_digits (id), "") < 0)
     return (ctf_set_errno (fp, ENOMEM));
@@ -976,9 +1001,20 @@ ctf_dump (ctf_dict_t *fp, ctf_dump_state_t **statep, ctf_sect_names_t sect,
            goto err;                   /* errno is set for us.  */
          break;
        case CTF_SECT_TYPE:
-         if (ctf_type_iter_all (fp, ctf_dump_type, state) < 0)
-           goto err;                   /* errno is set for us.  */
-         break;
+         {
+           ctf_next_t *it = NULL;
+           ctf_id_t type;
+           int hidden;
+
+           while ((type = ctf_type_next (fp, &it, &hidden, 1)) != CTF_ERR)
+             {
+               if (ctf_dump_type (fp, type, hidden, state) < 0)
+                 goto err;                     /* errno is set for us.  */
+             }
+           if (ctf_errno (fp) != ECTF_NEXT_END)
+             goto err;                         /* errno is set for us.  */
+           break;
+         }
        case CTF_SECT_STR:
          ctf_dump_str (fp, state);
          break;
index cb7a82fe4a03425e7cafbd74e96aea34e8d56d61..221b6d67853efdabe8a61543b5c446024c04850d 100644 (file)
@@ -162,34 +162,6 @@ ctf_vlen (ctf_dict_t *fp, ctf_id_t type, const ctf_type_t *tp, size_t *vlen_len)
     }
 }
 
-/* Iterate over the members of a STRUCT or UNION.  We pass the name, member
-   type, and offset of each member to the specified callback function.  */
-
-int
-ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
-{
-  ctf_next_t *i = NULL;
-  ssize_t offset;
-  int bit_width;
-  const char *name;
-  ctf_id_t membtype;
-
-  while ((offset = ctf_member_next (fp, type, &i, &name, &membtype,
-                                   &bit_width, 0)) >= 0)
-    {
-      int rc;
-      if ((rc = func (fp, name, membtype, offset, bit_width, arg)) != 0)
-       {
-         ctf_next_destroy (i);
-         return rc;
-       }
-    }
-  if (ctf_errno (fp) != ECTF_NEXT_END)
-    return -1;                                 /* errno is set for us.  */
-
-  return 0;
-}
-
 /* Iterate over the members of a STRUCT or UNION, returning each member's
    offset and optionally name and member type in turn.  On end-of-iteration,
    returns -1.  If FLAGS is CTF_MN_RECURSE, recurse into unnamed members.  */
@@ -371,31 +343,6 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
   return ctf_set_errno (ofp, ECTF_NEXT_END);
 }
 
-/* Iterate over the members of an ENUM.  We pass the string name and associated
-   integer value of each enum element to the specified callback function.  */
-
-int64_t
-ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
-{
-  ctf_next_t *i = NULL;
-  const char *name;
-  int64_t val;
-
-  while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
-    {
-      int rc;
-      if ((rc = func (name, val, arg)) != 0)
-       {
-         ctf_next_destroy (i);
-         return rc;
-       }
-    }
-  if (ctf_errno (fp) != ECTF_NEXT_END)
-    return -1;                                 /* errno is set for us.  */
-
-  return 0;
-}
-
 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
    NULL at end of iteration or error, and optionally passing back the
    enumerand's integer VALue.  */
@@ -500,98 +447,6 @@ ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
   return NULL;
 }
 
-/* Iterate over every root (user-visible) type in the given CTF dict.  We pass
-   the type ID of each type to the specified callback function.
-
-   Does not traverse parent types: you have to do that explicitly.  This is by
-   design, to avoid traversing them more than once if traversing many children
-   of a single parent.  */
-
-int
-ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
-{
-  ctf_next_t *i = NULL;
-  ctf_id_t type;
-
-  while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR)
-    {
-      int rc;
-      if ((rc = func (fp, type, arg)) != 0)
-       {
-         ctf_next_destroy (i);
-         return rc;
-       }
-    }
-  if (ctf_errno (fp) != ECTF_NEXT_END)
-    return -1;                                 /* errno is set for us.  */
-
-  return 0;
-}
-
-/* Iterate over every type in the given CTF dict, user-visible or not.  We pass
-   the type ID of each type to the specified callback function.
-
-   Does not traverse parent types: you have to do that explicitly.  This is by
-   design, to avoid traversing them more than once if traversing many children
-  of a single parent.  */
-
-int
-ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
-{
-  ctf_next_t *i = NULL;
-  ctf_id_t type;
-  int flag;
-
-  while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR)
-    {
-      int rc;
-      if ((rc = func (fp, type, flag, arg)) != 0)
-       {
-         ctf_next_destroy (i);
-         return rc;
-       }
-    }
-  if (ctf_errno (fp) != ECTF_NEXT_END)
-    return -1;                                 /* errno is set for us.  */
-
-  return 0;
-}
-
-/* Iterate over every type of the given kind in the given CTF dict.
-   We pass the type ID of each type to the specified callback function.
-
-   Types returned may be prefixed (but this is normally invisible): you can also
-   specifically traverse prefixed types by asking for CTF_K_BIG or CTF_K_HIDDEN.
-   In this case, the kind of the type returned will be different (the kind
-   prefixed).  Using CTF_K_BIG may have unexpected results if types have been
-   added to this dict since it was opened, since types are only 'unbiggened'
-   upon being written out.
-
-   Does not traverse parent types: you have to do that explicitly.  This is by
-   design, to avoid traversing them more than once if traversing many children
-   of a single parent.  */
-
-int
-ctf_type_kind_iter (ctf_dict_t *fp, int kind, ctf_type_kind_f *func, void *arg)
-{
-  ctf_next_t *i = NULL;
-  ctf_id_t type;
-
-  while ((type = ctf_type_kind_next (fp, &i, kind)) != CTF_ERR)
-    {
-      int rc;
-      if ((rc = func (fp, type, kind, arg)) != 0)
-       {
-         ctf_next_destroy (i);
-         return rc;
-       }
-    }
-  if (ctf_errno (fp) != ECTF_NEXT_END)
-    return -1;                                 /* errno is set for us.  */
-
-  return 0;
-}
-
 /* Iterate over every type in the given CTF dict, optionally including
    non-user-visible types, returning each type ID and hidden flag in turn.
    Returns CTF_ERR on end of iteration or error.
@@ -700,31 +555,6 @@ ctf_type_kind_next (ctf_dict_t *fp, ctf_next_t **it, int kind)
   return ctf_set_typed_errno (fp, ECTF_NEXT_END);
 }
 
-/* Iterate over every variable in the given CTF dict, in arbitrary order.
-   We pass the name of each variable to the specified callback function.  */
-
-int
-ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
-{
-  ctf_next_t *i = NULL;
-  ctf_id_t type;
-  const char *name;
-
-  while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR)
-    {
-      int rc;
-      if ((rc = func (fp, name, type, arg)) != 0)
-       {
-         ctf_next_destroy (i);
-         return rc;
-       }
-    }
-  if (ctf_errno (fp) != ECTF_NEXT_END)
-    return -1;                                 /* errno is set for us.  */
-
-  return 0;
-}
-
 /* Iterate over every variable in the given CTF dict, in arbitrary order,
    returning the name and type of each variable in turn.  The name argument is
    not optional.  Returns CTF_ERR on end of iteration or error.  */
@@ -779,33 +609,6 @@ end:
   return ctf_set_typed_errno (fp, err);
 }
 
-/* Iterate over every variable in the given DATASEC, in arbitrary order.  We
-   pass the type ID, datasec-recorded size (usually 0), and offset of each
-   variable to the specified callback function.  */
-
-int
-ctf_datasec_var_iter (ctf_dict_t *fp, ctf_id_t datasec,
-                     ctf_datasec_var_f *func, void *arg)
-{
-  ctf_next_t *i = NULL;
-  ctf_id_t type;
-  size_t size, offset;
-
-  while ((type = ctf_datasec_var_next (fp, datasec, &i, &size, &offset)) != CTF_ERR)
-    {
-      int rc;
-      if ((rc = func (fp, type, offset, size, arg)) != 0)
-       {
-         ctf_next_destroy (i);
-         return rc;
-       }
-    }
-  if (ctf_errno (fp) != ECTF_NEXT_END)
-    return -1;                                 /* errno is set for us.  */
-
-  return 0;
-}
-
 /* Iterate over every variable in the given CTF datasec, in arbitrary order,
    returning the name and type of each variable in turn.  Returns CTF_ERR on end
    of iteration or error.
index 1d0ddc403b1c97747ba1285ef4672b23023f3cc8..35d9b1df5a7d237af16bfc48c034bcaf1bdb0fee 100644 (file)
@@ -103,17 +103,10 @@ LIBCTF_2.0 {
        ctf_lookup_enumerator_next;
        ctf_arc_lookup_enumerator_next;
 
-       ctf_member_iter;
-       ctf_enum_iter;
        ctf_enum_next;
-       ctf_type_iter;
        ctf_type_next;
-       ctf_type_iter_all;
-       ctf_type_kind_iter;
        ctf_type_kind_next;
-       ctf_variable_iter;
        ctf_variable_next;
-       ctf_datasec_iter;
        ctf_datasec_next;
        ctf_tag_next;
 
@@ -182,7 +175,6 @@ LIBCTF_2.0 {
        ctf_arc_open_by_name;
        ctf_arc_open_by_name_sections;
        ctf_archive_count;
-       ctf_archive_iter;
        ctf_archive_next;
        ctf_archive_raw_iter;
        ctf_get_arc;
index 1804b23a69ed203804ee5b06b9e6ddc8545b3658..8b49869658423ef47db996273e8f769ee1655a91 100644 (file)
@@ -2,13 +2,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-static int
-print_enum (const char *name, int val, void *unused)
-{
-  printf ("iter test: %s has value %i\n", name, val);
-  return 0;
-}
-
 int
 main (int argc, char *argv[])
 {
@@ -48,9 +41,6 @@ main (int argc, char *argv[])
   if ((type = ctf_lookup_by_name (fp, "enum ie") ) == CTF_ERR)
     goto err;
 
-  if ((ctf_enum_iter (fp, type, print_enum, NULL)) < 0)
-    goto ierr;
-
   while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
     {
       printf ("next test: %s has value %i\n", name, val);
@@ -69,10 +59,7 @@ main (int argc, char *argv[])
  err:
   fprintf (stderr, "Lookup failed: %s\n", ctf_errmsg (ctf_errno (fp)));
   return 1;
- ierr:
-  fprintf (stderr, "_iter iteration failed: %s\n", ctf_errmsg (ctf_errno (fp)));
-  return 1;
  nerr:
-  fprintf (stderr, "_next iteration failed: %s\n", ctf_errmsg (ctf_errno (fp)));
+  fprintf (stderr, "iteration failed: %s\n", ctf_errmsg (ctf_errno (fp)));
   return 1;
 }