DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

CmdArgs.cpp (5124B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 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.
     23 
     24 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.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #include "precompiled.h"
     30 #pragma hdrstop
     31 
     32 /*
     33 ============
     34 idCmdArgs::operator=
     35 ============
     36 */
     37 void idCmdArgs::operator=( const idCmdArgs &args ) {
     38 	int i;
     39 
     40 	argc = args.argc;
     41 	memcpy( tokenized, args.tokenized, MAX_COMMAND_STRING );
     42 	for ( i = 0; i < argc; i++ ) {
     43 		argv[ i ] = tokenized + ( args.argv[ i ] - args.tokenized );
     44 	}
     45 }
     46 
     47 /*
     48 ============
     49 idCmdArgs::Args
     50 ============
     51 */
     52 const char *idCmdArgs::Args(  int start, int end, bool escapeArgs ) const {
     53 	static char cmd_args[MAX_COMMAND_STRING];
     54 	int		i;
     55 
     56 	assert( argc < MAX_COMMAND_ARGS );
     57 	if ( end < 0 ) {
     58 		end = argc - 1;
     59 	} else if ( end >= argc ) {
     60 		end = argc - 1;
     61 	}
     62 	cmd_args[0] = '\0';
     63 	if ( escapeArgs ) {
     64 		strcat( cmd_args, "\"" );
     65 	}
     66 	for ( i = start; i <= end; i++ ) {
     67 		if ( i > start ) {
     68 			if ( escapeArgs ) {
     69 				strcat( cmd_args, "\" \"" );
     70 			} else {
     71 				strcat( cmd_args, " " );
     72 			}
     73 		}
     74 		if ( escapeArgs && strchr( argv[i], '\\' ) ) {
     75 			char *p = argv[i];
     76 			while ( *p != '\0' ) {
     77 				if ( *p == '\\' ) {
     78 					strcat( cmd_args, "\\\\" );
     79 				} else {
     80 					int l = strlen( cmd_args );
     81 					cmd_args[ l ] = *p;
     82 					cmd_args[ l+1 ] = '\0';
     83 				}
     84 				p++;
     85 			}
     86 		} else {
     87 			strcat( cmd_args, argv[i] );
     88 		}
     89 	}
     90 	if ( escapeArgs ) {
     91 		strcat( cmd_args, "\"" );
     92 	}
     93 
     94 	return cmd_args;
     95 }
     96 
     97 /*
     98 ============
     99 idCmdArgs::TokenizeString
    100 
    101 Parses the given string into command line tokens.
    102 The text is copied to a separate buffer and 0 characters
    103 are inserted in the appropriate place. The argv array
    104 will point into this temporary buffer.
    105 ============
    106 */
    107 void idCmdArgs::TokenizeString( const char *text, bool keepAsStrings ) {
    108 	idLexer		lex;
    109 	idToken		token, number;
    110 	int			len, totalLen;
    111 
    112 	// clear previous args
    113 	argc = 0;
    114 
    115 	if ( !text ) {
    116 		return;
    117 	}
    118 
    119 	lex.LoadMemory( text, strlen( text ), "idCmdSystemLocal::TokenizeString" );
    120 	lex.SetFlags( LEXFL_NOERRORS
    121 				| LEXFL_NOWARNINGS
    122 				| LEXFL_NOSTRINGCONCAT
    123 				| LEXFL_ALLOWPATHNAMES
    124 				| LEXFL_NOSTRINGESCAPECHARS
    125 				| LEXFL_ALLOWIPADDRESSES | ( keepAsStrings ? LEXFL_ONLYSTRINGS : 0 ) );
    126 
    127 	totalLen = 0;
    128 
    129 	while ( 1 ) {
    130 		if ( argc == MAX_COMMAND_ARGS ) {
    131 			return;			// this is usually something malicious
    132 		}
    133 
    134 		if ( !lex.ReadToken( &token ) ) {
    135 			return;
    136 		}
    137 
    138 		// check for negative numbers
    139 		if ( !keepAsStrings && ( token == "-" ) ) {
    140 			if ( lex.CheckTokenType( TT_NUMBER, 0, &number ) ) {
    141 				token = "-" + number;
    142 			}
    143 		}
    144 
    145 		// check for cvar expansion
    146 		if ( token == "$" ) {
    147 			if ( !lex.ReadToken( &token ) ) {
    148 				return;
    149 			}
    150 			if ( idLib::cvarSystem ) {
    151 				token = idLib::cvarSystem->GetCVarString( token.c_str() );
    152 			} else {
    153 				token = "<unknown>";
    154 			}
    155 		}
    156 
    157 		len = token.Length();
    158 
    159 		if ( totalLen + len + 1 > sizeof( tokenized ) ) {
    160 			return;			// this is usually something malicious
    161 		}
    162 
    163 		// regular token
    164 		argv[argc] = tokenized + totalLen;
    165 		argc++;
    166 
    167 		idStr::Copynz( tokenized + totalLen, token.c_str(), sizeof( tokenized ) - totalLen );
    168 
    169 		totalLen += len + 1;
    170 	}
    171 }
    172 
    173 /*
    174 ============
    175 idCmdArgs::AppendArg
    176 ============
    177 */
    178 void idCmdArgs::AppendArg( const char *text ) {
    179 	if ( argc >= MAX_COMMAND_ARGS ) {
    180 		return;
    181 	}
    182 	if ( !argc ) {
    183 		argc = 1;
    184 		argv[ 0 ] = tokenized;
    185 		idStr::Copynz( tokenized, text, sizeof( tokenized ) );
    186 	} else {
    187 		argv[ argc ] = argv[ argc-1 ] + strlen( argv[ argc-1 ] ) + 1;
    188 		idStr::Copynz( argv[ argc ], text, sizeof( tokenized ) - ( argv[ argc ] - tokenized ) );
    189 		argc++;
    190 	}
    191 }
    192 
    193 /*
    194 ============
    195 idCmdArgs::GetArgs
    196 ============
    197 */
    198 const char * const * idCmdArgs::GetArgs( int *_argc ) {
    199 	*_argc = argc;
    200 	return (const char **)&argv[0];
    201 }
    202