Copied in new updated Italian translation from Michele Petrecca. Thanks.
[geda-gaf/peter-b.git] / libgeda / src / s_clib.c
blobc1ec6cba8dec6e21ca7a19c87d217bbd21fbaf51
1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2000 Ales V. Hvezda
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
19 /*! \file s_clib.c
20 * <B>clib</B> stands for component library.
22 * A component library is made of several directories gathering
23 * component files.
25 * It must first be initialized with #s_clib_init(). When it is no more
26 * useful, use #s_clib_free() to free memory and reset the component
27 * library.
29 * To add a directory to the library, use #s_clib_add_directory().
31 * To retrieve a list of the directories that make the library, use
32 * #s_clib_get_directories(). For a list of component files in a
33 * directory of the library, use #s_clib_get_files().
35 * #s_clib_search_basename() let you find a specific component from
36 * its name. Please note that it returns a list of directories as there
37 * may be several places that contains a component with this name.
40 #include <config.h>
42 #include <glib.h>
44 #ifdef HAVE_STRING_H
45 #include <string.h>
46 #endif
48 #ifdef HAVE_LIBDMALLOC
49 #include <dmalloc.h>
50 #endif
52 #include "defines.h"
55 void s_clib_free (void);
57 static GList *clib_directories = NULL;
59 static GHashTable *clib_cache = NULL;
61 /*! \brief Initializes the component library handling code.
62 * \par Function Description
63 * Initializes the component library handling code.
64 * \warning This function must be called before any other function
65 * of this file.
67 void s_clib_init (void)
69 if (clib_directories != NULL || clib_cache != NULL) {
70 s_clib_free ();
73 clib_cache = g_hash_table_new (g_str_hash, g_str_equal);
77 /*! \todo Finish function documentation!!!
78 * \brief
79 * \par Function Description
82 static void clib_free_cache_entry (gpointer key, gpointer value,
83 gpointer user_data)
85 g_free (key);
86 if (value != NULL) {
87 /* value is a singly-linked list of strings */
88 g_list_foreach (value, (GFunc)g_free, NULL);
89 g_slist_free ((GSList*)value);
93 /*! \brief Frees memory used by the component library.
94 * \par Function Description
95 * Frees memory used by the component library.
97 void s_clib_free (void)
99 if (clib_directories != NULL) {
100 g_list_foreach (clib_directories, (GFunc)g_free, NULL);
101 g_list_free (clib_directories);
102 clib_directories = NULL;
105 if (clib_cache != NULL) {
106 g_hash_table_foreach (clib_cache, clib_free_cache_entry, NULL);
107 g_hash_table_destroy (clib_cache);
108 clib_cache = NULL;
113 /*! \brief Adds a new directory to the component library.
114 * \par Function Description
115 * Adds <B>directory</B> as a new directory for the component library.
117 * \param [in] directory Character string with the new directory name.
119 void s_clib_add_directory (const gchar *directory)
121 /* search for directory in clib_directories */
122 if (!g_list_find_custom (clib_directories,
123 directory,
124 (GCompareFunc) g_strcasecmp))
126 /* directory not yet in the list of known directories */
127 /* add directory to list */
128 clib_directories = g_list_append (clib_directories,
129 g_strdup (directory));
134 /*! \brief Get list of component library directories.
135 * \par Function Description
136 * This function returns the list of directories part of
137 * the component library.
139 * \return Global libgead #clib_directories variable.
140 * \warning
141 * The returned value is owned by libgeda and must not be modified or freed.
144 const GList *s_clib_get_directories()
146 return clib_directories;
149 /*! \brief Get a list of files found a directory.
150 * \par Function Description
151 * This function returns a list of file names found in <B>directory</B> and
152 * that match <B>filter</B>
154 * \param [in] directory Character string with the path to search.
155 * \param [in] filter Character string to compare file names against.
156 * \return List of file name that matched <B>filter</B>, NULL otherwise.
158 GSList *s_clib_get_files (const gchar *directory, const gchar *filter)
160 GDir *dir;
161 const gchar *entry;
162 GSList *ret = NULL;
164 /* check directory is in clib_directories */
165 if (g_list_find_custom (clib_directories,
166 directory,
167 (GCompareFunc) g_strcasecmp) == NULL)
169 /* no, unknown directory: report an error */
170 s_log_message ("Directory [%s] is not part of the component library\n",
171 directory);
172 return NULL;
175 /* open the directory */
176 dir = g_dir_open (directory, 0, NULL);
177 if (dir == NULL) {
178 s_log_message ("Failed to open directory [%s]\n", directory);
179 return NULL;
182 /* now read the entire directory */
183 /* and build a list of filenames in directory that match filter */
184 while ((entry = g_dir_read_name (dir)) != NULL) {
185 /* skip .'s */
186 if (entry[0] == '.') {
187 continue;
190 /* identify filter-matching filenames */
191 if (strstr (entry, filter)) {
192 ret = g_slist_append (ret, (gpointer)g_strdup (entry));
197 /* finished: close the directory stream */
198 g_dir_close (dir);
200 /* sort the list alphabetically */
201 ret = g_slist_sort (ret, (GCompareFunc)g_strcasecmp);
203 /* and return the sorted list of filenames */
204 return ret;
207 /*! \brief Search for a symbol file in the component library.
208 * \par Function Description
209 * Searches in component library for a symbol file with name <B>basename</B>.
211 * \param [in] basename Character string with base symbol name to search for.
212 * \return List of directories where symbol file with this name was found,
213 * NULL otherwise.
215 * \warning
216 * The returned value is owned by libgeda and must not be modified or freed.
219 const GSList *s_clib_search_basename(const gchar *basename)
221 GSList *ret;
222 GList *tmp;
224 /* first check if basename is in cache */
225 ret = g_hash_table_lookup (clib_cache, basename);
226 if (ret != NULL) {
227 /* yes, found basename in cache, nothing more to do */
228 return ret;
231 /* looks like we have to search for basename in the library */
232 for (tmp = g_list_last(clib_directories);
233 tmp != NULL; tmp = g_list_previous (tmp)) {
234 gchar *dir_name = (gchar*)tmp->data;
235 gchar *file_name = g_strconcat (dir_name,
236 G_DIR_SEPARATOR_S,
237 basename,
238 NULL);
240 if (g_file_test (file_name, G_FILE_TEST_EXISTS)) {
241 /* add directory name to the list */
242 ret = g_slist_append (ret, g_strdup (dir_name));
245 g_free (file_name);
248 /* have we found something? */
249 if (ret != NULL) {
250 /* yes, add the result to cache */
251 g_hash_table_insert (clib_cache, g_strdup (basename), ret);
254 return ret;