OSDN Git Service

- Bio Hazard's ACC tweaks:
[zandronum/zandronum-acc.git] / token.c
diff --git a/token.c b/token.c
index 0864a92..d949b79 100644 (file)
--- a/token.c
+++ b/token.c
@@ -7,12 +7,18 @@
 \r
 // HEADER FILES ------------------------------------------------------------\r
 \r
+#if defined(_WIN32) && !defined(_MSC_VER)\r
+#define WIN32_LEAN_AND_MEAN\r
+#include <windows.h>\r
+#endif\r
+\r
 #ifdef __NeXT__\r
 #include <libc.h>\r
 #else\r
 #ifndef unix\r
 #include <io.h>\r
 #endif\r
+#include <limits.h>\r
 #include <fcntl.h>\r
 #include <stdlib.h>\r
 #endif\r
@@ -62,7 +68,7 @@ typedef struct
 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------\r
 \r
 static int SortKeywords(const void *a, const void *b);\r
-static void MakeIncludePath(char *sourceName);\r
+static void SetLocalIncludePath(char *sourceName);\r
 static int PopNestedSource(enum ImportModes *prevMode);\r
 static void ProcessLetterToken(void);\r
 static void ProcessNumberToken(void);\r
@@ -90,7 +96,7 @@ tokenType_t tk_Token;
 int tk_Line;\r
 int tk_Number;\r
 char *tk_String;\r
-U_BYTE tk_SpecialValue;\r
+int tk_SpecialValue;\r
 int tk_SpecialArgCount;\r
 char *tk_SourceName;\r
 int tk_IncludedLines;\r
@@ -114,10 +120,15 @@ static nestInfo_t OpenFiles[MAX_NESTED_SOURCES];
 static boolean AlreadyGot;\r
 static int NestDepth;\r
 static boolean IncLineNumber;\r
-static char IncludePath[MAX_FILE_NAME_LENGTH];\r
 static char *FileNames;\r
 static size_t FileNamesLen, FileNamesMax;\r
 \r
