1 /*****************************************************************************/
5 /* Search path path handling for ld65 */
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 /* A search path list is a collection containing path elements. We have
63 static Collection SearchPaths[MAX_SEARCH_PATHS] = {
64 STATIC_COLLECTION_INITIALIZER,
65 STATIC_COLLECTION_INITIALIZER,
66 STATIC_COLLECTION_INITIALIZER,
67 STATIC_COLLECTION_INITIALIZER,
68 STATIC_COLLECTION_INITIALIZER,
69 STATIC_COLLECTION_INITIALIZER,
70 STATIC_COLLECTION_INITIALIZER,
71 STATIC_COLLECTION_INITIALIZER,
76 /*****************************************************************************/
78 /*****************************************************************************/
82 static void Add (Collection* Paths, const char* New)
83 /* Cleanup a new search path and add it to the list */
88 /* Get the length of the new path */
89 NewLen = strlen (New);
91 /* Check for a trailing path separator and remove it */
92 if (NewLen > 0 && (New[NewLen-1] == '\\' || New[NewLen-1] == '/')) {
96 /* Allocate memory for the new string */
97 NewPath = (char*) xmalloc (NewLen + 1);
99 /* Copy the path and terminate it */
100 memcpy (NewPath, New, NewLen);
101 NewPath [NewLen] = '\0';
103 /* Add the path to the collection */
104 CollAppend (Paths, NewPath);
109 static char* Find (const Collection* PathList, const char* File)
110 /* Search for a file in a list of directories. If found, return the complete
111 * name including the path in a malloced data area, if not found, return 0.
115 StrBuf PathName = AUTO_STRBUF_INITIALIZER;
117 /* Start the search */
119 for (I = 0; I < CollCount (PathList); ++I) {
121 /* Copy the next path element into the buffer */
122 SB_CopyStr (&PathName, CollConstAt (PathList, I));
124 /* Add a path separator and the filename */
125 if (SB_NotEmpty (&PathName)) {
126 SB_AppendChar (&PathName, '/');
128 SB_AppendStr (&PathName, File);
129 SB_Terminate (&PathName);
131 /* Check if this file exists */
132 if (access (SB_GetBuf (&PathName), 0) == 0) {
133 /* The file exists, we're done */
134 Name = xstrdup (SB_GetBuf (&PathName));
139 /* Cleanup and return the result of the search */
146 void AddSearchPath (const char* NewPath, unsigned Where)
147 /* Add a new search path to the existing one */
149 /* Allow a NULL path */
152 for (I = 0; I < MAX_SEARCH_PATHS; ++I) {
153 if (Where & (0x01U << I)) {
154 Add (&SearchPaths[I], NewPath);
162 void AddSearchPathFromEnv (const char* EnvVar, unsigned Where)
163 /* Add a search path from an environment variable */
165 AddSearchPath (getenv (EnvVar), Where);
170 void AddSubSearchPathFromEnv (const char* EnvVar, const char* SubDir, unsigned Where)
171 /* Add a search path from an environment variable, adding a subdirectory to
172 * the environment variable value.
175 StrBuf Dir = AUTO_STRBUF_INITIALIZER;
177 const char* EnvVal = getenv (EnvVar);
183 /* Copy the environment variable to the buffer */
184 SB_CopyStr (&Dir, EnvVal);
186 /* Add a path separator if necessary */
187 if (SB_NotEmpty (&Dir)) {
188 if (SB_LookAtLast (&Dir) != '\\' && SB_LookAtLast (&Dir) != '/') {
189 SB_AppendChar (&Dir, '/');
193 /* Add the subdirectory */
194 SB_AppendStr (&Dir, SubDir);
196 /* Terminate the string */
199 /* Add the search path */
200 AddSearchPath (SB_GetConstBuf (&Dir), Where);
202 /* Free the temp buffer */
208 void ForgetAllSearchPaths (unsigned Where)
209 /* Forget all search paths in the given lists. */
212 for (I = 0; I < MAX_SEARCH_PATHS; ++I) {
213 if (Where & (0x01U << I)) {
215 Collection* P = &SearchPaths[I];
216 for (J = 0; J < CollCount (P); ++J) {
217 xfree (CollAt (P, J));
226 char* SearchFile (const char* Name, unsigned Where)
227 /* Search for a file in a list of directories. Return a pointer to a malloced
228 * area that contains the complete path, if found, return 0 otherwise.
232 for (I = 0; I < MAX_SEARCH_PATHS; ++I) {
233 if (Where & (0x01U << I)) {
234 char* Path = Find (&SearchPaths[I], Name);