Subversion Repositories DevTools

Rev

Rev 2269 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2263 kivins 1
//## begin module%1.7%.codegen_version preserve=yes
2
//   Read the documentation to learn more about C++ code generator
3
//   versioning.
4
//## end module%1.7%.codegen_version
5
 
6
//## begin module%420AC16002C1.cm preserve=no
7
//## end module%420AC16002C1.cm
8
 
9
//## begin module%420AC16002C1.cp preserve=no
10
//	C O P Y R I G H T   N O T I C E
11
//	This material is confidential to ERG and may not be disclosed in whole
12
//	or in part to any third party nor used in any manner whatsoever other
13
//	than for the purposes expressly consented to by ERG in writing.
14
//
15
//	This material is also copyright and may not be reproduced, stored in a
16
//	retrieval system or transmitted in any form or by any means in whole or
17
//	in part without the express written consent of ERG.
18
//## end module%420AC16002C1.cp
19
 
20
//## Module: FieldExpression%420AC16002C1; Pseudo Package body
21
//## Subsystem: MASS::Dev::Tools::TxnTestManager::src%41F5A79001E4
22
//## Source file: Z:\MASS_Dev\Tools\TxnTestManager\src\FieldExpression.cpp
23
 
24
//## begin module%420AC16002C1.additionalIncludes preserve=no
25
//## end module%420AC16002C1.additionalIncludes
26
 
27
//## begin module%420AC16002C1.includes preserve=yes
28
#pragma warn -com
29
#include <LoggingMacros.h>
30
#pragma warn +com
31
 
32
#include <vcl.h>
33
#pragma hdrstop
34
//## end module%420AC16002C1.includes
35
 
36
// ICryptographicServerProxy
37
#include "ICryptographicServerProxy.h"
38
// IMessageDigest
39
#include "IMessageDigest.h"
40
// IXmlSchemaWrapperElement
41
#include "IXmlSchemaWrapperElement.h"
42
// TransactionSpecification
43
#include "TransactionSpecification.h"
44
// EvaluationContext
45
#include "EvaluationContext.h"
46
// SequenceCollection
47
#include "SequenceCollection.h"
48
// Sequence
49
#include "Sequence.h"
50
// FieldExpression
51
#include "FieldExpression.h"
52
// DefinedVariable
53
#include "DefinedVariable.h"
54
// DefinedVariableTable
55
#include "DefinedVariableTable.h"
56
//## begin module%420AC16002C1.additionalDeclarations preserve=yes
57
#include <time>
58
#include <locale>
59
#include <sstream>
60
 
61
enum TokenId
62
{
63
	TOKENID_INVALID = 0,
64
	TOKENID_FUNCTION,
65
	TOKENID_VARIABLE,
66
	TOKENID_CONSTANT
67
};
68
enum FunctionId
69
{
70
	EXPRESSIONID_INVALID = 0,
71
	EXPRESSIONID_FORMATVERSION,
72
	EXPRESSIONID_NOW,
73
	EXPRESSIONID_UTCNOW,
74
	EXPRESSIONID_TODAY,
75
	EXPRESSIONID_YESTERDAY,
76
	EXPRESSIONID_TOMORROW,
77
	EXPRESSIONID_RAND,
78
	EXPRESSIONID_UDTYPE,
79
	EXPRESSIONID_UDSUBTYPE,
80
	EXPRESSIONID_ACCOUNTTYPE,
81
	EXPRESSIONID_SEQ,
82
	EXPRESSIONID_KEYVERSION,
83
	EXPRESSIONID_KEYNUMBER,
84
	EXPRESSIONID_MAC,
85
	EXPRESSIONID_SAMID,
86
	EXPRESSIONID_SCENARIO_INDEX,
87
	EXPRESSIONID_HOSTNAME,
2267 kivins 88
	EXPRESSIONID_USERNAME,
89
	EXPRESSIONID_USESEQ,
90
    EXPRESSIONID_SETSHIFTSTART,   
91
    EXPRESSIONID_USESHIFTSTART,
92
    };
