libgeda

s_slib.c

Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines