perfsrv/analyzetool/commandlineengine/src/arguments.cpp
changeset 48 516af714ebb4
equal deleted inserted replaced
45:185201be11b0 48:516af714ebb4
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Argument parsing functions.
       
    15 */
       
    16 #include "../inc/ATCommonDefines.h"
       
    17 #include "../inc/CATBase.h"
       
    18 
       
    19 //Forward declarations.
       
    20 bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args );
       
    21 bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args );
       
    22 bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args );
       
    23 bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args );
       
    24 bool checkDataFileName( string& sFileName );
       
    25 bool checkDataFilePath( string& sFilePath );
       
    26 bool parseSbsConfiguration( string& sConfiguration, ARGUMENTS& args );
       
    27 
       
    28 // Constants for old "hooking" parameter parsing.
       
    29 #define INVALID_PARAMETER "AnalyzeTool : Error, invalid parameter: "
       
    30 const char DATAFILENAME_INVALID_CHARS[] = " &^+-@$*()|\\/[]{}<>?;:,\"'";
       
    31 const char DATAFILEPATH_INVALID_CHARS[] = " &^+-@$%*()|/[]{}<>?;,\"'";
       
    32 
       
    33 /**
       
    34 * Check datafile name for invalid characters.
       
    35 * @return true if file name ok.
       
    36 */
       
    37 bool checkDataFileName( string& sFileName )
       
    38 {
       
    39 	for ( size_t i = 0; i < sFileName.length(); i++ )
       
    40 	{
       
    41 		const char c = sFileName.at( i );
       
    42 		if( strchr( DATAFILENAME_INVALID_CHARS, c ) != 0 )
       
    43 			return false;
       
    44 	}
       
    45 	return true;
       
    46 }
       
    47 
       
    48 /**
       
    49 * Check datafile path for invalid characters and correct format.
       
    50 * @return true if file path ok.
       
    51 */
       
    52 bool checkDataFilePath( string& sFilePath )
       
    53 {
       
    54 	for ( size_t i = 0; i < sFilePath.length(); i++ )
       
    55 	{
       
    56 		char c = sFilePath.at( i );
       
    57 		if( strchr( DATAFILEPATH_INVALID_CHARS, c ) != 0 )
       
    58 			return false;
       
    59 		// first char must be drive letter a-z
       
    60 		if( i == 0 && ( c = tolower( c ) < 'a' || c > 'z' ) )
       
    61 			return false;
       
    62 		// if last char is not '\', add it
       
    63 		if( i == sFilePath.length()-1 &&  c != '\\' )
       
    64 			sFilePath.append( "\\" );
       
    65 	}
       
    66 
       
    67 	// ':\' after drive letter
       
    68 	if( sFilePath.find( ":\\" ) != 1 )
       
    69 		return false;
       
    70 
       
    71 	// there can be only one ':' on pos 1
       
    72 	if( sFilePath.find( ":", 2 ) != string::npos )
       
    73 		return false;
       
    74 
       
    75 	//check double slashes
       
    76 	if( sFilePath.find( "\\\\" ) != string::npos )
       
    77 		return false;
       
    78 
       
    79 	return true;
       
    80 }
       
    81 
       
    82 /**
       
    83 * Parse base arguments from given vector of strings.
       
    84 * Removes debug / help arguments from vector.
       
    85 */
       
    86 bool parseBaseArguments( vector<string>& vArgs, ARGUMENTS& args )
       
    87 {
       
    88 	// Iterator used in this function.
       
    89 	vector<string>::iterator it;
       
    90 	// If no arguments set show help true.
       
    91  	if ( vArgs.size() == 0 )
       
    92 	{
       
    93 		args.eMainSwitch = SWITCH_UNKNOWN;
       
    94 		args.bHelp = true;
       
    95 	}
       
    96 	//Try find help and debug switches.
       
    97 	//Note: -help is main switch what shows syntax examples.
       
    98 	for(it = vArgs.begin(); it != vArgs.end(); it++ )
       
    99 	{
       
   100 		//Help switches.
       
   101 		if ( ! _stricmp( (*it).c_str(), "-?" ) )
       
   102 		{
       
   103 			args.bHelp = true;
       
   104 			it = vArgs.erase( it );
       
   105 			if ( it == vArgs.end() )
       
   106 				break;
       
   107 		}
       
   108 		else if ( ! _stricmp( (*it).c_str(), "--?" ) )
       
   109 		{
       
   110 			args.bHelp = true;
       
   111 			it = vArgs.erase( it );
       
   112 			if ( it == vArgs.end() )
       
   113 				break;
       
   114 		}
       
   115 		else if ( ! _stricmp( (*it).c_str(), "--help" ) )
       
   116 		{
       
   117 			args.bHelp = true;
       
   118 			it = vArgs.erase( it );
       
   119 			if ( it == vArgs.end() )
       
   120 				break;
       
   121 		}
       
   122 		else if ( ! _stricmp( (*it).c_str(), "/?" ) )
       
   123 		{
       
   124 			args.bHelp = true;
       
   125 			it = vArgs.erase( it );
       
   126 			if ( it == vArgs.end() )
       
   127 				break;
       
   128 		}
       
   129 		//Debug switches.
       
   130 		else if ( ! _stricmp( (*it).c_str(), "-show_debug" ) )
       
   131 		{
       
   132 			args.bDebugConsole = true;
       
   133 			it = vArgs.erase( it );
       
   134 			if ( it == vArgs.end() )
       
   135 				break;
       
   136 		}
       
   137 		else if ( ! _stricmp( (*it).c_str(), "--show_debug" ) )
       
   138 		{
       
   139 			args.bDebugConsole = true;
       
   140 			it = vArgs.erase( it );
       
   141 			if ( it == vArgs.end() )
       
   142 				break;
       
   143 		}
       
   144 		else if ( ! _stricmp( (*it).c_str(), "-show_debug_all" ) )
       
   145 		{
       
   146 			args.bDebugConsole = true;
       
   147 			args.bDebugLowLevel = true;
       
   148 			it = vArgs.erase( it );
       
   149 			if ( it == vArgs.end() )
       
   150 				break;
       
   151 		}
       
   152 		else if ( ! _stricmp( (*it).c_str(), "--show_debug_all" ) )
       
   153 		{
       
   154 			args.bDebugConsole = true;
       
   155 			args.bDebugLowLevel = true;
       
   156 			it = vArgs.erase( it );
       
   157 			if ( it == vArgs.end() )
       
   158 				break;
       
   159 		}
       
   160 		else if ( ! _stricmp( (*it).c_str(), "-show_dbgview" ) )
       
   161 		{
       
   162 			args.bDebugDbgView = true;
       
   163 			it = vArgs.erase( it );
       
   164 			if ( it == vArgs.end() )
       
   165 				break;
       
   166 		}
       
   167 		else if ( ! _stricmp( (*it).c_str(), "--show_dbgview" ) )
       
   168 		{
       
   169 			args.bDebugDbgView = true;
       
   170 			it = vArgs.erase( it );
       
   171 			if ( it == vArgs.end() )
       
   172 				break;
       
   173 		}
       
   174 		else if ( ! _stricmp( (*it).c_str(), "-show_dbgview_all" ) )
       
   175 		{
       
   176 			args.bDebugDbgView = true;
       
   177 			args.bDebugLowLevel = true;
       
   178 			it = vArgs.erase( it );
       
   179 			if ( it == vArgs.end() )
       
   180 				break;
       
   181 		}
       
   182 		else if ( ! _stricmp( (*it).c_str(), "--show_dbgview_all" ) )
       
   183 		{
       
   184 			args.bDebugDbgView = true;
       
   185 			args.bDebugLowLevel = true;
       
   186 			it = vArgs.erase( it );
       
   187 			if ( it == vArgs.end() )
       
   188 				break;
       
   189 		}
       
   190 		//Raptor switch.
       
   191 		else if ( ! _stricmp( (*it).c_str(), "-sbs2" ) )
       
   192 		{
       
   193 			args.bEnableSbs2 = true;
       
   194 			it = vArgs.erase( it );
       
   195 			if ( it == vArgs.end() )
       
   196 				break;
       
   197 		}
       
   198 	}
       
   199 	if ( vArgs.size() > 0 )
       
   200 	{
       
   201 		//Pick up main switch.
       
   202 		it = vArgs.begin();
       
   203 		if ( ! _stricmp( (*it).c_str(), "-a" ) )
       
   204 			args.eMainSwitch = SWITCH_ANALYZE;
       
   205 		else if ( ! _stricmp( (*it).c_str(), "-p" ) )
       
   206 			args.eMainSwitch = SWITCH_PARSE_TRACE;
       
   207 		else if ( ! _stricmp( (*it).c_str(), "-c" ) )
       
   208 			args.eMainSwitch = SWITCH_CLEAN;
       
   209 		else if ( ! _stricmp( (*it).c_str(), "-v" ) )
       
   210 			args.eMainSwitch = SWITCH_VERSION;
       
   211 		else if ( ! _stricmp( (*it).c_str(), "-vdbghelp" ) )
       
   212 			args.eMainSwitch = SWITCH_DBGHELP_VERSION;
       
   213 		else if ( ! _stricmp( (*it).c_str(), "-help" ) )
       
   214 			args.eMainSwitch = SWITCH_HELP;
       
   215 		else if ( ! _stricmp( (*it).c_str(), "-me" ) )
       
   216 		{
       
   217 			cout << AT_MSG << "This feature is no longer supported. You can use -tr parameter for output to trace. \n" << endl;
       
   218 		}
       
   219 		else if ( ! _stricmp( (*it).c_str(), "-e" ) ||  ! _stricmp( (*it).c_str(), "-tr" ) )
       
   220 		{
       
   221 			args.eMainSwitch = SWITCH_HOOK;
       
   222 			args.eHookSwitch = HOOK_EXTERNAL_FAST;
       
   223 		}
       
   224 		else if ( ! _stricmp( (*it).c_str(), "-mi" ) )
       
   225 		{
       
   226 			cout << AT_MSG << "This feature is no longer supported. You can use -lf parameter for logging to file. \n" << endl;
       
   227 		}
       
   228 		else if ( ! _stricmp( (*it).c_str(), "-lf" ) )
       
   229 		{
       
   230 			args.eMainSwitch = SWITCH_HOOK;
       
   231 			args.eHookSwitch = HOOK_INTERNAL;
       
   232 		}
       
   233 		else if ( ! _stricmp( (*it).c_str(), "-instrument_i" ) )
       
   234 		{
       
   235 			args.eMainSwitch = SWITCH_HOOK;
       
   236 			args.eHookSwitch = HOOK_EXTENSION_INTERNAL;
       
   237 		}
       
   238 		else if ( ! _stricmp( (*it).c_str(), "-instrument_e" ) )
       
   239 		{
       
   240 			args.eMainSwitch = SWITCH_HOOK;
       
   241 			args.eHookSwitch = HOOK_EXTENSION_EXTERNAL;
       
   242 		}
       
   243 		else if ( ! _stricmp( (*it).c_str(), "-instrument_ef" ) )
       
   244 		{
       
   245 			args.eMainSwitch = SWITCH_HOOK;
       
   246 			args.eHookSwitch = HOOK_EXTENSION_EXTERNAL_FAST;
       
   247 		}
       
   248 		else if ( ! _stricmp( (*it).c_str(), "-uninstrument" ) )
       
   249 		{
       
   250 			args.eMainSwitch = SWITCH_UNHOOK;
       
   251 			args.eHookSwitch = HOOK_EXTENSION_UNINSTRUMENT;
       
   252 		}
       
   253 		else if ( ! _stricmp( (*it).c_str(), "-uninstrument_failed" ) )
       
   254 		{
       
   255 			args.eMainSwitch = SWITCH_UNHOOK;
       
   256 			args.eHookSwitch = HOOK_EXTENSION_FAILED;
       
   257 		}
       
   258 	}
       
   259 	return true;
       
   260 }
       
   261 
       
   262 /**
       
   263 * Parse analyze related arguments from given vector of strings.
       
   264 */
       
   265 bool parseAnalyzeArguments( vector<string>& vArgs, ARGUMENTS& args )
       
   266 {
       
   267 	bool bRet = true;
       
   268 	if ( vArgs.size() < 2 )
       
   269 	{
       
   270 		cout << AT_MSG << "Error, missing datafile." << endl;
       
   271 		return false;
       
   272 	}
       
   273 	// Iterator used in this function.
       
   274 	vector<string>::const_iterator it;
       
   275 	for(it = vArgs.begin()+1; it != vArgs.end(); it++ )
       
   276 	{
       
   277 		if ( it->find("-l") != string::npos )
       
   278 		{
       
   279 			if ( it->length() == 3 )
       
   280 			{
       
   281 				// Create char array for atoi function
       
   282 				char level[2];
       
   283 				level[0] = it->at(2);
       
   284 				level[1] = 0; // null terminate
       
   285 				// check that its digit first
       
   286 				if ( isdigit(level[0]) )
       
   287 				{
       
   288 					// pass array to atoi
       
   289 					int iLoggingLevel = atoi( level );
       
   290 					if ( iLoggingLevel >= 0 && iLoggingLevel <= 3 )
       
   291 					{
       
   292 						// log level ok
       
   293 						args.ANALYZE.iLoggingLevel = iLoggingLevel;
       
   294 						continue;
       
   295 					}
       
   296 				}
       
   297 				bRet = false;
       
   298 				cout << AT_MSG << "Invalid logging level specified (0-3)." << endl;
       
   299 				args.ANALYZE.iLoggingLevel = -1;
       
   300 			}
       
   301 		}
       
   302 		// No else here because logging level check is done to all args in list.
       
   303 		// Rom symbol file
       
   304 		if( _stricmp( it->c_str(), "-s" ) == 0 )
       
   305 		{
       
   306 			it++;
       
   307 			if ( it == vArgs.end() )
       
   308 			{
       
   309 				bRet = false;
       
   310 				cout << AT_MSG << "Missing symbol file." << endl;
       
   311 				break; // Leave for loop.
       
   312 			}
       
   313 			else
       
   314 			{
       
   315 				args.ANALYZE.bSymbolFile = true;
       
   316 				args.ANALYZE.vSymbolFiles.push_back( *it );
       
   317 				continue;
       
   318 			}
       
   319 		}
       
   320 		else 
       
   321 		{
       
   322 			// If we got datafile we must assume this is output
       
   323 			if( ! args.ANALYZE.sDataFile.empty() )
       
   324 			{
       
   325 				if ( args.ANALYZE.sOutputFile.empty() )
       
   326 					args.ANALYZE.sOutputFile = *it;
       
   327 				else
       
   328 				{
       
   329 					bRet = false;
       
   330 					cout << AT_MSG << "Invalid parameter: " << *it << endl;
       
   331 				}
       
   332 			}
       
   333 			// If this is file we assume datafile
       
   334 			else if( CATBase::FileExists( it->c_str() ) )
       
   335 			{
       
   336 				args.ANALYZE.sDataFile = *it;
       
   337 			}
       
   338 			else
       
   339 			{
       
   340 				bRet = false;
       
   341 				cout << AT_MSG << "Specified datafile does not exist." << endl;
       
   342 			}
       
   343 		}
       
   344 	}
       
   345 	if ( args.ANALYZE.sDataFile.empty() )
       
   346 		bRet = false;
       
   347 	return bRet;
       
   348 }
       
   349 
       
   350 
       
   351 /**
       
   352 * Parse hooking related arguments from given vector of strings.
       
   353 */
       
   354 bool parseHookArguments( vector<string>& vArgs, ARGUMENTS& args )
       
   355 {
       
   356 	bool bRet = true;
       
   357 	try {
       
   358 		// Iterator used in this function.
       
   359 		vector<string>::const_iterator it;
       
   360 
       
   361 		// Check that we have some arguments except main switch.
       
   362 		if ( vArgs.size() < 2 )
       
   363 		{
       
   364 			if ( args.eHookSwitch == HOOK_EXTENSION_UNINSTRUMENT
       
   365 				|| args.eHookSwitch == HOOK_EXTENSION_FAILED
       
   366 				)
       
   367 				return bRet;
       
   368 			cout << AT_MSG << "Error, Missing build command." << endl;
       
   369 			bRet = false;
       
   370 		}
       
   371 		bool bBuildFound = false;
       
   372 		for(it = vArgs.begin()+1; it != vArgs.end(); it++ )
       
   373 		{
       
   374 			// If's to pickup atool options
       
   375 			// no build switch
       
   376 			if ( _stricmp( it->c_str(), "-nobuild" ) == 0 )
       
   377 			{
       
   378 				args.HOOK.bNoBuild = true;
       
   379 			}
       
   380 			// call stack size(s)
       
   381 			else if ( _stricmp( it->c_str(), "-acs" ) == 0 || _stricmp( it->c_str(), "-fcs" ) == 0 )
       
   382 			{
       
   383 				// Free vs Alloc
       
   384 				bool bAlloc = true;
       
   385 				if ( _stricmp( it->c_str(), "-fcs" ) == 0 )
       
   386 					bAlloc = false;
       
   387 				// Value
       
   388 				it++;
       
   389 				if ( it== vArgs.end() )
       
   390 				{
       
   391 					bRet = false;
       
   392 					cout << AT_MSG << "Error, missing call stack size parameter." << endl;
       
   393 					break;
       
   394 				}
       
   395 				else if ( ! _stricmp( it->c_str(), "sbs" ) 
       
   396 					|| ! _stricmp( it->c_str(), "abld" )
       
   397 					|| ! _stricmp( it->c_str(), "-f" )
       
   398 					|| ! _stricmp( it->c_str(), "-fp" ) )
       
   399 				{
       
   400 					bRet = false;
       
   401 					cout << AT_MSG << "Error, missing call stack size parameter." << endl;
       
   402 					break;
       
   403 				}
       
   404 				else
       
   405 				{
       
   406 					int i;
       
   407 					// Try to parse integer value using stream.
       
   408 					istringstream ss( *it );
       
   409 					if ( ss>>i )
       
   410 					{
       
   411 						// Value parsed ok now check bounds.
       
   412 						if ( i < AT_CALL_STACK_SIZE_MIN  )
       
   413 						{
       
   414 							bRet = false;
       
   415 							cout << AT_MSG << "Error, specified call stack size value too small." << endl;
       
   416 							break;
       
   417 						}
       
   418 						else if ( i > AT_CALL_STACK_SIZE_MAX )
       
   419 						{
       
   420 							bRet = false;
       
   421 							cout << AT_MSG << "Error, specified call stack size value too big." << endl;
       
   422 							break;
       
   423 						}
       
   424 						else
       
   425 						{
       
   426 							// Value valid.
       
   427 							if ( bAlloc )
       
   428 								args.HOOK.iAllocCallStackSize = i;
       
   429 							else
       
   430 								args.HOOK.iFreeCallStackSize = i;
       
   431 						}
       
   432 					}
       
   433 					else
       
   434 					{
       
   435 						// Error parsing value using stream.
       
   436 						bRet = false;
       
   437 						cout << AT_MSG << "Error, specified call stack size value invalid." << endl;
       
   438 						break;
       
   439 					}
       
   440 
       
   441 				}
       
   442 			}
       
   443 			// Data file name.
       
   444 			else if ( _stricmp( it->c_str(), "-f" ) == 0 )
       
   445 			{
       
   446 				it++;
       
   447 				if ( it == vArgs.end() )
       
   448 				{
       
   449 					bRet = false;
       
   450 					cout << AT_MSG << "Error, missing log file name." << endl;
       
   451 					break;
       
   452 				}
       
   453 				else if ( ! _stricmp( it->c_str(), "sbs" ) || ! _stricmp( it->c_str(), "abld" ) )
       
   454 				{
       
   455 					bRet = false;
       
   456 					cout << AT_MSG << "Error, missing log file name." << endl;
       
   457 					break;
       
   458 				}
       
   459 				else
       
   460 				{
       
   461 					if ( checkDataFileName( string( *it ) ) )
       
   462 					{
       
   463 						// Pickup filename.
       
   464 						args.HOOK.bDataFileName = true;
       
   465 						args.HOOK.sDataFileName = *it;
       
   466 					}
       
   467 					else
       
   468 					{
       
   469 						bRet = false;
       
   470 						cout << AT_MSG << "Error, specified log file name contains invalid character(s)." << endl;
       
   471 						break;
       
   472 					}
       
   473 				}
       
   474 			}
       
   475 			// Data file path.
       
   476 			else if ( _stricmp( it->c_str(), "-fp" ) == 0 )
       
   477 			{
       
   478 				it++;
       
   479 				if ( it == vArgs.end() )
       
   480 				{
       
   481 					bRet = false;
       
   482 					cout << AT_MSG << "Error, missing path for log file." << endl;
       
   483 					break;
       
   484 				}
       
   485 				else if ( ! _stricmp( it->c_str(), "sbs" ) || ! _stricmp( it->c_str(), "abld" ) )
       
   486 				{
       
   487 					bRet = false;
       
   488 					cout << AT_MSG << "Error, missing path for log file." << endl;
       
   489 					break;
       
   490 				}
       
   491 				else
       
   492 				{
       
   493 					string sFormattedPath = string(*it);
       
   494 					if ( checkDataFilePath( sFormattedPath ) )
       
   495 					{
       
   496 						// Pickup filename.
       
   497 						args.HOOK.bDataFilePath = true;
       
   498 						args.HOOK.sDataFilePath = sFormattedPath;
       
   499 					}
       
   500 					else
       
   501 					{
       
   502 						bRet = false;
       
   503 						cout << AT_MSG << "Error, specified log file path contains invalid character(s) "
       
   504 							<< "or is in wrong format. Please, check help for correct format," << endl;
       
   505 						break;
       
   506 					}
       
   507 				}
       
   508 			}
       
   509 			// Build command parsing.
       
   510 			else if ( _stricmp( it->c_str(), "sbs" ) == 0 )
       
   511 			{
       
   512 				// By default sbs command is not valid.
       
   513 				bRet = false;
       
   514 				// By default build found
       
   515 				bBuildFound = true;
       
   516 				// Use raptor build system, pickup all rest arguments to sbs commmand.
       
   517 				bool bFoundConfig = false; // Is configuration defined.
       
   518 				args.HOOK.iBuildSystem = 2;
       
   519 				vector<string>::const_iterator itC = it;
       
   520 				args.HOOK.sBuildCmd.clear();
       
   521 				for ( ; itC != vArgs.end() ; itC++ )
       
   522 				{
       
   523 					args.HOOK.sBuildCmd.append( *itC );
       
   524 					args.HOOK.sBuildCmd.append( " " );
       
   525 					args.HOOK.vBuildCmd.push_back( *itC );
       
   526 				}
       
   527 				// Remove last space
       
   528 				if ( args.HOOK.vBuildCmd.size() > 1 )
       
   529 					args.HOOK.sBuildCmd.erase( args.HOOK.sBuildCmd.size()-1 );
       
   530 
       
   531 				// Parse needed variables from sbs command.
       
   532 				vector<string>::iterator itSbs;
       
   533 				for( itSbs = args.HOOK.vBuildCmd.begin(); itSbs != args.HOOK.vBuildCmd.end() ; itSbs++ )
       
   534 				{
       
   535 					// Program(s).
       
   536 					if ( _stricmp( itSbs->c_str(), "-p" ) == 0 )
       
   537 					{
       
   538 						// Next is program.
       
   539 						itSbs++;
       
   540 						args.HOOK.vTargetPrograms.push_back( *itSbs );
       
   541 					}
       
   542 					else if ( itSbs->find( "--project=" ) != string::npos )
       
   543 					{
       
   544 						itSbs->erase(0, 10 );
       
   545 						args.HOOK.vTargetPrograms.push_back( *itSbs );
       
   546 					}
       
   547 					// platform & build type ( configuration )
       
   548 					else if ( _stricmp( itSbs->c_str(), "-c" ) == 0 || itSbs->find( "--config=" ) != string::npos )
       
   549 					{
       
   550 						// Error message if config found more than once.
       
   551 						if ( bFoundConfig )
       
   552 						{
       
   553 							cout << AT_MSG << "Error, no support defining more than one configuration." << endl;
       
   554 							bRet = false;
       
   555 							continue;
       
   556 						}
       
   557 
       
   558 						if (_stricmp( itSbs->c_str(), "-c" ) == 0 )
       
   559 						{
       
   560 							// Next is the configuration
       
   561 							itSbs++;
       
   562 							// Check that iterator is valid.
       
   563 							if ( itSbs == args.HOOK.vBuildCmd.end() )
       
   564 								break;
       
   565 						}
       
   566 						else
       
   567 						{
       
   568 							// Remove the "--config=".
       
   569 							itSbs->erase( 0, 9 );
       
   570 							// Check its not empty.
       
   571 							if ( itSbs->size() == 0 )
       
   572 								break;
       
   573 						}
       
   574 						
       
   575 						// Identify configuration, if successful set sbs command as valid.
       
   576 						if ( parseSbsConfiguration( *itSbs, args ) )
       
   577 							bRet = true;
       
   578 						// Set we encountered one configuration.
       
   579 						bFoundConfig = true;
       
   580 					}
       
   581 				}
       
   582 				// Error message if command is missing configuration.
       
   583 				if ( !bFoundConfig )
       
   584 					cout << AT_MSG << "Error, missing configuration definition from sbs cmd." << endl;
       
   585 			}
       
   586 			else if ( _stricmp( it->c_str(), "abld" ) == 0 )
       
   587 			{
       
   588 				bBuildFound = true;
       
   589 				// Use abld build system, pickup all rest argumenst as abld options.
       
   590 				args.HOOK.iBuildSystem = 1;
       
   591 				
       
   592 				vector<string>::const_iterator itC = it;
       
   593 				args.HOOK.sBuildCmd.clear();
       
   594 				for ( ; itC != vArgs.end() ; itC++ )
       
   595 				{
       
   596 					args.HOOK.sBuildCmd.append( *itC );
       
   597 					args.HOOK.sBuildCmd.append( " " );
       
   598 					args.HOOK.vBuildCmd.push_back( *itC );
       
   599 				}
       
   600 				
       
   601 				string sCmd( args.HOOK.sBuildCmd ); // build command to lower case here.
       
   602 				for( size_t i = 0 ; i < sCmd.size(); i++ )
       
   603 					sCmd.at(i) = tolower( sCmd.at(i) );
       
   604 
       
   605 				// Remove all until platform
       
   606 				if ( sCmd.find("build ") != string::npos )
       
   607 				{
       
   608 					// Check is test defined
       
   609 					if ( sCmd.substr(0, sCmd.find("build ")).find("test") != string::npos )
       
   610 						args.HOOK.bAbldTest = true;
       
   611 					sCmd.erase( 0, sCmd.find("build")+6 );
       
   612 				}
       
   613 				else
       
   614 					return false;
       
   615 				
       
   616 				//Is -debug switch in command?
       
   617 				if( sCmd.find( "-debug " ) != string::npos )
       
   618 				{
       
   619 					sCmd.erase( sCmd.find( "-debug " ), 7 );
       
   620 				}
       
   621 
       
   622 				// Parse needed "variables" from command.
       
   623 				bool bOk = false;
       
   624 
       
   625 				// Find platform
       
   626 				if ( sCmd.find( "armv5" ) != string::npos )
       
   627 				{
       
   628 					bOk = true;
       
   629 					args.HOOK.sPlatform = "armv5";
       
   630 					sCmd.erase( sCmd.find( "armv5" ), 5 );
       
   631 				}
       
   632 				else if ( sCmd.find( "winscw" ) != string::npos )
       
   633 				{
       
   634 					bOk = true;
       
   635 					args.HOOK.sPlatform = "winscw";
       
   636 					sCmd.erase( sCmd.find( "winscw" ), 6 );
       
   637 				}
       
   638 				else if ( sCmd.find( "gcce" ) != string::npos )
       
   639 				{
       
   640 					bOk = true;
       
   641 					args.HOOK.sPlatform = "gcce";
       
   642 					sCmd.erase( sCmd.find( "gcce" ), 4 );
       
   643 				}
       
   644 				if ( bOk )
       
   645 				{
       
   646 					// Feature variant.
       
   647 					if ( sCmd.at(0 ) == '.' )
       
   648 					{
       
   649 						sCmd.erase(0,1);
       
   650 						args.HOOK.sFeatureVariant = sCmd.substr( 0, sCmd.find_first_of(' ') );
       
   651 						sCmd.erase(0, sCmd.find_first_of(' ')+1 );
       
   652 					}
       
   653 				}
       
   654 				else
       
   655 				{
       
   656 					// not platform specified.
       
   657 					cout << AT_MSG << "Error, no supported platform found in abld parameters (armv5/winscw/gcce)." << endl;
       
   658 					bRet = false;
       
   659 				}
       
   660 				
       
   661 				// find build type
       
   662 				bOk = false;
       
   663 				if (  sCmd.find( "urel" ) != string::npos )
       
   664 				{
       
   665 					bOk = true;
       
   666 					args.HOOK.sBuildType = "urel";
       
   667 					sCmd.erase( sCmd.find( "urel" ), 4 );
       
   668 				}
       
   669 
       
   670 				else if ( sCmd.find( "udeb" ) != string::npos )
       
   671 				{
       
   672 					bOk = true;
       
   673 					args.HOOK.sBuildType = "udeb";
       
   674 					sCmd.erase( sCmd.find( "udeb" ), 4 );
       
   675 				}
       
   676 				if( !bOk )
       
   677 				{
       
   678 					// no build type specified.
       
   679 					cout << AT_MSG << "Error, no build type specified in abld parameters (udeb/urel)." << endl;
       
   680 					bRet = false;
       
   681 				}
       
   682 		
       
   683 				// Is there multiple programs (only should be used from extension).
       
   684 				if ( sCmd.find(" -p") != string::npos )
       
   685 				{
       
   686 					sCmd.erase( sCmd.find(" -p" ), sCmd.size() - sCmd.find(" -p" ) );
       
   687 					// Loop thru all parameters and pick up programs.
       
   688 					vector<string>::iterator it;
       
   689 					for( it = args.HOOK.vBuildCmd.begin(); it != args.HOOK.vBuildCmd.end(); it++ )
       
   690 					{
       
   691 						if ( _stricmp( it->c_str(), "-p" ) == 0 )
       
   692 						{
       
   693 							// Next is program.
       
   694 							it++;
       
   695 							string sProgram = *it;
       
   696 							// Make sure program name ends with ".mmp".
       
   697 							CATBase::ChangeToLower( sProgram );
       
   698 							if ( sProgram.length() >= 4 )
       
   699 							{
       
   700                                 string sEnd = sProgram.substr( sProgram.length()-4, 4 );
       
   701 								if ( sEnd.compare( ".mmp" ) != 0 )
       
   702 									sProgram.append( ".mmp" );
       
   703 							}
       
   704 							else
       
   705 								sProgram.append( ".mmp" );
       
   706 							args.HOOK.vTargetPrograms.push_back( sProgram );
       
   707 						}
       
   708 					}
       
   709 				}
       
   710 				else {
       
   711 					// find single defined program.
       
   712 					if ( sCmd.find_first_not_of(' ') != string::npos )
       
   713 					{
       
   714 						size_t iS = sCmd.find_first_not_of(' ');
       
   715 						size_t iE = sCmd.find_first_of(' ', iS );
       
   716 						string sProgram;
       
   717 						if ( iE == string::npos )
       
   718 							sProgram = sCmd.substr( iS, sCmd.size()-iS );
       
   719 						else
       
   720 							sProgram =  sCmd.substr( iS, iE-iS);
       
   721 						// Make sure program name ends with ".mmp".
       
   722 						CATBase::ChangeToLower( sProgram );
       
   723 						if ( sProgram.length() >= 4 )
       
   724 						{
       
   725                             string sEnd = sProgram.substr( sProgram.length()-4, 4 );
       
   726 							if ( sEnd.compare( ".mmp" ) != 0 )
       
   727 								sProgram.append( ".mmp" );
       
   728 						}
       
   729 						else
       
   730 							sProgram.append( ".mmp" );
       
   731 						args.HOOK.vTargetPrograms.push_back( sProgram );
       
   732 					}
       
   733 				}
       
   734 			}
       
   735 			else
       
   736 			{
       
   737 				if ( ! bBuildFound )
       
   738 				{
       
   739 					bRet = false;
       
   740 					cout << AT_MSG << "Error, invalid parameter :" << *it << endl;
       
   741 					break;
       
   742 				}
       
   743 			}
       
   744 		}
       
   745 	}
       
   746 	catch(...)
       
   747 	{
       
   748 		bRet = false;
       
   749 		cout << AT_MSG << "Error parsing arguments." << endl;
       
   750 	}
       
   751 	return bRet;
       
   752 }
       
   753 
       
   754 
       
   755 /**
       
   756 * Parse trace parsing related arguments from given vector of strings.
       
   757 */
       
   758 bool parseParseArguments( vector<string>& vArgs, ARGUMENTS& args )
       
   759 {
       
   760 	// Iterator used in this function.
       
   761 	vector<string>::const_iterator it = vArgs.begin();
       
   762 
       
   763 	if ( it == vArgs.end() )
       
   764 		return false;
       
   765 
       
   766 	it++;
       
   767 
       
   768 	if ( it == vArgs.end() )
       
   769 	{
       
   770 		cout << AT_MSG << "Error, input file not defined (raw data file)." << endl;
       
   771 		return false;
       
   772 	}
       
   773 
       
   774 	//Input.
       
   775 	args.PARSE.bDataFile = true;
       
   776 	args.PARSE.sDataFile = *it;
       
   777 	
       
   778 	it++;
       
   779 	if ( it == vArgs.end() )
       
   780 	{
       
   781 	
       
   782 		cout << AT_MSG << "Error, output file not defined (device data file)." << endl;
       
   783 		return false;
       
   784 	}
       
   785 
       
   786 	//Output.
       
   787 	args.PARSE.bOutputFile = true;
       
   788 	args.PARSE.sOutputFile = *it;
       
   789 	return true;
       
   790 }
       
   791 
       
   792 /**
       
   793 * Identifies/parses the configuration string when raptor used (-c / --config= ).
       
   794 */
       
   795 bool parseSbsConfiguration( string& sConfiguration, ARGUMENTS& args )
       
   796 {
       
   797 	CATBase::ChangeToLower( sConfiguration );
       
   798 	vector<string> tokens = CATBase::ParseStringToVector( sConfiguration, '.' );
       
   799 	
       
   800 	//we check if winscw/armv5 and udeb/urel is used
       
   801 	//rest of the "." are variants which we all support by default.
       
   802 
       
   803 	//first we check if some of aliases is used
       
   804 	if ( tokens.at(0).compare("armv5_urel") == 0 )
       
   805 	{
       
   806 		args.HOOK.sPlatform = "armv5";
       
   807 		args.HOOK.sBuildType = "urel";
       
   808 		return true;
       
   809 	}
       
   810 	else if ( tokens.at(0).compare("armv5_udeb") == 0 )
       
   811 	{
       
   812 		args.HOOK.sPlatform = "armv5";
       
   813 		args.HOOK.sBuildType = "udeb";
       
   814 		return true;
       
   815 	}
       
   816 	else if ( tokens.at(0).compare("winscw_udeb") == 0)
       
   817 	{
       
   818 		args.HOOK.sPlatform = "winscw";
       
   819 		args.HOOK.sBuildType = "udeb";
       
   820 		return true;
       
   821 	}
       
   822 	else if ( tokens.at(0).compare("winscw_urel") == 0 )
       
   823 	{
       
   824 		args.HOOK.sPlatform = "winscw";
       
   825 		args.HOOK.sBuildType = "urel";
       
   826 		return true;
       
   827 	}
       
   828 	//if 1st token is not an alias, lets try dot configurations
       
   829 	else if ( tokens.at(0).compare("arm") == 0 )
       
   830 	{
       
   831 		// check we have atleast 3 tokens. i.e arm v5 debug x ...
       
   832 		if ( tokens.size() >= 3 )
       
   833 		{
       
   834 			// Next configuration is arm version, we only support v5.
       
   835 			if ( tokens.at(1).compare( "v5" ) == 0)
       
   836 			{
       
   837 				args.HOOK.sPlatform = "armv5";
       
   838 
       
   839 				// Check next configuration part is debug or release
       
   840 				if ( tokens.at(2).compare( "udeb" ) == 0)
       
   841 				{
       
   842 					args.HOOK.sBuildType = "udeb";
       
   843 					return true;
       
   844 				}
       
   845 				else if ( tokens.at(2).compare( "urel" ) == 0 )
       
   846 				{
       
   847 					args.HOOK.sBuildType = "urel";
       
   848 					return true;
       
   849 				}
       
   850 				else
       
   851 				{
       
   852 					cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(2) << endl;
       
   853 				    cout << AT_MSG << "Supported are: udeb,urel." << endl;
       
   854 				    return false;
       
   855 				}
       
   856 			}
       
   857 			else
       
   858 			{
       
   859 				cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(1) << endl;
       
   860 				cout << AT_MSG << "Supported are: v5." << endl;
       
   861 				return false;
       
   862 			}
       
   863 		}
       
   864 	}
       
   865 	
       
   866 	cout << AT_MSG << "Error in sbs configuration part: " << tokens.at(0) << endl;
       
   867 	cout << AT_MSG << "Supported are: arm, armv5_urel, armv5_udeb, winscw_udeb, winscw_urel." << endl;
       
   868 	return false;
       
   869 
       
   870 }
       
   871 
       
   872 //EOF