2263 kivins 93
struct PredefinedFunction
94
{
95
	const char *	functor;
96
	FunctionId		functionId;
97
};
98
 
99
static const PredefinedFunction functions[] =
100
{
101
	{ "FORMATVERSION",	EXPRESSIONID_FORMATVERSION },
102
	{ "NOW",			EXPRESSIONID_NOW },
103
	{ "UTCNOW",			EXPRESSIONID_UTCNOW },
104
	{ "TODAY",			EXPRESSIONID_TODAY },
105
	{ "YESTERDAY",		EXPRESSIONID_YESTERDAY },
106
	{ "TOMORROW",		EXPRESSIONID_TOMORROW },
107
	{ "RAND",			EXPRESSIONID_RAND },
108
	{ "UDTYPE",			EXPRESSIONID_UDTYPE },
109
	{ "UDSUBTYPE",		EXPRESSIONID_UDSUBTYPE },
110
	{ "ACCOUNTTYPE",	EXPRESSIONID_ACCOUNTTYPE },
111
	{ "SEQ",			EXPRESSIONID_SEQ },
112
	{ "KEYVERSION",		EXPRESSIONID_KEYVERSION },
113
	{ "KEYNUMBER",		EXPRESSIONID_KEYNUMBER },
114
	{ "MAC",			EXPRESSIONID_MAC },
115
	{ "SAMID",			EXPRESSIONID_SAMID },
116
	{ "SCENARIOINDEX",	EXPRESSIONID_SCENARIO_INDEX },
117
	{ "HOSTNAME",		EXPRESSIONID_HOSTNAME },
118
	{ "USERNAME",		EXPRESSIONID_USERNAME },
2267 kivins 119
	{ "USESEQ",			EXPRESSIONID_USESEQ },
120
	{ "SETSHIFTSTART",	EXPRESSIONID_SETSHIFTSTART },
121
	{ "USESHIFTSTART",	EXPRESSIONID_USESHIFTSTART },
2263 kivins 122
	{ 0,				EXPRESSIONID_INVALID }
123
};
124
 
125
static const std::locale myLocale;
126
 
127
const FunctionId & getFunctionId( const std::string & string )
128
{
129
	PredefinedFunction const * where = 0;
130
 
131
	for ( where = functions; where->functor; ++where )
132
	{
133
		if ( string == where->functor )
134
		{
135
			break;
136
		}
137
	}
138
 
139
	return ( where->functionId );
140
}
141
 
142
const bool readExpression( std::istream & stream, std::string & symbol, TokenId & token, EvaluationContext& evaluationContext )
143
{
144
	symbol.erase();
145
 
146
	char character = 0;
147
	while ( stream.get( character ).good() )
148
	{
149
		if ( std::isalnum( character ) || character == '_' )
150
		{
151
			symbol += character;
152
		}
153
		else
154
		{
155
			stream.putback( character );	// Always put this back.
156
 
157
			if ( character == '(' )
158
			{
159
				token = TOKENID_FUNCTION;
160
				return ( true );
161
			}
162
 
163
			break;	// We have read in a lexeme, now tokenise it.
164
		}
165
	}
166
 
167
	// Only do this when we didn't fail reading from the stream.
168
	if ( stream.good() || stream.eof() )
169
	{
170
		token = ( evaluationContext.getSymbolTable().isVariable( symbol, evaluationContext )
171
			? TOKENID_VARIABLE
172
			: TOKENID_CONSTANT );
173
		return ( true );
174
	}
175
 
176
	return ( false );
177
}
178
//## end module%420AC16002C1.additionalDeclarations
179
 
180
 
181
// Class FieldExpression 
182
 
183
FieldExpression::FieldExpression()
184
  //## begin FieldExpression::FieldExpression%420AC16002C1_const.initialization preserve=yes
