[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: gaf.git: branch: master updated (1.5.2-20090328-53-g6f54111)



The branch, master has been updated
       via  6f54111ee069795ab27292e23181be49751cc5ce (commit)
       via  7e0e339dc47211254ff5e968fa402f4735ef41fa (commit)
       via  6940a50d7e05a19cd75678190ae56aefdc4407e9 (commit)
       via  9bee7186e31a9852cebdd65b7952261df0c1749b (commit)
       via  aa7b65e3a1cc59eadf247ed0fe74afeaeb7c5fe3 (commit)
       via  c99db7713faaad225501710e58220e580bca58b1 (commit)
       via  04a22009e68284327bdb57bf7c31e5788b0bfc67 (commit)
       via  33b113b078e9647d7304b4c2caa04da1dd367e4f (commit)
       via  f6e0d43eb80615c5314c4caab7ba727a50f3bcde (commit)
       via  b4996e267b5d9696f7e8122c40b31482ef852904 (commit)
       via  52fc6981d5dc91cb08e3314d5b77bdb7505418ba (commit)
       via  031e46d5d1b8071ebcde097b2a0f75984885a953 (commit)
       via  58859ac33ddd97e1cb7aa6eeaff832d3ed87c725 (commit)
       via  9e375afb9c865705ed4eff3b982f1a1a3e8fc843 (commit)
       via  2212036b0b38fb4c929d2abeaec638e4d483b91b (commit)
       via  3dc2a7150357119355212af164e38299df8e1649 (commit)
       via  8a2e32035cdac22ca6d355560bb9fdf935a99af8 (commit)
       via  f505ad65da209bd8d7e766d495466b904643e9b7 (commit)
       via  88c205ea2ff69936aa5362a52d27471fbab87e6b (commit)
       via  ca55a937a7f865e851e8352e7c80005b1d94f36f (commit)
       via  b1484835dce050c1bc67faf898622336a1f9cde3 (commit)
       via  02fde480e0d58300d9e7ee1cf0357fb96d14adbb (commit)
       via  5920b9ac846a1d0da2d76a3d72887489e7a93316 (commit)
      from  989908d06ad71c2cc883e32b23f61a34200f1b98 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 gattrib/src/s_attrib.c              |    4 +-
 gattrib/src/s_sheet_data.c          |    4 +-
 gattrib/src/s_table.c               |    2 +-
 gattrib/src/s_toplevel.c            |    8 +-
 gnetlist/src/g_netlist.c            |  154 ++----
 gnetlist/src/s_hierarchy.c          |   41 +-
 gnetlist/src/s_net.c                |    5 +-
 gnetlist/src/s_netattrib.c          |  235 ++++------
 gnetlist/src/s_traverse.c           |   17 +-
 gschem/src/i_callbacks.c            |   30 +-
 gschem/src/o_misc.c                 |   15 +-
 gschem/src/o_select.c               |    4 +-
 gschem/src/o_slot.c                 |   53 +--
 gschem/src/x_autonumber.c           |    2 +-
 gschem/src/x_compselect.c           |    5 +-
 gschem/src/x_dialog.c               |    8 +-
 gschem/src/x_multiattrib.c          |   29 +-
 gsymcheck/src/s_check.c             |   36 +-
 libgeda/include/libgeda/prototype.h |   20 +-
 libgeda/src/o_attrib.c              |  936 +++++++----------------------------
 libgeda/src/o_complex_basic.c       |  135 ++----
 libgeda/src/s_hierarchy.c           |    8 +-
 22 files changed, 465 insertions(+), 1286 deletions(-)


=================
 Commit Messages
=================

commit 7e0e339dc47211254ff5e968fa402f4735ef41fa
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem,libgeda: Tidy up invocation of the slot dialog
    
    Avoid presenting the whole "slot=..." attribute text in the slot
    dialog, since the user only needs to see the value portion.
    
    We now use o_attrib_search_object_attribs_by_name() to retrieve the
    current slot for a component when bringing up the dialog. This means
    that if there is no slot= attribute attached, the default slot= value
    (if any) from the symbol will be returned automatically, and we don't
    need an explicit call to o_attrib_search_default_slot().
    
    Remove the now unused function o_attrib_search_default_slot().

:100644 100644 0162c78... dea14bc... M	gschem/src/o_slot.c
:100644 100644 79c4eca... 074f963... M	gschem/src/x_dialog.c
:100644 100644 162637c... 10cf349... M	libgeda/include/libgeda/prototype.h
:100644 100644 e9d05bf... e6cfc1a... M	libgeda/src/o_attrib.c

commit 6940a50d7e05a19cd75678190ae56aefdc4407e9
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove now unused functions from the old attribute API.
    
    Removed functions:
    
      o_attrib_search_attrib_value()
      o_attrib_search_attrib_name()
      o_attrib_search_name_single_count()

:100644 100644 6b14813... 162637c... M	libgeda/include/libgeda/prototype.h
:100644 100644 88d4036... e9d05bf... M	libgeda/src/o_attrib.c

commit 9bee7186e31a9852cebdd65b7952261df0c1749b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Use new attrib API for o_attrib_search_slot()
    
    Deleted now unused function o_attrib_search_name_single()

:100644 100644 721d3a8... 6b14813... M	libgeda/include/libgeda/prototype.h
:100644 100644 4a3d575... 88d4036... M	libgeda/src/o_attrib.c

commit aa7b65e3a1cc59eadf247ed0fe74afeaeb7c5fe3
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make use of the new API o_attrib_search_attached_attribs_by_name()

:100644 100644 2cccbc1... f3fafc2... M	gattrib/src/s_toplevel.c
:100644 100644 0b67226... 96bac9f... M	gnetlist/src/s_hierarchy.c
:100644 100644 1465afd... e5bfa4a... M	gschem/src/i_callbacks.c
:100644 100644 4d783c4... 812efa2... M	gschem/src/o_misc.c
:100644 100644 1c4315b... b8629aa... M	libgeda/src/o_complex_basic.c
:100644 100644 20ce0a4... 1f9f1e4... M	libgeda/src/s_hierarchy.c

commit c99db7713faaad225501710e58220e580bca58b1
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make use of new API o_attrib_search_floating_attribs_by_name()
    
    Replaces the less specific API, o_attrib_search_name() previously
    used to search for floating attributes.
    
    Remove the now unused function o_attrib_search_name().

:100644 100644 cbc6d7b... faf61ec... M	gsymcheck/src/s_check.c
:100644 100644 81bd057... 721d3a8... M	libgeda/include/libgeda/prototype.h
:100644 100644 679dd19... 4a3d575... M	libgeda/src/o_attrib.c

commit 04a22009e68284327bdb57bf7c31e5788b0bfc67
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make use of new API o_attrib_search_inherited_attribs_by_name()
    
    Replaces the less specific API, o_attrib_search_name() previously
    used to search for floating attributes inside complex objects.

:100644 100644 2995b75... 0b67226... M	gnetlist/src/s_hierarchy.c
:100644 100644 b6736a0... 1465afd... M	gschem/src/i_callbacks.c
:100644 100644 4124ffc... 4d783c4... M	gschem/src/o_misc.c
:100644 100644 0f5e861... 679dd19... M	libgeda/src/o_attrib.c
:100644 100644 00fe604... 1c4315b... M	libgeda/src/o_complex_basic.c
:100644 100644 731f094... 20ce0a4... M	libgeda/src/s_hierarchy.c

commit 33b113b078e9647d7304b4c2caa04da1dd367e4f
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use o_attrib_search_object_attribs_by_name() where appropriate

:100644 100644 d6afc91... 6e5a485... M	gattrib/src/s_attrib.c
:100644 100644 185f832... 3f8996d... M	gattrib/src/s_sheet_data.c
:100644 100644 ba00be0... 189dfc2... M	gattrib/src/s_table.c
:100644 100644 2843c12... 2cccbc1... M	gattrib/src/s_toplevel.c
:100644 100644 9011c82... 61d3e26... M	gnetlist/src/g_netlist.c
:100644 100644 f5ececb... 2995b75... M	gnetlist/src/s_hierarchy.c
:100644 100644 5fdf975... d3f57c3... M	gnetlist/src/s_net.c
:100644 100644 f9faf0f... a23fa34... M	gnetlist/src/s_traverse.c
:100644 100644 f35497f... b6736a0... M	gschem/src/i_callbacks.c
:100644 100644 a844755... d2fba3a... M	gschem/src/o_select.c
:100644 100644 0bf1a54... e9a9726... M	gschem/src/x_autonumber.c
:100644 100644 c6fc509... cbc6d7b... M	gsymcheck/src/s_check.c
:100644 100644 dcc2a1d... 0f5e861... M	libgeda/src/o_attrib.c
:100644 100644 3707c6a... 00fe604... M	libgeda/src/o_complex_basic.c

commit f6e0d43eb80615c5314c4caab7ba727a50f3bcde
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Use new attrib API for o_attrib_slot_update()
    
    Also tidy up the function a little.
    
    We now use o_attrib_search_object_attribs_by_name() to find the
    slot= attribute value of an OBJECT, so we automatically get the
    correct fallback to the symbol's embedded default slot= attribute
    value if the attached slot= attribute is missing.
    
    (This means a behavioral change in the uncommon case where the
    attached slot= attribute is missing, and the symbol specifies a
    default which is not slot=1)

:100644 100644 b0ccfe2... dcc2a1d... M	libgeda/src/o_attrib.c

commit b4996e267b5d9696f7e8122c40b31482ef852904
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gnetlist: Use new attrib API for s_netattrib_{handle,net_search}()
    
    Also tidy up the function implementation somewhat.

:100644 100644 9fa0a11... 0467b31... M	gnetlist/src/s_netattrib.c

commit 52fc6981d5dc91cb08e3314d5b77bdb7505418ba
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_attrib_search_string_list() and o_attrib_search_string_single()
    
    Reworked the one remaining caller of these functions to use
    o_complex_find_pin_by_attribute(), which utilises the newer APIs.

:100644 100644 880808a... 9011c82... M	gnetlist/src/g_netlist.c
:100644 100644 e9ae505... 81bd057... M	libgeda/include/libgeda/prototype.h
:100644 100644 ea05fed... b0ccfe2... M	libgeda/src/o_attrib.c

commit 031e46d5d1b8071ebcde097b2a0f75984885a953
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Replace o_attrib_search_pinseq() with o_complex_find_pin_by_attribute()
    
    Calling o_complex_find_pin_by_attribute() with "pinseq" as its name
    argument, a char * wanted_value and a complex OBJECT (rather than its
    prim_objs) is functionally identical.

:100644 100644 22c1565... ea05fed... M	libgeda/src/o_attrib.c

commit 58859ac33ddd97e1cb7aa6eeaff832d3ed87c725
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Replace o_complex_return_pin() with new o_complex_find_pin_by_attribute()
    
    Implement a more generic version of o_complex_return_pin(). The old
    function takes a pinnumber as its argument, and finds a pin which has
    a matching "pinnumber=..." attribute.
    
    The new function takes an explicit attribute name argument as well as
    the value, so we can find pins by any attached attribute. This is useful
    so we can search by "pinseq=..." attributes as well.

:100644 100644 21fe86c... 880808a... M	gnetlist/src/g_netlist.c
:100644 100644 a40ef72... e9ae505... M	libgeda/include/libgeda/prototype.h
:100644 100644 810f9eb... 3707c6a... M	libgeda/src/o_complex_basic.c

commit 9e375afb9c865705ed4eff3b982f1a1a3e8fc843
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove unused function o_complex_return_nth_pin()

:100644 100644 a7943e2... a40ef72... M	libgeda/include/libgeda/prototype.h
:100644 100644 bd5bd10... 810f9eb... M	libgeda/src/o_complex_basic.c

commit 2212036b0b38fb4c929d2abeaec638e4d483b91b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Allow symbols to override the slotdef= attribute definitions
    
    This should pave the way to allow attachement of slotdef= attributes
    overriding those inside the symbol.
    
    NB: If this is done, pinnumber updates in gschem won't be triggered
    immediately, since they are only run when a slot= attribute changes.

:100644 100644 00ee372... 22c1565... M	libgeda/src/o_attrib.c

commit 3dc2a7150357119355212af164e38299df8e1649
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Eliminate usage of, and remove o_attrib_search_string_partial()
    
    This function's one caller was using it to find an attribute containing
    "slotdef=X:", where X is the slot number being retrieved.
    
    o_attribute_search_string_partial() would look at the full name=value
    string of each text object in the given object list, looking for a
    substring match on the desired text. (In fact, we only want a match
    at the beginning of the string).
    
    The new implementation may be somewhat less efficient, since it queries
    all slotdef= attributes in turn, checking to see if the one returned is
    the desired value. The speed penalty should be impercievable though, and
    the new code better abstracts the implementation details of the attribute
    system.

:100644 100644 6b133bb... a7943e2... M	libgeda/include/libgeda/prototype.h
:100644 100644 31a10e5... 00ee372... M	libgeda/src/o_attrib.c

commit 8a2e32035cdac22ca6d355560bb9fdf935a99af8
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Move logic of function o_attrib_search_toplevel_all() to its one caller
    
    This function was only used in one place, and probably didn't deserve its
    own API in libgeda. The function it is called from is not used anyway, so
    could probably be removed completely at some point. (Although it forms
    part of the scheme API for gnetlist, comments above it suggest that it is
    "still highly temp and doesn't work right"). It is not requied by any
    known (shipped) gnetlist backends.

:100644 100644 f8ef142... 21fe86c... M	gnetlist/src/g_netlist.c
:100644 100644 379d35f... 6b133bb... M	libgeda/include/libgeda/prototype.h
:100644 100644 a1a934f... 31a10e5... M	libgeda/src/o_attrib.c

commit f505ad65da209bd8d7e766d495466b904643e9b7
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_complex_get_toplevel_attribs() in favour of newer attrib API
    
    o_attrib_find_floating_attribs() is functionally identical.

:100644 100644 eb17b79... b596903... M	gschem/src/x_compselect.c
:100644 100644 71a8759... 379d35f... M	libgeda/include/libgeda/prototype.h
:100644 100644 5f49033... bd5bd10... M	libgeda/src/o_complex_basic.c

commit 88c205ea2ff69936aa5362a52d27471fbab87e6b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_attrib_search_toplevel() in favour of the newer API
    
    o_attrib_search_floating_attribs_by_name() is functionally identical

:100644 100644 1ba5052... c6fc509... M	gsymcheck/src/s_check.c
:100644 100644 efe7d6f... 71a8759... M	libgeda/include/libgeda/prototype.h
:100644 100644 f063f0c... a1a934f... M	libgeda/src/o_attrib.c

commit ca55a937a7f865e851e8352e7c80005b1d94f36f
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_attrib_search_component() in favour of the new API
    
    Calling o_attrib_search_object_attribs_by_name() with a count
    parameter of 0 is functionally identical.

:100644 100644 345b5cf... 2843c12... M	gattrib/src/s_toplevel.c
:100644 100644 4613c82... f9faf0f... M	gnetlist/src/s_traverse.c
:100644 100644 82e0440... efe7d6f... M	libgeda/include/libgeda/prototype.h
:100644 100644 5545690... f063f0c... M	libgeda/src/o_attrib.c

commit b1484835dce050c1bc67faf898622336a1f9cde3
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Introduce new attribute searching API
    
    This new API aims to be explicit as to the scope of its behaviour.
    Various of the existing APIs are very similarly named, yet will have
    subtly different behaviours when passed a list of OBJECTs, attribute
    OBJECTs, some general OBJECT, or an attribute OBJECT.
    
    Since the current APIs are confusing, the sensible course of action seems
    to be introducing a new simple API for searching a GList of attributes by
    name, then providing specialised wrappers which construct the appropriate
    list of attributes to search.
    
    To this end, inside libgeda/src/o_attrib.c, the following new functions
    are created:
    
    The generic search routine:
      static OBJECT *o_attrib_find_attrib_by_name ()
    
    A helper which returns the value of the found attribute:
      static char *o_attrib_search_attrib_list_by_name ()
    
    Exported API to search:
    
      floating attributes (on a page, or inside a symbol):
        char *o_attrib_search_floating_attribs_by_name ()
    
      Attributes attached to an OBJECT:
        char *o_attrib_search_attached_attribs_by_name ()
    
      Attributes inside an OBJECT (inherited):
        char *o_attrib_search_inherited_attribs_by_name ()
    
      Attributes from an object - either attached, or from inside the symbol:
      char *o_attrib_search_object_attribs_by_name ()
    
    
    The latter is in preparation to make more use of an aggregate attribute
    list for objects - rather than having each piece of code duplicate the
    logic to check both attached attributes, and those inside symbols.
    
    We also make o_attrib_find_floating_attribs() static, since it is
    only used inside o_attrib.c now.

:100644 100644 db709b3... 82e0440... M	libgeda/include/libgeda/prototype.h
:100644 100644 e8ba4b5... 5545690... M	libgeda/src/o_attrib.c

commit 02fde480e0d58300d9e7ee1cf0357fb96d14adbb
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Add inherited attributes to the list returned by o_attrib_return_attribs()
    
    This starts to allow a common place where attributes from the symbol will
    be combined with attached attributes to form an aggregate attribute list.
    
    Currently, various pieces of code which deal with reading attributes will
    check the attached attributes of a symbol, then the inherited attributes
    explicitly. For cases where a simple combining rule exists, we can reduce
    such checks to a single lookup of the aggregate list.
    
    Atttributes such as "net=" and "source=" which often exist multiple times,
    possibly both as inherited and attahched attributes, present difficulties
    though.
    
    For now, just pile all inherited attributes at the end of the returned
    list. This means any code which wants to check for the first attribtue
    with a given name should do the "right thing", with attached attributes
    taking presidence over inherited ones.

:100644 100644 4fde1ac... 23aa994... M	gschem/src/x_multiattrib.c
:100644 100644 3dea009... e8ba4b5... M	libgeda/src/o_attrib.c

commit 5920b9ac846a1d0da2d76a3d72887489e7a93316
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Improve doxygen comments for o_attrib_find_floating_attribs()

:100644 100644 ff1f411... 3dea009... M	libgeda/src/o_attrib.c

=========
 Changes
=========

commit 7e0e339dc47211254ff5e968fa402f4735ef41fa
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem,libgeda: Tidy up invocation of the slot dialog
    
    Avoid presenting the whole "slot=..." attribute text in the slot
    dialog, since the user only needs to see the value portion.
    
    We now use o_attrib_search_object_attribs_by_name() to retrieve the
    current slot for a component when bringing up the dialog. This means
    that if there is no slot= attribute attached, the default slot= value
    (if any) from the symbol will be returned automatically, and we don't
    need an explicit call to o_attrib_search_default_slot().
    
    Remove the now unused function o_attrib_search_default_slot().

diff --git a/gschem/src/o_slot.c b/gschem/src/o_slot.c
index 0162c78..dea14bc 100644
--- a/gschem/src/o_slot.c
+++ b/gschem/src/o_slot.c
@@ -39,51 +39,22 @@
  */
 void o_slot_start (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
-  OBJECT *slot_text_object;
-  char *default_slot_value;
   char *slot_value;
 
   /* single object for now */
-  if (object->type == OBJ_COMPLEX) {
-    /* first see if slot attribute already exists outside
-     * complex */
-    slot_value = o_attrib_search_slot(object, &slot_text_object);
-
-    if (slot_value) {
-#if DEBUG
-      printf("slot=%s\n", slot_value);
-      printf("text string : %s\n",
-             slot_text_object->text->string);
-#endif
-      slot_edit_dialog(w_current,
-                       o_text_get_string (w_current->toplevel,
-                                          slot_text_object));
-      g_free(slot_value);
-    } else {
-      /* we didn't find an attached slot=? attribute */
-
-      /* See if there is a default value */
-      default_slot_value =
-        o_attrib_search_default_slot(object);
-
-      if (default_slot_value) {
-        slot_value = g_strdup_printf ("slot=%s", default_slot_value);
-      } else {
-				/* no default, make something up? */
-				/* for now.. this is an error
-                                   condition */
-        slot_value = g_strdup ("slot=1");
-      }
+  if (object->type != OBJ_COMPLEX)
+    return;
 
-#if DEBUG
-      printf("slot value: %s\n", slot_value);
-#endif
+  slot_value = o_attrib_search_object_attribs_by_name (object, "slot", 0);
 
-      slot_edit_dialog(w_current, slot_value);
-      g_free(slot_value);
-      g_free(default_slot_value);
-    }
+  if (slot_value == NULL) {
+    /* we didn't find a slot=? attribute, make something up */
+    /* for now.. this is an error condition */
+    slot_value = g_strdup ("1");
   }
+
+  slot_edit_dialog (w_current, slot_value);
+  g_free (slot_value);
 }
 
 /*! \todo Finish function documentation!!!
@@ -120,14 +91,12 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len)
     }
   }
 
-  /* now find the slot attribute on the outside first */
   if (object != NULL) {
     numslots_value = o_attrib_search_numslots (object);
 
     if (!numslots_value) {
       s_log_message(_("numslots attribute missing\n"));
-      s_log_message(
-                    _("Slotting not allowed for this component\n"));
+      s_log_message(_("Slotting not allowed for this component\n"));
       g_free(value);
       return;
     }
diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 79c4eca..074f963 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -2067,6 +2067,7 @@ void snap_size_dialog (GSCHEM_TOPLEVEL *w_current)
 void slot_edit_dialog_response(GtkWidget *widget, gint response, GSCHEM_TOPLEVEL *w_current)
 {
   GtkWidget *textentry;
+  char *slot_string;
   int len;
   gchar *string = NULL;
 
@@ -2080,7 +2081,9 @@ void slot_edit_dialog_response(GtkWidget *widget, gint response, GSCHEM_TOPLEVEL
     string = (gchar*) gtk_entry_get_text(GTK_ENTRY(textentry));
     len = strlen(string);
     if (len != 0) {
-      o_slot_end(w_current, string, len);
+      slot_string = g_strdup_printf ("slot=%s", string);
+      o_slot_end(w_current, slot_string, len);
+      g_free (slot_string);
     }
     break;
   default:
@@ -2157,8 +2160,7 @@ void slot_edit_dialog (GSCHEM_TOPLEVEL *w_current, const char *string)
   if (string != NULL) {
     textentry = g_object_get_data(G_OBJECT(w_current->sewindow),"textentry");
     gtk_entry_set_text(GTK_ENTRY(textentry), string);
-    gtk_entry_select_region(GTK_ENTRY(textentry),
-                            strlen("slot="), strlen(string));
+    gtk_editable_select_region (GTK_EDITABLE(textentry), 0, -1);
   }
 }
 
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 162637c..10cf349 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -108,7 +108,6 @@ char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int
 char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_slot(OBJECT *object, OBJECT **return_found);
 char *o_attrib_search_numslots(OBJECT *object);
-char *o_attrib_search_default_slot(OBJECT *object);
 void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object);
 GList *o_attrib_return_attribs(OBJECT *object);
 int o_attrib_is_inherited(OBJECT *attrib);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index e9d05bf..e6cfc1a 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -678,22 +678,6 @@ char *o_attrib_search_numslots(OBJECT *object)
   return o_attrib_search_object_attribs_by_name (object, "numslots", 0);
 }
 
-/*! \brief Search for default slot attribute.
- *  \par Function Description
- *  Search for default slot attribute.
- *
- *  \param [in] object  OBJECT list to search.
- *  \return Character string with attribute value, NULL otherwise.
- *
- *  \warning
- *  Caller must g_free returned character string.
- */
-char *o_attrib_search_default_slot(OBJECT *object)
-{
-  /* search for default value attribute buried inside the complex */
-  return o_attrib_search_inherited_attribs_by_name (object, "slot", 0);
-}
-
 
 /*! \brief Search for slotdef attribute.
  *  \par Function Description

commit 6940a50d7e05a19cd75678190ae56aefdc4407e9
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove now unused functions from the old attribute API.
    
    Removed functions:
    
      o_attrib_search_attrib_value()
      o_attrib_search_attrib_name()
      o_attrib_search_name_single_count()

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 6b14813..162637c 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -106,9 +106,6 @@ char *o_attrib_search_floating_attribs_by_name (const GList *list, char *name, i
 char *o_attrib_search_attached_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter);
-OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name, int counter);
-char *o_attrib_search_attrib_name(GList *list, char *name, int counter);
-char *o_attrib_search_name_single_count(OBJECT *object, char *name, int counter);
 char *o_attrib_search_slot(OBJECT *object, OBJECT **return_found);
 char *o_attrib_search_numslots(OBJECT *object);
 char *o_attrib_search_default_slot(OBJECT *object);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 88d4036..e9d05bf 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -626,232 +626,6 @@ char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int co
 }
 
 
-/*! \brief Search for attribute by value and name.
- *  \par Function Description
- *  Search for attribute by value and name.
- *  
- *  Counter is the n'th occurance of the attribute, and starts searching
- *  from zero.  Zero is the first occurance of an attribute.
- *
- *  The value is the primary search key, but name is checked before
- *  an OBJECT is returned to ensure the correct OBJECT has been found.
- *
- *  \param [in] list     The attribute OBJECT list to search.
- *  \param [in] value    Character string with value to search for.
- *  \param [in] name     Character string with name to compare.
- *  \param [in] counter  Which occurance to return.
- *  \return The attribute OBJECT if found, NULL otherwise.
- *
- */
-OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name,
-				     int counter) 
-{
-  OBJECT *a_current;
-  GList *a_iter;
-  int val;
-  int internal_counter=0;
-  char *found_name = NULL;
-  char *found_value = NULL;
-
-  a_iter = list;
-	
-  if (!value) 
-  return(NULL);
-
-  if (!name) 
-  return(NULL);
-
-  while(a_iter != NULL) {
-    a_current = a_iter->data;
-    if (a_current->type == OBJ_TEXT) {
-      val = o_attrib_get_name_value(a_current->text->string,
-                                    &found_name, &found_value);
-
-      if (val) {
-#if DEBUG
-        printf("found value: %s\n", found_value);
-        printf("looking for: %s\n", value);
-#endif
-        if (strcmp(value, found_value) == 0) {
-          if (counter != internal_counter) {
-            internal_counter++;
-          } else {
-            if (strstr(found_name, name)) {
-              g_free(found_name);
-              g_free(found_value);
-              return a_current;
-            }
-          }
-        }
-        if (found_name) { g_free(found_name); found_name = NULL; }
-        if (found_value) { g_free(found_value); found_value = NULL; }
-      }
-
-    }
-    a_iter = g_list_next (a_iter);
-  }
-
-  g_free(found_name);
-  g_free(found_value);
-  return (NULL);
-} 
-
-/*! \brief Search for an attribute by name.
- *  \par Function Description
- *  Search for an attribute by name.
- *
- *  Counter is the n'th occurance of the attribute, and starts searching
- *  from zero.  Zero is the first occurance of an attribute.
- *
- *  \param [in] list     attribute OBJECT list to search.
- *  \param [in] name     Character string with attribute name to search for.
- *  \param [in] counter  Which occurance to return.
- *  \return Character string with attribute value, NULL otherwise.
- *
- *  \warning
- *  Caller must g_free returned character string.
- */
-char *
-o_attrib_search_attrib_name(GList *list, char *name, int counter)
-{
-  OBJECT *a_current;
-  GList *a_iter;
-  int val;
-  int internal_counter=0;
-  char *found_name = NULL;
-  char *found_value = NULL;
-  char *return_string = NULL;
-
-  a_iter = list;
-
-  while(a_iter != NULL) {
-    a_current = a_iter->data;
-    if (a_current->type == OBJ_TEXT) {
-      val = o_attrib_get_name_value(a_current->text->string,
-                                    &found_name, &found_value);
-
-      if (val) {
-#if DEBUG
-        printf("found name: %s\n", found_name);
-        printf("looking for: %s\n", name);
-#endif
-        if (strcmp(name, found_name) == 0) {
-          if (counter != internal_counter) {
-            internal_counter++;
-          } else {
-            return_string = g_strdup (found_value);
-            g_free(found_name);
-            g_free(found_value);
-            return(return_string);
-          }
-        }
-        if (found_name) { g_free(found_name); found_name = NULL; }
-        if (found_value) { g_free(found_value); found_value = NULL; }
-      }
-    }
-    a_iter = g_list_next (a_iter);
-  }
-
-  g_free(found_name);
-  g_free(found_value);
-  return (NULL);
-} 
-
-
-/*! \brief Search for N'th occurance of a named attribute.
- *  \par Function Description
- *  Search for N'th occurance of a named attribute.
- *
- *  \param [in] object   The OBJECT list to search.
- *  \param [in] name     Character string of attribute name to search for.
- *  \param [in] counter  Which occurance to return.
- *  \return Character string with attribute value, NULL otherwise.
- *  
- *  \warning
- *  Caller must g_free returned character string.
- */
-/* be sure caller free's return value */
-/* this function is like above, except that it returns the n'th occurance */
-/* of the attribute.  counter starts counting at zero */
-char *o_attrib_search_name_single_count(OBJECT *object, char *name, 
-					int counter) 
-{
-  OBJECT *o_current;
-  OBJECT *a_current;
-  GList *a_iter;
-  int val;
-  char *found_name = NULL;
-  char *found_value = NULL;
-  char *return_string = NULL;
-  int internal_counter=0;
-
-  o_current = object;
-
-  if (o_current == NULL) {
-    return(NULL);
-  }
-
-  a_iter = o_current->attribs;
-
-  while(a_iter != NULL) {
-    a_current = a_iter->data;
-    if (a_current->type == OBJ_TEXT) {
-      val = o_attrib_get_name_value(a_current->text->string,
-                                    &found_name, &found_value);
-
-      if (val) {
-        if (strcmp(name, found_name) == 0) {
-          if (counter != internal_counter) {
-            internal_counter++;
-          } else {
-            return_string = g_strdup (found_value);
-            g_free(found_name);
-            g_free(found_value);
-            return(return_string);
-          }
-        }
-        if (found_name) { g_free(found_name); found_name = NULL; }
-        if (found_value) { g_free(found_value); found_value = NULL; }
-      }
-
-#if DEBUG
-      printf("0 _%s_\n", a_current->text->string);
-      printf("1 _%s_\n", found_name);
-      printf("2 _%s_\n", found_value);
-#endif
-    }
-    a_iter = g_list_next (a_iter);
-  }
-
-  /* search for attributes outside */
-
-  if (o_current->type == OBJ_TEXT) {
-    g_free(found_name);
-    g_free(found_value);
-    val = o_attrib_get_name_value(o_current->text->string, 
-                                  &found_name, &found_value);
-
-    if (val) {
-      if (strcmp(name, found_name) == 0) {
-        if (counter != internal_counter) {
-          internal_counter++;
-        } else {
-          return_string = g_strdup (found_value);
-	  g_free(found_name);
-	  g_free(found_value);
-          return(return_string);
-        }
-      }
-      if (found_name) { g_free(found_name); found_name = NULL; }
-      if (found_value) { g_free(found_value); found_value = NULL; }
-    }
-  }	
-  
-  g_free(found_name);
-  g_free(found_value);
-  return (NULL);
-}
-
 /*! \brief Search for slot attribute.
  *  \par Function Description
  *  Search for slot attribute.

commit 9bee7186e31a9852cebdd65b7952261df0c1749b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Use new attrib API for o_attrib_search_slot()
    
    Deleted now unused function o_attrib_search_name_single()

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 721d3a8..6b14813 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -108,7 +108,6 @@ char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int
 char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter);
 OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name, int counter);
 char *o_attrib_search_attrib_name(GList *list, char *name, int counter);
-char *o_attrib_search_name_single(OBJECT *object, char *name, OBJECT **return_found);
 char *o_attrib_search_name_single_count(OBJECT *object, char *name, int counter);
 char *o_attrib_search_slot(OBJECT *object, OBJECT **return_found);
 char *o_attrib_search_numslots(OBJECT *object);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 4a3d575..88d4036 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -757,98 +757,6 @@ o_attrib_search_attrib_name(GList *list, char *name, int counter)
   return (NULL);
 } 
 
-/*! \brief Search for first occurance of a named attribute.
- *  \par Function Description
- *  Search for first occurance of a named attribute.
- *
- *  \param [in]  object        The OBJECT list to search.
- *  \param [in]  name          Character string of attribute name to search for.
- *  \param [out] return_found  Contains attribute OBJECT if found, NULL otherwise.
- *  \return Character string with attribute value, NULL otherwise.
- *
- *  \warning
- *  Caller must g_free returned character string.
- */
-char *o_attrib_search_name_single(OBJECT *object, char *name,
-				  OBJECT **return_found) 
-{
-  OBJECT *o_current;
-  OBJECT *a_current;
-  GList *a_iter;
-  int val;
-  char *found_name = NULL;
-  char *found_value = NULL;
-  char *return_string = NULL;
-
-  o_current = object;
-
-  if (o_current == NULL) {
-    return(NULL);
-  }
-
-  if (o_current->attribs != NULL) {
-    a_iter = o_current->attribs;
-
-    while(a_iter != NULL) {
-      a_current = a_iter->data;
-      if (a_current->type == OBJ_TEXT) {
-        val = o_attrib_get_name_value(a_current->text->string,
-                                      &found_name, &found_value);
-
-        if (val) {
-          if (strcmp(name, found_name) == 0) {
-            return_string = g_strdup (found_value);
-            if (return_found) {
-              *return_found = a_current;
-            }
-            g_free(found_name);
-            g_free(found_value);
-            return(return_string);
-          }
-          if (found_name) { g_free(found_name); found_name = NULL; }
-          if (found_value) { g_free(found_value); found_value = NULL; }
-        }
-
-#if DEBUG
-        printf("0 _%s_\n", found->text->string);
-        printf("1 _%s_\n", found_name);
-        printf("2 _%s_\n", found_value);
-#endif
-      }
-      a_iter = g_list_next (a_iter);
-    }
-  }
-  /* search for attributes outside */
-
-  if (o_current->type == OBJ_TEXT) {
-    g_free(found_name);
-    g_free(found_value);
-    val = o_attrib_get_name_value(o_current->text->string, 
-                                  &found_name, &found_value);
-
-    if (val) {
-      if (strcmp(name, found_name) == 0) {
-        return_string = g_strdup (found_value);
-        if (return_found) {
-          *return_found = o_current;
-        }
-	g_free(found_name);
-	g_free(found_value);
-        return(return_string);
-      }
-      if (found_name) { g_free(found_name); found_name = NULL; }
-      if (found_value) { g_free(found_value); found_value = NULL; }
-    }
-  }
-
-  if (return_found) {
-    *return_found = NULL;
-  }
-  
-  g_free(found_name);
-  g_free(found_value);
-  return (NULL);
-}
 
 /*! \brief Search for N'th occurance of a named attribute.
  *  \par Function Description
@@ -948,8 +856,10 @@ char *o_attrib_search_name_single_count(OBJECT *object, char *name,
  *  \par Function Description
  *  Search for slot attribute.
  *
+ *  The returned value will only come from an attached attribute.
+ *
  *  \param [in] object        OBJECT list to search.
- *  \param [in] return_found  slot attribute if found, NULL otherwise.
+ *  \param [in] return_found  attached slot attribute if found, NULL otherwise.
  *  \return Character string with attribute value, NULL otherwise.
  *
  *  \warning
@@ -957,20 +867,21 @@ char *o_attrib_search_name_single_count(OBJECT *object, char *name,
  */
 char *o_attrib_search_slot(OBJECT *object, OBJECT **return_found)
 {
-  char *return_value;
+  GList *attributes;
+  OBJECT *attrib;
+  char *value = NULL;
 
-  /* search for default value attribute buried inside the complex */
-  return_value = o_attrib_search_name_single(object, "slot", return_found);
+  attributes = o_attrib_return_attribs (object);
+  attrib = o_attrib_find_attrib_by_name (attributes, "slot", 0);
+  g_list_free (attributes);
 
-  /* I'm confused here does the next if get ever called? */
-  if (return_value) {
-    return(return_value);
-  }
+  if (attrib != NULL)
+    o_attrib_get_name_value (attrib->text->string, NULL, &value);
 
-  if (return_found) {
-    *return_found = NULL;
-  }
-  return(NULL);
+  if (return_found)
+    *return_found = attrib;
+
+  return value;
 }
 
 /*! \brief Search for numslots attribute.

commit aa7b65e3a1cc59eadf247ed0fe74afeaeb7c5fe3
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make use of the new API o_attrib_search_attached_attribs_by_name()

diff --git a/gattrib/src/s_toplevel.c b/gattrib/src/s_toplevel.c
index 2cccbc1..f3fafc2 100644
--- a/gattrib/src/s_toplevel.c
+++ b/gattrib/src/s_toplevel.c
@@ -710,7 +710,7 @@ void s_toplevel_update_component_attribs_in_toplevel(OBJECT *o_current,
   /*  Now get the old attrib name & value from complete_comp_attrib_list 
    *  and value from o_current  */
   old_attrib_name = u_basic_breakup_string(local_list->data, '=', 0); 
-  old_attrib_value = o_attrib_search_name_single_count(o_current, old_attrib_name, 0);
+  old_attrib_value = o_attrib_search_attached_attribs_by_name (o_current, old_attrib_name, 0);
 
 #if DEBUG
   printf("        In s_toplevel_update_component_attribs_in_toplevel, old name = \"%s\" .\n", 
@@ -964,7 +964,7 @@ void s_toplevel_update_pin_attribs_in_toplevel(char *refdes, OBJECT *o_pin,
     g_free(new_attrib_value);   
     new_attrib_value = NULL;  /* s_misc_remaining_string doesn't return NULL for empty substring. */
   }
-  old_attrib_value = o_attrib_search_name_single_count(o_pin, new_attrib_name, 0);
+  old_attrib_value = o_attrib_search_attached_attribs_by_name (o_pin, new_attrib_name, 0);
                                                                                                        
     /* -------  Four cases to consider: Case 1: old and new attribs exist ----- */
     if ( (old_attrib_value != NULL) && (new_attrib_value != NULL) && (strlen(new_attrib_value) != 0) ) {
diff --git a/gnetlist/src/s_hierarchy.c b/gnetlist/src/s_hierarchy.c
index 0b67226..96bac9f 100644
--- a/gnetlist/src/s_hierarchy.c
+++ b/gnetlist/src/s_hierarchy.c
@@ -52,7 +52,7 @@ s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current,
     char *current_filename;
     int graphical=FALSE;
 
-    attrib = o_attrib_search_name_single_count(o_current, "source", 0);
+    attrib = o_attrib_search_attached_attribs_by_name (o_current, "source", 0);
 
     /* if above is null, then look inside symbol */
     if (attrib == NULL) {
@@ -135,8 +135,8 @@ s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current,
 	/* continue looking outside first */
 	if (!looking_inside) {
 	    attrib =
-		o_attrib_search_name_single_count(o_current, "source",
-						  count);
+		o_attrib_search_attached_attribs_by_name (o_current, "source",
+		                                          count);
 	}
 
 	/* okay we were looking outside and didn't */
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 1465afd..e5bfa4a 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2850,7 +2850,7 @@ DEFINE_I_CALLBACK(hierarchy_down_schematic)
     return;
 
   parent = w_current->toplevel->page_current;
-  attrib = o_attrib_search_name_single_count(object, "source", count);
+  attrib = o_attrib_search_attached_attribs_by_name (object, "source", count);
 
   /* if above is null, then look inside symbol */
   if (attrib == NULL) {
@@ -2916,7 +2916,8 @@ DEFINE_I_CALLBACK(hierarchy_down_schematic)
 
     /* continue looking outside first */
     if (!looking_inside) {
-      attrib = o_attrib_search_name_single_count(object, "source", count);
+      attrib =
+        o_attrib_search_attached_attribs_by_name (object, "source", count);
     }
 
     /* okay we were looking outside and didn't find anything,
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 4d783c4..812efa2 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -520,7 +520,8 @@ int o_edit_find_text (GSCHEM_TOPLEVEL *w_current, const GList *o_list,
     if (descend) {
       if (o_current->type == OBJ_COMPLEX) {
         parent = toplevel->page_current;
-        attrib = o_attrib_search_name_single_count(o_current, "source", count);
+        attrib = o_attrib_search_attached_attribs_by_name (o_current,
+                                                           "source", count);
 
         /* if above is null, then look inside symbol */
         if (attrib == NULL) {
@@ -751,9 +752,13 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     o_attrib_get_name_value (o_text_get_string (toplevel, a_current),
                              &name, NULL);
 
-    attrfound = o_attrib_search_name_single(o_current, name, NULL);
+    /* We are only interested in the attributes which were promoted during
+     * load of the new complex. Any which aren't already promoted in the
+     * schematic are migrated.
+     */
+    attrfound = o_attrib_search_attached_attribs_by_name (o_current, name, 0);
 
-    /* free these now since they are no longer being used */
+    /* free this now since it is no longer being used */
     g_free(name);
 
     if (attrfound == NULL) {
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 1c4315b..b8629aa 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -1288,7 +1288,7 @@ o_complex_check_symversion(TOPLEVEL* toplevel, OBJECT* object)
   inside = o_attrib_search_inherited_attribs_by_name (object, "symversion", 0);
 
   /* now look for the symversion= attached to object */
-  outside = o_attrib_search_attrib_name(object->attribs, "symversion", 0);
+  outside = o_attrib_search_attached_attribs_by_name (object, "symversion", 0);
 
   /* get the uref for future use */
   refdes = o_attrib_search_object_attribs_by_name(object, "refdes", 0);
diff --git a/libgeda/src/s_hierarchy.c b/libgeda/src/s_hierarchy.c
index 20ce0a4..1f9f1e4 100644
--- a/libgeda/src/s_hierarchy.c
+++ b/libgeda/src/s_hierarchy.c
@@ -239,8 +239,8 @@ GList *s_hierarchy_traversepages(TOPLEVEL *toplevel,
 
     /* only complex things like symbols can contain attributes */
     if (o_current->type == OBJ_COMPLEX) {
-      filename = o_attrib_search_name_single_count(o_current,
-						   "source", 0);
+      filename =
+        o_attrib_search_attached_attribs_by_name (o_current, "source", 0);
       
       /* if above is NULL, then look inside symbol */
       if (filename == NULL) {

commit c99db7713faaad225501710e58220e580bca58b1
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make use of new API o_attrib_search_floating_attribs_by_name()
    
    Replaces the less specific API, o_attrib_search_name() previously
    used to search for floating attributes.
    
    Remove the now unused function o_attrib_search_name().

diff --git a/gsymcheck/src/s_check.c b/gsymcheck/src/s_check.c
index cbc6d7b..faf61ec 100644
--- a/gsymcheck/src/s_check.c
+++ b/gsymcheck/src/s_check.c
@@ -350,7 +350,7 @@ s_check_graphical (const GList *obj_list, SYMCHECK *s_current)
   char *temp;
   
   /* look for special graphical tag */
-  temp = o_attrib_search_name (obj_list, "graphical", 0);
+  temp = o_attrib_search_floating_attribs_by_name (obj_list, "graphical", 0);
 
   if (temp) {
     s_current->graphical_symbol=TRUE;
@@ -365,7 +365,7 @@ s_check_device (const GList *obj_list, SYMCHECK *s_current)
   char *message;
   
   /* search for device attribute */
-  temp = o_attrib_search_name (obj_list, "device", 0);
+  temp = o_attrib_search_floating_attribs_by_name (obj_list, "device", 0);
   if (!temp) {
     /* did not find device= attribute */
     message = g_strdup ("Missing device= attribute\n");
@@ -790,7 +790,7 @@ s_check_slotdef (const GList *obj_list, SYMCHECK *s_current)
   int errors_found = 0;
 
   /* look for numslots to see if this symbol has slotting info */
-  value = o_attrib_search_name (obj_list, "numslots", 0);
+  value = o_attrib_search_floating_attribs_by_name (obj_list, "numslots", 0);
 
   if (!value) {
     message = g_strdup ("Did not find numslots= attribute, not checking slotting\n");
@@ -823,7 +823,7 @@ s_check_slotdef (const GList *obj_list, SYMCHECK *s_current)
 
   i = 0;
   /* get the slotdef attribute */
-  slotdef = o_attrib_search_name (obj_list, "slotdef", 0);
+  slotdef = o_attrib_search_floating_attribs_by_name (obj_list, "slotdef", 0);
   while ((slotdef != NULL) && (!error_parsing))
   {
 
@@ -985,7 +985,7 @@ s_check_slotdef (const GList *obj_list, SYMCHECK *s_current)
     slotdef = NULL;
    
     i++;
-    slotdef = o_attrib_search_name (obj_list, "slotdef", i);
+    slotdef = o_attrib_search_floating_attribs_by_name (obj_list, "slotdef", i);
   }
 
   if (!slotdef && i < s_current->numslots) {
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 81bd057..721d3a8 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -106,7 +106,6 @@ char *o_attrib_search_floating_attribs_by_name (const GList *list, char *name, i
 char *o_attrib_search_attached_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter);
-char *o_attrib_search_name(const GList *list, char *name, int counter);
 OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name, int counter);
 char *o_attrib_search_attrib_name(GList *list, char *name, int counter);
 char *o_attrib_search_name_single(OBJECT *object, char *name, OBJECT **return_found);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 679dd19..4a3d575 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -626,106 +626,6 @@ char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int co
 }
 
 
-/*! \brief Search for attibute by name.
- *  \par Function Description
- *  Search for attribute by name.
- *
- *  \warning
- *  The list is the top level list. Do not pass it an object_list list
- *  unless you know what you are doing.
- *  
- *  Counter is the n'th occurance of the attribute, and starts searching
- *  from zero.  Zero is the first occurance of an attribute.
- *
- *  \param [in] list     GList to search.
- *  \param [in] name     Character string with attribute name to search for.
- *  \param [in] counter  Which occurance to return.
- *  \return Character string with attribute value, NULL otherwise.
- *
- *  \warning
- *  Caller must g_free returned character string.
- */
-char *o_attrib_search_name (const GList *list, char *name, int counter)
-{
-  OBJECT *o_current;
-  OBJECT *a_current;
-  GList *a_iter;
-  int val;
-  int internal_counter=0;
-  char *found_name = NULL;
-  char *found_value = NULL;
-  char *return_string = NULL;
-  const GList *iter;
-
-  iter = list;
-
-  while (iter != NULL) {
-    o_current = (OBJECT *)iter->data;
-    if (o_current->attribs != NULL) {
-      a_iter = o_current->attribs;
-      while(a_iter != NULL) {
-        a_current = a_iter->data;
-        if (a_current->type == OBJ_TEXT) {
-          val = o_attrib_get_name_value(a_current->text->string,
-                                        &found_name, &found_value);
-
-          if (val) {
-            if (strcmp(name, found_name) == 0) {
-              if (counter != internal_counter) {
-                internal_counter++;
-              } else {
-                return_string = g_strdup (found_value);
-                g_free(found_name);
-                g_free(found_value);
-                return(return_string);
-              }
-            }
-            if (found_name) { g_free(found_name); found_name = NULL; }
-            if (found_value) { g_free(found_value); found_value = NULL; }
-          }
-
-#if DEBUG
-          printf("0 _%s_\n", a_current->text->string);
-          printf("1 _%s_\n", found_name);
-          printf("2 _%s_\n", found_value);
-#endif
-        }
-        a_iter = g_list_next (a_iter);
-      }
-    }
-
-    /* search for attributes outside */
-
-    if (o_current->type == OBJ_TEXT) {
-      g_free(found_name);
-      g_free(found_value);
-      val = o_attrib_get_name_value(o_current->text->string, 
-                                    &found_name, &found_value);
-      if (val) {
-        if (strcmp(name, found_name) == 0) {
-          if (counter != internal_counter) {
-            internal_counter++;	
-          } else {
-            return_string = g_strdup (found_value);
-	    g_free(found_name);
-	    g_free(found_value);
-            return(return_string);
-          }
-        }
-	if (found_name) { g_free(found_name); found_name = NULL; }
-	if (found_value) { g_free(found_value); found_value = NULL; }
-      }	
-    }
-
-    iter = g_list_next (iter);
-  }
-	
-  g_free(found_name);
-  g_free(found_value);
-  return (NULL);
-} 
-
-
 /*! \brief Search for attribute by value and name.
  *  \par Function Description
  *  Search for attribute by value and name.

commit 04a22009e68284327bdb57bf7c31e5788b0bfc67
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Make use of new API o_attrib_search_inherited_attribs_by_name()
    
    Replaces the less specific API, o_attrib_search_name() previously
    used to search for floating attributes inside complex objects.

diff --git a/gnetlist/src/s_hierarchy.c b/gnetlist/src/s_hierarchy.c
index 2995b75..0b67226 100644
--- a/gnetlist/src/s_hierarchy.c
+++ b/gnetlist/src/s_hierarchy.c
@@ -56,8 +56,8 @@ s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current,
 
     /* if above is null, then look inside symbol */
     if (attrib == NULL) {
-	attrib = o_attrib_search_name(o_current->complex->prim_objs,
-				      "source", count);
+	attrib = o_attrib_search_inherited_attribs_by_name (o_current,
+	                                                    "source", count);
 
 	looking_inside = TRUE;
 #if DEBUG
@@ -153,8 +153,9 @@ s_hierarchy_traverse(TOPLEVEL * pr_current, OBJECT * o_current,
 #if DEBUG
 	    printf("looking inside\n");
 #endif
-	    attrib = o_attrib_search_name(o_current->complex->prim_objs,
-					  "source", count);
+	    attrib =
+	        o_attrib_search_inherited_attribs_by_name (o_current,
+	                                                   "source", count);
 	}
 
         graphical = s_hierarchy_graphical_search(o_current, count);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index b6736a0..1465afd 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2854,7 +2854,8 @@ DEFINE_I_CALLBACK(hierarchy_down_schematic)
 
   /* if above is null, then look inside symbol */
   if (attrib == NULL) {
-    attrib = o_attrib_search_name(object->complex->prim_objs, "source", count);
+    attrib =
+      o_attrib_search_inherited_attribs_by_name (object, "source", count);
     looking_inside = TRUE;
 #if DEBUG
     printf("going to look inside now\n");
@@ -2931,7 +2932,8 @@ DEFINE_I_CALLBACK(hierarchy_down_schematic)
 #if DEBUG
       printf("looking inside\n");
 #endif
-      attrib = o_attrib_search_name(object->complex->prim_objs, "source", count);
+      attrib =
+        o_attrib_search_inherited_attribs_by_name (object, "source", count);
     }
   }
 
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 4124ffc..4d783c4 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -524,8 +524,8 @@ int o_edit_find_text (GSCHEM_TOPLEVEL *w_current, const GList *o_list,
 
         /* if above is null, then look inside symbol */
         if (attrib == NULL) {
-          attrib = o_attrib_search_name(o_current->complex->prim_objs,
-                                        "source", count);
+          attrib = o_attrib_search_inherited_attribs_by_name (o_current,
+                                                              "source", count);
           /*          looking_inside = TRUE; */
         }
 
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 0f5e861..679dd19 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1106,7 +1106,7 @@ char *o_attrib_search_numslots(OBJECT *object)
 char *o_attrib_search_default_slot(OBJECT *object)
 {
   /* search for default value attribute buried inside the complex */
-  return o_attrib_search_name (object->complex->prim_objs, "slot", 0);
+  return o_attrib_search_inherited_attribs_by_name (object, "slot", 0);
 }
 
 
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 00fe604..1c4315b 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -1285,7 +1285,7 @@ o_complex_check_symversion(TOPLEVEL* toplevel, OBJECT* object)
   g_return_if_fail (object->complex != NULL);
 
   /* first look on the inside for the symversion= attribute */
-  inside = o_attrib_search_name(object->complex->prim_objs, "symversion", 0);
+  inside = o_attrib_search_inherited_attribs_by_name (object, "symversion", 0);
 
   /* now look for the symversion= attached to object */
   outside = o_attrib_search_attrib_name(object->attribs, "symversion", 0);
diff --git a/libgeda/src/s_hierarchy.c b/libgeda/src/s_hierarchy.c
index 731f094..20ce0a4 100644
--- a/libgeda/src/s_hierarchy.c
+++ b/libgeda/src/s_hierarchy.c
@@ -244,8 +244,8 @@ GList *s_hierarchy_traversepages(TOPLEVEL *toplevel,
       
       /* if above is NULL, then look inside symbol */
       if (filename == NULL) {
-	filename = o_attrib_search_name(o_current->
-				      complex->prim_objs, "source", 0);
+	filename =
+          o_attrib_search_inherited_attribs_by_name (o_current, "source", 0);
       }
 
       if (filename != NULL) {

commit 33b113b078e9647d7304b4c2caa04da1dd367e4f
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use o_attrib_search_object_attribs_by_name() where appropriate

diff --git a/gattrib/src/s_attrib.c b/gattrib/src/s_attrib.c
index d6afc91..6e5a485 100644
--- a/gattrib/src/s_attrib.c
+++ b/gattrib/src/s_attrib.c
@@ -84,9 +84,9 @@ char *s_attrib_get_refdes(OBJECT *object)
   OBJECT *slot_text_object;
 
   /*------ Try to get the refdes -----*/
-  temp_uref = o_attrib_search_name_single(object, "refdes", NULL);
+  temp_uref = o_attrib_search_object_attribs_by_name (object, "refdes", 0);
   if (!temp_uref) {
-    temp_uref = o_attrib_search_name_single(object, "uref", NULL); // deprecated
+    temp_uref = o_attrib_search_object_attribs_by_name (object, "uref", 0); // deprecated
     if (temp_uref) {
       printf("WARNING: Found uref=%s, uref= is deprecated, please use refdes=\n", temp_uref);
     } else {        /* didn't find refdes.  Report error to log. */
diff --git a/gattrib/src/s_sheet_data.c b/gattrib/src/s_sheet_data.c
index 185f832..3f8996d 100644
--- a/gattrib/src/s_sheet_data.c
+++ b/gattrib/src/s_sheet_data.c
@@ -263,7 +263,7 @@ void s_sheet_data_add_master_net_attrib_list_items (const GList *obj_start) {
  * 3.  Dive down to o_lower_current = o_current->complex->prim_objs
  * 4.  Loop on o_lower_current looking for OBJ_PIN
  * 5.  When we find a pin, find the pinnumber by calling
- *     o_attrib_search_name_single(o_lower_current, "pinnumber", NULL)
+ *     o_attrib_search_object_attribs_by_name (o_lower_current, "pinnumber", 0)
  * 6.  Create the pin list label as "refdes=XXX", and stick it into
  *     the master pin list.
  * Since this fcn operates on the global sheet_data->master_pin_list, 
@@ -308,7 +308,7 @@ void s_sheet_data_add_master_pin_list_items (const GList *obj_list) {
           printf ("In s_sheet_data_add_master_pin_list_items, examining object name %s\n", o_lower_current->name);
 #endif
           if (o_lower_current->type == OBJ_PIN) {
-            temp_pinnumber = o_attrib_search_name_single (o_lower_current, "pinnumber", NULL);
+            temp_pinnumber = o_attrib_search_object_attribs_by_name (o_lower_current, "pinnumber", 0);
 
             if (temp_pinnumber != NULL) {
               row_label = g_strconcat (temp_uref, ":", temp_pinnumber, NULL);
diff --git a/gattrib/src/s_table.c b/gattrib/src/s_table.c
index ba00be0..189dfc2 100644
--- a/gattrib/src/s_table.c
+++ b/gattrib/src/s_table.c
@@ -481,7 +481,7 @@ void s_table_add_toplevel_pin_items_to_pin_table (const GList *obj_list) {
 
 	  if (o_lower_current->type == OBJ_PIN) {
 	    /* -----  Found a pin.  First get its pinnumber.  then get attrib head and loop on attribs.  ----- */
-	    pinnumber = o_attrib_search_name_single(o_lower_current, "pinnumber", NULL);
+	    pinnumber = o_attrib_search_object_attribs_by_name (o_lower_current, "pinnumber", 0);
 	    row_label = g_strconcat(temp_uref, ":", pinnumber, NULL);
 
 #if DEBUG
diff --git a/gattrib/src/s_toplevel.c b/gattrib/src/s_toplevel.c
index 2843c12..2cccbc1 100644
--- a/gattrib/src/s_toplevel.c
+++ b/gattrib/src/s_toplevel.c
@@ -865,7 +865,7 @@ STRING_LIST *s_toplevel_get_pin_attribs_in_sheet(char *refdes, OBJECT *pin)
   /* First find pos of this pin in the master pin list */
   /* first convert refdes, pin to refdes:pinno text string. Then call table_get_index.  */
 
-  pinnumber = o_attrib_search_name_single(pin, "pinnumber", NULL);
+  pinnumber = o_attrib_search_object_attribs_by_name (pin, "pinnumber", 0);
 
   if ( (refdes != NULL) && (pinnumber != NULL) ) {
     row_label = g_strconcat(refdes, ":", pinnumber, NULL);
diff --git a/gnetlist/src/g_netlist.c b/gnetlist/src/g_netlist.c
index 9011c82..61d3e26 100644
--- a/gnetlist/src/g_netlist.c
+++ b/gnetlist/src/g_netlist.c
@@ -499,21 +499,9 @@ SCM g_get_package_attribute(SCM scm_uref, SCM scm_wanted_attrib)
 	if (nl_current->component_uref) {
 	    if (strcmp(nl_current->component_uref, uref) == 0) {
 
-		/* first search outside the symbol */
-		return_value =
-		    o_attrib_search_name_single(nl_current->object_ptr,
-						wanted_attrib, NULL);
-
-		if (return_value) {
-		    break;
-		}
-
-		/* now search inside the symbol */
 		return_value =
-		    o_attrib_search_name(nl_current->object_ptr->
-					 complex->prim_objs, wanted_attrib,
-					 0);
-
+		    o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
+		                                            wanted_attrib, 0);
 		break;
 	    }
 	}
@@ -577,9 +565,9 @@ SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
                                                         "pinseq", pinseq);
 
         if (o_pin_object) {
-          return_value = o_attrib_search_name_single(o_pin_object,
-                                                     wanted_attrib,
-                                                     NULL);
+          return_value =
+            o_attrib_search_object_attribs_by_name (o_pin_object,
+                                                    wanted_attrib, 0);
           if (return_value) {
             break;
           }
@@ -650,8 +638,8 @@ SCM g_get_attribute_by_pinnumber(SCM scm_uref, SCM scm_pin, SCM
 
 		    /* only look for the first occurance of wanted_attrib */
 		    return_value =
-			o_attrib_search_attrib_name(pin_object->attribs,
-						    wanted_attrib, 0);
+		      o_attrib_search_object_attribs_by_name (pin_object,
+		                                              wanted_attrib, 0);
 #if DEBUG
 		    if (return_value) {
 			printf("GOT IT: %s\n", return_value);
@@ -777,16 +765,9 @@ SCM g_get_slots(SCM scm_uref)
 
 		/* first search outside the symbol */
 		slot_tmp =
-		    o_attrib_search_name_single(nl_current->object_ptr,
-						"slot", NULL);
+		  o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
+		                                          "slot", 0);
 
-		if (!slot_tmp) {
-		/* if not found, search inside the symbol */
-		slot_tmp =
-		    o_attrib_search_name(nl_current->object_ptr->
-					 complex->prim_objs, "slot",
-					 0);
-		}
 		/* When a package has no slot attribute, then assume it's slot number 1 */
 		if (!slot_tmp) {
 		  slot_tmp=g_strdup("1");
@@ -842,16 +823,9 @@ SCM g_get_unique_slots(SCM scm_uref)
 
 		/* first search outside the symbol */
 		slot_tmp =
-		    o_attrib_search_name_single(nl_current->object_ptr,
-						"slot", NULL);
+		  o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
+		                                          "slot", 0);
 
-		if (!slot_tmp) {
-		/* if not found, search inside the symbol */
-		slot_tmp =
-		    o_attrib_search_name(nl_current->object_ptr->
-					 complex->prim_objs, "slot",
-					 0);
-		}
 		/* When a package has no slot attribute, then assume it's slot number 1 */
 		if (!slot_tmp) {
 		  slot_tmp=g_strdup("1");
@@ -984,15 +958,16 @@ SCM g_graphical_objs_in_net_with_attrib_get_attrib (SCM scm_netname, SCM scm_has
 		  if (o_attrib_get_name_value (has_attrib, &has_attrib_name,
 					       &has_attrib_value) != 0) {
 		    attrib_value = 
-		      o_attrib_search_name_single(nl_current->object_ptr,
-						  has_attrib_name, NULL);
+		      o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
+		                                              has_attrib_name, 0);
 		    
 		    if ( ((has_attrib_value == NULL) && (attrib_value == NULL)) ||
 			 ((has_attrib_value != NULL) && (attrib_value != NULL) &&
 			  (strcmp(attrib_value, has_attrib_value) == 0)) ) {
 		      g_free (attrib_value);
-		      attrib_value = o_attrib_search_name_single(nl_current->object_ptr,
-								 wanted_attrib, NULL);
+		      attrib_value =
+		        o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
+		                                                wanted_attrib, 0);
 		      if (attrib_value) {
 			list = scm_cons (scm_makfrom0str (attrib_value), list);
 		      }
diff --git a/gnetlist/src/s_hierarchy.c b/gnetlist/src/s_hierarchy.c
index f5ececb..2995b75 100644
--- a/gnetlist/src/s_hierarchy.c
+++ b/gnetlist/src/s_hierarchy.c
@@ -625,23 +625,17 @@ char *s_hierarchy_return_baseuref(TOPLEVEL * pr_current, char *uref)
     return (return_value);
 }
 
-int 
-s_hierarchy_graphical_search(OBJECT* o_current, int count)
+int s_hierarchy_graphical_search (OBJECT* o_current, int count)
 {
-    char *graphical_attrib;
-    graphical_attrib = o_attrib_search_name_single_count(o_current, 
-                                                         "graphical", count);
+  char *graphical_attrib;
+  graphical_attrib =
+    o_attrib_search_object_attribs_by_name (o_current, "graphical", count);
 
-    if (graphical_attrib == NULL) {
-       graphical_attrib = o_attrib_search_name(o_current->complex->prim_objs,
-                                               "graphical", count);
-    }
- 
-    if (graphical_attrib) {
-      g_free(graphical_attrib);      
-      return TRUE;
-    }
-  
-    return FALSE;
+  if (graphical_attrib) {
+    g_free (graphical_attrib);
+    return TRUE;
+  }
+
+  return FALSE;
 }
 
diff --git a/gnetlist/src/s_net.c b/gnetlist/src/s_net.c
index 5fdf975..d3f57c3 100644
--- a/gnetlist/src/s_net.c
+++ b/gnetlist/src/s_net.c
@@ -142,7 +142,6 @@ char *s_net_return_connected_string(TOPLEVEL * pr_current, OBJECT * object,
 				    char *hierarchy_tag)
 {
     OBJECT *o_current;
-    OBJECT *o_pinnum_object;
     char *pinnum = NULL;
     char *uref = NULL;
     SCM scm_uref;
@@ -154,9 +153,7 @@ char *s_net_return_connected_string(TOPLEVEL * pr_current, OBJECT * object,
 
     o_current = object;
 
-    /* this function only searches the single o_current */
-    pinnum = o_attrib_search_name_single(o_current, "pinnumber",
-                                         &o_pinnum_object);
+    pinnum = o_attrib_search_object_attribs_by_name (o_current, "pinnumber", 0);
 
 #if DEBUG
     printf("found pinnum: %s\n", pinnum);
diff --git a/gnetlist/src/s_traverse.c b/gnetlist/src/s_traverse.c
index f9faf0f..a23fa34 100644
--- a/gnetlist/src/s_traverse.c
+++ b/gnetlist/src/s_traverse.c
@@ -219,9 +219,7 @@ s_traverse_sheet (TOPLEVEL * pr_current, const GList *obj_list, char *hierarchy_
 	/* search of net attribute */
 	/* maybe symbol is not a component */
 	/* but a power / gnd symbol */
-	temp =
-	  o_attrib_search_name(o_current->complex->prim_objs,
-			       "net", 0);
+	temp = o_attrib_search_object_attribs_by_name (o_current, "net", 0);
 	
 	/* nope net attribute not found */
 	if ( (!temp) && (!is_graphical) ) {
@@ -288,12 +286,11 @@ CPINLIST *s_traverse_component(TOPLEVEL * pr_current, OBJECT * component,
     cpins->plid = o_current->sid;
     cpins->type = o_current->pin_type;
 
-    /* search the object only */
     cpins->pin_number =
-      o_attrib_search_name_single (o_current, "pinnumber", NULL);
+      o_attrib_search_object_attribs_by_name (o_current, "pinnumber", 0);
 
     cpins->pin_label =
-      o_attrib_search_name_single_count(o_current, "pinlabel", 0);
+      o_attrib_search_object_attribs_by_name (o_current, "pinlabel", 0);
 
     /* head nets node */
     /* is this really need */
@@ -349,7 +346,7 @@ NET *s_traverse_net (TOPLEVEL *pr_current, NET *nets, int starting,
   if (object->type != OBJ_PIN) {
     /* Ignore netname attributes on buses */
     if (object->type == OBJ_NET)
-      temp = o_attrib_search_name_single (object, "netname", NULL);
+      temp = o_attrib_search_object_attribs_by_name (object, "netname", 0);
 
     if (temp) {
       new_net->net_name =
@@ -358,7 +355,7 @@ NET *s_traverse_net (TOPLEVEL *pr_current, NET *nets, int starting,
       g_free(temp);
     } else if (object->type == OBJ_NET) {
       /* search for the old label= attribute on nets */
-      temp = o_attrib_search_name_single (object, "label", NULL);
+      temp = o_attrib_search_object_attribs_by_name (object, "label", 0);
       if (temp) {
         printf("WARNING: Found label=%s. label= is deprecated, please use netname=\n", temp);
         new_net->net_name =
@@ -379,7 +376,7 @@ NET *s_traverse_net (TOPLEVEL *pr_current, NET *nets, int starting,
     new_net->connected_to =
       s_net_return_connected_string (pr_current, object, hierarchy_tag);
 
-    temp = o_attrib_search_name_single_count (object, "pinlabel", 0);
+    temp = o_attrib_search_object_attribs_by_name (object, "pinlabel", 0);
 
     if (temp) {
       new_net->pin_label = temp;
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index f35497f..b6736a0 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -3029,22 +3029,13 @@ DEFINE_I_CALLBACK(hierarchy_documentation)
     /* only allow going into symbols */
     if (object->type == OBJ_COMPLEX) {
 
-      /* look for "documentation" first outside, then inside symbol */
-      attrib_doc = o_attrib_search_name_single_count(object, "documentation", 0);
-      if (!attrib_doc) {
-        attrib_doc = o_attrib_search_name(object->complex->prim_objs, "documentation", 0);
-      }
+      /* look for "documentation" */
+      attrib_doc = o_attrib_search_object_attribs_by_name (object, "documentation", 0);
       /* look for "device" */
-      attrib_device = o_attrib_search_name_single_count(object, "device", 0);
-      if (!attrib_device) {
-        attrib_device = o_attrib_search_name(object->complex->prim_objs, "device", 0);
-      }
+      attrib_device = o_attrib_search_object_attribs_by_name (object, "device", 0);
       /* look for "value" */
-      attrib_value = o_attrib_search_name_single_count(object, "value", 0);
-      if (!attrib_value) {
-        attrib_value = o_attrib_search_name(object->complex->prim_objs, "value", 0);
-      }
-      
+      attrib_value = o_attrib_search_object_attribs_by_name (object, "value", 0);
+
       sym = s_clib_get_symbol_by_name (object->complex_basename);
       if (sym != NULL) {
         sourcename = s_clib_source_get_name (s_clib_symbol_get_source(sym));
diff --git a/gschem/src/o_select.c b/gschem/src/o_select.c
index a844755..d2fba3a 100644
--- a/gschem/src/o_select.c
+++ b/gschem/src/o_select.c
@@ -414,7 +414,7 @@ void o_select_connected_nets(GSCHEM_TOPLEVEL *w_current, OBJECT* o_net)
 	}
 	if (w_current->net_selection_state > 2) {
 	  /* collect netnames */
-	  netname = o_attrib_search_attrib_name(o_current->attribs, "netname", 0);
+	  netname = o_attrib_search_object_attribs_by_name (o_current, "netname", 0);
 	  if (netname != NULL) {
 	    if (g_list_find_custom(netnamestack, netname, (GCompareFunc) strcmp) == NULL) {
 	      netnamestack = g_list_append(netnamestack, netname);
@@ -440,7 +440,7 @@ void o_select_connected_nets(GSCHEM_TOPLEVEL *w_current, OBJECT* o_net)
       if (o_current->type == OBJ_TEXT
 	  && o_current->attached_to != NULL) {
 	if (o_current->attached_to->type == OBJ_NET) {
-	  netname = o_attrib_search_attrib_name(o_current->attached_to->attribs, "netname", 0);
+	  netname = o_attrib_search_object_attribs_by_name (o_current->attached_to, "netname", 0);
 	  if (netname != NULL) {
 	    if (g_list_find_custom(netnamestack, netname, (GCompareFunc) strcmp) != NULL) {
 	      netstack = g_list_prepend(netstack, o_current->attached_to);
diff --git a/gschem/src/x_autonumber.c b/gschem/src/x_autonumber.c
index 0bf1a54..e9a9726 100644
--- a/gschem/src/x_autonumber.c
+++ b/gschem/src/x_autonumber.c
@@ -408,7 +408,7 @@ void autonumber_get_used(GSCHEM_TOPLEVEL *w_current, AUTONUMBER_TEXT *autotext)
 	  g_free(numslot_str);
 
 	  if (numslots > 0) { 
-	    slot_str=o_attrib_search_attrib_name(o_parent->attribs,"slot",0);
+	    slot_str = o_attrib_search_object_attribs_by_name (o_parent, "slot", 0);
 	    if (slot_str == NULL) {
 	      s_log_message(_("slotted object without slot attribute may cause "
 			      "problems when autonumbering slots\n"));
diff --git a/gsymcheck/src/s_check.c b/gsymcheck/src/s_check.c
index c6fc509..cbc6d7b 100644
--- a/gsymcheck/src/s_check.c
+++ b/gsymcheck/src/s_check.c
@@ -426,8 +426,8 @@ s_check_pinseq (const GList *obj_list, SYMCHECK *s_current)
       found_first = FALSE;
       counter = 0;
       
-      string = o_attrib_search_name_single_count(o_current, "pinseq",
-                                                 counter);
+      string = o_attrib_search_object_attribs_by_name (o_current, "pinseq",
+                                                       counter);
       if (!string)
       {
         message = g_strdup ("Missing pinseq= attribute\n");
@@ -474,8 +474,8 @@ s_check_pinseq (const GList *obj_list, SYMCHECK *s_current)
         }
         
         counter++;
-        string = o_attrib_search_name_single_count(o_current, "pinseq",
-                                                   counter);
+        string = o_attrib_search_object_attribs_by_name (o_current, "pinseq",
+                                                         counter);
       }
 
       s_current->missing_pinseq_attrib += missing_pinseq_attrib_sum;
@@ -619,8 +619,8 @@ s_check_pinnumber (const GList *obj_list, SYMCHECK *s_current)
       multiple_pinnumber_attrib_sum = 0;
       
       for (counter = 0; 
-	   (string = o_attrib_search_name_single_count(o_current, "pinnumber",
-						       counter)) != NULL;
+	   (string = o_attrib_search_object_attribs_by_name (o_current, "pinnumber",
+	                                                     counter)) != NULL;
 	   counter++) {
 	
         message = g_strdup_printf ("Found pinnumber=%s attribute\n", string);
@@ -1267,7 +1267,7 @@ s_check_missing_attribute(OBJECT *object, char *attribute, SYMCHECK *s_current)
     return;
   }
 
-  string = o_attrib_search_name_single_count (object, attribute, counter);
+  string = o_attrib_search_object_attribs_by_name (object, attribute, counter);
   if (!string)
   {
     message = g_strdup_printf (
@@ -1304,7 +1304,7 @@ s_check_missing_attribute(OBJECT *object, char *attribute, SYMCHECK *s_current)
     g_free(string);
 
     counter++;
-    string = o_attrib_search_name_single_count (object, attribute, counter);
+    string = o_attrib_search_object_attribs_by_name (object, attribute, counter);
   }
 
 }
@@ -1395,10 +1395,10 @@ void s_check_pintype (const GList *obj_list, SYMCHECK *s_current)
     if (o_current->type == OBJ_PIN) {
 
       for (counter = 0;
-	   (pintype = o_attrib_search_name_single_count(o_current, "pintype",
-							counter)) != NULL;
-	   counter++) {
-        
+           (pintype = o_attrib_search_object_attribs_by_name (o_current, "pintype",
+                                                              counter)) != NULL;
+           counter++) {
+
         message = g_strdup_printf("Found pintype=%s attribute\n", pintype);
         s_current->info_messages = g_list_append(s_current->info_messages,
 	 	    			         message);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index dcc2a1d..0f5e861 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1090,7 +1090,7 @@ char *o_attrib_search_numslots(OBJECT *object)
   if (object->type != OBJ_COMPLEX)
     return NULL;
 
-  return o_attrib_search_name (object->complex->prim_objs, "numslots", 0);
+  return o_attrib_search_object_attribs_by_name (object, "numslots", 0);
 }
 
 /*! \brief Search for default slot attribute.
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 3707c6a..00fe604 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -1291,7 +1291,7 @@ o_complex_check_symversion(TOPLEVEL* toplevel, OBJECT* object)
   outside = o_attrib_search_attrib_name(object->attribs, "symversion", 0);
 
   /* get the uref for future use */
-  refdes = o_attrib_search_attrib_name(object->attribs, "refdes", 0);
+  refdes = o_attrib_search_object_attribs_by_name(object, "refdes", 0);
   if (!refdes)
   {
     refdes = g_strdup ("unknown");

commit f6e0d43eb80615c5314c4caab7ba727a50f3bcde
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Use new attrib API for o_attrib_slot_update()
    
    Also tidy up the function a little.
    
    We now use o_attrib_search_object_attribs_by_name() to find the
    slot= attribute value of an OBJECT, so we automatically get the
    correct fallback to the symbol's embedded default slot= attribute
    value if the attached slot= attribute is missing.
    
    (This means a behavioral change in the uncommon case where the
    attached slot= attribute is missing, and the symbol specifies a
    default which is not slot=1)

diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index b0ccfe2..dcc2a1d 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1146,24 +1146,23 @@ static char *o_attrib_search_slotdef (OBJECT *object, int slotnumber)
 
 /*! \brief Update all slot attributes in an object.
  *  \par Function Description
- *  Update pinnumber attributes in a graphic object.  
+ *  Update pinnumber attributes in a graphic object.
  *  The interesting case is where the object is an
- *  instantiation of a slotted part.  This means that 
+ *  instantiation of a slotted part.  This means that
  *  o_attrib_slot_update iterates through all pins
  *  found on object and sets the pinnumber= attrib
  *  on each.  This doesn't matter for non-slotted
- *  parts, but on slotted parts, this is what sets the 
+ *  parts, but on slotted parts, this is what sets the
  *  pinnumber= attribute on slots 2, 3, 4....
  *
  *  \param [in]     toplevel  The TOPLEVEL object.
  *  \param [in,out] object     The OBJECT to update.
  */
-void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object)
+void o_attrib_slot_update (TOPLEVEL *toplevel, OBJECT *object)
 {
-  OBJECT *o_current;  /* o_current points to the sch level complex object */
-  OBJECT *o_slot_attrib;
   OBJECT *o_pin_object;
-  OBJECT *o_pinnum_object;
+  OBJECT *o_pinnum_attrib;
+  GList *attributes;
   char *string;
   char *slotdef;
   char *pinseq;
@@ -1173,40 +1172,38 @@ void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object)
   char* current_pin;  /* text from slotdef= to be made into pinnumber= */
   char* cptr;         /* char pointer pointing to pinnumbers in slotdef=#:#,#,# string */
 
-  o_current = object;
   /* For this particular graphic object (component instantiation) */
   /* get the slot number as a string */
-  string = o_attrib_search_slot(o_current, &o_slot_attrib);
+  string = o_attrib_search_object_attribs_by_name (object, "slot", 0);
 
-  if (!string) {
-    /* "Did not find slot= attribute", this is true if 
-     *  * there is no slot attribut
-     *  * or the slot attribute was deleted and we have to assume to use the 
-     *    first slot now
+  if (string == NULL) {
+    /* Did not find slot= attribute.
+     * This happens if there is no attached slot attribute, and
+     * there is no default slot= attribute inside the symbol.
+     * Assume slot=1.
      */
     slot = 1;
     slot_string = 0;
-  } 
-  else {
+  } else {
     slot_string = 1;
-    slot = atoi(string);
-    g_free(string);
+    slot = atoi (string);
+    g_free (string);
   }
-  
+
   /* OK, now that we have the slot number, use it to get the */
   /* corresponding slotdef=#:#,#,# string.  */
-  slotdef = o_attrib_search_slotdef(o_current, slot);
-  
-  if (!slotdef) { 
+  slotdef = o_attrib_search_slotdef (object, slot);
+
+  if (slotdef == NULL) {
     if (slot_string) /* only an error if there's a slot string */
-      s_log_message(_("Did not find slotdef=#:#,#,#... attribute\n"));
+      s_log_message (_("Did not find slotdef=#:#,#,#... attribute\n"));
     return;
   }
 
-  if (!strstr(slotdef, ":")) {
+  if (!strstr (slotdef, ":")) {
     /* Didn't find proper slotdef=#:... put warning into log */
-    s_log_message(_("Improper slotdef syntax: missing \":\".\n"));
-    g_free(slotdef);    
+    s_log_message (_("Improper slotdef syntax: missing \":\".\n"));
+    g_free (slotdef);
     return;
   }
 
@@ -1220,47 +1217,43 @@ void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object)
   cptr++; /* skip colon */
 
   if (*cptr == '\0') {
-    s_log_message(_("Did not find proper slotdef=#:#,#,#... attribute\n"));
-    g_free(slotdef);    
+    s_log_message (_("Did not find proper slotdef=#:#,#,#... attribute\n"));
+    g_free (slotdef);
     return;
   }
 
   /* loop on all pins found in slotdef= attribute */
   pin_counter = 1;  /* internal pin_counter */
   /* get current pinnumber= from slotdef= attrib */
-  current_pin = strtok(cptr, DELIMITERS); 
-  while(current_pin != NULL) {
+  current_pin = strtok (cptr, DELIMITERS);
+  while (current_pin != NULL) {
     /* get pin on this component with pinseq == pin_counter */
     pinseq = g_strdup_printf ("%d", pin_counter);
-    o_pin_object = o_complex_find_pin_by_attribute (o_current,
-                                                    "pinseq", pinseq);
+    o_pin_object = o_complex_find_pin_by_attribute (object, "pinseq", pinseq);
     g_free (pinseq);
 
-    if (o_pin_object) {
+    if (o_pin_object != NULL) {
       /* Now rename pinnumber= attrib on this part with value found */
       /* in slotdef attribute  */
-      string = o_attrib_search_name_single(o_pin_object, "pinnumber",
-                                           &o_pinnum_object);
-  
-      if (string && o_pinnum_object && o_pinnum_object->type == OBJ_TEXT &&
-          o_pinnum_object->text->string) {
-        g_free(o_pinnum_object->text->string);
-
-        o_pinnum_object->text->string = g_strdup_printf ("pinnumber=%s", current_pin);
-        
-        o_text_recreate(toplevel, o_pinnum_object);
+      attributes = o_attrib_return_attribs (o_pin_object);
+      o_pinnum_attrib = o_attrib_find_attrib_by_name (attributes, "pinnumber", 0);
+      g_list_free (attributes);
+
+      if (o_pinnum_attrib != NULL) {
+        g_free (o_pinnum_attrib->text->string);
+        o_pinnum_attrib->text->string = g_strdup_printf ("pinnumber=%s", current_pin);
+        o_text_recreate (toplevel, o_pinnum_attrib);
       }
-      g_free(string);
 
       pin_counter++;
     } else {
-      s_log_message(_("component missing pinseq= attribute\n"));
+      s_log_message (_("component missing pinseq= attribute\n"));
     }
-    
-    current_pin = strtok(NULL, DELIMITERS);
-  } 
-  
-  g_free(slotdef);
+
+    current_pin = strtok (NULL, DELIMITERS);
+  }
+
+  g_free (slotdef);
 }
 
 

commit b4996e267b5d9696f7e8122c40b31482ef852904
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gnetlist: Use new attrib API for s_netattrib_{handle,net_search}()
    
    Also tidy up the function implementation somewhat.

diff --git a/gnetlist/src/s_netattrib.c b/gnetlist/src/s_netattrib.c
index 9fa0a11..0467b31 100644
--- a/gnetlist/src/s_netattrib.c
+++ b/gnetlist/src/s_netattrib.c
@@ -178,162 +178,119 @@ s_netattrib_create_pins(TOPLEVEL * pr_current, OBJECT * o_current,
 
 
 void
-s_netattrib_handle(TOPLEVEL * pr_current, OBJECT * o_current,
-		   NETLIST * netlist, char *hierarchy_tag)
+s_netattrib_handle (TOPLEVEL * pr_current, OBJECT * o_current,
+                    NETLIST * netlist, char *hierarchy_tag)
 {
-    char *value;
-    int counter = 0;
-
-    /* for now just look inside the component */
-    value = o_attrib_search_name(o_current->complex->prim_objs,
-				 "net", counter);
-
-#if DEBUG
-    printf("found net= %s\n", value);
-#endif
-
-    while (value != NULL) {
-	if (value) {
-	    s_netattrib_create_pins(pr_current, o_current, netlist, value,
-				    hierarchy_tag);
-	    g_free(value);
-	}
-	counter++;
-	value = o_attrib_search_name(o_current->complex->prim_objs,
-				     "net", counter);
-#if DEBUG
-	printf("found net= %s\n", value);
-#endif
-    }
-
-
-    g_free(value);
-
-
-    /* for now just look inside the component */
-    counter = 0;
-    value = o_attrib_search_name_single_count(o_current, "net", counter);
-    while (value != NULL) {
-	if (value) {
-	    s_netattrib_create_pins(pr_current, o_current, netlist, value,
-				    hierarchy_tag);
-	    g_free(value);
-	}
-	counter++;
-	value =
-	    o_attrib_search_name_single_count(o_current, "net", counter);
-    }
-
-    g_free(value);
+  char *value;
+  int counter;
+
+  /* for now just look inside the component */
+  for (counter = 0; ;) {
+    value = o_attrib_search_inherited_attribs_by_name (o_current,
+                                                       "net", counter);
+    if (value == NULL)
+      break;
+
+    counter++;
+
+    s_netattrib_create_pins (pr_current, o_current,
+                             netlist, value, hierarchy_tag);
+    g_free (value);
+  }
+
+  /* now look outside the component */
+  for (counter = 0; ;) {
+    value = o_attrib_search_attached_attribs_by_name (o_current,
+                                                      "net", counter);
+    if (value == NULL)
+      break;
+
+    counter++;
+
+    s_netattrib_create_pins (pr_current, o_current,
+                             netlist, value, hierarchy_tag);
+    g_free (value);
+  }
 }
 
-char *s_netattrib_net_search(OBJECT * o_current, char *wanted_pin)
+char *s_netattrib_net_search (OBJECT * o_current, char *wanted_pin)
 {
-    char *value = NULL;
-    char *char_ptr = NULL;
-    char *net_name = NULL;
-    char *current_pin = NULL;
-    char *start_of_pinlist = NULL;
-    char *return_value = NULL;
-    int counter = 0;
-
-    if (o_current == NULL) {
-	return(NULL); 
-    }
-
-    if (o_current->complex == NULL) {
-	return(NULL); 
+  char *value = NULL;
+  char *char_ptr = NULL;
+  char *net_name = NULL;
+  char *current_pin = NULL;
+  char *start_of_pinlist = NULL;
+  char *return_value = NULL;
+  int counter;
+
+  if (o_current == NULL ||
+      o_current->complex == NULL)
+    return NULL;
+
+  /* for now just look inside the component */
+  for (counter = 0; ;) {
+    value = o_attrib_search_inherited_attribs_by_name (o_current,
+                                                       "net", counter);
+    if (value == NULL)
+      break;
+
+    counter++;
+
+    char_ptr = strchr (value, ':');
+    if (char_ptr == NULL) {
+      fprintf (stderr, "Got an invalid net= attrib [net=%s]\n"
+                       "Missing : in net= attrib\n", value);
+      g_free (value);
+      return NULL;
     }
 
-    /* for now just look inside the component */
-    value = o_attrib_search_name(o_current->complex->prim_objs,
-				 "net", counter);
-    while (value != NULL) {
-	if (value) {
-	    char_ptr = strchr(value, ':');
-	    if (char_ptr == NULL) {
-		fprintf(stderr, "Got an invalid net= attrib [net=%s]\nMissing : in net= attrib\n",
-			value);
-		return (NULL);
-	    }
-
-	    net_name = s_netattrib_extract_netname(value);
+    net_name = s_netattrib_extract_netname (value);
 
-	    start_of_pinlist = char_ptr + 1;
-	    current_pin = strtok(start_of_pinlist, DELIMITERS);
-	    while (current_pin && !return_value) {
-#if DEBUG
-		printf("looking at: %s\n", current_pin);
-#endif
-		if (strcmp(current_pin, wanted_pin) == 0) {
-#if DEBUG
-		    printf("found net_name: _%s_\n", net_name);
-#endif
-		    return_value = net_name;
-		}
-		current_pin = strtok(NULL, DELIMITERS);
-	    }
-
-	    g_free(value);
-	}
-	counter++;
-	value = o_attrib_search_name(o_current->complex->prim_objs,
-				     "net", counter);
+    start_of_pinlist = char_ptr + 1;
+    current_pin = strtok (start_of_pinlist, DELIMITERS);
+    while (current_pin && !return_value) {
+      if (strcmp (current_pin, wanted_pin) == 0) {
+        return_value = net_name;
+      }
+      current_pin = strtok (NULL, DELIMITERS);
     }
 
+    g_free (value);
+  }
 
-    g_free(value);
-
-
-    /* now look outside the component */
-    counter = 0;
-    value = o_attrib_search_name_single_count(o_current, "net", counter);
-    while (value != NULL) {
-	if (value) {
-	    char_ptr = strchr(value, ':');
-	    if (char_ptr == NULL) {
-		fprintf(stderr, "Got an invalid net= attrib [net=%s]\nMissing : in net= attrib\n",
-			value);
-		return (NULL);
-	    }
-
-	    net_name = s_netattrib_extract_netname(value);
+  /* now look outside the component */
+  for (counter = 0; ;) {
+    value = o_attrib_search_attached_attribs_by_name (o_current,
+                                                      "net", counter);
+    if (value == NULL)
+      break;
 
-	    start_of_pinlist = char_ptr + 1;
-	    current_pin = strtok(start_of_pinlist, DELIMITERS);
-	    while (current_pin) {
+    counter++;
 
-#if DEBUG
-		printf("looking at: %s\n", current_pin);
-#endif
-		if (strcmp(current_pin, wanted_pin) == 0) {
-#if DEBUG
-		    printf("found net_name: _%s_\n", net_name);
-#endif
-		    if (return_value) {
-			g_free(return_value);
-			return_value = NULL;
-		    }
+    char_ptr = strchr (value, ':');
+    if (char_ptr == NULL) {
+      fprintf (stderr, "Got an invalid net= attrib [net=%s]\n"
+                       "Missing : in net= attrib\n", value);
+      g_free (value);
+      return NULL;
+    }
 
-		    return (net_name);
-		}
-		current_pin = strtok(NULL, DELIMITERS);
-	    }
+    net_name = s_netattrib_extract_netname (value);
 
-	    g_free(value);
-	}
-	counter++;
-	value =
-	    o_attrib_search_name_single_count(o_current, "net", counter);
+    start_of_pinlist = char_ptr + 1;
+    current_pin = strtok (start_of_pinlist, DELIMITERS);
+    while (current_pin && !return_value) {
+      if (strcmp (current_pin, wanted_pin) == 0) {
+        g_free (return_value);
+        return net_name;
+      }
+      current_pin = strtok (NULL, DELIMITERS);
     }
 
-    g_free(value);
+    g_free (value);
+  }
 
-    if (return_value) {
-	return (return_value);
-    } else {
-	return (NULL);
-    }
+  return return_value;
 }
 
 char *s_netattrib_return_netname(TOPLEVEL * pr_current, OBJECT * o_current,

commit 52fc6981d5dc91cb08e3314d5b77bdb7505418ba
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_attrib_search_string_list() and o_attrib_search_string_single()
    
    Reworked the one remaining caller of these functions to use
    o_complex_find_pin_by_attribute(), which utilises the newer APIs.

diff --git a/gnetlist/src/g_netlist.c b/gnetlist/src/g_netlist.c
index 880808a..9011c82 100644
--- a/gnetlist/src/g_netlist.c
+++ b/gnetlist/src/g_netlist.c
@@ -539,9 +539,7 @@ SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
   char *uref;
   char *pinseq;
   char *wanted_attrib;
-  char *pinseq_attrib;
   char *return_value = NULL;
-  OBJECT *o_text_object;
   OBJECT *o_pin_object;
 
   SCM_ASSERT(scm_is_string (scm_uref),
@@ -557,8 +555,6 @@ SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
   uref          = SCM_STRING_CHARS (scm_uref);
   pinseq        = SCM_STRING_CHARS (scm_pinseq);
   wanted_attrib = SCM_STRING_CHARS (scm_wanted_attrib);
-  
-  pinseq_attrib = g_strconcat ("pinseq=", pinseq, NULL);
 
 #if DEBUG
   printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- \n");
@@ -577,48 +573,18 @@ SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
     if (nl_current->component_uref) {
       if (strcmp(nl_current->component_uref, uref) == 0) {
 
-        /* first search outside the symbol */
-	/* This checks for attributes attached to this component */
-        /* at schematic level */
-        o_text_object = o_attrib_search_string_single(nl_current->object_ptr,
-                                                      pinseq_attrib);
-        if (o_text_object && o_text_object->attached_to) {
-          o_pin_object = o_text_object->attached_to;
-
-          if (o_pin_object) {
-            return_value = o_attrib_search_name_single(o_pin_object,
-                                                       wanted_attrib,
-                                                       NULL);
-            if (return_value) {
-              break;
-            }
-          }
+        o_pin_object = o_complex_find_pin_by_attribute (nl_current->object_ptr,
+                                                        "pinseq", pinseq);
 
-        } else {
-#if DEBUG
-	  printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- ");
-          printf("can't find pinseq at schematic level\n");
-#endif
-	}
-
-        
-        /* now search inside the symbol */
-	/* This checks for attributes attached at the symbol level */
-        o_text_object =
-          o_attrib_search_string_list(nl_current->object_ptr->
-                                      complex->prim_objs, pinseq_attrib);
-
-        if (o_text_object && o_text_object->attached_to) {
-          o_pin_object = o_text_object->attached_to;
-          if (o_pin_object) {
-            return_value = o_attrib_search_name_single(o_pin_object,
-                                                       wanted_attrib,
-                                                       NULL);
-            if (return_value) {
-              break;
-            }
+        if (o_pin_object) {
+          return_value = o_attrib_search_name_single(o_pin_object,
+                                                     wanted_attrib,
+                                                     NULL);
+          if (return_value) {
+            break;
           }
-        }         
+        }
+
         /* Don't break until we search the whole netlist to handle slotted */
         /* parts.   4.28.2007 -- SDB. */
       }
@@ -637,8 +603,6 @@ SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
   printf("return_value: %s\n", return_value);
 #endif
 
-  g_free(pinseq_attrib);
-
   return (scm_return_value);
 }
 
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index e9ae505..81bd057 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -107,8 +107,6 @@ char *o_attrib_search_attached_attribs_by_name (OBJECT *object, char *name, int
 char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_name(const GList *list, char *name, int counter);
-OBJECT *o_attrib_search_string_list(GList *list, char *string);
-OBJECT *o_attrib_search_string_single(OBJECT *object, char *search_for);
 OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name, int counter);
 char *o_attrib_search_attrib_name(GList *list, char *name, int counter);
 char *o_attrib_search_name_single(OBJECT *object, char *name, OBJECT **return_found);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index ea05fed..b0ccfe2 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -725,130 +725,6 @@ char *o_attrib_search_name (const GList *list, char *name, int counter)
   return (NULL);
 } 
 
-/*! \brief Search OBJECT list for text string.
- *  \par Function Description
- *  Given an OBJECT list (i.e. OBJECTs on schematic page or
- *  inside symbol), search for the attribute called out in
- *  "string".  It iterates over all objects in the OBJECT list
- *  and dives into the attached attribute OBJECT list for
- *  each OBJECT if it finds one.
- *  Inside the attribute OBJECT list it looks for an attached text
- *  attribute matching "string".  It returns the
- *  pointer to the associated OBJECT if found.  If the attribute
- *  string is not found in the attribute OBJECT list, then the fcn
- *  looks on the OBJECT itself for the attribute.  Then it
- *  iterates to the next OBJECT.
- *
- *  \warning
- *  The list is the top level list. Do not pass it an object_list list
- *  unless you know what you are doing.
- *  
- *  \param [in] list    OBJECT list to search.
- *  \param [in] string  Character string to search for.
- *  \return A matching OBJECT if found, NULL otherwise.
- */
-OBJECT *o_attrib_search_string_list (GList *list, char *string)
-{
-  OBJECT *o_current;
-  OBJECT *a_current;
-  GList *a_iter;
-  GList *o_iter;
-
-  o_iter = list;
-
-  while (o_iter != NULL) {
-    o_current = o_iter->data;
-    /* first search attribute list */
-    if (o_current->attribs != NULL) {
-      a_iter = o_current->attribs;
-
-      while(a_iter != NULL) {
-        a_current = a_iter->data;
-        if (a_current->type == OBJ_TEXT) {
-#if DEBUG
-    printf("libgeda:o_attrib.c:o_attrib_search_string_list --");
-    printf("found OBJ_TEXT, string = %s\n", found->text->string);
-#endif
-          if (strcmp(string, a_current->text->string) == 0) {
-            return a_current;
-          }
-        }
-        a_iter = g_list_next (a_iter);
-      }
-    }
-
-    /* search for attributes outside (ie the actual object) */
-    if (o_current->type == OBJ_TEXT) {
-      if (strcmp(string, o_current->text->string) == 0) {
-        return(o_current);
-      }
-    }
-    
-    o_iter = g_list_next (o_iter);
-  }
-
-  return (NULL);
-} 
-
-
-/*! \brief Check if object matches string.
- *  \par Function Description
- *  This function will check if the text->string value of
- *  the passed OBJECT matches the <B>search_for</B> parameter.
- *  If not, it then searches the object's attribute list
- *  (if it has one.)
- *  Only this single OBJECT and its attribute list is
- *  checked, and other OBJECTs on the page are not checked.
- *  \param [in] object      The OBJECT to compare.
- *  \param [in] search_for  Character string to compare against.  
- *  Usually name=value
- *  \return The OBJECT passed in <B>object</B> parameter, NULL otherwise.
- */
-OBJECT *o_attrib_search_string_single(OBJECT *object, char *search_for)
-{
-  OBJECT *o_current;
-  OBJECT *a_current;
-  GList *a_iter;
-
-  o_current = object;
-
-#if DEBUG
-  printf("In libgeda:o_attrib.c:o_attrib_search_string_single\n");
-  printf("   Examining object->name = %s\n", object->name);
-#endif
-
-  if (o_current == NULL) {
-    return(NULL);
-  }
-
-  /* First check to see if this OBJECT itself is the attribute we want */
-  if (o_current->type == OBJ_TEXT) {
-    if (strcmp(o_current->text->string, search_for) == 0) {
-#if DEBUG
-      printf("   This object is searched-for attribute\n");
-#endif
-      return(o_current);
-    }
-  }
-
-  /* Next check to see if this OBJECT has an attribute list we */
-  /* can search.  If not return NULL.  If so, search it. */
-  if (o_current->attribs == NULL) 
-    return(NULL);
-
-  a_iter = o_current->attribs;
-  while(a_iter != NULL) {
-    a_current = a_iter->data;
-    if (a_current->type == OBJ_TEXT) {
-      if(strcmp(a_current->text->string, search_for) == 0) {
-        return a_current;
-      }
-    }
-    a_iter = g_list_next (a_iter);
-  }
-
-  return (NULL);
-} 
 
 /*! \brief Search for attribute by value and name.
  *  \par Function Description

commit 031e46d5d1b8071ebcde097b2a0f75984885a953
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Replace o_attrib_search_pinseq() with o_complex_find_pin_by_attribute()
    
    Calling o_complex_find_pin_by_attribute() with "pinseq" as its name
    argument, a char * wanted_value and a complex OBJECT (rather than its
    prim_objs) is functionally identical.

diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 22c1565..ea05fed 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1233,31 +1233,6 @@ char *o_attrib_search_default_slot(OBJECT *object)
   return o_attrib_search_name (object->complex->prim_objs, "slot", 0);
 }
 
-/*! \brief Search pinseq attribute.
- *  \par Function Description
- *  Given list of objects (generally a pin with attached attribs), 
- *  and a pinnumber, 
- *  search for and return pinseq= attrib (object).
- *
- *  \param [in] list        GList list to search.
- *  \param [in] pin_number  pin number to search for.
- *  \return OBJECT containing pinseq data, NULL otherwise.
- */
-static OBJECT *o_attrib_search_pinseq (GList *list, int pin_number)
-{
-  OBJECT *pinseq_text_object;
-  char *search_for;
-
-  search_for = g_strdup_printf ("pinseq=%d", pin_number);
-  pinseq_text_object = o_attrib_search_string_list(list, search_for);
-  g_free(search_for);
-  
-  if (pinseq_text_object && pinseq_text_object->attached_to) {
-    return pinseq_text_object->attached_to;
-  }
-  
-  return(NULL);
-}
 
 /*! \brief Search for slotdef attribute.
  *  \par Function Description
@@ -1315,6 +1290,7 @@ void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object)
   OBJECT *o_pinnum_object;
   char *string;
   char *slotdef;
+  char *pinseq;
   int slot;
   int slot_string;
   int pin_counter;    /* Internal pin counter private to this fcn. */
@@ -1379,8 +1355,10 @@ void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object)
   current_pin = strtok(cptr, DELIMITERS); 
   while(current_pin != NULL) {
     /* get pin on this component with pinseq == pin_counter */
-    o_pin_object = o_attrib_search_pinseq(o_current->complex->prim_objs, 
-                                          pin_counter);
+    pinseq = g_strdup_printf ("%d", pin_counter);
+    o_pin_object = o_complex_find_pin_by_attribute (o_current,
+                                                    "pinseq", pinseq);
+    g_free (pinseq);
 
     if (o_pin_object) {
       /* Now rename pinnumber= attrib on this part with value found */

commit 58859ac33ddd97e1cb7aa6eeaff832d3ed87c725
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Replace o_complex_return_pin() with new o_complex_find_pin_by_attribute()
    
    Implement a more generic version of o_complex_return_pin(). The old
    function takes a pinnumber as its argument, and finds a pin which has
    a matching "pinnumber=..." attribute.
    
    The new function takes an explicit attribute name argument as well as
    the value, so we can find pins by any attached attribute. This is useful
    so we can search by "pinseq=..." attributes as well.

diff --git a/gnetlist/src/g_netlist.c b/gnetlist/src/g_netlist.c
index 21fe86c..880808a 100644
--- a/gnetlist/src/g_netlist.c
+++ b/gnetlist/src/g_netlist.c
@@ -679,8 +679,8 @@ SCM g_get_attribute_by_pinnumber(SCM scm_uref, SCM scm_pin, SCM
 	    if (strcmp(nl_current->component_uref, uref) == 0) {
 
 		pin_object =
-		    o_complex_return_pin_object(nl_current->object_ptr,
-						pin);
+		    o_complex_find_pin_by_attribute (nl_current->object_ptr,
+		                                     "pinnumber", pin);
 
 		if (pin_object) {
 
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index a40ef72..e9ae505 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -186,7 +186,7 @@ void o_complex_unset_color_single(OBJECT *o_current);
 void o_complex_set_saved_color_only(GList *list, int color);
 void o_complex_rotate_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, int angle, OBJECT *object);
 void o_complex_mirror_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, OBJECT *object);
-OBJECT *o_complex_return_pin_object(OBJECT *object, char *pin);
+OBJECT *o_complex_find_pin_by_attribute(OBJECT *object, char *name, char *wanted_value);
 void o_complex_check_symversion(TOPLEVEL* toplevel, OBJECT* object);
 
 /* o_embed.c */
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 810f9eb..3707c6a 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -1214,48 +1214,43 @@ void o_complex_mirror_world(TOPLEVEL *toplevel,
 }
 
 
-/*! \brief search the pin with a given pin number
+/*! \brief Find a pin with a particular attribute.
  *  \par Function Description
- *  This function searches a pin object inside the complex \a object.
- *  The pin name is a character string \a pin.
-
- *  \param  object  The complex object
- *  \param  pin     The pin number (string) to find
- *  \return a pin object if found, NULL otherwise
+ *  Search for a pin inside the given complex which has an attribute
+ *  matching those passed.
+ *
+ *  \param [in] object        complex OBJECT whos pins to search.
+ *  \param [in] name          the attribute name to search for.
+ *  \param [in] wanted_value  the attribute value to search for.
+ *  \return The pin OBJECT with the given attribute, NULL otherwise.
  */
-OBJECT *o_complex_return_pin_object(OBJECT *object, char *pin) 
+OBJECT *o_complex_find_pin_by_attribute (OBJECT *object, char *name, char *wanted_value)
 {
-  OBJECT *found;
   GList *iter;
+  OBJECT *o_current;
+  char *value;
+  int found;
 
-  g_return_val_if_fail(object != NULL, NULL);
-  g_return_val_if_fail(((object->type == OBJ_COMPLEX) ||
-			(object->type == OBJ_PLACEHOLDER)) , NULL);
-  g_return_val_if_fail(object->complex != NULL, NULL);
+  g_return_val_if_fail (object != NULL, NULL);
+  g_return_val_if_fail (object->type == OBJ_COMPLEX ||
+                        object->type == OBJ_PLACEHOLDER, NULL);
 
-  /* go inside complex objects */
-  for (iter = object->complex->prim_objs;
-       iter != NULL;
+  for (iter = object->complex->prim_objs; iter != NULL;
        iter = g_list_next (iter)) {
-    OBJECT *o_current = iter->data;
+    o_current = iter->data;
 
-    switch(o_current->type) {
-      case(OBJ_PIN):
-        /* Search for the pin making sure that */
-        /* any found attribute starts with "pinnumber" */
-        found = o_attrib_search_attrib_value(o_current->attribs, pin,
-                                             "pinnumber", 0);
-        if (found) {
-#if DEBUG
-          printf("%s: %s\n", found->name,
-                 found->text->string);
-#endif
-          return(o_current);
-        }
-        break;
-    }
+    if (o_current->type != OBJ_PIN)
+      continue;
+
+    value = o_attrib_search_object_attribs_by_name (o_current, name, 0);
+    found = (value != NULL && strcmp (value, wanted_value) == 0);
+    g_free (value);
+
+    if (found)
+      return o_current;
   }
-  return(NULL);
+
+  return NULL;
 }
 
 

commit 9e375afb9c865705ed4eff3b982f1a1a3e8fc843
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove unused function o_complex_return_nth_pin()

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index a7943e2..a40ef72 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -184,7 +184,6 @@ void o_complex_set_color_save(GList *list, int color);
 void o_complex_unset_color(GList *list);
 void o_complex_unset_color_single(OBJECT *o_current);
 void o_complex_set_saved_color_only(GList *list, int color);
-OBJECT *o_complex_return_nth_pin(GList *list, int counter);
 void o_complex_rotate_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, int angle, OBJECT *object);
 void o_complex_mirror_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, OBJECT *object);
 OBJECT *o_complex_return_pin_object(OBJECT *object, char *pin);
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index bd5bd10..810f9eb 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -1133,38 +1133,6 @@ void o_complex_set_saved_color_only (GList *list, int color)
   }
 }
 
-/*! \brief get the nth pin of a object list
- *  \par Function Description
- *  Search the nth pin the object list \a list and return it.
- *  
- *  \param list     the object list to search through
- *  \param counter  specifies the nth pin
- *  \return the counter'th pin object, NULL if there is no more pin
- */
-OBJECT *o_complex_return_nth_pin (GList *list, int counter)
-{
-  OBJECT *o_current;
-  int internal_counter=0;
-  GList *iter;
-
-  iter = list;
-
-  while (iter != NULL) {
-    o_current = (OBJECT *)iter->data;
-    if (o_current->type == OBJ_PIN) {
-
-      if (counter == internal_counter) {
-        return(o_current);
-      } else {
-        internal_counter++;
-      }
-    }
-    iter = g_list_next (iter);
-  }
-
-  return(NULL);
-}
-
 
 /*! \todo Finish function documentation!!!
  *  \brief

commit 2212036b0b38fb4c929d2abeaec638e4d483b91b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Allow symbols to override the slotdef= attribute definitions
    
    This should pave the way to allow attachement of slotdef= attributes
    overriding those inside the symbol.
    
    NB: If this is done, pinnumber updates in gschem won't be triggered
    immediately, since they are only run when a slot= attribute changes.

diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 00ee372..22c1565 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1279,8 +1279,8 @@ static char *o_attrib_search_slotdef (OBJECT *object, int slotnumber)
   search_for = g_strdup_printf ("%d:", slotnumber);
 
   while (1) {
-    slotdef = o_attrib_search_inherited_attribs_by_name (object, "slotdef",
-                                                         counter++);
+    slotdef = o_attrib_search_object_attribs_by_name (object, "slotdef",
+                                                      counter++);
     if (slotdef == NULL ||
         strncmp (slotdef, search_for, strlen (search_for)) == 0)
       break;

commit 3dc2a7150357119355212af164e38299df8e1649
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Eliminate usage of, and remove o_attrib_search_string_partial()
    
    This function's one caller was using it to find an attribute containing
    "slotdef=X:", where X is the slot number being retrieved.
    
    o_attribute_search_string_partial() would look at the full name=value
    string of each text object in the given object list, looking for a
    substring match on the desired text. (In fact, we only want a match
    at the beginning of the string).
    
    The new implementation may be somewhat less efficient, since it queries
    all slotdef= attributes in turn, checking to see if the one returned is
    the desired value. The speed penalty should be impercievable though, and
    the new code better abstracts the implementation details of the attribute
    system.

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 6b133bb..a7943e2 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -108,7 +108,6 @@ char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int
 char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_name(const GList *list, char *name, int counter);
 OBJECT *o_attrib_search_string_list(GList *list, char *string);
-char *o_attrib_search_string_partial(OBJECT *object, char *search_for, int counter);
 OBJECT *o_attrib_search_string_single(OBJECT *object, char *search_for);
 OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name, int counter);
 char *o_attrib_search_attrib_name(GList *list, char *name, int counter);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 31a10e5..00ee372 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -790,55 +790,6 @@ OBJECT *o_attrib_search_string_list (GList *list, char *string)
   return (NULL);
 } 
 
-/*! \brief Search list for partial string match.
- *  \par Function Description
- *  Search list for partial string match.
- *
- *  Counter is the n'th occurance of the attribute, and starts searching
- *  from zero.  Zero is the first occurance of an attribute.
- *
- *  \param [in] object      The OBJECT list to search.
- *  \param [in] search_for  Partial character string to search for.
- *  \param [in] counter     Which occurance to return.
- *  \return Matching object value if found, NULL otherwise.
- *
- *  \warning
- *  Caller must g_free returned character string.
- */
-char *o_attrib_search_string_partial(OBJECT *object, char *search_for,
-				     int counter) 
-{
-  OBJECT *o_current;
-  int val;
-  int internal_counter=0;
-  char *found_value = NULL;
-  char *return_string = NULL;
-
-  o_current = object;
-
-  if (o_current == NULL) {
-    return(NULL);
-  }
-
-  if (o_current->type == OBJ_TEXT) {
-    if (strstr(o_current->text->string, search_for)) {
-      if (counter != internal_counter) {
-        internal_counter++;	
-      } else {
-        val = o_attrib_get_name_value(o_current->text->string, 
-                                      NULL, &found_value);
-        if (val) {
-          return_string = g_strdup(found_value);
-	  g_free(found_value);
-	  return(return_string);
-        }
-      }
-    }
-  }	
-	
-  g_free(found_value);
-  return (NULL);
-} 
 
 /*! \brief Check if object matches string.
  *  \par Function Description
@@ -1319,31 +1270,26 @@ static OBJECT *o_attrib_search_pinseq (GList *list, int pin_number)
  *  \warning
  *  Caller must g_free returned character string.
  */
-static char *o_attrib_search_slotdef(OBJECT *object, int slotnumber)
+static char *o_attrib_search_slotdef (OBJECT *object, int slotnumber)
 {
-  char *return_value=NULL;
-  char *search_for=NULL;
-  OBJECT *o_current;
-  GList *iter;
+  int counter;
+  char *slotdef;
+  char *search_for;
 
-  search_for = g_strdup_printf ("slotdef=%d:", slotnumber);
+  search_for = g_strdup_printf ("%d:", slotnumber);
 
-  iter = object->complex->prim_objs;
-  while (iter != NULL) {
-    o_current = (OBJECT *)iter->data;
-    return_value = o_attrib_search_string_partial(o_current, search_for, 0);
-    if (return_value) {
+  while (1) {
+    slotdef = o_attrib_search_inherited_attribs_by_name (object, "slotdef",
+                                                         counter++);
+    if (slotdef == NULL ||
+        strncmp (slotdef, search_for, strlen (search_for)) == 0)
       break;
-    }
-    iter = g_list_next (iter);
-  }
-  g_free(search_for);
 
-  if (return_value) {
-    return(return_value);
+    g_free (slotdef);
   }
 
-  return(NULL);
+  g_free (search_for);
+  return slotdef;
 }
 
 

commit 8a2e32035cdac22ca6d355560bb9fdf935a99af8
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Move logic of function o_attrib_search_toplevel_all() to its one caller
    
    This function was only used in one place, and probably didn't deserve its
    own API in libgeda. The function it is called from is not used anyway, so
    could probably be removed completely at some point. (Although it forms
    part of the scheme API for gnetlist, comments above it suggest that it is
    "still highly temp and doesn't work right"). It is not requied by any
    known (shipped) gnetlist backends.

diff --git a/gnetlist/src/g_netlist.c b/gnetlist/src/g_netlist.c
index f8ef142..21fe86c 100644
--- a/gnetlist/src/g_netlist.c
+++ b/gnetlist/src/g_netlist.c
@@ -727,26 +727,39 @@ SCM g_get_attribute_by_pinnumber(SCM scm_uref, SCM scm_pin, SCM
 /* still highly temp and doesn't work right */
 SCM g_get_toplevel_attribute(SCM scm_wanted_attrib)
 {
-    char *wanted_attrib;
-    char *return_value;
-    SCM scm_return_value;
+  const GList *p_iter;
+  PAGE *p_current;
+  char *wanted_attrib;
+  char *attrib_value = NULL;
+  SCM scm_return_value;
 
-    SCM_ASSERT(scm_is_string (scm_wanted_attrib),
-	       scm_wanted_attrib, SCM_ARG1, "gnetlist:get-toplevel-attribute");
+  SCM_ASSERT(scm_is_string (scm_wanted_attrib),
+             scm_wanted_attrib, SCM_ARG1, "gnetlist:get-toplevel-attribute");
 
-    wanted_attrib = SCM_STRING_CHARS (scm_wanted_attrib);
+  wanted_attrib = SCM_STRING_CHARS (scm_wanted_attrib);
 
-    return_value = o_attrib_search_toplevel_all(project_current->pages,
-						wanted_attrib);
+  for (p_iter = geda_list_get_glist (project_current->pages); p_iter != NULL;
+       p_iter = g_list_next (p_iter)) {
+    p_current = p_iter->data;
 
-    if (return_value) {
-      scm_return_value = scm_makfrom0str (return_value);
-      g_free(return_value);
-    } else {
-      scm_return_value = scm_makfrom0str ("not found");
-    }
+    /* only look for first occurrance of the attribute on each page */
+    attrib_value =
+      o_attrib_search_floating_attribs_by_name (s_page_objects (p_current),
+                                                wanted_attrib, 0);
 
-    return (scm_return_value);
+    /* Stop when we find the first one */
+    if (attrib_value != NULL)
+      break;
+  }
+
+  if (attrib_value != NULL) {
+    scm_return_value = scm_makfrom0str (attrib_value);
+    g_free (attrib_value);
+  } else {
+    scm_return_value = scm_makfrom0str ("not found");
+  }
+
+  return (scm_return_value);
 }
 
 #if 0	      /* No longer needed, but the netlist_mode variable is still used */
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 379d35f..6b133bb 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -118,7 +118,6 @@ char *o_attrib_search_slot(OBJECT *object, OBJECT **return_found);
 char *o_attrib_search_numslots(OBJECT *object);
 char *o_attrib_search_default_slot(OBJECT *object);
 void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object);
-char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name);
 GList *o_attrib_return_attribs(OBJECT *object);
 int o_attrib_is_inherited(OBJECT *attrib);
 
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index a1a934f..31a10e5 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1464,40 +1464,6 @@ void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object)
 }
 
 
-/*! \brief Search for first TOPLEVEL attribute.
- *  \par Function Description
- *  This function searches all loaded pages for the first
- *  TOPLEVEL attribute found.
- *  The caller is responsible for freeing the returned value.
- *
- *  \param [in] page_list  Page list to search through.
- *  \param [in] name       Character string name to search for.
- *  \return Character string from the found attribute, NULL otherwise.
- */
-char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name)
-{
-  const GList *iter;
-  PAGE *p_current;
-  char *ret_value=NULL;
-
-  iter = geda_list_get_glist( page_list );
-
-  while( iter != NULL ) {
-    p_current = (PAGE *)iter->data;
-
-    /* only look for first occurrance of the attribute */
-    ret_value = o_attrib_search_floating_attribs_by_name (s_page_objects (p_current), name, 0);
-
-    if (ret_value != NULL) {
-      return(ret_value);
-    }
-
-    iter = g_list_next( iter );
-  }
-
-  return(NULL);
-}
-
 /*! \brief Get all attached attributes of the specified OBJECT.
  *  \par Function Description
  *  This function returns all attributes of the specified object.

commit f505ad65da209bd8d7e766d495466b904643e9b7
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_complex_get_toplevel_attribs() in favour of newer attrib API
    
    o_attrib_find_floating_attribs() is functionally identical.

diff --git a/gschem/src/x_compselect.c b/gschem/src/x_compselect.c
index eb17b79..b596903 100644
--- a/gschem/src/x_compselect.c
+++ b/gschem/src/x_compselect.c
@@ -511,9 +511,8 @@ update_attributes_model (Compselect *compselect, TOPLEVEL *preview_toplevel)
     return;
   }
 
-  o_attrlist =
-    o_complex_get_toplevel_attribs (preview_toplevel,
-                                    s_page_objects (preview_toplevel->page_current));
+  o_attrlist = o_attrib_find_floating_attribs (
+                              s_page_objects (preview_toplevel->page_current));
 
   filter_list = GSCHEM_DIALOG (compselect)->w_current->component_select_attrlist;
 
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 71a8759..379d35f 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -173,7 +173,6 @@ int world_get_object_glist_bounds(TOPLEVEL *toplevel, const GList *o_list,
 			     int *left, int *top, 
 			     int *right, int *bottom);
 int o_complex_is_embedded(OBJECT *o_current);
-GList *o_complex_get_toplevel_attribs (TOPLEVEL *toplevel, const GList *obj_list);
 GList *o_complex_promote_attribs (TOPLEVEL *toplevel, OBJECT *object);
 OBJECT *o_complex_new(TOPLEVEL *toplevel, char type, int color, int x, int y, int angle, int mirror, const CLibSymbol *clib_sym, const gchar *basename, int selectable);
 OBJECT *o_complex_new_embedded(TOPLEVEL *toplevel, char type, int color, int x, int y, int angle, int mirror, const gchar *basename, int selectable);
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 5f49033..bd5bd10 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -256,39 +256,6 @@ int o_complex_is_embedded(OBJECT *o_current)
 }
 
 
-/*! \brief Get a list of all toplevel attributes of and object list
- *
- *  \par Function Description
- *  Returns a GList of all attribute OBJECTs
- *
- *  \param [in]  toplevel  The toplevel environment.
- *  \param [in]  obj_list  The object list to search for attributes
- *  \returns               A GList of attribute OBJECTs
- */
-GList *o_complex_get_toplevel_attribs (TOPLEVEL *toplevel,
-                                       const GList *obj_list)
-{
-  OBJECT *o_current;
-  GList *attr_list = NULL;
-  const GList *iter;
-
-  for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) {
-    o_current = iter->data;
-
-    if (o_current->type == OBJ_TEXT &&
-        o_current->attached_to == NULL &&
-        o_attrib_get_name_value (o_current->text->string, NULL, NULL)) {
-
-      attr_list = g_list_prepend (attr_list, o_current);
-    }
-  }
-
-  attr_list = g_list_reverse (attr_list);
-
-  return attr_list;
-}
-
-
 /*! \brief Get attributes eligible for promotion from inside a complex
  *
  *  \par Function Description
@@ -317,8 +284,7 @@ static GList *o_complex_get_promotable (TOPLEVEL *toplevel, OBJECT *object, int
   if (!toplevel->attribute_promotion) /* controlled through rc file */
     return NULL;
 
-  attribs = o_complex_get_toplevel_attribs (toplevel,
-                                            object->complex->prim_objs);
+  attribs = o_attrib_find_floating_attribs (object->complex->prim_objs);
 
   for (iter = attribs; iter != NULL; iter = g_list_next (iter)) {
     tmp = iter->data;

commit 88c205ea2ff69936aa5362a52d27471fbab87e6b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_attrib_search_toplevel() in favour of the newer API
    
    o_attrib_search_floating_attribs_by_name() is functionally identical

diff --git a/gsymcheck/src/s_check.c b/gsymcheck/src/s_check.c
index 1ba5052..c6fc509 100644
--- a/gsymcheck/src/s_check.c
+++ b/gsymcheck/src/s_check.c
@@ -548,7 +548,7 @@ s_check_pinnumber (const GList *obj_list, SYMCHECK *s_current)
     
   /* collect all net pins */
   for (counter = 0;
-       (net = o_attrib_search_toplevel (obj_list, "net", counter)) != NULL;
+       (net = o_attrib_search_floating_attribs_by_name (obj_list, "net", counter)) != NULL;
        counter++) {
     message = g_strdup_printf ("Found net=%s attribute\n", net);
     s_current->info_messages = g_list_append(s_current->info_messages,
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index efe7d6f..71a8759 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -112,7 +112,6 @@ char *o_attrib_search_string_partial(OBJECT *object, char *search_for, int count
 OBJECT *o_attrib_search_string_single(OBJECT *object, char *search_for);
 OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name, int counter);
 char *o_attrib_search_attrib_name(GList *list, char *name, int counter);
-char *o_attrib_search_toplevel(const GList *list, char *name, int counter);
 char *o_attrib_search_name_single(OBJECT *object, char *name, OBJECT **return_found);
 char *o_attrib_search_name_single_count(OBJECT *object, char *name, int counter);
 char *o_attrib_search_slot(OBJECT *object, OBJECT **return_found);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index f063f0c..a1a934f 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1030,69 +1030,6 @@ o_attrib_search_attrib_name(GList *list, char *name, int counter)
   return (NULL);
 } 
 
-/*! \brief Search TOPLEVEL attributes.
- *  \par Function Description
- *  This function should only be used to search for TOPLEVEL attributes.
- *  \warning
- *  The list is the top level list. Do not pass it an object_list list
- *  unless you know what you are doing.
- *  
- *  Counter is the n'th occurance of the attribute, and starts searching
- *  from zero.  Zero is the first occurance of an attribute.
- * 
- *  \param [in] list     The GList to search (TOPLEVEL only).
- *  \param [in] name     Character string of attribute name to search for.
- *  \param [in] counter  Which occurance to return.
- *  \return Character string with attribute value, NULL otherwise.
- *
- *  \warning
- *  Caller must g_free returned character string.
- */
-char *o_attrib_search_toplevel (const GList *list, char *name, int counter)
-{
-  OBJECT *o_current;
-  int val;
-  int internal_counter=0;
-  char *found_name = NULL;
-  char *found_value = NULL;
-  char *return_string = NULL;
-  const GList *iter;
-
-  iter = list;
-
-  while (iter != NULL) {
-    o_current = (OBJECT *)iter->data;
-
-    /* search for attributes outside */
-
-    if (o_current->type == OBJ_TEXT) {
-      val = o_attrib_get_name_value(o_current->text->string, 
-                                    &found_name, &found_value);
-      if (val) {
-        if (strcmp(name, found_name) == 0) {
-          if (counter != internal_counter) {
-            internal_counter++;	
-          } else {
-            return_string = g_strdup (found_value);
-	    g_free(found_name);
-	    g_free(found_value);
-            return(return_string);
-          }
-        }
-	if (found_name) { g_free(found_name); found_name = NULL; }
-	if (found_value) { g_free(found_value); found_value = NULL; }
-      }	
-    }
-
-    iter = g_list_next (iter);
-  }
-	
-  g_free(found_name);
-  g_free(found_value);
-  return (NULL);
-} 
-
-
 /*! \brief Search for first occurance of a named attribute.
  *  \par Function Description
  *  Search for first occurance of a named attribute.
@@ -1532,7 +1469,6 @@ void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object)
  *  This function searches all loaded pages for the first
  *  TOPLEVEL attribute found.
  *  The caller is responsible for freeing the returned value.
- *  See #o_attrib_search_toplevel() for other comments.
  *
  *  \param [in] page_list  Page list to search through.
  *  \param [in] name       Character string name to search for.
@@ -1550,7 +1486,7 @@ char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name)
     p_current = (PAGE *)iter->data;
 
     /* only look for first occurrance of the attribute */
-    ret_value = o_attrib_search_toplevel (s_page_objects (p_current), name, 0);
+    ret_value = o_attrib_search_floating_attribs_by_name (s_page_objects (p_current), name, 0);
 
     if (ret_value != NULL) {
       return(ret_value);

commit ca55a937a7f865e851e8352e7c80005b1d94f36f
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Remove o_attrib_search_component() in favour of the new API
    
    Calling o_attrib_search_object_attribs_by_name() with a count
    parameter of 0 is functionally identical.

diff --git a/gattrib/src/s_toplevel.c b/gattrib/src/s_toplevel.c
index 345b5cf..2843c12 100644
--- a/gattrib/src/s_toplevel.c
+++ b/gattrib/src/s_toplevel.c
@@ -425,7 +425,7 @@ s_toplevel_sheetdata_to_toplevel (PAGE *page)
     if (o_current->type == OBJ_COMPLEX) {    /* Note that OBJ_COMPLEX = component + attribs */
 
 #if 0
-      if ( o_attrib_search_component(o_current, "graphical") ) {
+      if (o_attrib_search_object_attribs_by_name (o_current, "graphical", 0)) {
         break;  /* Ignore graphical components */
       }
 #endif
diff --git a/gnetlist/src/s_traverse.c b/gnetlist/src/s_traverse.c
index 4613c82..f9faf0f 100644
--- a/gnetlist/src/s_traverse.c
+++ b/gnetlist/src/s_traverse.c
@@ -179,7 +179,7 @@ s_traverse_sheet (TOPLEVEL * pr_current, const GList *obj_list, char *hierarchy_
       verbose_print(" C");
 
       /* look for special tag */
-      temp = o_attrib_search_component(o_current, "graphical");
+      temp = o_attrib_search_object_attribs_by_name (o_current, "graphical", 0);
       if (temp) {
         /* traverse graphical elements, but adding them to the
 	   graphical netlist */
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 82e0440..efe7d6f 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -118,7 +118,6 @@ char *o_attrib_search_name_single_count(OBJECT *object, char *name, int counter)
 char *o_attrib_search_slot(OBJECT *object, OBJECT **return_found);
 char *o_attrib_search_numslots(OBJECT *object);
 char *o_attrib_search_default_slot(OBJECT *object);
-char *o_attrib_search_component(OBJECT *object, char *name);
 void o_attrib_slot_update(TOPLEVEL *toplevel, OBJECT *object);
 char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name);
 GList *o_attrib_return_attribs(OBJECT *object);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 5545690..f063f0c 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1409,43 +1409,6 @@ static char *o_attrib_search_slotdef(OBJECT *object, int slotnumber)
   return(NULL);
 }
 
-/*! \brief Search for component.
- *  \par Function Description
- *  Search for component.
- *
- *  \param [in] object  The OBJECT list to search.
- *  \param [in] name    Character string containing component name to match.
- *  \return Character string with the component value, NULL otherwise.
- */
-char *o_attrib_search_component(OBJECT *object, char *name)
-{
-  char *return_value = NULL;
-
-  if (!name) {
-    return(NULL);
-  }
-
-  if (object->type != OBJ_COMPLEX && object->type != OBJ_PLACEHOLDER) {
-    return(NULL);
-  }
-
-  /* first look inside the complex object */
-  return_value = o_attrib_search_name(object->complex->prim_objs, 
-                                      name, 0);
-
-  if (return_value) {
-    return(return_value);
-  }
-
-  /* now look outside to see if it was attached externally */
-  return_value = o_attrib_search_name_single(object, name, NULL);
-
-  if (return_value) {
-    return(return_value);
-  }
-
-  return(NULL);
-}
 
 /*! \brief Update all slot attributes in an object.
  *  \par Function Description

commit b1484835dce050c1bc67faf898622336a1f9cde3
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Introduce new attribute searching API
    
    This new API aims to be explicit as to the scope of its behaviour.
    Various of the existing APIs are very similarly named, yet will have
    subtly different behaviours when passed a list of OBJECTs, attribute
    OBJECTs, some general OBJECT, or an attribute OBJECT.
    
    Since the current APIs are confusing, the sensible course of action seems
    to be introducing a new simple API for searching a GList of attributes by
    name, then providing specialised wrappers which construct the appropriate
    list of attributes to search.
    
    To this end, inside libgeda/src/o_attrib.c, the following new functions
    are created:
    
    The generic search routine:
      static OBJECT *o_attrib_find_attrib_by_name ()
    
    A helper which returns the value of the found attribute:
      static char *o_attrib_search_attrib_list_by_name ()
    
    Exported API to search:
    
      floating attributes (on a page, or inside a symbol):
        char *o_attrib_search_floating_attribs_by_name ()
    
      Attributes attached to an OBJECT:
        char *o_attrib_search_attached_attribs_by_name ()
    
      Attributes inside an OBJECT (inherited):
        char *o_attrib_search_inherited_attribs_by_name ()
    
      Attributes from an object - either attached, or from inside the symbol:
      char *o_attrib_search_object_attribs_by_name ()
    
    
    The latter is in preparation to make more use of an aggregate attribute
    list for objects - rather than having each piece of code duplicate the
    logic to check both attached attributes, and those inside symbols.
    
    We also make o_attrib_find_floating_attribs() static, since it is
    only used inside o_attrib.c now.

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index db709b3..82e0440 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -102,6 +102,10 @@ void o_attrib_print(GList *attributes);
 void o_attrib_remove(GList **list, OBJECT *remove);
 gboolean o_attrib_get_name_value (const gchar *string, gchar **name_ptr, gchar **value_ptr);
 GList *o_attrib_find_floating_attribs (const GList *list);
+char *o_attrib_search_floating_attribs_by_name (const GList *list, char *name, int counter);
+char *o_attrib_search_attached_attribs_by_name (OBJECT *object, char *name, int counter);
+char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int counter);
+char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter);
 char *o_attrib_search_name(const GList *list, char *name, int counter);
 OBJECT *o_attrib_search_string_list(GList *list, char *string);
 char *o_attrib_search_string_partial(OBJECT *object, char *search_for, int counter);
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index e8ba4b5..5545690 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -461,6 +461,175 @@ GList *o_attrib_find_floating_attribs (const GList *list)
  *  \par Function Description
  *  Search for attribute by name.
  *
+ *  Counter is the n'th occurance of the attribute, and starts searching
+ *  from zero.  Zero is the first occurance of an attribute.
+ *
+ *  \param [in] list     GList of attributes to search.
+ *  \param [in] name     Character string with attribute name to search for.
+ *  \param [in] counter  Which occurance to return.
+ *  \return The n'th attribute object in the given list with the given name.
+ */
+static OBJECT *o_attrib_find_attrib_by_name (const GList *list, char *name, int count)
+{
+  OBJECT *a_current;
+  const GList *iter;
+  char *found_name;
+  int internal_counter = 0;
+
+  for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+    a_current = iter->data;
+
+    g_return_val_if_fail (a_current->type == OBJ_TEXT, NULL);
+
+    if (!o_attrib_get_name_value (a_current->text->string, &found_name, NULL))
+      continue;
+
+    if (strcmp (name, found_name) == 0) {
+      if (internal_counter == count) {
+        g_free (found_name);
+        return a_current;
+      }
+      internal_counter++;
+    }
+
+    g_free (found_name);
+  }
+
+  return NULL;
+}
+
+
+/*! \brief Search for attibute by name.
+ *  \par Function Description
+ *  Search for attribute by name.
+ *
+ *  Counter is the n'th occurance of the attribute, and starts searching
+ *  from zero.  Zero is the first occurance of an attribute.
+ *
+ *  \param [in] list     GList of attributes to search.
+ *  \param [in] name     Character string with attribute name to search for.
+ *  \param [in] counter  Which occurance to return.
+ *  \return The n'th attribute object in the given list with the given name.
+ */
+static char *o_attrib_search_attrib_list_by_name (const GList *list, char *name, int counter)
+{
+  OBJECT *attrib;
+  char *value = NULL;
+
+  attrib = o_attrib_find_attrib_by_name (list, name, counter);
+
+  if (attrib != NULL)
+    o_attrib_get_name_value (attrib->text->string, NULL, &value);
+
+  return value;
+}
+
+
+/*! \brief Search for attibute by name.
+ *  \par Function Description
+ *  Search for attribute by name.
+ *
+ *  Counter is the n'th occurance of the attribute, and starts searching
+ *  from zero.  Zero is the first occurance of an attribute.
+ *
+ *  \param [in] list     GList of OBJECTs to search for floating attributes.
+ *  \param [in] name     Character string with attribute name to search for.
+ *  \param [in] counter  Which occurance to return.
+ *  \return Character string with attribute value, NULL otherwise.
+ *
+ *  \warning
+ *  Caller must g_free returned character string.
+ */
+char *o_attrib_search_floating_attribs_by_name (const GList *list, char *name, int counter)
+{
+  char *result;
+  GList *attributes;
+
+  attributes = o_attrib_find_floating_attribs (list);
+  result = o_attrib_search_attrib_list_by_name (attributes, name, counter);
+  g_list_free (attributes);
+
+  return result;
+}
+
+
+/*! \brief Search for attibute by name.
+ *  \par Function Description
+ *  Search for attribute by name.
+ *
+ *  Counter is the n'th occurance of the attribute, and starts searching
+ *  from zero.  Zero is the first occurance of an attribute.
+ *
+ *  \param [in] object   The OBJECT whos attached attributes to search.
+ *  \param [in] name     Character string with attribute name to search for.
+ *  \param [in] counter  Which occurance to return.
+ *  \return Character string with attribute value, NULL otherwise.
+ *
+ *  \warning
+ *  Caller must g_free returned character string.
+ */
+char *o_attrib_search_attached_attribs_by_name (OBJECT *object, char *name, int counter)
+{
+  return o_attrib_search_attrib_list_by_name (object->attribs, name, counter);
+}
+
+
+/*! \brief Search for attibute by name.
+ *  \par Function Description
+ *  Search for attribute by name.
+ *
+ *  Counter is the n'th occurance of the attribute, and starts searching
+ *  from zero.  Zero is the first occurance of an attribute.
+ *
+ *  \param [in] object   The OBJECT whos inherited attributes to search.
+ *  \param [in] name     Character string with attribute name to search for.
+ *  \param [in] counter  Which occurance to return.
+ *  \return Character string with attribute value, NULL otherwise.
+ *
+ *  \warning
+ *  Caller must g_free returned character string.
+ */
+char *o_attrib_search_inherited_attribs_by_name (OBJECT *object, char *name, int counter)
+{
+  g_return_val_if_fail (object->type == OBJ_COMPLEX ||
+                        object->type == OBJ_PLACEHOLDER, NULL);
+
+  return o_attrib_search_floating_attribs_by_name (object->complex->prim_objs, name, counter);
+}
+
+
+/*! \brief Search for attibute by name.
+ *  \par Function Description
+ *  Search for attribute by name.
+ *
+ *  Counter is the n'th occurance of the attribute, and starts searching
+ *  from zero.  Zero is the first occurance of an attribute.
+ *
+ *  \param [in] list     OBJECT whos attributes to search.
+ *  \param [in] name     Character string with attribute name to search for.
+ *  \param [in] counter  Which occurance to return.
+ *  \return Character string with attribute value, NULL otherwise.
+ *
+ *  \warning
+ *  Caller must g_free returned character string.
+ */
+char *o_attrib_search_object_attribs_by_name (OBJECT *object, char *name, int counter)
+{
+  char *result;
+  GList *attributes;
+
+  attributes = o_attrib_return_attribs (object);
+  result = o_attrib_search_attrib_list_by_name (attributes, name, counter);
+  g_list_free (attributes);
+
+  return result;
+}
+
+
+/*! \brief Search for attibute by name.
+ *  \par Function Description
+ *  Search for attribute by name.
+ *
  *  \warning
  *  The list is the top level list. Do not pass it an object_list list
  *  unless you know what you are doing.

commit 02fde480e0d58300d9e7ee1cf0357fb96d14adbb
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Add inherited attributes to the list returned by o_attrib_return_attribs()
    
    This starts to allow a common place where attributes from the symbol will
    be combined with attached attributes to form an aggregate attribute list.
    
    Currently, various pieces of code which deal with reading attributes will
    check the attached attributes of a symbol, then the inherited attributes
    explicitly. For cases where a simple combining rule exists, we can reduce
    such checks to a single lookup of the aggregate list.
    
    Atttributes such as "net=" and "source=" which often exist multiple times,
    possibly both as inherited and attahched attributes, present difficulties
    though.
    
    For now, just pile all inherited attributes at the end of the returned
    list. This means any code which wants to check for the first attribtue
    with a given name should do the "right thing", with attached attributes
    taking presidence over inherited ones.

diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 4fde1ac..23aa994 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -2132,6 +2132,9 @@ void multiattrib_update (Multiattrib *multiattrib)
   if (!sensitive)
     return;
 
+  show_inherited =
+    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiattrib->show_inherited));
+
   /* get list of attributes */
   object_attribs = o_attrib_return_attribs (multiattrib->object);
   /* populate the store with attributes */
@@ -2139,6 +2142,10 @@ void multiattrib_update (Multiattrib *multiattrib)
        a_iter = g_list_next (a_iter)) {
     a_current = a_iter->data;
 
+    /* Skip over inherited attributes if we don't want to show them */
+    if (!show_inherited && o_attrib_is_inherited (a_current))
+      continue;
+
     gtk_list_store_append (liststore, &iter);
     gtk_list_store_set (liststore, &iter,
                         COLUMN_ATTRIBUTE, a_current,
@@ -2146,26 +2153,4 @@ void multiattrib_update (Multiattrib *multiattrib)
   }
   /* delete the list of attribute objects */
   g_list_free (object_attribs);
-
-  show_inherited =
-    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multiattrib->show_inherited));
-
-  /* get list of inherited attributes from inside the symbol */
-  if (show_inherited && (multiattrib->object->type == OBJ_COMPLEX ||
-                         multiattrib->object->type == OBJ_PLACEHOLDER)) {
-    object_attribs =
-      o_attrib_find_floating_attribs (multiattrib->object->complex->prim_objs);
-
-    for (a_iter = object_attribs; a_iter != NULL;
-         a_iter = g_list_next (a_iter)) {
-      a_current = a_iter->data;
-
-      gtk_list_store_append (liststore, &iter);
-      gtk_list_store_set (liststore, &iter,
-                          COLUMN_ATTRIBUTE, a_current,
-                          -1);
-    }
-    g_list_free (object_attribs);
-  }
-
 }
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index 3dea009..e8ba4b5 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -1432,13 +1432,14 @@ char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name)
 
 /*! \brief Get all attached attributes of the specified OBJECT.
  *  \par Function Description
- *  This function returns all attached attributes of the specified object.
+ *  This function returns all attributes of the specified object.
  *
  *  The returned GList should be freed using the #g_list_free().
  *
- *  This function does not look for inherited attributes. (Inherited
- *  attributes are those which live as toplevel un-attached attributes
- *  inside in a complex OBJECT's prim_objs).
+ *  This function aggregates the attached and inherited attributes
+ *  belonging to a given OBJECT. (inherited attributes are those
+ *  which live as toplevel un-attached attributes inside in a
+ *  complex OBJECT's prim_objs).
  *
  *  \param [in] object       OBJECT whos attributes to return.
  *  \return A GList of attributes belinging to the passed object.
@@ -1446,6 +1447,7 @@ char *o_attrib_search_toplevel_all(GedaPageList *page_list, char *name)
 GList * o_attrib_return_attribs (OBJECT *object)
 {
   GList *attribs = NULL;
+  GList *inherited_attribs;
   OBJECT *a_current;
   GList *a_iter;
 
@@ -1464,10 +1466,20 @@ GList * o_attrib_return_attribs (OBJECT *object)
       continue;
 
     attribs = g_list_prepend (attribs, a_current);
-
   }
 
   attribs = g_list_reverse (attribs);
+
+  /* Inherited attributes (inside complex objects) */
+  if (object->type == OBJ_COMPLEX ||
+      object->type == OBJ_PLACEHOLDER) {
+
+    inherited_attribs =
+      o_attrib_find_floating_attribs (object->complex->prim_objs);
+
+    attribs = g_list_concat (attribs, inherited_attribs);
+  }
+
   return attribs;
 }
 

commit 5920b9ac846a1d0da2d76a3d72887489e7a93316
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Improve doxygen comments for o_attrib_find_floating_attribs()

diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index ff1f411..3dea009 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -427,7 +427,7 @@ o_attrib_get_name_value (const gchar *string, gchar **name_ptr, gchar **value_pt
  *  \par Function Description
  *  Find all floating attributes in the given object list.
  *
- *  \param [in] list     GList of OBJECTs to search.
+ *  \param [in] list  GList of OBJECTs to search for floating attributes.
  *  \return GList of floating attributes from the input list
  *
  *  \warning




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs