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 */
25 #include <sys/types.h>
35 #include "libgeda_priv.h"
37 #ifdef HAVE_LIBDMALLOC
41 /* need to test everything at boundary conditions (exceed cache size etc...) */
49 static int slib_index
=0;
55 * and eventually make this unlimited
58 static struct st_slib slib
[MAX_SLIBS
];
60 /*! \todo Finish function documentation!!!
62 * \par Function Description
65 int s_slib_add_entry(char *new_path
)
67 if (new_path
== NULL
) {
71 if (slib_index
>= MAX_SLIBS
) {
75 slib
[slib_index
].dir_name
= g_strdup (new_path
);
81 /*! \todo Finish function documentation!!!
83 * \par Function Description
85 * \return 1 if directory is found, zero otherwise.
87 int s_slib_search_for_dirname(char *dir_name
)
91 for (i
= 0; i
< slib_index
; i
++) {
92 if (strcmp(slib
[i
].dir_name
, dir_name
) == 0) {
100 /*! \todo Finish function documentation!!!
102 * \par Function Description
105 * Caller must g_free returned pointer.
107 char *s_slib_search_dirs(const char *basename
)
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++) {*/
119 printf("searching: %d %s\n", i
, slib
[i
].dir_name
);
122 ptr
= opendir(slib
[i
].dir_name
);
124 g_return_val_if_fail ((ptr
!= NULL
), NULL
);
128 while(dptr
!= NULL
) {
130 /* Do a substring comp for a match */
131 if (strstr(dptr
->d_name
, basename
) != NULL
) {
132 slib_path
= g_strdup (slib
[i
].dir_name
);
159 /*! \todo Finish function documentation!!!
161 * \par Function Description
164 * Caller must g_free returned pointer.
166 char *s_slib_search_lowlevel(const char *basename
)
168 char *slib_path
=NULL
;
169 char *full_path
=NULL
;
171 slib_path
= s_slib_search_dirs(basename
);
176 s_log_message(_("Found [%s]\n"), basename
);
177 /* s_log_message("Found [%s] in [%s]\n", basename, slib_path);*/
179 full_path
= g_build_filename (slib_path
, basename
, NULL
);
186 s_log_message(_("Could not find [%s] in any SourceLibrary\n"), basename
);
192 /*! \todo Finish function documentation!!!
193 * \brief Get the base file name from a raw file name string.
194 * \par Function Description
195 * This function takes a raw file name and returns a processed file name.
196 * It takes the raw file name and copies everything up to the first period
197 * and removes any _# (where # is any number of digits.
199 * \param [in] rawname Character string with the raw file name to parse.
200 * \return The base file name in a character string.
203 * Caller must g_free returned pointer.
205 char *s_slib_getbasename(const char *rawname
)
207 char *return_filename
;
213 int seen_underscore
=0;
218 len
= strlen(rawname
)+1;
220 return_filename
= (char *) g_malloc(sizeof(char)*len
);
223 /* first get everything up to the leading dot */
224 while(rawname
[i
] != '\0' && rawname
[i
] != '.') {
225 return_filename
[i
] = rawname
[i
];
230 return_filename
[i
] = '\0';
232 /* skip null terminator */
237 /* this is a quick and dirty state machine to */
238 /* go back and strip off any _#'s */
239 /* if there is a better way let me know */
240 while (i
>= 0 && !done
) {
242 /* first we need to check to see if we have seen the first '_' */
243 /* if we have then we already removing chars, continue with that */
244 if ( seen_underscore
) {
245 if (return_filename
[i
] == '_') {
249 return_filename
[i
] = '\0';
251 /* we are still searching for the first underscore */
253 /* first make sure char is a number */
254 if (isdigit((int) return_filename
[i
])) {
256 } else if (return_filename
[i
] == '_' && valid
) {
257 /* yes it is okay to delete the chars */
259 /* incremented, since it is then */
271 /* be sure to g_free this somewhere */
272 return(return_filename
);
275 /*! \todo Finish function documentation!!!
276 * \brief Search SLIB for a particular file name.
277 * \par Function Description
278 * This function will search the SLIB for a particular file name starting
279 * at a location specified by the <B>flag</B> parameter.
281 * \param [in] filename Character string with file name to search for.
282 * \param [in] flag Specifies search start location. (See below...)
284 * The <B>flag</B> parameter can be one of the following values:
286 * <DT>SLIB_SEARCH_START</DT><DD>Starts a new search for a source file.
287 * <DT>SLIB_SEARCH_NEXT</DT><DD>Returns the next instance of the file if
289 * <DT>SLIB_SEARCH_DONE</DT><DD>Finish searching.
292 * Filename is the raw symbol/whatever file name. This function does all the
293 * required stripping (up to the first period).
296 * Caller must g_free returned pointer.
298 char *s_slib_search(const char *filename
, int flag
)
300 char *processed_name
=NULL
;
301 char *new_filename
=NULL
;
306 case(SLIB_SEARCH_START
):
311 case(SLIB_SEARCH_NEXT
):
314 /* be sure to g_free processed_name */
315 processed_name
= s_slib_getbasename(filename
);
318 printf("proced: %s\n", processed_name
);
321 /* for now only look for .sch's */
322 /* this needs to be *MUCH* more flexible */
323 /* number_suffix is large enough ? */
324 new_filename
= g_strdup_printf ("%s_%d.sch", processed_name
, count
);
326 string
= s_slib_search_lowlevel(new_filename
);
328 g_free(new_filename
);
331 case(SLIB_SEARCH_DONE
):
337 g_free(processed_name
);
339 /* don't forget to g_free this string */
343 /*! \todo Finish function documentation!!!
344 * \brief Search SLIB for a particular file name.
345 * \par Function Description
346 * This function will search the SLIB for a particular file name starting
347 * at a location specified by the <B>flag</B> parameter.
349 * \param [in] filename Character string with file name to search for.
351 * Filename is the raw symbol/whatever file name. This function only looks
352 * for the file name as is and does no other changes to it.
355 * Caller must g_free returned pointer.
357 char *s_slib_search_single(const char *filename
)
361 string
= s_slib_search_lowlevel(filename
);
363 /* don't forget to g_free this string */
367 /*! \todo Finish function documentation!!!
369 * \par Function Description
376 for (i
= 0; i
< slib_index
; i
++) {
377 g_free(slib
[i
].dir_name
);
383 /*! \todo Finish function documentation!!!
385 * \par Function Description
391 for (i
= 0; i
< MAX_SLIBS
; i
++) {
392 slib
[i
].dir_name
= NULL
;
396 /*! \todo Finish function documentation!!!
398 * \par Function Description
401 * Caller must not free the returned pointer.
404 char *s_slib_getdir(int index
)
406 if (slib
[index
].dir_name
!= NULL
)
407 return(slib
[index
].dir_name
);
412 /*! \todo Finish function documentation!!!
414 * \par Function Description
416 * \param [in] directory Character string with directory to get files from.
417 * \param [in] flag Search control flag. (See below...)
418 * \return A file name if one is found, NULL otherwise.
421 * Caller must g_free returned pointer.
423 * The flag parameter can be one of the following values:
425 * <DT>OPEN_DIR</DT><DD>Opens the directory and returns NULL.
426 * <DT>READ_DIR</DT><DD>Returns the next non "." entry.
427 * <DT>CLOSE_DIR</DT><DD>Closes the directory.
429 * \bug This is TOTTALLY BROKEN!
430 * statics are not allowed anymore
432 * this function is not reentrant
434 char *s_slib_getfiles(char *directory
, int flag
)
437 static struct dirent
*dptr
;
438 static char *whole_dir
[256]; /* make this dynamic hack */
440 static int current
=0;
453 for (j
= 0 ; j
< count
;j
++) {
454 g_free(whole_dir
[j
]);
456 count
= current
= 0 ;
461 /* open the directory and return first element (after if) */
470 for (j
= 0 ; j
< count
;j
++) {
471 g_free(whole_dir
[j
]);
473 count
= current
= 0 ;
475 ptr
= opendir(directory
); /* hack check for existance */
481 /* now read the entire directory */
484 while (dptr
!= NULL
) {
487 while (dptr
!= NULL
) {
488 if (dptr
->d_name
[0] == '.') {
499 if (dptr
->d_name
!= NULL
) {
503 whole_dir
[count
] = g_strdup (dptr
->d_name
);
506 g_error ("uggg. too many files in s_slib_getfiles!\n");
519 if (whole_dir
[current
] && current
< count
) {
520 return(whole_dir
[current
++]);
532 for (j
= 0;j
< count
; j
++) {
533 printf("string: %s\n", whole_dir
[j
]);
539 /*! \todo Finish function documentation!!!
541 * \par Function Description
544 void s_slib_print(void)
548 for (i
= 0; i
< slib_index
; i
++) {
549 printf("%s\n", slib
[i
].dir_name
);
553 /*! \todo Finish function documentation!!!
555 * \par Function Description
558 int s_slib_uniq(char *path
)
560 if (s_slib_search_for_dirname(path
)) {
569 printf("NOT found\n");
576 /*! \todo Finish function documentation!!!
578 * \par Function Description
581 void s_slib_print_dirs(void)
588 string
= s_slib_getdir(i
);
589 while(string
!= NULL
) {
591 s_slib_getfiles(string
, OPEN_DIR
);
592 printf("Opened %s\n", string
);
594 file
= (char *) s_slib_getfiles(string
, READ_DIR
);
596 while(file
!= NULL
) {
597 printf("file: %s\n", file
);
598 file
= (char *) s_slib_getfiles(string
, READ_DIR
);
601 printf("Closed %s\n", string
);
602 s_slib_getfiles(string
, CLOSE_DIR
);
604 string
= s_slib_getdir(i
);