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

Re: gEDA-user: cvs.gedasymbols.org and gschem



Peter:
> karl@xxxxxxxxxxx (Karl Hammar) writes:
> >[about code that enables recursion in component-library-search]
> Nack, for a number of reasons.
> 

*****

> 1) GRegex was introduced in GLib 2.14, and during the 1.7.x cycle we are
> targetting GLib 2.12 or later.

Regular expression is actually overkill for this. It would suffice to 
check (is it required that ".sym" is lowercase?) if the last 4 chars
is ".sym" or not for the files tested.
Corrected in attached "recursive.diff".

*****

> 2) This is an absolutely *textbook* example of the sort of thing that's
> more cleanly done using Scheme (Guile has all of the necessary
> functionality in the standard library).

a, Can you provide some pointers to which scheme "functions" to use?
   Is there something like "find path -name \*.sym" ?

   If I still have to use opendir et al., I don't see the gain of doing
   the c to scheme conversion.

b, One could possible initialize the gafrc with a shell script.
   It would be a static configuration which would be awkward to update.
   Maybe someone finds it helpful.
   See attached "gedasymbols.sh".

*****

> 3) I strongly recommend *not* using component-library-search because it
> gives you no control over the precedence ordering of libraries when
> searching for a symbol name match --

What do you mean by "precedence ordering of libraries"?

a, Is it the ordering in the library browser?

 There is 71 duplicate and 6 triplicate symbols names in the cvs.
 One of the triplicate is triac-1.sym, and searching for triac in
 the browser gives me five alternatives:

 dj_delorie/symbols/nvsemis
  triac-1.sym
 dj_delorie/symbols
  triac-1.sym
 levente_kovacs/symbols
  triac-1.sym
 werner_hoch/symbols/sf
  triac-2.sym
 Basic devices
  triac-1.sym

 Why should I ever care in what order thoose five are displayed?

b, or do you mean ..., if I have the file:

  v 20110116 2
  C 40000 40000 0 0 0 title-B.sym
  C 53500 46700 1 0 0 triac-1.sym
  {
  T 54600 47500 5 10 1 1 0 0 1
  refdes=TR?
  T 53500 46700 5 10 0 1 0 0 1
  footprint=TO220
  }

 how does gschem find the sym file?

 Well, that has actually nothing to do with ...-search.

 In gaf/docs/wiki/geda-file_format_spec.html, under component,
 it calls the last field of the "C" line for "basename".
 Using the basename of a file to find it opens up for ambiguity.

 Consider a schematic containg components a.sym and b.sym,
 and two libraries with

 path1/ a.sym b.sym
 path2/ a.sym b.sym

 and suppose we want path1/a.sym and path2/b.sym.

 This cannot ever be handled with a precedence ordering of libraries
 unless you can specify precedence for each and every component.
 But then you could just as well allow some part of the path or entry
 name to the field "basename".

*****

> you're entirely at the mercy of the
> order in which the filesystem decides to give the directories to
> you. Even when that happens to be in alphabetical order, it's rarely
> what you actually want.

a, To add a sorter should not be a big deal.
   An experimental one is attached (includes the recursive ...-search)
   in "component-library-sort.diff"
   Using the diff, and (component-library-sort "asc") added to my gafrc
   I get the browser listing sorted :)

b, And BTW, entries are listed in the reverse order in the library
   browser compared to how they are listed in the gafrc file with
   "component-library". That is rarely what I actually want:)

In libgeda/src/s_slib.c, lines 846-876:

  const CLibSource *s_clib_add_directory (const gchar *directory, 
					  const gchar *name)
  {
...
    /* Sources added later get scanned earlier */
    clib_sources = g_list_prepend (clib_sources, source);
...
  }

why do we use _prepend instead of _append here, there should not be
any performance problems with _append here ?

*****

> Having it implemented in C as a core part of
> libgeda functionality seems to me to send the incorrect message that
> using it is a good idea.

I don't understand the reasoning in this. Regardless if ...-search or
something like it is implemented in c or scheme, I think it is a good
idea to use it, why shouldn't it.

Compare maintaining one line of

 (component-library-search-recursive "root_directory" "prefix")

to 109 lines of

 (component-library "/var/home/karl/Net/cvs/cvs.gedasymbols.org/www/user/wojtek_zabolotny/symbols" "cvs/wojtek_zabolotny/symbols")
 (component-library "/var/home/karl/Net/cvs/cvs.gedasymbols.org/www/user/werner_hoch/symbols/sf" "cvs/werner_hoch/symbols/sf")
