Ejemplo n.º 1
0
/*
==============
LoadScriptFile
==============
*/
void LoadScriptFile( const char *filename ) {
	script = scriptstack;
	AddScriptToStack (filename);

	endofscript = qfalse;
	tokenready = qfalse;
}
Ejemplo n.º 2
0
/*
==============
LoadScriptFile
==============
*/
void LoadScriptFile (char *filename, ScriptPathMode_t pathMode)
{
	script = scriptstack;
	AddScriptToStack (filename, pathMode);

	endofscript = false;
	tokenready = false;
}
Ejemplo n.º 3
0
/*
==============
GetToken
==============
*/
qboolean GetToken (qboolean crossline)
{
	char    *token_p;

	if (tokenready)                         // is a token allready waiting?
	{
		tokenready = false;
		return true;
	}

	if (script->script_p >= script->end_p)
		return EndOfScript (crossline);

	TestBrushBegin();
//
// skip space
//
skipspace:
	while (*script->script_p <= 32)
	{
		if (script->script_p >= script->end_p)
			return EndOfScript (crossline);
		if (*script->script_p++ == '\n')
		{
			if (!crossline)
				Error ("Line %i is incomplete\n",scriptline);
			scriptline = script->line++;
		}
	}

	if (script->script_p >= script->end_p)
		return EndOfScript (crossline);

	// ; # // comments
	if (*script->script_p == ';' || *script->script_p == '#'
		|| ( script->script_p[0] == '/' && script->script_p[1] == '/') )
	{
		if (!crossline)
			Error ("Line %i is incomplete\n",scriptline);
		while (*script->script_p++ != '\n')
			if (script->script_p >= script->end_p)
				return EndOfScript (crossline);
			scriptline = script->line++;
		goto skipspace;
	}

	// /* */ comments
	if (script->script_p[0] == '/' && script->script_p[1] == '*')
	{
		if (!crossline)
			Error ("Line %i is incomplete\n",scriptline);
		script->script_p+=2;
		while (script->script_p[0] != '*' && script->script_p[1] != '/')
		{
			if(script->script_p[0] == '\n')
				scriptline = script->line++;

			script->script_p++;
			if (script->script_p >= script->end_p)
				return EndOfScript (crossline);
		}
		script->script_p += 2;
		goto skipspace;
	}

//
// copy token
//
	token_p = token;

	if (*script->script_p == '"')
	{
		// quoted token
		script->script_p++;
		while (*script->script_p != '"')
		{
			*token_p++ = *script->script_p++;
			if (script->script_p == script->end_p)
				break;
			if (token_p == &token[MAXTOKEN])
				Error ("Token too large on line %i\n",scriptline);
		}
		script->script_p++;
	}
	else	// regular token
	while ( *script->script_p > 32 && *script->script_p != ';')
	{
		*token_p++ = *script->script_p++;
		if (script->script_p == script->end_p)
			break;
		if (token_p == &token[MAXTOKEN])
			Error ("Token too large on line %i\n",scriptline);
	}

	*token_p = 0;

	if (!strcmp (token, "$include"))
	{
		GetToken (false);
		AddScriptToStack (token);
		return GetToken (crossline);
	}

	return true;
}
Ejemplo n.º 4
0
/*
==============
GetExprToken - use C mathematical operator parsing rules to split tokens instead of whitespace
==============
*/
qboolean GetExprToken (qboolean crossline)
{
	char    *token_p;

	if (tokenready)                         // is a token allready waiting?
	{
		tokenready = false;
		return true;
	}

	if (script->script_p >= script->end_p)
		return EndOfScript (crossline);

	tokenready = false;

//
// skip space
//
skipspace:
	while (*script->script_p <= 32)
	{
		if (script->script_p >= script->end_p)
			return EndOfScript (crossline);
		if (*script->script_p++ == '\n')
		{
			if (!crossline)
				Error ("Line %i is incomplete\n",scriptline);
			scriptline = ++script->line;
		}
	}

	if (script->script_p >= script->end_p)
		return EndOfScript (crossline);

	if (*script->script_p == ';' || *script->script_p == '#' ||		 // semicolon and # is comment field
		(*script->script_p == '/' && *((script->script_p)+1) == '/')) // also make // a comment field
	{											
		if (!crossline)
			Error ("Line %i is incomplete\n",scriptline);
		while (*script->script_p++ != '\n')
			if (script->script_p >= script->end_p)
				return EndOfScript (crossline);
		goto skipspace;
	}

//
// copy token
//
	token_p = token;

	if (*script->script_p == '"')
	{
		// quoted token
		script->script_p++;
		while (*script->script_p != '"')
		{
			*token_p++ = *script->script_p++;
			if (script->script_p == script->end_p)
				break;
			if (token_p == &token[MAXTOKEN])
				Error ("Token too large on line %i\n",scriptline);
		}
		script->script_p++;
	}
	else
	{
		if ( V_isalpha( *script->script_p ) || *script->script_p == '_' )
		{
			// regular token
			while ( V_isalnum( *script->script_p ) || *script->script_p == '_' )
			{
				*token_p++ = *script->script_p++;
				if (script->script_p == script->end_p)
					break;
				if (token_p == &token[MAXTOKEN])
					Error ("Token too large on line %i\n",scriptline);
			}
		}
		else if ( V_isdigit( *script->script_p ) || *script->script_p == '.' )
		{
			// regular token
			while ( V_isdigit( *script->script_p ) || *script->script_p == '.' )
			{
				*token_p++ = *script->script_p++;
				if (script->script_p == script->end_p)
					break;
				if (token_p == &token[MAXTOKEN])
					Error ("Token too large on line %i\n",scriptline);
			}
		}
		else
		{
			// single char
			*token_p++ = *script->script_p++;
		}
	}

	*token_p = 0;

	if (!stricmp (token, "$include"))
	{
		GetToken (false);
		AddScriptToStack (token);
		return GetToken (crossline);
	}

	return true;
}
Ejemplo n.º 5
0
/*
==============
GetToken
==============
*/
qboolean GetToken (qboolean crossline)
{
	char    *token_p;

	if (tokenready)                         // is a token allready waiting?
	{
		tokenready = false;
		return true;
	}

	// printf("script_p %x (%x)\n", script->script_p, script->end_p ); fflush( stdout );

	if (script->script_p >= script->end_p)
	{
		return EndOfScript (crossline);
	}

	tokenready = false;

	// skip space, ctrl chars
skipspace:
	while (*script->script_p <= 32)
	{
		if (script->script_p >= script->end_p)
		{
			return EndOfScript (crossline);
		}
		if (*(script->script_p++) == '\n')
		{
			if (!crossline)
			{
				Error ("Line %i is incomplete\n",scriptline);
			}
			scriptline = ++script->line;
		}
	}

	if (script->script_p >= script->end_p)
	{
		return EndOfScript (crossline);
	}

	// strip single line comments
	if (*script->script_p == ';' || *script->script_p == '#' ||		 // semicolon and # is comment field
		(*script->script_p == '/' && *((script->script_p)+1) == '/')) // also make // a comment field
	{											
		if (!crossline)
			Error ("Line %i is incomplete\n",scriptline);
		while (*script->script_p++ != '\n')
		{
			if (script->script_p >= script->end_p)
			{
				return EndOfScript (crossline);
			}
		}
		scriptline = ++script->line;
		goto skipspace;
	}

	//  strip out matching /* */ comments
	if (*script->script_p == '/' && *((script->script_p)+1) == '*')
	{
		script->script_p += 2;
		while (*script->script_p != '*' || *((script->script_p)+1) != '/')
		{
			if (*script->script_p++ != '\n')
			{
				if (script->script_p >= script->end_p)
				{
					return EndOfScript (crossline);
				}

				scriptline = ++script->line;
			}
		}
		script->script_p += 2;
		goto skipspace;
	}

	// copy token to buffer
	token_p = token;

	if (*script->script_p == '"')
	{
		// quoted token
		script->script_p++;
		while (*script->script_p != '"')
		{
			*token_p++ = *script->script_p++;
			if (script->script_p == script->end_p)
				break;
			if (token_p == &token[MAXTOKEN])
				Error ("Token too large on line %i\n",scriptline);
		}
		script->script_p++;
	}
	else if ( g_bCheckSingleCharTokens && !g_sSingleCharTokens.IsEmpty() && strchr( g_sSingleCharTokens.String(), *script->script_p ) != NULL )
	{
		*token_p++ = *script->script_p++;
	}
	else	// regular token
	while ( *script->script_p > 32 && *script->script_p != ';')
	{
		if ( !ExpandMacroToken( token_p ) )
		{
			if ( !ExpandVariableToken( token_p ) )
			{
				*token_p++ = *script->script_p++;
				if (script->script_p == script->end_p)
					break;
				if (token_p == &token[MAXTOKEN])
					Error ("Token too large on line %i\n",scriptline);

			}
		}
	}

	// add null to end of token
	*token_p = 0;

	// check for other commands
	if ( !stricmp( token, "$include" ) )
	{
		GetToken( false );

		bool bFallbackToToken = true;

		CUtlVector< CUtlString > expandedPathList;

		if ( CmdLib_ExpandWithBasePaths( expandedPathList, token ) > 0 )
		{
			for ( int i = 0; i < expandedPathList.Count(); ++i )
			{
				CUtlVector< CUtlString > findFileList;
				FindFileAbsoluteList( findFileList, expandedPathList[i].String() );

				if ( findFileList.Count() > 0 )
				{
					bFallbackToToken = false;

					// Only add the first set of glob matches from the first base path
					for ( int j = 0; j < findFileList.Count(); ++j )
					{
						AddScriptToStack( const_cast< char * >( findFileList[j].String() ) );
					}

					break;
				}
			}
		}

		if ( bFallbackToToken )
		{
			AddScriptToStack( token );
		}

		return GetToken( crossline );
	}
	else if (!stricmp (token, "$definemacro"))
	{
		GetToken (false);
		DefineMacro(token);
		return GetToken (crossline);
	}
	else if (!stricmp (token, "$definevariable"))
	{
		GetToken (false);
		DefineVariable(token);
		return GetToken (crossline);
	}
	else if (AddMacroToStack( token ))
	{
		return GetToken (crossline);
	}

	return true;
}
Ejemplo n.º 6
0
/*
==============
GetToken
==============
*/
qboolean GetToken (qboolean crossline)
{
	char    *token_p;

	if (tokenready)                         // is a token allready waiting?
	{
		tokenready = false;
		return true;
	}

	// printf("script_p %x (%x)\n", script->script_p, script->end_p ); fflush( stdout );

	if (script->script_p >= script->end_p)
	{
		return EndOfScript (crossline);
	}

	tokenready = false;

	// skip space, ctrl chars
skipspace:
	while (*script->script_p <= 32)
	{
		if (script->script_p >= script->end_p)
		{
			return EndOfScript (crossline);
		}
		if (*(script->script_p++) == '\n')
		{
			if (!crossline)
			{
				Error ("Line %i is incomplete\n",scriptline);
			}
			scriptline = ++script->line;
		}
	}

	if (script->script_p >= script->end_p)
	{
		return EndOfScript (crossline);
	}

	// strip single line comments
	if (*script->script_p == ';' || *script->script_p == '#' ||		 // semicolon and # is comment field
		(*script->script_p == '/' && *((script->script_p)+1) == '/')) // also make // a comment field
	{											
		if (!crossline)
			Error ("Line %i is incomplete\n",scriptline);
		while (*script->script_p++ != '\n')
		{
			if (script->script_p >= script->end_p)
			{
				return EndOfScript (crossline);
			}
		}
		scriptline = ++script->line;
		goto skipspace;
	}

	//  strip out matching /* */ comments
	if (*script->script_p == '/' && *((script->script_p)+1) == '*')
	{
		script->script_p += 2;
		while (*script->script_p != '*' || *((script->script_p)+1) != '/')
		{
			if (*script->script_p++ != '\n')
			{
				if (script->script_p >= script->end_p)
				{
					return EndOfScript (crossline);
				}

				scriptline = ++script->line;
			}
		}
		script->script_p += 2;
		goto skipspace;
	}

	// copy token to buffer
	token_p = token;

	if (*script->script_p == '"')
	{
		// quoted token
		script->script_p++;
		while (*script->script_p != '"')
		{
			*token_p++ = *script->script_p++;
			if (script->script_p == script->end_p)
				break;
			if (token_p == &token[MAXTOKEN])
				Error ("Token too large on line %i\n",scriptline);
		}
		script->script_p++;
	}
	else	// regular token
	while ( *script->script_p > 32 && *script->script_p != ';')
	{
		if ( !ExpandMacroToken( token_p ) )
		{
			if ( !ExpandVariableToken( token_p ) )
			{
				*token_p++ = *script->script_p++;
				if (script->script_p == script->end_p)
					break;
				if (token_p == &token[MAXTOKEN])
					Error ("Token too large on line %i\n",scriptline);

			}
		}
	}

	// add null to end of token
	*token_p = 0;

	// check for other commands
	if (!stricmp (token, "$include"))
	{
		GetToken (false);
		AddScriptToStack (token);
		return GetToken (crossline);
	}
	else if (!stricmp (token, "$definemacro"))
	{
		GetToken (false);
		DefineMacro(token);
		return GetToken (crossline);
	}
	else if (!stricmp (token, "$definevariable"))
	{
		GetToken (false);
		DefineVariable(token);
		return GetToken (crossline);
	}
	else if (AddMacroToStack( token ))
	{
		return GetToken (crossline);
	}

	return true;
}
Ejemplo n.º 7
0
void LoadScriptFile (const char *filename)
{
	script = scriptstack;
	AddScriptToStack(filename);
}
Ejemplo n.º 8
0
/*
   ==============
   GetToken
   ==============
 */
