/*
=================
PC_Int_Parse
=================
*/
bool PC_Int_Parse( int handle, int *i )
{
	pc_token_t token;
	int        negative = false;

	if ( !trap_Parse_ReadToken( handle, &token ) )
	{
		return false;
	}

	if ( token.string[ 0 ] == '(' )
	{
		float f;

		if ( PC_Expression_Parse( handle, &f ) )
		{
			*i = ( int ) f;
			return true;
		}
		else
		{
			return false;
		}
	}

	if ( token.string[ 0 ] == '-' )
	{
		if ( !trap_Parse_ReadToken( handle, &token ) )
		{
			return false;
		}

		negative = true;
	}

	if ( token.type != TT_NUMBER )
	{
		PC_SourceError( handle, "expected integer but found %s", token.string );
		return false;
	}

	*i = token.intvalue;

	if ( negative )
	{
		*i = -*i;
	}

	return true;
}
pc_token_list *CreateTokenList( int handle )
{
	pc_token_t token;
	char filename[ MAX_QPATH ];
	pc_token_list *current = nullptr;
	pc_token_list *root = nullptr;

	while ( trap_Parse_ReadToken( handle, &token ) )
	{
		pc_token_list *list = ( pc_token_list * ) BG_Alloc( sizeof( pc_token_list ) );
		
		if ( current )
		{
			list->prev = current;
			current->next = list;
		}
		else
		{
			list->prev = list;
			root = list;
		}
		
		current = list;
		current->next = nullptr;

		current->token.floatvalue = token.floatvalue;
		current->token.intvalue = token.intvalue;
		current->token.subtype = token.subtype;
		current->token.type = token.type;
		current->token.string = BG_strdup( token.string );
		trap_Parse_SourceFileAndLine( handle, filename, &current->token.line );
	}

	return root;
}
/*
=================
PC_Script_Parse
=================
*/
bool PC_Script_Parse( int handle, const char **out )
{
	char       script[ 1024 ];
	pc_token_t token;

	memset( script, 0, sizeof( script ) );
	// scripts start with { and have ; separated command lists.. commands are command, arg..
	// basically we want everything between the { } as it will be interpreted at run time

	if ( !trap_Parse_ReadToken( handle, &token ) )
	{
		return false;
	}

	if ( Q_stricmp( token.string, "{" ) != 0 )
	{
		return false;
	}

	while ( 1 )
	{
		if ( !trap_Parse_ReadToken( handle, &token ) )
		{
			return false;
		}

		if ( Q_stricmp( token.string, "}" ) == 0 )
		{
			*out = BG_strdup( script );
			return true;
		}

		if ( token.string[ 1 ] != '\0' )
		{
			Q_strcat( script, 1024, va( "\"%s\"", token.string ) );
		}
		else
		{
			Q_strcat( script, 1024, token.string );
		}

		Q_strcat( script, 1024, " " );
	}

	return false;
}
/*
=================
PC_Float_Parse
=================
*/
bool PC_Float_Parse( int handle, float *f )
{
	pc_token_t token;
	int        negative = false;

	if ( !trap_Parse_ReadToken( handle, &token ) )
	{
		return false;
	}

	if ( token.string[ 0 ] == '(' )
	{
		return PC_Expression_Parse( handle, f );
	}

	if ( token.string[ 0 ] == '-' )
	{
		if ( !trap_Parse_ReadToken( handle, &token ) )
		{
			return false;
		}

		negative = true;
	}

	if ( token.type != TT_NUMBER )
	{
		PC_SourceError( handle, "expected float but found %s", token.string );
		return false;
	}

	if ( negative )
	{
		*f = -token.floatvalue;
	}
	else
	{
		*f = token.floatvalue;
	}

	return true;
}
/*
================
PC_Char_Parse
================
*/
bool PC_Char_Parse( int handle, char *out )
{
	pc_token_t token;

	if ( !trap_Parse_ReadToken( handle, &token ) )
	{
		return false;
	}

	*out = token.string[ 0 ];

	return true;
}
bool PC_String_ParseTranslate( int handle, const char **out )
{
	pc_token_t token;

	if ( !trap_Parse_ReadToken( handle, &token ) )
	{
		return false;
	}

	* ( out ) = BG_strdup( _(token.string) );

	return true;
}
void CG_BuildableStatusParse( const char *filename, buildStat_t *bs )
{
  pc_token_t token;
  int        handle;
  const char *s;
  int        i;
  float      f;
  vec4_t     c;

  handle = trap_Parse_LoadSource( filename );
  if( !handle )
    return;
  while( 1 )
  {
    if( !trap_Parse_ReadToken( handle, &token ) )
      break;
    if( !Q_stricmp( token.string, "frameShader" ) )
    {
      if( PC_String_Parse( handle, &s ) )
        bs->frameShader = trap_R_RegisterShader( s );
      continue;
    }
    else if( !Q_stricmp( token.string, "overlayShader" ) )
    {
      if( PC_String_Parse( handle, &s ) )
        bs->overlayShader = trap_R_RegisterShader( s );
      continue;
    }
    else if( !Q_stricmp( token.string, "noPowerShader" ) )
    {
      if( PC_String_Parse( handle, &s ) )
        bs->noPowerShader = trap_R_RegisterShader( s );
      continue;
    }
    else if( !Q_stricmp( token.string, "markedShader" ) )
    {
      if( PC_String_Parse( handle, &s ) )
        bs->markedShader = trap_R_RegisterShader( s );
      continue;
    }
    else if( !Q_stricmp( token.string, "healthSevereColor" ) )
    {
      if( PC_Color_Parse( handle, &c ) )
        Vector4Copy( c, bs->healthSevereColor );
      continue;
    }
    else if( !Q_stricmp( token.string, "healthHighColor" ) )
    {
      if( PC_Color_Parse( handle, &c ) )
        Vector4Copy( c, bs->healthHighColor );
      continue;
    }
    else if( !Q_stricmp( token.string, "healthElevatedColor" ) )
    {
      if( PC_Color_Parse( handle, &c ) )
        Vector4Copy( c, bs->healthElevatedColor );
      continue;
    }
    else if( !Q_stricmp( token.string, "healthGuardedColor" ) )
    {
      if( PC_Color_Parse( handle, &c ) )
        Vector4Copy( c, bs->healthGuardedColor );
      continue;
    }
    else if( !Q_stricmp( token.string, "healthLowColor" ) )
    {
      if( PC_Color_Parse( handle, &c ) )
        Vector4Copy( c, bs->healthLowColor );
      continue;
    }
    else if( !Q_stricmp( token.string, "foreColor" ) )
    {
      if( PC_Color_Parse( handle, &c ) )
        Vector4Copy( c, bs->foreColor );
      continue;
    }
    else if( !Q_stricmp( token.string, "backColor" ) )
    {
      if( PC_Color_Parse( handle, &c ) )
        Vector4Copy( c, bs->backColor );
      continue;
    }
    else if( !Q_stricmp( token.string, "frameHeight" ) )
    {
      if( PC_Int_Parse( handle, &i ) )
        bs->frameHeight = i;
      continue;
    }
    else if( !Q_stricmp( token.string, "frameWidth" ) )
    {
      if( PC_Int_Parse( handle, &i ) )
        bs->frameWidth = i;
      continue;
    }
    else if( !Q_stricmp( token.string, "healthPadding" ) )
    {
      if( PC_Int_Parse( handle, &i ) )
        bs->healthPadding = i;
      continue;
    }
    else if( !Q_stricmp( token.string, "overlayHeight" ) )
    {
      if( PC_Int_Parse( handle, &i ) )
        bs->overlayHeight = i;
      continue;
    }
    else if( !Q_stricmp( token.string, "overlayWidth" ) )
    {
      if( PC_Int_Parse( handle, &i ) )
        bs->overlayWidth = i;
      continue;
    }
    else if( !Q_stricmp( token.string, "verticalMargin" ) )
    {
      if( PC_Float_Parse( handle, &f ) )
        bs->verticalMargin = f;
      continue;
    }
    else if( !Q_stricmp( token.string, "horizontalMargin" ) )
    {
      if( PC_Float_Parse( handle, &f ) )
        bs->horizontalMargin = f;
      continue;
    }
    else
    {
      Com_Printf("CG_BuildableStatusParse: unknown token %s in %s\n",
        token.string, filename );
      bs->loaded = qfalse;
      return;
    }
  }
  bs->loaded = qtrue;
}
/*
=================
PC_Expression_Parse
=================
*/
static bool PC_Expression_Parse( int handle, float *f )
{
	pc_token_t  token;
	int         unmatchedParentheses = 0;
	exprList_t  stack, fifo;
	exprToken_t *value;
	bool    expectingNumber = true;

#define FULL( a )  ( a.b >= ( MAX_EXPR_ELEMENTS - 1 ) )
#define EMPTY( a ) ( a.f > a.b )

#define PUSH_VAL( a, v ) \
  { \
    if( FULL( a ) ) { \
      return false; } \
    a.b++; \
    a.l[ a.b ].type = EXPR_VALUE; \
    a.l[ a.b ].u.val = v; \
  }

#define PUSH_OP( a, o ) \
  { \
    if( FULL( a ) ) { \
      return false; } \
    a.b++; \
    a.l[ a.b ].type = EXPR_OPERATOR; \
    a.l[ a.b ].u.op = o; \
  }

#define POP_STACK( a ) \
  { \
    if( EMPTY( a ) ) { \
      return false; } \
    value = &a.l[ a.b ]; \
    a.b--; \
  }

#define PEEK_STACK_OP( a )  ( a.l[ a.b ].u.op )
#define PEEK_STACK_VAL( a ) ( a.l[ a.b ].u.val )

#define POP_FIFO( a ) \
  { \
    if( EMPTY( a ) ) { \
      return false; } \
    value = &a.l[ a.f ]; \
    a.f++; \
  }

	stack.f = fifo.f = 0;
	stack.b = fifo.b = -1;

	while ( trap_Parse_ReadToken( handle, &token ) )
	{
		if ( !unmatchedParentheses && token.string[ 0 ] == ')' )
		{
			break;
		}

		// Special case to catch negative numbers
		if ( expectingNumber && token.string[ 0 ] == '-' )
		{
			if ( !trap_Parse_ReadToken( handle, &token ) )
			{
				return false;
			}

			token.floatvalue = -token.floatvalue;
		}

		if ( token.type == TT_NUMBER )
		{
			if ( !expectingNumber )
			{
				return false;
			}

			expectingNumber = !expectingNumber;

			PUSH_VAL( fifo, token.floatvalue );
		}
		else
		{
			switch ( token.string[ 0 ] )
			{
				case '(':
					unmatchedParentheses++;
					PUSH_OP( stack, '(' );
					break;

				case ')':
					unmatchedParentheses--;

					if ( unmatchedParentheses < 0 )
					{
						return false;
					}

					while ( !EMPTY( stack ) && PEEK_STACK_OP( stack ) != '(' )
					{
						POP_STACK( stack );
						PUSH_OP( fifo, value->u.op );
					}

					// Pop the '('
					POP_STACK( stack );

					break;

				case '*':
				case '/':
				case '+':
				case '-':
					if ( expectingNumber )
					{
						return false;
					}

					expectingNumber = !expectingNumber;

					if ( EMPTY( stack ) )
					{
						PUSH_OP( stack, token.string[ 0 ] );
					}
					else
					{
						while ( !EMPTY( stack ) && OpPrec( token.string[ 0 ] ) < OpPrec( PEEK_STACK_OP( stack ) ) )
						{
							POP_STACK( stack );
							PUSH_OP( fifo, value->u.op );
						}

						PUSH_OP( stack, token.string[ 0 ] );
					}

					break;

				default:
					// Unknown token
					return false;
			}
		}
	}

	while ( !EMPTY( stack ) )
	{
		POP_STACK( stack );
		PUSH_OP( fifo, value->u.op );
	}

	while ( !EMPTY( fifo ) )
	{
		POP_FIFO( fifo );

		if ( value->type == EXPR_VALUE )
		{
			PUSH_VAL( stack, value->u.val );
		}
		else if ( value->type == EXPR_OPERATOR )
		{
			char  op = value->u.op;
			float operand1, operand2, result;

			POP_STACK( stack );
			operand2 = value->u.val;
			POP_STACK( stack );
			operand1 = value->u.val;

			switch ( op )
			{
				case '*':
					result = operand1 * operand2;
					break;

				case '/':
					result = operand1 / operand2;
					break;

				case '+':
					result = operand1 + operand2;
					break;

				case '-':
					result = operand1 - operand2;
					break;

				default:
					Com_Error( ERR_FATAL, "Unknown operator '%c' in postfix string", op );
			}

			PUSH_VAL( stack, result );
		}
	}

	POP_STACK( stack );

	*f = value->u.val;

	return true;

#undef FULL
#undef EMPTY
#undef PUSH_VAL
#undef PUSH_OP
#undef POP_STACK
#undef PEEK_STACK_OP
#undef PEEK_STACK_VAL
#undef POP_FIFO
}
/*
============
BG_VoiceParse
============
*/
static voiceCmd_t *BG_VoiceParse( const char *name )
{
	voiceCmd_t *voiceCmds = NULL;
	voiceCmd_t *top = NULL;
	pc_token_t token;
	qboolean   parsingCmd = qfalse;
	int        handle;

	handle = trap_Parse_LoadSource( va( "voice/%s.voice", name ) );

	if ( !handle )
	{
		return NULL;
	}

	while ( trap_Parse_ReadToken( handle, &token ) )
	{
		if ( parsingCmd )
		{
			if ( token.string[ 0 ] == '{' )
			{
				voiceCmds->tracks = BG_VoiceParseCommand( handle );
				parsingCmd = qfalse;
				continue;
			}
			else
			{
				int  line;
				char filename[ MAX_QPATH ];

				trap_Parse_SourceFileAndLine( handle, filename, &line );
				Com_Error( ERR_FATAL, "BG_VoiceParse(): "
				           "parse error on line %d of %s", line, filename );
			}
		}

		if ( strlen( token.string ) >= MAX_VOICE_CMD_LEN )
		{
			int  line;
			char filename[ MAX_QPATH ];

			trap_Parse_SourceFileAndLine( handle, filename, &line );
			Com_Error( ERR_FATAL, "BG_VoiceParse(): "
			           "command \"%s\" exceeds MAX_VOICE_CMD_LEN (%d) on line %d of %s",
			           token.string, MAX_VOICE_CMD_LEN, line, filename );
		}

		if ( top == NULL )
		{
			voiceCmds = BG_Alloc( sizeof( voiceCmd_t ) );
			top = voiceCmds;
		}
		else
		{
			voiceCmds->next = BG_Alloc( sizeof( voiceCmd_t ) );
			voiceCmds = voiceCmds->next;
		}

		Q_strncpyz( voiceCmds->cmd, token.string, sizeof( voiceCmds->cmd ) );
		voiceCmds->next = NULL;
		parsingCmd = qtrue;
	}

	trap_Parse_FreeSource( handle );

	return top;
}
Exemple #10
0
/*
============
BG_VoiceParseCommand
============
*/
static voiceTrack_t *BG_VoiceParseCommand( int handle )
{
	pc_token_t   token;
	qboolean     parsingTrack = qfalse;
	voiceTrack_t *voiceTracks = NULL;
	voiceTrack_t *top = NULL;

	while ( trap_Parse_ReadToken( handle, &token ) )
	{
		if ( !parsingTrack && token.string[ 0 ] == '}' )
		{
			return top;
		}

		if ( parsingTrack )
		{
			if ( token.string[ 0 ] == '{' )
			{
				BG_VoiceParseTrack( handle, voiceTracks );
				parsingTrack = qfalse;
				continue;
			}
			else
			{
				BG_VoiceParseError( handle, va( "BG_VoiceParseCommand(): "
				                                "parse error at \"%s\"", token.string ) );
			}
		}

		if ( top == NULL )
		{
			voiceTracks = BG_Alloc( sizeof( voiceTrack_t ) );
			top = voiceTracks;
		}
		else
		{
			voiceTracks->next = BG_Alloc( sizeof( voiceCmd_t ) );
			voiceTracks = voiceTracks->next;
		}

		if ( !trap_FS_FOpenFile( token.string, NULL, FS_READ ) )
		{
			int  line;
			char filename[ MAX_QPATH ];

			trap_Parse_SourceFileAndLine( handle, filename, &line );
			Com_Printf( S_WARNING "BG_VoiceParseCommand(): "
			            "track \"%s\" referenced on line %d of %s does not exist\n",
			            token.string, line, filename );
		}
		else
		{
#ifdef CGAME
			voiceTracks->track = trap_S_RegisterSound( token.string, qfalse );
			voiceTracks->duration = 0; // FIXME: Was always zero...
#endif
		}

		voiceTracks->team = -1;
		voiceTracks->pClass = -1;
		voiceTracks->weapon = -1;
		voiceTracks->enthusiasm = 0;
		voiceTracks->text = NULL;
		voiceTracks->next = NULL;
		parsingTrack = qtrue;
	}

	return NULL;
}
Exemple #11
0
/*
============
BG_VoiceParseTrack
============
*/
static qboolean BG_VoiceParseTrack( int handle, voiceTrack_t *voiceTrack )
{
	pc_token_t token;
	qboolean   found = qfalse;
	qboolean   foundText = qfalse;
	qboolean   foundToken = qfalse;

	foundToken = trap_Parse_ReadToken( handle, &token );

	while ( foundToken )
	{
		if ( token.string[ 0 ] == '}' )
		{
			if ( foundText )
			{
				return qtrue;
			}
			else
			{
				BG_VoiceParseError( handle, "BG_VoiceParseTrack(): "
				                    "missing text attribute for track" );
			}
		}
		else if ( !Q_stricmp( token.string, "team" ) )
		{
			foundToken = trap_Parse_ReadToken( handle, &token );
			found = qfalse;

			while ( foundToken )
			{
				if ( voiceTrack->team < 0 )
				{
					voiceTrack->team = 0;
				}

				if ( !Q_stricmp( token.string, "humans" ) )
				{
					voiceTrack->team |= 1 << TEAM_HUMANS;
				}
				else if ( !Q_stricmp( token.string, "aliens" ) )
				{
					voiceTrack->team |= 1 << TEAM_ALIENS;
				}
				else
				{
					break;
				}

				found = qtrue;
				foundToken = trap_Parse_ReadToken( handle, &token );
			}

			if ( !found )
			{
				BG_VoiceParseError( handle, "BG_VoiceParseTrack(): missing \"team\" name" );
			}

			continue;
		}
		else if ( !Q_stricmp( token.string, "class" ) )
		{
			qboolean negate = qfalse;

			foundToken = trap_Parse_ReadToken( handle, &token );
			found = qfalse;

			while ( foundToken )
			{
				classModelConfig_t *model;
				int                modelno = -1;

				if ( voiceTrack->pClass < 0 )
				{
					voiceTrack->pClass = 0;
				}

				if ( !Q_stricmp( token.string, "all" ) )
				{
					modelno = PCL_ALL_CLASSES;
				}
				else if ( !Q_stricmp( token.string, "humans" ) )
				{
					modelno = PCL_HUMAN_CLASSES;
				}
				else if ( !Q_stricmp( token.string, "aliens" ) )
				{
					modelno = PCL_ALIEN_CLASSES;
				}
				else if ( !Q_stricmp( token.string, "-" ) ) // this must be outside quotation marks
				{
					negate = qtrue;
					modelno = 0;
				}
				else
				{
					model = BG_ClassModelConfigByName( token.string );

					if ( model != BG_ClassModelConfigByName( NULL ) )
					{
						modelno = 1 << ( model - BG_ClassModelConfig( 0 ) );

						if ( modelno <= 1)
						{
							modelno = -1; // match failure
						}
					}

				}

				if ( modelno > 0 )
				{
					if ( negate )
					{
						negate = qfalse;
						voiceTrack->pClass &= ~modelno;
					}
					else
					{
						voiceTrack->pClass |= modelno;
					}
				}
				else if ( modelno < 0 )
				{
				        break; // possibly the next keyword
				}

				found = qtrue;
				foundToken = trap_Parse_ReadToken( handle, &token );
			}

			if ( !found )
			{
				BG_VoiceParseError( handle, "BG_VoiceParseTrack(): missing \"class\" name" );
			}

			continue;
		}
		else if ( !Q_stricmp( token.string, "text" ) )
		{
			if ( foundText )
			{
				BG_VoiceParseError( handle, "BG_VoiceParseTrack(): "
				                    "duplicate \"text\" definition for track" );
			}

			foundToken = trap_Parse_ReadToken( handle, &token );

			if ( !foundToken )
			{
				BG_VoiceParseError( handle, "BG_VoiceParseTrack(): "
				                    "missing \"text\" value" );
			}

			foundText = qtrue;

			if ( strlen( token.string ) >= MAX_SAY_TEXT )
			{
				BG_VoiceParseError( handle, va( "BG_VoiceParseTrack(): "
				                                "\"text\" value " "\"%s\" exceeds MAX_SAY_TEXT length",
				                                token.string ) );
			}

			voiceTrack->text = ( char * ) BG_Alloc( strlen( token.string ) + 1 );
			Q_strncpyz( voiceTrack->text, token.string, strlen( token.string ) + 1 );
			foundToken = trap_Parse_ReadToken( handle, &token );
			continue;
		}
		else if ( !Q_stricmp( token.string, "enthusiasm" ) )
		{
			foundToken = trap_Parse_ReadToken( handle, &token );

			if ( token.type == TT_NUMBER )
			{
				voiceTrack->enthusiasm = token.intvalue;
			}
			else
			{
				BG_VoiceParseError( handle, "BG_VoiceParseTrack(): "
				                    "missing \"enthusiasm\" value" );
			}

			foundToken = trap_Parse_ReadToken( handle, &token );
			continue;
		}
		else
		{
			BG_VoiceParseError( handle, va( "BG_VoiceParseTrack():"
			                                " unknown token \"%s\"", token.string ) );
		}
	}

	return qfalse;
}