mirror of
https://github.com/blendogames/thirtyflightsofloving.git
synced 2024-11-15 00:41:21 +00:00
1425 lines
41 KiB
C
1425 lines
41 KiB
C
/*
|
||
===========================================================================
|
||
|
||
Return to Castle Wolfenstein single player GPL Source Code
|
||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||
|
||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||
|
||
RTCW SP Source Code is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
RTCW SP Source Code is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||
|
||
In addition, the RTCW SP Source Code is also subject to certain additional terms.
|
||
You should have received a copy of these additional terms immediately following the
|
||
terms and conditions of the GNU General Public License which accompanied the RTCW SP
|
||
Source Code. If not, please request a copy in writing from id Software at the address below.
|
||
|
||
If you have questions concerning this license or the applicable additional terms,
|
||
you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||
|
||
===========================================================================
|
||
*/
|
||
|
||
|
||
/*****************************************************************************
|
||
* name: l_script.c
|
||
*
|
||
* desc: lexicographical parser
|
||
*
|
||
*
|
||
*****************************************************************************/
|
||
|
||
//#define SCREWUP
|
||
//#define BOTLIB
|
||
//#define MEQCC
|
||
//#define BSPC
|
||
|
||
#ifdef SCREWUP
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <limits.h>
|
||
#include <string.h>
|
||
#include <stdarg.h>
|
||
#include "l_memory.h"
|
||
#include "l_script.h"
|
||
|
||
typedef enum {qfalse, qtrue} qboolean;
|
||
|
||
#endif //SCREWUP
|
||
|
||
#ifdef BOTLIB
|
||
//include files for usage in the bot library
|
||
#include "../game/q_shared.h"
|
||
#include "botlib.h"
|
||
#include "be_interface.h"
|
||
#include "l_script.h"
|
||
#include "l_memory.h"
|
||
#include "l_log.h"
|
||
#include "l_libvar.h"
|
||
#endif //BOTLIB
|
||
|
||
#ifdef MEQCC
|
||
//include files for usage in MrElusive's QuakeC Compiler
|
||
#include "qcc.h"
|
||
#include "l_script.h"
|
||
#include "l_memory.h"
|
||
#include "l_log.h"
|
||
|
||
#define qtrue true
|
||
#define qfalse false
|
||
#endif //MEQCC
|
||
|
||
#ifdef BSPC
|
||
//include files for usage in the BSP Converter
|
||
#include "../bspc/qbsp.h"
|
||
#include "../bspc/l_log.h"
|
||
#include "../bspc/l_mem.h"
|
||
|
||
#define qtrue true
|
||
#define qfalse false
|
||
#endif //BSPC
|
||
|
||
|
||
#define PUNCTABLE
|
||
|
||
//longer punctuations first
|
||
punctuation_t default_punctuations[] =
|
||
{
|
||
//binary operators
|
||
{">>=",P_RSHIFT_ASSIGN, NULL},
|
||
{"<<=",P_LSHIFT_ASSIGN, NULL},
|
||
//
|
||
{"...",P_PARMS, NULL},
|
||
//define merge operator
|
||
{"##",P_PRECOMPMERGE, NULL},
|
||
//logic operators
|
||
{"&&",P_LOGIC_AND, NULL},
|
||
{"||",P_LOGIC_OR, NULL},
|
||
{">=",P_LOGIC_GEQ, NULL},
|
||
{"<=",P_LOGIC_LEQ, NULL},
|
||
{"==",P_LOGIC_EQ, NULL},
|
||
{"!=",P_LOGIC_UNEQ, NULL},
|
||
//arithmatic operators
|
||
{"*=",P_MUL_ASSIGN, NULL},
|
||
{"/=",P_DIV_ASSIGN, NULL},
|
||
{"%=",P_MOD_ASSIGN, NULL},
|
||
{"+=",P_ADD_ASSIGN, NULL},
|
||
{"-=",P_SUB_ASSIGN, NULL},
|
||
{"++",P_INC, NULL},
|
||
{"--",P_DEC, NULL},
|
||
//binary operators
|
||
{"&=",P_BIN_AND_ASSIGN, NULL},
|
||
{"|=",P_BIN_OR_ASSIGN, NULL},
|
||
{"^=",P_BIN_XOR_ASSIGN, NULL},
|
||
{">>",P_RSHIFT, NULL},
|
||
{"<<",P_LSHIFT, NULL},
|
||
//reference operators
|
||
{"->",P_POINTERREF, NULL},
|
||
//C++
|
||
{"::",P_CPP1, NULL},
|
||
{".*",P_CPP2, NULL},
|
||
//arithmatic operators
|
||
{"*",P_MUL, NULL},
|
||
{"/",P_DIV, NULL},
|
||
{"%",P_MOD, NULL},
|
||
{"+",P_ADD, NULL},
|
||
{"-",P_SUB, NULL},
|
||
{"=",P_ASSIGN, NULL},
|
||
//binary operators
|
||
{"&",P_BIN_AND, NULL},
|
||
{"|",P_BIN_OR, NULL},
|
||
{"^",P_BIN_XOR, NULL},
|
||
{"~",P_BIN_NOT, NULL},
|
||
//logic operators
|
||
{"!",P_LOGIC_NOT, NULL},
|
||
{">",P_LOGIC_GREATER, NULL},
|
||
{"<",P_LOGIC_LESS, NULL},
|
||
//reference operator
|
||
{".",P_REF, NULL},
|
||
//seperators
|
||
{",",P_COMMA, NULL},
|
||
{";",P_SEMICOLON, NULL},
|
||
//label indication
|
||
{":",P_COLON, NULL},
|
||
//if statement
|
||
{"?",P_QUESTIONMARK, NULL},
|
||
//embracements
|
||
{"(",P_PARENTHESESOPEN, NULL},
|
||
{")",P_PARENTHESESCLOSE, NULL},
|
||
{"{",P_BRACEOPEN, NULL},
|
||
{"}",P_BRACECLOSE, NULL},
|
||
{"[",P_SQBRACKETOPEN, NULL},
|
||
{"]",P_SQBRACKETCLOSE, NULL},
|
||
//
|
||
{"\\",P_BACKSLASH, NULL},
|
||
//precompiler operator
|
||
{"#",P_PRECOMP, NULL},
|
||
#ifdef DOLLAR
|
||
{"$",P_DOLLAR, NULL},
|
||
#endif //DOLLAR
|
||
{NULL, 0}
|
||
};
|
||
|
||
//===========================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//===========================================================================
|
||
void PS_CreatePunctuationTable( script_t *script, punctuation_t *punctuations ) {
|
||
int i;
|
||
punctuation_t *p, *lastp, *newp;
|
||
|
||
//get memory for the table
|
||
if ( !script->punctuationtable ) {
|
||
script->punctuationtable = (punctuation_t **)
|
||
GetMemory( 256 * sizeof( punctuation_t * ) );
|
||
}
|
||
memset( script->punctuationtable, 0, 256 * sizeof( punctuation_t * ) );
|
||
//add the punctuations in the list to the punctuation table
|
||
for ( i = 0; punctuations[i].p; i++ )
|
||
{
|
||
newp = &punctuations[i];
|
||
lastp = NULL;
|
||
//sort the punctuations in this table entry on length (longer punctuations first)
|
||
for ( p = script->punctuationtable[(unsigned int) newp->p[0]]; p; p = p->next )
|
||
{
|
||
if ( strlen( p->p ) < strlen( newp->p ) ) {
|
||
newp->next = p;
|
||
if ( lastp ) {
|
||
lastp->next = newp;
|
||
} else { script->punctuationtable[(unsigned int) newp->p[0]] = newp;}
|
||
break;
|
||
} //end if
|
||
lastp = p;
|
||
} //end for
|
||
if ( !p ) {
|
||
newp->next = NULL;
|
||
if ( lastp ) {
|
||
lastp->next = newp;
|
||
} else { script->punctuationtable[(unsigned int) newp->p[0]] = newp;}
|
||
} //end if
|
||
} //end for
|
||
} //end of the function PS_CreatePunctuationTable
|
||
//===========================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//===========================================================================
|
||
char *PunctuationFromNum( script_t *script, int num ) {
|
||
int i;
|
||
|
||
for ( i = 0; script->punctuations[i].p; i++ )
|
||
{
|
||
if ( script->punctuations[i].n == num ) {
|
||
return script->punctuations[i].p;
|
||
}
|
||
} //end for
|
||
return "unkown punctuation";
|
||
} //end of the function PunctuationFromNum
|
||
//===========================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//===========================================================================
|
||
void QDECL ScriptError( script_t *script, char *str, ... ) {
|
||
char text[1024];
|
||
va_list ap;
|
||
|
||
if ( script->flags & SCFL_NOERRORS ) {
|
||
return;
|
||
}
|
||
|
||
va_start( ap, str );
|
||
// vsprintf( text, str, ap );
|
||
Q_vsnprintf (text, sizeof(text), str, ap);
|
||
va_end( ap );
|
||
#ifdef BOTLIB
|
||
botimport.Print( PRT_ERROR, "file %s, line %d: %s\n", script->filename, script->line, text );
|
||
#endif //BOTLIB
|
||
#ifdef MEQCC
|
||
printf( "error: file %s, line %d: %s\n", script->filename, script->line, text );
|
||
#endif //MEQCC
|
||
#ifdef BSPC
|
||
Log_Print( "error: file %s, line %d: %s\n", script->filename, script->line, text );
|
||
#endif //BSPC
|
||
} //end of the function ScriptError
|
||
//===========================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//===========================================================================
|
||
void QDECL ScriptWarning( script_t *script, char *str, ... ) {
|
||
char text[1024];
|
||
va_list ap;
|
||
|
||
if ( script->flags & SCFL_NOWARNINGS ) {
|
||
return;
|
||
}
|
||
|
||
va_start( ap, str );
|
||
// vsprintf( text, str, ap );
|
||
Q_vsnprintf (text, sizeof(text), str, ap);
|
||
va_end( ap );
|
||
#ifdef BOTLIB
|
||
botimport.Print( PRT_WARNING, "file %s, line %d: %s\n", script->filename, script->line, text );
|
||
#endif //BOTLIB
|
||
#ifdef MEQCC
|
||
printf( "warning: file %s, line %d: %s\n", script->filename, script->line, text );
|
||
#endif //MEQCC
|
||
#ifdef BSPC
|
||
Log_Print( "warning: file %s, line %d: %s\n", script->filename, script->line, text );
|
||
#endif //BSPC
|
||
} //end of the function ScriptWarning
|
||
//===========================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//===========================================================================
|
||
void SetScriptPunctuations( script_t *script, punctuation_t *p ) {
|
||
#ifdef PUNCTABLE
|
||
if ( p ) {
|
||
PS_CreatePunctuationTable( script, p );
|
||
} else { PS_CreatePunctuationTable( script, default_punctuations );}
|
||
#endif //PUNCTABLE
|
||
if ( p ) {
|
||
script->punctuations = p;
|
||
} else { script->punctuations = default_punctuations;}
|
||
} //end of the function SetScriptPunctuations
|
||
//============================================================================
|
||
// Reads spaces, tabs, C-like comments etc.
|
||
// When a newline character is found the scripts line counter is increased.
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadWhiteSpace( script_t *script ) {
|
||
while ( 1 )
|
||
{
|
||
//skip white space
|
||
while ( *script->script_p <= ' ' )
|
||
{
|
||
if ( !*script->script_p ) {
|
||
return 0;
|
||
}
|
||
if ( *script->script_p == '\n' ) {
|
||
script->line++;
|
||
}
|
||
script->script_p++;
|
||
} //end while
|
||
//skip comments
|
||
if ( *script->script_p == '/' ) {
|
||
//comments //
|
||
if ( *( script->script_p + 1 ) == '/' ) {
|
||
script->script_p++;
|
||
do
|
||
{
|
||
script->script_p++;
|
||
if ( !*script->script_p ) {
|
||
return 0;
|
||
}
|
||
} //end do
|
||
while ( *script->script_p != '\n' );
|
||
script->line++;
|
||
script->script_p++;
|
||
if ( !*script->script_p ) {
|
||
return 0;
|
||
}
|
||
continue;
|
||
} //end if
|
||
//comments /* */
|
||
else if ( *( script->script_p + 1 ) == '*' ) {
|
||
script->script_p++;
|
||
do
|
||
{
|
||
script->script_p++;
|
||
if ( !*script->script_p ) {
|
||
return 0;
|
||
}
|
||
if ( *script->script_p == '\n' ) {
|
||
script->line++;
|
||
}
|
||
} //end do
|
||
while ( !( *script->script_p == '*' && *( script->script_p + 1 ) == '/' ) );
|
||
script->script_p++;
|
||
if ( !*script->script_p ) {
|
||
return 0;
|
||
}
|
||
script->script_p++;
|
||
if ( !*script->script_p ) {
|
||
return 0;
|
||
}
|
||
continue;
|
||
} //end if
|
||
} //end if
|
||
break;
|
||
} //end while
|
||
return 1;
|
||
} //end of the function PS_ReadWhiteSpace
|
||
//============================================================================
|
||
// Reads an escape character.
|
||
//
|
||
// Parameter: script : script to read from
|
||
// ch : place to store the read escape character
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadEscapeCharacter( script_t *script, char *ch ) {
|
||
int c, val, i;
|
||
|
||
//step over the leading '\\'
|
||
script->script_p++;
|
||
//determine the escape character
|
||
switch ( *script->script_p )
|
||
{
|
||
case '\\': c = '\\'; break;
|
||
case 'n': c = '\n'; break;
|
||
case 'r': c = '\r'; break;
|
||
case 't': c = '\t'; break;
|
||
case 'v': c = '\v'; break;
|
||
case 'b': c = '\b'; break;
|
||
case 'f': c = '\f'; break;
|
||
case 'a': c = '\a'; break;
|
||
case '\'': c = '\''; break;
|
||
case '\"': c = '\"'; break;
|
||
case '\?': c = '\?'; break;
|
||
case 'x':
|
||
{
|
||
script->script_p++;
|
||
for ( i = 0, val = 0; ; i++, script->script_p++ )
|
||
{
|
||
c = *script->script_p;
|
||
if ( c >= '0' && c <= '9' ) {
|
||
c = c - '0';
|
||
} else if ( c >= 'A' && c <= 'Z' ) {
|
||
c = c - 'A' + 10;
|
||
} else if ( c >= 'a' && c <= 'z' ) {
|
||
c = c - 'a' + 10;
|
||
} else { break;}
|
||
val = ( val << 4 ) + c;
|
||
} //end for
|
||
script->script_p--;
|
||
if ( val > 0xFF ) {
|
||
ScriptWarning( script, "too large value in escape character" );
|
||
val = 0xFF;
|
||
} //end if
|
||
c = val;
|
||
break;
|
||
} //end case
|
||
default: //NOTE: decimal ASCII code, NOT octal
|
||
{
|
||
if ( *script->script_p < '0' || *script->script_p > '9' ) {
|
||
ScriptError( script, "unknown escape char" );
|
||
}
|
||
for ( i = 0, val = 0; ; i++, script->script_p++ )
|
||
{
|
||
c = *script->script_p;
|
||
if ( c >= '0' && c <= '9' ) {
|
||
c = c - '0';
|
||
} else { break;}
|
||
val = val * 10 + c;
|
||
} //end for
|
||
script->script_p--;
|
||
if ( val > 0xFF ) {
|
||
ScriptWarning( script, "too large value in escape character" );
|
||
val = 0xFF;
|
||
} //end if
|
||
c = val;
|
||
break;
|
||
} //end default
|
||
} //end switch
|
||
//step over the escape character or the last digit of the number
|
||
script->script_p++;
|
||
//store the escape character
|
||
*ch = c;
|
||
//succesfully read escape character
|
||
return 1;
|
||
} //end of the function PS_ReadEscapeCharacter
|
||
//============================================================================
|
||
// Reads C-like string. Escape characters are interpretted.
|
||
// Quotes are included with the string.
|
||
// Reads two strings with a white space between them as one string.
|
||
//
|
||
// Parameter: script : script to read from
|
||
// token : buffer to store the string
|
||
// Returns: qtrue when a string was read succesfully
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadString( script_t *script, token_t *token, int quote ) {
|
||
int len, tmpline;
|
||
char *tmpscript_p;
|
||
|
||
if ( quote == '\"' ) {
|
||
token->type = TT_STRING;
|
||
} else { token->type = TT_LITERAL;}
|
||
|
||
len = 0;
|
||
//leading quote
|
||
token->string[len++] = *script->script_p++;
|
||
//
|
||
while ( 1 )
|
||
{
|
||
//minus 2 because trailing double quote and zero have to be appended
|
||
if ( len >= MAX_TOKEN - 2 ) {
|
||
ScriptError( script, "string longer than MAX_TOKEN = %d", MAX_TOKEN );
|
||
return 0;
|
||
} //end if
|
||
//if there is an escape character and
|
||
//if escape characters inside a string are allowed
|
||
if ( *script->script_p == '\\' && !( script->flags & SCFL_NOSTRINGESCAPECHARS ) ) {
|
||
if ( !PS_ReadEscapeCharacter( script, &token->string[len] ) ) {
|
||
token->string[len] = 0;
|
||
return 0;
|
||
} //end if
|
||
len++;
|
||
} //end if
|
||
//if a trailing quote
|
||
else if ( *script->script_p == quote ) {
|
||
//step over the double quote
|
||
script->script_p++;
|
||
//if white spaces in a string are not allowed
|
||
if ( script->flags & SCFL_NOSTRINGWHITESPACES ) {
|
||
break;
|
||
}
|
||
//
|
||
tmpscript_p = script->script_p;
|
||
tmpline = script->line;
|
||
//read unusefull stuff between possible two following strings
|
||
if ( !PS_ReadWhiteSpace( script ) ) {
|
||
script->script_p = tmpscript_p;
|
||
script->line = tmpline;
|
||
break;
|
||
} //end if
|
||
//if there's no leading double qoute
|
||
if ( *script->script_p != quote ) {
|
||
script->script_p = tmpscript_p;
|
||
script->line = tmpline;
|
||
break;
|
||
} //end if
|
||
//step over the new leading double quote
|
||
script->script_p++;
|
||
} //end if
|
||
else
|
||
{
|
||
if ( *script->script_p == '\0' ) {
|
||
token->string[len] = 0;
|
||
ScriptError( script, "missing trailing quote" );
|
||
return 0;
|
||
} //end if
|
||
if ( *script->script_p == '\n' ) {
|
||
token->string[len] = 0;
|
||
ScriptError( script, "newline inside string %s", token->string );
|
||
return 0;
|
||
} //end if
|
||
token->string[len++] = *script->script_p++;
|
||
} //end else
|
||
} //end while
|
||
//trailing quote
|
||
token->string[len++] = quote;
|
||
//end string with a zero
|
||
token->string[len] = '\0';
|
||
//the sub type is the length of the string
|
||
token->subtype = len;
|
||
return 1;
|
||
} //end of the function PS_ReadString
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadName( script_t *script, token_t *token ) {
|
||
int len = 0;
|
||
char c;
|
||
|
||
token->type = TT_NAME;
|
||
do
|
||
{
|
||
token->string[len++] = *script->script_p++;
|
||
if ( len >= MAX_TOKEN ) {
|
||
ScriptError( script, "name longer than MAX_TOKEN = %d", MAX_TOKEN );
|
||
return 0;
|
||
} //end if
|
||
c = *script->script_p;
|
||
} while ( ( c >= 'a' && c <= 'z' ) ||
|
||
( c >= 'A' && c <= 'Z' ) ||
|
||
( c >= '0' && c <= '9' ) ||
|
||
c == '_' );
|
||
token->string[len] = '\0';
|
||
//the sub type is the length of the name
|
||
token->subtype = len;
|
||
return 1;
|
||
} //end of the function PS_ReadName
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void NumberValue( char *string, int subtype, unsigned long int *intvalue,
|
||
long double *floatvalue ) {
|
||
unsigned long int dotfound = 0;
|
||
|
||
*intvalue = 0;
|
||
*floatvalue = 0;
|
||
//floating point number
|
||
if ( subtype & TT_FLOAT ) {
|
||
while ( *string )
|
||
{
|
||
if ( *string == '.' ) {
|
||
if ( dotfound ) {
|
||
return;
|
||
}
|
||
dotfound = 10;
|
||
string++;
|
||
} //end if
|
||
if ( dotfound ) {
|
||
*floatvalue = *floatvalue + ( long double )( *string - '0' ) /
|
||
(long double) dotfound;
|
||
dotfound *= 10;
|
||
} //end if
|
||
else
|
||
{
|
||
*floatvalue = *floatvalue * 10.0 + ( long double )( *string - '0' );
|
||
} //end else
|
||
string++;
|
||
} //end while
|
||
*intvalue = (unsigned long) *floatvalue;
|
||
} //end if
|
||
else if ( subtype & TT_DECIMAL ) {
|
||
while ( *string ) *intvalue = *intvalue * 10 + ( *string++ - '0' );
|
||
*floatvalue = *intvalue;
|
||
} //end else if
|
||
else if ( subtype & TT_HEX ) {
|
||
//step over the leading 0x or 0X
|
||
string += 2;
|
||
while ( *string )
|
||
{
|
||
*intvalue <<= 4;
|
||
if ( *string >= 'a' && *string <= 'f' ) {
|
||
*intvalue += *string - 'a' + 10;
|
||
} else if ( *string >= 'A' && *string <= 'F' ) {
|
||
*intvalue += *string - 'A' + 10;
|
||
} else { *intvalue += *string - '0';}
|
||
string++;
|
||
} //end while
|
||
*floatvalue = *intvalue;
|
||
} //end else if
|
||
else if ( subtype & TT_OCTAL ) {
|
||
//step over the first zero
|
||
string += 1;
|
||
while ( *string ) *intvalue = ( *intvalue << 3 ) + ( *string++ - '0' );
|
||
*floatvalue = *intvalue;
|
||
} //end else if
|
||
else if ( subtype & TT_BINARY ) {
|
||
//step over the leading 0b or 0B
|
||
string += 2;
|
||
while ( *string ) *intvalue = ( *intvalue << 1 ) + ( *string++ - '0' );
|
||
*floatvalue = *intvalue;
|
||
} //end else if
|
||
} //end of the function NumberValue
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadNumber( script_t *script, token_t *token ) {
|
||
int len = 0, i;
|
||
int octal, dot;
|
||
char c;
|
||
// unsigned long int intvalue = 0;
|
||
// long double floatvalue = 0;
|
||
|
||
token->type = TT_NUMBER;
|
||
//check for a hexadecimal number
|
||
if ( *script->script_p == '0' &&
|
||
( *( script->script_p + 1 ) == 'x' ||
|
||
*( script->script_p + 1 ) == 'X' ) ) {
|
||
token->string[len++] = *script->script_p++;
|
||
token->string[len++] = *script->script_p++;
|
||
c = *script->script_p;
|
||
//hexadecimal
|
||
while ( ( c >= '0' && c <= '9' ) ||
|
||
( c >= 'a' && c <= 'f' ) ||
|
||
( c >= 'A' && c <= 'A' ) )
|
||
{
|
||
token->string[len++] = *script->script_p++;
|
||
if ( len >= MAX_TOKEN ) {
|
||
ScriptError( script, "hexadecimal number longer than MAX_TOKEN = %d", MAX_TOKEN );
|
||
return 0;
|
||
} //end if
|
||
c = *script->script_p;
|
||
} //end while
|
||
token->subtype |= TT_HEX;
|
||
} //end if
|
||
#ifdef BINARYNUMBERS
|
||
//check for a binary number
|
||
else if ( *script->script_p == '0' &&
|
||
( *( script->script_p + 1 ) == 'b' ||
|
||
*( script->script_p + 1 ) == 'B' ) ) {
|
||
token->string[len++] = *script->script_p++;
|
||
token->string[len++] = *script->script_p++;
|
||
c = *script->script_p;
|
||
//hexadecimal
|
||
while ( c == '0' || c == '1' )
|
||
{
|
||
token->string[len++] = *script->script_p++;
|
||
if ( len >= MAX_TOKEN ) {
|
||
ScriptError( script, "binary number longer than MAX_TOKEN = %d", MAX_TOKEN );
|
||
return 0;
|
||
} //end if
|
||
c = *script->script_p;
|
||
} //end while
|
||
token->subtype |= TT_BINARY;
|
||
} //end if
|
||
#endif //BINARYNUMBERS
|
||
else //decimal or octal integer or floating point number
|
||
{
|
||
octal = qfalse;
|
||
dot = qfalse;
|
||
if ( *script->script_p == '0' ) {
|
||
octal = qtrue;
|
||
}
|
||
while ( 1 )
|
||
{
|
||
token->string[len++] = *script->script_p++;
|
||
if ( len >= MAX_TOKEN ) {
|
||
ScriptError( script, "number longer than MAX_TOKEN = %d", MAX_TOKEN );
|
||
return 0;
|
||
} //end if
|
||
c = *script->script_p;
|
||
if ( c == '.' ) {
|
||
dot = qtrue;
|
||
} else if ( c == '8' || c == '9' ) {
|
||
octal = qfalse;
|
||
} else if ( c < '0' || c > '9' ) {
|
||
break;
|
||
}
|
||
} //end while
|
||
if ( octal ) {
|
||
token->subtype |= TT_OCTAL;
|
||
} else { token->subtype |= TT_DECIMAL;}
|
||
if ( dot ) {
|
||
token->subtype |= TT_FLOAT;
|
||
}
|
||
} //end else
|
||
for ( i = 0; i < 2; i++ )
|
||
{
|
||
c = *script->script_p;
|
||
//check for a LONG number
|
||
if ( c == 'l' || c == 'L' &&
|
||
!( token->subtype & TT_LONG ) ) {
|
||
script->script_p++;
|
||
token->subtype |= TT_LONG;
|
||
} //end if
|
||
//check for an UNSIGNED number
|
||
else if ( c == 'u' || c == 'U' &&
|
||
!( token->subtype & ( TT_UNSIGNED | TT_FLOAT ) ) ) {
|
||
script->script_p++;
|
||
token->subtype |= TT_UNSIGNED;
|
||
} //end if
|
||
} //end for
|
||
token->string[len] = '\0';
|
||
#ifdef NUMBERVALUE
|
||
NumberValue( token->string, token->subtype, &token->intvalue, &token->floatvalue );
|
||
#endif //NUMBERVALUE
|
||
if ( !( token->subtype & TT_FLOAT ) ) {
|
||
token->subtype |= TT_INTEGER;
|
||
}
|
||
return 1;
|
||
} //end of the function PS_ReadNumber
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadLiteral( script_t *script, token_t *token ) {
|
||
token->type = TT_LITERAL;
|
||
//first quote
|
||
token->string[0] = *script->script_p++;
|
||
//check for end of file
|
||
if ( !*script->script_p ) {
|
||
ScriptError( script, "end of file before trailing \'" );
|
||
return 0;
|
||
} //end if
|
||
//if it is an escape character
|
||
if ( *script->script_p == '\\' ) {
|
||
if ( !PS_ReadEscapeCharacter( script, &token->string[1] ) ) {
|
||
return 0;
|
||
}
|
||
} //end if
|
||
else
|
||
{
|
||
token->string[1] = *script->script_p++;
|
||
} //end else
|
||
//check for trailing quote
|
||
if ( *script->script_p != '\'' ) {
|
||
ScriptWarning( script, "too many characters in literal, ignored" );
|
||
while ( *script->script_p &&
|
||
*script->script_p != '\'' &&
|
||
*script->script_p != '\n' )
|
||
{
|
||
script->script_p++;
|
||
} //end while
|
||
if ( *script->script_p == '\'' ) {
|
||
script->script_p++;
|
||
}
|
||
} //end if
|
||
//store the trailing quote
|
||
token->string[2] = *script->script_p++;
|
||
//store trailing zero to end the string
|
||
token->string[3] = '\0';
|
||
//the sub type is the integer literal value
|
||
token->subtype = token->string[1];
|
||
//
|
||
return 1;
|
||
} //end of the function PS_ReadLiteral
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadPunctuation( script_t *script, token_t *token ) {
|
||
int len;
|
||
char *p;
|
||
punctuation_t *punc;
|
||
|
||
#ifdef PUNCTABLE
|
||
for ( punc = script->punctuationtable[(unsigned int)*script->script_p]; punc; punc = punc->next )
|
||
{
|
||
#else
|
||
int i;
|
||
|
||
for ( i = 0; script->punctuations[i].p; i++ )
|
||
{
|
||
punc = &script->punctuations[i];
|
||
#endif //PUNCTABLE
|
||
p = punc->p;
|
||
len = (int)strlen( p );
|
||
//if the script contains at least as much characters as the punctuation
|
||
if ( script->script_p + len <= script->end_p ) {
|
||
//if the script contains the punctuation
|
||
if ( !strncmp( script->script_p, p, len ) ) {
|
||
strncpy( token->string, p, MAX_TOKEN );
|
||
script->script_p += len;
|
||
token->type = TT_PUNCTUATION;
|
||
//sub type is the number of the punctuation
|
||
token->subtype = punc->n;
|
||
return 1;
|
||
} //end if
|
||
} //end if
|
||
} //end for
|
||
return 0;
|
||
} //end of the function PS_ReadPunctuation
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadPrimitive( script_t *script, token_t *token ) {
|
||
int len;
|
||
|
||
len = 0;
|
||
while ( *script->script_p > ' ' && *script->script_p != ';' )
|
||
{
|
||
if ( len >= MAX_TOKEN ) {
|
||
ScriptError( script, "primitive token longer than MAX_TOKEN = %d", MAX_TOKEN );
|
||
return 0;
|
||
} //end if
|
||
token->string[len++] = *script->script_p++;
|
||
} //end while
|
||
token->string[len] = 0;
|
||
//copy the token into the script structure
|
||
memcpy( &script->token, token, sizeof( token_t ) );
|
||
//primitive reading successfull
|
||
return 1;
|
||
} //end of the function PS_ReadPrimitive
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ReadToken( script_t *script, token_t *token ) {
|
||
//if there is a token available (from UnreadToken)
|
||
if ( script->tokenavailable ) {
|
||
script->tokenavailable = 0;
|
||
memcpy( token, &script->token, sizeof( token_t ) );
|
||
return 1;
|
||
} //end if
|
||
//save script pointer
|
||
script->lastscript_p = script->script_p;
|
||
//save line counter
|
||
script->lastline = script->line;
|
||
//clear the token stuff
|
||
memset( token, 0, sizeof( token_t ) );
|
||
//start of the white space
|
||
script->whitespace_p = script->script_p;
|
||
token->whitespace_p = script->script_p;
|
||
//read unusefull stuff
|
||
if ( !PS_ReadWhiteSpace( script ) ) {
|
||
return 0;
|
||
}
|
||
//end of the white space
|
||
script->endwhitespace_p = script->script_p;
|
||
token->endwhitespace_p = script->script_p;
|
||
//line the token is on
|
||
token->line = script->line;
|
||
//number of lines crossed before token
|
||
token->linescrossed = script->line - script->lastline;
|
||
//if there is a leading double quote
|
||
if ( *script->script_p == '\"' ) {
|
||
if ( !PS_ReadString( script, token, '\"' ) ) {
|
||
return 0;
|
||
}
|
||
} //end if
|
||
//if an literal
|
||
else if ( *script->script_p == '\'' ) {
|
||
//if (!PS_ReadLiteral(script, token)) return 0;
|
||
if ( !PS_ReadString( script, token, '\'' ) ) {
|
||
return 0;
|
||
}
|
||
} //end if
|
||
//if there is a number
|
||
else if ( ( *script->script_p >= '0' && *script->script_p <= '9' ) ||
|
||
( *script->script_p == '.' &&
|
||
( *( script->script_p + 1 ) >= '0' && *( script->script_p + 1 ) <= '9' ) ) ) {
|
||
if ( !PS_ReadNumber( script, token ) ) {
|
||
return 0;
|
||
}
|
||
} //end if
|
||
//if this is a primitive script
|
||
else if ( script->flags & SCFL_PRIMITIVE ) {
|
||
return PS_ReadPrimitive( script, token );
|
||
} //end else if
|
||
//if there is a name
|
||
else if ( ( *script->script_p >= 'a' && *script->script_p <= 'z' ) ||
|
||
( *script->script_p >= 'A' && *script->script_p <= 'Z' ) ||
|
||
*script->script_p == '_' ) {
|
||
if ( !PS_ReadName( script, token ) ) {
|
||
return 0;
|
||
}
|
||
} //end if
|
||
//check for punctuations
|
||
else if ( !PS_ReadPunctuation( script, token ) ) {
|
||
ScriptError( script, "can't read token" );
|
||
return 0;
|
||
} //end if
|
||
//copy the token into the script structure
|
||
memcpy( &script->token, token, sizeof( token_t ) );
|
||
//succesfully read a token
|
||
return 1;
|
||
} //end of the function PS_ReadToken
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ExpectTokenString( script_t *script, char *string ) {
|
||
token_t token;
|
||
|
||
if ( !PS_ReadToken( script, &token ) ) {
|
||
ScriptError( script, "couldn't find expected %s", string );
|
||
return 0;
|
||
} //end if
|
||
|
||
if ( strcmp( token.string, string ) ) {
|
||
ScriptError( script, "expected %s, found %s", string, token.string );
|
||
return 0;
|
||
} //end if
|
||
return 1;
|
||
} //end of the function PS_ExpectToken
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ExpectTokenType( script_t *script, int type, int subtype, token_t *token ) {
|
||
char str[MAX_TOKEN];
|
||
|
||
if ( !PS_ReadToken( script, token ) ) {
|
||
ScriptError( script, "couldn't read expected token" );
|
||
return 0;
|
||
} //end if
|
||
|
||
if ( token->type != type ) {
|
||
if ( type == TT_STRING ) {
|
||
strcpy( str, "string" );
|
||
}
|
||
if ( type == TT_LITERAL ) {
|
||
strcpy( str, "literal" );
|
||
}
|
||
if ( type == TT_NUMBER ) {
|
||
strcpy( str, "number" );
|
||
}
|
||
if ( type == TT_NAME ) {
|
||
strcpy( str, "name" );
|
||
}
|
||
if ( type == TT_PUNCTUATION ) {
|
||
strcpy( str, "punctuation" );
|
||
}
|
||
ScriptError( script, "expected a %s, found %s", str, token->string );
|
||
return 0;
|
||
} //end if
|
||
if ( token->type == TT_NUMBER ) {
|
||
if ( ( token->subtype & subtype ) != subtype ) {
|
||
if ( subtype & TT_DECIMAL ) {
|
||
strcpy( str, "decimal" );
|
||
}
|
||
if ( subtype & TT_HEX ) {
|
||
strcpy( str, "hex" );
|
||
}
|
||
if ( subtype & TT_OCTAL ) {
|
||
strcpy( str, "octal" );
|
||
}
|
||
if ( subtype & TT_BINARY ) {
|
||
strcpy( str, "binary" );
|
||
}
|
||
if ( subtype & TT_LONG ) {
|
||
strcat( str, " long" );
|
||
}
|
||
if ( subtype & TT_UNSIGNED ) {
|
||
strcat( str, " unsigned" );
|
||
}
|
||
if ( subtype & TT_FLOAT ) {
|
||
strcat( str, " float" );
|
||
}
|
||
if ( subtype & TT_INTEGER ) {
|
||
strcat( str, " integer" );
|
||
}
|
||
ScriptError( script, "expected %s, found %s", str, token->string );
|
||
return 0;
|
||
} //end if
|
||
} //end if
|
||
else if ( token->type == TT_PUNCTUATION ) {
|
||
if ( subtype < 0 ) {
|
||
ScriptError( script, "BUG: wrong punctuation subtype" );
|
||
return 0;
|
||
} //end if
|
||
if ( token->subtype != subtype ) {
|
||
ScriptError( script, "expected %s, found %s",
|
||
script->punctuations[subtype], token->string );
|
||
return 0;
|
||
} //end if
|
||
} //end else if
|
||
return 1;
|
||
} //end of the function PS_ExpectTokenType
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_ExpectAnyToken( script_t *script, token_t *token ) {
|
||
if ( !PS_ReadToken( script, token ) ) {
|
||
ScriptError( script, "couldn't read expected token" );
|
||
return 0;
|
||
} //end if
|
||
else
|
||
{
|
||
return 1;
|
||
} //end else
|
||
} //end of the function PS_ExpectAnyToken
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_CheckTokenString( script_t *script, char *string ) {
|
||
token_t tok;
|
||
|
||
if ( !PS_ReadToken( script, &tok ) ) {
|
||
return 0;
|
||
}
|
||
//if the token is available
|
||
if ( !strcmp( tok.string, string ) ) {
|
||
return 1;
|
||
}
|
||
//token not available
|
||
script->script_p = script->lastscript_p;
|
||
return 0;
|
||
} //end of the function PS_CheckTokenString
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_CheckTokenType( script_t *script, int type, int subtype, token_t *token ) {
|
||
token_t tok;
|
||
|
||
if ( !PS_ReadToken( script, &tok ) ) {
|
||
return 0;
|
||
}
|
||
//if the type matches
|
||
if ( tok.type == type &&
|
||
( tok.subtype & subtype ) == subtype ) {
|
||
memcpy( token, &tok, sizeof( token_t ) );
|
||
return 1;
|
||
} //end if
|
||
//token is not available
|
||
script->script_p = script->lastscript_p;
|
||
return 0;
|
||
} //end of the function PS_CheckTokenType
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int PS_SkipUntilString( script_t *script, char *string ) {
|
||
token_t token;
|
||
|
||
while ( PS_ReadToken( script, &token ) )
|
||
{
|
||
if ( !strcmp( token.string, string ) ) {
|
||
return 1;
|
||
}
|
||
} //end while
|
||
return 0;
|
||
} //end of the function PS_SkipUntilString
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void PS_UnreadLastToken( script_t *script ) {
|
||
script->tokenavailable = 1;
|
||
} //end of the function UnreadLastToken
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void PS_UnreadToken( script_t *script, token_t *token ) {
|
||
memcpy( &script->token, token, sizeof( token_t ) );
|
||
script->tokenavailable = 1;
|
||
} //end of the function UnreadToken
|
||
//============================================================================
|
||
// returns the next character of the read white space, returns NULL if none
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
char PS_NextWhiteSpaceChar( script_t *script ) {
|
||
if ( script->whitespace_p != script->endwhitespace_p ) {
|
||
return *script->whitespace_p++;
|
||
} //end if
|
||
else
|
||
{
|
||
return 0;
|
||
} //end else
|
||
} //end of the function PS_NextWhiteSpaceChar
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void StripDoubleQuotes( char *string ) {
|
||
if ( *string == '\"' ) {
|
||
strcpy( string, string + 1 );
|
||
} //end if
|
||
if ( string[strlen( string ) - 1] == '\"' ) {
|
||
string[strlen( string ) - 1] = '\0';
|
||
} //end if
|
||
} //end of the function StripDoubleQuotes
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void StripSingleQuotes( char *string ) {
|
||
if ( *string == '\'' ) {
|
||
strcpy( string, string + 1 );
|
||
} //end if
|
||
if ( string[strlen( string ) - 1] == '\'' ) {
|
||
string[strlen( string ) - 1] = '\0';
|
||
} //end if
|
||
} //end of the function StripSingleQuotes
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
long double ReadSignedFloat( script_t *script ) {
|
||
token_t token;
|
||
long double sign = 1;
|
||
|
||
PS_ExpectAnyToken( script, &token );
|
||
if ( !strcmp( token.string, "-" ) ) {
|
||
sign = -1;
|
||
PS_ExpectTokenType( script, TT_NUMBER, 0, &token );
|
||
} //end if
|
||
else if ( token.type != TT_NUMBER ) {
|
||
ScriptError( script, "expected float value, found %s\n", token.string );
|
||
} //end else if
|
||
return sign * token.floatvalue;
|
||
} //end of the function ReadSignedFloat
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
signed long int ReadSignedInt( script_t *script ) {
|
||
token_t token;
|
||
signed long int sign = 1;
|
||
|
||
PS_ExpectAnyToken( script, &token );
|
||
if ( !strcmp( token.string, "-" ) ) {
|
||
sign = -1;
|
||
PS_ExpectTokenType( script, TT_NUMBER, TT_INTEGER, &token );
|
||
} //end if
|
||
else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) {
|
||
ScriptError( script, "expected integer value, found %s\n", token.string );
|
||
} //end else if
|
||
return sign * token.intvalue;
|
||
} //end of the function ReadSignedInt
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void SetScriptFlags( script_t *script, int flags ) {
|
||
script->flags = flags;
|
||
} //end of the function SetScriptFlags
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int GetScriptFlags( script_t *script ) {
|
||
return script->flags;
|
||
} //end of the function GetScriptFlags
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void ResetScript( script_t *script ) {
|
||
//pointer in script buffer
|
||
script->script_p = script->buffer;
|
||
//pointer in script buffer before reading token
|
||
script->lastscript_p = script->buffer;
|
||
//begin of white space
|
||
script->whitespace_p = NULL;
|
||
//end of white space
|
||
script->endwhitespace_p = NULL;
|
||
//set if there's a token available in script->token
|
||
script->tokenavailable = 0;
|
||
//
|
||
script->line = 1;
|
||
script->lastline = 1;
|
||
//clear the saved token
|
||
memset( &script->token, 0, sizeof( token_t ) );
|
||
} //end of the function ResetScript
|
||
//============================================================================
|
||
// returns true if at the end of the script
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int EndOfScript( script_t *script ) {
|
||
return script->script_p >= script->end_p;
|
||
} //end of the function EndOfScript
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int NumLinesCrossed( script_t *script ) {
|
||
return script->line - script->lastline;
|
||
} //end of the function NumLinesCrossed
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int ScriptSkipTo( script_t *script, char *value ) {
|
||
int len;
|
||
char firstchar;
|
||
|
||
firstchar = *value;
|
||
len = (int)strlen( value );
|
||
do
|
||
{
|
||
if ( !PS_ReadWhiteSpace( script ) ) {
|
||
return 0;
|
||
}
|
||
if ( *script->script_p == firstchar ) {
|
||
if ( !strncmp( script->script_p, value, len ) ) {
|
||
return 1;
|
||
} //end if
|
||
} //end if
|
||
script->script_p++;
|
||
} while ( 1 );
|
||
} //end of the function ScriptSkipTo
|
||
#ifndef BOTLIB
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
int FileLength( FILE *fp ) {
|
||
int pos;
|
||
int end;
|
||
|
||
pos = ftell( fp );
|
||
fseek( fp, 0, SEEK_END );
|
||
end = ftell( fp );
|
||
fseek( fp, pos, SEEK_SET );
|
||
|
||
return end;
|
||
} //end of the function FileLength
|
||
#endif
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
script_t *LoadScriptFile( char *filename ) {
|
||
#ifdef BOTLIB
|
||
fileHandle_t fp;
|
||
char pathname[MAX_QPATH];
|
||
#else
|
||
FILE *fp;
|
||
#endif
|
||
int length;
|
||
void *buffer;
|
||
script_t *script;
|
||
|
||
#ifdef BOTLIB
|
||
Com_sprintf( pathname, MAX_QPATH, "botfiles/%s", filename );
|
||
length = botimport.FS_FOpenFile( pathname, &fp, FS_READ );
|
||
if ( !fp ) {
|
||
return NULL;
|
||
}
|
||
#else
|
||
fp = fopen( filename, "rb" );
|
||
if ( !fp ) {
|
||
return NULL;
|
||
}
|
||
|
||
length = FileLength( fp );
|
||
#endif
|
||
|
||
buffer = GetClearedMemory( sizeof( script_t ) + length + 1 );
|
||
script = (script_t *) buffer;
|
||
memset( script, 0, sizeof( script_t ) );
|
||
strcpy( script->filename, filename );
|
||
script->buffer = (char *) buffer + sizeof( script_t );
|
||
script->buffer[length] = 0;
|
||
script->length = length;
|
||
//pointer in script buffer
|
||
script->script_p = script->buffer;
|
||
//pointer in script buffer before reading token
|
||
script->lastscript_p = script->buffer;
|
||
//pointer to end of script buffer
|
||
script->end_p = &script->buffer[length];
|
||
//set if there's a token available in script->token
|
||
script->tokenavailable = 0;
|
||
//
|
||
script->line = 1;
|
||
script->lastline = 1;
|
||
//
|
||
SetScriptPunctuations( script, NULL );
|
||
//
|
||
#ifdef BOTLIB
|
||
botimport.FS_Read( script->buffer, length, fp );
|
||
botimport.FS_FCloseFile( fp );
|
||
#else
|
||
if ( fread( script->buffer, length, 1, fp ) != 1 ) {
|
||
FreeMemory( buffer );
|
||
script = NULL;
|
||
} //end if
|
||
fclose( fp );
|
||
#endif
|
||
//
|
||
return script;
|
||
} //end of the function LoadScriptFile
|
||
//============================================================================
|
||
//load a script from the given memory with the given length
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
script_t *LoadScriptMemory( char *ptr, int length, char *name ) {
|
||
void *buffer;
|
||
script_t *script;
|
||
|
||
buffer = GetClearedMemory( sizeof( script_t ) + length + 1 );
|
||
script = (script_t *) buffer;
|
||
memset( script, 0, sizeof( script_t ) );
|
||
strcpy( script->filename, name );
|
||
script->buffer = (char *) buffer + sizeof( script_t );
|
||
script->buffer[length] = 0;
|
||
script->length = length;
|
||
//pointer in script buffer
|
||
script->script_p = script->buffer;
|
||
//pointer in script buffer before reading token
|
||
script->lastscript_p = script->buffer;
|
||
//pointer to end of script buffer
|
||
script->end_p = &script->buffer[length];
|
||
//set if there's a token available in script->token
|
||
script->tokenavailable = 0;
|
||
//
|
||
script->line = 1;
|
||
script->lastline = 1;
|
||
//
|
||
SetScriptPunctuations( script, NULL );
|
||
//
|
||
memcpy( script->buffer, ptr, length );
|
||
//
|
||
return script;
|
||
} //end of the function LoadScriptMemory
|
||
//============================================================================
|
||
//
|
||
// Parameter: -
|
||
// Returns: -
|
||
// Changes Globals: -
|
||
//============================================================================
|
||
void FreeScript( script_t *script ) {
|
||
#ifdef PUNCTABLE
|
||
if ( script->punctuationtable ) {
|
||
FreeMemory( script->punctuationtable );
|
||
}
|
||
#endif //PUNCTABLE
|
||
FreeMemory( script );
|
||
} //end of the function FreeScript
|