...
 (component-library "/var/home/karl/Net/cvs/cvs.gedasymbols.org/www/user/ales_hvezda/symbols" "cvs/ales_hvezda/symbols")

in your gafrc file.

My idea is to have the whole of cvs.gedasymbols.org's sym files 
accessible via the library browser.

In what way is that not a good idea ?

Regards,
/Karl Hammar

-----------------------------------------------------------------------
Aspö Data
Lilla Aspö 148
S-742 94 Östhammar
Sweden
+46 173 140 57



diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 4f0f584..fda05c4 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -288,6 +288,7 @@ const CLibSource *s_clib_get_source_by_name (const gchar *name);
 void s_clib_refresh ();
 const CLibSource *s_clib_add_directory (const gchar *directory, 
 					const gchar *name);
+int s_clib_sort(const gchar *how);
 const CLibSource *s_clib_add_command (const gchar *list_cmd,
                                       const gchar *get_cmd,
 				      const gchar *name);
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index b240e0b..48d38d4 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -18,6 +18,7 @@ SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name);
 SCM g_rc_component_library_search(SCM path);
 SCM g_rc_source_library(SCM path);
 SCM g_rc_source_library_search(SCM path);
+SCM g_rc_component_library_sort(SCM how);
 SCM g_rc_world_size(SCM width, SCM height, SCM border);
 SCM g_rc_reset_component_library(void);
 SCM g_rc_reset_source_library(void);
diff --git a/libgeda/src/g_rc.c b/libgeda/src/g_rc.c
index e287da7..30b184f 100644
--- a/libgeda/src/g_rc.c
+++ b/libgeda/src/g_rc.c
@@ -534,6 +534,38 @@ SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name)
   return result;
 }
 
+/*! \brief Guile callback for sorting the library entries
+ *  \par Function Description
+ *  Callback function for the "component-library-sort" Guile
+ *  function, which can be used in the rc files to sort the
+ *  entries in the component library system. *  
+ *
+ *  \param [in] how    should we sort them ascending, etc...
+ *
+ *  \returns SCM_BOOL_T on success, SCM_BOOL_F otherwise.
+ */
+SCM g_rc_component_library_sort(SCM how)
+{
+  gchar *string;
+  char *temp;
+  int ix;
+
+  SCM_ASSERT (scm_is_string (how), how,
+              SCM_ARG1, "component-library-sort");
+
+  /* take care of any shell variables */
+  temp = scm_to_locale_string (how);
+  string = s_expand_env_variables (temp);
+  free (temp);
+
+  ix = s_clib_sort(string);
+
+  g_free(string);
+
+  if (ix < 0) return SCM_BOOL_F;
+  else return SCM_BOOL_T;
+}
+
 /*! \todo Finish function description!!!
  *  \brief
  *  \par Function Description
@@ -541,13 +573,14 @@ SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name)
  *  \param [in] path  
  *  \return SCM_BOOL_T on success, SCM_BOOL_F otherwise.
  */
+static int C_g_rc_component_library_search(gchar *string, const gchar *name);
 SCM g_rc_component_library_search(SCM path)
 {
   gchar *string;
   char *temp;
-  GDir *dir;
-  const gchar *entry;
-  
+  int ix;
+  const char prefix[] = "cvs";
+
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "component-library-search");
 
@@ -556,13 +589,26 @@ SCM g_rc_component_library_search(SCM path)
   string = s_expand_env_variables (temp);
   free (temp);
 
+  ix = C_g_rc_component_library_search(string, prefix);
+
+  g_free(string);
+
+  if (ix < 0) return SCM_BOOL_F;
+  else return SCM_BOOL_T;
+}
+
+int C_g_rc_component_library_search(gchar *string, const gchar *name)
+{
+  GDir *dir;
+  const gchar *entry;
+  int have_sym = 0;
+
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
     fprintf (stderr,
              "Invalid path [%s] passed to component-library-search\n",
              string);
-    g_free(string);
-    return SCM_BOOL_F;
+    return -1;
   }
 
   dir = g_dir_open (string, 0, NULL);
@@ -570,37 +616,45 @@ SCM g_rc_component_library_search(SCM path)
     fprintf (stderr,
              "Invalid path [%s] passed to component-library-search\n",
              string);
