From d310c2c3610765ef672bfeef060020834b8bf32d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Nov 2008 19:35:53 +0000 Subject: [PATCH] - Added CodeImp's submission for specifying include paths to ACC. SVN r1292 (trunk) --- acc.c | 71 +++++++++++++++++++++++++++------------- common.h | 4 +++ error.c | 1 + error.h | 3 +- misc.c | 16 +++++++++ misc.h | 1 + token.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++---------- token.h | 1 + 8 files changed, 155 insertions(+), 41 deletions(-) diff --git a/acc.c b/acc.c index ba52a46..01cea68 100644 --- a/acc.c +++ b/acc.c @@ -127,6 +127,7 @@ static void DisplayBanner(void) fprintf(stderr, "Even more changes by James Bentler\n"); fprintf(stderr, "Some additions by Michael \"Necromage\" Weber\n"); fprintf(stderr, "Error reporting improvements and limit expansion by Ty Halderman\n"); + fprintf(stderr, "Include paths added by Pascal vd Heiden\n"); } //========================================================================== @@ -158,21 +159,25 @@ static void Init(void) // // ProcessArgs // +// Pascal 12/11/08 +// Allowing space after options (option parameter as the next argument) +// //========================================================================== static void ProcessArgs(void) { - int i; - int count; + int i = 1; + int count = 0; char *text; char option; - - count = 0; - for(i = 1; i < ArgCount; i++) + + while(i < ArgCount) { text = ArgVector[i]; + if(*text == '-') { + // Option text++; if(*text == 0) { @@ -181,44 +186,63 @@ static void ProcessArgs(void) option = toupper(*text++); switch(option) { + case 'I': + if((i + 1) < ArgCount) + { + TK_AddIncludePath(ArgVector[++i]); + } + break; + case 'D': acs_DebugMode = YES; acs_VerboseMode = YES; - if(*text != 0) + if((i + 1) < ArgCount) { - OpenDebugFile(text); + OpenDebugFile(ArgVector[++i]); } break; + case 'H': pc_NoShrink = TRUE; pc_HexenCase = TRUE; break; + default: DisplayUsage(); break; } - continue; } - count++; - switch(count) + else { - case 1: - strcpy(acs_SourceFileName, text); - MS_SuggestFileExt(acs_SourceFileName, ".acs"); - break; - case 2: - strcpy(ObjectFileName, text); - MS_SuggestFileExt(ObjectFileName, ".o"); - break; - default: - DisplayUsage(); - break; + // Input/output file + count++; + switch(count) + { + case 1: + strcpy(acs_SourceFileName, text); + MS_SuggestFileExt(acs_SourceFileName, ".acs"); + break; + + case 2: + strcpy(ObjectFileName, text); + MS_SuggestFileExt(ObjectFileName, ".o"); + break; + + default: + DisplayUsage(); + break; + } } + + // Next arg + i++; } + if(count == 0) { DisplayUsage(); } + if(count == 1) { strcpy(ObjectFileName, acs_SourceFileName); @@ -236,8 +260,9 @@ static void ProcessArgs(void) static void DisplayUsage(void) { puts("\nUsage: ACC [options] source[.acs] [object[.o]]\n"); - puts("-d[file] Output debugging information"); - puts("-h Create pcode compatible with Hexen and old ZDooms"); + puts("-i [path] Add include path to find include files"); + puts("-d [file] Output debugging information"); + puts("-h Create pcode compatible with Hexen and old ZDooms"); exit(1); } diff --git a/common.h b/common.h index 081cd78..bc41786 100644 --- a/common.h +++ b/common.h @@ -56,6 +56,10 @@ #define MAX_IMPORTS 256 +// Max number of include paths the user can specify +// This includes the "working directory"! +#define MAX_INCLUDE_PATHS 16 + // Maximum number of translations that can be used #define MAX_TRANSLATIONS 32 diff --git a/error.c b/error.c index 29efae0..64de2c5 100644 --- a/error.c +++ b/error.c @@ -175,6 +175,7 @@ static struct { ERR_DISCONNECT_NEEDS_1_ARG, "Disconnect scripts must have 1 argument." }, { ERR_UNCLOSED_WITH_ARGS, "Most special scripts must not have arguments." }, { ERR_NOT_A_CHAR_ARRAY, "%s has %d dimensions. Use %d subscripts to get a char array." }, + { ERR_CANT_FIND_INCLUDE, "Couldn't find include file \"%s\"." }, { ERR_NONE, NULL } }; diff --git a/error.h b/error.h index cc44061..c144892 100644 --- a/error.h +++ b/error.h @@ -142,7 +142,8 @@ typedef enum ERR_NEED_ARRAY_SIZE, ERR_DISCONNECT_NEEDS_1_ARG, ERR_UNCLOSED_WITH_ARGS, - ERR_NOT_A_CHAR_ARRAY + ERR_NOT_A_CHAR_ARRAY, + ERR_CANT_FIND_INCLUDE } error_t; // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- diff --git a/misc.c b/misc.c index f7144ea..1b50db6 100644 --- a/misc.c +++ b/misc.c @@ -171,6 +171,22 @@ int MS_LoadFile(char *name, char **buffer) return size; } + +//========================================================================== +// +// MS_FileExists +// +// Pascal 21/11/08 +// +//========================================================================== +boolean MS_FileExists(char *name) +{ + struct stat info; + int ret = stat(name, &info); + return (ret == 0); +} + + //========================================================================== // // MS_SaveFile diff --git a/misc.h b/misc.h index bffe7c1..3011f9a 100644 --- a/misc.h +++ b/misc.h @@ -35,6 +35,7 @@ U_WORD MS_LittleUWORD(U_WORD val); // U_LONG MS_LittleULONG(U_LONG val); U_INT MS_LittleUINT(U_INT val); int MS_LoadFile(char *name, char **buffer); +boolean MS_FileExists(char *name); boolean MS_SaveFile(char *name, void *buffer, int length); int MS_StrCmp(char *s1, char *s2); char *MS_StrLwr(char *string); diff --git a/token.c b/token.c index 0864a92..7bd3695 100644 --- a/token.c +++ b/token.c @@ -62,7 +62,7 @@ typedef struct // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- static int SortKeywords(const void *a, const void *b); -static void MakeIncludePath(char *sourceName); +static void SetLocalIncludePath(char *sourceName); static int PopNestedSource(enum ImportModes *prevMode); static void ProcessLetterToken(void); static void ProcessNumberToken(void); @@ -114,10 +114,15 @@ static nestInfo_t OpenFiles[MAX_NESTED_SOURCES]; static boolean AlreadyGot; static int NestDepth; static boolean IncLineNumber; -static char IncludePath[MAX_FILE_NAME_LENGTH]; static char *FileNames; static size_t FileNamesLen, FileNamesMax; +// Pascal 11/12/08 +// Include paths. Lowest is searched first. +// Include path 0 is always set to the directory of the file being parsed. +static char IncludePaths[MAX_INCLUDE_PATHS][MAX_FILE_NAME_LENGTH]; +static int NumIncludePaths; + static struct keyword_s { char *name; @@ -229,6 +234,7 @@ void TK_Init(void) tk_String = TokenStringBuffer; IncLineNumber = FALSE; tk_IncludedLines = 0; + NumIncludePaths = 1; // the first path is always the parsed file path - Pascal 12/11/08 SourceOpen = FALSE; *MasterSourceLine = '\0'; // master line - Ty 07jan2000 MasterSourcePos = 0; // master position - Ty 07jan2000 @@ -264,7 +270,7 @@ void TK_OpenSource(char *fileName) TK_CloseSource(); size = MS_LoadFile(fileName, &FileStart); tk_SourceName = AddFileName(fileName); - MakeIncludePath(fileName); + SetLocalIncludePath(fileName); SourceOpen = TRUE; FileEnd = FileStart+size; FilePtr = FileStart; @@ -299,23 +305,55 @@ static char *AddFileName(const char *name) //========================================================================== // -// MakeIncludePath +// AddIncludePath +// This adds an include path with less priority than the ones already added +// +// Pascal 11/12/08 // //========================================================================== -static void MakeIncludePath(char *sourceName) +void TK_AddIncludePath(char *sourcePath) { - strcpy(IncludePath, sourceName); - if(MS_StripFilename(IncludePath) == NO) + if(NumIncludePaths < MAX_INCLUDE_PATHS) { - IncludePath[0] = 0; - } - else - { // Add a directory delimiter to the include path - strcat(IncludePath, DIRECTORY_DELIMITER); + // Add to list + strcpy(IncludePaths[NumIncludePaths], sourcePath); + + // Not ending with directory delimiter? + if((IncludePaths[NumIncludePaths] + strlen(IncludePaths[NumIncludePaths]) - 1) != DIRECTORY_DELIMITER_CHAR) + { + // Add a directory delimiter to the include path + strcat(IncludePaths[NumIncludePaths], DIRECTORY_DELIMITER); + } + NumIncludePaths++; } } + +//========================================================================== +// +// SetLocalIncludePath +// This sets the first include path +// +// Pascal 11/12/08 +// +//========================================================================== + +static void SetLocalIncludePath(char *sourceName) +{ + strcpy(IncludePaths[0], sourceName); + if(MS_StripFilename(IncludePaths[0]) == NO) + { + IncludePaths[0][0] = 0; + } + else + { + // Add a directory delimiter to the include path + strcat(IncludePaths[0], DIRECTORY_DELIMITER); + } +} + + //========================================================================== // // TK_Include @@ -325,9 +363,10 @@ static void MakeIncludePath(char *sourceName) void TK_Include(char *fileName) { char sourceName[MAX_FILE_NAME_LENGTH]; - int size; + int size, i; nestInfo_t *info; - + boolean foundfile = FALSE; + MS_Message(MSG_DEBUG, "*Including %s\n", fileName); if(NestDepth == MAX_NESTED_SOURCES) { @@ -342,8 +381,29 @@ void TK_Include(char *fileName) info->incLineNumber = IncLineNumber; info->lastChar = Chr; info->imported = NO; - strcpy(sourceName, IncludePath); - strcat(sourceName, fileName); + + // Pascal 11/12/08 + // Find the file in the include paths + for(i = 0; i < NumIncludePaths; i++) + { + strcpy(sourceName, IncludePaths[i]); + strcat(sourceName, fileName); + if(MS_FileExists(sourceName)) + { + foundfile = TRUE; + break; + } + } + + if(!foundfile) + { + ERR_ErrorAt(tk_SourceName, tk_Line); + ERR_Exit(ERR_CANT_FIND_INCLUDE, YES, fileName, tk_SourceName, tk_Line); + } + + // Now change the first include path to the file directory + SetLocalIncludePath(sourceName); + tk_SourceName = AddFileName(sourceName); size = MS_LoadFile(tk_SourceName, &FileStart); FileEnd = FileStart+size; @@ -379,7 +439,7 @@ void TK_Import(char *fileName, enum ImportModes prevMode) static int PopNestedSource(enum ImportModes *prevMode) { nestInfo_t *info; - + MS_Message(MSG_DEBUG, "*Leaving %s\n", tk_SourceName); free(FileStart); SY_FreeConstants(NestDepth); @@ -394,6 +454,11 @@ static int PopNestedSource(enum ImportModes *prevMode) Chr = info->lastChar; tk_Token = TK_NONE; AlreadyGot = FALSE; + + // Pascal 11/12/08 + // Set the first include path back to this file directory + SetLocalIncludePath(tk_SourceName); + *prevMode = info->prevMode; return info->imported ? 2 : 0; } diff --git a/token.h b/token.h index ec9eba4..f84db4e 100644 --- a/token.h +++ b/token.h @@ -146,6 +146,7 @@ void TK_Undo(void); void TK_SkipLine(void); void TK_SkipPast(tokenType_t token); void TK_SkipTo(tokenType_t token); +void TK_AddIncludePath(char *sourceName); // PUBLIC DATA DECLARATIONS ------------------------------------------------