1 /*****************************************************************
2 * HMMER - Biological sequence analysis with profile HMMs
3 * Copyright (C) 1992-1999 Washington University School of Medicine
6 * This source code is distributed under the terms of the
7 * GNU General Public License. See the files COPYING and LICENSE
9 *****************************************************************/
13 * SRE, Wed Jun 19 11:19:22 1996
15 * File operation utilities, dealing with pathnames, directories,
16 * and environment variables.
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().)
22 * RCS $Id: file.c,v 1.1.1.1 2005/03/22 08:34:26 cmzmasek Exp $
33 * VMS: #define DIRSLASH ']'
34 * MacOS: #define DIRSLASH ':'
35 * DOS: #define DIRSLASH '\\'
37 * The code assumes that '.' is used for file name extensions,
40 #define DIRSLASH '/' /* UNIX directory paths have /foo/bar */
44 /* Function: FileDirname()
46 * Purpose: Returns the path from a filename:
47 * "/foo/bar/baz" -> "/foo/bar"
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.
58 * Args: file - name of file "/foo/bar/baz".
60 * Return: ptr to malloc'ed string "/foo/bar".
63 FileDirname(char *file)
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; }
80 /* Function: FileTail()
82 * Purpose: Return everything after the DIRSLASH:
83 * "/foo/bar/baz.1" -> "baz.1"
87 * If noextension is TRUE, removes a trailing ".foo" extension
90 * Args: file - name of file "/foo/bar/baz.1"
91 * noextension - TRUE to also remove extensions
93 * Return: ptr to malloc'ed string "baz.1"
96 FileTail(char *file, int noextension)
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 */
108 if ((lastdot = strrchr(tail, '.')) != NULL)
116 /* Function: FileConcat()
118 * Purpose: Concatenate a directory path and a file name,
119 * returning a pointer to a malloc'ed string with the
123 FileConcat(char *dir, char *file)
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);
134 /* Function: FileAddSuffix()
135 * Date: SRE, Wed Aug 1 11:19:33 2001 [Pasadena]
137 * Purpose: Add a suffix to a filename, return a malloc'ed
138 * string containing the new filename.sfx name.
140 * FileAddSuffix("genbank", "ssi")
141 * returns "genbank.ssi".
144 FileAddSuffix(char *filename, char *sfx)
147 new = MallocOrDie(strlen(filename) + strlen(sfx) + 2);
148 sprintf(new, "%s.%s", filename, sfx);
152 /* Function: EnvFileOpen()
153 * Date: Sun Feb 12 10:55:29 1995
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.
161 * fp = EnvFileOpen("BLOSUM45", "BLASTMAT", NULL);
163 * fp = EnvFileOpen("swiss", "BLASTDB", NULL);
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
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
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.
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.
187 EnvFileOpen(char *fname, char *env, char **ret_dir)
191 char *s; /* ptr to indiv element in env list */
192 char full[1024]; /* constructed file name */
194 if (env == NULL) return NULL;
195 if ((path = Strdup(getenv(env))) == NULL) return NULL;
198 s = strtok(path, ":");
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, ":");
208 /* Return the path we used, if caller wants it
210 if (ret_dir != NULL) *ret_dir = Strdup(s);
217 /* Function: FileExists()
219 * Purpose: Return TRUE if filename exists.
220 * Testing fopen() is the only possible platform-independent test
224 FileExists(char *filename)
227 if ((fp = fopen(filename, "r"))) { fclose(fp); return TRUE; }