1 //**************************************************************************************************
2 //                                          PrcGWave.cpp                                           *
3 //                                         --------------                                          *
4 // Started     : 2004-03-29                                                                        *
5 // Last Update : 2014-12-30                                                                        *
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 "PrcGWave.hpp"
18 
19 //**************************************************************************************************
20 // Constructor.
21 
PrcGWave(void)22 PrcGWave::PrcGWave( void ) : PrcBase( wxPROCESS_REDIRECT )
23 {
24   // Initialize the object attributes
25   m_ofnResults.Clear( );
26   m_ofnLog    .Clear( );
27 
28   // Attempt to set and find the gWave binary
29   bSetBinary( BIN_GWAVE );
30 }
31 
32 //**************************************************************************************************
33 // Destructor.
34 
~PrcGWave()35 PrcGWave::~PrcGWave( )
36 {
37 }
38 
39 //**************************************************************************************************
40 // Set the simulation results file name.
41 //
42 // Argument List:
43 //   psFileName - a string containing the full path and file name
44 //
45 // Return Values:
46 //   true  - Success
47 //   false - Failure
48 
bSetResults(const wxString & rosFileName)49 bool  PrcGWave::bSetResults( const wxString & rosFileName )
50 {
51   wxFileName  ofn1;
52 
53   ofn1 = rosFileName;
54   if( ofn1.GetPath( ).IsEmpty( ) ) ofn1.SetPath( wxT(".") );
55 
56   if( ! ofn1.IsOk( )       ) return( false );
57   if( ! ofn1.FileExists( ) ) return( false );
58 
59   m_ofnResults = ofn1;
60 
61   return( true );
62 }
63 
64 //**************************************************************************************************
65 // Filter the results file so that the data viewer utility is happy with it.
66 //
67 // There are several things that a data viewer can object to :
68 //  - gwave doesn't like the GNU-Cap banner at the start to the results file, so it's removed here.
69 //  - gwave doesn't like error messages interspersed with the lines of data, so they are removed
70 //    here.
71 //  - For good measure lines and fields are also formatted.
72 //
73 // Return Values:
74 //   true  - Success
75 //   false - Failure
76 
bFilterFile(void)77 bool  PrcGWave::bFilterFile( void )
78 {
79   wxString  os1;
80   size_t    szt1, szt2;
81   wxChar    oc1;
82   bool      bRtn=true;
83 
84   // Attempt to open the results file
85   wxTextFile  oFileCct( m_ofnResults.GetFullPath( ) );
86   if( ! oFileCct.Exists( ) ) return( false );
87   if( ! oFileCct.Open( ) )   return( false );
88 
89   // Has this file been formatted already?
90   if( oFileCct.GetFirstLine( ).GetChar( 0 ) == wxT('#') ) return( true );
91 
92   // Find the beginning of the data area (ie. the last line beginning with '#')
93   for( szt1=szt2=0; szt1<oFileCct.GetLineCount( ); szt1++ )
94   {
95     os1 = oFileCct.GetLine( szt1 );
96     if( ! os1.IsEmpty( ) )
97       if( os1.GetChar( 0 ) == wxT('#') )
98         szt2 = szt1;
99   }
100 
101   // Delete the banner
102   for( szt1=0; szt1<szt2; szt1++ ) oFileCct.RemoveLine( 0 );
103   if( oFileCct.GetLineCount( ) <= 1 )                     return( false );
104 
105   // Delete any simulator error messages eg. "open circuit: internal node 3"
106   // (All lines should start with a digit except for the first)
107   for( szt1=1; !oFileCct.Eof( ) && szt1<oFileCct.GetLineCount( ); szt1++ )
108   {
109     os1 = oFileCct.GetLine( szt1 );
110     if( os1.Length( ) <= 1 )
111     { // Delete empty lines
112       oFileCct.RemoveLine( szt1 );
113       szt1--;
114       continue;
115     }
116     oc1 = os1.GetChar( 1 );
117     if( ! wxIsdigit( oc1 ) )
118     { // Delete non-data lines
119       oFileCct.RemoveLine( szt1 );
120       szt1--;
121       continue;
122     }
123   }
124 
125   // Format each data line in the file
126 //  for( szt1=1; szt1<oFileCct.GetLineCount( ); szt1++ )
127 //    if( ! bFormatLine( oFileCct.GetLine( szt1 ) ) )
128 //      bRtn = false;
129 
130   oFileCct.Write( ); // Save the changes to disk
131   oFileCct.Close( ); // Close the file
132 
133   return( bRtn );
134 }
135 
136 //**************************************************************************************************
137 // Reformat the lines from the results file.
138 //
139 // Argument List:
140 //   rosLine - The line to be formatted
141 //
142 // Return Values:
143 //   true  - Success
144 //   false - Failure
145 /*
146 bool  PrcGWave::bFormatLine( wxString & rosLine )
147 {
148   wxStringTokenizer  ostk1;
149   wxString  os1, os2;
150 
151   // Check for an empty string
152   if( rosLine.IsEmpty( ) )         return( false );
153 
154   // Break the line into fields
155   ostk1.SetString( rosLine );
156   if( ostk1.CountTokens( ) < 2 ) return( false );
157 
158   // Reformat the line
159   while( ostk1.HasMoreTokens( ) )
160   {
161     os1 = ostk1.GetNextToken( );
162     if( ! bFormatField( os1 ) )    return( false );
163     if( os2.IsEmpty( ) ) os2 = os1;
164     else                 os2 << wxT("     ") << os1;
165   }
166 
167   rosLine = os2;
168 
169   return( true );
170 }
171 */
172 //**************************************************************************************************
173 // Reformat the fields from the results file.
174 //
175 // Argument List:
176 //   rosField - The field to be formatted
177 //
178 // Return Values:
179 //   true  - Success
180 //   false - Failure
181 /*
182 bool  PrcGWave::bFormatField( wxString & rosField )
183 {
184   wxString  os1;
185   wxChar    oc1;
186   size_t    szt1;
187 
188   // Check for an empty string
189   if( rosField.IsEmpty( ) ) return( false );
190 
191   // Extract the value and the units
192   oc1 = 0;
193   for( szt1=0; szt1<rosField.Length( ); szt1++ )
194   {
195     oc1 = rosField.GetChar( szt1 );
196     if( oc1!=wxT('-') && !wxIsdigit( oc1 ) && oc1!=wxT('.') ) break;
197     else oc1 = 0;
198   }
199   os1 = rosField.Left( szt1 );
200 
201   // Reformat the field
202   switch( oc1 )
203   {
204     case wxT('M'): os1 << wxT("E+06"); break;
205     case wxT('K'): os1 << wxT("E+03"); break;
206     case wxT('m'): os1 << wxT("E-03"); break;
207     case wxT('u'): os1 << wxT("E-06"); break;
208     case wxT('n'): os1 << wxT("E-09"); break;
209     case wxT('p'): os1 << wxT("E-12"); break;
210     case 0: break;
211     default : return( false );
212   }
213 
214   rosField = os1;
215 
216   return( true );
217 }
218 */
219 //**************************************************************************************************
220 // View the results of a simulation.
221 //
222 // (Eg. using the following: gwave ../sch/test-amp1.gnucap.dc)
223 //
224 // Return Values:
225 //   true  - Success
226 //   false - Failure
227 
bExec(void)228 bool  PrcGWave::bExec( void )
229 {
230   wxString  os1;
231 
232   // Test file names needed by this function
233   if( ! bBinExists( ) )                             return( false );
234   if( !m_ofnResults.FileExists( ) || !m_ofnResults.IsOk( ) )
235   {
236     os1 = m_ofnResults.GetFullPath( );
237     m_osErrMsg.Empty( );
238     if( os1.IsEmpty( ) )
239          m_osErrMsg << wxT("The results file has not been set.");
240     else m_osErrMsg << wxT("The results file doesn't exist : ") << os1;
241     return( false );
242   }
243 
244   // Append input file name to argument list
245   if( ! bSetArgLst( m_ofnResults.GetFullPath( ) ) ) return( false );
246 
247   // Filter the file before passing it to the waveform viewer process
248   if( ! bFilterFile( ) )                            return( false );
249 
250   // Execute the process
251   if( ! PrcBase::bExecAsync( ) )                    return( false );
252 
253   return( true );
254 }
255 
256 //**************************************************************************************************
257