2012-11-26 18:58:24 +00:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
|
|
|
|
Doom 3 BFG Edition GPL Source Code
|
2012-11-28 15:47:07 +00:00
|
|
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
2012-11-26 18:58:24 +00:00
|
|
|
|
2012-11-28 15:47:07 +00:00
|
|
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
2012-11-26 18:58:24 +00:00
|
|
|
|
|
|
|
Doom 3 BFG Edition 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.
|
|
|
|
|
|
|
|
Doom 3 BFG Edition 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
In addition, the Doom 3 BFG Edition 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 Doom 3 BFG Edition 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.
|
|
|
|
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "precompiled.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
idCmdArgs::operator=
|
|
|
|
============
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
void idCmdArgs::operator=( const idCmdArgs& args )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
int i;
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
argc = args.argc;
|
|
|
|
memcpy( tokenized, args.tokenized, MAX_COMMAND_STRING );
|
2012-11-28 15:47:07 +00:00
|
|
|
for( i = 0; i < argc; i++ )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
argv[ i ] = tokenized + ( args.argv[ i ] - args.tokenized );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
idCmdArgs::Args
|
|
|
|
============
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
const char* idCmdArgs::Args( int start, int end, bool escapeArgs ) const
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
static char cmd_args[MAX_COMMAND_STRING];
|
|
|
|
int i;
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
assert( argc < MAX_COMMAND_ARGS );
|
2012-11-28 15:47:07 +00:00
|
|
|
if( end < 0 )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
end = argc - 1;
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else if( end >= argc )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
end = argc - 1;
|
|
|
|
}
|
|
|
|
cmd_args[0] = '\0';
|
2012-11-28 15:47:07 +00:00
|
|
|
if( escapeArgs )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
strcat( cmd_args, "\"" );
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
for( i = start; i <= end; i++ )
|
|
|
|
{
|
|
|
|
if( i > start )
|
|
|
|
{
|
|
|
|
if( escapeArgs )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
strcat( cmd_args, "\" \"" );
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
strcat( cmd_args, " " );
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( escapeArgs && strchr( argv[i], '\\' ) )
|
|
|
|
{
|
|
|
|
char* p = argv[i];
|
|
|
|
while( *p != '\0' )
|
|
|
|
{
|
|
|
|
if( *p == '\\' )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
strcat( cmd_args, "\\\\" );
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
int l = strlen( cmd_args );
|
|
|
|
cmd_args[ l ] = *p;
|
2012-11-28 15:47:07 +00:00
|
|
|
cmd_args[ l + 1 ] = '\0';
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
strcat( cmd_args, argv[i] );
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( escapeArgs )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
strcat( cmd_args, "\"" );
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
return cmd_args;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
idCmdArgs::TokenizeString
|
|
|
|
|
|
|
|
Parses the given string into command line tokens.
|
|
|
|
The text is copied to a separate buffer and 0 characters
|
|
|
|
are inserted in the appropriate place. The argv array
|
|
|
|
will point into this temporary buffer.
|
|
|
|
============
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
void idCmdArgs::TokenizeString( const char* text, bool keepAsStrings )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
idLexer lex;
|
|
|
|
idToken token, number;
|
|
|
|
int len, totalLen;
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// clear previous args
|
|
|
|
argc = 0;
|
2012-11-28 15:47:07 +00:00
|
|
|
|
|
|
|
if( !text )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
lex.LoadMemory( text, strlen( text ), "idCmdSystemLocal::TokenizeString" );
|
|
|
|
lex.SetFlags( LEXFL_NOERRORS
|
2012-11-28 15:47:07 +00:00
|
|
|
| LEXFL_NOWARNINGS
|
|
|
|
| LEXFL_NOSTRINGCONCAT
|
|
|
|
| LEXFL_ALLOWPATHNAMES
|
|
|
|
| LEXFL_NOSTRINGESCAPECHARS
|
|
|
|
| LEXFL_ALLOWIPADDRESSES | ( keepAsStrings ? LEXFL_ONLYSTRINGS : 0 ) );
|
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
totalLen = 0;
|
2012-11-28 15:47:07 +00:00
|
|
|
|
|
|
|
while( 1 )
|
|
|
|
{
|
|
|
|
if( argc == MAX_COMMAND_ARGS )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return; // this is usually something malicious
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
|
|
|
|
if( !lex.ReadToken( &token ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// check for negative numbers
|
2012-11-28 15:47:07 +00:00
|
|
|
if( !keepAsStrings && ( token == "-" ) )
|
|
|
|
{
|
|
|
|
if( lex.CheckTokenType( TT_NUMBER, 0, &number ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
token = "-" + number;
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// check for cvar expansion
|
2012-11-28 15:47:07 +00:00
|
|
|
if( token == "$" )
|
|
|
|
{
|
|
|
|
if( !lex.ReadToken( &token ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( idLib::cvarSystem )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
token = idLib::cvarSystem->GetCVarString( token.c_str() );
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
token = "<unknown>";
|
|
|
|
}
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
len = token.Length();
|
2012-11-28 15:47:07 +00:00
|
|
|
|
|
|
|
if( totalLen + len + 1 > sizeof( tokenized ) )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return; // this is usually something malicious
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
// regular token
|
|
|
|
argv[argc] = tokenized + totalLen;
|
|
|
|
argc++;
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr::Copynz( tokenized + totalLen, token.c_str(), sizeof( tokenized ) - totalLen );
|
2012-11-28 15:47:07 +00:00
|
|
|
|
2012-11-26 18:58:24 +00:00
|
|
|
totalLen += len + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
idCmdArgs::AppendArg
|
|
|
|
============
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
void idCmdArgs::AppendArg( const char* text )
|
|
|
|
{
|
|
|
|
if( argc >= MAX_COMMAND_ARGS )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-11-28 15:47:07 +00:00
|
|
|
if( !argc )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
argc = 1;
|
|
|
|
argv[ 0 ] = tokenized;
|
|
|
|
idStr::Copynz( tokenized, text, sizeof( tokenized ) );
|
2012-11-28 15:47:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
argv[ argc ] = argv[ argc - 1 ] + strlen( argv[ argc - 1 ] ) + 1;
|
2012-11-26 18:58:24 +00:00
|
|
|
idStr::Copynz( argv[ argc ], text, sizeof( tokenized ) - ( argv[ argc ] - tokenized ) );
|
|
|
|
argc++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
idCmdArgs::GetArgs
|
|
|
|
============
|
|
|
|
*/
|
2012-11-28 15:47:07 +00:00
|
|
|
const char* const* idCmdArgs::GetArgs( int* _argc )
|
|
|
|
{
|
2012-11-26 18:58:24 +00:00
|
|
|
*_argc = argc;
|
2012-11-28 15:47:07 +00:00
|
|
|
return ( const char** )&argv[0];
|
2012-11-26 18:58:24 +00:00
|
|
|
}
|
|
|
|
|