/* =========================================================================== Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 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 . 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= ============ */ void idCmdArgs::operator=( const idCmdArgs& args ) { int i; argc = args.argc; memcpy( tokenized, args.tokenized, MAX_COMMAND_STRING ); for( i = 0; i < argc; i++ ) { argv[ i ] = tokenized + ( args.argv[ i ] - args.tokenized ); } } /* ============ idCmdArgs::Args ============ */ const char* idCmdArgs::Args( int start, int end, bool escapeArgs ) const { static char cmd_args[MAX_COMMAND_STRING]; int i; assert( argc < MAX_COMMAND_ARGS ); if( end < 0 ) { end = argc - 1; } else if( end >= argc ) { end = argc - 1; } cmd_args[0] = '\0'; if( escapeArgs ) { strcat( cmd_args, "\"" ); } for( i = start; i <= end; i++ ) { if( i > start ) { if( escapeArgs ) { strcat( cmd_args, "\" \"" ); } else { strcat( cmd_args, " " ); } } if( escapeArgs && strchr( argv[i], '\\' ) ) { char* p = argv[i]; while( *p != '\0' ) { if( *p == '\\' ) { strcat( cmd_args, "\\\\" ); } else { int l = strlen( cmd_args ); cmd_args[ l ] = *p; cmd_args[ l + 1 ] = '\0'; } p++; } } else { strcat( cmd_args, argv[i] ); } } if( escapeArgs ) { strcat( cmd_args, "\"" ); } 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. ============ */ void idCmdArgs::TokenizeString( const char* text, bool keepAsStrings ) { idLexer lex; idToken token, number; int len, totalLen; // clear previous args argc = 0; if( !text ) { return; } lex.LoadMemory( text, strlen( text ), "idCmdSystemLocal::TokenizeString" ); lex.SetFlags( LEXFL_NOERRORS | LEXFL_NOWARNINGS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWIPADDRESSES | ( keepAsStrings ? LEXFL_ONLYSTRINGS : 0 ) ); totalLen = 0; while( 1 ) { if( argc == MAX_COMMAND_ARGS ) { return; // this is usually something malicious } if( !lex.ReadToken( &token ) ) { return; } // check for negative numbers if( !keepAsStrings && ( token == "-" ) ) { if( lex.CheckTokenType( TT_NUMBER, 0, &number ) ) { token = "-" + number; } } // check for cvar expansion if( token == "$" ) { if( !lex.ReadToken( &token ) ) { return; } if( idLib::cvarSystem ) { token = idLib::cvarSystem->GetCVarString( token.c_str() ); } else { token = ""; } } len = token.Length(); if( totalLen + len + 1 > sizeof( tokenized ) ) { return; // this is usually something malicious } // regular token argv[argc] = tokenized + totalLen; argc++; idStr::Copynz( tokenized + totalLen, token.c_str(), sizeof( tokenized ) - totalLen ); totalLen += len + 1; } } /* ============ idCmdArgs::AppendArg ============ */ void idCmdArgs::AppendArg( const char* text ) { if( argc >= MAX_COMMAND_ARGS ) { return; } if( !argc ) { argc = 1; argv[ 0 ] = tokenized; idStr::Copynz( tokenized, text, sizeof( tokenized ) ); } else { argv[ argc ] = argv[ argc - 1 ] + strlen( argv[ argc - 1 ] ) + 1; idStr::Copynz( argv[ argc ], text, sizeof( tokenized ) - ( argv[ argc ] - tokenized ) ); argc++; } } /* ============ idCmdArgs::GetArgs ============ */ const char* const* idCmdArgs::GetArgs( int* _argc ) { *_argc = argc; return ( const char** )&argv[0]; }