-    g_free(string);
-    return SCM_BOOL_F;
+    return -1;
   }
 
   while ((entry = g_dir_read_name (dir))) {
     /* don't do . and .. and special case font */
-    if ((g_strcasecmp (entry, ".")    != 0) && 
-        (g_strcasecmp (entry, "..")   != 0) &&
-        (g_strcasecmp (entry, "font") != 0))
-    {
+    if ((g_strcasecmp (entry, ".")    == 0) && 
+        (g_strcasecmp (entry, "..")   == 0) &&
+        (g_strcasecmp (entry, "CVS")   == 0) &&
+        (g_strcasecmp (entry, "font") == 0)) continue;
+
+    if (  g_str_has_suffix(entry, ".sym") ) {
+      have_sym++;
+    } else {
       gchar *fullpath = g_build_filename (string, entry, NULL);
+      gchar *entry_name;
+
+      if (name == NULL) entry_name = g_strdup(entry);
+      else entry_name = g_strconcat(name, "/", entry, NULL);
 
       if (g_file_test (fullpath, G_FILE_TEST_IS_DIR)) {
         if (g_path_is_absolute (fullpath)) {
-          s_clib_add_directory (fullpath, NULL);
+	  if (C_g_rc_component_library_search(fullpath, entry_name) > 0)
+	    s_clib_add_directory (fullpath, entry_name);
         } else {
           gchar *cwd = g_get_current_dir ();
           gchar *temp;
           temp = g_build_filename (cwd, fullpath, NULL);
-          s_clib_add_directory (temp, NULL);
+	  if (C_g_rc_component_library_search(temp, entry_name) > 0)
+	    s_clib_add_directory (temp, entry_name);
           g_free(temp);
           g_free(cwd);
         }
       }
       g_free(fullpath);
+      g_free(entry_name);
     }
   }
 
-  g_free(string);
-
-  return SCM_BOOL_T;
+  return have_sym;
 }
 
 /*! \todo Finish function description!!!
diff --git a/libgeda/src/g_register.c b/libgeda/src/g_register.c
index b40f250..2193a08 100644
--- a/libgeda/src/g_register.c
+++ b/libgeda/src/g_register.c
@@ -53,6 +53,7 @@ static struct gsubr_t libgeda_funcs[] = {
   { "component-library-command", 3, 0, 0, g_rc_component_library_command },
   { "component-library-funcs",  3, 0, 0, g_rc_component_library_funcs },
   { "component-library-search", 1, 0, 0, g_rc_component_library_search },
+  { "component-library-sort",   1, 0, 0, g_rc_component_library_sort },
   { "source-library",           1, 0, 0, g_rc_source_library },
   { "source-library-search",    1, 0, 0, g_rc_source_library_search },
   
diff --git a/libgeda/src/s_clib.c b/libgeda/src/s_clib.c
index b23f53f..e9d6573 100644
--- a/libgeda/src/s_clib.c
+++ b/libgeda/src/s_clib.c
@@ -874,6 +874,42 @@ const CLibSource *s_clib_add_directory (const gchar *directory,
   return source;
 }
 
+/*! \todo Should the cache be regenerated/flushed or what
+ *  \brief sort the entries in the component library system
+ *  \par Function Description
+ *  sort the entries in the component library system
+ *
+ *  \todo how only does ascending for the time beeing, what would be useful and how should we specify it?
+ *  \param [in] how    should we sort them ascending, etc...
+ *
+ *  \returns SCM_BOOL_T on success, SCM_BOOL_F otherwise.
+ */
+static gint sort_library(gconstpointer a, gconstpointer b, gpointer user_data) {
+  const CLibSource *src1 = a;
+  const CLibSource *src2 = b;
+  gchar *how = (gchar *) user_data;
+  int ix;
+
+  g_assert (src1 != NULL);
+  g_assert (src2 != NULL);
+
+  g_assert (src1->name != NULL);
+  g_assert (src2->name != NULL);
+
+  // \todo if()'s or switch {} to select how to test
+  (void) how;
+  ix = g_strcmp0(src1->name, src2->name);
+
+  return ix;
+}
+
+int s_clib_sort(const gchar *how)
+{
+  clib_sources = g_list_sort_with_data( clib_sources, sort_library, (gpointer) how);
+  // \todo should some caches be flushed here?
+  return 1;
+}
+
 /*! \brief Add symbol-generating commands to the library
  *  \par Function Description
  *  Adds a set of commands which can generate symbols to the
#!/bin/sh

dir=$1
pfx=$2

if [ ! "$pfx" ]
then
  echo gedasymbols.sh
  echo \ find dirctories with symbol files
  echo \ and make gafrc lines to add them to the library browser
  echo Usage:
  echo " gedasymbols root_of_file_tree prefix"
  echo Example:
  echo ' gedasymbols.sh ~/Net/cvs/cvs.gedasymbols.org/www/user/ cvs >> .gEDA/gafrc'
  exit 1
fi

cd $1

find . -type f -name \*.sym |
sed -e 's|/[^/]*$||; s/^\.\///' |
sort -u |
while read a
do
  echo "(component-library \"$1/$a\" \"$pfx/$a\")" | sed -e 's|//|/|'
done |
sort -r
diff --git a/libgeda/src/g_rc.c b/libgeda/src/g_rc.c
index e287da7..7895f7f 100644
--- a/libgeda/src/g_rc.c
+++ b/libgeda/src/g_rc.c
@@ -541,13 +541,14 @@ SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name)
  *  \param [in] path  
  *  \return SCM_BOOL_T on success, SCM_BOOL_F otherwise.
  */
+static int C_g_rc_component_library_search(gchar *string, const gchar *name);
 SCM g_rc_component_library_search(SCM path)
 {
   gchar *string;
   char *temp;
-  GDir *dir;
-  const gchar *entry;
-  
+  int ix;
+  const char prefix[] = "cvs";
+
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "component-library-search");
 
@@ -556,13 +557,26 @@ SCM g_rc_component_library_search(SCM path)
   string = s_expand_env_variables (temp);
   free (temp);
 
+  ix = C_g_rc_component_library_search(string, prefix);
+
+  g_free(string);
+
+  if (ix < 0) return SCM_BOOL_F;
+  else return SCM_BOOL_T;
+}
+
+int C_g_rc_component_library_search(gchar *string, const gchar *name)
+{
+  GDir *dir;
+  const gchar *entry;
+  int have_sym = 0;
+
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
     fprintf (stderr,
              "Invalid path [%s] passed to component-library-search\n",
              string);
-    g_free(string);
-    return SCM_BOOL_F;
+    return -1;
   }
 
   dir = g_dir_open (string, 0, NULL);
@@ -570,37 +584,45 @@ SCM g_rc_component_library_search(SCM path)
     fprintf (stderr,
              "Invalid path [%s] passed to component-library-search\n",
              string);
-    g_free(string);
-    return SCM_BOOL_F;
+    return -1;
   }
 
   while ((entry = g_dir_read_name (dir))) {
     /* don't do . and .. and special case font */
-    if ((g_strcasecmp (entry, ".")    != 0) && 
-        (g_strcasecmp (entry, "..")   != 0) &&
-        (g_strcasecmp (entry, "font") != 0))
-    {
+    if ((g_strcasecmp (entry, ".")    == 0) && 
+        (g_strcasecmp (entry, "..")   == 0) &&
+        (g_strcasecmp (entry, "CVS")   == 0) &&
+        (g_strcasecmp (entry, "font") == 0)) continue;
+
+    if (  g_str_has_suffix(entry, ".sym") ) {
+      have_sym++;
+    } else {
       gchar *fullpath = g_build_filename (string, entry, NULL);
+      gchar *entry_name;
+
+      if (name == NULL) entry_name = g_strdup(entry);
+      else entry_name = g_strconcat(name, "/", entry, NULL);
 
       if (g_file_test (fullpath, G_FILE_TEST_IS_DIR)) {
         if (g_path_is_absolute (fullpath)) {
-          s_clib_add_directory (fullpath, NULL);
+	  if (C_g_rc_component_library_search(fullpath, entry_name) > 0)
+	    s_clib_add_directory (fullpath, entry_name);
         } else {
           gchar *cwd = g_get_current_dir ();
           gchar *temp;
           temp = g_build_filename (cwd, fullpath, NULL);
-          s_clib_add_directory (temp, NULL);
+	  if (C_g_rc_component_library_search(temp, entry_name) > 0)
+	    s_clib_add_directory (temp, entry_name);
           g_free(temp);
           g_free(cwd);
         }
       }
       g_free(fullpath);
+      g_free(entry_name);
     }
   }
 
-  g_free(string);
-
-  return SCM_BOOL_T;
+  return have_sym;
 }
 
 /*! \todo Finish function description!!!

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