From: uz Date: Fri, 28 May 2010 12:00:12 +0000 (+0000) Subject: Changed search path logic: Include files are now search first in the directory X-Git-Tag: V2.13.3~756 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=02f5b5499efc472f3d19f1fecbb979dd4389f9df;p=cc65 Changed search path logic: Include files are now search first in the directory containing the file that had the #include statement. The path of the main file will also added to the front of the search path list, so includes will not be search in the current directory first, but in the directory that contains the main file. git-svn-id: svn://svn.cc65.org/cc65/trunk@4673 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/cc65/input.c b/src/cc65/input.c index 46d380969..d59ffc77a 100644 --- a/src/cc65/input.c +++ b/src/cc65/input.c @@ -42,6 +42,7 @@ /* common */ #include "check.h" #include "coll.h" +#include "fname.h" #include "print.h" #include "strbuf.h" #include "xmalloc.h" @@ -87,9 +88,10 @@ struct IFile { /* Struct that describes an active input file */ typedef struct AFile AFile; struct AFile { - unsigned Line; /* Line number for this file */ - FILE* F; /* Input file stream */ - IFile* Input; /* Points to corresponding IFile */ + unsigned Line; /* Line number for this file */ + FILE* F; /* Input file stream */ + IFile* Input; /* Points to corresponding IFile */ + int SearchPath; /* True if we've added a path for this file */ }; /* List of all input files */ @@ -142,8 +144,12 @@ static IFile* NewIFile (const char* Name, InputType Type) static AFile* NewAFile (IFile* IF, FILE* F) -/* Create and return a new AFile */ +/* Create a new AFile, push it onto the stack, add the path of the file to + * the path search list, and finally return a pointer to the new AFile struct. + */ { + const char* Filename; + /* Allocate a AFile structure */ AFile* AF = (AFile*) xmalloc (sizeof (AFile)); @@ -158,7 +164,7 @@ static AFile* NewAFile (IFile* IF, FILE* F) */ if (IF->Usage++ == 0) { - /* Get file size and modification time. There a race condition here, + /* Get file size and modification time. There a race condition here, * since we cannot use fileno() (non standard identifier in standard * header file), and therefore not fstat. When using stat with the * file name, there's a risk that the file was deleted and recreated @@ -166,21 +172,40 @@ static AFile* NewAFile (IFile* IF, FILE* F) * if a file has changed in the debugger, we will ignore this problem * here. */ - struct stat Buf; - if (stat (IF->Name, &Buf) != 0) { - /* Error */ - Fatal ("Cannot stat `%s': %s", IF->Name, strerror (errno)); - } + struct stat Buf; + if (stat (IF->Name, &Buf) != 0) { + /* Error */ + Fatal ("Cannot stat `%s': %s", IF->Name, strerror (errno)); + } IF->Size = (unsigned long) Buf.st_size; - IF->MTime = (unsigned long) Buf.st_mtime; + IF->MTime = (unsigned long) Buf.st_mtime; - /* Set the debug data */ - g_fileinfo (IF->Name, IF->Size, IF->MTime); + /* Set the debug data */ + g_fileinfo (IF->Name, IF->Size, IF->MTime); } /* Insert the new structure into the AFile collection */ CollAppend (&AFiles, AF); + /* Get the path of this file. If it is not empty, add it as an extra + * search path. To avoid file search overhead, we will not add empty + * paths, since the search path list is initialized with an empty + * path, so files in the current directory are always found first. + */ + Filename = FindName (IF->Name); + AF->SearchPath = (Filename - IF->Name); /* Actually the length */ + if (AF->SearchPath) { + /* We have a path, extract and push it to the search path list */ + StrBuf Path = AUTO_STRBUF_INITIALIZER; + SB_CopyBuf (&Path, IF->Name, AF->SearchPath); + SB_Terminate (&Path); + if (PushSearchPath (UsrIncSearchPath, SB_GetConstBuf (&Path)) == 0) { + /* The path is already there ... */ + AF->SearchPath = 0; + } + SB_Done (&Path); + } + /* Return the new struct */ return AF; } @@ -324,6 +349,11 @@ static void CloseIncludeFile (void) /* Delete the last active file from the active file collection */ CollDelete (&AFiles, AFileCount-1); + /* If we had added an extra search path for this AFile, remove it */ + if (Input->SearchPath) { + PopSearchPath (UsrIncSearchPath); + } + /* Delete the active file structure */ FreeAFile (Input); }