Updated po files using make update-po
[geda-gaf/peter-b.git] / libgeda / src / s_slib.c
blob2892c93fbbdd0b586cc10a30c421e764fcd2facc
1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111 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 #ifdef HAVE_DIRENT_H
34 #include <dirent.h>
35 #endif
37 #include <gtk/gtk.h>
38 #include <libguile.h>
40 #include "defines.h"
41 #include "struct.h"
42 #include "globals.h"
44 #include "../include/prototype.h"
46 #ifdef HAVE_LIBDMALLOC
47 #include <dmalloc.h>
48 #endif
50 /* need to test everything at boundary conditions (exceed cache size etc...) */
52 /*! \brief */
53 struct st_slib {
54 char *dir_name;
57 /*! \brief */
58 static int slib_index=0;
60 /*! \brief */
61 #define MAX_SLIBS 128
63 /*! \brief
64 * and eventually make this unlimited
65 * hack hack
67 static struct st_slib slib[MAX_SLIBS];
69 /*! \todo Finish function documentation!!!
70 * \brief
71 * \par Function Description
74 int s_slib_add_entry(char *new_path)
76 if (new_path == NULL) {
77 return(-1);
80 if (slib_index >= MAX_SLIBS) {
81 return(-1);
84 slib[slib_index].dir_name =
85 (char *) g_malloc(sizeof(char)*strlen(new_path)+1);
87 strcpy(slib[slib_index].dir_name, new_path);
89 slib_index++;
90 return(slib_index);
93 /*! \todo Finish function documentation!!!
94 * \brief
95 * \par Function Description
97 * \return 1 if directory is found, zero otherwise.
99 int s_slib_search_for_dirname(char *dir_name)
101 int i;
103 for (i = 0; i < slib_index; i++) {
104 if (strcmp(slib[i].dir_name, dir_name) == 0) {
105 return(1);
109 return(0);
112 /*! \todo Finish function documentation!!!
113 * \brief
114 * \par Function Description
116 * \warning
117 * Caller must g_free returned pointer.
119 char *s_slib_search_dirs(const char *basename)
121 int i;
122 int len;
123 DIR *ptr=NULL;
124 struct dirent *dptr;
125 char *slib_path=NULL;
127 /* search slib paths backwards */
128 for (i = slib_index-1 ; i >= 0; i--) {
129 /* for (i = 0 ; i < slib_index; i++) {*/
131 #if DEBUG
132 printf("searching: %d %s\n", i, slib[i].dir_name);
133 #endif
135 ptr = opendir(slib[i].dir_name);
137 if (ptr == NULL) {
138 fprintf(stderr, "Oops got a null dir_name!\n");
139 exit(-1);
142 dptr = readdir(ptr);
144 while(dptr != NULL) {
146 /* Do a substring comp for a match */
147 if (strstr(dptr->d_name, basename) != NULL) {
148 len = strlen(slib[i].dir_name);
149 slib_path = (char *) g_malloc(sizeof(char)*len+1);
150 strcpy(slib_path, slib[i].dir_name);
152 if (ptr) {
153 closedir(ptr);
154 ptr = NULL;
157 return(slib_path);
159 dptr = readdir(ptr);
162 if (ptr) {
163 closedir(ptr);
164 ptr = NULL;
169 if (ptr) {
170 closedir(ptr);
171 ptr = NULL;
174 return(NULL);
177 /*! \todo Finish function documentation!!!
178 * \brief
179 * \par Function Description
181 * \warning
182 * Caller must g_free returned pointer.
184 char *s_slib_search_lowlevel(const char *basename)
186 char *slib_path=NULL;
187 char *full_path=NULL;
188 int len;
190 slib_path = s_slib_search_dirs(basename);
192 if (slib_path) {
193 /* return type */
195 s_log_message("Found [%s]\n", basename);
196 /* s_log_message("Found [%s] in [%s]\n", basename, slib_path);*/
198 len = strlen(basename)+strlen(slib_path);
200 /* The 2 is for NULL char and the slash inbetween the two */
201 /* strings */
202 full_path = (char *) g_malloc(sizeof(char)*(len+2));
204 sprintf(full_path, "%s%c%s", slib_path, G_DIR_SEPARATOR, basename);
206 g_free(slib_path);
208 return(full_path);
209 } else {
211 s_log_message("Could not find [%s] in any SourceLibrary\n", basename);
213 #if DEBUG
214 fprintf(stderr, "Could not find [%s] in any SourceLibrary\n", basename);
215 #endif
216 return(NULL);
220 /*! \todo Finish function documentation!!!
221 * \brief Get the base file name from a raw file name string.
222 * \par Function Description
223 * This function takes a raw file name and returns a processed file name.
224 * It takes the raw file name and copies everything up to the first period
225 * and removes any _# (where # is any number of digits.
227 * \param [in] rawname Character string with the raw file name to parse.
228 * \return The base file name in a character string.
230 * \warning
231 * Caller must g_free returned pointer.
233 char *s_slib_getbasename(const char *rawname)
235 char *return_filename;
236 char *copy;
237 int i;
238 int done=0;
239 int lastchar;
240 int valid=0;
241 int len;
242 int seen_underscore=0;
244 if (!rawname)
245 return(NULL);
247 len = strlen(rawname)+1;
249 return_filename = (char *) g_malloc(sizeof(char)*len);
251 i = 0;
252 /* first get everything up to the leading dot */
253 while(rawname[i] != '\0' && rawname[i] != '.') {
254 return_filename[i] = rawname[i];
255 i++;
259 return_filename[i] = '\0';
262 /* keep filename for safe keeping */
263 copy = return_filename;
265 /* skip null terminator */
266 i--;
268 lastchar=i;
270 /* this is a quick and dirty state machine to */
271 /* go back and strip off any _#'s */
272 /* if there is a better way let me know */
273 while (i >= 0 && !done) {
275 /* first we need to check to see if we have seen the first '_' */
276 /* if we have then we already removing chars, continue with that */
277 if ( seen_underscore ) {
278 if (return_filename[i] == '_') {
279 done = 1;
282 return_filename[i] = '\0';
283 } else {
284 /* we are still searching for the first underscore */
286 /* first make sure char is a number */
287 if (isdigit((int) return_filename[i])) {
288 valid=1;
289 } else if (return_filename[i] == '_' && valid) {
290 /* yes it is okay to delete the chars */
291 seen_underscore=1;
292 /* incremented, since it is then */
293 /* decremented */
294 i = lastchar+1;
295 } else {
296 valid = 0;
297 done = 1;
301 i--;
304 /* be sure to g_free this somewhere */
305 return(return_filename);
308 /*! \todo Finish function documentation!!!
309 * \brief Search SLIB for a particular file name.
310 * \par Function Description
311 * This function will search the SLIB for a particular file name starting
312 * at a location specified by the <B>flag</B> parameter.
314 * \param [in] filename Character string with file name to search for.
315 * \param [in] flag Specifies search start location. (See below...)
317 * The <B>flag</B> parameter can be one of the following values:
318 * <DL>
319 * <DT>SLIB_SEARCH_START</DT><DD>Starts a new search for a source file.
320 * <DT>SLIB_SEARCH_NEXT</DT><DD>Returns the next instance of the file if
321 * one exists.
322 * <DT>SLIB_SEARCH_DONE</DT><DD>Finish searching.
323 * </DL>
325 * Filename is the raw symbol/whatever file name. This function does all the
326 * required stripping (up to the first period).
328 * \warning
329 * Caller must g_free returned pointer.
331 char *s_slib_search(const char *filename, int flag)
333 char *processed_name=NULL;
334 char *new_filename=NULL;
335 char *string=NULL;
336 char *number_suffix;
337 int len;
338 int len2;
339 static int count;
341 switch(flag) {
342 case(SLIB_SEARCH_START):
343 count = 0;
344 string=NULL;
345 break;
347 case(SLIB_SEARCH_NEXT):
348 count++;
350 /* be sure to g_free processed_name */
351 processed_name = s_slib_getbasename(filename);
353 #if DEBUG
354 printf("proced: %s\n", processed_name);
355 #endif
357 len = strlen(processed_name);
359 /* for now only look for .sch's */
360 /* this needs to be *MUCH* more flexible */
361 /* number_suffix is large enough ? */
362 number_suffix = g_strdup_printf("_%d.sch", count);
363 len2 = strlen(number_suffix);
364 new_filename = (char *)
365 g_malloc (sizeof(char)*(len+len2+1));
367 sprintf(new_filename, "%s%s", processed_name, number_suffix);
368 string = s_slib_search_lowlevel(new_filename);
370 g_free(new_filename);
371 g_free(number_suffix);
372 break;
374 case(SLIB_SEARCH_DONE):
375 count = 0;
376 string=NULL;
377 break;
380 if (processed_name)
381 g_free(processed_name);
383 /* don't forget to g_free this string */
384 return(string);
387 /*! \todo Finish function documentation!!!
388 * \brief Search SLIB for a particular file name.
389 * \par Function Description
390 * This function will search the SLIB for a particular file name starting
391 * at a location specified by the <B>flag</B> parameter.
393 * \param [in] filename Character string with file name to search for.
395 * Filename is the raw symbol/whatever file name. This function only looks
396 * for the file name as is and does no other changes to it.
398 * \warning
399 * Caller must g_free returned pointer.
401 char *s_slib_search_single(const char *filename)
403 char *string=NULL;
405 string = s_slib_search_lowlevel(filename);
407 /* don't forget to g_free this string */
408 return(string);
411 /*! \todo Finish function documentation!!!
412 * \brief
413 * \par Function Description
416 void s_slib_free()
418 int i;
420 for (i = 0; i < slib_index; i++) {
421 if (slib[i].dir_name)
422 g_free(slib[i].dir_name);
425 slib_index=0;
428 /*! \todo Finish function documentation!!!
429 * \brief
430 * \par Function Description
433 void s_slib_init()
435 int i;
436 for (i = 0; i < MAX_SLIBS; i++) {
437 slib[i].dir_name = NULL;
441 /*! \todo Finish function documentation!!!
442 * \brief
443 * \par Function Description
445 * \warning
446 * Caller must not free the returned pointer.
448 /* returns slibs */
449 char *s_slib_getdir(int index)
451 if (slib[index].dir_name != NULL)
452 return(slib[index].dir_name);
453 else
454 return(NULL);
457 /*! \todo Finish function documentation!!!
458 * \brief
459 * \par Function Description
461 * \param [in] directory Character string with directory to get files from.
462 * \param [in] flag Search control flag. (See below...)
463 * \return A file name if one is found, NULL otherwise.
465 * \warning
466 * Caller must g_free returned pointer.
468 * The flag parameter can be one of the following values:
469 * <DL>
470 * <DT>OPEN_DIR</DT><DD>Opens the directory and returns NULL.
471 * <DT>READ_DIR</DT><DD>Returns the next non "." entry.
472 * <DT>CLOSE_DIR</DT><DD>Closes the directory.
473 * </DL>
474 * \bug This is TOTTALLY BROKEN!
475 * statics are not allowed anymore
476 * \warning
477 * this function is not reentrant
479 char *s_slib_getfiles(char *directory, int flag)
481 static DIR *ptr;
482 static struct dirent *dptr;
483 static char *whole_dir[256]; /* make this dynamic hack */
484 static int count=0;
485 static int current=0;
487 int j;
488 int len;
490 switch(flag) {
492 case(CLOSE_DIR):
493 if (ptr) {
494 closedir(ptr);
497 ptr = NULL;
499 for (j = 0 ; j < count ;j++) {
500 if (whole_dir[j])
501 g_free(whole_dir[j]);
503 count = current = 0 ;
505 return(NULL);
506 break;
508 /* open the directory and return first element (after if) */
509 case(OPEN_DIR):
511 if (ptr) {
512 closedir(ptr);
515 ptr = NULL;
517 for (j = 0 ; j < count ;j++) {
518 if (whole_dir[j])
519 g_free(whole_dir[j]);
521 count = current = 0 ;
523 ptr = opendir(directory); /* hack check for existance */
525 if (ptr == NULL)
526 return(NULL);
529 /* now read the entire directory */
530 dptr = readdir(ptr);
532 while (dptr != NULL) {
534 /* skip .'s */
535 while (dptr != NULL) {
536 if (dptr->d_name[0] == '.') {
537 dptr = readdir(ptr);
538 } else {
539 break;
543 if (dptr == NULL) {
544 break;
547 if (dptr->d_name != NULL) {
548 len = strlen(dptr->d_name);
550 /* hack */
551 if (count < 256) {
553 whole_dir[count] = (char *)
554 g_malloc(sizeof(char)*len+1);
555 strcpy(whole_dir[count], dptr->d_name);
556 count++;
557 } else {
558 fprintf(stderr,
559 "uggg. too many files in s_slib_getfiles!\n");
560 exit(-1);
564 dptr = readdir(ptr);
566 return(NULL);
568 break;
570 case(READ_DIR):
573 if (whole_dir[current] && current < count) {
574 return(whole_dir[current++]);
575 } else {
576 return(NULL);
579 break;
581 default:
582 return(NULL);
585 #if DEBUG
586 for (j = 0;j < count; j++) {
587 printf("string: %s\n", whole_dir[j]);
589 #endif
593 /*! \todo Finish function documentation!!!
594 * \brief
595 * \par Function Description
598 void s_slib_print(void)
600 int i;
602 for (i = 0; i < slib_index; i++) {
603 printf("%s\n", slib[i].dir_name);
607 /*! \todo Finish function documentation!!!
608 * \brief
609 * \par Function Description
612 int s_slib_uniq(char *path)
614 if (s_slib_search_for_dirname(path)) {
616 #if DEBUG
617 printf("found\n");
618 #endif
619 return(0);
620 } else {
622 #if DEBUG
623 printf("NOT found\n");
624 #endif
626 return(1);
630 /*! \todo Finish function documentation!!!
631 * \brief
632 * \par Function Description
635 void s_slib_print_dirs(void)
637 int i;
638 char *string;
639 char *file;
641 i = 0;
642 string = s_slib_getdir(i);
643 while(string != NULL) {
645 s_slib_getfiles(string, OPEN_DIR);
646 printf("Opened %s\n", string);
648 file = (char *) s_slib_getfiles(string, READ_DIR);
650 while(file != NULL) {
651 printf("file: %s\n", file);
652 file = (char *) s_slib_getfiles(string, READ_DIR);
655 printf("Closed %s\n", string);
656 s_slib_getfiles(string, CLOSE_DIR);
657 i++;
658 string = s_slib_getdir(i);