qboolean GetToken( qboolean crossline ){
	char    *token_p;


	/* ydnar: dummy testing */
	if ( script == NULL || script->buffer == NULL ) {
		return qfalse;
	}

	if ( tokenready ) {                       // is a token already waiting?
		tokenready = qfalse;
		return qtrue;
	}

	if ( ( script->script_p >= script->end_p ) || ( script->script_p == NULL ) ) {
		return EndOfScript( crossline );
	}

//
// skip space
//
skipspace:
	while ( *script->script_p <= 32 )
	{
		if ( script->script_p >= script->end_p ) {
			return EndOfScript( crossline );
		}
		if ( *script->script_p++ == '\n' ) {
			if ( !crossline ) {
				Error( "Line %i is incomplete\n",scriptline );
			}
			script->line++;
			scriptline = script->line;
		}
	}

	if ( script->script_p >= script->end_p ) {
		return EndOfScript( crossline );
	}

	// ; # // comments
	if ( *script->script_p == ';' || *script->script_p == '#'
		 || ( script->script_p[0] == '/' && script->script_p[1] == '/' ) ) {
		if ( !crossline ) {
			Error( "Line %i is incomplete\n",scriptline );
		}
		while ( *script->script_p++ != '\n' )
			if ( script->script_p >= script->end_p ) {
				return EndOfScript( crossline );
			}
		script->line++;
		scriptline = script->line;
		goto skipspace;
	}

	// /* */ comments
	if ( script->script_p[0] == '/' && script->script_p[1] == '*' ) {
		if ( !crossline ) {
			Error( "Line %i is incomplete\n",scriptline );
		}
		script->script_p += 2;
		while ( script->script_p[0] != '*' && script->script_p[1] != '/' )
		{
			if ( *script->script_p == '\n' ) {
				script->line++;
				scriptline = script->line;
			}
			script->script_p++;
			if ( script->script_p >= script->end_p ) {
				return EndOfScript( crossline );
			}
		}
		script->script_p += 2;
		goto skipspace;
	}

//
// copy token
//
	token_p = token;

	if ( *script->script_p == '"' ) {
		// quoted token
		script->script_p++;
		while ( *script->script_p != '"' )
		{
			*token_p++ = *script->script_p++;
			if ( script->script_p == script->end_p ) {
				break;
			}
			if ( token_p == &token[MAXTOKEN] ) {
				Error( "Token too large on line %i\n",scriptline );
			}
		}
		script->script_p++;
	}
	else{   // regular token
		while ( *script->script_p > 32 && *script->script_p != ';' )
		{
			*token_p++ = *script->script_p++;
			if ( script->script_p == script->end_p ) {
				break;
			}
			if ( token_p == &token[MAXTOKEN] ) {
				Error( "Token too large on line %i\n",scriptline );
			}
		}
	}

	*token_p = 0;

	if ( !strcmp( token, "$include" ) ) {
		GetToken( qfalse );
		AddScriptToStack( token, 0 );
		return GetToken( crossline );
	}

	return qtrue;
}
Ejemplo n.º 9
0
// *INDENT-OFF*
qboolean GetToken(qboolean crossline)
{
	char           *token_p;

	// ydnar: dummy testing
	if(script == NULL || script->buffer == NULL)
		return qfalse;

	if(tokenready)				// is a token already waiting?
	{
		tokenready = qfalse;
		return qtrue;
	}

	if((script->script_p >= script->end_p) || (script->script_p == NULL))
		return EndOfScript(crossline);

skipspace:
	// skip whitespace
	while(*script->script_p <= ' ')
	{
		if(script->script_p >= script->end_p)
			return EndOfScript(crossline);

		if(*script->script_p++ == '\n')
		{
			if(!crossline)
				Error("Line %i is incomplete", script->line);

			script->line++;
		}
	}

	if(script->script_p >= script->end_p)
		return EndOfScript(crossline);

	// skip ; # // comments
	if(*script->script_p == ';' || *script->script_p == '#' || (*script->script_p == '/' && script->script_p[1] == '/'))
	{
		if(!crossline)
			Error("Line %i is incomplete", script->line);

		while(*script->script_p && *script->script_p++ != '\n')
		{
			if(script->script_p >= script->end_p)
				return EndOfScript(crossline);
		}
		script->line++;
		goto skipspace;
	}

	// skip /* */ comments
#if 1
	if(*script->script_p == '/' && script->script_p[1] == '*')
	{
		if(!crossline)
			Error("Line %i is incomplete", script->line);

		script->script_p += 2;
		while(*script->script_p && (*script->script_p != '*' || script->script_p[1] != '/'))
		{
			if(*script->script_p == '\n')
			{
				script->line++;
			}
			script->script_p++;

			if(script->script_p >= script->end_p)
				return EndOfScript(crossline);
		}
		if(*script->script_p)
		{
			script->script_p += 2;
		}
		goto skipspace;
	}
#endif

	// copy token
	token_p = token;

	// check for a quotation
	if(*script->script_p == '"')
	{
		// quoted token
		script->script_p++;
		while(*script->script_p != '"')
		{
			*token_p++ = *script->script_p++;

			if(script->script_p == script->end_p)
				break;

			if(token_p == &token[MAXTOKEN])
				Error("Token too large on line %i", script->line);
		}
		script->script_p++;
	}
	// check for 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')	||
			(*script->script_p == '+' && script->script_p[1] >= '0' && script->script_p[1] <= '9')	||
			(*script->script_p == '.' && script->script_p[1] >= '0' && script->script_p[1] <= '9')	||
			(*script->script_p == '-' && script->script_p[1] == '.' && script->script_p[2] >= '0' && script->script_p[2] <= '9')
	)
	{
		do
		{
			*token_p++ = *script->script_p++;

			if(script->script_p == script->end_p)
				break;

			if(token_p == &token[MAXTOKEN])
				Error("Token too large on line %i", script->line);

		} while((*script->script_p >= '0' && *script->script_p <= '9') || *script->script_p == '.' );

		// parse the exponent
		if(*script->script_p == 'e' || *script->script_p == 'E')
		{
			*token_p++ = *script->script_p;

			script->script_p++;
			if(*script->script_p == '-' || *script->script_p == '+')
			{
				*token_p++ = *script->script_p++;
			}

			do
			{
				*token_p++ = *script->script_p++;

				if(script->script_p == script->end_p)
					break;

				if(token_p == &token[MAXTOKEN])
					Error("Token too large on line %i", script->line);

			} while(*script->script_p >= '0' && *script->script_p <= '9');
		}
	}
	// check for a regular word
	// we still allow forward and back slashes in name tokens for pathnames
	// and also colons for drive letters
	else if((*script->script_p >= 'a' && *script->script_p <= 'z')	||
			(*script->script_p >= 'A' && *script->script_p <= 'Z')	||
			(*script->script_p == '_')								||
			(*script->script_p == '/')								||
			(*script->script_p == '\\')								||
			(*script->script_p == '$')	)
	{
		do
		{
			*token_p++ = *script->script_p++;

			if(script->script_p == script->end_p)
				break;

			if(token_p == &token[MAXTOKEN])
				Error("Token too large on line %i", script->line);
		}
		while
		(
			   (*script->script_p >= 'a' && *script->script_p <= 'z')	||
			   (*script->script_p >= 'A' && *script->script_p <= 'Z')	||
			   (*script->script_p == '_') 								||
			   (*script->script_p == '-') 								||
			   (*script->script_p >= '0' && *script->script_p <= '9')	||
			   (*script->script_p == '/')								||
			   (*script->script_p == '\\')								||
			   (*script->script_p == ':')								||
			   (*script->script_p == '.')								||
			   (*script->script_p == '$')								||
			   (*script->script_p == '@')
		);
	}
	else
	{
		// single character punctuation
		*token_p++ = *script->script_p++;

		if(token_p == &token[MAXTOKEN])
			Error("Token too large on line %i", script->line);
	}

	// add tailing zero
	*token_p = 0;

	if(!strcmp(token, "$include"))
	{
		GetToken(qfalse);
		AddScriptToStack(token, 0);
		return GetToken(crossline);
	}

	return qtrue;
}
Ejemplo n.º 10
0
/**
 * @brief
 */
void LoadScriptFile(const char *file_name) {
	script = scriptstack;
	AddScriptToStack(file_name);

	endofscript = false;
}
Ejemplo n.º 11
0
/**
 * @brief
 */
_Bool GetToken(_Bool crossline) {
	char *token_p;

	if (script->script_p >= script->end_p) {
		return EndOfScript(crossline);
	}

	// skip space
skipspace:
	while (script->script_p < script->end_p && *script->script_p <= 32) {
		if (script->script_p >= script->end_p) {
			return EndOfScript(crossline);
		}
		if (*script->script_p++ == '\n') {
			if (!crossline) {
				Com_Error(ERROR_FATAL, "Line %i is incomplete (skip space)\n", scriptline);
			}
			scriptline = script->line++;
		}
	}

	if (script->script_p >= script->end_p) {
		return EndOfScript(crossline);
	}

	// comments
	if ((script->script_p[0] == '/' && script->script_p[1] == '/') || script->script_p[0] == ';') {
		if (!crossline) {
			Com_Error(ERROR_FATAL, "Line %i is incomplete (// comments)\n", scriptline);
		}
		while (*script->script_p++ != '\n')
			if (script->script_p >= script->end_p) {
				return EndOfScript(crossline);
			}
		goto skipspace;
	}

	// /* */ comments
	if (script->script_p[0] == '/' && script->script_p[1] == '*') {
		if (!crossline) {
			Com_Error(ERROR_FATAL, "Line %i is incomplete (/* comments */)\n", scriptline);
		}
		script->script_p += 2;
		while (script->script_p[0] != '*' && script->script_p[1] != '/') {
			script->script_p++;
			if (script->script_p >= script->end_p) {
				return EndOfScript(crossline);
			}
		}
		script->script_p += 2;
		goto skipspace;
	}

	// copy token
	token_p = token;

	if (*script->script_p == '"') {
		// quoted token
		script->script_p++;
		while (*script->script_p != '"') {
			*token_p++ = *script->script_p++;
			if (script->script_p == script->end_p) {
				break;
			}
			if (token_p == &token[MAXTOKEN]) {
				Com_Error(ERROR_FATAL, "Token too large on line %i\n", scriptline);
			}
		}
		script->script_p++;
	} else
		// regular token
		while (*script->script_p > 32 && *script->script_p != ';') {
			*token_p++ = *script->script_p++;
			if (script->script_p == script->end_p) {
				break;
			}
			if (token_p == &token[MAXTOKEN]) {
				Com_Error(ERROR_FATAL, "Token too large on line %i\n", scriptline);
			}
		}

	*token_p = 0;

	if (!g_strcmp0(token, "$include")) {
		GetToken(false);
		AddScriptToStack(token);
		return GetToken(crossline);
	}

	return true;
}
Ejemplo n.º 12
0
/*
 * GetToken
 */
boolean_t GetToken(boolean_t crossline){
	char *token_p;

	if(script->script_p >= script->end_p)
		return EndOfScript(crossline);

// skip space
skipspace:
	while(script->script_p < script->end_p && *script->script_p <= 32){
		if(script->script_p >= script->end_p)
			return EndOfScript(crossline);
		if(*script->script_p++ == '\n'){
			if(!crossline)
				Com_Error(ERR_FATAL, "GetToken 0: Line %i is incomplete\n", scriptline);
			scriptline = script->line++;
		}
	}

	if(script->script_p >= script->end_p)
		return EndOfScript(crossline);

	// comments
	if((script->script_p[0] == '/' && script->script_p[1] == '/') ||
			script->script_p[0] == ';'){
		if(!crossline)
			Com_Error(ERR_FATAL, "GetToken 1: Line %i is incomplete\n", scriptline);
		while(*script->script_p++ != '\n')
			if(script->script_p >= script->end_p)
				return EndOfScript(crossline);
		goto skipspace;
	}

	// /* */ comments
	if(script->script_p[0] == '/' && script->script_p[1] == '*'){
		if(!crossline)
			Com_Error(ERR_FATAL, "GetToken 2: Line %i is incomplete\n", scriptline);
		script->script_p+=2;
		while(script->script_p[0] != '*' && script->script_p[1] != '/'){
			script->script_p++;
			if(script->script_p >= script->end_p)
				return EndOfScript(crossline);
		}
		script->script_p += 2;
		goto skipspace;
	}

	// copy token
	token_p = token;

	if(*script->script_p == '"'){
		// quoted token
		script->script_p++;
		while(*script->script_p != '"'){
			*token_p++ = *script->script_p++;
			if(script->script_p == script->end_p)
				break;
			if(token_p == &token[MAXTOKEN])
				Com_Error(ERR_FATAL, "Token too large on line %i\n", scriptline);
		}
		script->script_p++;
	} else	// regular token
		while(*script->script_p > 32 && *script->script_p != ';'){
			*token_p++ = *script->script_p++;
			if(script->script_p == script->end_p)
				break;
			if(token_p == &token[MAXTOKEN])
				Com_Error(ERR_FATAL, "Token too large on line %i\n", scriptline);
		}

	*token_p = 0;

	if(!strcmp(token, "$include")){
		GetToken(false);
		AddScriptToStack(token);
		return GetToken(crossline);
	}

	return true;
}