KiCad PCB EDA Suite
datafile_read_write.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 2016 Jean-Pierre Charras
9  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 3
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 #include <wx/app.h>
26 #include <wx/msgdlg.h>
27 
28 #include <build_version.h>
30 #include <class_regulator_data.h>
31 #include <datafile_read_write.h>
32 #include <string_utils.h>
33 #include <locale_io.h>
34 #include <macros.h>
35 #include <pcb_calculator_datafile_lexer.h>
36 #include <pcb_calculator_frame.h>
37 #include <pgm_base.h>
38 
39 
40 using namespace PCBCALC_DATA_T;
41 
42 
43 static const char* getTokenName( T aTok )
44 {
45  return PCB_CALCULATOR_DATAFILE_LEXER::TokenName( aTok );
46 }
47 
48 
50 {
51  FILE* file = wxFopen( GetDataFilename(), wxT( "rt" ) );
52 
53  if( file == nullptr )
54  return false;
55 
56  // Switch the locale to standard C (needed to read/write floating point numbers)
57  LOCALE_IO toggle;
58 
59  PCB_CALCULATOR_DATAFILE* datafile = new PCB_CALCULATOR_DATAFILE( &m_RegulatorList );
60 
61  // dataReader dtor will close file
62  FILE_LINE_READER dataReader( file, GetDataFilename() );
63  PCB_CALCULATOR_DATAFILE_PARSER datafile_parser( &dataReader );
64 
65  try
66  {
67  datafile_parser.Parse( datafile );
68  }
69  catch( const IO_ERROR& ioe )
70  {
71  delete datafile;
72 
73  wxString msg = ioe.What();
74 
75  msg += wxChar('\n');
76  msg += _("Data file error.");
77 
78  wxMessageBox( msg );
79  return false;
80  }
81 
82  m_choiceRegulatorSelector->Clear();
83  m_choiceRegulatorSelector->Append( m_RegulatorList.GetRegList() );
84  SelectLastSelectedRegulator();
85 
86  delete datafile;
87 
88  return true;
89 }
90 
91 
93 {
94  // Switch the locale to standard C (needed to read/write floating point numbers)
95  LOCALE_IO toggle;
96 
97  auto datafile = std::make_unique<PCB_CALCULATOR_DATAFILE>( &m_RegulatorList );
98 
99  try
100  {
101  FILE_OUTPUTFORMATTER formatter( GetDataFilename() );
102 
103  int nestlevel = datafile->WriteHeader( &formatter );
104 
105  datafile->Format( &formatter, nestlevel );
106 
107  while( nestlevel-- )
108  formatter.Print( nestlevel, ")\n" );
109  }
110  catch( const IO_ERROR& )
111  {
112  return false;
113  }
114 
115  m_RegulatorListChanged = false;
116  return true;
117 }
118 
119 
121 {
122  m_list = aList;
123 }
124 
125 
126 static const char* regtype_str[] =
127 {
128  "normal", "3terminal"
129 };
130 
131 
133 {
134  int nestlevel = 0;
135  aFormatter->Print( nestlevel++, "(datafile\n");
136  aFormatter->Print( nestlevel++, "(version 1)\n" );
137  aFormatter->Print( nestlevel++, "(date %s)\n",
138  aFormatter->Quotew( DateAndTime() ).c_str() );
139  aFormatter->Print( nestlevel++, "(tool %s)\n",
140  aFormatter->Quotew( Pgm().App().GetAppName() +
141  wxChar(' ') + GetBuildVersion() ).c_str() );
142 
143  return nestlevel;
144 }
145 
147  int aNestLevel ) const
148 {
149  // Write regulators list:
150  aFormatter->Print( aNestLevel++, "(%s\n", getTokenName( T_regulators ) );
151 
152  for( REGULATOR_DATA* item : m_list->m_List )
153  {
154  aFormatter->Print( aNestLevel, "(%s %s\n", getTokenName( T_regulator ),
155  aFormatter->Quotew(item->m_Name ).c_str() );
156  aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_vref ),
157  item->m_Vref );
158 
159  if( item->m_Iadj != 0 && item->m_Type == 1)
160  {
161  aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_iadj ),
162  item->m_Iadj );
163  }
164 
165  aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_reg_type ),
166  regtype_str[item->m_Type] );
167  aFormatter->Print( aNestLevel, ")\n" );
168  }
169 
170  aFormatter->Print( --aNestLevel, ")\n" );
171 }
172 
173 
175 {
176  aParser->Parse( this );
177 }
178 
179 
181  PCB_CALCULATOR_DATAFILE_LEXER( aReader )
182 {
183 }
184 
185 
187  const wxString& aSource ) :
188  PCB_CALCULATOR_DATAFILE_LEXER( aLine, aSource )
189 {
190 }
191 
192 
194 {
195  T token;
196 
197  while( ( token = NextTok() ) != T_EOF)
198  {
199  if( token == T_LEFT )
200  {
201  token = NextTok();
202 
203  if( token == T_regulators )
204  {
205  ParseRegulatorDescr( aDataList );
206  continue;
207  }
208  }
209  }
210 }
211 
212 
214 {
215  T token;
216  wxString name;
217  double vref, iadj;
218  int type;
219 
220  while( ( token = NextTok() ) != T_RIGHT )
221  {
222  if( token == T_EOF)
223  Unexpected( T_EOF );
224 
225  if( token == T_LEFT )
226  token = NextTok();
227 
228  if( token == T_regulator )
229  {
230  type = 0;
231  vref = 0.0;
232 
233  // Read name
234  token = NextTok();
235  name = FROM_UTF8( CurText() );
236 
237  while( ( token = NextTok() ) != T_RIGHT )
238  {
239  if( token == T_EOF)
240  Unexpected( T_EOF );
241 
242  if( token == T_LEFT )
243  token = NextTok();
244 
245  switch( token )
246  {
247  case T_reg_vref: // the voltage reference value
248  token = NextTok();
249 
250  if( token != T_NUMBER )
251  Expecting( T_NUMBER );
252 
253  sscanf( CurText(), "%lf" , &vref);
254  NeedRIGHT();
255  break;
256 
257  case T_reg_iadj: // the Iadj reference value
258  token = NextTok();
259 
260  if( token != T_NUMBER )
261  Expecting( T_NUMBER );
262 
263  sscanf( CurText(), "%lf" , &iadj);
264  NeedRIGHT();
265  break;
266 
267  case T_reg_type: // type: normal or 3 terminal reg
268  token = NextTok();
269 
270  if( strcasecmp( CurText(), regtype_str[0] ) == 0 )
271  type = 0;
272  else if( strcasecmp( CurText(), regtype_str[1] ) == 0 )
273  type = 1;
274  else
275  Unexpected( CurText() );
276 
277  NeedRIGHT();
278  break;
279 
280  default:
281  Unexpected( CurText() );
282  break;
283  }
284  }
285 
286  if( ! name.IsEmpty() )
287  {
288  if( type != 1 )
289  iadj = 0.0;
290 
291  REGULATOR_DATA* new_item = new REGULATOR_DATA( name, vref, type, iadj );
292  aDataList->m_list->Add( new_item );
293  }
294  }
295  }
296 }
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:80
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
PCB_CALCULATOR_DATAFILE(REGULATOR_LIST *aList)
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:309
void Parse(PCB_CALCULATOR_DATAFILE *aDataList)
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
int WriteHeader(OUTPUTFORMATTER *aFormatter) const
This file contains miscellaneous commonly used macros and functions.
A LINE_READER that reads from an open file.
Definition: richio.h:172
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
wxString GetBuildVersion()
Get the full KiCad version string.
Parser for PCB_CALCULATOR_DATAFILE.
Contains structures for storage of regulator data.
void Add(REGULATOR_DATA *aItem)
static const char * getTokenName(T aTok)
#define _(s)
static const char * regtype_str[]
see class PGM_BASE
PCB_CALCULATOR_DATAFILE_PARSER(LINE_READER *aReader)
const char * name
Definition: DXF_plotter.cpp:56
void ParseRegulatorDescr(PCB_CALCULATOR_DATAFILE *aDataList)
PCB_CALCULATOR_DATAFILE handles data to calculate regulators parameters.
Used for text file output.
Definition: richio.h:456
void Parse(PCB_CALCULATOR_DATAFILE_PARSER *aParser)
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:426
wxString DateAndTime()
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494
void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel) const