Updated TODO.
[ahxm.git] / support.c
blob7ee4059d810ef2d5c5326766af13fe7501c18d1b
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2005 Angel Ortega <angel@triptico.com>
6 support.c - Miscellaneous support functions
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
26 #include "config.h"
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
32 #include "annhell.h"
34 /*******************
35 Data
36 ********************/
38 static char ** library_path=NULL;
39 static int n_library_paths=0;
41 /*******************
42 Code
43 ********************/
45 /**
46 * add_to_library_path - Adds a directory path to the search path
47 * @path: the directory path
48 * @strip: flag to strip the upper level
50 * Adds @path to the list of searchable paths for path_fopen(),
51 * optionally stripping the upper level if @strip is set.
52 * The last part of the path is stripped before being stored,
53 * and duplication is avoided.
55 void add_to_library_path(char * path, int strip)
57 int n;
58 char * ptr;
60 /* if path starts with ~, pre-prend $HOME */
61 if(*path == '~')
63 char * new;
64 char * home;
66 if((home=getenv("HOME")) == NULL)
67 return;
69 if((new=malloc(strlen(home) + strlen(path) + 2)) == NULL)
70 return;
72 strcpy(new, home);
73 strcat(new, "/");
74 strcat(new, path + 1);
76 path=new;
78 else
80 /* just duplicate */
81 path=strdup(path);
84 /* if no directory path remains, abort */
85 if((ptr=strrchr(path, '/')) == NULL)
87 free(path);
88 return;
91 /* strip the filename part */
92 if(strip) *ptr='\0';
94 /* now try to find if that path is already stored */
95 for(n=0;n < n_library_paths;n++)
97 if(strcmp(path, library_path[n]) == 0)
99 /* found; free and return */
100 free(path);
101 return;
105 /* add room for the new path */
106 n_library_paths++;
107 library_path=(char **)realloc(library_path,
108 n_library_paths * sizeof(char *));
110 /* store */
111 library_path[n_library_paths - 1]=path;
116 * path_fopen - Opens a file, optionally searching in a path list
117 * @filename: the file name
118 * @mode: the file mode
120 * Opens a file. If the file is found as is, it's opened;
121 * otherwise, the full list of directory paths maintained by
122 * add_to_library_path() is searched until it's found or the
123 * end of the list is reached. Whenever a file
124 * is successfully opened, its path is also stored.
126 FILE * path_fopen(char * filename, char * mode)
128 int n;
129 FILE * f=NULL;
131 /* try first here */
132 if((f=fopen(filename, mode)) != NULL)
134 add_to_library_path(filename, 1);
135 return(f);
138 /* couldn't open; try concatenating all stored paths */
139 for(n=n_library_paths - 1;n >= 0;n--)
141 char tmp[4096];
143 snprintf(tmp, sizeof(tmp) - 1, "%s/%s",
144 library_path[n], filename);
145 tmp[sizeof(tmp) - 1]='\0';
147 if((f=fopen(tmp, mode)) != NULL)
149 add_to_library_path(tmp, 1);
150 break;
154 return(f);