KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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>
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>
37#include <pgm_base.h>
38
39
40using namespace PCBCALC_DATA_T;
41
42
43static 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;
59
61
62 // dataReader dtor will close file
63 FILE_LINE_READER dataReader( file, GetDataFilename() );
64 PCB_CALCULATOR_DATAFILE_PARSER datafile_parser( &dataReader );
65
66 try
67 {
68 datafile_parser.Parse( datafile );
69 }
70 catch( const IO_ERROR& ioe )
71 {
72 delete datafile;
73
74 wxString msg = ioe.What();
75
76 msg += wxChar('\n');
77 msg += _("Data file error.");
78
79 wxMessageBox( msg );
80 return false;
81 }
82
86
87 delete datafile;
88
89 return true;
90}
91
92
94{
95 // Switch the locale to standard C (needed to read/write floating point numbers)
96 LOCALE_IO toggle;
97
98 auto datafile = std::make_unique<PCB_CALCULATOR_DATAFILE>( &m_RegulatorList );
99
100 try
101 {
103
104 int nestlevel = datafile->WriteHeader( &formatter );
105
106 datafile->Format( &formatter, nestlevel );
107
108 while( nestlevel-- )
109 formatter.Print( nestlevel, ")\n" );
110 }
111 catch( const IO_ERROR& )
112 {
113 return false;
114 }
115
117 return true;
118}
119
120
122{
123 m_list = aList;
124}
125
126
127static const char* regtype_str[] =
128{
129 "normal", "3terminal"
130};
131
132
134{
135 int nestlevel = 0;
136 aFormatter->Print( nestlevel++, "(datafile\n");
137 aFormatter->Print( nestlevel++, "(version 2)\n" );
138 aFormatter->Print( nestlevel++, "(date %s)\n",
139 aFormatter->Quotew( GetISO8601CurrentDateTime() ).c_str() );
140 aFormatter->Print( nestlevel++, "(tool %s)\n",
141 aFormatter->Quotew( Pgm().App().GetAppName() +
142 wxChar(' ') + GetBuildVersion() ).c_str() );
143
144 return nestlevel;
145}
146
148 int aNestLevel ) const
149{
150 // Write regulators list:
151 aFormatter->Print( aNestLevel++, "(%s\n", getTokenName( T_regulators ) );
152
153 for( REGULATOR_DATA* item : m_list->m_List )
154 {
155 aFormatter->Print( aNestLevel, "(%s %s\n", getTokenName( T_regulator ),
156 aFormatter->Quotew( item->m_Name ).c_str() );
157
158 aFormatter->Print( aNestLevel + 1, "(%s %g)\n", getTokenName( T_reg_vref_min ),
159 item->m_VrefMin );
160 aFormatter->Print( aNestLevel + 1, "(%s %g)\n", getTokenName( T_reg_vref_typ ),
161 item->m_VrefTyp );
162 aFormatter->Print( aNestLevel + 1, "(%s %g)\n", getTokenName( T_reg_vref_max ),
163 item->m_VrefMax );
164
165 if( item->m_Type == 1 )
166 {
167 aFormatter->Print( aNestLevel + 1, "(%s %g)\n", getTokenName( T_reg_iadj_typ ),
168 item->m_IadjTyp );
169 aFormatter->Print( aNestLevel + 1, "(%s %g)\n", getTokenName( T_reg_iadj_max ),
170 item->m_IadjMax );
171 }
172
173 aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_reg_type ),
174 regtype_str[item->m_Type] );
175 aFormatter->Print( aNestLevel, ")\n" );
176 }
177
178 aFormatter->Print( --aNestLevel, ")\n" );
179}
180
181
183{
184 aParser->Parse( this );
185}
186
187
189 PCB_CALCULATOR_DATAFILE_LEXER( aReader )
190{
191}
192
193
195 const wxString& aSource ) :
196 PCB_CALCULATOR_DATAFILE_LEXER( aLine, aSource )
197{
198}
199
200
202{
203 T token;
204
205 while( ( token = NextTok() ) != T_EOF)
206 {
207 if( token == T_LEFT )
208 {
209 token = NextTok();
210
211 if( token == T_regulators )
212 {
213 ParseRegulatorDescr( aDataList );
214 continue;
215 }
216 }
217 }
218}
219
220
222{
223 T token;
224 wxString name;
225 double vrefmin, vreftyp, vrefmax = 0.0;
226 double iadjtyp, iadjmax = 0.0;
227
228 auto parseToken = [&]()
229 {
230 double val;
231 token = NextTok();
232
233 if( token != T_NUMBER )
234 Expecting( T_NUMBER );
235
236 sscanf( CurText(), "%lf", &val );
237 NeedRIGHT();
238 return val;
239 };
240
241 int type;
242
243 while( ( token = NextTok() ) != T_RIGHT )
244 {
245 if( token == T_EOF)
246 Unexpected( T_EOF );
247
248 if( token == T_LEFT )
249 token = NextTok();
250
251 if( token == T_regulator )
252 {
253 type = 0;
254 vrefmin = 0.0;
255 vreftyp = 0.0;
256 vrefmax = 0.0;
257 iadjtyp = 0.0;
258 iadjmax = 0.0;
259
260 // Read name
261 token = NextTok();
262 name = From_UTF8( CurText() );
263
264 while( ( token = NextTok() ) != T_RIGHT )
265 {
266 if( token == T_EOF)
267 Unexpected( T_EOF );
268
269 if( token == T_LEFT )
270 token = NextTok();
271
272 switch( token )
273 {
274 // Parse legacy entry
275 case T_reg_vref:
276 vreftyp = parseToken();
277 vrefmin = vreftyp;
278 vrefmax = vreftyp;
279 break;
280
281 case T_reg_vref_min: vrefmin = parseToken(); break;
282 case T_reg_vref_typ: vreftyp = parseToken(); break;
283 case T_reg_vref_max: vrefmax = parseToken(); break;
284
285 // Parse legacy entry
286 case T_reg_iadj:
287 iadjtyp = parseToken();
288 iadjmax = iadjtyp;
289 break;
290
291 case T_reg_iadj_typ: iadjtyp = parseToken(); break;
292 case T_reg_iadj_max: iadjmax = parseToken(); break;
293
294 case T_reg_type: // type: normal or 3 terminal reg
295 token = NextTok();
296
297 if( strcasecmp( CurText(), regtype_str[0] ) == 0 )
298 type = 0;
299 else if( strcasecmp( CurText(), regtype_str[1] ) == 0 )
300 type = 1;
301 else
302 Unexpected( CurText() );
303
304 NeedRIGHT();
305 break;
306
307 default:
308 Unexpected( CurText() );
309 break;
310 }
311 }
312
313 if( ! name.IsEmpty() )
314 {
315 REGULATOR_DATA* new_item = new REGULATOR_DATA( name, vrefmin, vreftyp, vrefmax,
316 type, iadjtyp, iadjmax );
317 aDataList->m_list->Add( new_item );
318 }
319 }
320 }
321}
const char * name
Definition: DXF_plotter.cpp:57
wxString GetBuildVersion()
Get the full KiCad version string.
A LINE_READER that reads from an open file.
Definition: richio.h:185
Used for text file output.
Definition: richio.h:475
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:93
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:322
std::string Quotew(const wxString &aWrapee) const
Definition: richio.cpp:526
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:458
wxChoice * m_choiceRegulatorSelector
REGULATOR_LIST m_RegulatorList
const wxString GetDataFilename()
void SelectLastSelectedRegulator()
If m_lastSelectedRegulatorName is empty, just calls RegulatorPageUpdate()
Parser for PCB_CALCULATOR_DATAFILE.
PCB_CALCULATOR_DATAFILE_PARSER(LINE_READER *aReader)
void Parse(PCB_CALCULATOR_DATAFILE *aDataList)
void ParseRegulatorDescr(PCB_CALCULATOR_DATAFILE *aDataList)
PCB_CALCULATOR_DATAFILE handles data to calculate regulators parameters.
void Parse(PCB_CALCULATOR_DATAFILE_PARSER *aParser)
void Format(OUTPUTFORMATTER *aFormatter, int aNestLevel) const
int WriteHeader(OUTPUTFORMATTER *aFormatter) const
PCB_CALCULATOR_DATAFILE(REGULATOR_LIST *aList)
wxArrayString GetRegList() const
void Add(REGULATOR_DATA *aItem)
std::vector< REGULATOR_DATA * > m_List
Contains structures for storage of regulator data.
static const char * regtype_str[]
static const char * getTokenName(T aTok)
static const char * getTokenName(T aTok)
#define _(s)
This file contains miscellaneous commonly used macros and functions.
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
see class PGM_BASE
wxString From_UTF8(const char *cstring)
wxString GetISO8601CurrentDateTime()