scriplib.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 1997-2001 Id Software, Inc.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 
00024 */
00025 
00026 
00027 #include "shared.h"
00028 #include "scriplib.h"
00029 
00030 /*
00031 =============================================================================
00032 PARSING STUFF
00033 =============================================================================
00034 */
00035 
00036 typedef struct {
00037     char    filename[MAX_OSPATH];
00038     char    *buffer;
00039     char    *script_p;
00040     char    *end_p;
00041     int     line;
00042 } script_t;
00043 
00044 #define MAX_INCLUDES    2
00045 static script_t scriptstack[MAX_INCLUDES];
00046 static script_t *script;
00047 
00048 char parsedToken[MAX_TOKEN_CHARS];
00049 
00050 int GetScriptLine (void)
00051 {
00052     assert(script);
00053     return script->line;
00054 }
00055 
00059 static void AddScriptToStack (const char *filename)
00060 {
00061     int size;
00062 
00063     assert(script);
00064 
00065     script++;
00066     if (script == &scriptstack[MAX_INCLUDES])
00067         Sys_Error("script file exceeded MAX_INCLUDES");
00068     strncpy(script->filename, filename, sizeof(script->filename));
00069 
00070     size = FS_LoadFile(script->filename, (byte **)&script->buffer);
00071     if (size == -1)
00072         Sys_Error("file '%s' doesn't exist", script->filename);
00073 
00074     Verb_Printf(VERB_LESS, "entering %s\n", script->filename);
00075 
00076     script->line = 1;
00077 
00078     script->script_p = script->buffer;
00079     script->end_p = script->buffer + size;
00080 }
00081 
00082 void LoadScriptFile (const char *filename)
00083 {
00084     script = scriptstack;
00085     AddScriptToStack(filename);
00086 }
00087 
00091 void ParseFromMemory (char *buffer, int size)
00092 {
00093     script = scriptstack;
00094     script++;
00095     if (script == &scriptstack[MAX_INCLUDES])
00096         Sys_Error("script file exceeded MAX_INCLUDES");
00097     Q_strncpyz(script->filename, "memory buffer", sizeof(script->filename));
00098 
00099     script->buffer = buffer;
00100     script->line = 1;
00101     script->script_p = script->buffer;
00102     script->end_p = script->buffer + size;
00103 }
00104 
00105 static qboolean EndOfScript (qboolean crossline)
00106 {
00107     assert(script);
00108 
00109     if (!crossline)
00110         Sys_Error("Line %i is incomplete\n", script->line);
00111 
00112     /* not if the current script is a memory buffer */
00113     if (!strcmp(script->filename, "memory buffer"))
00114         return qfalse;
00115 
00116     Mem_Free(script->buffer);
00117     if (script == scriptstack + 1)
00118         return qfalse;
00119 
00120     script--;
00121     Com_Printf("returning to %s\n", script->filename);
00122     return GetToken(crossline);
00123 }
00124 
00131 qboolean GetToken (qboolean crossline)
00132 {
00133     char *token_p;
00134 
00135     assert(script);
00136 
00137     if (script->script_p >= script->end_p)
00138         return EndOfScript(crossline);
00139 
00140     /* skip space */
00141 skipspace:
00142     while (*script->script_p <= ' ') {
00143         if (script->script_p >= script->end_p)
00144             return EndOfScript(crossline);
00145         if (*script->script_p++ == '\n') {
00146             if (!crossline)
00147                 Sys_Error("Line %i is incomplete\n", script->line);
00148             script->line++;
00149         }
00150     }
00151 
00152     if (script->script_p >= script->end_p)
00153         return EndOfScript(crossline);
00154 
00155     /* // comments */
00156     if (script->script_p[0] == '/' && script->script_p[1] == '/') {
00157         if (!crossline)
00158             Sys_Error("Line %i is incomplete\n", script->line);
00159         while (*script->script_p++ != '\n')
00160             if (script->script_p >= script->end_p)
00161                 return EndOfScript(crossline);
00162         script->line++;
00163         goto skipspace;
00164     }
00165 
00166     /* copy token */
00167     token_p = parsedToken;
00168 
00169     if (*script->script_p == '"') {
00170         /* quoted token */
00171         script->script_p++;
00172         while (*script->script_p != '"') {
00173             *token_p++ = *script->script_p++;
00174             if (script->script_p == script->end_p)
00175                 break;
00176             if (token_p == &parsedToken[MAX_TOKEN_CHARS])
00177                 Sys_Error("Token too large on line %i\n", script->line);
00178         }
00179         script->script_p++;
00180     } else  /* regular token */
00181         while (*script->script_p > ' ') {
00182             *token_p++ = *script->script_p++;
00183             if (script->script_p == script->end_p)
00184                 break;
00185             if (token_p == &parsedToken[MAX_TOKEN_CHARS])
00186                 Sys_Error("Token too large on line %i\n", script->line);
00187         }
00188 
00189     *token_p = 0;
00190 
00191     return qtrue;
00192 }
00193 
00194 
00198 qboolean TokenAvailable (void)
00199 {
00200     char *search_p;
00201 
00202     assert(script);
00203 
00204     search_p = script->script_p;
00205 
00206     if (search_p >= script->end_p)
00207         return qfalse;
00208 
00209     while (*search_p <= ' ') {
00210         if (*search_p == '\n')
00211             return qfalse;
00212         search_p++;
00213         if (search_p == script->end_p)
00214             return qfalse;
00215     }
00216 
00217     return qtrue;
00218 }

Generated by  doxygen 1.6.2