libgeda
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * libgeda - gEDA's library 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00022 #include <config.h> 00023 00024 #include <stdio.h> 00025 #include <sys/types.h> 00026 #include <ctype.h> 00027 #ifdef HAVE_STDLIB_H 00028 #include <stdlib.h> 00029 #endif 00030 #ifdef HAVE_STRING_H 00031 #include <string.h> 00032 #endif 00033 #include <dirent.h> 00034 00035 #include "libgeda_priv.h" 00036 00037 #ifdef HAVE_LIBDMALLOC 00038 #include <dmalloc.h> 00039 #endif 00040 00041 /* need to test everything at boundary conditions (exceed cache size etc...) */ 00042 00044 struct st_slib { 00045 char *dir_name; 00046 }; 00047 00049 static int slib_index=0; 00050 00052 #define MAX_SLIBS 128 00053 00058 static struct st_slib slib[MAX_SLIBS]; 00059 00065 int s_slib_add_entry(char *new_path) 00066 { 00067 if (new_path == NULL) { 00068 return(-1); 00069 } 00070 00071 if (slib_index >= MAX_SLIBS) { 00072 return(-1); 00073 } 00074 00075 slib[slib_index].dir_name = g_strdup (new_path); 00076 00077 slib_index++; 00078 return(slib_index); 00079 } 00080 00087 int s_slib_search_for_dirname(char *dir_name) 00088 { 00089 int i; 00090 00091 for (i = 0; i < slib_index; i++) { 00092 if (strcmp(slib[i].dir_name, dir_name) == 0) { 00093 return(1); 00094 } 00095 } 00096 00097 return(0); 00098 } 00099 00107 char *s_slib_search_dirs(const char *basename) 00108 { 00109 int i; 00110 DIR *ptr=NULL; 00111 struct dirent *dptr; 00112 char *slib_path=NULL; 00113 00114 /* search slib paths backwards */ 00115 for (i = slib_index-1 ; i >= 0; i--) { 00116 /* for (i = 0 ; i < slib_index; i++) {*/ 00117 00118 #if DEBUG 00119 printf("searching: %d %s\n", i, slib[i].dir_name); 00120 #endif 00121 00122 ptr = opendir(slib[i].dir_name); 00123 00124 g_return_val_if_fail ((ptr != NULL), NULL); 00125 00126 dptr = readdir(ptr); 00127 00128 while(dptr != NULL) { 00129 00130 /* Do a substring comp for a match */ 00131 if (strstr(dptr->d_name, basename) != NULL) { 00132 slib_path = g_strdup (slib[i].dir_name); 00133 00134 if (ptr) { 00135 closedir(ptr); 00136 ptr = NULL; 00137 } 00138 00139 return(slib_path); 00140 } 00141 dptr = readdir(ptr); 00142 } 00143 00144 if (ptr) { 00145 closedir(ptr); 00146 ptr = NULL; 00147 } 00148 00149 } 00150 00151 return(NULL); 00152 } 00153 00161 char *s_slib_search_lowlevel(const char *basename) 00162 { 00163 char *slib_path=NULL; 00164 char *full_path=NULL; 00165 00166 slib_path = s_slib_search_dirs(basename); 00167 00168 if (slib_path) { 00169 /* return type */ 00170 00171 s_log_message(_("Found [%s]\n"), basename); 00172 /* s_log_message("Found [%s] in [%s]\n", basename, slib_path);*/ 00173 00174 full_path = g_build_filename (slib_path, basename, NULL); 00175 00176 g_free(slib_path); 00177 00178 return(full_path); 00179 } else { 00180 00181 s_log_message(_("Could not find [%s] in any SourceLibrary\n"), basename); 00182 00183 return(NULL); 00184 } 00185 } 00186 00200 char *s_slib_getbasename(const char *rawname) 00201 { 00202 char *return_filename; 00203 int i; 00204 int done=0; 00205 int lastchar; 00206 int valid=0; 00207 int len; 00208 int seen_underscore=0; 00209 00210 if (!rawname) 00211 return(NULL); 00212 00213 len = strlen(rawname)+1; 00214 00215 return_filename = (char *) g_malloc(sizeof(char)*len); 00216 00217 i = 0; 00218 /* first get everything up to the leading dot */ 00219 while(rawname[i] != '\0' && rawname[i] != '.') { 00220 return_filename[i] = rawname[i]; 00221 i++; 00222 } 00223 00224 00225 return_filename[i] = '\0'; 00226 00227 /* skip null terminator */ 00228 i--; 00229 00230 lastchar=i; 00231 00232 /* this is a quick and dirty state machine to */ 00233 /* go back and strip off any _#'s */ 00234 /* if there is a better way let me know */ 00235 while (i >= 0 && !done) { 00236 00237 /* first we need to check to see if we have seen the first '_' */ 00238 /* if we have then we already removing chars, continue with that */ 00239 if ( seen_underscore ) { 00240 if (return_filename[i] == '_') { 00241 done = 1; 00242 } 00243 00244 return_filename[i] = '\0'; 00245 } else { 00246 /* we are still searching for the first underscore */ 00247 00248 /* first make sure char is a number */ 00249 if (isdigit((int) return_filename[i])) { 00250 valid=1; 00251 } else if (return_filename[i] == '_' && valid) { 00252 /* yes it is okay to delete the chars */ 00253 seen_underscore=1; 00254 /* incremented, since it is then */ 00255 /* decremented */ 00256 i = lastchar+1; 00257 } else { 00258 valid = 0; 00259 done = 1; 00260 } 00261 } 00262 00263 i--; 00264 } 00265 00266 /* be sure to g_free this somewhere */ 00267 return(return_filename); 00268 } 00269 00293 char *s_slib_search(const char *filename, int flag) 00294 { 00295 char *processed_name=NULL; 00296 char *new_filename=NULL; 00297 char *string=NULL; 00298 static int count; 00299 00300 switch(flag) { 00301 case(SLIB_SEARCH_START): 00302 count = 0; 00303 string=NULL; 00304 break; 00305 00306 case(SLIB_SEARCH_NEXT): 00307 count++; 00308 00309 /* be sure to g_free processed_name */ 00310 processed_name = s_slib_getbasename(filename); 00311 00312 #if DEBUG 00313 printf("proced: %s\n", processed_name); 00314 #endif 00315 00316 /* for now only look for .sch's */ 00317 /* this needs to be *MUCH* more flexible */ 00318 /* number_suffix is large enough ? */ 00319 new_filename = g_strdup_printf ("%s_%d.sch", processed_name, count); 00320 00321 string = s_slib_search_lowlevel(new_filename); 00322 00323 g_free(new_filename); 00324 break; 00325 00326 case(SLIB_SEARCH_DONE): 00327 count = 0; 00328 string=NULL; 00329 break; 00330 } 00331 00332 g_free(processed_name); 00333 00334 /* don't forget to g_free this string */ 00335 return(string); 00336 } 00337 00352 char *s_slib_search_single(const char *filename) 00353 { 00354 char *string=NULL; 00355 00356 string = s_slib_search_lowlevel(filename); 00357 00358 /* don't forget to g_free this string */ 00359 return(string); 00360 } 00361 00367 void s_slib_free() 00368 { 00369 int i; 00370 00371 for (i = 0; i < slib_index; i++) { 00372 g_free(slib[i].dir_name); 00373 } 00374 00375 slib_index=0; 00376 } 00377 00383 void s_slib_init() 00384 { 00385 int i; 00386 for (i = 0; i < MAX_SLIBS; i++) { 00387 slib[i].dir_name = NULL; 00388 } 00389 } 00390 00398 /* returns slibs */ 00399 char *s_slib_getdir(int index) 00400 { 00401 if (slib[index].dir_name != NULL) 00402 return(slib[index].dir_name); 00403 else 00404 return(NULL); 00405 } 00406 00429 char *s_slib_getfiles(char *directory, int flag) 00430 { 00431 static DIR *ptr; 00432 static struct dirent *dptr; 00433 static char *whole_dir[256]; /* make this dynamic hack */ 00434 static int count=0; 00435 static int current=0; 00436 00437 int j; 00438 00439 switch(flag) { 00440 00441 case(CLOSE_DIR): 00442 if (ptr) { 00443 closedir(ptr); 00444 } 00445 00446 ptr = NULL; 00447 00448 for (j = 0 ; j < count ;j++) { 00449 g_free(whole_dir[j]); 00450 } 00451 count = current = 0 ; 00452 00453 return(NULL); 00454 break; 00455 00456 /* open the directory and return first element (after if) */ 00457 case(OPEN_DIR): 00458 00459 if (ptr) { 00460 closedir(ptr); 00461 } 00462 00463 ptr = NULL; 00464 00465 for (j = 0 ; j < count ;j++) { 00466 g_free(whole_dir[j]); 00467 } 00468 count = current = 0 ; 00469 00470 ptr = opendir(directory); /* hack check for existance */ 00471 00472 if (ptr == NULL) 00473 return(NULL); 00474 00475 00476 /* now read the entire directory */ 00477 dptr = readdir(ptr); 00478 00479 while (dptr != NULL) { 00480 00481 /* skip .'s */ 00482 while (dptr != NULL) { 00483 if (dptr->d_name[0] == '.') { 00484 dptr = readdir(ptr); 00485 } else { 00486 break; 00487 } 00488 } 00489 00490 if (dptr == NULL) { 00491 break; 00492 } 00493 00494 /* hack */ 00495 if (count < 256) { 00496 00497 whole_dir[count] = g_strdup (dptr->d_name); 00498 count++; 00499 } else { 00500 g_error ("uggg. too many files in s_slib_getfiles!\n"); 00501 } 00502 00503 dptr = readdir(ptr); 00504 } 00505 return(NULL); 00506 00507 break; 00508 00509 case(READ_DIR): 00510 00511 00512 if (whole_dir[current] && current < count) { 00513 return(whole_dir[current++]); 00514 } else { 00515 return(NULL); 00516 } 00517 00518 break; 00519 00520 default: 00521 return(NULL); 00522 } 00523 00524 #if DEBUG 00525 for (j = 0;j < count; j++) { 00526 printf("string: %s\n", whole_dir[j]); 00527 } 00528 #endif 00529 00530 } 00531 00537 void s_slib_print(void) 00538 { 00539 int i; 00540 00541 for (i = 0; i < slib_index; i++) { 00542 printf("%s\n", slib[i].dir_name); 00543 } 00544 } 00545 00551 int s_slib_uniq(char *path) 00552 { 00553 if (s_slib_search_for_dirname(path)) { 00554 00555 #if DEBUG 00556 printf("found\n"); 00557 #endif 00558 return(0); 00559 } else { 00560 00561 #if DEBUG 00562 printf("NOT found\n"); 00563 #endif 00564 00565 return(1); 00566 } 00567 } 00568 00574 void s_slib_print_dirs(void) 00575 { 00576 int i; 00577 char *string; 00578 char *file; 00579 00580 i = 0; 00581 string = s_slib_getdir(i); 00582 while(string != NULL) { 00583 00584 s_slib_getfiles(string, OPEN_DIR); 00585 printf("Opened %s\n", string); 00586 00587 file = (char *) s_slib_getfiles(string, READ_DIR); 00588 00589 while(file != NULL) { 00590 printf("file: %s\n", file); 00591 file = (char *) s_slib_getfiles(string, READ_DIR); 00592 } 00593 00594 printf("Closed %s\n", string); 00595 s_slib_getfiles(string, CLOSE_DIR); 00596 i++; 00597 string = s_slib_getdir(i); 00598 } 00599 }