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

gEDA-cvs: branch: master updated (rel_20070526-44-g1f1c7f4)



The branch, master has been updated
       via  1f1c7f4d9ab541454d39a4ec770f6e9bdd9bfa16 (commit)
       via  67038ed9bece3a1317757b58a982ed29af2831c6 (commit)
       via  1c226a4ebe5f297460cccf8568b7d7b7b2179253 (commit)
       via  fe621022acfbe69688878b70d4c40883f8f2a3df (commit)
       via  01fd87d78aa26d3c29b4141878b5f48edab264ec (commit)
      from  9dde0233ebed32065511b567445f9f34d4b3bea1 (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.


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

commit 1f1c7f4d9ab541454d39a4ec770f6e9bdd9bfa16
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Jun 23 14:01:30 2007 +0100

    Re-enable s_clib_refresh().
    
    Now that OBJECT and TOPLEVEL no longer store pointers to CLibSymbol
    structures, calling s_clib_refresh() is no longer likely to cause a
    segfault.

:100644 100644 fcea2d4... cca50dd... M	libgeda/src/s_clib.c

commit 67038ed9bece3a1317757b58a982ed29af2831c6
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Jun 23 13:50:57 2007 +0100

    Don't cache symbol pointers in persistent structures.
    
    Several persistent structures, including TOPLEVEL and OBJECT, cache
    pointers to CLibSymbols.  This is bad, because it makes removing
    component sources or rescanning them likely to cause stale pointers
    around the place.
    
    With fast hashtable-cached searches in place, this is no longer
    necessary.  This patch ensures that only symbol names are stored
    persistently.
    
    This patch also enables descending into embedded symbols using a
    component library lookup on the embedded symbol's name.

:100644 100644 9feb6fb... d9254e1... M	gschem/src/i_callbacks.c
:100644 100644 edb52a1... 022054e... M	gschem/src/o_complex.c
:100644 100644 bc3793b... ee8ca2b... M	gschem/src/o_misc.c
:100644 100644 3510bc7... 9dfa13f... M	gschem/src/x_compselect.c
:100644 100644 1b74f7c... e2d99f7... M	gschem/src/x_window.c
:100644 100644 641b8b2... de198fd... M	libgeda/include/prototype.h
:100644 100644 63070d0... dcf2cd9... M	libgeda/include/struct.h
:100644 100644 914c506... 8ee54a7... M	libgeda/src/o_complex_basic.c
:100644 100644 74cae6a... 24608f2... M	libgeda/src/o_embed.c
:100644 100644 0aa28d7... 5dfcc7c... M	libgeda/src/s_basic.c
:100644 100644 daa414f... 78915ce... M	libgeda/src/s_toplevel.c

commit 1c226a4ebe5f297460cccf8568b7d7b7b2179253
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Jun 23 13:32:45 2007 +0100

    Factor out TOPLEVEL.current_clib.

:100644 100644 bfce626... 3510bc7... M	gschem/src/x_compselect.c
:100644 100644 2d4188e... 63070d0... M	libgeda/include/struct.h
:100644 100644 889ea0b... daa414f... M	libgeda/src/s_toplevel.c

commit fe621022acfbe69688878b70d4c40883f8f2a3df
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Jun 22 08:34:33 2007 +0100

    Add s_clib_get_symbol_by_name().
    
    Add a new function which returns the first exact match for a given
    symbol name, printing log messages if either there are more than one
    match or no matches are found at all.  Also update
    s_clib_symbol_get_data_by_name() to use new function and remove
    o_complex_add_by_name() as more or less redundant.

:100644 100644 a4497eb... 5005eaa... M	gschem/src/g_hook.c
:100644 100644 37faab2... 641b8b2... M	libgeda/include/prototype.h
:100644 100644 7948348... 914c506... M	libgeda/src/o_complex_basic.c
:100644 100644 088ac1a... fcea2d4... M	libgeda/src/s_clib.c

commit 01fd87d78aa26d3c29b4141878b5f48edab264ec
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Jun 15 09:05:53 2007 +0100

    Make comp. library search faster and more flexible
    
    Replace s_clib_glob() with s_clib_search(), which can operate in
    either exact matching or glob matching mode.  Use a hashtable to cache
    the results of library searches. The hashtable is cleared every time
    it is invalidated (for instance if a component source is added or
    removed, or the component sources are rescanned).

:100644 100644 f870629... bc3793b... M	gschem/src/o_misc.c
:100644 100644 7db67b2... 182a840... M	gschem/src/o_net.c
:100644 100644 14f7ba6... 37faab2... M	libgeda/include/prototype.h
:100644 100644 e75b6ab... 2d4188e... M	libgeda/include/struct.h
:100644 100644 065b59e... 7948348... M	libgeda/src/o_complex_basic.c
:100644 100644 b635900... 74cae6a... M	libgeda/src/o_embed.c
:100644 100644 c05792e... 088ac1a... M	libgeda/src/s_clib.c

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

commit 1f1c7f4d9ab541454d39a4ec770f6e9bdd9bfa16
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Jun 23 14:01:30 2007 +0100

    Re-enable s_clib_refresh().
    
    Now that OBJECT and TOPLEVEL no longer store pointers to CLibSymbol
    structures, calling s_clib_refresh() is no longer likely to cause a
    segfault.

diff --git a/libgeda/src/s_clib.c b/libgeda/src/s_clib.c
index fcea2d4..cca50dd 100644
--- a/libgeda/src/s_clib.c
+++ b/libgeda/src/s_clib.c
@@ -688,7 +688,6 @@ static void refresh_scm (CLibSource *source)
  */
 void s_clib_refresh ()
 {
-#if 0
   GList *sourcelist;
   CLibSource *source;
 
@@ -712,7 +711,6 @@ void s_clib_refresh ()
 	g_assert_not_reached();
       }
   }