185
  //## end FieldExpression::FieldExpression%420AC16002C1_const.initialization
186
{
187
  //## begin FieldExpression::FieldExpression%420AC16002C1_const.body preserve=yes
188
  //## end FieldExpression::FieldExpression%420AC16002C1_const.body
189
}
190
 
191
//## Operation: FieldExpression%42105AAC0084
192
FieldExpression::FieldExpression (const std::string &expression)
193
  //## begin FieldExpression::FieldExpression%42105AAC0084.hasinit preserve=no
194
  //## end FieldExpression::FieldExpression%42105AAC0084.hasinit
195
  //## begin FieldExpression::FieldExpression%42105AAC0084.initialization preserve=yes
196
 
197
:	m_expression( expression )
198
 
199
  //## end FieldExpression::FieldExpression%42105AAC0084.initialization
200
{
201
  //## begin FieldExpression::FieldExpression%42105AAC0084.body preserve=yes
202
  //## end FieldExpression::FieldExpression%42105AAC0084.body
203
}
204
 
205
 
206
FieldExpression::~FieldExpression()
207
{
208
  //## begin FieldExpression::~FieldExpression%420AC16002C1_dest.body preserve=yes
209
  //## end FieldExpression::~FieldExpression%420AC16002C1_dest.body
210
}
211
 
212
 
213
 
