Mac binaries
[jabaws.git] / website / archive / binaries / mac / src / clustalo / src / squid / file.c
1 /*****************************************************************
2  * SQUID - a library of functions for biological sequence analysis
3  * Copyright (C) 1992-2002 Washington University School of Medicine
4  * 
5  *     This source code is freely distributed under the terms of the
6  *     GNU General Public License. See the files COPYRIGHT and LICENSE
7  *     for details.
8  *****************************************************************/
9
10
11 /* file.c
12  * SRE, Wed Jun 19 11:19:22 1996
13  * 
14  * File operation utilities, dealing with pathnames, directories,
15  * and environment variables.
16  * 
17  * The goal is to have these be platform-independent but they
18  * currently are UNIX-specific: i.e. this file is currently POSIX compliant
19  * but it is NOT ANSI C compliant. (The sole offender is getenv().)
20  *
21  * RCS $Id: file.c 217 2011-03-19 10:27:10Z andreas $ (Original squid RCS Id: file.c,v 1.8 2002/03/07 03:18:02 eddy Exp)
22  */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "squid.h"
29 #include "sqfuncs.h"
30
31 /* 
32  * VMS:    #define DIRSLASH ']'
33  * MacOS:  #define DIRSLASH ':'
34  * DOS:    #define DIRSLASH '\\'
35  * 
36  * The code assumes that '.' is used for file name extensions,
37  * such as "foo.bar".
38  */
39 #define DIRSLASH '/'           /* UNIX directory paths have /foo/bar */
40
41
42
43 /* Function: FileDirname()
44  * 
45  * Purpose:  Returns the path from a filename:
46  *             "/foo/bar/baz"  -> "/foo/bar"
47  *             "foo/bar"       -> "foo" 
48  *             "foo"           -> "."
49  *             "/"             -> "/" 
50  *           i.e. the string will be non-NULL; it will
51  *           contain the string up to but not including the
52  *           last '/' character; returns "." if
53  *           there are no '/' characters, and returns "/"
54  *           if the last slash is the first character.
55  *           Modeled on Tcl's "file dirname" command.
56  *
57  * Args:     file - name of file "/foo/bar/baz".
58  *           
59  * Return:   ptr to malloc'ed string "/foo/bar".          
60  */
61 char *
62 FileDirname(char *file)
63 {
64   char *dirname;
65   char *lastslash;
66   int   len;
67   
68   lastslash = strrchr(file, DIRSLASH);
69   len =  (lastslash == NULL) ? 0 : (int) (lastslash - file);
70   dirname = (char *) MallocOrDie (sizeof(char) * (len+2));
71   if (len > 0)                strncpy(dirname, file, len);
72   else if (*file != DIRSLASH) { *dirname = '.';      len = 1; }
73   else                        { *dirname = DIRSLASH; len = 1; }
74   dirname[len] = '\0';
75   return dirname;
76 }
77
78
79 /* Function: FileTail()
80  * 
81  * Purpose:  Return everything after the DIRSLASH:
82  *             "/foo/bar/baz.1"  -> "baz.1"
83  *             "foo/bar"         -> "bar" 
84  *             "foo"             -> "foo"
85  *             "/"               -> "" 
86  *           If noextension is TRUE, removes a trailing ".foo" extension
87  *           too.
88  *           
89  * Args:     file        - name of file "/foo/bar/baz.1"         
90  *           noextension - TRUE to also remove extensions
91  *           
92  * Return:   ptr to malloc'ed string "baz.1"          
93  */      
94 char * 
95 FileTail(char *file, int noextension)
96 {
97   char *tail;
98   char *lastslash;
99   char *lastdot;
100                                 /* remove directory prefix */
101   lastslash = strrchr(file, DIRSLASH);
102   tail = (char *) MallocOrDie (sizeof(char) * (strlen(file)+1));
103   if (lastslash == NULL) strcpy(tail, file);
104   else                   strcpy(tail, lastslash+1);
105                                 /* remove trailing suffix */
106   if (noextension) {
107     if ((lastdot = strrchr(tail, '.')) != NULL)
108       *lastdot = '\0';
109   }
110
111   return tail;
112 }
113
114
115 /* Function: FileSameDirectory()
116  * Date:     SRE, Wed Mar  6 20:03:23 2002 [St. Louis]
117  *
118  * Purpose:  Given a path to one file, and the 
119  *           name of another file in the same directory,
120  *           concat the path from file1 onto file2, and
121  *           return the result. Caller must free the ptr
122  *           that's returned. 
123  *           
124  *           Written for SSI - SSI indices contain filenames
125  *           without paths, and we will need to convert that
126  *           to a full path.
127  *
128  * Args:     file1 - a path to a file, e.g. "/foo/bar/baz.1"
129  *           file2 - a simple filename, e.g. "quux.2"
130  *           
131  * Returns:  path to file2: e.g. "/foo/bar/quux.2"
132  *           Returns NULL if file2 already has a path, and the result
133  *           would be a different place.
134  */
135 char *
136 FileSameDirectory(char *file1, char *file2)
137 {
138   char *path;
139   char *tail;
140   char *result;
141   int   seems_ok = 1;
142
143   path  = FileDirname(file1);
144   tail  = FileTail(file2, FALSE);
145   if (strcmp(file2, tail) != 0) seems_ok = 0; /* ut-oh, file2 *had* a path */
146   result = FileConcat(path, tail);
147   if (! seems_ok && strcmp(result, file2) != 0) {
148     free(result); result = NULL; 
149   }
150   free(path);
151   free(tail);
152   return result;
153 }
154
155 /* Function: FileConcat()
156  * 
157  * Purpose:  Concatenate a directory path and a file name,
158  *           returning a pointer to a malloc'ed string with the
159  *           full filename. This isn't just a string concat,
160  *           because we're careful about the dir slash.
161  */
162 char *
163 FileConcat(char *dir, char *file)
164 {
165   char *full;
166
167   full = (char *) MallocOrDie (sizeof(char) * (strlen(dir)+strlen(file)+2));
168   if (*file == DIRSLASH) strcpy(full, file); /* file = "/foo", ignore directory. */
169   else                   sprintf(full, "%s%c%s", dir, DIRSLASH, file);
170   return full;
171 }
172
173
174 /* Function: FileAddSuffix()
175  * Date:     SRE, Wed Aug  1 11:19:33 2001 [Pasadena]
176  *
177  * Purpose:  Add a suffix to a filename, return a malloc'ed
178  *           string containing the new filename.sfx name.
179  *           Example:
180  *             FileAddSuffix("genbank", "ssi")
181  *           returns "genbank.ssi".  
182  */
183 char *
184 FileAddSuffix(char *filename, char *sfx)
185 {
186   char *new;
187   new = MallocOrDie(strlen(filename) + strlen(sfx) + 2);
188   sprintf(new, "%s.%s", filename, sfx);
189   return new;
190 }
191
192 /* Function: EnvFileOpen()
193  * Date:     Sun Feb 12 10:55:29 1995            
194  * 
195  * Purpose:  Open a file, given a file name and an environment
196  *           variable that contains a directory path. Files
197  *           are opened read-only. Does not look at current directory
198  *           unless "." is explicitly in the path specified by env.
199  *           
200  *           For instance: 
201  *             fp = EnvFileOpen("BLOSUM45", "BLASTMAT", NULL);
202  *           or:
203  *             fp = EnvFileOpen("swiss", "BLASTDB", NULL);  
204  *             
205  *           Environment variables may contain a colon-delimited
206  *           list of more than one path; e.g.
207  *             setenv BLASTDB /nfs/databases/foo:/nfs/databases/bar
208  *             
209  *           Sometimes a group of files may be found in
210  *           one directory; for instance, an index file with a
211  *           database. The caller can EnvFileOpen() the main
212  *           file, and ask to get the name of the
213  *           directory back in ret_dir, so it can construct
214  *           the other auxiliary file names and fopen() them. (If it called
215  *           EnvFileOpen(), it might get confused by 
216  *           file name clashes and open files in different
217  *           directories.
218  *             
219  * Args:     fname   - name of file to open
220  *           env     - name of environment variable containing path
221  *           ret_dir - if non-NULL, RETURN: name of dir that was used.
222  *  
223  * Return:   FILE * to open file, or NULL on failure -- same as fopen()
224  *           Caller must free ret_dir if it passed a non-NULL address.
225  */
226 FILE *
227 EnvFileOpen(char *fname, char *env, char **ret_dir)
228 {
229   FILE *fp;
230   char *path;
231   char *s;                      /* ptr to indiv element in env list */
232   char  full[1024];             /* constructed file name */
233
234   if (env == NULL) return NULL;
235   if ((path = Strdup(getenv(env))) == NULL) return NULL;
236   
237   fp = NULL;
238   s  = strtok(path, ":");
239   while (s != NULL)
240     {
241       if (((int) strlen(fname) + (int) strlen(s) + 2) > 1024) 
242         { free(path); return NULL; }
243       sprintf(full, "%s%c%s", s, DIRSLASH, fname);
244       if ((fp = fopen(full, "r")) != NULL) break;
245       s = strtok(NULL, ":");
246     }
247
248   /* Return the path we used, if caller wants it
249    */
250   if (ret_dir != NULL) *ret_dir = Strdup(s);
251   free(path);
252   
253   return fp;
254 }
255
256
257 /* Function: FileExists()
258  * 
259  * Purpose:  Return TRUE if filename exists.
260  *           Testing fopen() is the only possible platform-independent test
261  *           I'm aware of.  
262  */
263 int
264 FileExists(char *filename)
265 {
266   FILE *fp;
267   if ((fp = fopen(filename, "r"))) { fclose(fp); return TRUE; }
268   return FALSE;
269 }
270
271