Bump gEDA version
[geda-gaf.git] / libgeda / src / s_clib.c
blobabeedfd77ccff08efac6d59ae40c14bde1925322
1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2020 gEDA Contributors (see ChangeLog for details)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 /*! \file s_clib.c
21 * \brief The component library system
23 * <B>clib</B> stands for component library.
25 * The <b>component library</b> is made up of a number of
26 * <b>component sources</b>, each of which in turn makes available a
27 * number of component <b>symbols</b>. Each source may be either a
28 * directory on disk containing symbol files, a command in the system
29 * PATH which can generate gEDA symbol data (e.g. from a database),
30 * or a Scheme function which can do likewise. A component source is
31 * represented by a #CLibSource instance.
33 * The component library system manages component sources and
34 * symbols, and abstracts the interface to the underlying storage.
36 * To initialise the component library, s_clib_init() is called. To
37 * clean up when it is no longer needed, s_clib_free() should be
38 * called.
40 * A directory which contains one or more symbol files in gEDA
41 * format may be used as a component source. Each symbol file should
42 * have a filename ending in ".sym" (case insensitive). A
43 * component source based on a directory can be added using
44 * s_clib_add_directory(). Symbol files with filenames starting with
45 * a period "." are ignored.
47 * An executable program in the system search path may be used as a
48 * component source, and it must conform with the specification given
49 * on page \ref libcmds. A component source based on a command may
50 * be added using s_clib_add_command().
52 * Scheme functions may be used as a component source; for more
53 * information, please see page \ref libscms. A component source
54 * based on Scheme functions may be added using s_clib_add_scm().
56 * Each symbol is identified by its \b name, which is stored in the
57 * saved schematic file. The name must be a valid for storage in a
58 * gEDA schematic file as the "basename" of a "component" object.
59 * For symbols from directory sources, the filename of the symbol is
60 * taken as the symbol name. For a command source, the name may be
61 * any permissible string. Guidelines to follow:
63 * -# Do not begin a symbol name with "EMBEDDED"
64 * -# Do not use whitespace, or any of the characters "<tt>/:!*?</tt>".
65 * -# Try to use unique names.
67 * The component database may be queried using s_clib_search(). A
68 * null-terminated buffer containing symbol data (suitable for
69 * loading using o_read_buffer()) may be obtained using
70 * s_clib_symbol_get_data(). If an exact symbol name is known, the
71 * symbol data may be requested directly using
72 * s_clib_symbol_get_data_by_name().
75 * \section libcmds Library Commands
77 * A program or set of programs can be used as a component source. The procedure used to add such a source from a gEDA rc file is:
79 * <code>
80 * (component-library-command listcmd getcmd name)
81 * </code>
83 * This is implemented by g_rc_component_library_command(), which is
84 * a wrapper for s_clib_add_command().
86 * The list command will be executed with no further arguments, and
87 * should output a list of available symbol names on stdout. The get
88 * command will have a symbol name appended to it as the final
89 * argument, and should output gEDA symbol data on stdout.
91 * If the command cannot successfully complete, it should exit with
92 * non-zero exit status. Anything it has output on stdout will be
93 * ignored, and any stderr output displayed to the user.
95 * \section libscms Library Scheme Procedures
97 * A set of Scheme procedures can be used as a component source. The
98 * procedure used to add such a source from a gEDA rc file is:
100 * <code>
101 * (component-library-funcs listfunc getfunc name)
102 * </code>
104 * This is implemented by g_rc_component_library_funcs(), which is a
105 * wrapper for s_clib_add_scm().
107 * \b listfunc and \b getfunc must both be Guile procedures. \b
108 * listfunc takes no arguments, and returns a list of symbol
109 * names. \b getfunc takes a symbol name as an argument, and returns
110 * gEDA symbol data in a string, or \b \#f if not known.
113 #include <config.h>
115 #include <stdio.h>
116 #include <glib.h>
118 #ifdef HAVE_STRING_H
119 #include <string.h>
120 #endif
122 #ifdef HAVE_SYS_WAIT_H
123 #include <sys/wait.h>
124 #else
125 #define WIFSIGNALED(x) 0
126 #define WTERMSIG(x) 0
127 #define WIFEXITED(x) 1
128 #define WEXITSTATUS(x) 0
129 #endif
131 #include <time.h>
133 #include "libgeda_priv.h"
135 /* Constant definitions
136 * ===================
139 /*! All symbols in directory sources end with this string. Must be
140 * lowercase. */
141 #define SYM_FILENAME_FILTER ".sym"
143 /*! Library command mode used to fetch list of symbols */
144 #define CLIB_LIST_CMD "list"
146 /*! Library command mode used to fetch symbol data */
147 #define CLIB_DATA_CMD "get"
149 /*! Maximum number of symbol cache entries */
150 #define CLIB_MAX_SYMBOL_CACHE 128
151 /*! When symbol cache gets full, remove down to this level */
152 #define CLIB_MIN_SYMBOL_CACHE 96
154 /* Type definitions
155 * ================
158 /*! Valid types of component source */
159 enum CLibSourceType {
160 CLIB_NONE = 0,
161 /*! Directory source */
162 CLIB_DIR,
163 /*! Command source */
164 CLIB_CMD,
165 /*! Guile function source */
166 CLIB_SCM,
169 /*! Stores data about a particular component source */
170 struct _CLibSource {
171 /*! Type of source */
172 enum CLibSourceType type;
173 /*! Name of source */
174 gchar *name;
175 /*! Available symbols (#CLibSymbol) */
176 GList *symbols;
178 /*! Path to directory */
179 gchar *directory;
181 /*! Command & arguments for listing symbols */
182 gchar *list_cmd;
183 /*! Command & arguments for retrieving symbol data */
184 gchar *get_cmd;
186 /*! Scheme function for listing symbols */
187 SCM list_fn;
188 /*! Scheme function for retrieving symbol data */
189 SCM get_fn;
192 /*! Stores data about a particular symbol */
193 struct _CLibSymbol {
194 /*! The source this symbol is available from */
195 CLibSource *source;
196 /*! The name of this symbol */
197 gchar *name;
200 /*! Symbol data cache entry */
201 typedef struct _CacheEntry CacheEntry;
202 struct _CacheEntry {
203 /*! Pointer to symbol */
204 CLibSymbol *ptr;
205 /*! Symbol data */
206 gchar *data;
207 /*! Last access */
208 time_t accessed;
211 /* Static variables
212 * ================
215 /*! Holds the list of all known component sources */
216 static GList *clib_sources = NULL;
218 /*! Caches results of s_clib_search(). The key of the hashtable is a
219 * string describing the search that was carried out, and the value
220 * is a list of symbol pointers. */
221 static GHashTable *clib_search_cache = NULL;
223 /*! Caches symbol data. The key of the hashtable is a symbol pointer,
224 * and the value is a #CacheEntry structure containing the data and
225 * the time it was last used. */
226 static GHashTable *clib_symbol_cache = NULL;
228 /* Local static functions
229 * ======================
231 static void free_symbol (gpointer data, gpointer user_data);
232 static void free_symbol_cache_entry (gpointer data);
233 static void free_source (gpointer data, gpointer user_data);
234 static gint compare_source_name (gconstpointer a, gconstpointer b);
235 static gint compare_symbol_name (gconstpointer a, gconstpointer b);
236 static void cache_find_oldest (gpointer key, gpointer value, gpointer user_data);
237 static gchar *run_source_command (const gchar *command);
238 static CLibSymbol *source_has_symbol (const CLibSource *source,
239 const gchar *name);
240 static gchar *uniquify_source_name (const gchar *name);
241 static void refresh_directory (CLibSource *source);
242 static void refresh_command (CLibSource *source);
243 static void refresh_scm (CLibSource *source);
244 static gchar *get_data_directory (const CLibSymbol *symbol);
245 static gchar *get_data_command (const CLibSymbol *symbol);
246 static gchar *get_data_scm (const CLibSymbol *symbol);
248 static gboolean s_clib_updating = FALSE;
249 static GList *s_clib_update_closures = NULL;
251 /*! \brief Initialise the component library.
252 * \par Function Description
253 * Resets and initialises the component library.
255 * \warning This function must be called before any other functions
256 * from s_clib.c.
258 void s_clib_init ()
260 if (clib_sources != NULL) {
261 s_clib_free ();
264 if (clib_search_cache != NULL) {
265 s_clib_flush_search_cache();
266 } else {
267 clib_search_cache = g_hash_table_new_full ((GHashFunc) g_str_hash,
268 (GEqualFunc)g_str_equal,
269 (GDestroyNotify) g_free,
270 (GDestroyNotify) g_list_free);
273 if (clib_symbol_cache != NULL) {
274 s_clib_flush_symbol_cache();
275 } else {
276 clib_symbol_cache =
277 g_hash_table_new_full ((GHashFunc) g_direct_hash,
278 (GEqualFunc) g_direct_equal,
279 NULL,
280 (GDestroyNotify) free_symbol_cache_entry);
284 /*! \brief Iterator callback for freeing a symbol.
285 * \par Function Description
286 * Private function used only in s_clib.c.
288 static void free_symbol (gpointer data, gpointer user_data)
290 CLibSymbol *symbol = data;
291 if (symbol != NULL) {
292 if (symbol->source != NULL) {
293 symbol->source = NULL;
295 if (symbol->name != NULL) {
296 g_free (symbol->name);
297 symbol->name = NULL;
299 g_free(symbol);
303 /*! \brief Iterator callback for freeing a symbol cache entry.
304 * \par Function Description
305 * Private function used only in s_clib.c.
307 static void free_symbol_cache_entry (gpointer data)
309 CacheEntry *entry = data;
310 g_return_if_fail (entry != NULL);
311 g_free (entry->data);
312 g_free (entry);
315 /*! \brief Iterator callback for freeing a source.
316 * \par Function Description
317 * Private function used only in s_clib.c.
319 static void free_source (gpointer data, gpointer user_data)
321 CLibSource *source = data;
322 if (source != NULL) {
323 if (source->name != NULL) {
324 g_free (source->name);
325 source->name = NULL;
327 if (source->symbols != NULL) {
328 g_list_foreach (source->symbols, (GFunc) free_symbol, NULL);
329 g_list_free (source->symbols);
330 source->symbols = NULL;
332 if (source->directory != NULL) {
333 g_free (source->directory);
334 source->directory = NULL;
336 if (source->list_cmd != NULL) {
337 g_free (source->list_cmd);
338 source->list_cmd = NULL;
340 if (source->get_cmd != NULL) {
341 g_free (source->get_cmd);
342 source->get_cmd = NULL;
344 if (source->type == CLIB_SCM) {
345 scm_gc_unprotect_object (source->list_fn);
346 scm_gc_unprotect_object (source->get_fn);
351 /*! \brief Free all memory used by the component library.
352 * \par Function Description
353 * Should be called at program exit to clean up any remaining data
354 * being used by the component library system.
356 void s_clib_free ()
358 if (clib_sources != NULL) {
359 g_list_foreach (clib_sources, (GFunc) free_source, NULL);
360 g_list_free (clib_sources);
361 clib_sources = NULL;
364 s_clib_begin_update ();
367 /*! \brief Compare two component sources by name.
368 * \par Function Description
369 * Compare two component sources by name, case-insensitively.
370 * Typically used when calling g_list_sort(). Private function used
371 * only in s_clib.c. Argument order is as strcasecmp().
373 * \param a First source to compare
374 * \param b Second source to compare
376 * \return As strcasecmp().
378 static gint compare_source_name (gconstpointer a, gconstpointer b)
380 const CLibSource *src1 = a;
381 const CLibSource *src2 = b;
383 g_return_val_if_fail ((src1 != NULL), 0);
384 g_return_val_if_fail ((src2 != NULL), 0);
386 g_return_val_if_fail ((src1->name != NULL), 0);
387 g_return_val_if_fail ((src2->name != NULL), 0);
389 return strcasecmp(src1->name, src2->name);
392 /*! \brief Compare two component symbols by name.
393 * \par Function Description
394 * Compare two component symbols by name, case-insensitively.
395 * Typically used when calling g_list_sort(). Private function used
396 * only in s_clib.c. Argument order is as strcasecmp().
398 * \param a First symbol to compare
399 * \param b Second symbol to compare
401 * \return As strcasecmp().
403 static gint compare_symbol_name (gconstpointer a, gconstpointer b)
405 const CLibSymbol *sym1 = a;
406 const CLibSymbol *sym2 = b;
408 g_return_val_if_fail ((sym1 != NULL), 0);
409 g_return_val_if_fail ((sym2 != NULL), 0);
411 g_return_val_if_fail ((sym1->name != NULL), 0);
412 g_return_val_if_fail ((sym2->name != NULL), 0);
414 return strcasecmp(sym1->name, sym2->name);
417 /*! \brief Iterator callback for finding oldest symbol cache entry
418 * \par Function Description
419 * Private function used only in s_clib.c.
421 static void cache_find_oldest (gpointer key,
422 gpointer value,
423 gpointer user_data)
425 CacheEntry *current = value;
426 CacheEntry **oldest = user_data;
428 if (current->accessed < (*oldest)->accessed) {
429 *oldest = current;
433 /*! \brief Execute a library command.
434 * \par Function Description
435 * Execute a library command, returning the standard output, or \b
436 * NULL if the command fails for some reason. The system \b PATH is
437 * used to find the program to execute.
438 * The command can write messages to the standard error output. They
439 * are forwarded to the libgeda logging mechanism.
441 * Private function used only in s_clib.c.
443 * \todo This is probably generally useful.
445 * \param command Command string to execute.
446 * \return The program's output, or \b NULL on failure.
448 static gchar *run_source_command (const gchar *command)
450 gchar *standard_output = NULL;
451 gchar *standard_error = NULL;
452 gint exit_status;
453 GError *e = NULL;
454 gboolean success = FALSE;
456 g_return_val_if_fail((command != NULL), NULL);
458 g_spawn_command_line_sync (command,
459 &standard_output,
460 &standard_error,
461 &exit_status,
462 &e);
464 if (e != NULL) {
465 s_log_message (_("Library command failed [%s]: %s\n"), command,
466 e->message);
467 g_error_free (e);
469 } else if (WIFSIGNALED(exit_status)) {
470 s_log_message (_("Library command failed [%s]: Uncaught signal %i.\n"),
471 command, WTERMSIG(exit_status));
473 } else if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status)) {
474 s_log_message (_("Library command failed [%s]\n"), command);
475 s_log_message(_("Error output was:\n%s\n"), standard_error);
477 } else {
478 success = TRUE;
481 /* forward library command messages */
482 if (success && standard_error != NULL)
483 s_log_message ("%s", standard_error);
485 g_free (standard_error);
487 if (success) return standard_output;
489 g_free (standard_output);
490 return NULL;
493 /*! \brief Get a list of available component sources.
494 * \par Function Description
495 * Gets the current list of sources.
496 * \warning The GList returned should be freed when no longer
497 * needed. The returned value is not guaranteed to remain valid over
498 * calls to s_clib_add_directory() or s_clib_add_command().
499 * \return A \b GList of CLibSource.
501 GList *s_clib_get_sources (const gboolean sorted)
503 GList *l = g_list_copy(clib_sources);
504 if (sorted) {
505 l = g_list_sort (l, (GCompareFunc) compare_source_name);
507 return l;
510 /*! \brief Find any symbols within a source with a given name.
511 * \par Function Description
512 * Iterates through the symbol list of the given source, checking if
513 * there is already a symbol with the given name. If there is
514 * such a symbol, it is returned.
516 * \param source The source to check.
517 * \param name The symbol name to look for.
518 * \return The matching symbol, or \b NULL if no match was found.
520 static CLibSymbol *source_has_symbol (const CLibSource *source,
521 const gchar *name)
523 GList *symlist;
524 CLibSymbol *symbol;
526 for (symlist = g_list_first(source->symbols);
527 symlist != NULL;
528 symlist = g_list_next(symlist)) {
530 symbol = (CLibSymbol *) symlist->data;
532 if (strcmp (symbol->name, name) == 0) return symbol;
535 return NULL;
538 /*! \brief Make sure a source name is unique.
539 * \par Function Description
540 * Checks if a source already exists with the given \a name. If one
541 * does, appends a number to the source name. If \a name is not
542 * already in use, returns it as is. The return value is always a
543 * newly-allocated string, and should be freed.
544 * it.
546 static gchar *uniquify_source_name (const gchar *name)
548 gchar *newname = NULL;
549 gint i = 0;
551 if (s_clib_get_source_by_name (name) == NULL) {
552 return g_strdup (name);
555 do {
556 g_free (newname);
557 i++;
558 newname = g_strdup_printf ("%s<%i>", name, i);
559 } while (s_clib_get_source_by_name (newname) != NULL);
561 s_log_message (_("Library name [%s] already in use. Using [%s].\n"),
562 name, newname);
564 return newname;
567 /*! \brief Rescan a directory for symbols.
568 * \par Function Description
569 * Rescans a directory for symbols.
571 * \todo Does this need to do something more sane with subdirectories
572 * than just skipping them silently?
574 * Private function used only in s_clib.c.
576 static void refresh_directory (CLibSource *source)
578 CLibSymbol *symbol;
579 GDir *dir;
580 const gchar *entry;
581 gchar *low_entry;
582 gchar *fullpath;
583 gboolean isfile;
584 GError *e = NULL;
586 g_return_if_fail (source != NULL);
587 g_return_if_fail (source->type == CLIB_DIR);
589 s_clib_begin_update ();
591 /* Clear the current symbol list */
592 g_list_foreach (source->symbols, (GFunc) free_symbol, NULL);
593 g_list_free (source->symbols);
594 source->symbols = NULL;
596 /* Open the directory for reading. */
597 dir = g_dir_open (source->directory, 0, &e);
599 if (e != NULL) {
600 s_log_message (_("Failed to open directory [%s]: %s\n"),
601 source->directory, e->message);
602 g_error_free (e);
603 return;
606 while ((entry = g_dir_read_name (dir)) != NULL) {
607 /* skip ".", ".." & hidden files */
608 if (entry[0] == '.') continue;
610 /* skip subdirectories (for now) */
611 fullpath = g_build_filename (source->directory, entry, NULL);
612 isfile = g_file_test (fullpath, G_FILE_TEST_IS_REGULAR);
613 g_free (fullpath);
614 if (!isfile) continue;
616 /* skip filenames that we already know about. */
617 if (source_has_symbol (source, entry) != NULL) continue;
619 /* skip filenames which don't have the right suffix. */
620 low_entry = g_utf8_strdown (entry, -1);
621 if (!g_str_has_suffix (low_entry, SYM_FILENAME_FILTER)) {
622 g_free (low_entry);
623 continue;
625 g_free (low_entry);
627 /* Create and add new symbol record */
628 symbol = g_new0 (CLibSymbol, 1);
629 symbol->source = source;
630 symbol->name = g_strdup(entry);
632 /* Prepend because it's faster and it doesn't matter what order we
633 * add them. */
634 source->symbols = g_list_prepend (source->symbols, symbol);
637 entry = NULL;
638 g_dir_close (dir);
640 /* Now sort the list of symbols by name. */
641 source->symbols = g_list_sort (source->symbols,
642 (GCompareFunc) compare_symbol_name);
644 s_clib_flush_search_cache();
645 s_clib_flush_symbol_cache();
648 /*! \brief Re-poll a library command for symbols.
649 * \par Function Description
650 * Runs a library command, requesting a list of available symbols,
651 * and updates the source with the new list.
653 * Private function used only in s_clib.c.
655 static void refresh_command (CLibSource *source)
657 gchar *cmdout;
658 TextBuffer *tb;
659 const gchar *line;
660 CLibSymbol *symbol;
661 gchar *name;
663 g_return_if_fail (source != NULL);
664 g_return_if_fail (source->type == CLIB_CMD);
666 s_clib_begin_update ();
668 /* Clear the current symbol list */
669 g_list_foreach (source->symbols, (GFunc) free_symbol, NULL);
670 g_list_free (source->symbols);
671 source->symbols = NULL;
673 /* Run the command to get the list of symbols */
674 cmdout = run_source_command (source->list_cmd);
675 if (cmdout == NULL) return;
677 /* Use a TextBuffer to help reading out the lines of the output */
678 tb = s_textbuffer_new (cmdout, -1);
680 while (1) {
681 line = s_textbuffer_next_line (tb);
682 if (line == NULL) break;
683 if (line[0] == '.') continue; /* TODO is this sane? */
685 name = remove_nl(g_strdup(line));
687 /* skip symbols already known about */
688 if (source_has_symbol (source, name) != NULL) {
689 g_free (name);
690 continue;
693 symbol = g_new0 (CLibSymbol, 1);
694 symbol->source = source;
695 symbol->name = name;
697 /* Prepend because it's faster and it doesn't matter what order we
698 * add them. */
699 source->symbols = g_list_prepend (source->symbols, symbol);
702 s_textbuffer_free (tb);
703 g_free (cmdout);
705 /* Sort all symbols by name. */
706 source->symbols = g_list_sort (source->symbols,
707 (GCompareFunc) compare_symbol_name);
709 s_clib_flush_search_cache();
710 s_clib_flush_symbol_cache();
713 /*! \brief Re-poll a scheme procedure for symbols.
714 * \par Function Description
715 * Calls a Scheme procedure to obtain a list of available symbols,
716 * and updates the source with the new list
718 * Private function used only in s_clib.c.
720 static void refresh_scm (CLibSource *source)
722 SCM symlist;
723 SCM symname;
724 CLibSymbol *symbol;
725 char *tmp;
727 g_return_if_fail (source != NULL);
728 g_return_if_fail (source->type == CLIB_SCM);
730 s_clib_begin_update ();
732 /* Clear the current symbol list */
733 g_list_foreach (source->symbols, (GFunc) free_symbol, NULL);
734 g_list_free (source->symbols);
735 source->symbols = NULL;
737 symlist = scm_call_0 (source->list_fn);
739 if (!scm_is_pair (symlist) && !scm_is_null (symlist)) {
740 s_log_message (_("Failed to scan library [%s]: Scheme function returned non-list\n"),
741 source->name);
742 return;
745 while (!scm_is_null (symlist)) {
746 symname = SCM_CAR (symlist);
747 if (!scm_is_string (symname)) {
748 s_log_message (_("Non-string symbol name while scanning library [%s]\n"),
749 source->name);
750 } else {
751 symbol = g_new0 (CLibSymbol, 1);
752 symbol->source = source;
754 /* Need to make sure that the correct free() function is called
755 * on strings allocated by Guile. */
756 tmp = scm_to_utf8_string (symname);
757 symbol->name = g_strdup(tmp);
758 free (tmp);
760 /* Prepend because it's faster and it doesn't matter what order we
761 * add them. */
762 source->symbols = g_list_prepend (source->symbols, symbol);
765 symlist = SCM_CDR (symlist);
768 /* Now sort the list of symbols by name. */
769 source->symbols = g_list_sort (source->symbols,
770 (GCompareFunc) compare_symbol_name);
772 s_clib_flush_search_cache();
773 s_clib_flush_symbol_cache();
776 /*! \brief Rescan all available component libraries.
777 * \par Function Description
778 * Resets the list of symbols available from each source, and
779 * repopulates it from scratch. Useful e.g. for checking for new
780 * symbols.
782 void s_clib_refresh ()
784 GList *sourcelist;
785 CLibSource *source;
787 for (sourcelist = clib_sources;
788 sourcelist != NULL;
789 sourcelist = g_list_next(sourcelist)) {
791 source = (CLibSource *) sourcelist->data;
792 switch (source->type)
794 case CLIB_DIR:
795 refresh_directory(source);
796 break;
797 case CLIB_CMD:
798 refresh_command (source);
799 break;
800 case CLIB_SCM:
801 refresh_scm (source);
802 break;
803 default:
804 g_critical("s_clib_refresh: source %p has bad source type %i\n",
805 source, (gint) source->type);
806 break;
810 s_clib_end_update ();
813 /*! \brief Get a named component source.
814 * \par Function Description
815 * Iterates through the known component sources, checking if there is
816 * a source with the given \a name.
818 * \param name The source name to look for.
820 * \return The matching source, or \b NULL if no match was found.
822 const CLibSource *s_clib_get_source_by_name (const gchar *name)
824 GList *sourcelist;
825 CLibSource *source;
827 for (sourcelist = clib_sources;
828 sourcelist != NULL;
829 sourcelist = g_list_next(sourcelist)) {
831 source = (CLibSource *) sourcelist->data;
832 if (strcmp (source->name, name) == 0) {
833 return source;
837 return NULL;
840 /*! \brief Add a directory of symbol files to the library
841 * \par Function Description
842 * Adds a directory containing symbol files to the library. Only
843 * files ending with #SYM_FILENAME_FILTER are considered to be symbol
844 * files. A \a name may be specified for the source; if \a name is
845 * \b NULL, the basename of the directory as returned by
846 * g_path_get_basename() is used.
848 * \param directory The path of the directory to add.
849 * \param name A descriptive name for the directory.
850 * \return The #CLibSource associated with the directory.
852 const CLibSource *s_clib_add_directory (const gchar *directory,
853 const gchar *name)
855 CLibSource *source;
856 gchar *intname, *realname;
858 if (directory == NULL) {
859 return NULL;
862 if (name == NULL) {
863 intname = g_path_get_basename (directory);
864 realname = uniquify_source_name (intname);
865 g_free (intname);
866 } else {
867 realname = uniquify_source_name (name);
870 source = g_new0 (CLibSource, 1);
871 source->type = CLIB_DIR;
872 source->directory = g_strdup (directory);
873 source->name = realname;
875 refresh_directory (source);
877 /* Sources added later get scanned earlier */
878 clib_sources = g_list_prepend (clib_sources, source);
880 return source;
883 /*! \brief Add symbol-generating commands to the library
884 * \par Function Description
885 * Adds a set of commands which can generate symbols to the
886 * library. \a list_cmd and \a get_cmd should be strings consisting
887 * of an executable name followed by any arguments required.
888 * Executables are resolved using the current PATH. See page \ref
889 * libcmds for more information on library commands.
891 * \param list_cmd The executable & arguments used to list available
892 * symbols.
893 * \param get_cmd The executable & arguments used to retrieve symbol
894 * data.
895 * \param name A descriptive name for the component source.
896 * \return The CLibSource associated with the component source.
898 const CLibSource *s_clib_add_command (const gchar *list_cmd,
899 const gchar *get_cmd,
900 const gchar *name)
902 CLibSource *source;
903 gchar *realname;
905 if (name == NULL) {
906 s_log_message (_("Cannot add library: name not specified\n"));
907 return NULL;
910 realname = uniquify_source_name (name);
912 if (list_cmd == NULL || get_cmd == NULL) {
913 s_log_message (_("Cannot add library [%s]: both 'list' and "
914 "'get' commands must be specified.\n"),
915 realname);
918 source = g_new0 (CLibSource, 1);
919 source->type = CLIB_CMD;
920 source->name = realname;
922 source->list_cmd = g_strdup (list_cmd);
923 source->get_cmd = g_strdup (get_cmd);
925 refresh_command (source);
927 /* Sources added later get sacnned earlier */
928 clib_sources = g_list_prepend (clib_sources, source);
930 return source;
933 /*! \brief Add symbol-generating Scheme procedures to the library.
934 * \par Function Description
935 * Adds a source to the library based on Scheme procedures. See page
936 * \ref libscms for more information. Two procedures are required: \a
937 * listfunc must return a Scheme list of symbol names, and \a getfunc
938 * must return a string containing symbol data when passed a symbol
939 * name.
941 * \param listfunc A Scheme function returning a list of symbols.
942 * \param getfunc A Scheme function returning symbol data.
943 * \param name A descriptive name for the component source.
945 * \return The new CLibSource.
947 const CLibSource *s_clib_add_scm (SCM listfunc, SCM getfunc, const gchar *name)
949 CLibSource *source;
950 gchar *realname;
952 if (name == NULL) {
953 s_log_message (_("Cannot add library: name not specified\n"));
954 return NULL;
957 realname = uniquify_source_name (name);
959 if (scm_is_false (scm_procedure_p (listfunc))
960 && scm_is_false (scm_procedure_p (getfunc))) {
961 s_log_message (_("Cannot add Scheme-library [%s]: callbacks must be closures\n"),
962 realname);
963 return NULL;
966 source = g_new0 (CLibSource, 1);
967 source->type = CLIB_SCM;
968 source->name = realname;
969 source->list_fn = scm_gc_protect_object (listfunc);
970 source->get_fn = scm_gc_protect_object (getfunc);
972 refresh_scm (source);
974 clib_sources = g_list_prepend (clib_sources, source);
976 return source;
979 /*! \brief Get the name of a source.
980 * \par Function Description
981 * Get the name of a source for use e.g. in displaying a GUI.
983 * \param source Source to be examined.
984 * \return Name of source.
986 const gchar *s_clib_source_get_name (const CLibSource *source)
988 if (source == NULL) return NULL;
989 return source->name;
992 /*! \brief Get a list of symbols available from a given source.
993 * \par Function Description
994 * Get a \b GList containing all of the symbols available from \a
995 * source.
997 * \warning The returned \b GList will not be consistent over a call to
998 * s_clib_refresh(). It should be freed when no longer needed.
1000 * \param source Source to be examined.
1001 * \return A \b GList of #CLibSymbol.
1003 GList *s_clib_source_get_symbols (const CLibSource *source)
1005 if (source == NULL) return NULL;
1006 return g_list_copy(source->symbols);
1010 /*! \brief Get the name of a symbol.
1011 * \par Function Description
1012 * Get the name of a symbol. The symbol name uniquely identifies it
1013 * to libgeda.
1015 * \param symbol Symbol to be examined.
1016 * \return Name of symbol.
1018 const gchar *s_clib_symbol_get_name (const CLibSymbol *symbol)
1020 if (symbol == NULL) return NULL;
1021 return symbol->name;
1024 /*! \brief Get a filename for editing a symbol.
1025 * \par Function Description
1026 * Get the filename of the file a symbol was loaded from, if possible
1027 * (e.g. to allow loading for user editing).
1029 * \warning The returned string should be freed when no longer
1030 * needed.
1032 * \todo This is hack until there is a way to edit documents in
1033 * gschem which do not have a file in the filesystem associated with
1034 * them.
1036 * \deprecated This function is a temporary workaround.
1038 * \param symbol Symbol to be examined.
1039 * \return Filename of symbol.
1041 gchar *s_clib_symbol_get_filename (const CLibSymbol *symbol)
1043 if (symbol == NULL) return NULL;
1045 if (symbol->source->type != CLIB_DIR) return NULL;
1047 return g_build_filename(symbol->source->directory, symbol->name, NULL);
1050 const gchar *s_clib_source_get_directory (const CLibSource *source)
1052 if (source->type != CLIB_DIR)
1053 return NULL;
1055 return source->directory;
1058 /*! \brief Get the source to which a symbol belongs.
1059 * \par Function Description
1060 * Get the source which a symbol is associated.
1062 * \param symbol Symbol to be examined.
1063 * \return Source which owns symbol.
1065 const CLibSource *s_clib_symbol_get_source (const CLibSymbol *symbol)
1067 if (symbol == NULL) return NULL;
1068 return symbol->source;
1071 /*! \brief Get symbol data from a directory source.
1072 * \par Function Description
1073 * Get symbol data from a directory data source. The return value
1074 * should be free()'d when no longer needed.
1076 * Private function used only in s_clib.c.
1078 * \param symbol Symbol to get data for.
1079 * \return Allocated buffer containing symbol data.
1081 static gchar *get_data_directory (const CLibSymbol *symbol)
1083 gchar *filename = NULL;
1084 gchar *data = NULL;
1085 GError *e = NULL;
1087 g_return_val_if_fail ((symbol != NULL), NULL);
1088 g_return_val_if_fail ((symbol->source->type == CLIB_DIR), NULL);
1090 filename = g_build_filename(symbol->source->directory,
1091 symbol->name, NULL);
1093 g_file_get_contents (filename, &data, NULL, &e);
1095 if (e != NULL) {
1096 s_log_message (_("Failed to load symbol from file [%s]: %s\n"),
1097 filename, e->message);
1098 g_error_free (e);
1101 g_free (filename);
1102 return data;
1105 /*! \brief Get symbol data from a library command.
1106 * \par Function Description
1107 * Get symbol data from a library command. The return value should
1108 * be free()'d when no longer needed.
1110 * Private function used only in s_clib.c.
1112 * \param symbol Symbol to get data for.
1113 * \return Allocated buffer containing symbol data.
1115 static gchar *get_data_command (const CLibSymbol *symbol)
1117 gchar *command;
1118 gchar *result;
1120 g_return_val_if_fail ((symbol != NULL), NULL);
1121 g_return_val_if_fail ((symbol->source->type == CLIB_CMD), NULL);
1123 command = g_strdup_printf ("%s %s", symbol->source->get_cmd,
1124 symbol->name);
1126 result = run_source_command ( command );
1128 g_free (command);
1130 return result;
1133 /*! \brief Get symbol data from a Scheme-based component source.
1134 * \par Function Description
1135 * Get symbol data from a Scheme-based component source. The return
1136 * value should be free()'d when no longer needed.
1138 * Private function used only in s_clib.c.
1140 * \param symbol Symbol to get data for.
1141 * \return Allocated buffer containing symbol data.
1143 static gchar *get_data_scm (const CLibSymbol *symbol)
1145 SCM symdata;
1146 char *tmp;
1147 gchar *result;
1149 g_return_val_if_fail ((symbol != NULL), NULL);
1150 g_return_val_if_fail ((symbol->source->type == CLIB_SCM), NULL);
1152 symdata = scm_call_1 (symbol->source->get_fn,
1153 scm_from_utf8_string (symbol->name));
1155 if (!scm_is_string (symdata)) {
1156 s_log_message (_("Failed to load symbol data [%s] from source [%s]\n"),
1157 symbol->name, symbol->source->name);
1158 return NULL;
1161 /* Need to make sure that the correct free() function is called
1162 * on strings allocated by Guile. */
1163 tmp = scm_to_utf8_string (symdata);
1164 result = g_strdup(tmp);
1165 free (tmp);
1167 return result;
1170 /*! \brief Get symbol data.
1171 * \par Function Description
1172 * Get the unparsed gEDA-format data corresponding to a symbol from
1173 * the symbol's data source. The return value should be free()'d
1174 * when no longer needed.
1176 * On failure, returns \b NULL (the error will be logged).
1178 * \param symbol Symbol to get data for.
1179 * \return Allocated buffer containing symbol data.
1181 gchar *s_clib_symbol_get_data (const CLibSymbol *symbol)
1183 CacheEntry *cached;
1184 gchar *data;
1185 gpointer symptr;
1186 gint n;
1188 g_return_val_if_fail ((symbol != NULL), NULL);
1189 g_return_val_if_fail ((symbol->source != NULL), NULL);
1191 /* Trickery to bypass effects of const */
1192 symptr = (gpointer) symbol;
1194 /* First, try the cache. */
1195 cached = g_hash_table_lookup (clib_symbol_cache, symptr);
1196 if (cached != NULL) {
1197 cached->accessed = time(NULL);
1198 return g_strdup(cached->data);
1201 /* If the symbol wasn't found in the cache, get it directly. */
1202 switch (symbol->source->type)
1204 case CLIB_DIR:
1205 data = get_data_directory (symbol);
1206 break;
1207 case CLIB_CMD:
1208 data = get_data_command (symbol);
1209 break;
1210 case CLIB_SCM:
1211 data = get_data_scm (symbol);
1212 break;
1213 default:
1214 g_critical("s_clib_symbol_get_data: source %p has bad source type %i\n",
1215 symbol->source, (gint) symbol->source->type);
1216 return NULL;
1219 if (data == NULL) return NULL;
1221 /* Cache the symbol data */
1222 cached = g_new (CacheEntry, 1);
1223 cached->ptr = (CLibSymbol *) symptr;
1224 cached->data = g_strdup (data);
1225 cached->accessed = time (NULL);
1226 g_hash_table_insert (clib_symbol_cache, symptr, cached);
1228 /* Clean out the cache if it's too full */
1229 n = g_hash_table_size (clib_symbol_cache);
1230 if (n > CLIB_MAX_SYMBOL_CACHE) {
1231 for ( ; n > CLIB_MIN_SYMBOL_CACHE; n--) {
1232 g_hash_table_foreach (clib_symbol_cache,
1233 (GHFunc) cache_find_oldest,
1234 &cached);
1235 g_hash_table_remove (clib_symbol_cache, cached->ptr);
1239 return data;
1242 /*! \brief Find all symbols matching a pattern.
1244 * \par Function Description
1245 * Searches the library, returning all symbols whose
1246 * names match \a pattern.
1248 * Two search modes are available: \b CLIB_EXACT, where \a pattern is
1249 * compared to the symbol name using strcmp(), and \b CLIB_GLOB,
1250 * where \a pattern is assumed to be a glob pattern (see the GLib
1251 * documentation for details of the glob syntax applicable).
1253 * \warning The #CLibSymbol instances in the \b GList returned belong
1254 * to the component library, and should be considered constants; they
1255 * should not be manipulated or free()'d. On the other hand, the \b
1256 * GList returned must be freed with \b g_list_free() when no longer
1257 * needed. Note that the values returned will be invalidated by a
1258 * call to s_clib_free() or s_clib_refresh().
1260 * \param pattern The pattern to match against.
1261 * \param mode The search mode to use.
1262 * \return A \b GList of matching #CLibSymbol structures.
1264 GList *s_clib_search (const gchar *pattern, const CLibSearchMode mode)
1266 GList *sourcelist;
1267 GList *symlist;
1268 GList *result = NULL;
1269 CLibSource *source;
1270 CLibSymbol *symbol;
1271 GPatternSpec *globpattern = NULL;
1272 gchar *key;
1273 gchar keytype;
1275 if (pattern == NULL) return NULL;
1277 /* Use different cache keys depending on what sort of search is being done */
1278 switch (mode)
1280 case CLIB_GLOB:
1281 keytype = 'g';
1282 break;
1283 case CLIB_EXACT:
1284 keytype = 's';
1285 break;
1286 default:
1287 g_critical ("s_clib_search: Bad search mode %i\n", mode);
1288 return NULL;
1290 key = g_strdup_printf("%c%s", keytype, pattern);
1292 /* Check to see if the query is already in the cache */
1293 result = (GList *) g_hash_table_lookup (clib_search_cache, key);
1294 if (result != NULL) {
1295 g_free (key);
1296 return g_list_copy (result);
1299 if (mode == CLIB_GLOB) {
1300 globpattern = g_pattern_spec_new(pattern);
1303 for (sourcelist = clib_sources;
1304 sourcelist != NULL;
1305 sourcelist = g_list_next(sourcelist)) {
1307 source = (CLibSource *) sourcelist->data;
1309 for (symlist = source->symbols;
1310 symlist != NULL;
1311 symlist = g_list_next(symlist)) {
1313 symbol = (CLibSymbol *) symlist->data;
1315 switch (mode)
1317 case CLIB_EXACT:
1318 if (strcmp (pattern, symbol->name) == 0) {
1319 result = g_list_prepend (result, symbol);
1321 break;
1322 case CLIB_GLOB:
1323 if (g_pattern_match_string (globpattern, symbol->name)) {
1324 result = g_list_prepend (result, symbol);
1326 break;
1331 result = g_list_reverse (result);
1333 if (globpattern != NULL) {
1334 g_pattern_spec_free (globpattern);
1337 g_hash_table_insert (clib_search_cache, key, g_list_copy (result));
1338 /* __don't__ free key here, it's stored by the hash table! */
1340 return result;
1346 /*! \brief Flush the symbol name lookup cache.
1347 * \par Function Description
1348 * Clears the hashtable which caches the results of s_clib_search().
1349 * You shouldn't ever need to call this, as all functions which
1350 * invalidate the cache are supposed to make sure it's flushed.
1352 void s_clib_flush_search_cache ()
1354 g_hash_table_remove_all (clib_search_cache); /* Introduced in glib 2.12 */
1358 /*! \brief Flush the symbol data cache.
1359 * \par Function Description
1360 * Clears the hashtable which caches the results of s_clib_symbol_get_data().
1361 * You shouldn't ever need to call this, as all functions which
1362 * invalidate the cache are supposed to make sure it's flushed.
1364 void s_clib_flush_symbol_cache ()
1366 g_hash_table_remove_all (clib_symbol_cache); /* Introduced in glib 2.12 */
1369 /*! \brief Invalidate all cached data about a symbol.
1370 * \par Function Description
1371 * Removes all cached symbol data for \a symbol.
1373 * \param symbol Symbol to flush cached data for.
1375 void
1376 s_clib_symbol_invalidate_data (const CLibSymbol *symbol)
1378 g_hash_table_remove (clib_symbol_cache, (gpointer) symbol);
1381 /*! \brief Get symbol structure for a given symbol name.
1382 * \par Function Description
1383 * Return the first symbol found with the given \a name. If more
1384 * than one matching symbol is found or no matches are found at all,
1385 * emits a log message warning the user.
1387 * \param name The symbol name to match against.
1388 * \return The first matching symbol, or NULL if none found.
1390 const CLibSymbol *s_clib_get_symbol_by_name (const gchar *name)
1392 GList *symlist = NULL;
1393 const CLibSymbol *retval;
1395 symlist = s_clib_search (name, CLIB_EXACT);
1397 if (symlist == NULL) {
1398 s_log_message (_("Component [%s] was not found in the component library\n"),
1399 name);
1400 return NULL;
1403 if (g_list_next (symlist) != NULL) { /* More than one symbol */
1404 s_log_message (_("More than one component found with name [%s]\n"),
1405 name);
1408 retval = (CLibSymbol *) symlist->data;
1409 g_list_free (symlist);
1411 return retval;
1414 /*! \brief Get symbol data for a given symbol name.
1415 * \par Function Description
1416 * Return the data for the first symbol found with the given name.
1417 * This is a helper function for the schematic load system, as it
1418 * will always want to load symbols given only their name.
1420 * On failure, returns \b NULL (the error will be logged).
1422 * \param name The symbol name to match against.
1423 * \return Allocated buffer containing symbol data.
1425 gchar *s_clib_symbol_get_data_by_name (const gchar *name)
1427 const CLibSymbol *symbol;
1429 symbol = s_clib_get_symbol_by_name (name);
1430 if (symbol == NULL) return NULL;
1431 return s_clib_symbol_get_data (symbol);
1434 /*! \brief Get a list of symbols used.
1435 * \par Function Description
1437 * Scan a #TOPLEVEL structure's object list looking for symbols, and
1438 * return them in a list.
1440 * \warning The #CLibSymbol instances in the \b GList returned belong
1441 * to the component library, and should be considered constants; they
1442 * should not be manipulated or free()'d. On the other hand, the \b
1443 * GList returned must be freed with \b g_list_free() when no longer
1444 * needed. Note that the values returned will be invalidated by a
1445 * call to s_clib_free() or s_clib_refresh().
1447 * \bug Only includes components which are not embedded, but they
1448 * should (probably) also appear in the list.
1450 * \param toplevel #TOPLEVEL structure to scan.
1451 * \return GList of symbols.
1453 GList *s_toplevel_get_symbols (const TOPLEVEL *toplevel)
1455 GList *result = NULL;
1456 GList *iter = NULL;
1457 OBJECT *o = NULL;
1458 PAGE *page;
1459 GList *symlist = NULL;
1460 CLibSymbol *sym = NULL;
1461 const GList *p_iter;
1462 const GList *o_iter;
1464 g_return_val_if_fail ((toplevel != NULL), NULL);
1466 for ( p_iter = geda_list_get_glist( toplevel->pages );
1467 p_iter != NULL;
1468 p_iter = g_list_next( p_iter )) {
1469 page = (PAGE *)p_iter->data;
1470 for (o_iter = s_page_objects (page);
1471 o_iter != NULL;
1472 o_iter = g_list_next (o_iter)) {
1473 o = (OBJECT *)o_iter->data;
1474 if (o->type != OBJ_COMPLEX) continue;
1475 if (o->complex_basename == NULL) continue;
1477 /* Since we're not looking at embedded symbols, the first
1478 * component with the given name will be the one we need.
1479 * N.b. we don't use s_clib_get_symbol_by_name() because it's
1480 * spammeh. */
1481 symlist = s_clib_search (o->complex_basename, CLIB_EXACT);
1482 if (symlist == NULL) continue;
1483 sym = (CLibSymbol *) symlist->data;
1484 g_list_free (symlist);
1486 /* We do the list insertion by evilly comparing pointers. This
1487 * is okay, because we always take the first symbol with the
1488 * given name, and symbol pointers don't change while this
1489 * function is running (we hope). Note that this creates a
1490 * sorted list.*/
1491 for (iter = result;
1492 iter != NULL;
1493 iter = g_list_next(iter)) {
1494 if (iter->data == sym) {
1495 break; /* Already in list */
1497 if (compare_symbol_name (iter->data, sym) > 0) {
1498 /* not in list yet, and gone past point where it should go */
1499 result = g_list_insert_before (result, iter, sym);
1500 break;
1503 if (iter == NULL) {
1504 /* not in list yet, and at end of list */
1505 result = g_list_append (result, sym);
1510 return result;
1515 /*! \brief A marshaller for a GCClosure with a callback of type
1516 * `void (*callback) (gpointer user_data)`.
1518 static void
1519 update_marshal (GClosure *closure,
1520 GValue *return_value,
1521 guint n_param_values,
1522 const GValue *param_values,
1523 gpointer invocation_hint,
1524 gpointer marshal_data)
1526 GCClosure *cclosure = (GCClosure *) closure;
1527 g_return_if_fail (n_param_values == 0);
1529 typedef void (*marshal_func) (gpointer data);
1530 marshal_func callback = (marshal_func) (marshal_data ? marshal_data
1531 : cclosure->callback);
1532 callback (closure->data);
1535 void s_clib_add_update_callback (void (*update) (gpointer user_data),
1536 gpointer user_data)
1538 GClosure *closure = g_cclosure_new (G_CALLBACK (update), user_data, NULL);
1539 g_closure_set_marshal (closure, update_marshal);
1541 s_clib_update_closures = g_list_append (s_clib_update_closures, closure);
1542 g_closure_ref (closure);
1543 g_closure_sink (closure);
1546 void s_clib_remove_update_callback (gpointer user_data)
1548 for (GList *l = s_clib_update_closures; l != NULL; l = l->next) {
1549 GClosure *closure = (GClosure *) l->data;
1550 if (closure->data != user_data)
1551 continue;
1553 s_clib_update_closures = g_list_remove (s_clib_update_closures, closure);
1554 g_closure_unref (closure);
1555 break;
1559 void s_clib_begin_update ()
1561 s_clib_updating = TRUE;
1564 void s_clib_end_update ()
1566 if (!s_clib_updating)
1567 return;
1568 s_clib_updating = FALSE;
1570 for (GList *l = s_clib_update_closures; l != NULL; l = l->next)
1571 g_closure_invoke ((GClosure *) l->data, NULL, 0, NULL, NULL);