[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-cvs: CVS update: g_rc.c
User: peterb
Date: 07/05/28 03:56:47
Modified: . g_rc.c g_register.c s_clib.c
Log:
Add component sources based on Scheme procedures.
Add the ability to use a set of Scheme procedures which list and
return component symbols as the backend of a component library. Adds
the g_rc_component_library_funcs() and s_clib_add_scm() functions to
libgeda, as well as the component-library-funcs rc file function.
Revision Changes Path
1.5 eda/geda/gaf/libgeda/src/g_rc.c
(In the diff below, changes in quantity of whitespace are not shown.)
Index: g_rc.c
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/gaf/libgeda/src/g_rc.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- g_rc.c 28 May 2007 07:48:31 -0000 1.4
+++ g_rc.c 28 May 2007 07:56:47 -0000 1.5
@@ -426,6 +426,37 @@
return SCM_BOOL_T;
}
+/*! \brief Guile callback for adding library functions.
+ * \par Function Description
+ * Callback function for the "component-library-funcs" Guile
+ * function, which can be used in the rc files to add a set of Guile
+ * procedures for listing and generating symbols.
+ *
+ * \param [in] listfunc A Scheme procedure which takes no arguments
+ * and returns a Scheme list of component names.
+ * \param [in] getfunc A Scheme procedure which takes a component
+ * name as an argument and returns a symbol
+ * encoded in a string in gEDA format, or the \b
+ * \#f if the component name is unknown.
+ *
+ * \returns SCM_BOOL_T on success, SCM_BOOL_F otherwise.
+ */
+SCM g_rc_component_library_funcs (SCM listfunc, SCM getfunc, SCM name)
+{
+ SCM_ASSERT (scm_is_true (scm_procedure_p (listfunc)), listfunc, SCM_ARG1,
+ "component-library-funcs");
+ SCM_ASSERT (scm_is_true (scm_procedure_p (getfunc)), getfunc, SCM_ARG2,
+ "component-library-funcs");
+ SCM_ASSERT (SCM_STRINGP (name), name, SCM_ARG1,
+ "component-library-funcs");
+
+ if (s_clib_add_scm (listfunc, getfunc, SCM_STRING_CHARS (name)) != NULL) {
+ return SCM_BOOL_T;
+ } else {
+ return SCM_BOOL_F;
+ }
+}
+
/*! \todo Finish function description!!!
* \brief
* \par Function Description
1.4 eda/geda/gaf/libgeda/src/g_register.c
(In the diff below, changes in quantity of whitespace are not shown.)
Index: g_register.c
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/gaf/libgeda/src/g_register.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- g_register.c 28 May 2007 07:48:31 -0000 1.3
+++ g_register.c 28 May 2007 07:56:47 -0000 1.4
@@ -59,6 +59,7 @@
static struct gsubr_t libgeda_funcs[] = {
{ "component-library", 1, 1, 0, g_rc_component_library },
{ "component-library-command", 1, 1, 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 },
{ "source-library", 1, 0, 0, g_rc_source_library },
{ "source-library-search", 1, 0, 0, g_rc_source_library_search },
1.24 eda/geda/gaf/libgeda/src/s_clib.c
(In the diff below, changes in quantity of whitespace are not shown.)
Index: s_clib.c
===================================================================
RCS file: /home/cvspsrv/cvsroot/eda/geda/gaf/libgeda/src/s_clib.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- s_clib.c 28 May 2007 07:53:25 -0000 1.23
+++ s_clib.c 28 May 2007 07:56:47 -0000 1.24
@@ -158,10 +158,14 @@
/*! Valid types of component source */
enum CLibSourceType {
+ CLIB_NONE = 0,
/*! Directory source */
CLIB_DIR,
/*! Command source */
- CLIB_CMD };
+ CLIB_CMD,
+ /*! Guile function source */
+ CLIB_SCM,
+};
/*! Stores data about a particular component source */
struct _CLibSource {
@@ -173,6 +177,9 @@
gchar *name;
/*! Available symbols (CLibSymbol) */
GList *symbols;
+
+ SCM list_fn;
+ SCM get_fn;
};
/*! Stores data about a particular symbol */
@@ -203,8 +210,10 @@
const gchar *name);
static void refresh_directory (CLibSource *source);
static void refresh_command (CLibSource *source);
+static void refresh_scm (CLibSource *source);
static gchar *get_data_directory (const CLibSymbol *symbol);
static gchar *get_data_command (const CLibSymbol *symbol);
+static gchar *get_data_scm (const CLibSymbol *symbol);
/*! \brief Initialise the component library.
* \par Function Description
@@ -259,6 +268,10 @@
g_list_free (source->symbols);
source->symbols = NULL;
}
+ if (source->type == CLIB_SCM) {
+ scm_gc_unprotect_object (source->list_fn);
+ scm_gc_unprotect_object (source->get_fn);
+ }
}
}
@@ -566,6 +579,59 @@
(GCompareFunc) compare_symbol_name);
}
+/*! \brief Re-poll a scheme procedure for symbols.
+ * \par Function Description
+ * Calls a Scheme procedure to obtain a list of available symbols,
+ * and updates the source with the new list
+ *
+ * Private function used only in s_clib.c.
+ */
+static void refresh_scm (CLibSource *source)
+{
+ SCM symlist;
+ SCM symname;
+ CLibSymbol *symbol;
+
+ g_assert (source != NULL);
+ g_assert (source->type == CLIB_SCM);
+
+ /* Clear the current symbol list */
+ g_list_foreach (source->symbols, (GFunc) free_symbol, NULL);
+ g_list_free (source->symbols);
+ source->symbols = NULL;
+
+ symlist = scm_call_0 (source->list_fn);
+
+ if (SCM_NCONSP (symlist) && (symlist != SCM_EOL)) {
+ s_log_message ("Failed to scan library [%s]: Scheme function returned non-list\n",
+ source->name);
+ return;
+ }
+
+ while (symlist != SCM_EOL) {
+ symname = SCM_CAR (symlist);
+ if (!SCM_STRINGP (symname)) {
+ s_log_message ("Non-string symbol name while scanning library [%s]\n",
+ source->name);
+ } else {
+ symbol = g_new0 (CLibSymbol, 1);
+ symbol->source = source;
+ symbol->name = g_strdup(SCM_STRING_CHARS (symname));
+
+
+ /* Prepend because it's faster and it doesn't matter what order we
+ * add them. */
+ source->symbols = g_list_prepend (source->symbols, symbol);
+ }
+
+ symlist = SCM_CDR (symlist);
+ }
+
+ /* Now sort the list of symbols by name. */
+ source->symbols = g_list_sort (source->symbols,
+ (GCompareFunc) compare_symbol_name);
+}
+
/*! \brief Rescan all available component libraries.
* \par Function Description
* Resets the list of symbols available from each source, and
@@ -594,6 +660,9 @@
case CLIB_CMD:
refresh_command (source);
break;
+ case CLIB_SCM:
+ refresh_scm (source);
+ break;
default:
g_assert_not_reached();
}
@@ -643,6 +712,7 @@
const CLibSource *s_clib_add_directory (const gchar *directory,
const gchar *name)
{
+ const CLibSource *oldsource;
CLibSource *source;
gchar *realname;
@@ -656,8 +726,8 @@
realname = g_strdup(name);
}
- source = s_clib_get_source_by_name (realname);
- if (source != NULL) {
+ oldsource = s_clib_get_source_by_name (realname);
+ if (oldsource != NULL) {
s_log_message ("Cannot add library [%s]: name in use.",
realname);
g_free (realname);
@@ -692,6 +762,7 @@
const CLibSource *s_clib_add_command (const gchar *command,
const gchar *name)
{
+ const CLibSource *oldsource;
CLibSource *source;
gchar *realname;
@@ -705,9 +776,9 @@
realname = g_strdup (name);
}
- source = s_clib_get_source_by_name (realname);
- if (source != NULL) {
- s_log_message ("Cannot add library [%s]: name in use.",
+ oldsource = s_clib_get_source_by_name (realname);
+ if (oldsource != NULL) {
+ s_log_message ("Cannot add library [%s]: name in use.\n",
realname);
g_free (realname);
return NULL;
@@ -720,12 +791,60 @@
refresh_command (source);
- /* Sources added later get scanned earlier */
+ /* Sources added later get sacnned earlier */
clib_sources = g_list_prepend (clib_sources, source);
return source;
}
+/*! \brief Add symbol-generating Scheme procedures to the library.
+ * \par Function Description
+ * Adds a source to the library based on Scheme procedures. Two
+ * procedures are required: \a listfunc must return a Scheme list of
+ * symbol names, and \a getfunc must return a string containing
+ * symbol data when passed a symbol name.
+ *
+ * \param listfunc A Scheme function returning a list of symbols.
+ * \param getfunc A Scheme function returning symbol data.
+ * \param name A descriptive name for the component source.
+ *
+ * \return The new CLibSource.
+ */
+const CLibSource *s_clib_add_scm (SCM listfunc, SCM getfunc, const gchar *name)
+{
+ const CLibSource *oldsource;
+ CLibSource *source;
+
+ if (name == NULL) {
+ s_log_message ("Cannot add library: name not specified\n");
+ return NULL;
+ }
+
+ oldsource = s_clib_get_source_by_name (name);
+ if (oldsource != NULL) {
+ s_log_message ("Cannot add library [%s]: name in use.\n", name);
+ return NULL;
+ }
+
+ if (scm_is_false (scm_procedure_p (listfunc))
+ && scm_is_false (scm_procedure_p (getfunc))) {
+ s_log_message ("Cannot add Scheme-library [%s]: callbacks must be closures\n",
+ name);
+ return NULL;
+ }
+
+ source = g_new0 (CLibSource, 1);
+ source->type = CLIB_SCM;
+ source->name = g_strdup (name);
+ source->list_fn = scm_gc_protect_object (listfunc);
+ source->get_fn = scm_gc_protect_object (getfunc);
+
+ refresh_scm (source);
+
+ clib_sources = g_list_prepend (clib_sources, source);
+
+ return source;
+}
/*! \brief Get the name of a source.
* \par Function Description
@@ -873,6 +992,25 @@
return run_source_command ( argv );
}
+static gchar *get_data_scm (const CLibSymbol *symbol)
+{
+ SCM symdata;
+
+ g_assert (symbol != NULL);
+ g_assert (symbol->source->type == CLIB_SCM);
+
+ symdata = scm_call_1 (symbol->source->get_fn,
+ scm_from_locale_string (symbol->name));
+
+ if (!SCM_STRINGP (symdata)) {
+ s_log_message ("Failed to load symbol data [%s] from source [%s]\n",
+ symbol->name, symbol->source->name);
+ return NULL;
+ }
+
+ return g_strdup (SCM_STRING_CHARS (symdata));
+}
+
/*! \brief Get symbol data.
* \par Function Description
* Get the unparsed gEDA-format data corresponding to a symbol from
@@ -894,6 +1032,8 @@
return get_data_directory (symbol);
case CLIB_CMD:
return get_data_command (symbol);
+ case CLIB_SCM:
+ return get_data_scm (symbol);
default:
g_assert_not_reached();
}
_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs