]> git.sur5r.net Git - cc65/blob - src/common/searchpath.c
Removed unused header.
[cc65] / src / common / searchpath.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                               searchpath.h                                */
4 /*                                                                           */
5 /*                         Handling of search paths                          */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2000-2013, Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <stdlib.h>
37 #include <string.h>
38 #if defined(_WIN32)
39 #  include <windows.h>
40 #endif
41 #if defined(_MSC_VER)
42 /* Microsoft compiler */
43 #  include <io.h>
44 #  pragma warning(disable : 4996)
45 #else
46 /* Anyone else */
47 #  include <unistd.h>
48 #endif
49
50 /* common */
51 #include "coll.h"
52 #include "searchpath.h"
53 #include "strbuf.h"
54 #include "xmalloc.h"
55
56
57
58 /*****************************************************************************/
59 /*                                   Code                                    */
60 /*****************************************************************************/
61
62
63
64 static char* CleanupPath (const char* Path)
65 /* Prepare and return a clean copy of Path */
66 {
67     unsigned Len;
68     char*    NewPath;
69
70     /* Get the length of the path */
71     Len = strlen (Path);
72
73     /* Check for a trailing path separator and remove it */
74     if (Len > 0 && (Path[Len-1] == '\\' || Path[Len-1] == '/')) {
75         --Len;
76     }
77
78     /* Allocate memory for the new string */
79     NewPath = (char*) xmalloc (Len + 1);
80
81     /* Copy the path and terminate it, then return the copy */
82     memcpy (NewPath, Path, Len);
83     NewPath [Len] = '\0';
84     return NewPath;
85 }
86
87
88
89 static void Add (SearchPaths* P, const char* New)
90 /* Cleanup a new search path and add it to the list */
91 {
92     /* Add a clean copy of the path to the collection */
93     CollAppend (P, CleanupPath (New));
94 }
95
96
97
98 SearchPaths* NewSearchPath (void)
99 /* Create a new, empty search path list */
100 {
101     return NewCollection ();
102 }
103
104
105
106 void AddSearchPath (SearchPaths* P, const char* NewPath)
107 /* Add a new search path to the end of an existing list */
108 {
109     /* Allow a NULL path */
110     if (NewPath) {
111         Add (P, NewPath);
112     }
113 }
114
115
116
117 void AddSearchPathFromEnv (SearchPaths* P, const char* EnvVar)
118 /* Add a search path from an environment variable to the end of an existing
119  * list.
120  */
121 {
122     AddSearchPath (P, getenv (EnvVar));
123 }
124
125
126
127 void AddSubSearchPathFromEnv (SearchPaths* P, const char* EnvVar, const char* SubDir)
128 /* Add a search path from an environment variable, adding a subdirectory to
129  * the environment variable value.
130  */
131 {
132     StrBuf Dir = AUTO_STRBUF_INITIALIZER;
133
134     const char* EnvVal = getenv (EnvVar);
135     if (EnvVal == 0) {
136         /* Not found */
137         return;
138     }
139
140     /* Copy the environment variable to the buffer */
141     SB_CopyStr (&Dir, EnvVal);
142
143     /* Add a path separator if necessary */
144     if (SB_NotEmpty (&Dir)) {
145         if (SB_LookAtLast (&Dir) != '\\' && SB_LookAtLast (&Dir) != '/') {
146             SB_AppendChar (&Dir, '/');
147         }
148     }
149
150     /* Add the subdirectory and terminate the string */
151     SB_AppendStr (&Dir, SubDir);
152     SB_Terminate (&Dir);
153
154     /* Add the search path */
155     AddSearchPath (P, SB_GetConstBuf (&Dir));
156
157     /* Free the temp buffer */
158     SB_Done (&Dir);
159 }
160
161
162
163 void AddSubSearchPathFromWinBin (SearchPaths* P, const char* SubDir)
164 {
165 /* Windows only:
166  * Add a search path from the running binary, adding a subdirectory to
167  * the parent directory of the directory containing the binary.
168  */
169 #if defined(_WIN32)
170
171     char Dir[_MAX_PATH];
172     char* Ptr;
173
174     if (GetModuleFileName (NULL, Dir, _MAX_PATH) == 0) {
175         return;
176     }
177
178     /* Remove binary name */
179     Ptr = strrchr (Dir, '\\');
180     if (Ptr == 0) {
181         return;
182     }
183     *Ptr = '\0';
184
185     /* Check for 'bin' directory */
186     Ptr = strrchr (Dir, '\\');
187     if (Ptr == 0) {
188         return;
189     }
190     if (strcmp (Ptr++, "\\bin") != 0) {
191         return;
192     }
193
194     /* Append SubDir */
195     strcpy (Ptr, SubDir);
196
197     /* Add the search path */
198     AddSearchPath (P, Dir);
199
200 #else
201
202     (void) P;
203     (void) SubDir;
204
205 #endif
206 }
207
208
209 int PushSearchPath (SearchPaths* P, const char* NewPath)
210 /* Add a new search path to the head of an existing search path list, provided
211  * that it's not already there. If the path is already at the first position,
212  * return zero, otherwise return a non zero value.
213  */
214 {                                      
215     /* Generate a clean copy of NewPath */
216     char* Path = CleanupPath (NewPath);   
217
218     /* If we have paths, check if Path is already at position zero */
219     if (CollCount (P) > 0 && strcmp (CollConstAt (P, 0), Path) == 0) {
220         /* Match. Delete the copy and return to the caller */
221         xfree (Path);
222         return 0;
223     }
224
225     /* Insert a clean copy of the path at position 0, return success */
226     CollInsert (P, Path, 0);
227     return 1;
228 }
229
230
231
232 void PopSearchPath (SearchPaths* P)
233 /* Remove a search path from the head of an existing search path list */
234 {
235     /* Remove the path at position 0 */
236     xfree (CollAt (P, 0));
237     CollDelete (P, 0);
238 }
239
240
241
242 char* SearchFile (const SearchPaths* P, const char* File)
243 /* Search for a file in a list of directories. Return a pointer to a malloced
244  * area that contains the complete path, if found, return 0 otherwise.
245  */
246 {
247     char* Name = 0;
248     StrBuf PathName = AUTO_STRBUF_INITIALIZER;
249
250     /* Start the search */
251     unsigned I;
252     for (I = 0; I < CollCount (P); ++I) {
253
254         /* Copy the next path element into the buffer */
255         SB_CopyStr (&PathName, CollConstAt (P, I));
256
257         /* Add a path separator and the filename */
258         if (SB_NotEmpty (&PathName)) {
259             SB_AppendChar (&PathName, '/');
260         }
261         SB_AppendStr (&PathName, File);
262         SB_Terminate (&PathName);
263
264         /* Check if this file exists */
265         if (access (SB_GetBuf (&PathName), 0) == 0) {
266             /* The file exists, we're done */
267             Name = xstrdup (SB_GetBuf (&PathName));
268             break;
269         }
270     }
271
272     /* Cleanup and return the result of the search */
273     SB_Done (&PathName);
274     return Name;
275 }