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