Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

scriplib.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 // scriplib.c
00023 
00024 #include "cmdlib.h"
00025 #include "scriplib.h"
00026 
00027 /*
00028 =============================================================================
00029 
00030                         PARSING STUFF
00031 
00032 =============================================================================
00033 */
00034 
00035 typedef struct
00036 {
00037     char    filename[1024];
00038     char    *buffer,*script_p,*end_p;
00039     int     line;
00040 } script_t;
00041 
00042 #define MAX_INCLUDES    8
00043 script_t    scriptstack[MAX_INCLUDES];
00044 script_t    *script;
00045 int         scriptline;
00046 
00047 char    token[MAXTOKEN];
00048 qboolean endofscript;
00049 qboolean tokenready;                     // only qtrue if UnGetToken was just called
00050 
00051 /*
00052 ==============
00053 AddScriptToStack
00054 ==============
00055 */
00056 void AddScriptToStack( const char *filename ) {
00057     int            size;
00058 
00059     script++;
00060     if (script == &scriptstack[MAX_INCLUDES])
00061         Error ("script file exceeded MAX_INCLUDES");
00062     strcpy (script->filename, ExpandPath (filename) );
00063 
00064     size = LoadFile (script->filename, (void **)&script->buffer);
00065 
00066     printf ("entering %s\n", script->filename);
00067 
00068     script->line = 1;
00069 
00070     script->script_p = script->buffer;
00071     script->end_p = script->buffer + size;
00072 }
00073 
00074 
00075 /*
00076 ==============
00077 LoadScriptFile
00078 ==============
00079 */
00080 void LoadScriptFile( const char *filename ) {
00081     script = scriptstack;
00082     AddScriptToStack (filename);
00083 
00084     endofscript = qfalse;
00085     tokenready = qfalse;
00086 }
00087 
00088 
00089 /*
00090 ==============
00091 ParseFromMemory
00092 ==============
00093 */
00094 void ParseFromMemory (char *buffer, int size)
00095 {
00096     script = scriptstack;
00097     script++;
00098     if (script == &scriptstack[MAX_INCLUDES])
00099         Error ("script file exceeded MAX_INCLUDES");
00100     strcpy (script->filename, "memory buffer" );
00101 
00102     script->buffer = buffer;
00103     script->line = 1;
00104     script->script_p = script->buffer;
00105     script->end_p = script->buffer + size;
00106 
00107     endofscript = qfalse;
00108     tokenready = qfalse;
00109 }
00110 
00111 
00112 /*
00113 ==============
00114 UnGetToken
00115 
00116 Signals that the current token was not used, and should be reported
00117 for the next GetToken.  Note that
00118 
00119 GetToken (qtrue);
00120 UnGetToken ();
00121 GetToken (qfalse);
00122 
00123 could cross a line boundary.
00124 ==============
00125 */
00126 void UnGetToken (void)
00127 {
00128     tokenready = qtrue;
00129 }
00130 
00131 
00132 qboolean EndOfScript (qboolean crossline)
00133 {
00134     if (!crossline)
00135         Error ("Line %i is incomplete\n",scriptline);
00136 
00137     if (!strcmp (script->filename, "memory buffer"))
00138     {
00139         endofscript = qtrue;
00140         return qfalse;
00141     }
00142 
00143     free (script->buffer);
00144     if (script == scriptstack+1)
00145     {
00146         endofscript = qtrue;
00147         return qfalse;
00148     }
00149     script--;
00150     scriptline = script->line;
00151     printf ("returning to %s\n", script->filename);
00152     return GetToken (crossline);
00153 }
00154 
00155 /*
00156 ==============
00157 GetToken
00158 ==============
00159 */
00160 qboolean GetToken (qboolean crossline)
00161 {
00162     char    *token_p;
00163 
00164     if (tokenready)                         // is a token allready waiting?
00165     {
00166         tokenready = qfalse;
00167         return qtrue;
00168     }
00169 
00170     if (script->script_p >= script->end_p)
00171         return EndOfScript (crossline);
00172 
00173 //
00174 // skip space
00175 //
00176 skipspace:
00177     while (*script->script_p <= 32)
00178     {
00179         if (script->script_p >= script->end_p)
00180             return EndOfScript (crossline);
00181         if (*script->script_p++ == '\n')
00182         {
00183             if (!crossline)
00184                 Error ("Line %i is incomplete\n",scriptline);
00185             scriptline = script->line++;
00186         }
00187     }
00188 
00189     if (script->script_p >= script->end_p)
00190         return EndOfScript (crossline);
00191 
00192     // ; # // comments
00193     if (*script->script_p == ';' || *script->script_p == '#'
00194         || ( script->script_p[0] == '/' && script->script_p[1] == '/') )
00195     {
00196         if (!crossline)
00197             Error ("Line %i is incomplete\n",scriptline);
00198         while (*script->script_p++ != '\n')
00199             if (script->script_p >= script->end_p)
00200                 return EndOfScript (crossline);
00201         scriptline = script->line++;
00202         goto skipspace;
00203     }
00204 
00205     // /* */ comments
00206     if (script->script_p[0] == '/' && script->script_p[1] == '*')
00207     {
00208         if (!crossline)
00209             Error ("Line %i is incomplete\n",scriptline);
00210         script->script_p+=2;
00211         while (script->script_p[0] != '*' && script->script_p[1] != '/')
00212         {
00213             if ( *script->script_p == '\n' ) {
00214                 scriptline = script->line++;
00215             }
00216             script->script_p++;
00217             if (script->script_p >= script->end_p)
00218                 return EndOfScript (crossline);
00219         }
00220         script->script_p += 2;
00221         goto skipspace;
00222     }
00223 
00224 //
00225 // copy token
00226 //
00227     token_p = token;
00228 
00229     if (*script->script_p == '"')
00230     {
00231         // quoted token
00232         script->script_p++;
00233         while (*script->script_p != '"')
00234         {
00235             *token_p++ = *script->script_p++;
00236             if (script->script_p == script->end_p)
00237                 break;
00238             if (token_p == &token[MAXTOKEN])
00239                 Error ("Token too large on line %i\n",scriptline);
00240         }
00241         script->script_p++;
00242     }
00243     else    // regular token
00244     while ( *script->script_p > 32 && *script->script_p != ';')
00245     {
00246         *token_p++ = *script->script_p++;
00247         if (script->script_p == script->end_p)
00248             break;
00249         if (token_p == &token[MAXTOKEN])
00250             Error ("Token too large on line %i\n",scriptline);
00251     }
00252 
00253     *token_p = 0;
00254 
00255     if (!strcmp (token, "$include"))
00256     {
00257         GetToken (qfalse);
00258         AddScriptToStack (token);
00259         return GetToken (crossline);
00260     }
00261 
00262     return qtrue;
00263 }
00264 
00265 
00266 /*
00267 ==============
00268 TokenAvailable
00269 
00270 Returns qtrue if there is another token on the line
00271 ==============
00272 */
00273 qboolean TokenAvailable (void) {
00274     int     oldLine;
00275     qboolean    r;
00276 
00277     oldLine = script->line;
00278     r = GetToken( qtrue );
00279     if ( !r ) {
00280         return qfalse;
00281     }
00282     UnGetToken();
00283     if ( oldLine == script->line ) {
00284         return qtrue;
00285     }
00286     return qfalse;
00287 }
00288 
00289 
00290 //=====================================================================
00291 
00292 
00293 void MatchToken( char *match ) {
00294     GetToken( qtrue );
00295 
00296     if ( strcmp( token, match ) ) {
00297         Error( "MatchToken( \"%s\" ) failed at line %i", match, scriptline );
00298     }
00299 }
00300 
00301 
00302 void Parse1DMatrix (int x, vec_t *m) {
00303     int     i;
00304 
00305     MatchToken( "(" );
00306 
00307     for (i = 0 ; i < x ; i++) {
00308         GetToken( qfalse );
00309         m[i] = atof(token);
00310     }
00311 
00312     MatchToken( ")" );
00313 }
00314 
00315 void Parse2DMatrix (int y, int x, vec_t *m) {
00316     int     i;
00317 
00318     MatchToken( "(" );
00319 
00320     for (i = 0 ; i < y ; i++) {
00321         Parse1DMatrix (x, m + i * x);
00322     }
00323 
00324     MatchToken( ")" );
00325 }
00326 
00327 void Parse3DMatrix (int z, int y, int x, vec_t *m) {
00328     int     i;
00329 
00330     MatchToken( "(" );
00331 
00332     for (i = 0 ; i < z ; i++) {
00333         Parse2DMatrix (y, x, m + i * x*y);
00334     }
00335 
00336     MatchToken( ")" );
00337 }
00338 
00339 
00340 void Write1DMatrix (FILE *f, int x, vec_t *m) {
00341     int     i;
00342 
00343     fprintf (f, "( ");
00344     for (i = 0 ; i < x ; i++) {
00345         if (m[i] == (int)m[i] ) {
00346             fprintf (f, "%i ", (int)m[i]);
00347         } else {
00348             fprintf (f, "%f ", m[i]);
00349         }
00350     }
00351     fprintf (f, ")");
00352 }
00353 
00354 void Write2DMatrix (FILE *f, int y, int x, vec_t *m) {
00355     int     i;
00356 
00357     fprintf (f, "( ");
00358     for (i = 0 ; i < y ; i++) {
00359         Write1DMatrix (f, x, m + i*x);
00360         fprintf (f, " ");
00361     }
00362     fprintf (f, ")\n");
00363 }
00364 
00365 
00366 void Write3DMatrix (FILE *f, int z, int y, int x, vec_t *m) {
00367     int     i;
00368 
00369     fprintf (f, "(\n");
00370     for (i = 0 ; i < z ; i++) {
00371         Write2DMatrix (f, y, x, m + i*(x*y) );
00372     }
00373     fprintf (f, ")\n");
00374 }
00375 

Generated on Thu Aug 25 12:38:08 2005 for Quake III Arena by  doxygen 1.3.9.1