+// Pascal 12/11/08\r
+// Include paths. Lowest is searched first.\r
+// Include path 0 is always set to the directory of the file being parsed.\r
+static char IncludePaths[MAX_INCLUDE_PATHS][MAX_FILE_NAME_LENGTH];\r
+static int NumIncludePaths;\r
+\r
 static struct keyword_s\r
 {\r
        char *name;\r
@@ -178,6 +189,7 @@ static struct keyword_s
        { "libdefine", TK_LIBDEFINE },\r
        { "bool", TK_BOOL },\r
        { "net", TK_NET },\r
+       { "clientside", TK_CLIENTSIDE }, // [BB]\r
        { "disconnect", TK_DISCONNECT },\r
        { "unloading", TK_UNLOADING },\r
        { "static", TK_STATIC }\r
@@ -229,6 +241,7 @@ void TK_Init(void)
        tk_String = TokenStringBuffer;\r
        IncLineNumber = FALSE;\r
        tk_IncludedLines = 0;\r
+       NumIncludePaths = 1;    // the first path is always the parsed file path - Pascal 12/11/08\r
        SourceOpen = FALSE;\r
        *MasterSourceLine = '\0'; // master line - Ty 07jan2000\r
        MasterSourcePos = 0;      // master position - Ty 07jan2000\r
@@ -264,7 +277,7 @@ void TK_OpenSource(char *fileName)
        TK_CloseSource();\r
        size = MS_LoadFile(fileName, &FileStart);\r
        tk_SourceName = AddFileName(fileName);\r
-       MakeIncludePath(fileName);\r
+       SetLocalIncludePath(fileName);\r
        SourceOpen = TRUE;\r
        FileEnd = FileStart+size;\r
        FilePtr = FileStart;\r
@@ -299,23 +312,93 @@ static char *AddFileName(const char *name)
 \r
 //==========================================================================\r
 //\r
-// MakeIncludePath\r
+// TK_AddIncludePath\r
+// This adds an include path with less priority than the ones already added\r
+// \r
+// Pascal 12/11/08\r
 //\r
 //==========================================================================\r
 \r
-static void MakeIncludePath(char *sourceName)\r
+void TK_AddIncludePath(char *sourcePath)\r
 {\r
-       strcpy(IncludePath, sourceName);\r
-       if(MS_StripFilename(IncludePath) == NO)\r
+       if(NumIncludePaths < MAX_INCLUDE_PATHS)\r
        {\r
-               IncludePath[0] = 0;\r
+               // Add to list\r
+               strcpy(IncludePaths[NumIncludePaths], sourcePath);\r
+               \r
+               // Not ending with directory delimiter?\r
+               if(!MS_IsDirectoryDelimiter(*(IncludePaths[NumIncludePaths] + strlen(IncludePaths[NumIncludePaths]) - 1)))\r
+               {\r
+                       // Add a directory delimiter to the include path\r
+                       strcat(IncludePaths[NumIncludePaths], "/");\r
+               }\r
+               MS_Message(MSG_DEBUG, "Add include path %d: \"%s\"\n", NumIncludePaths, IncludePaths[NumIncludePaths]);\r
+               NumIncludePaths++;\r
        }\r
-       else\r
-       { // Add a directory delimiter to the include path\r
-               strcat(IncludePath, DIRECTORY_DELIMITER);\r
+}\r
+\r
+//==========================================================================\r
+//\r
+// TK_AddProgramIncludePath\r
+// Adds an include path for the directory of the executable.\r
+//\r
+//==========================================================================\r
+\r
+void TK_AddProgramIncludePath(char *progname)\r
+{\r
+       if(NumIncludePaths < MAX_INCLUDE_PATHS)\r
+       {\r
+#ifdef _WIN32\r
+#ifdef _MSC_VER\r
+#if _MSC_VER >= 1300\r
+               if (_get_pgmptr(&progname) != 0)\r
+               {\r
+                       return;\r
+               }\r
+#else\r
+               progname = _pgmptr;\r
+#endif\r
+#else\r
+               char progbuff[1024];\r
+               GetModuleFileName(0, progbuff, sizeof(progbuff));\r
+               progbuff[sizeof(progbuff)-1] = '\0';\r
+               progname = progbuff;\r
+#endif\r
+#else\r
+               char progbuff[PATH_MAX];\r
+               if (realpath(progname, progbuff) != NULL)\r
+               {\r
+                       progname = progbuff;\r
+               }\r
+#endif\r
+               strcpy(IncludePaths[NumIncludePaths], progname);\r
+               if(MS_StripFilename(IncludePaths[NumIncludePaths]))\r
+               {\r
+                       MS_Message(MSG_DEBUG, "Program include path is %d: \"%s\"\n", NumIncludePaths, IncludePaths[NumIncludePaths]);\r
+                       NumIncludePaths++;\r
+               }\r
+       }\r
+}\r
+\r
+//==========================================================================\r
+//\r
+// SetLocalIncludePath\r
+// This sets the first include path\r
+// \r
+// Pascal 12/11/08\r
+//\r
+//==========================================================================\r
+\r
+static void SetLocalIncludePath(char *sourceName)\r
+{\r
+       strcpy(IncludePaths[0], sourceName);\r
+       if(MS_StripFilename(IncludePaths[0]) == NO)\r
+       {\r
+               IncludePaths[0][0] = 0;\r
        }\r
 }\r
 \r
+\r
 //==========================================================================\r
 //\r
 // TK_Include\r
@@ -325,9 +408,10 @@ static void MakeIncludePath(char *sourceName)
 void TK_Include(char *fileName)\r
 {\r
        char sourceName[MAX_FILE_NAME_LENGTH];\r
-       int size;\r
+       int size, i;\r
        nestInfo_t *info;\r
-\r
+       boolean foundfile = FALSE;\r
+       \r
        MS_Message(MSG_DEBUG, "*Including %s\n", fileName);\r
        if(NestDepth == MAX_NESTED_SOURCES)\r
        {\r
@@ -342,8 +426,58 @@ void TK_Include(char *fileName)
        info->incLineNumber = IncLineNumber;\r
        info->lastChar = Chr;\r
        info->imported = NO;\r
-       strcpy(sourceName, IncludePath);\r
-       strcat(sourceName, fileName);\r
+       \r
+       // Pascal 30/11/08\r
+       // Handle absolute paths\r
+       if(MS_IsPathAbsolute(fileName))\r
+       {\r
+#if defined(_WIN32) || defined(__MSDOS__)\r
+               sourceName[0] = '\0';\r
+               if(MS_IsDirectoryDelimiter(fileName[0]))\r
+               {\r
+                       // The source file is absolute for the drive, but does not\r
+                       // specify a drive. Use the path for the current file to\r
+                       // get the drive letter, if it has one.\r
+                       if(IncludePaths[0][0] != '\0' && IncludePaths[0][1] == ':')\r
+                       {\r
+                               sourceName[0] = IncludePaths[0][0];\r
+                               sourceName[1] = ':';\r
+                               sourceName[2] = '\0';\r
+                       }\r
+               }\r
+               strcat(sourceName, fileName);\r
+#else\r
+               strcpy(sourceName, fileName);\r
+#endif\r
+               foundfile = MS_FileExists(sourceName);\r
+       }\r
+       else\r
+       {\r
+               // Pascal 12/11/08\r
+               // Find the file in the include paths\r
+               for(i = 0; i < NumIncludePaths; i++)\r
+               {\r
+                       strcpy(sourceName, IncludePaths[i]);\r
+                       strcat(sourceName, fileName);\r
+                       if(MS_FileExists(sourceName))\r
+                       {\r
+                               foundfile = TRUE;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       if(!foundfile)\r
+       {\r
+               ERR_ErrorAt(tk_SourceName, tk_Line);\r
+               ERR_Exit(ERR_CANT_FIND_INCLUDE, YES, fileName, tk_SourceName, tk_Line);\r
+       }\r
+\r
+       MS_Message(MSG_DEBUG, "*Include file found at %s\n", sourceName);\r
+\r
+       // Now change the first include path to the file directory\r
+       SetLocalIncludePath(sourceName);\r
+       \r
        tk_SourceName = AddFileName(sourceName);\r
        size = MS_LoadFile(tk_SourceName, &FileStart);\r
        FileEnd = FileStart+size;\r
@@ -379,7 +513,7 @@ void TK_Import(char *fileName, enum ImportModes prevMode)
 static int PopNestedSource(enum ImportModes *prevMode)\r
 {\r
        nestInfo_t *info;\r
-\r
+       \r
        MS_Message(MSG_DEBUG, "*Leaving %s\n", tk_SourceName);\r
        free(FileStart);\r
        SY_FreeConstants(NestDepth);\r
@@ -394,6 +528,11 @@ static int PopNestedSource(enum ImportModes *prevMode)
        Chr = info->lastChar;\r
        tk_Token = TK_NONE;\r
        AlreadyGot = FALSE;\r
+       \r
+       // Pascal 12/11/08\r
+       // Set the first include path back to this file directory\r
+       SetLocalIncludePath(tk_SourceName);\r
+       \r
        *prevMode = info->prevMode;\r
        return info->imported ? 2 : 0;\r
 }\r
@@ -534,7 +673,7 @@ int TK_NextCharacter(void)
 \r
 void TK_SkipPast(tokenType_t token)\r
 {\r
-       while (tk_Token != token)\r
+       while (tk_Token != token && tk_Token != TK_EOF)\r
        {\r
                TK_NextToken();\r
        }\r
@@ -549,7 +688,7 @@ void TK_SkipPast(tokenType_t token)
 \r
 void TK_SkipTo(tokenType_t token)\r
 {\r
-       while (tk_Token != token)\r
+       while (tk_Token != token && tk_Token != TK_EOF)\r
        {\r
                TK_NextToken();\r
        }\r
@@ -824,8 +963,8 @@ static void ProcessNumberToken(void)
 \r
 static void EvalFixedConstant(int whole)\r
 {\r
-       int frac;\r
-       int divisor;\r
+       double frac;\r
+       double divisor;\r
 \r
        frac = 0;\r
        divisor = 1;\r
@@ -835,7 +974,7 @@ static void EvalFixedConstant(int whole)
                divisor *= 10;\r
                NextChr();\r
        }\r
-       tk_Number = (whole<<16)+((frac<<16)/divisor);\r
+       tk_Number = (whole<<16)+(int)(65536.0*frac/divisor);\r
        tk_Token = TK_NUMBER;\r
 }\r
 \r
@@ -943,8 +1082,8 @@ static void ProcessQuoteToken(void)
                        *text++ = Chr;\r
                }\r
                // escape the character after a backslash [JB]\r
-               if(Chr == ASCII_BACKSLASH)\r
-                       escaped ^= (Chr == ASCII_BACKSLASH);\r
+               if(Chr == '\\')\r
+                       escaped ^= (Chr == '\\');\r
                else\r
                        escaped = FALSE;\r
                NextChr();\r
@@ -1240,6 +1379,7 @@ static void ProcessSpecialToken(void)
                                        tk_Number = '\r';\r
                                        break;\r
                                case '\'':\r
+                               case '\\':\r
                                        tk_Number = Chr;\r
                                        break;\r
                                default:\r