-#endif
 }
 
 /*! \brief Get a named component source.

commit 67038ed9bece3a1317757b58a982ed29af2831c6
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Jun 23 13:50:57 2007 +0100

    Don't cache symbol pointers in persistent structures.
    
    Several persistent structures, including TOPLEVEL and OBJECT, cache
    pointers to CLibSymbols.  This is bad, because it makes removing
    component sources or rescanning them likely to cause stale pointers
    around the place.
    
    With fast hashtable-cached searches in place, this is no longer
    necessary.  This patch ensures that only symbol names are stored
    persistently.
    
    This patch also enables descending into embedded symbols using a
    component library lookup on the embedded symbol's name.

diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 9feb6fb..d9254e1 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2829,8 +2829,7 @@ DEFINE_I_CALLBACK(hierarchy_down_schematic)
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
- *  \todo Allow hierarchy descent into embedded components (using a
- *  component library lookup)
+ *  \bug may cause problems with non-directory symbols
  */
 DEFINE_I_CALLBACK(hierarchy_down_symbol)
 {
@@ -2843,11 +2842,10 @@ DEFINE_I_CALLBACK(hierarchy_down_symbol)
   object = o_select_return_first_object(w_current);
   if (object != NULL) {
     /* only allow going into symbols */
-    if (object->type == OBJ_COMPLEX &&
-        !o_complex_is_embedded (object)) {
-      sym = object->complex_clib;
+    if (object->type == OBJ_COMPLEX) {
       s_log_message(_("Searching for symbol [%s]\n"), 
-		    s_clib_symbol_get_name(sym));
+		    object->complex_basename);
+      sym = s_clib_get_symbol_by_name (object->complex_basename);
       s_hierarchy_down_symbol(w_current, sym, 
 			      w_current->page_current);
       /* s_hierarchy_down_symbol() will not zoom the loaded page */
@@ -2891,6 +2889,7 @@ DEFINE_I_CALLBACK(hierarchy_documentation)
   char *attrib_value = NULL;
   OBJECT *object = NULL;
   const gchar *sourcename = NULL;
+  const CLibSymbol *sym = NULL;
 
   exit_if_null(w_current);
 
@@ -2915,7 +2914,11 @@ DEFINE_I_CALLBACK(hierarchy_documentation)
         attrib_value = o_attrib_search_name(object->complex->prim_objs, "value", 0);
       }
       
-      sourcename = s_clib_source_get_name (s_clib_symbol_get_source(object->complex_clib));
+      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));
+      }
+
       initiate_gschemdoc(attrib_doc,
                          attrib_device,
                          attrib_value,
diff --git a/gschem/src/o_complex.c b/gschem/src/o_complex.c
index edb52a1..022054e 100644
--- a/gschem/src/o_complex.c
+++ b/gschem/src/o_complex.c
@@ -127,6 +127,7 @@ void o_complex_start(TOPLEVEL *w_current, int screen_x, int screen_y)
 {
   int x, y;
   int i, temp;
+  const CLibSymbol *sym;
 
   w_current->last_x = w_current->start_x = fix_x(w_current, screen_x);
   w_current->last_y = w_current->start_y = fix_y(w_current, screen_y);
@@ -143,11 +144,11 @@ void o_complex_start(TOPLEVEL *w_current, int screen_x, int screen_y)
 
   w_current->DONT_DRAW_CONN = 1;
   w_current->ADDING_SEL = 1; /* reuse this flag, rename later hack */
+  sym = s_clib_get_symbol_by_name (w_current->internal_symbol_name);
   o_complex_add(w_current, NULL,
 		&(w_current->page_current->complex_place_list),
 		OBJ_COMPLEX, WHITE, x, y, 0, 0,
-		w_current->internal_clib,
-		s_clib_symbol_get_name (w_current->internal_clib), 
+		sym, w_current->internal_symbol_name,
 		1, TRUE);
   w_current->ADDING_SEL = 0;
   w_current->DONT_DRAW_CONN = 0;
@@ -264,6 +265,7 @@ void o_complex_end(TOPLEVEL *w_current, int screen_x, int screen_y)
   char *buffer;
   int temp, new_angle, i;
   GList *connected_objects=NULL;
+  const CLibSymbol *sym;
 
   diff_x = w_current->last_x - w_current->start_x;
   diff_y = w_current->last_y - w_current->start_y;
@@ -278,7 +280,7 @@ void o_complex_end(TOPLEVEL *w_current, int screen_x, int screen_y)
 #endif
 
   if (w_current->include_complex) {
-    buffer = s_clib_symbol_get_data (w_current->internal_clib);
+    buffer = s_clib_symbol_get_data_by_name (w_current->internal_symbol_name);
 
     w_current->ADDING_SEL=1;
     o_start = w_current->page_current->object_tail;
@@ -286,7 +288,7 @@ void o_complex_end(TOPLEVEL *w_current, int screen_x, int screen_y)
       o_read_buffer(w_current,
 		    w_current->page_current->object_tail,
 		    buffer, -1,
-		    s_clib_symbol_get_name(w_current->internal_clib));
+		    w_current->internal_symbol_name);
     o_start = o_start->next;
     w_current->ADDING_SEL=0;
     
@@ -352,12 +354,12 @@ void o_complex_end(TOPLEVEL *w_current, int screen_x, int screen_y)
   }
 
   o_temp = w_current->page_current->object_tail;
+  sym = s_clib_get_symbol_by_name (w_current->internal_symbol_name);
   w_current->page_current->object_tail =
     o_complex_add(w_current,
                   w_current->page_current->object_tail, NULL,
                   OBJ_COMPLEX, WHITE, x, y, w_current->complex_rotate, 0,
-                  w_current->internal_clib,
-                  s_clib_symbol_get_name (w_current->internal_clib), 
+                  sym, w_current->internal_symbol_name,
 		  1, TRUE);
 
   /* complex rotate post processing */
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index bc3793b..ee8ca2b 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -1063,31 +1063,15 @@ void o_update_component(TOPLEVEL *w_current, OBJECT *o_current)
 
   is_embedded = o_complex_is_embedded (o_current);
 
-  /* find symbol if not known */
-  if (o_current->complex_clib == NULL) {
-    const GList *symlist = NULL;
-    
-    g_assert (o_current->complex_basename != NULL);
-    symlist = s_clib_search (o_current->complex_basename, CLIB_EXACT);
-
-    if (symlist == NULL) {
-      s_log_message (_("Could not find symbol [%s] in library. Update failed.\n"), 
-		     o_current->complex_basename);
-      return;
-    } else {
-      if (g_list_next (symlist) != NULL) {
-	s_log_message (_("More than one component found with name [%s]\n"),
-		       o_current->complex_basename);
-      /* PB: for now, use the first directory in clibs */
-      /* PB: maybe open a dialog to select the right one? */
-      }
-    }
+  g_assert (o_current->complex_basename != NULL);
+  clib = s_clib_get_symbol_by_name (o_current->complex_basename);
 
-    o_current->complex_clib = (CLibSymbol *) symlist->data;
+  if (clib == NULL) {
+    s_log_message (_("Could not find symbol [%s] in library. Update failed.\n"), 
+                   o_current->complex_basename);
+    return;
   }
 
-  clib = o_current->complex_clib;
-
   /* erase the complex object */
   o_erase_single (w_current, o_current);
   /* delete its connections */
diff --git a/gschem/src/x_compselect.c b/gschem/src/x_compselect.c
index 3510bc7..9dfa13f 100644
--- a/gschem/src/x_compselect.c
+++ b/gschem/src/x_compselect.c
@@ -126,7 +126,7 @@ x_compselect_callback_response (GtkDialog *dialog,
 	g_list_free(toplevel->page_current->complex_place_list);
 	toplevel->page_current->complex_place_list = NULL;
 	
-	o_complex_set_filename(toplevel, symbol, NULL);
+	o_complex_set_filename(toplevel, s_clib_symbol_get_name (symbol));
         
 	toplevel->event_state = DRAWCOMP;
 
diff --git a/gschem/src/x_window.c b/gschem/src/x_window.c
index 1b74f7c..e2d99f7 100644
--- a/gschem/src/x_window.c
+++ b/gschem/src/x_window.c
@@ -63,7 +63,7 @@ void x_window_setup (TOPLEVEL *toplevel)
   toplevel->current_visible = -1; /* not sure on these */
   toplevel->current_show = -1;
 
-  toplevel->internal_clib=NULL;
+  toplevel->internal_symbol_name = NULL;
 
   toplevel->series_name = NULL;
   toplevel->untitled_name = NULL;
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 641b8b2..de198fd 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -297,7 +297,7 @@ OBJECT *o_complex_add_embedded(TOPLEVEL *w_current, OBJECT *object_list, char ty
 void o_complex_recalc(TOPLEVEL *w_current, OBJECT *o_current);
 OBJECT *o_complex_read(TOPLEVEL *w_current, OBJECT *object_list, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
 char *o_complex_save(OBJECT *object);
-void o_complex_set_filename(TOPLEVEL *w_current, const CLibSymbol *clib, char *basename);
+void o_complex_set_filename(TOPLEVEL *w_current, const char *basename);
 void o_complex_free_filename(TOPLEVEL *w_current);
 void o_complex_world_translate(TOPLEVEL *w_current, int x1, int y1, OBJECT *prim_objs);
 void o_complex_world_translate_toplevel(TOPLEVEL *w_current, int x1, int y1, OBJECT *object);
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 63070d0..dcf2cd9 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -217,7 +217,6 @@ struct st_object {
 
   gboolean complex_embedded;                    /* is embedded component? */
   gchar *complex_basename;              /* Component Library Symbol name */
-  const CLibSymbol *complex_clib;	/* Component Library Symbol */
   OBJECT *complex_parent;		/* Complex parent object pointer */
   /* used only in complex head nodes */
 
@@ -424,7 +423,7 @@ struct st_toplevel {
   /* if it should go in here or not */
   /* leave outside for now */
 
-  const CLibSymbol *internal_clib;     
+  gchar *internal_symbol_name;     
   /* have to decided on component list stuff */
   /* if it should go in here or not */
   /* leave outside for now */
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 914c506..8ee54a7 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -349,7 +349,6 @@ OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list,
   new_node = s_basic_init_object("complex");
   new_node->type = type;
 
-  new_node->complex_clib = clib;
   if (clib != NULL) {
     new_node->complex_basename = g_strdup (s_clib_symbol_get_name (clib));
   } else {
@@ -641,7 +640,6 @@ OBJECT *o_complex_add_embedded(TOPLEVEL *w_current, OBJECT *object_list,
   new_node->complex->angle = angle;
   new_node->complex->mirror = 0;
 	
-  new_node->complex_clib = NULL;
   new_node->complex_basename = g_strdup(basename);
 
   new_node->complex_embedded = TRUE;
@@ -810,14 +808,11 @@ char *o_complex_save(OBJECT *object)
  *  \par Function Description
  *
  */
-void o_complex_set_filename(TOPLEVEL *w_current, const CLibSymbol *clib, char *basename) 
+void o_complex_set_filename(TOPLEVEL *w_current, const char *basename) 
 {
-  if (clib == NULL) {
-    fprintf(stderr, "Got NULL clib in o_complex_set_filename!\n");
-    exit(-1);
-  }
+  o_complex_free_filename (w_current);
 
-  w_current->internal_clib = clib;
+  w_current->internal_symbol_name = g_strdup (basename);
 } 
 
 /*! \brief
@@ -826,7 +821,10 @@ void o_complex_set_filename(TOPLEVEL *w_current, const CLibSymbol *clib, char *b
  */
 void o_complex_free_filename(TOPLEVEL *w_current)
 {
-
+  if (w_current->internal_symbol_name != NULL) {
+    g_free(w_current->internal_symbol_name);
+    w_current->internal_symbol_name = NULL;
+  }
 }
 
 /*! \brief
@@ -948,6 +946,7 @@ OBJECT *o_complex_copy(TOPLEVEL *w_current, OBJECT *list_tail,
   ATTRIB *a_current;
   int color;
   int selectable;
+  const CLibSymbol *clib = NULL;
 
   g_return_val_if_fail(o_current != NULL, NULL);
 
@@ -963,11 +962,13 @@ OBJECT *o_complex_copy(TOPLEVEL *w_current, OBJECT *list_tail,
     selectable = FALSE;	
   }
 
+  clib = s_clib_get_symbol_by_name (o_current->complex_basename);
+
   new_obj = o_complex_add(w_current, list_tail, NULL, o_current->type, color,
                           o_current->complex->x, o_current->complex->y, 
                           o_current->complex->angle, 
 			  o_current->complex->mirror,
-                          o_current->complex_clib, o_current->complex_basename, 
+                          clib, o_current->complex_basename, 
                           selectable, FALSE); 
 
   o_attrib_slot_copy(w_current, o_current, new_obj);
diff --git a/libgeda/src/o_embed.c b/libgeda/src/o_embed.c
index 74cae6a..24608f2 100644
--- a/libgeda/src/o_embed.c
+++ b/libgeda/src/o_embed.c
@@ -88,7 +88,7 @@ void o_embed(TOPLEVEL *w_current, OBJECT *o_current)
  */
 void o_unembed(TOPLEVEL *w_current, OBJECT *o_current)
 {
-  GList *symlist;
+  const CLibSymbol *sym;
   
   /* check o_current is an embedded complex */
   if (o_current->type == OBJ_COMPLEX &&
@@ -96,24 +96,14 @@ void o_unembed(TOPLEVEL *w_current, OBJECT *o_current)
   {
         
     /* search for the symbol in the library */
-    symlist = s_clib_search (o_current->complex_basename, CLIB_EXACT);
+    sym = s_clib_get_symbol_by_name (o_current->complex_basename);
 
-    if (!symlist) {
+    if (sym == NULL) {
       /* symbol not found in the symbol library: signal an error */
       s_log_message ("Could not find component [%s], while trying to unembed. Component is still embedded\n",
                      o_current->complex_basename);
       
     } else {
-
-      /* set the object new clib */
-      if (g_list_next (symlist)) {
-        s_log_message ("More than one component found with name [%s]\n",
-                       o_current->complex_basename);
-        /* PB: for now, use the first directory in clibs */
-        /* PB: maybe open a dialog to select the right one? */
-      }
-      o_current->complex_clib = (CLibSymbol *) symlist->data;
-
       /* clear the embedded flag */
       o_current->complex_embedded = FALSE;
 
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 0aa28d7..5dfcc7c 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -190,7 +190,6 @@ OBJECT *s_basic_init_object( char *name )
   new_node->visited = 0;
 	
   new_node->complex_basename = NULL;
-  new_node->complex_clib = NULL;
   new_node->complex_parent = NULL;
 		
   /* Setup the color */
@@ -454,8 +453,6 @@ s_delete_object(TOPLEVEL *w_current, OBJECT *o_current)
     }
     o_current->complex_basename = NULL;
 
-    o_current->complex_clib = NULL;
-
     if (o_current->complex) {
 
       if (o_current->complex->prim_objs) {
diff --git a/libgeda/src/s_toplevel.c b/libgeda/src/s_toplevel.c
index daa414f..78915ce 100644
--- a/libgeda/src/s_toplevel.c
+++ b/libgeda/src/s_toplevel.c
@@ -93,7 +93,7 @@ TOPLEVEL *s_toplevel_new (void)
   toplevel->current_visible = -1; /* not sure on these */
   toplevel->current_show    = -1;
 
-  toplevel->internal_clib = NULL;
+  toplevel->internal_symbol_name = NULL;
   
   toplevel->RC_list = NULL;
 
@@ -209,7 +209,6 @@ TOPLEVEL *s_toplevel_new (void)
   toplevel->cswindow      = NULL;
   toplevel->clib_list     = NULL;
   toplevel->basename_list = NULL;
-/*   toplevel->current_basename 	 */
 
 /*   toplevel->fileselect */
 
@@ -478,6 +477,8 @@ void s_toplevel_delete (TOPLEVEL *toplevel)
     return;
   }
 
+  g_free (toplevel->internal_symbol_name);
+
   g_free (toplevel->series_name);
   g_free (toplevel->untitled_name);
   g_free (toplevel->font_directory);

commit 1c226a4ebe5f297460cccf8568b7d7b7b2179253
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Sat Jun 23 13:32:45 2007 +0100

    Factor out TOPLEVEL.current_clib.

diff --git a/gschem/src/x_compselect.c b/gschem/src/x_compselect.c
index bfce626..3510bc7 100644
--- a/gschem/src/x_compselect.c
+++ b/gschem/src/x_compselect.c
@@ -112,8 +112,6 @@ x_compselect_callback_response (GtkDialog *dialog,
           break;
         }
                 
-	toplevel->current_clib = symbol;
-        
 	if (toplevel->event_state == ENDCOMP) {
           gint diff_x, diff_y;
 
@@ -128,7 +126,7 @@ x_compselect_callback_response (GtkDialog *dialog,
 	g_list_free(toplevel->page_current->complex_place_list);
 	toplevel->page_current->complex_place_list = NULL;
 	
-	o_complex_set_filename(toplevel, toplevel->current_clib, NULL);
+	o_complex_set_filename(toplevel, symbol, NULL);
         
 	toplevel->event_state = DRAWCOMP;
 
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 2d4188e..63070d0 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -553,7 +553,6 @@ struct st_toplevel {
   GtkWidget *cswindow;			/* component select */
   GtkWidget *clib_list;
   GtkWidget *basename_list;
-  CLibSymbol *current_clib;
 
   GtkWidget *iwindow;			/* image write dialog box */
   GtkWidget *ifilename_entry; 
diff --git a/libgeda/src/s_toplevel.c b/libgeda/src/s_toplevel.c
index 889ea0b..daa414f 100644
--- a/libgeda/src/s_toplevel.c
+++ b/libgeda/src/s_toplevel.c
@@ -209,7 +209,6 @@ TOPLEVEL *s_toplevel_new (void)
   toplevel->cswindow      = NULL;
   toplevel->clib_list     = NULL;
   toplevel->basename_list = NULL;
-  toplevel->current_clib = NULL;
 /*   toplevel->current_basename 	 */
 
 /*   toplevel->fileselect */

commit fe621022acfbe69688878b70d4c40883f8f2a3df
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Jun 22 08:34:33 2007 +0100

    Add s_clib_get_symbol_by_name().
    
    Add a new function which returns the first exact match for a given
    symbol name, printing log messages if either there are more than one
    match or no matches are found at all.  Also update
    s_clib_symbol_get_data_by_name() to use new function and remove
    o_complex_add_by_name() as more or less redundant.

diff --git a/gschem/src/g_hook.c b/gschem/src/g_hook.c
index a4497eb..5005eaa 100644
--- a/gschem/src/g_hook.c
+++ b/gschem/src/g_hook.c
@@ -672,6 +672,7 @@ SCM g_add_component(SCM page_smob, SCM scm_comp_name, SCM scm_x, SCM scm_y,
   gchar *comp_name;
   int x, y, angle;
   OBJECT *new_object;
+  const CLibSymbol *clib;
 
   /* Return if scm_comp_name is NULL (an empty list) or scheme's FALSE */
   if (SCM_NULLP(scm_comp_name) || 
@@ -711,16 +712,18 @@ SCM g_add_component(SCM page_smob, SCM scm_comp_name, SCM scm_x, SCM scm_y,
     return SCM_BOOL_F;
   }
 
+  clib = s_clib_get_symbol_by_name (comp_name);
+
   new_object 
     = page->object_tail 
-    = o_complex_add_by_name(w_current, 
-			    page->object_tail, NULL, 
-			    'C', 
-			    WHITE, 
-			    x, y, 
-			    angle, mirror,
-			    comp_name, 
-			    selectable, FALSE);
+    = o_complex_add(w_current, 
+                    page->object_tail, NULL, 
+                    'C', 
+                    WHITE, 
+                    x, y, 
+                    angle, mirror,
+                    clib, comp_name, 
+                    selectable, FALSE);
   
   /* 
    * For now, do not redraw the newly added complex, since this might cause
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 37faab2..641b8b2 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -288,12 +288,6 @@ void world_get_complex_bounds(TOPLEVEL *w_current, OBJECT *complex, int *left, i
 OBJECT *add_head(void);
 int o_complex_is_eligible_attribute(TOPLEVEL *w_current, OBJECT *object, int promote_invisible);
 int o_complex_is_embedded(OBJECT *o_current);
-OBJECT *o_complex_add_by_name(TOPLEVEL *w_current, OBJECT *object_list, 
-			      GList **object_glist, char type,
-			      int color, int x, int y, int angle,
-			      int mirror, const gchar *basename,
-			      int selectable,
-			      int attribute_promotion);
 OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, 
 		      GList **object_glist, char type, int color, 
 		      int x, int y, int angle, int mirror, 
@@ -516,6 +510,7 @@ const CLibSource *s_clib_symbol_get_source (const CLibSymbol *symbol);
 gchar *s_clib_symbol_get_data (const CLibSymbol *symbol);
 GList *s_clib_search (const gchar *pattern, const CLibSearchMode mode);
 void s_clib_flush_cache ();
+const CLibSymbol *s_clib_get_symbol_by_name (const gchar *name);
 gchar *s_clib_symbol_get_data_by_name (const gchar *name);
 
 /* s_color.c */
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 7948348..914c506 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -316,46 +316,6 @@ int o_complex_is_embedded(OBJECT *o_current)
 
 }
 
-/*! \brief Add a symbol given its basename.
- *  \todo Complete function documentation
- */
-OBJECT *o_complex_add_by_name(TOPLEVEL *w_current, OBJECT *object_list, 
-			      GList **object_glist, char type,
-			      int color, int x, int y, int angle,
-			      int mirror, const gchar *basename,
-			      int selectable,
-			      int attribute_promotion)
-{
-  const CLibSymbol *sym;
-  GList *symlist;
-
-  symlist = s_clib_search (basename, CLIB_EXACT);
-
-  if (symlist == NULL) {
-    s_log_message("Component [%s] was not found in any component library\n", 
-		  basename);
-    fprintf(stderr,
-	    "Component [%s] was not found in any component library\n", 
-	    basename);
-    sym = NULL;
-  } else {
-    if (g_list_next (symlist) != NULL) {
-      s_log_message ("More than one component found with name [%s]\n",
-		     basename);
-    }
-    /*! \todo For now, use the first source with a symbol with that
-     *  name. Maybe open a dialog to select the right one? */
-    sym = (CLibSymbol *) symlist->data;
-  }
-
-  g_list_free (symlist);
-
-  return o_complex_add (w_current, object_list, object_glist, type,
-			color, x, y, angle, mirror, sym, basename,
-			selectable, attribute_promotion);
-
-}
-
 /* Done */
 /*! \brief
  *  \par Function Description
@@ -790,11 +750,13 @@ OBJECT *o_complex_read(TOPLEVEL *w_current, OBJECT *object_list,
                                        selectable);
   } else {
     
-    object_list = o_complex_add_by_name(w_current, object_list, NULL, type, 
-					WHITE, 
-					x1, y1, 
-					angle, mirror,
-					basename, selectable, FALSE);
+    const CLibSymbol *clib = s_clib_get_symbol_by_name (basename);
+
+    object_list = o_complex_add(w_current, object_list, NULL, type, 
+                                WHITE, 
+                                x1, y1, 
+                                angle, mirror, clib,
+                                basename, selectable, FALSE);
   }
 
   return object_list;
diff --git a/libgeda/src/s_clib.c b/libgeda/src/s_clib.c
index 088ac1a..fcea2d4 100644
--- a/libgeda/src/s_clib.c
+++ b/libgeda/src/s_clib.c
@@ -1205,6 +1205,43 @@ void s_clib_flush_cache ()
   g_hash_table_remove_all (clib_cache);
 }
 
+/*! \brief Get symbol structure for a given symbol name.
+ *  \par Function Description
+ *  Return the first symbol found with the given \a name.  If more
+ *  than one matching symbol is found or no matches are found at all,
+ *  emits a log message warning the user.
+ *
+ *  \param name The symbol name to match against.
+ *  \return The first matching symbol, or NULL if none found.
+ */
+const CLibSymbol *s_clib_get_symbol_by_name (const gchar *name)
+{
+  GList *symlist = NULL;
+  const CLibSymbol *retval;
+
+  symlist = s_clib_search (name, CLIB_EXACT);
+
+  if (symlist == NULL) {
+    s_log_message ("Component [%s] was not found in the component library\n", 
+                   name);
+    /*! \bug Why does this need to go to stderr as well? */
+    fprintf(stderr,
+	    "Component [%s] was not found in any component library\n", 
+	    name);
+    return NULL;
+  }
+
+  if (g_list_next (symlist) != NULL) { /* More than one symbol */
+    s_log_message ("More than one component found with name [%s]\n",
+                   name);
+  }
+
+  retval = (CLibSymbol *) symlist->data;
+  g_list_free (symlist);
+
+  return retval;
+}
+
 /*! \brief Get symbol data for a given symbol name.
  *  \par Function Description
  *  Return the data for the first symbol found with the given name.
@@ -1213,31 +1250,14 @@ void s_clib_flush_cache ()
  *
  *  On failure, returns \b NULL (the error will be logged).
  *
- *  \todo Speed this up repeated calls by caching the #CLibSymbol
- *  pointers found for each name requested.
- *
  *  \param name The symbol name to match against.
  *  \return Allocated buffer containing symbol data.
  */
 gchar *s_clib_symbol_get_data_by_name (const gchar *name)
 {
-  GList *sourcelist;
-  CLibSource *source;
-  CLibSymbol *symbol;
-
-  for (sourcelist = clib_sources; 
-       sourcelist != NULL; 
-       sourcelist = g_list_next(sourcelist)) {
-
-    source = (CLibSource *) sourcelist->data;
+  const CLibSymbol *symbol;
 
-    symbol = source_has_symbol (source, name);
-
-    if (symbol != NULL) {
-      return s_clib_symbol_get_data (symbol);
-    }
-    
-  }
-
-  return NULL;
+  symbol = s_clib_get_symbol_by_name (name);
+  if (symbol == NULL) return NULL;
+  return s_clib_symbol_get_data (symbol);
 }

commit 01fd87d78aa26d3c29b4141878b5f48edab264ec
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Date:   Fri Jun 15 09:05:53 2007 +0100

    Make comp. library search faster and more flexible
    
    Replace s_clib_glob() with s_clib_search(), which can operate in
    either exact matching or glob matching mode.  Use a hashtable to cache
    the results of library searches. The hashtable is cleared every time
    it is invalidated (for instance if a component source is added or
    removed, or the component sources are rescanned).

diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index f870629..bc3793b 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -1068,7 +1068,7 @@ void o_update_component(TOPLEVEL *w_current, OBJECT *o_current)
     const GList *symlist = NULL;
     
     g_assert (o_current->complex_basename != NULL);
-    symlist = s_clib_glob (o_current->complex_basename);
+    symlist = s_clib_search (o_current->complex_basename, CLIB_EXACT);
 
     if (symlist == NULL) {
       s_log_message (_("Could not find symbol [%s] in library. Update failed.\n"), 
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 7db67b2..182a840 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -1123,7 +1123,8 @@ int o_net_add_busrippers(TOPLEVEL *w_current, OBJECT *net_obj,
     s_conn_remove(w_current, net_obj);
 
     if (w_current->bus_ripper_type == COMP_BUS_RIPPER) {
-      GList *symlist = s_clib_glob (w_current->bus_ripper_symname);
+      GList *symlist = 
+	s_clib_search (w_current->bus_ripper_symname, CLIB_EXACT);
       if (symlist != NULL) {
         rippersym = (CLibSymbol *) symlist->data;
       }
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 14f7ba6..37faab2 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -514,7 +514,8 @@ const gchar *s_clib_symbol_get_name (const CLibSymbol *symbol);
 gchar *s_clib_symbol_get_filename (const CLibSymbol *symbol);
 const CLibSource *s_clib_symbol_get_source (const CLibSymbol *symbol);
 gchar *s_clib_symbol_get_data (const CLibSymbol *symbol);
-GList *s_clib_glob (const gchar *glob);
+GList *s_clib_search (const gchar *pattern, const CLibSearchMode mode);
+void s_clib_flush_cache ();
 gchar *s_clib_symbol_get_data_by_name (const gchar *name);
 
 /* s_color.c */
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index e75b6ab..2d4188e 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -62,6 +62,9 @@ typedef struct _TextBuffer TextBuffer;
 typedef struct _CLibSource CLibSource;
 typedef struct _CLibSymbol CLibSymbol;
 
+/* Component library search modes */
+typedef enum { CLIB_EXACT=0, CLIB_GLOB } CLibSearchMode;
+
 /* PB : change begin */
 /* PB : these enum are constant to define :
    - the end of open line of an object ;
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 065b59e..7948348 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -329,7 +329,7 @@ OBJECT *o_complex_add_by_name(TOPLEVEL *w_current, OBJECT *object_list,
   const CLibSymbol *sym;
   GList *symlist;
 
-  symlist = s_clib_glob (basename);
+  symlist = s_clib_search (basename, CLIB_EXACT);
 
   if (symlist == NULL) {
     s_log_message("Component [%s] was not found in any component library\n", 
diff --git a/libgeda/src/o_embed.c b/libgeda/src/o_embed.c
index b635900..74cae6a 100644
--- a/libgeda/src/o_embed.c
+++ b/libgeda/src/o_embed.c
@@ -96,7 +96,7 @@ void o_unembed(TOPLEVEL *w_current, OBJECT *o_current)
   {
         
     /* search for the symbol in the library */
-    symlist = s_clib_glob (o_current->complex_basename);
+    symlist = s_clib_search (o_current->complex_basename, CLIB_EXACT);
 
     if (!symlist) {
       /* symbol not found in the symbol library: signal an error */
diff --git a/libgeda/src/s_clib.c b/libgeda/src/s_clib.c
index c05792e..088ac1a 100644
--- a/libgeda/src/s_clib.c
+++ b/libgeda/src/s_clib.c
@@ -64,7 +64,7 @@
  *    -# Do not use whitespace, or any of the characters "<tt>/:!*?</tt>".
  *    -# Try to use unique names.
  *  
- *  The component database may be queried using s_clib_glob().  A
+ *  The component database may be queried using s_clib_search().  A
  *  null-terminated buffer containing symbol data (suitable for
  *  loading using o_read_buffer()) may be obtained using
  *  s_clib_symbol_get_data().  If an exact symbol name is known, the
@@ -217,10 +217,12 @@ struct _CLibSymbol {
 /*! Holds the list of all known component sources */
 static GList *clib_sources = NULL;
 
+/*! Caches results of s_clib_search() */
+static GHashTable *clib_cache = NULL;
+
 /* Local static functions
  * ======================
  */
-
 static void free_symbol (gpointer data, gpointer user_data);
 static void free_source (gpointer data, gpointer user_data);
 static gint compare_source_name (gconstpointer a, gconstpointer b);
@@ -247,6 +249,15 @@ void s_clib_init ()
   if (clib_sources != NULL) {
     s_clib_free ();
   }
+
+  if (clib_cache != NULL) {
+    s_clib_flush_cache();
+  } else {
+    clib_cache = g_hash_table_new_full ((GHashFunc) g_str_hash,
+					(GEqualFunc)g_str_equal,
+					(GDestroyNotify) g_free, 
+					(GDestroyNotify) g_list_free);
+  }
 }
 
 /*! \brief Iterator callback for freeing a symbol.
@@ -541,6 +552,8 @@ static void refresh_directory (CLibSource *source)
   /* Now sort the list of symbols by name. */
   source->symbols = g_list_sort (source->symbols, 
 				 (GCompareFunc) compare_symbol_name);
+
+  s_clib_flush_cache();
 }
 
 /*! \brief Re-poll a library command for symbols.
@@ -605,6 +618,8 @@ static void refresh_command (CLibSource *source)
   /* Sort all symbols by name. */
   source->symbols = g_list_sort (source->symbols, 
 				 (GCompareFunc) compare_symbol_name);
+
+  s_clib_flush_cache();
 }
 
 /*! \brief Re-poll a scheme procedure for symbols.
@@ -658,6 +673,8 @@ static void refresh_scm (CLibSource *source)
   /* Now sort the list of symbols by name. */
   source->symbols = g_list_sort (source->symbols, 
 				 (GCompareFunc) compare_symbol_name);
+
+  s_clib_flush_cache();
 }
 
 /*! \brief Rescan all available component libraries.
@@ -1076,10 +1093,16 @@ gchar *s_clib_symbol_get_data (const CLibSymbol *symbol)
 }
 
 
-/*! \brief Find all symbols matching a glob pattern.  \par Function
- *  Description Searches the library, returning all symbols whose
- *  names match \a glob (see the GLib documentation for details of the
- *  glob syntax applicable).
+/*! \brief Find all symbols matching a pattern.  
+ *
+ *  \par Function Description 
+ *  Searches the library, returning all symbols whose
+ *  names match \a pattern.
+ *
+ *  Two search modes are available: \b CLIB_EXACT, where \a pattern is
+ *  compared to the symbol name using strcmp(), and \b CLIB_GLOB,
+ *  where \a pattern is assumed to be a glob pattern (see the GLib
+ *  documentation for details of the glob syntax applicable).
  *
  *  \warning The #CLibSymbol instances in the \b GList returned belong
  *  to the component library, and should be considered constants; they
@@ -1088,21 +1111,47 @@ gchar *s_clib_symbol_get_data (const CLibSymbol *symbol)
  *  needed.  Note that the values returned will be invalidated by a
  *  call to s_clib_free() or s_clib_refresh().
  *
- *  \param glob The glob pattern to match against.
+ *  \param pattern The pattern to match against.
+ *  \param mode    The search mode to use.
  *  \return A \b GList of matching #CLibSymbol structures.
  */
-GList *s_clib_glob (const gchar *glob)
+GList *s_clib_search (const gchar *pattern, const CLibSearchMode mode)
 {  
   GList *sourcelist;
   GList *symlist;
   GList *result = NULL;
   CLibSource *source;
   CLibSymbol *symbol;
-  GPatternSpec *pattern;
+  GPatternSpec *globpattern = NULL;
+  gchar *key;
+  gchar keytype;
 
-  if (glob == NULL) return NULL;
+  if (pattern == NULL) return NULL;
 
-  pattern = g_pattern_spec_new(glob);
+  /* Use different cache keys depending on what sort of search is being done */
+  switch (mode)
+    {
+    case CLIB_GLOB:
+      keytype = 'g';
+      break;
+    case CLIB_EXACT:
+      keytype = 's';
+      break;
+    default:
+      g_assert_not_reached();
+    }
+  key = g_strdup_printf("%c%s", keytype, pattern);
+
+  /* Check to see if the query is already in the cache */
+  result = (GList *) g_hash_table_lookup (clib_cache, key);
+  if (result != NULL) {
+    g_free (key);
+    return g_list_copy (result);
+  }
+
+  if (mode == CLIB_GLOB) {
+    globpattern = g_pattern_spec_new(pattern);
+  }
 
   for (sourcelist = clib_sources; 
        sourcelist != NULL; 
@@ -1116,21 +1165,46 @@ GList *s_clib_glob (const gchar *glob)
     
       symbol = (CLibSymbol *) symlist->data;
 
-      if (g_pattern_match_string (pattern, symbol->name)) {
-	result = g_list_prepend (result, symbol);
-      }
-
+      switch (mode)
+	{
+	case CLIB_EXACT:
+	  if (strcmp (pattern, symbol->name) == 0) {
+	    result = g_list_prepend (result, symbol);
+	  }
+	  break;
+	case CLIB_GLOB:
+	  if (g_pattern_match_string (globpattern, symbol->name)) {
+	    result = g_list_prepend (result, symbol);
+	  }
+	  break;
+	}
     }
-    
   }
 
   result = g_list_reverse (result);
 
-  g_pattern_spec_free (pattern);
+  if (globpattern != NULL) {
+    g_pattern_spec_free (globpattern);
+  }
+
+  g_hash_table_insert (clib_cache, key, g_list_copy (result));
+  /* __don't__ free key here, it's stored by the hash table! */
 
   return result;
 }
 
+
+/*! \brief Flush the symbol name lookup cache.
+ *  \par Function Description
+ *  Clears the hashtable which caches the results of s_clib_search().
+ *  You shouldn't ever need to call this, as all functions which
+ *  invalidate the cache are supposed to make sure it's flushed.
+ */
+void s_clib_flush_cache ()
+{
+  g_hash_table_remove_all (clib_cache);
+}
+
 /*! \brief Get symbol data for a given symbol name.
  *  \par Function Description
  *  Return the data for the first symbol found with the given name.


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

 gschem/src/g_hook.c           |   19 +++--
 gschem/src/i_callbacks.c      |   17 +++--
 gschem/src/o_complex.c        |   14 ++--
 gschem/src/o_misc.c           |   28 ++-----
 gschem/src/o_net.c            |    3 +-
 gschem/src/x_compselect.c     |    4 +-
 gschem/src/x_window.c         |    2 +-
 libgeda/include/prototype.h   |   12 +--
 libgeda/include/struct.h      |    7 +-
 libgeda/src/o_complex_basic.c |   73 ++++-------------
 libgeda/src/o_embed.c         |   16 +---
 libgeda/src/s_basic.c         |    3 -
 libgeda/src/s_clib.c          |  172 +++++++++++++++++++++++++++++++----------
 libgeda/src/s_toplevel.c      |    6 +-
 14 files changed, 203 insertions(+), 173 deletions(-)



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