214
//## Other Operations (implementation)
215
//## Operation: evaluate%420456630303
216
const bool FieldExpression::evaluate (std::string &value, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
217
{
218
  //## begin FieldExpression::evaluate%420456630303.body preserve=yes
219
 
220
	if ( m_cachedValue.length() )
221
	{
222
		value = m_cachedValue;
223
		return ( true );
224
	}
225
 
226
	/**
227
	 *	TODO: Eventually replace the use of streams with a char buffer, but
228
	 *	right now I just need to get it working.
229
	 */
230
	if ( ( m_expression[ 0 ] == '\"' ) &&
231
		 ( m_expression[ m_expression.length() - 1 ] == '\"' ) )
232
	{
233
		value = m_cachedValue = m_expression.substr( 1, m_expression.length() - 2 );
234
		return ( true );
235
	}
236
 
237
	std::istringstream is( m_expression );
238
	skipCharacter( is, '=' );	// Skip the '=' if its there.
239
 
240
	/**
241
	 *	TODO: evaluate this field using the defined collection of variables
242
	 *	and sequence generators, making sure we respect the sideEffect flag.
243
	 */
244
	/**
245
		For now, we assume a very simple syntax:
246
 
247
			expression		::= function | variable | constant
248
			function		::= =functor ( [ argument list ] )
249
			variable		::= =variable
250
			constant		::= alphanumeric
251
			argument list	::= argument[, argument list ]
252
			argument		::= expression
253
	 */
254
	std::string	symbol;
255
	TokenId		token = TOKENID_INVALID;
256
	while ( readExpression( is, symbol, token, evaluationContext ) )
257
	{
258
		switch ( token )
259
		{
260
		case TOKENID_FUNCTION:
261
			return ( evaluateFunction( is, value, symbol, sideEffect, evaluationContext, path, postponed ) );
262
		case TOKENID_VARIABLE:
263
			return ( evaluateVariable( is, value, symbol, sideEffect, evaluationContext, path, postponed ) );
264
		case TOKENID_CONSTANT:
265
			// Its not a defined variable or function, so just evaluate to
266
			// it.
267
			m_cachedValue = value = m_expression;
268
			return ( true );
269
		}
270
	}
271
 
272
	return ( true );
273
 
274
  //## end FieldExpression::evaluate%420456630303.body
275
}
276
 
277
//## Operation: evaluateFunction%4208AE9D0216
278
const bool FieldExpression::evaluateFunction (std::istream &is, std::string &value, std::string &symbol, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
279
{
280
  //## begin FieldExpression::evaluateFunction%4208AE9D0216.body preserve=yes
281
 
282
	/**
283
	 *	Check parameter lists on all functions calls, and report an error
284
	 *	when a function is called with superfluous arguments.
285
	 */
286
 
287
	postponed = false;
288
	switch ( getFunctionId( symbol ) )
289
	{
290
	case EXPRESSIONID_UDTYPE:
291
		{
292
			AnsiString os;
293
			os.sprintf( "%hu", evaluationContext.getTransaction().getUdType() );
294
			m_cachedValue = value = os.c_str();
295
		}
296
		return ( true );
297
	case EXPRESSIONID_UDSUBTYPE:
298
		{
299
			AnsiString os;
300
			os.sprintf( "%hu", evaluationContext.getTransaction().getUdSubtype() );
301
			m_cachedValue = value = os.c_str();
302
		}
303
		return ( true );
304
	case EXPRESSIONID_TODAY:
305
		m_cachedValue = value = TDateTime::CurrentDateTime().FormatString( "dd-mm-yyyy" ).c_str();
306
		return ( true );
307
	case EXPRESSIONID_FORMATVERSION:
308
		{
309
			AnsiString os;
310
			os.sprintf( "%d", evaluationContext.getTransaction().getFormatVersion() );
311
			m_cachedValue = value = os.c_str();
312
		}
313
		return ( true );
314
	case EXPRESSIONID_NOW:
2273 kivins 315
		value = TDateTime::CurrentDateTime().FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str();
2263 kivins 316
		return ( true );
317
	case EXPRESSIONID_UTCNOW:
318
		{
319
			const TDateTime time = TDateTime::CurrentDateTime() + ( ( _timezone / 3600.0 ) / 24.0 );
320
 
2273 kivins 321
			value = time.FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str();
2263 kivins 322
		}
323
		return ( true );
324
	case EXPRESSIONID_YESTERDAY:
325
		{
326
			const TDateTime time = TDateTime::CurrentDateTime() - 1;
327
 
328
			m_cachedValue = value = time.FormatString( "dd-mm-yyyy" ).c_str();
329
		}
330
		return ( true );
331
	case EXPRESSIONID_TOMORROW:
2267 kivins 332
		{      
333
        	std::string days;
334
            int advanceDays;
335
			if ( skipCharacter( is, '(' ) &&
336
				 readTerm( is, days ) &&
337
				 skipCharacter( is, ')' ) )
338
			{
339
				advanceDays	= 	atoi( days.c_str() );
340
                if (advanceDays == 0) advanceDays = 1; //for invalid format default to tomorrow
341
            }
342
            else
343
            {
344
                advanceDays = 1;
345
            }							
346
 
347
			const TDateTime time = TDateTime::CurrentDateTime() + advanceDays;
2263 kivins 348
 
349
			m_cachedValue = value = time.FormatString( "dd-mm-yyyy" ).c_str();
350
		}
2267 kivins 351
		return ( true );        
352
    case EXPRESSIONID_SETSHIFTSTART:
353
		{                                         
354
            const TDateTime time = TDateTime::CurrentDateTime() + ( ( _timezone / 3600.0 ) / 24.0 );
355
 
356
			value = ( time.FormatString( "dd-mm-yyyy hh:nn:ss" ).c_str());
357
 
358
            evaluationContext.setStartTime (value);
359
		}
360
		return ( true );    
361
    case EXPRESSIONID_USESHIFTSTART:
362
		{                  
363
            value = evaluationContext.getStartTime();
364
		}
2263 kivins 365
		return ( true );
366
	case EXPRESSIONID_ACCOUNTTYPE:
367
		switch( evaluationContext.getTransaction().getUdType() )
368
		{
369
		case 1:	// Card
370
			value = "2";
371
			break;
372
		case 2:	// Application
373
			value = "1";
374
			break;
375
		case 3:	// Product
376
			value = "3";
377
			break;
378
		case 4:	// Other
379
			value = "4";
380
			break;
381
		case 5:	// Audit
382
			value = "4";
383
			break;
384
		case 6:	// Event
385
			value = "4";
386
			break;
387
		case 7:	// Project
388
			value = "4";
389
			break;
390
		default:
391
			value.erase();
392
			break;
393
		}
394
		m_cachedValue = value;
395
		return ( true );
396
	case EXPRESSIONID_RAND:
397
		{
398
			std::string lowerBound;
399
			std::string upperBound;
400
			if ( skipCharacter( is, '(' ) &&
401
				 readTerm( is, lowerBound ) &&
402
				 skipCharacter( is, ',' ) &&
403
				 readTerm( is, upperBound ) &&
404
				 skipCharacter( is, ')' ) )
405
			{
406
				const int first	= std::min< int >(
407
									atoi( lowerBound.c_str() ),
408
									atoi( upperBound.c_str() ) );
409
				const int last	= std::max< int >(
410
									atoi( lowerBound.c_str() ),
411
									atoi( upperBound.c_str() ) );
412
 
413
				AnsiString os;
414
				os.sprintf( "%d",
415
					int( ( rand() / double( RAND_MAX ) ) *
416
						 ( last - first + 1 ) + first ) );
417
				value = os.c_str();
418
				return ( true );
419
			}
420
			else
421
			{
422
				MERROR( "Cannot parse argument list." );
423
			}
424
		}
425
		break;
426
	case EXPRESSIONID_SEQ:
427
		{
428
			bool persisted = false;
429
			std::string name;
430
			std::string first;
431
			std::string increment;
432
			std::string last;
433
			std::string discriminant;
434
			std::string	fullName;
435
 
436
			/**
437
			 *	SEQ( name, first, increment, last[, discriminant] )
438
			 *	name ::= transient name | # persisted name
439
			 */
440
			if ( skipCharacter( is, '(' ) )
441
			{
442
				persisted = skipCharacter( is, '#' );
443
 
444
				if ( readIdentifier( is, name ) &&
445
					 skipCharacter( is, ',' ) &&
446
					 readTerm( is, first ) &&
447
					 skipCharacter( is, ',' ) &&
448
					 readTerm( is, last ) &&
449
					 skipCharacter( is, ',' ) &&
450
					 readTerm( is, increment ) &&
451
					 ( ( skipCharacter( is, ',' ) &&
452
						 readIdentifier( is, discriminant ) ) ||
453
					   skipCharacter( is, ')' ) ) )
454
				{
455
					if ( discriminant.length() )
456
					{
457
						/**
458
						 *	We have a discriminant, so we evaluate it to form
459
						 *	our name,
2269 kivins 460
                                                         *     With a special cases for auto udsn, ssn, trip and psn
2263 kivins 461
						 */
2269 kivins 462
 
463
                        if (name == "UDSN")
464
                        {
465
                            fullName = "UDSN["+evaluationContext.getDeviceId()+"]";
466
                        }
467
                        else if (name == "AUTOSSN")
468
                        {
469
                            fullName = "AUTOSSN["+evaluationContext.getDeviceId()+"]";
470
                        }
471
                        else if (name == "AUTOTRIP")
472
                        {
473
                            fullName = "AUTOTRIP["+evaluationContext.getDeviceId()+"]";
474
                        }                         
475
                        else if (name == "AUTOPSN")
476
                        {
477
                            fullName = "AUTOPSN["+evaluationContext.getCsn()+"]";
478
                        } 
479
                        else  
480
                        {
481
						   FieldExpression subexpression( discriminant );
2263 kivins 482
 
2269 kivins 483
						   std::string discriminantValue;
484
						   if ( subexpression.evaluate( discriminantValue, true, evaluationContext, path, postponed ) )
485
						   {
486
						       AnsiString full;
487
							   full.sprintf( "%s[%s]", name.c_str(), discriminantValue.c_str() );
488
							   fullName = full.c_str();
489
						   }
490
                        }
2263 kivins 491
					}
492
					else
493
					{
494
						fullName = name;
495
					}
496
 
497
					Sequence & sequence = evaluationContext.
498
						getSequenceCollection().getSequence(
499
							fullName,
500
							persisted,
501
							atoi( first.c_str() ) );
2267 kivins 502
 
503
                    // don't increment on very first use of a new sequence  
2269 kivins 504
                    if(sequence.isDirty() || sequence.isUpdate())
2267 kivins 505
                    {                    
506
    					sequence.incrementValue(
507
    						atoi( first.c_str() ),
508
    						atoi( last.c_str() ),
509
    						atoi( increment.c_str() ) );
510
                    }    
2263 kivins 511
					AnsiString os;
512
					os.sprintf( "%d", sequence.getValue() );
513
					value = os.c_str();
2267 kivins 514
 
515
                    sequence.setDirty (true); //used to force an increment next time round as well as db refresh    
2263 kivins 516
 
2267 kivins 517
					return ( true );
518
				}
519
			}
2263 kivins 520
 
2267 kivins 521
			MERROR( "Cannot parse argument list." );
522
		}
523
		break;
524
	case EXPRESSIONID_USESEQ:
525
		{
526
			bool persisted = false;
527
			std::string name;
528
			std::string discriminant;
529
			std::string	fullName;
530
 
531
			/**
532
			 *	SEQ( name, first, increment, last[, discriminant] )
533
			 *	name ::= transient name | # persisted name
534
			 */
535
			if ( skipCharacter( is, '(' ) )
536
			{
537
				persisted = skipCharacter( is, '#' );
538
				if ( readIdentifier( is, name ) &&
539
					 ( ( skipCharacter( is, ',' ) &&
540
						 readIdentifier( is, discriminant ) ) ||
541
					   skipCharacter( is, ')' ) ) )
542
				{
543
					if ( discriminant.length() )
544
					{
545
						/**
546
						 *	We have a discriminant, so we evaluate it to form
547
						 *	our name,
548
						 */
2273 kivins 549
                        if (name == "AUTOSSN")
2269 kivins 550
                        {
2273 kivins 551
                            fullName = "AUTOSSN["+evaluationContext.getDeviceId()+"]";
2269 kivins 552
                        }
2273 kivins 553
                        else if (name == "AUTOTRIP")
2269 kivins 554
                        {
2273 kivins 555
                            fullName = "AUTOTRIP["+evaluationContext.getDeviceId()+"]";
2269 kivins 556
                        } 
557
                        else if (name == "AUTOPSN")
558
                        {
559
                            fullName = "AUTOPSN["+evaluationContext.getCsn()+"]";
560
                        }                         
561
                        else  
562
                        {
563
						   FieldExpression subexpression( discriminant );
2267 kivins 564
 
2269 kivins 565
						   std::string discriminantValue;
566
						   if ( subexpression.evaluate( discriminantValue, true, evaluationContext, path, postponed ) )
567
						   {
568
						       AnsiString full;
569
							   full.sprintf( "%s[%s]", name.c_str(), discriminantValue.c_str() );
570
							   fullName = full.c_str();
571
						   }
572
                        }                         
2267 kivins 573
					}
574
					else
575
					{
576
						fullName = name;
577
					}
578
 
579
					Sequence & sequence = evaluationContext.
580
						getSequenceCollection().getSequence(
581
							fullName,
582
							true,      // really don't care
583
							1 );       // default if seq not already created
584
					AnsiString os;
585
					os.sprintf( "%d", sequence.getValue() );
586
					value = os.c_str();
587
 
588
                    // note: there is intentionally no increment
589
 
2263 kivins 590
					return ( true );
591
				}
592
			}
593
 
594
			MERROR( "Cannot parse argument list." );
595
		}
2267 kivins 596
		break;        
2263 kivins 597
	case EXPRESSIONID_KEYVERSION:
598
		if ( evaluationContext.haveMessageDigest() )
599
		{
600
			AnsiString os;
601
			os.sprintf( "%hu", evaluationContext.getMessageDigest().getKeyVersion() );
602
			value = os.c_str();
603
 
604
			return ( true );
605
		}
606
		break;
607
	case EXPRESSIONID_KEYNUMBER:
608
		if ( evaluationContext.haveMessageDigest() )
609
		{
610
			AnsiString os;
611
			os.sprintf( "%hu", evaluationContext.getMessageDigest().getKeyNumber() );
612
			value = os.c_str();
613
 
614
			return ( true );
615
		}
616
		break;
617
	case EXPRESSIONID_MAC:
618
		/**
619
		 *	We add the schema element to the collection of schema elements to
620
		 *	which we must assign the MAC.  Because we can compute the MAC only
621
		 *	when all fields have been evaluated, this must be postponed, and
622
		 *	until then we must report success.
623
		 */
624
		if ( evaluationContext.haveSchemaElement() )
625
		{
626
			evaluationContext.getTransaction().addMacField(
627
				evaluationContext.getSchemaElement().clone() );
628
			postponed = true;
629
 
630
			return ( true );
631
		}
632
		break;
633
	case EXPRESSIONID_SAMID:
634
		if ( evaluationContext.haveCryptographicServer() )
635
		{
636
			/**
637
			 *	We don't know which module will be used to compute the
638
			 *	MAC (security doesn't tell us), so until they do we
639
			 *	assume its the first module.
640
			 */
641
			/*
642
      if ( evaluationContext.getCryptographicServer().getModuleCount() )
643
			{
644
				AnsiString os;
645
				os.sprintf( "%hu", evaluationContext.getCryptographicServer().getSamId( 0 ) );
646
				value = os.c_str();
647
				return ( true );
648
			}
649
			*/
650
			value = 1;
651
			return ( true );
652
		}
653
		break;
654
	case EXPRESSIONID_SCENARIO_INDEX:
655
		{
656
			AnsiString os;
657
			os.sprintf( "%u", evaluationContext.getScenarioIndex() );
658
			value = os.c_str();
659
		}
660
		return ( true );
661
	case EXPRESSIONID_HOSTNAME:
662
		{
663
			char name[ 1024 ];
664
			unsigned long size = sizeof( name );
665
			if ( GetComputerName( name, &size ) )
666
			{
667
				value = name;
668
				return ( true );
669
			}
670
		}
671
	case EXPRESSIONID_USERNAME:
672
		{
673
			char name[ 1024 ];
674
			unsigned long size = sizeof( name );
675
			if ( GetUserName( name, &size ) )
676
			{
677
				value = name;
678
				return ( true );
679
			}
680
		}
681
	default:
682
		MERROR( "Function \"" << symbol << "\" is not implemented." );
683
		break;
684
	}
685
 
686
	return ( false );
687
 
688
  //## end FieldExpression::evaluateFunction%4208AE9D0216.body
689
}
690
 
691
//## Operation: evaluateVariable%420AE22101D7
692
const bool FieldExpression::evaluateVariable (std::istream &is, std::string &value, std::string &symbol, const bool &sideEffect, EvaluationContext& evaluationContext, std::vector< DefinedVariable * > &path, bool &postponed)
693
{
694
  //## begin FieldExpression::evaluateVariable%420AE22101D7.body preserve=yes
695
 
696
	return ( evaluationContext.getSymbolTable().getVariable( symbol, evaluationContext ).
697
				evaluate( value, sideEffect, evaluationContext, path, postponed ) );
698
 
699
  //## end FieldExpression::evaluateVariable%420AE22101D7.body
700
}
701
 
702
//## Operation: getExpression%420AC68F02E4
703
const std::string & FieldExpression::getExpression () const
704
{
705
  //## begin FieldExpression::getExpression%420AC68F02E4.body preserve=yes
706
 
707
	return ( m_expression );
708
 
709
  //## end FieldExpression::getExpression%420AC68F02E4.body
710
}
711
 
712
//## Operation: isFunctor%4209B773036F
713
const bool FieldExpression::isFunctor (const std::string &string)
714
{
715
  //## begin FieldExpression::isFunctor%4209B773036F.body preserve=yes
716
 
717
	PredefinedFunction const * where = 0;
718
 
719
	for ( where = functions; where->functor; ++where )
720
	{
721
		if ( string == where->functor )
722
		{
723
			return ( true );
724
		}
725
	}
726
 
727
	return ( false );
728
 
729
  //## end FieldExpression::isFunctor%4209B773036F.body
730
}
731
 
732
//## Operation: readIdentifier%42102FB70219
733
const bool FieldExpression::readIdentifier (std::istream &is, std::string &identifier)
734
{
735
  //## begin FieldExpression::readIdentifier%42102FB70219.body preserve=yes
736
 
737
	char character = 0;
738
 
739
	identifier.clear();
740
 
741
	is >> std::ws;
742
	if ( is.get( character ).good() )
743
	{
744
		if ( std::isalpha( character ) )
745
		{
746
			do
747
			{
748
				identifier += character;
749
			}
750
			while ( is.get( character ).good() &&
751
					( std::isalnum( character ) || ( character == '_' ) ) );
752
		}
753
 
754
		if ( is.good() )
755
		{
756
			is.putback( character );
757
		}
758
	}
759
 
760
	return ( identifier.length() > 0 );
761
 
762
  //## end FieldExpression::readIdentifier%42102FB70219.body
763
}
764
 
765
//## Operation: readTerm%420B0EB603D2
766
const bool FieldExpression::readTerm (std::istream &is, std::string &term)
767
{
768
  //## begin FieldExpression::readTerm%420B0EB603D2.body preserve=yes
769
 
770
	char character = 0;
771
 
772
	term.clear();
773
 
774
	is >> std::ws;
775
	if ( is.get( character ).good() )
776
	{
777
		const bool quoted = ( character == '\"' );
778
		if ( std::isalnum( character ) || ( character == '-' ) || quoted )
779
		{
780
			do
781
			{
782
				term += character;
783
			}
784
			while ( is.get( character ).good() && std::isalnum( character ) );
785
		}
786
 
787
		if ( is.good() && ( !quoted || character != '\"' ) )
788
		{
789
			is.putback( character );
790
		}
791
	}
792
 
793
	return ( term.length() > 0 );
794
 
795
  //## end FieldExpression::readTerm%420B0EB603D2.body
796
}
797
 
798
//## Operation: setExpression%420AC68F02F3
799
const std::string & FieldExpression::setExpression (const std::string &value)
800
{
801
  //## begin FieldExpression::setExpression%420AC68F02F3.body preserve=yes
802
 
803
	return ( m_expression = value );
804
 
805
  //## end FieldExpression::setExpression%420AC68F02F3.body
806
}
807
 
808
//## Operation: skipCharacter%420B100701E7
809
const bool FieldExpression::skipCharacter (std::istream &is, const char &character)
810
{
811
  //## begin FieldExpression::skipCharacter%420B100701E7.body preserve=yes
812
 
813
	char c = 0;
814
	is >> std::ws >> c;
815
 
816
	if ( is.good() )
817
	{
818
		if ( c == character )
819
		{
820
			return ( true );
821
		}
822
 
823
		is.putback( c );
824
	}
825
 
826
	return ( false );
827
 
828
  //## end FieldExpression::skipCharacter%420B100701E7.body
829
}
830
 
831
// Additional Declarations
832
  //## begin FieldExpression%420AC16002C1.declarations preserve=yes
833
  //## end FieldExpression%420AC16002C1.declarations
834
 
835
//## begin module%420AC16002C1.epilog preserve=yes
836
//## end module%420AC16002C1.epilog