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>
29 #include <class_regulator_data.h>
30 #include <common.h>
31 #include <datafile_read_write.h>
32 #include <kicad_string.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  delete datafile;
83 
84  return true;
85 }
86 
87 
89 {
90  // Switch the locale to standard C (needed to read/write floating point numbers)
91  LOCALE_IO toggle;
92 
93  auto datafile = std::make_unique<PCB_CALCULATOR_DATAFILE>( &m_RegulatorList );
94 
95  try
96  {
97  FILE_OUTPUTFORMATTER formatter( GetDataFilename() );
98 
99  int nestlevel = datafile->WriteHeader( &formatter );
100 
101  datafile->Format( &formatter, nestlevel );
102 
103  while( nestlevel-- )
104  formatter.Print( nestlevel, ")\n" );
105  }
106  catch( const IO_ERROR& )
107  {
108  return false;
109  }
110 
111  m_RegulatorListChanged = false;
112  return true;
113 }
114 
115 
117 {
118  m_list = aList;
119 }
120 
121 
122 static const char* regtype_str[] =
123 {
124  "normal", "3terminal"
125 };
126 
127 
129 {
130  int nestlevel = 0;
131  aFormatter->Print( nestlevel++, "(datafile\n");
132  aFormatter->Print( nestlevel++, "(version 1)\n" );
133  aFormatter->Print( nestlevel++, "(date %s)\n",
134  aFormatter->Quotew( DateAndTime() ).c_str() );
135  aFormatter->Print( nestlevel++, "(tool %s)\n",
136  aFormatter->Quotew( Pgm().App().GetAppName() +
137  wxChar(' ') + GetBuildVersion() ).c_str() );
138 
139  return nestlevel;
140 }
141 
143  int aNestLevel ) const
144 {
145  // Write regulators list:
146  aFormatter->Print( aNestLevel++, "(%s\n", getTokenName( T_regulators ) );
147 
148  for( unsigned ii = 0; ii < m_list->m_List.size(); ii++ )
149  {
150  REGULATOR_DATA * item = m_list->m_List[ii];
151  aFormatter->Print( aNestLevel, "(%s %s\n", getTokenName( T_regulator ),
152  aFormatter->Quotew(item->m_Name ).c_str() );
153  aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_vref ),
154  item->m_Vref );
155 
156  if( item->m_Iadj != 0 && item->m_Type == 1)
157  {
158  aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_iadj ),
159  item->m_Iadj );
160  }
161 
162  aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_reg_type ),
163  regtype_str[item->m_Type] );
164  aFormatter->Print( aNestLevel, ")\n" );
165  }
166 
167  aFormatter->Print( --aNestLevel, ")\n" );
168 }
169 
170 
172 {
173  aParser->Parse( this );
174 }
175 
176 
178  PCB_CALCULATOR_DATAFILE_LEXER( aReader )
179 {
180 }
181 
182 
184  const wxString& aSource ) :
185  PCB_CALCULATOR_DATAFILE_LEXER( aLine, aSource )
186 {
187 }
188 
189 
191 {
192  T token;
193 
194  while( ( token = NextTok() ) != T_EOF)
195  {
196  if( token == T_LEFT )
197  {
198  token = NextTok();
199 
200  if( token == T_regulators )
201  {
202  ParseRegulatorDescr( aDataList );
203  continue;
204  }
205  }
206  }
207 }
208 
209 
211 {
212  T token;
213  wxString name;
214  double vref, iadj;
215  int type;
216 
217  while( ( token = NextTok() ) != T_RIGHT )
218  {
219  if( token == T_EOF)
220  Unexpected( T_EOF );
221 
222  if( token == T_LEFT )
223  token = NextTok();
224 
225  if( token == T_regulator )
226  {
227  type = 0;
228  vref = 0.0;
229 
230  // Read name
231  token = NextTok();
232  name = FROM_UTF8( CurText() );
233 
234  while( ( token = NextTok() ) != T_RIGHT )
235  {
236  if( token == T_EOF)
237  Unexpected( T_EOF );
238 
239  if( token == T_LEFT )
240  token = NextTok();
241 
242  switch( token )
243  {
244  case T_reg_vref: // the voltage reference value
245  token = NextTok();
246 
247  if( token != T_NUMBER )
248  Expecting( T_NUMBER );
249 
250  sscanf( CurText(), "%lf" , &vref);
251  NeedRIGHT();
252  break;
253 
254  case T_reg_iadj: // the Iadj reference value
255  token = NextTok();
256 
257  if( token != T_NUMBER )
258  Expecting( T_NUMBER );
259 
260  sscanf( CurText(), "%lf" , &iadj);
261  NeedRIGHT();
262  break;
263 
264  case T_reg_type: // type: normal or 3 terminal reg
265  token = NextTok();
266 
267  if( strcasecmp( CurText(), regtype_str[0] ) == 0 )
268  type = 0;
269  else if( strcasecmp( CurText(), regtype_str[1] ) == 0 )
270  type = 1;
271  else
272  Unexpected( CurText() );
273 
274  NeedRIGHT();
275  break;
276 
277  default:
278  Unexpected( CurText() );
279  break;
280  }
281  }
282 
283  if( ! name.IsEmpty() )
284  {
285  if( type != 1 )
286  iadj = 0.0;
287 
288  REGULATOR_DATA* new_item = new REGULATOR_DATA( name, vref, type, iadj );
289  aDataList->m_list->Add( new_item );
290  }
291  }
292  }
293 }
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:59
void ParseRegulatorDescr(PCB_CALCULATOR_DATAFILE *aDataList)
The common library.
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
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
wxString DateAndTime()
Definition: string.cpp:509
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:494
void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel) const