1 //**************************************************************************************************
2 // Component.cpp *
3 // --------------- *
4 // Started : 2004-05-14 *
5 // Last Update : 2015-04-06 *
6 // Copyright : (C) 2004 by MSWaters *
7 //**************************************************************************************************
8
9 //**************************************************************************************************
10 // *
11 // This program is free software; you can redistribute it and/or modify it under the *
12 // terms of the GNU General Public License as published by the Free Software Foundation; *
13 // either version 3 of the License, or (at your option) any later version. *
14 // *
15 //**************************************************************************************************
16
17 #include "Component.hpp"
18
19 //**************************************************************************************************
20 // Finish the definition of the ArrayComponent type. The following expands into
21 // some C++ code and so should only be compiled once (ie. don't put this into a
22 // header file rather put it in a source file or there will be linker errors).
23
24 #include <wx/arrimpl.cpp>
25 WX_DEFINE_OBJARRAY( ArrayComponent );
26
27 //**************************************************************************************************
28 // Constructor.
29
Component(void)30 Component::Component( void ) : wxString( )
31 {
32 bClear( );
33 }
34
35 //**************************************************************************************************
36 // Destructor.
37
~Component()38 Component::~Component( )
39 {
40 }
41
42 //**************************************************************************************************
43 // Get the component ports.
44
GetPorts(void)45 void Component::GetPorts( void )
46 {
47 // Not yet implemented ???
48 }
49
50 //**************************************************************************************************
51 // Test the values against each other.
52 //
53 // Return Values :
54 // true - Success
55 // false - Failure
56
bValidate(void)57 bool Component::bValidate( void )
58 {
59 m_osErrMsg.Empty( );
60
61 if( IsEmpty( ) ) bSetErrMsg( wxT("component is empty") );
62 else if( m_osName.IsEmpty( ) ) bSetErrMsg( wxT("component has no name") );
63 else if( m_osaNodes.GetCount( ) < 2 ) bSetErrMsg( wxT("component has less than two nodes") );
64 else if( m_osValue.IsEmpty( ) ) bSetErrMsg( wxT("component has no value") );
65
66 return( bIsValid( ) );
67 }
68
69 //**************************************************************************************************
70 // Attempt to set the objects error message string attribute.
71 //
72 // Argument List :
73 // rosErrMsg - A reference to a string containing the new error message
74 //
75 // Return Values :
76 // true - Success
77 // false - Failure
78
bSetErrMsg(const wxString & rosErrMsg)79 bool Component::bSetErrMsg( const wxString & rosErrMsg )
80 {
81 if( ! bIsValid( ) ) return( false );
82
83 m_osErrMsg = rosErrMsg;
84
85 return( true );
86 }
87
88 //**************************************************************************************************
89 // Compare algorithm for sorting Component objects.
90 //
91 // Argument List :
92 // ppo1 - The address of a pointer to the first Component object to compare
93 // ppo2 - The address of a pointer to the second Component object to compare
94 //
95 // Return Values :
96 // >0 - If *(*ppo1) is greater than *(*ppo2)
97 // =0 - If *(*ppo1) is equal to *(*ppo2)
98 // <0 - If *(*ppo1) is less than *(*ppo2)
99
iCompare(Component ** ppo1,Component ** ppo2)100 int Component::iCompare( Component ** ppo1, Component ** ppo2 )
101 {
102 const wxString & ros1 = (const wxString &) **ppo1;
103 const wxString & ros2 = (const wxString &) **ppo2;
104
105 return( ros1.Cmp( ros2 ) );
106 }
107
108 //**************************************************************************************************
109 // Clear the object attributes.
110 //
111 // Return Values :
112 // true - Success
113 // false - Failure
114
bClear(void)115 bool Component::bClear( void )
116 {
117 wxString::Empty( );
118
119 m_osErrMsg = wxT("Invalid");
120
121 m_osName .Clear( );
122 m_osaNodes.Clear( );
123 m_osValue .Clear( );
124
125 m_eType = eCPNT_NONE;
126 m_osaPorts.Clear( );
127
128 return( true );
129 }
130
131 //**************************************************************************************************
132 // Parse a component definition string extracted from a netlist.
133 //
134 // Return Values :
135 // true - Success
136 // false - Failure
137
bParse(void)138 bool Component::bParse( void )
139 {
140 wxStringTokenizer ostk1;
141 wxString os1;
142 size_t szt1;
143
144 // Clear the object attributes
145 os1 = (wxString &) *this;
146 bClear( );
147 wxString::assign( os1 );
148 m_osErrMsg.Empty( );
149
150 // Tokenize the command string
151 if( IsEmpty( ) ) return( bValidate( ) );
152 ostk1.SetString( os1 );
153
154 // Extract the component name
155 bSetName( ostk1.GetNextToken( ) );
156
157 // Extract the nodes the component is connected to
158 if( ! ostk1.HasMoreTokens( ) ) return( bValidate( ) );
159 bSetNodes( ostk1.GetString( ) );
160 for( szt1=0; szt1<m_osaNodes.GetCount( ); szt1++ )
161 ostk1.GetNextToken( );
162
163 // Extract the component value
164 if( ! ostk1.HasMoreTokens( ) ) return( bValidate( ) );
165 bSetValue( ostk1.GetString( ) );
166
167 return( bValidate( ) );
168 }
169
170 //**************************************************************************************************
171 // Format the command string.
172 //
173 // Eg. : C1 6 2 100n
174 //
175 // Return Values :
176 // true - Success
177 // false - Failure
178
bFormat(void)179 bool Component::bFormat( void )
180 {
181 wxString osCmd;
182 size_t sz1;
183
184 // Format the value part of the component definition
185 bFormatValue( );
186
187 // Set the name
188 osCmd = m_osName;
189
190 // Append the nodes
191 for( sz1=0; sz1<m_osaNodes.GetCount( ); sz1++ )
192 osCmd << wxT(' ') << m_osaNodes.Item( sz1 );
193
194 // Append the value
195 osCmd << wxT(' ') << m_osValue;
196
197 wxString::assign( osCmd );
198
199 return( bValidate( ) );
200 }
201
202 //**************************************************************************************************
203 // Set the object attributes via a component definition string.
204 //
205 // Argument List :
206 // rosCmd - A reference to a string containing a component definition
207 //
208 // Return Values :
209 // true - Success
210 // false - Failure
211
bSetString(const wxString & rosCmd)212 bool Component::bSetString( const wxString & rosCmd )
213 {
214 // Clear the component attributes
215 bClear( );
216
217 // Set the underlying string to the raw component definition
218 wxString::assign( rosTrim( rosCmd ) );
219
220 // Parse the component definition
221 bParse( );
222
223 return( bIsValid( ) );
224 }
225
226 //**************************************************************************************************
227 // Set the component name.
228 //
229 // Argument List :
230 // rosName - A reference to a string containing a compoent name
231 //
232 // Return Values :
233 // true - Success
234 // false - Failure
235
bSetName(const wxString & rosName)236 bool Component::bSetName( const wxString & rosName )
237 {
238 wxStringTokenizer ostk1;
239 wxString os1;
240 wxChar oc1;
241
242 // Tokenize the name string
243 ostk1.SetString( rosName );
244 if( ostk1.CountTokens( ) <=0 ) return( false );
245
246 // Extract the component name and check that it begins with an alpha character
247 os1 = ostk1.GetNextToken( );
248 oc1 = os1.GetChar( 0 );
249 if( !(oc1>=wxT('a') && oc1<=wxT('z')) && !(oc1>=wxT('A') && oc1<=wxT('Z')) ) return( false );
250 m_osName = os1;
251
252 // Determine the component type and units type
253 m_eType = eGetType( m_osName );
254
255 return( true );
256 }
257
258 //**************************************************************************************************
259 // Set the component nodes.
260 //
261 // Argument List :
262 // rosNodes - A reference to a string containing component nodes eg. "2,1".
263 //
264 // Return Values :
265 // true - Success
266 // false - Failure
267
bSetNodes(const wxString & rosNodes)268 bool Component::bSetNodes( const wxString & rosNodes )
269 {
270 wxStringTokenizer ostk1;
271 size_t szNodeCnt;
272 size_t sz1;
273
274 // Tokenize the name string
275 ostk1.SetString( rosNodes, wxT(" \t\r\n,") );
276 if( ostk1.CountTokens( ) <=0 ) return( false );
277
278 // Determine how many nodes to look for based on the component type
279 switch( m_eType )
280 {
281 case eCPNT_CAP :
282 case eCPNT_RES :
283 case eCPNT_IND :
284 case eCPNT_CIND :
285 case eCPNT_DIODE :
286 case eCPNT_VCVS :
287 case eCPNT_CCCS :
288 case eCPNT_VCCS :
289 case eCPNT_CCVS :
290 case eCPNT_IVS :
291 case eCPNT_ICS :
292 case eCPNT_NLDS :
293 case eCPNT_NLDCS :
294 case eCPNT_NLDVS :
295 case eCPNT_STJ : szNodeCnt = 2; break;
296
297 case eCPNT_JFET :
298 case eCPNT_MOSFET :
299 case eCPNT_MESFET :
300 case eCPNT_BJT :
301 case eCPNT_VCSW :
302 case eCPNT_CCSW :
303 case eCPNT_URC : szNodeCnt = 3; break;
304
305 case eCPNT_TLINE :
306 case eCPNT_LTRA :
307 case eCPNT_TXL : szNodeCnt = 4; break;
308
309 case eCPNT_LOGIC : szNodeCnt = ostk1.CountTokens( ) - 2; break;
310
311 case eCPNT_CPL :
312 case eCPNT_SUBCKT : szNodeCnt = ostk1.CountTokens( ) - 1; break;
313
314 // For the default guess that all but the last token are nodes
315 default : szNodeCnt = ostk1.CountTokens( ) - 1; break;
316 }
317 if( szNodeCnt > ostk1.CountTokens( ) ) return( false );
318
319 // Extract the nodes the component is connected to
320 m_osaNodes.Empty( );
321 if( szNodeCnt > 0 )
322 {
323 for( sz1=0; sz1<szNodeCnt; sz1++ )
324 m_osaNodes.Add( ostk1.GetNextToken( ) );
325 }
326 else
327 {
328 for( sz1=0; sz1<ostk1.CountTokens( ); sz1++ )
329 {
330 if( isalpha( ostk1.GetString( ).GetChar( 0 ) ) ) break;
331 m_osaNodes.Add( ostk1.GetNextToken( ) );
332 }
333 }
334
335 // Determine the device ports
336 GetPorts( );
337
338 return( true );
339 }
340
341 //**************************************************************************************************
342 // Set the component value.
343 //
344 // Argument List :
345 // rosName - A reference to a string containing a compoent value
346 //
347 // Return Values :
348 // true - Success
349 // false - Failure
350
bSetValue(const wxString & rosValue)351 bool Component::bSetValue( const wxString & rosValue )
352 {
353 wxString os1;
354
355 // Check if the string is empty
356 os1 = rosTrim( rosValue );
357 if( os1.IsEmpty( ) ) return( false );
358
359 // Extract the component value
360 m_osValue = os1;
361
362 return( bParseValue( ) );
363 }
364
365 //**************************************************************************************************
366 // Get the component definition string.
367 //
368 // Return Values :
369 // A reference to the component definition string
370
rosGetString(void)371 const wxString & Component::rosGetString( void )
372 {
373 bFormat( );
374
375 return( (wxString &) *this );
376 }
377
378 //**************************************************************************************************
379 // Get the component nodes as a string separated by a comma.
380 //
381 // Return Values :
382 // A reference to the component nodes string
383
rosGetNodes(void)384 const wxString & Component::rosGetNodes( void )
385 {
386 static wxString osNodes;
387 size_t sz1;
388
389 osNodes.Empty( );
390
391 if( ! m_osaNodes.IsEmpty( ) )
392 {
393 for( sz1=0; sz1<m_osaNodes.GetCount( ); sz1++ )
394 {
395 if( ! osNodes.IsEmpty( ) ) osNodes << wxT(",");
396 osNodes << m_osaNodes.Item( sz1 );
397 }
398 }
399
400 return( osNodes );
401 }
402
403 //**************************************************************************************************
404 // Get the numeric value as a mantissa and exponent if possible.
405 //
406 // Return Values :
407 // A reference to the component nodes string
408
rosGetNumValue(void)409 const wxString & Component::rosGetNumValue( void )
410 {
411 static wxString osNumValue;
412 wxStringTokenizer ostk1;
413 wxString os1;
414
415 // Clear the local static variable
416 osNumValue.Empty( );
417
418 // Tokenize the value string
419 ostk1 = m_osValue;
420
421 // Attempt to parse a field in the value string as a numeric quantity
422 while( ostk1.HasMoreTokens( ) )
423 {
424 os1 = ostk1.GetNextToken( );
425
426 if( CnvtType::bIsInteger( os1 ) )
427 {
428 osNumValue = os1;
429 break;
430 }
431 else if( CnvtType::bIsFloat( os1 ) )
432 {
433 osNumValue = os1;
434 break;
435 }
436 }
437
438 return( osNumValue );
439 }
440
441 //**************************************************************************************************
442 // Get the component type.
443 //
444 // Argument List :
445 // rosName - A component name
446 //
447 // Return Values :
448 // An enumerate type indicating the type of the component
449
eGetType(const wxString & rosName)450 eTypeCpnt Component::eGetType( const wxString & rosName )
451 {
452 // Determine the component type from the first character of the name
453 switch( toupper( rosName.GetChar( 0 ) ) )
454 {
455 case wxT('B') : return( eCPNT_NLDS );
456 case wxT('C') : return( eCPNT_CAP );
457 case wxT('D') : return( eCPNT_DIODE );
458 case wxT('E') : return( eCPNT_VCVS );
459 case wxT('F') : return( eCPNT_CCCS );
460 case wxT('G') : return( eCPNT_VCCS );
461 case wxT('H') : return( eCPNT_CCVS );
462 case wxT('I') : return( eCPNT_ICS );
463 case wxT('J') : return( eCPNT_JFET );
464 case wxT('K') : return( eCPNT_CIND );
465 case wxT('L') : return( eCPNT_IND );
466 case wxT('M') : return( eCPNT_MOSFET );
467 case wxT('O') : return( eCPNT_LTRA );
468 case wxT('P') : return( eCPNT_CPL );
469 case wxT('Q') : return( eCPNT_BJT );
470 case wxT('R') : return( eCPNT_RES );
471 case wxT('S') : return( eCPNT_VCSW );
472 case wxT('T') : return( eCPNT_TLINE );
473 case wxT('U') : return( eCPNT_URC );
474 case wxT('V') : return( eCPNT_IVS );
475 case wxT('W') : return( eCPNT_CCSW );
476 case wxT('X') : return( eCPNT_SUBCKT );
477 case wxT('Y') : return( eCPNT_TXL );
478 case wxT('Z') : return( eCPNT_MESFET );
479
480 default : return( eCPNT_NONE );
481 }
482 }
483
484 //**************************************************************************************************
485 // Get the units type (where appropriate).
486 //
487 // Argument List :
488 // rosName - A component name
489 //
490 // Return Values :
491 // An enumerate type indicating the type of units associated with this component
492
eGetUnitsType(const wxString & rosName)493 eTypeUnits Component::eGetUnitsType( const wxString & rosName )
494 {
495 // Determine the units type from the first character of the name
496 switch( toupper( rosName.GetChar( 0 ) ) )
497 {
498 case wxT('B') : return( eUNITS_EXP );
499 case wxT('C') : return( eUNITS_CAP );
500 case wxT('D') : return( eUNITS_NONE );
501 case wxT('E') : return( eUNITS_EXP );
502 case wxT('F') : return( eUNITS_EXP );
503 case wxT('G') : return( eUNITS_EXP );
504 case wxT('H') : return( eUNITS_EXP );
505 case wxT('I') : return( eUNITS_CURR );
506 case wxT('J') : return( eUNITS_NONE );
507 case wxT('K') : return( eUNITS_IND );
508 case wxT('L') : return( eUNITS_IND );
509 case wxT('M') : return( eUNITS_NONE );
510 case wxT('Q') : return( eUNITS_NONE );
511 case wxT('R') : return( eUNITS_RES );
512 case wxT('S') : return( eUNITS_NONE );
513 case wxT('T') : return( eUNITS_NONE );
514 case wxT('U') : return( eUNITS_NONE );
515 case wxT('V') : return( eUNITS_VOLT );
516 case wxT('W') : return( eUNITS_NONE );
517 case wxT('X') : return( eUNITS_NONE );
518 case wxT('Y') : return( eUNITS_RES );
519
520 default : return( eUNITS_NONE );
521 }
522 }
523
524 //**************************************************************************************************
525 // Trim a component definition string by replacing all field separaters with a single space
526 // character and removing any line terminators.
527 //
528 // Argument List :
529 // rosDefn - A reference to a string containing a component definition
530 //
531 // Return Values :
532 // A reference to a string containing a trimmed copy of the component defn
533
rosTrim(const wxString & rosDefn)534 const wxString & Component::rosTrim( const wxString & rosDefn )
535 {
536 static wxString osDefn;
537 wxStringTokenizer ostk1;
538
539 // Tokenize the component definition
540 ostk1.SetString( rosDefn, wxT(" \t\r\n"), wxTOKEN_STRTOK );
541
542 // Reconstruct the component definition
543 osDefn = ostk1.GetNextToken( );
544 while( ostk1.HasMoreTokens( ) )
545 osDefn << wxT(' ') << ostk1.GetNextToken( );
546
547 return( osDefn );
548 }
549
550 //**************************************************************************************************
551 // Copy the contents of a wxString object.
552 //
553 // Argument List :
554 // rosCmd - A reference to a string containing a component definition
555 //
556 // Return Values :
557 // A reference to this object
558
operator =(const wxString & rosCmd)559 wxString & Component::operator = ( const wxString & rosCmd )
560 {
561 bSetString( rosCmd );
562
563 return( *((wxString *) this) );
564 }
565
566 //**************************************************************************************************
567 // Copy the contents of another Component object.
568 //
569 // Argument List :
570 // roCpnt - A reference to a Component object
571 //
572 // Return Values :
573 // A reference to this object
574
operator =(const Component & roCpnt)575 Component & Component::operator = ( const Component & roCpnt )
576 {
577 (wxString &) *this = (wxString &) roCpnt;
578
579 m_eType = roCpnt.m_eType;
580
581 m_osName = roCpnt.m_osName;
582 m_osaNodes = roCpnt.m_osaNodes;
583 m_osValue = roCpnt.m_osValue;
584
585 m_osaPorts = roCpnt.m_osaPorts;
586
587 m_osErrMsg = roCpnt.m_osErrMsg;
588
589 return( *this );
590 }
591
592 //**************************************************************************************************
593 // Print the object attributes.
594 //
595 // Argument List :
596 // rosPrefix - A prefix to every line displayed (usually just spaces)
597
Print(const wxString & rosPrefix)598 void Component::Print( const wxString & rosPrefix )
599 {
600 size_t sz1;
601
602 std::cout << rosPrefix.mb_str( ) << "wxString:: : " << this ->mb_str( ) << '\n';
603
604 std::cout << rosPrefix.mb_str( ) << "m_osErrMsg : " << m_osErrMsg .mb_str( ) << '\n';
605
606 std::cout << rosPrefix.mb_str( ) << "m_eType : ";
607 switch( m_eType )
608 {
609 case eCPNT_CAP : std::cout << "eCPNT_CAP" ; break; // Capacitor
610 case eCPNT_RES : std::cout << "eCPNT_RES" ; break; // Resistor
611 case eCPNT_IND : std::cout << "eCPNT_IND" ; break; // Inductor
612 case eCPNT_CIND : std::cout << "eCPNT_CIND" ; break; // Coupled (Mutual) Inductors
613 case eCPNT_DIODE : std::cout << "eCPNT_DIODE" ; break; // Diode
614 case eCPNT_BJT : std::cout << "eCPNT_BJT" ; break; // BJT (Bipolar Junction Transistor)
615 case eCPNT_JFET : std::cout << "eCPNT_JFET" ; break; // JFET (Junction Field-Effect Transistor)
616 case eCPNT_MOSFET : std::cout << "eCPNT_MOSFET"; break; // MOSFET (Metal-Oxide Semiconductor Field-Effect Transistor)
617 case eCPNT_MESFET : std::cout << "eCPNT_MESFET"; break; // MESFET (Metal–Semiconductor Field Effect Transistor)
618 case eCPNT_VCVS : std::cout << "eCPNT_VCVS" ; break; // Voltage Controlled Voltage Source
619 case eCPNT_CCCS : std::cout << "eCPNT_CCCS" ; break; // Current Controlled Current Source
620 case eCPNT_VCCS : std::cout << "eCPNT_VCCS" ; break; // Voltage Controlled Current Source
621 case eCPNT_CCVS : std::cout << "eCPNT_CCVS" ; break; // Current Controlled Voltage Source
622 case eCPNT_TLINE : std::cout << "eCPNT_TLINE" ; break; // Lossless Transmission Line
623 case eCPNT_LTRA : std::cout << "eCPNT_LTRA" ; break; // Lossy Transmission Line (LTRA)
624 case eCPNT_CPL : std::cout << "eCPNT_CPL" ; break; // Coupled Multi-conductor Transmission Line (CPL)
625 case eCPNT_TXL : std::cout << "eCPNT_TXL" ; break; // Single Lossy Transmission Line (TXL)
626 case eCPNT_URC : std::cout << "eCPNT_URC" ; break; // Uniform Distributed RC Transmission Line (URC)
627 case eCPNT_ICS : std::cout << "eCPNT_ICS" ; break; // Independent Current Source
628 case eCPNT_IVS : std::cout << "eCPNT_IVS" ; break; // Independent Voltage Source
629 case eCPNT_NLDS : std::cout << "eCPNT_NLDS" ; break; // Non-Linear Dependent Source
630 case eCPNT_NLDCS : std::cout << "eCPNT_NLDCS" ; break; // Non-Linear Dependent Current Source
631 case eCPNT_NLDVS : std::cout << "eCPNT_NLDVS" ; break; // Non-Linear Dependent Voltage Source
632 case eCPNT_CCSW : std::cout << "eCPNT_CCSW" ; break; // Current Controlled Switch
633 case eCPNT_VCSW : std::cout << "eCPNT_VCSW" ; break; // Voltage Controlled Switch
634 case eCPNT_SUBCKT : std::cout << "eCPNT_SUBCKT"; break; // Sub-circuit
635 case eCPNT_LOGIC : std::cout << "eCPNT_LOGIC" ; break; // Logic Device
636 case eCPNT_STJ : std::cout << "eCPNT_STJ" ; break; // Super-conducting Tunnel Junction
637
638 default : std::cout << "Invalid";
639 }
640 std::cout << '\n';
641
642 std::cout << rosPrefix.mb_str( ) << "m_osName : " << m_osName .mb_str( ) << '\n';
643
644 std::cout << rosPrefix.mb_str( ) << "m_osaNodes[ ] : ";
645 for( sz1=0; sz1<m_osaNodes.GetCount( ); sz1++ )
646 {
647 if( sz1 > 0 ) std::cout << ", ";
648 std::cout << m_osaNodes.Item( sz1 ).mb_str( );
649 }
650 std::cout << '\n';
651
652 std::cout << rosPrefix.mb_str( ) << "m_osaPorts[ ] : ";
653 for( sz1=0; sz1<m_osaPorts.GetCount( ); sz1++ )
654 {
655 if( sz1 > 0 ) std::cout << " ";
656 std::cout << m_osaPorts.Item( sz1 ).mb_str( );
657 }
658 std::cout << '\n';
659
660 std::cout << rosPrefix.mb_str( ) << "m_osValue : " << m_osValue .mb_str( ) << '\n';
661
662 std::cout << rosPrefix.mb_str( ) << "rosGetNumValue( ) : " << rosGetNumValue( ).mb_str( ) << '\n';
663
664 std::cout << rosPrefix.mb_str( ) << "eGetUnitsType( ) : ";
665 switch( eGetUnitsType( m_osName ) )
666 {
667 case eUNITS_CAP : std::cout << "eUNITS_CAP"; break;
668 case eUNITS_IND : std::cout << "eUNITS_IND"; break;
669 case eUNITS_RES : std::cout << "eUNITS_RES"; break;
670 case eUNITS_VOLT : std::cout << "eUNITS_VOLT"; break;
671 case eUNITS_CURR : std::cout << "eUNITS_CURR"; break;
672 case eUNITS_TIME : std::cout << "eUNITS_TIME"; break;
673 case eUNITS_FREQ : std::cout << "eUNITS_FREQ"; break;
674 case eUNITS_PHAD : std::cout << "eUNITS_PHAD"; break;
675 case eUNITS_PHAR : std::cout << "eUNITS_PHAR"; break;
676 case eUNITS_TMPC : std::cout << "eUNITS_TMPC"; break;
677 case eUNITS_TMPF : std::cout << "eUNITS_TMPF"; break;
678 case eUNITS_EXP : std::cout << "eUNITS_EXP"; break;
679 case eUNITS_NONE : std::cout << "eUNITS_NONE"; break;
680
681 default : std::cout << "Invalid"; break;
682 }
683 std::cout << '\n';
684 }
685
686 //**************************************************************************************************
687 // Test Utility *
688 //**************************************************************************************************
689
690 #ifdef TEST_COMPONENT
691
692 using namespace std;
693
694 // Function prototypes
695
696 void Usage( char * psAppName );
697
698 //**************************************************************************************************
699
main(int argc,char * argv[])700 int main( int argc, char * argv[ ] )
701 {
702 wxString osCpnt;
703 wxString os1;
704
705 // Validate the argument count passed to the application
706 if( argc > 2 ) { Usage( argv[0] ); exit( EXIT_FAILURE ); }
707
708 // Process the command line arguments
709 os1 = wxConvLibc.cMB2WC( argv[ 1 ] );
710 if( argc > 1 )
711 {
712 if( os1.at( 0 ) == wxT('-') )
713 {
714 if( os1.at( 1 ) == wxT('h') ) { Usage( argv[0] ); exit( EXIT_SUCCESS ); }
715 else { Usage( argv[0] ); exit( EXIT_FAILURE ); }
716 }
717 }
718
719 // Display the utility banner
720 cout << "\n Component Class Test Utility"
721 << "\n Version 1.07 (19/08/2011)\n";
722
723 // Create a GNU-CAP OP command object
724 Component tCpnt;
725
726 // Use the following command example to check the formatter and the parser :
727 osCpnt = wxT("Vin 2 0 AC 1V"); // This contains TABs and SPACEs
728 cout << "\nCpnt defn to test : "
729 << osCpnt.mb_str( ) << "\n\n";
730
731 // ******************** Test the formatter ********************
732 cout << "Test the component formatter :";
733
734 // Set things up for a formatter test
735 tCpnt.bClear( );
736 tCpnt.bSetName ( wxT("Vin") );
737 tCpnt.bSetNodes( wxT("2,0") );
738 tCpnt.bSetValue( wxT("AC 1V") );
739
740 // Run the formatter
741 cout << "\n Run formatter : ";
742 if( tCpnt.bFormat( ) )
743 cout << "OK";
744 else cout << "FAULT (" << tCpnt.rosGetErrMsg( ).mb_str( ) << ')';
745
746 // Test the formatter output
747 cout << "\n Test format : ";
748 if( (wxString) tCpnt == Component::rosTrim( osCpnt ) )
749 cout << "OK\n" << " Component defn : "
750 << tCpnt.rosGetString( ).mb_str( ) << '\n';
751 else
752 { // There's been an error so print the component contents
753 cout << "FAULT\n";
754 cout << " tCpnt Contents : \n";
755 tCpnt.Print( wxT(" ") );
756 }
757
758 cout << "\n";
759
760 // ********************* Test the parser *********************
761 cout << "Test the component parser :";
762
763 // Set things up for a parser test
764 tCpnt.bClear( );
765 tCpnt = osCpnt;
766
767 // Run the parser
768 cout << "\n Run parser : ";
769 if( tCpnt.bParse( ) )
770 cout << "OK";
771 else cout << "FAULT (" << tCpnt.rosGetErrMsg( ).mb_str( ) << ')';
772
773 // Test the parser output
774 tCpnt.bFormat( );
775 cout << "\n Test format : ";
776 if( (wxString) tCpnt == Component::rosTrim( osCpnt ) )
777 cout << "OK\n" << " Component defn : "
778 << tCpnt.rosGetString( ).mb_str( ) << '\n';
779 else
780 { // There's been an error so print the component contents
781 cout << "FAULT\n";
782 cout << " tCpnt Contents : \n";
783 tCpnt.Print( wxT(" ") );
784 }
785
786 cout << "\n";
787
788 exit( EXIT_SUCCESS );
789 }
790
791 //**************************************************************************************************
792
Usage(char * psAppName)793 void Usage( char * psAppName )
794 {
795 cout << "\nUsage : " << psAppName << " [-OPTIONS]"
796 << "\nOptions :"
797 << "\n -h : Print usage (this message)\n";
798 }
799
800 #endif // TEST_COMPONENT
801
802 //**************************************************************************************************
803