X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcommon%2Fsearchpath.c;h=21750229903439d01a03ecca29fc181e5938288b;hb=0d8e8a95338560a1e0d96258d6def311cf2ad368;hp=d71326b8b170e14151b98b062d87b4493952d52e;hpb=39108e20b56ced16dbc09782c03dc7034cb32373;p=cc65 diff --git a/src/common/searchpath.c b/src/common/searchpath.c index d71326b8b..217502299 100644 --- a/src/common/searchpath.c +++ b/src/common/searchpath.c @@ -2,7 +2,7 @@ /* */ /* searchpath.h */ /* */ -/* Search path path handling for ld65 */ +/* Handling of search paths */ /* */ /* */ /* */ @@ -52,122 +52,75 @@ /*****************************************************************************/ -/* Data */ +/* Code */ /*****************************************************************************/ -/* A search path list is a collection containing path elements. We have - * several of those. - */ -static Collection SearchPaths[MAX_SEARCH_PATHS] = { - STATIC_COLLECTION_INITIALIZER, - STATIC_COLLECTION_INITIALIZER, - STATIC_COLLECTION_INITIALIZER, - STATIC_COLLECTION_INITIALIZER, - STATIC_COLLECTION_INITIALIZER, - STATIC_COLLECTION_INITIALIZER, - STATIC_COLLECTION_INITIALIZER, - STATIC_COLLECTION_INITIALIZER, -}; - - - -/*****************************************************************************/ -/* Code */ -/*****************************************************************************/ - - - -static void Add (Collection* Paths, const char* New) -/* Cleanup a new search path and add it to the list */ +static char* CleanupPath (const char* Path) +/* Prepare and return a clean copy of Path */ { - unsigned NewLen; + unsigned Len; char* NewPath; - /* Get the length of the new path */ - NewLen = strlen (New); + /* Get the length of the path */ + Len = strlen (Path); /* Check for a trailing path separator and remove it */ - if (NewLen > 0 && (New[NewLen-1] == '\\' || New[NewLen-1] == '/')) { - --NewLen; + if (Len > 0 && (Path[Len-1] == '\\' || Path[Len-1] == '/')) { + --Len; } /* Allocate memory for the new string */ - NewPath = (char*) xmalloc (NewLen + 1); + NewPath = (char*) xmalloc (Len + 1); - /* Copy the path and terminate it */ - memcpy (NewPath, New, NewLen); - NewPath [NewLen] = '\0'; - - /* Add the path to the collection */ - CollAppend (Paths, NewPath); + /* Copy the path and terminate it, then return the copy */ + memcpy (NewPath, Path, Len); + NewPath [Len] = '\0'; + return NewPath; } -static char* Find (const Collection* PathList, const char* File) -/* Search for a file in a list of directories. If found, return the complete - * name including the path in a malloced data area, if not found, return 0. - */ -{ - char* Name = 0; - StrBuf PathName = AUTO_STRBUF_INITIALIZER; - - /* Start the search */ - unsigned I; - for (I = 0; I < CollCount (PathList); ++I) { - - /* Copy the next path element into the buffer */ - SB_CopyStr (&PathName, CollConstAt (PathList, I)); +static void Add (SearchPath* P, const char* New) +/* Cleanup a new search path and add it to the list */ +{ + /* Add a clean copy of the path to the collection */ + CollAppend (P, CleanupPath (New)); +} - /* Add a path separator and the filename */ - if (SB_NotEmpty (&PathName)) { - SB_AppendChar (&PathName, '/'); - } - SB_AppendStr (&PathName, File); - SB_Terminate (&PathName); - /* Check if this file exists */ - if (access (SB_GetBuf (&PathName), 0) == 0) { - /* The file exists, we're done */ - Name = xstrdup (SB_GetBuf (&PathName)); - break; - } - } - /* Cleanup and return the result of the search */ - SB_Done (&PathName); - return Name; +SearchPath* NewSearchPath (void) +/* Create a new, empty search path list */ +{ + return NewCollection (); } -void AddSearchPath (const char* NewPath, unsigned Where) -/* Add a new search path to the existing one */ +void AddSearchPath (SearchPath* P, const char* NewPath) +/* Add a new search path to the end of an existing list */ { /* Allow a NULL path */ if (NewPath) { - unsigned I; - for (I = 0; I < MAX_SEARCH_PATHS; ++I) { - if (Where & (0x01U << I)) { - Add (&SearchPaths[I], NewPath); - } - } + Add (P, NewPath); } } -void AddSearchPathFromEnv (const char* EnvVar, unsigned Where) -/* Add a search path from an environment variable */ +void AddSearchPathFromEnv (SearchPath* P, const char* EnvVar) +/* Add a search path from an environment variable to the end of an existing + * list. + */ { - AddSearchPath (getenv (EnvVar), Where); + AddSearchPath (P, getenv (EnvVar)); } -void AddSubSearchPathFromEnv (const char* EnvVar, const char* SubDir, unsigned Where) +void AddSubSearchPathFromEnv (SearchPath* P, const char* EnvVar, const char* SubDir) /* Add a search path from an environment variable, adding a subdirectory to * the environment variable value. */ @@ -190,14 +143,12 @@ void AddSubSearchPathFromEnv (const char* EnvVar, const char* SubDir, unsigned W } } - /* Add the subdirectory */ + /* Add the subdirectory and terminate the string */ SB_AppendStr (&Dir, SubDir); - - /* Terminate the string */ SB_Terminate (&Dir); /* Add the search path */ - AddSearchPath (SB_GetConstBuf (&Dir), Where); + AddSearchPath (P, SB_GetConstBuf (&Dir)); /* Free the temp buffer */ SB_Done (&Dir); @@ -205,40 +156,84 @@ void AddSubSearchPathFromEnv (const char* EnvVar, const char* SubDir, unsigned W -void ForgetAllSearchPaths (unsigned Where) -/* Forget all search paths in the given lists. */ +int PushSearchPath (SearchPath* P, const char* NewPath) +/* Add a new search path to the head of an existing search path list, provided + * that it's not already there. If the path is already at the first position, + * return zero, otherwise return a non zero value. + */ +{ + /* Generate a clean copy of NewPath */ + char* Path = CleanupPath (NewPath); + + /* If we have paths, check if Path is already at position zero */ + if (CollCount (P) > 0 && strcmp (CollConstAt (P, 0), Path) == 0) { + /* Match. Delete the copy and return to the caller */ + xfree (Path); + return 0; + } + + /* Insert a clean copy of the path at position 0, return success */ + CollInsert (P, Path, 0); + return 1; +} + + + +void PopSearchPath (SearchPath* P) +/* Remove a search path from the head of an existing search path list */ +{ + /* Remove the path at position 0 */ + xfree (CollAt (P, 0)); + CollDelete (P, 0); +} + + + +void ForgetSearchPath (SearchPath* P) +/* Forget all search paths in the given list */ { unsigned I; - for (I = 0; I < MAX_SEARCH_PATHS; ++I) { - if (Where & (0x01U << I)) { - unsigned J; - Collection* P = &SearchPaths[I]; - for (J = 0; J < CollCount (P); ++J) { - xfree (CollAt (P, J)); - } - CollDeleteAll (P); - } + for (I = 0; I < CollCount (P); ++I) { + xfree (CollAt (P, I)); } + CollDeleteAll (P); } -char* SearchFile (const char* Name, unsigned Where) +char* SearchFile (const SearchPath* P, const char* File) /* Search for a file in a list of directories. Return a pointer to a malloced * area that contains the complete path, if found, return 0 otherwise. */ { + char* Name = 0; + StrBuf PathName = AUTO_STRBUF_INITIALIZER; + + /* Start the search */ unsigned I; - for (I = 0; I < MAX_SEARCH_PATHS; ++I) { - if (Where & (0x01U << I)) { - char* Path = Find (&SearchPaths[I], Name); - if (Path) { - /* Found the file */ - return Path; - } - } + for (I = 0; I < CollCount (P); ++I) { + + /* Copy the next path element into the buffer */ + SB_CopyStr (&PathName, CollConstAt (P, I)); + + /* Add a path separator and the filename */ + if (SB_NotEmpty (&PathName)) { + SB_AppendChar (&PathName, '/'); + } + SB_AppendStr (&PathName, File); + SB_Terminate (&PathName); + + /* Check if this file exists */ + if (access (SB_GetBuf (&PathName), 0) == 0) { + /* The file exists, we're done */ + Name = xstrdup (SB_GetBuf (&PathName)); + break; + } } - return 0; + + /* Cleanup and return the result of the search */ + SB_Done (&PathName); + return Name; }