1 //************************************************************************************************** 2 // PrcGaw.cpp * 3 // ------------ * 4 // Started : 2008-01-10 * 5 // Last Update : 2014-12-30 * 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 "PrcGaw.hpp" 18 19 //************************************************************************************************** 20 // Constructor. 21 PrcGaw(void)22PrcGaw::PrcGaw( 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 Gaw binary 29 bSetBinary( BIN_GAW ); 30 } 31 32 //************************************************************************************************** 33 // Destructor. 34 ~PrcGaw()35PrcGaw::~PrcGaw( ) 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)49bool PrcGaw::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)77bool PrcGaw::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 PrcGaw::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 PrcGaw::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: gaw ../sch/test-amp1.gnucap.dc) 223 // 224 // Return Values: 225 // true - Success 226 // false - Failure 227 bExec(void)228bool PrcGaw::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