Update README with new Automake requirement.
[geda-gaf.git] / libgeda / src / s_slib.c
blob5063dc1b6b54b38ba43882ea1527f7ab857e0a4e
1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 /*! slib stands for source (project/schematic/hdl/model source) library */
22 #include <config.h>
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <ctype.h>
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #endif
30 #ifdef HAVE_STRING_H
31 #include <string.h>
32 #endif
33 #include <dirent.h>
35 #include "libgeda_priv.h"
37 #ifdef HAVE_LIBDMALLOC
38 #include <dmalloc.h>
39 #endif
41 /* need to test everything at boundary conditions (exceed cache size etc...) */
43 /*! \brief */
44 struct st_slib {
45 char *dir_name;
48 /*! \brief */
49 static int slib_index=0;
51 /*! \brief */
52 #define MAX_SLIBS 128
54 /*! \brief
55 * and eventually make this unlimited
56 * hack hack
58 static struct st_slib slib[MAX_SLIBS];
60 /*! \todo Finish function documentation!!!
61 * \brief
62 * \par Function Description
65 int s_slib_add_entry(char *new_path)
67 if (new_path == NULL) {
68 return(-1);
71 if (slib_index >= MAX_SLIBS) {
72 return(-1);
75 slib[slib_index].dir_name = g_strdup (new_path);
77 slib_index++;
78 return(slib_index);
81 /*! \todo Finish function documentation!!!
82 * \brief
83 * \par Function Description
85 * \return 1 if directory is found, zero otherwise.
87 int s_slib_search_for_dirname(char *dir_name)
89 int i;
91 for (i = 0; i < slib_index; i++) {
92 if (strcmp(slib[i].dir_name, dir_name) == 0) {
93 return(1);
97 return(0);
100 /*! \todo Finish function documentation!!!
101 * \brief
102 * \par Function Description
104 * \warning
105 * Caller must g_free returned pointer.
107 char *s_slib_search_dirs(const char *basename)
109 int i;
110 DIR *ptr=NULL;
111 struct dirent *dptr;
112 char *slib_path=NULL;
114 /* search slib paths backwards */
115 for (i = slib_index-1 ; i >= 0; i--) {
116 /* for (i = 0 ; i < slib_index; i++) {*/
118 #if DEBUG
119 printf("searching: %d %s\n", i, slib[i].dir_name);
120 #endif
122 ptr = opendir(slib[i].dir_name);
124 g_return_val_if_fail ((ptr != NULL), NULL);
126 dptr = readdir(ptr);
128 while(dptr != NULL) {
130 /* Search for an exact match */
131 if (strcmp(dptr->d_name, basename) == NULL) {
132 slib_path = g_strdup (slib[i].dir_name);
134 if (ptr) {
135 closedir(ptr);
136 ptr = NULL;
139 return(slib_path);
141 dptr = readdir(ptr);
144 if (ptr) {
145 closedir(ptr);
146 ptr = NULL;
151 return(NULL);
154 /*! \todo Finish function documentation!!!
155 * \brief
156 * \par Function Description
158 * \warning
159 * Caller must g_free returned pointer.
161 char *s_slib_search_lowlevel(const char *basename)
163 char *slib_path=NULL;
164 char *full_path=NULL;
166 slib_path = s_slib_search_dirs(basename);
168 if (slib_path) {
169 full_path = g_build_filename (slib_path, basename, NULL);
171 g_free(slib_path);
173 return(full_path);
174 } else {
175 return(NULL);
179 /*! \todo Finish function documentation!!!
180 * \brief Get the base file name from a raw file name string.
181 * \par Function Description
182 * This function takes a raw file name and returns a processed file name.
183 * It takes the raw file name and copies everything up to the first period
184 * and removes any _# (where # is any number of digits.
186 * \param [in] rawname Character string with the raw file name to parse.
187 * \return The base file name in a character string.
189 * \warning
190 * Caller must g_free returned pointer.
192 char *s_slib_getbasename(const char *rawname)
194 char *return_filename;
195 int i;
196 int done=0;
197 int lastchar;
198 int valid=0;
199 int len;
200 int seen_underscore=0;
202 if (!rawname)
203 return(NULL);
205 len = strlen(rawname)+1;
207 return_filename = (char *) g_malloc(sizeof(char)*len);
209 i = 0;
210 /* first get everything up to the leading dot */
211 while(rawname[i] != '\0' && rawname[i] != '.') {
212 return_filename[i] = rawname[i];
213 i++;
217 return_filename[i] = '\0';
219 /* skip null terminator */
220 i--;
222 lastchar=i;
224 /* this is a quick and dirty state machine to */
225 /* go back and strip off any _#'s */
226 /* if there is a better way let me know */
227 while (i >= 0 && !done) {
229 /* first we need to check to see if we have seen the first '_' */
230 /* if we have then we already removing chars, continue with that */
231 if ( seen_underscore ) {
232 if (return_filename[i] == '_') {
233 done = 1;
236 return_filename[i] = '\0';
237 } else {
238 /* we are still searching for the first underscore */
240 /* first make sure char is a number */
241 if (isdigit((int) return_filename[i])) {
242 valid=1;
243 } else if (return_filename[i] == '_' && valid) {
244 /* yes it is okay to delete the chars */
245 seen_underscore=1;
246 /* incremented, since it is then */
247 /* decremented */
248 i = lastchar+1;
249 } else {
250 valid = 0;
251 done = 1;
255 i--;
258 /* be sure to g_free this somewhere */
259 return(return_filename);
262 /*! \todo Finish function documentation!!!
263 * \brief Search SLIB for a particular file name.
264 * \par Function Description
265 * This function will search the SLIB for a particular file name starting
266 * at a location specified by the <B>flag</B> parameter.
268 * \param [in] filename Character string with file name to search for.
270 * Filename is the raw symbol/whatever file name. This function only looks
271 * for the file name as is and does no other changes to it.
273 * \warning
274 * Caller must g_free returned pointer.
276 char *s_slib_search_single(const char *filename)
278 char *string=NULL;
280 string = s_slib_search_lowlevel(filename);
282 /* don't forget to g_free this string */
283 return(string);
286 /*! \todo Finish function documentation!!!
287 * \brief
288 * \par Function Description
291 void s_slib_free()
293 int i;
295 for (i = 0; i < slib_index; i++) {
296 g_free(slib[i].dir_name);
299 slib_index=0;
302 /*! \todo Finish function documentation!!!
303 * \brief
304 * \par Function Description
307 void s_slib_init()
309 int i;
310 for (i = 0; i < MAX_SLIBS; i++) {
311 slib[i].dir_name = NULL;
315 /*! \todo Finish function documentation!!!
316 * \brief
317 * \par Function Description
319 * \warning
320 * Caller must not free the returned pointer.
322 /* returns slibs */
323 char *s_slib_getdir(int index)
325 if (slib[index].dir_name != NULL)
326 return(slib[index].dir_name);
327 else
328 return(NULL);
331 /*! \todo Finish function documentation!!!
332 * \brief
333 * \par Function Description
335 * \param [in] directory Character string with directory to get files from.
336 * \param [in] flag Search control flag. (See below...)
337 * \return A file name if one is found, NULL otherwise.
339 * \warning
340 * Caller must g_free returned pointer.
342 * The flag parameter can be one of the following values:
343 * <DL>
344 * <DT>OPEN_DIR</DT><DD>Opens the directory and returns NULL.
345 * <DT>READ_DIR</DT><DD>Returns the next non "." entry.
346 * <DT>CLOSE_DIR</DT><DD>Closes the directory.
347 * </DL>
348 * \bug This is TOTTALLY BROKEN!
349 * statics are not allowed anymore
350 * \warning
351 * this function is not reentrant
353 char *s_slib_getfiles(char *directory, int flag)
355 static DIR *ptr;
356 static struct dirent *dptr;
357 static char *whole_dir[256]; /* make this dynamic hack */
358 static int count=0;
359 static int current=0;
361 int j;
363 switch(flag) {
365 case(CLOSE_DIR):
366 if (ptr) {
367 closedir(ptr);
370 ptr = NULL;
372 for (j = 0 ; j < count ;j++) {
373 g_free(whole_dir[j]);
375 count = current = 0 ;
377 return(NULL);
378 break;
380 /* open the directory and return first element (after if) */
381 case(OPEN_DIR):
383 if (ptr) {
384 closedir(ptr);
387 ptr = NULL;
389 for (j = 0 ; j < count ;j++) {
390 g_free(whole_dir[j]);
392 count = current = 0 ;
394 ptr = opendir(directory); /* hack check for existance */
396 if (ptr == NULL)
397 return(NULL);
400 /* now read the entire directory */
401 dptr = readdir(ptr);
403 while (dptr != NULL) {
405 /* skip .'s */
406 while (dptr != NULL) {
407 if (dptr->d_name[0] == '.') {
408 dptr = readdir(ptr);
409 } else {
410 break;
414 if (dptr == NULL) {
415 break;
418 /* hack */
419 if (count < 256) {
421 whole_dir[count] = g_strdup (dptr->d_name);
422 count++;
423 } else {
424 g_error ("uggg. too many files in s_slib_getfiles!\n");
427 dptr = readdir(ptr);
429 return(NULL);
431 break;
433 case(READ_DIR):
436 if (whole_dir[current] && current < count) {
437 return(whole_dir[current++]);
438 } else {
439 return(NULL);
442 break;
444 default:
445 return(NULL);
448 #if DEBUG
449 for (j = 0;j < count; j++) {
450 printf("string: %s\n", whole_dir[j]);
452 #endif
456 /*! \todo Finish function documentation!!!
457 * \brief
458 * \par Function Description
461 void s_slib_print(void)
463 int i;
465 for (i = 0; i < slib_index; i++) {
466 printf("%s\n", slib[i].dir_name);
470 /*! \todo Finish function documentation!!!
471 * \brief
472 * \par Function Description
475 int s_slib_uniq(char *path)
477 if (s_slib_search_for_dirname(path)) {
479 #if DEBUG
480 printf("found\n");
481 #endif
482 return(0);
483 } else {
485 #if DEBUG
486 printf("NOT found\n");
487 #endif
489 return(1);
493 /*! \todo Finish function documentation!!!
494 * \brief
495 * \par Function Description
498 void s_slib_print_dirs(void)
500 int i;
501 char *string;
502 char *file;
504 i = 0;
505 string = s_slib_getdir(i);
506 while(string != NULL) {
508 s_slib_getfiles(string, OPEN_DIR);
509 printf("Opened %s\n", string);
511 file = (char *) s_slib_getfiles(string, READ_DIR);
513 while(file != NULL) {
514 printf("file: %s\n", file);
515 file = (char *) s_slib_getfiles(string, READ_DIR);
518 printf("Closed %s\n", string);
519 s_slib_getfiles(string, CLOSE_DIR);
520 i++;
521 string = s_slib_getdir(i);