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 */
25 #include <sys/types.h>
44 #include "../include/prototype.h"
46 #ifdef HAVE_LIBDMALLOC
50 /* need to test everything at boundary conditions (exceed cache size etc...) */
58 static int slib_index
=0;
64 * and eventually make this unlimited
67 static struct st_slib slib
[MAX_SLIBS
];
69 /*! \todo Finish function documentation!!!
71 * \par Function Description
74 int s_slib_add_entry(char *new_path
)
76 if (new_path
== NULL
) {
80 if (slib_index
>= MAX_SLIBS
) {
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
);
93 /*! \todo Finish function documentation!!!
95 * \par Function Description
97 * \return 1 if directory is found, zero otherwise.
99 int s_slib_search_for_dirname(char *dir_name
)
103 for (i
= 0; i
< slib_index
; i
++) {
104 if (strcmp(slib
[i
].dir_name
, dir_name
) == 0) {
112 /*! \todo Finish function documentation!!!
114 * \par Function Description
117 * Caller must g_free returned pointer.
119 char *s_slib_search_dirs(const char *basename
)
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++) {*/
132 printf("searching: %d %s\n", i
, slib
[i
].dir_name
);
135 ptr
= opendir(slib
[i
].dir_name
);
138 fprintf(stderr
, "Oops got a null dir_name!\n");
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
);
177 /*! \todo Finish function documentation!!!
179 * \par Function Description
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
;
190 slib_path
= s_slib_search_dirs(basename
);
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 */
202 full_path
= (char *) g_malloc(sizeof(char)*(len
+2));
204 sprintf(full_path
, "%s%c%s", slib_path
, G_DIR_SEPARATOR
, basename
);
211 s_log_message("Could not find [%s] in any SourceLibrary\n", basename
);
214 fprintf(stderr
, "Could not find [%s] in any SourceLibrary\n", basename
);
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.
231 * Caller must g_free returned pointer.
233 char *s_slib_getbasename(const char *rawname
)
235 char *return_filename
;
242 int seen_underscore
=0;
247 len
= strlen(rawname
)+1;
249 return_filename
= (char *) g_malloc(sizeof(char)*len
);
252 /* first get everything up to the leading dot */
253 while(rawname
[i
] != '\0' && rawname
[i
] != '.') {
254 return_filename
[i
] = rawname
[i
];
259 return_filename
[i
] = '\0';
262 /* keep filename for safe keeping */
263 copy
= return_filename
;
265 /* skip null terminator */
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
] == '_') {
282 return_filename
[i
] = '\0';
284 /* we are still searching for the first underscore */
286 /* first make sure char is a number */
287 if (isdigit((int) return_filename
[i
])) {
289 } else if (return_filename
[i
] == '_' && valid
) {
290 /* yes it is okay to delete the chars */
292 /* incremented, since it is then */
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:
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
322 * <DT>SLIB_SEARCH_DONE</DT><DD>Finish searching.
325 * Filename is the raw symbol/whatever file name. This function does all the
326 * required stripping (up to the first period).
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
;
342 case(SLIB_SEARCH_START
):
347 case(SLIB_SEARCH_NEXT
):
350 /* be sure to g_free processed_name */
351 processed_name
= s_slib_getbasename(filename
);
354 printf("proced: %s\n", processed_name
);
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
);
374 case(SLIB_SEARCH_DONE
):
381 g_free(processed_name
);
383 /* don't forget to g_free this 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.
399 * Caller must g_free returned pointer.
401 char *s_slib_search_single(const char *filename
)
405 string
= s_slib_search_lowlevel(filename
);
407 /* don't forget to g_free this string */
411 /*! \todo Finish function documentation!!!
413 * \par Function Description
420 for (i
= 0; i
< slib_index
; i
++) {
421 if (slib
[i
].dir_name
)
422 g_free(slib
[i
].dir_name
);
428 /*! \todo Finish function documentation!!!
430 * \par Function Description
436 for (i
= 0; i
< MAX_SLIBS
; i
++) {
437 slib
[i
].dir_name
= NULL
;
441 /*! \todo Finish function documentation!!!
443 * \par Function Description
446 * Caller must not free the returned pointer.
449 char *s_slib_getdir(int index
)
451 if (slib
[index
].dir_name
!= NULL
)
452 return(slib
[index
].dir_name
);
457 /*! \todo Finish function documentation!!!
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.
466 * Caller must g_free returned pointer.
468 * The flag parameter can be one of the following values:
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.
474 * \bug This is TOTTALLY BROKEN!
475 * statics are not allowed anymore
477 * this function is not reentrant
479 char *s_slib_getfiles(char *directory
, int flag
)
482 static struct dirent
*dptr
;
483 static char *whole_dir
[256]; /* make this dynamic hack */
485 static int current
=0;
499 for (j
= 0 ; j
< count
;j
++) {
501 g_free(whole_dir
[j
]);
503 count
= current
= 0 ;
508 /* open the directory and return first element (after if) */
517 for (j
= 0 ; j
< count
;j
++) {
519 g_free(whole_dir
[j
]);
521 count
= current
= 0 ;
523 ptr
= opendir(directory
); /* hack check for existance */
529 /* now read the entire directory */
532 while (dptr
!= NULL
) {
535 while (dptr
!= NULL
) {
536 if (dptr
->d_name
[0] == '.') {
547 if (dptr
->d_name
!= NULL
) {
548 len
= strlen(dptr
->d_name
);
553 whole_dir
[count
] = (char *)
554 g_malloc(sizeof(char)*len
+1);
555 strcpy(whole_dir
[count
], dptr
->d_name
);
559 "uggg. too many files in s_slib_getfiles!\n");
573 if (whole_dir
[current
] && current
< count
) {
574 return(whole_dir
[current
++]);
586 for (j
= 0;j
< count
; j
++) {
587 printf("string: %s\n", whole_dir
[j
]);
593 /*! \todo Finish function documentation!!!
595 * \par Function Description
598 void s_slib_print(void)
602 for (i
= 0; i
< slib_index
; i
++) {
603 printf("%s\n", slib
[i
].dir_name
);
607 /*! \todo Finish function documentation!!!
609 * \par Function Description
612 int s_slib_uniq(char *path
)
614 if (s_slib_search_for_dirname(path
)) {
623 printf("NOT found\n");
630 /*! \todo Finish function documentation!!!
632 * \par Function Description
635 void s_slib_print_dirs(void)
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
);
658 string
= s_slib_getdir(i
);