1 /*****************************************************************************/
5 /* Handling of search paths */
9 /* (C) 2000-2010, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
39 /* Microsoft compiler */
48 #include "searchpath.h"
54 /*****************************************************************************/
56 /*****************************************************************************/
60 static char* CleanupPath (const char* Path)
61 /* Prepare and return a clean copy of Path */
66 /* Get the length of the path */
69 /* Check for a trailing path separator and remove it */
70 if (Len > 0 && (Path[Len-1] == '\\' || Path[Len-1] == '/')) {
74 /* Allocate memory for the new string */
75 NewPath = (char*) xmalloc (Len + 1);
77 /* Copy the path and terminate it, then return the copy */
78 memcpy (NewPath, Path, Len);
85 static void Add (SearchPath* P, const char* New)
86 /* Cleanup a new search path and add it to the list */
88 /* Add a clean copy of the path to the collection */
89 CollAppend (P, CleanupPath (New));
94 SearchPath* NewSearchPath (void)
95 /* Create a new, empty search path list */
97 return NewCollection ();
102 void AddSearchPath (SearchPath* P, const char* NewPath)
103 /* Add a new search path to the end of an existing list */
105 /* Allow a NULL path */
113 void AddSearchPathFromEnv (SearchPath* P, const char* EnvVar)
114 /* Add a search path from an environment variable to the end of an existing
118 AddSearchPath (P, getenv (EnvVar));
123 void AddSubSearchPathFromEnv (SearchPath* P, const char* EnvVar, const char* SubDir)
124 /* Add a search path from an environment variable, adding a subdirectory to
125 * the environment variable value.
128 StrBuf Dir = AUTO_STRBUF_INITIALIZER;
130 const char* EnvVal = getenv (EnvVar);
136 /* Copy the environment variable to the buffer */
137 SB_CopyStr (&Dir, EnvVal);
139 /* Add a path separator if necessary */
140 if (SB_NotEmpty (&Dir)) {
141 if (SB_LookAtLast (&Dir) != '\\' && SB_LookAtLast (&Dir) != '/') {
142 SB_AppendChar (&Dir, '/');
146 /* Add the subdirectory and terminate the string */
147 SB_AppendStr (&Dir, SubDir);
150 /* Add the search path */
151 AddSearchPath (P, SB_GetConstBuf (&Dir));
153 /* Free the temp buffer */
159 void PushSearchPath (SearchPath* P, const char* NewPath)
160 /* Add a new search path to the head of an existing search path list */
162 /* Insert a clean copy of the path at position 0 */
163 CollInsert (P, CleanupPath (NewPath), 0);
168 void PopSearchPath (SearchPath* P)
169 /* Remove a search path from the head of an existing search path list */
171 /* Remove the path at position 0 */
172 xfree (CollAt (P, 0));
178 void ForgetSearchPath (SearchPath* P)
179 /* Forget all search paths in the given list */
182 for (I = 0; I < CollCount (P); ++I) {
183 xfree (CollAt (P, I));
190 char* SearchFile (const SearchPath* P, const char* File)
191 /* Search for a file in a list of directories. Return a pointer to a malloced
192 * area that contains the complete path, if found, return 0 otherwise.
196 StrBuf PathName = AUTO_STRBUF_INITIALIZER;
198 /* Start the search */
200 for (I = 0; I < CollCount (P); ++I) {
202 /* Copy the next path element into the buffer */
203 SB_CopyStr (&PathName, CollConstAt (P, I));
205 /* Add a path separator and the filename */
206 if (SB_NotEmpty (&PathName)) {
207 SB_AppendChar (&PathName, '/');
209 SB_AppendStr (&PathName, File);
210 SB_Terminate (&PathName);
212 /* Check if this file exists */
213 if (access (SB_GetBuf (&PathName), 0) == 0) {
214 /* The file exists, we're done */
215 Name = xstrdup (SB_GetBuf (&PathName));
220 /* Cleanup and return the result of the search */