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-2019 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 <macros.h>
26 #include <common.h>
27 #include <kicad_string.h>
28 #include <pgm_base.h>
29 #include <pcb_calculator.h>
30 #include <pcb_calculator_datafile_lexer.h>
31 #include <class_regulator_data.h>
32 #include <datafile_read_write.h>
33 #include <build_version.h>
34 
35 
36 using namespace PCBCALC_DATA_T;
37 
38 
39 static const char* getTokenName( T aTok )
40 {
41  return PCB_CALCULATOR_DATAFILE_LEXER::TokenName( aTok );
42 }
43 
44 
46 {
47  FILE* file = wxFopen( GetDataFilename(), wxT( "rt" ) );
48 
49  if( file == NULL )
50  return false;
51 
52  // Switch the locale to standard C (needed to read/write floating point numbers)
53  LOCALE_IO toggle;
54 
55  PCB_CALCULATOR_DATAFILE * datafile = new PCB_CALCULATOR_DATAFILE( &m_RegulatorList );
56 
57  // dataReader dtor will close file
58  FILE_LINE_READER dataReader( file, GetDataFilename() );
59  PCB_CALCULATOR_DATAFILE_PARSER datafile_parser( &dataReader );
60 
61  try
62  {
63  datafile_parser.Parse( datafile );
64  }
65  catch( const IO_ERROR& ioe )
66  {
67  delete datafile;
68 
69  wxString msg = ioe.What();
70 
71  msg += wxChar('\n');
72  msg += _("Data file error.");
73 
74  wxMessageBox( msg );
75  return false;
76  }
77 
78  delete datafile;
79 
80  return true;
81 }
82 
84 {
85  // Switch the locale to standard C (needed to read/write floating point numbers)
86  LOCALE_IO toggle;
87 
88  std::unique_ptr<PCB_CALCULATOR_DATAFILE>
89  datafile( new PCB_CALCULATOR_DATAFILE( &m_RegulatorList ) );
90 
91  try
92  {
93  FILE_OUTPUTFORMATTER formatter( GetDataFilename() );
94 
95  int nestlevel = datafile->WriteHeader( &formatter );
96 
97  datafile->Format( &formatter, nestlevel );
98 
99  while( nestlevel-- )
100  formatter.Print( nestlevel, ")\n" );
101  }
102  catch( const IO_ERROR& )
103  {
104  return false;
105  }
106 
107  m_RegulatorListChanged = false;
108  return true;
109 }
110 
111 
113 {
114  m_list = aList;
115 }
116 
117 static const char* regtype_str[] =
118 {
119  "normal", "3terminal"
120 };
121 
123 {
124  int nestlevel = 0;
125  aFormatter->Print( nestlevel++, "(datafile\n");
126  aFormatter->Print( nestlevel++, "(version 1)\n" );
127  aFormatter->Print( nestlevel++, "(date %s)\n",
128  aFormatter->Quotew( DateAndTime() ).c_str() );
129  aFormatter->Print( nestlevel++, "(tool %s)\n",
130  aFormatter->Quotew( Pgm().App().GetAppName() +
131  wxChar(' ') + GetBuildVersion() ).c_str() );
132 
133  return nestlevel;
134 }
135 
137  int aNestLevel ) const
138 {
139  // Write regulators list:
140  aFormatter->Print( aNestLevel++, "(%s\n", getTokenName( T_regulators ) );
141  for( unsigned ii = 0; ii < m_list->m_List.size(); ii++ )
142  {
143  REGULATOR_DATA * item = m_list->m_List[ii];
144  aFormatter->Print( aNestLevel, "(%s %s\n", getTokenName( T_regulator ),
145  aFormatter->Quotew(item->m_Name ).c_str() );
146  aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_vref ),
147  item->m_Vref );
148  if( item->m_Iadj != 0 && item->m_Type == 1)
149  {
150  aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_iadj ),
151  item->m_Iadj );
152  }
153  aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_reg_type ),
154  regtype_str[item->m_Type] );
155  aFormatter->Print( aNestLevel, ")\n" );
156  }
157  aFormatter->Print( --aNestLevel, ")\n" );
158 }
159 
160 
162 {
163  aParser->Parse( this );
164 }
165 
166 
167 
168 // PCB_CALCULATOR_DATAFILE_PARSER
169 
171  PCB_CALCULATOR_DATAFILE_LEXER( aReader )
172 {
173 }
174 
175 
176 PCB_CALCULATOR_DATAFILE_PARSER::PCB_CALCULATOR_DATAFILE_PARSER( char* aLine, const wxString& aSource ) :
177  PCB_CALCULATOR_DATAFILE_LEXER( aLine, aSource )
178 {
179 }
180 
181 
183 {
184  T token;
185  while( ( token = NextTok() ) != T_EOF)
186  {
187  if( token == T_LEFT )
188  {
189  token = NextTok();
190 
191  if( token == T_regulators )
192  {
193  ParseRegulatorDescr( aDataList );
194  continue;
195  }
196  }
197  }
198 }
199 
201 {
202  T token;
203  wxString name;
204  double vref, iadj;
205  int type;
206 
207  while( ( token = NextTok() ) != T_RIGHT )
208  {
209  if( token == T_EOF)
210  Unexpected( T_EOF );
211 
212  if( token == T_LEFT )
213  token = NextTok();
214 
215  if( token == T_regulator )
216  {
217  type = 0;
218  vref = 0.0;
219 
220  // Read name
221  token = NextTok();
222  name = FROM_UTF8( CurText() );
223 
224  while( ( token = NextTok() ) != T_RIGHT )
225  {
226  if( token == T_EOF)
227  Unexpected( T_EOF );
228 
229  if( token == T_LEFT )
230  token = NextTok();
231 
232  switch( token )
233  {
234  case T_reg_vref: // the voltage reference value
235  token = NextTok();
236  if( token != T_NUMBER )
237  Expecting( T_NUMBER );
238  sscanf( CurText(), "%lf" , &vref);
239  NeedRIGHT();
240  break;
241 
242  case T_reg_iadj: // the Iadj reference value
243  token = NextTok();
244  if( token != T_NUMBER )
245  Expecting( T_NUMBER );
246  sscanf( CurText(), "%lf" , &iadj);
247  NeedRIGHT();
248  break;
249 
250  case T_reg_type: // type: normal or 3 terminal reg
251  token = NextTok();
252  if( strcasecmp( CurText(), regtype_str[0] ) == 0 )
253  type = 0;
254  else if( strcasecmp( CurText(), regtype_str[1] ) == 0 )
255  type = 1;
256  else
257  Unexpected( CurText() );
258  NeedRIGHT();
259  break;
260 
261  default:
262  Unexpected( CurText() );
263  break;
264  }
265  }
266 
267  if( ! name.IsEmpty() )
268  {
269  if( type != 1 )
270  iadj = 0.0;
271  REGULATOR_DATA * new_item = new REGULATOR_DATA(name, vref, type, iadj );
272  aDataList->m_list->Add( new_item );
273  }
274  }
275  }
276 }
LINE_READER is an abstract class from which implementation specific LINE_READERs may be derived to re...
Definition: richio.h:81
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:104
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:114
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:214
PCB_CALCULATOR_DATAFILE(REGULATOR_LIST *aList)
OUTPUTFORMATTER is an important interface (abstract class) used to output 8 bit text in a convenient ...
Definition: richio.h:327
void Parse(PCB_CALCULATOR_DATAFILE *aDataList)
int WriteHeader(OUTPUTFORMATTER *aFormatter) const
This file contains miscellaneous commonly used macros and functions.
FILE_LINE_READER is a LINE_READER that reads from an open file.
Definition: richio.h:180
#define NULL
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
wxString GetBuildVersion()
Get the full KiCad version string.
PCB_CALCULATOR_DATAFILE_PARSER is the parser class for PCB_CALCULATOR_DATAFILE.
void Add(REGULATOR_DATA *aItem)
static const char * getTokenName(T aTok)
std::string Quotew(const wxString &aWrapee)
Definition: richio.cpp:472
static const char * regtype_str[]
see class PGM_BASE
PCB_CALCULATOR_DATAFILE_PARSER(LINE_READER *aReader)
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
void ParseRegulatorDescr(PCB_CALCULATOR_DATAFILE *aDataList)
The common library.
PCB_CALCULATOR_DATAFILE handles data to calculate regulators parameters.
FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
void Parse(PCB_CALCULATOR_DATAFILE_PARSER *aParser)
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Function Print formats and writes text to the output stream.
Definition: richio.cpp:404
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76
wxString DateAndTime()
Definition: string.cpp:379
void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel) const