1 //**************************************************************************************************
2 //                                         CmdGnuCapGEN.cpp                                        *
3 //                                        ------------------                                       *
4 // Started     : 2008-03-11                                                                        *
5 // Last Update : 2014-12-23                                                                        *
6 // Copyright   : (C) 2008 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 "CmdGnuCapGEN.hpp"
18 
19 //**************************************************************************************************
20 // Constructor.
21 
CmdGnuCapGEN(void)22 CmdGnuCapGEN::CmdGnuCapGEN( void )
23 {
24   bSetDefaults( );
25 }
26 
27 //**************************************************************************************************
28 // Destructor.
29 
~CmdGnuCapGEN()30 CmdGnuCapGEN::~CmdGnuCapGEN( )
31 {
32 }
33 
34 //**************************************************************************************************
35 // Check that the object attributes are valid.
36 //
37 // Return Values :
38 //   true  - Success
39 //   false - Failure
40 
bValidate(void)41 bool  CmdGnuCapGEN::bValidate( void )
42 {
43   double  df1, df2, df3, df4;
44 
45   CmdBase::bValidate( );
46 
47   // Overall source characteristics
48   if( ! CnvtType::bStrToFlt( m_osAmplitude, &df1 ) )
49     SetErrMsg( wxT("overall amplitude value is invalid") );
50 //  if( df1 <= 0.0 ) ??? 05/10/2009
51 //    SetErrMsg( wxT("overall amplitude value must be greater than zero") );
52   if( ! CnvtType::bStrToFlt( m_osOffset,    &df1 ) )
53     SetErrMsg( wxT("overall offset value is invalid") );
54 
55   // Sinusoidal source characteristics
56   if( ! CnvtType::bStrToFlt( m_osSinFreq,  &df1 ) )
57     SetErrMsg( wxT("sinusoid frequency value is invalid") );
58   if( ! CnvtType::bStrToFlt( m_osSinPhase, &df1 ) )
59     SetErrMsg( wxT("sinusoid phase value is invalid") );
60 
61   // Check the pulse time values
62   if( ! CnvtType::bStrToFlt( m_osPulRise,   &df1 ) )
63     SetErrMsg( wxT("pulse rise time value is invalid") );
64   if( ! CnvtType::bStrToFlt( m_osPulWidth,  &df2 ) )
65     SetErrMsg( wxT("pulse width value is invalid") );
66   if( ! CnvtType::bStrToFlt( m_osPulFall,   &df3 ) )
67     SetErrMsg( wxT("pulse fall time value is invalid") );
68   if( ! CnvtType::bStrToFlt( m_osPulPeriod, &df4 ) )
69     SetErrMsg( wxT("pulse period value is invalid") );
70   if(      df4 < df1 )
71     SetErrMsg( wxT("pulse rise time is greater than the pulse period") );
72   else if( df4 < df2 )
73     SetErrMsg( wxT("pulse width is greater than the pulse period") );
74   else if( df4 < df3 )
75     SetErrMsg( wxT("pulse fall time is greater than the pulse period") );
76   else if( df4 < df1+df2+df3 )
77     SetErrMsg( wxT("pulse period is less then the pulse width") );
78 
79   // Check the pulse level values
80   if( ! CnvtType::bStrToFlt( m_osPulInitial, &df1 ) )
81     SetErrMsg( wxT("initial pulse value is invalid") );
82   if( ! CnvtType::bStrToFlt( m_osPulMin,     &df2 ) )
83     SetErrMsg( wxT("minimum pulse value is invalid") );
84   if( ! CnvtType::bStrToFlt( m_osPulMax,     &df3 ) )
85     SetErrMsg( wxT("maximum pulse value is invalid") );
86   if(      df1 < df2 )
87     SetErrMsg( wxT("initial pulse value is less than the minimum pulse value") );
88   else if( df1 > df3 )
89     SetErrMsg( wxT("initial pulse value is greater than the maximum pulse value") );
90   else if( df2 > df3 )
91     SetErrMsg( wxT("minimum pulse value is less than the maximum pulse value") );
92 
93   // Check overall pulse source logic
94   if( df4!=0.0  && (df2==0.0 && df3==0.0) )
95     SetErrMsg( wxT("pulse timing has been defined but no pulse levels") );
96   if( df4==0.0 && (df2!=0.0 || df3!=0.0) )
97     SetErrMsg( wxT("pulse levels have been defined but no pulse timing") );
98 
99   return( true );
100 }
101 
102 //**************************************************************************************************
103 // Set the object attributes to they're default values.
104 //
105 // Return Values :
106 //   true  - Success
107 //   false - Failure
108 
bSetDefaults(void)109 bool  CmdGnuCapGEN::bSetDefaults( void )
110 {
111   CmdBase::bSetDefaults( );
112 
113   m_eSimEng      = eSIMR_GNUCAP;
114   m_eCmdType     = eCMD_GEN;
115 
116   m_osAmplitude  = GCP_AMPLITUDE;
117   m_osOffset     = GCP_OFFSET;
118 
119   m_osSinFreq    = GCP_SINFREQ;
120   m_osSinPhase   = GCP_SINPHASE;
121 
122   m_osPulInitial = GCP_PULINITIAL;
123   m_osPulMin     = GCP_PULMIN;
124   m_osPulMax     = GCP_PULMAX;
125   m_osPulDelay   = GCP_PULDELAY;
126   m_osPulRise    = GCP_PULRISE;
127   m_osPulWidth   = GCP_PULWIDTH;
128   m_osPulFall    = GCP_PULFALL;
129   m_osPulPeriod  = GCP_PULPERIOD;
130 
131   return( true );
132 }
133 
134 //**************************************************************************************************
135 // Parse the command string.
136 //
137 // Eg.s : .GENERATOR AMP=2.00K OFFSET=1.00 FREQ=1.00K PHASE=50.00 INIT=5.00m
138 //                   MIN=2.00m MAX=10.00m DELAY=4.00m RISE=2.00m WIDTH=8.00m
139 //                   FALL=1.00m PERIOD=20.00m
140 //
141 // Return Values :
142 //   true  - Success
143 //   false - Failure
144 
bParse(void)145 bool  CmdGnuCapGEN::bParse( void )
146 {
147   wxStringTokenizer  ostk1;
148   wxString           os1, os2;
149   size_t             szt1;
150   int                i1;
151 
152   // Clear the object attributes
153   os1 = (wxString &) *this;
154   bSetDefaults( );
155   assign( os1 );
156 
157   // Tokenize the command string
158   ostk1.SetString( *this );
159   i1 = ostk1.CountTokens( );
160   if( i1<2 || i1>13 )      return( bValidate( ) );
161 
162   // Check command type
163   os1 = ostk1.GetNextToken( ).Left( 4 ).Upper( );
164   if( os1 != wxT(".GEN") ) return( bValidate( ) );
165 
166   // Extract each parameter value
167   while( ostk1.HasMoreTokens( ) )
168   {
169     // Extract the field name and the associated value
170     os1 = ostk1.GetNextToken( );
171     os2 = wxT("");
172     if( ( szt1=os1.find( wxT("=") ) ) != wxString::npos )
173     {
174       os2 = os1.Right( os1.Length( )-szt1-1 );
175       os1 = os1.Left( szt1 );
176     }
177 
178     // Set the object attribute values
179     if(      os1 == wxT("AMP")    ) m_osAmplitude  = os2;
180     else if( os1 == wxT("OFFSET") ) m_osOffset     = os2;
181     else if( os1 == wxT("FREQ")   ) m_osSinFreq    = os2;
182     else if( os1 == wxT("PHASE")  ) m_osSinPhase   = os2;
183     else if( os1 == wxT("INIT")   ) m_osPulInitial = os2;
184     else if( os1 == wxT("MIN")    ) m_osPulMin     = os2;
185     else if( os1 == wxT("MAX")    ) m_osPulMax     = os2;
186     else if( os1 == wxT("DELAY")  ) m_osPulDelay   = os2;
187     else if( os1 == wxT("RISE")   ) m_osPulRise    = os2;
188     else if( os1 == wxT("WIDTH")  ) m_osPulWidth   = os2;
189     else if( os1 == wxT("FALL")   ) m_osPulFall    = os2;
190     else if( os1 == wxT("PERIOD") ) m_osPulPeriod  = os2;
191     else                   return( bValidate( ) );
192   }
193 
194   return( bValidate( ) );
195 }
196 
197 //**************************************************************************************************
198 // Format the command string.
199 //
200 // Return Values :
201 //   true  - Success
202 //   false - Failure
203 
bFormat(void)204 bool  CmdGnuCapGEN::bFormat( void )
205 {
206   wxString  os1;
207   float     f1;
208   bool      b1;
209 
210   os1 = wxT(".GENERATOR");
211 
212   if( ! m_osAmplitude .IsEmpty( ) ) os1 << wxT(" AMP=")    << m_osAmplitude;
213   if( ! m_osOffset    .IsEmpty( ) ) os1 << wxT(" OFFSET=") << m_osOffset;
214 
215   f1 = 0.0;
216   b1 = CnvtType::bStrToFlt( m_osSinFreq, &f1 );
217   if( b1==true && f1!=0.0 )
218   {
219     os1 << wxT(" FREQ=")   << m_osSinFreq;
220     os1 << wxT(" PHASE=")  << m_osSinPhase;
221   }
222 
223   f1 = 0.0;
224   b1 = CnvtType::bStrToFlt( m_osPulMax, &f1 );
225   if( b1==true && f1!=0.0 )
226   {
227     os1 << wxT(" INIT=")   << m_osPulInitial;
228     os1 << wxT(" MIN=")    << m_osPulMin;
229     os1 << wxT(" MAX=")    << m_osPulMax;
230     os1 << wxT(" DELAY=")  << m_osPulDelay;
231     os1 << wxT(" RISE=")   << m_osPulRise;
232     os1 << wxT(" WIDTH=")  << m_osPulWidth;
233     os1 << wxT(" FALL=")   << m_osPulFall;
234     os1 << wxT(" PERIOD=") << m_osPulPeriod;
235   }
236 
237   assign( os1 );
238 
239   return( bValidate( ) );
240 }
241 
242 //**************************************************************************************************
243 // Copy the contents of a CpntNgsIndSrc object.
244 //
245 // Argument List :
246 //   roIndSrc - A reference to a CpntNgsIndSrc object
247 //
248 // Return Values :
249 //   A reference to this object
250 
operator =(const CpntNgsIndSrc & roIndSrc)251 CmdGnuCapGEN & CmdGnuCapGEN::operator = ( const CpntNgsIndSrc & roIndSrc )
252 {
253   double  df1, df2;
254 
255   if( ! roIndSrc.m_osSinAmp.IsEmpty( ) ) m_osAmplitude = roIndSrc.m_osSinAmp;
256   else                                   m_osAmplitude = wxT("1.0");
257   m_osOffset     = roIndSrc.m_osSinOffset;
258 
259   m_osSinFreq    = roIndSrc.m_osSinFreq;
260   if( CnvtType::bStrToFlt( roIndSrc.m_osSinFreq,  &df1 ) &&
261       CnvtType::bStrToFlt( roIndSrc.m_osSinDelay, &df2 ) )
262     CnvtType::bFltToStr( 360.0 * df2 * df1, m_osSinPhase );
263   else
264     m_osSinPhase = wxT("0.0");
265 
266   m_osPulInitial = roIndSrc.m_osPulInitial;
267   m_osPulMax     = roIndSrc.m_osPulMax;
268   m_osPulDelay   = roIndSrc.m_osPulDelay;
269   m_osPulRise    = roIndSrc.m_osPulRise;
270   m_osPulWidth   = roIndSrc.m_osPulWidth;
271   m_osPulFall    = roIndSrc.m_osPulFall;
272   m_osPulPeriod  = roIndSrc.m_osPulPeriod;
273 
274   bFormat( );
275 
276   return( *this );
277 }
278 
279 //**************************************************************************************************
280 // Print the object attributes.
281 //
282 // Argument List :
283 //   rosPrefix - A prefix to every line displayed (usually just spaces)
284 
Print(const wxString & rosPrefix)285 void  CmdGnuCapGEN::Print( const wxString & rosPrefix )
286 {
287   CmdBase::Print( rosPrefix + wxT("CmdBase::") );
288 
289   std::cout << rosPrefix.mb_str( ) << "m_osAmplitude  : " << m_osAmplitude .mb_str( ) << '\n';
290   std::cout << rosPrefix.mb_str( ) << "m_osOffset     : " << m_osOffset    .mb_str( ) << '\n';
291 
292   std::cout << rosPrefix.mb_str( ) << "m_osSinFreq    : " << m_osSinFreq   .mb_str( ) << '\n';
293   std::cout << rosPrefix.mb_str( ) << "m_osSinPhase   : " << m_osSinPhase  .mb_str( ) << '\n';
294 
295   std::cout << rosPrefix.mb_str( ) << "m_osPulInitial : " << m_osPulInitial.mb_str( ) << '\n';
296   std::cout << rosPrefix.mb_str( ) << "m_osPulMin     : " << m_osPulMin    .mb_str( ) << '\n';
297   std::cout << rosPrefix.mb_str( ) << "m_osPulMax     : " << m_osPulMax    .mb_str( ) << '\n';
298   std::cout << rosPrefix.mb_str( ) << "m_osPulDelay   : " << m_osPulDelay  .mb_str( ) << '\n';
299   std::cout << rosPrefix.mb_str( ) << "m_osPulRise    : " << m_osPulRise   .mb_str( ) << '\n';
300   std::cout << rosPrefix.mb_str( ) << "m_osPulWidth   : " << m_osPulWidth  .mb_str( ) << '\n';
301   std::cout << rosPrefix.mb_str( ) << "m_osPulFall    : " << m_osPulFall   .mb_str( ) << '\n';
302   std::cout << rosPrefix.mb_str( ) << "m_osPulPeriod  : " << m_osPulPeriod .mb_str( ) << '\n';
303 }
304 
305 //**************************************************************************************************
306 //                                          Test Utility                                           *
307 //**************************************************************************************************
308 
309 #ifdef TEST_CMDGNUCAPGEN
310 
311 using  namespace  std;
312 
313 // Function prototypes
314 
315 void  Usage( char * psAppName );
316 
317 //**************************************************************************************************
318 
main(int argc,char * argv[])319 int  main( int argc, char * argv[ ] )
320 {
321   wxString  osCmd;
322   wxString  os1;
323 
324   // Validate the argument count passed to the application
325   if( argc > 2 )           { Usage( argv[ 0 ] ); exit( EXIT_FAILURE ); }
326 
327   // Process the command line arguments
328   os1 = wxConvLibc.cMB2WC( argv[ 1 ] );
329   if( argc > 1 )
330   {
331     if( os1 == wxT("-h") ) { Usage( argv[ 0 ] ); exit( EXIT_SUCCESS ); }
332     else                   { Usage( argv[ 0 ] ); exit( EXIT_FAILURE ); }
333   }
334 
335   // Display the utility banner
336   cout << "\n  Class CmdGnuCapGEN Test Utility"
337        << "\n     Version 1.04 (12/08/2011)\n";
338 
339   // Create a GNU-CAP Transient command object
340   CmdGnuCapGEN  tCmd_GEN;
341 
342   // Use the following command example to check the formatter and the parser :
343   osCmd << wxT(".GENERATOR AMP=2.00K OFFSET=1.00 FREQ=1.00K PHASE=50.00 ")
344         << wxT("INIT=5.00m MIN=2.00m MAX=10.00m DELAY=4.00m RISE=2.00m ")
345         << wxT("WIDTH=8.00m FALL=1.00m PERIOD=20.00m");
346 
347   // Set things up for a formatter test
348   tCmd_GEN.m_osAmplitude  = wxT("2.00K");
349   tCmd_GEN.m_osOffset     = wxT("1.00");
350   tCmd_GEN.m_osSinFreq    = wxT("1.00K");
351   tCmd_GEN.m_osSinPhase   = wxT("50.00");
352   tCmd_GEN.m_osPulInitial = wxT("5.00m");
353   tCmd_GEN.m_osPulMin     = wxT("2.00m");
354   tCmd_GEN.m_osPulMax     = wxT("10.00m");
355   tCmd_GEN.m_osPulDelay   = wxT("4.00m");
356   tCmd_GEN.m_osPulRise    = wxT("2.00m");
357   tCmd_GEN.m_osPulWidth   = wxT("8.00m");
358   tCmd_GEN.m_osPulFall    = wxT("1.00m");
359   tCmd_GEN.m_osPulPeriod  = wxT("20.00m");
360   cout << "\nRun Formatter     : " << ( tCmd_GEN.bFormat( ) ? "OK" : "FAULT" );
361   cout << "\nTest Cmd Format   : " << ( tCmd_GEN == osCmd   ? "OK" : "FAULT" );
362   cout << "\nExample Command   : " << osCmd  .mb_str( );
363   cout << "\ntCmd_GEN Contents : " << tCmd_GEN.mb_str( ) << '\n';
364 
365   // Set things up for a parser test
366   tCmd_GEN.bSetString( osCmd );
367   cout << "\nRun Parser        : " << ( tCmd_GEN.bParse( ) ? "OK" : "FAULT" );
368   tCmd_GEN.bFormat( );
369   cout << "\nTest Cmd Format   : " << ( tCmd_GEN == osCmd  ? "OK" : "FAULT" );
370   cout << "\nExample Command   : " << osCmd  .mb_str( );
371   cout << "\ntCmd_GEN Contents : " << tCmd_GEN.mb_str( ) << '\n';
372 
373   cout << '\n';
374 
375   exit( EXIT_SUCCESS );
376 }
377 
378 //**************************************************************************************************
379 
Usage(char * psAppName)380 void  Usage( char * psAppName )
381 {
382   cout << "\nUsage   : " << psAppName << " [-OPTIONS]"
383        << "\nOptions :"
384        << "\n  -h : Print usage (this message)\n";
385 }
386 
387 #endif // TEST_CMDGNUCAPGEN
388 
389 //**************************************************************************************************
390