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 The 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 <fmt/format.h>
26
27#include <wx/app.h>
28#include <wx/msgdlg.h>
29
30#include <build_version.h>
33#include <datafile_read_write.h>
34#include <string_utils.h>
35#include <macros.h>
36#include <pcb_calculator_datafile_lexer.h>
38#include <pgm_base.h>
39
40
41using namespace PCBCALC_DATA_T;
42
43
44static const char* getTokenName( T aTok )
45{
46 return PCB_CALCULATOR_DATAFILE_LEXER::TokenName( aTok );
47}
48
49
51{
52 FILE* file = wxFopen( GetDataFilename(), wxT( "rt" ) );
53
54 if( file == nullptr )
55 return false;
56
58
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
85
86 delete datafile;
87
88 return true;
89}
90
91
93{
94 auto datafile = std::make_unique<PCB_CALCULATOR_DATAFILE>( &m_RegulatorList );
95
96 try
97 {
99
100 int nestlevel = datafile->WriteHeader( &formatter );
101
102 datafile->Format( &formatter, nestlevel );
103
104 while( nestlevel-- )
105 formatter.Print( nestlevel, ")\n" );
106 }
107 catch( const IO_ERROR& )
108 {
109 return false;
110 }
111
113 return true;
114}
115
116
118{
119 m_list = aList;
120}
121
122
123static const char* regtype_str[] =
124{
125 "normal", "3terminal"
126};
127
128
130{
131 int nestlevel = 0;
132 aFormatter->Print( nestlevel++, "(datafile\n");
133 aFormatter->Print( nestlevel++, "(version 2)\n" );
134 aFormatter->Print( nestlevel++, "(date %s)\n",
135 aFormatter->Quotew( GetISO8601CurrentDateTime() ).c_str() );
136 aFormatter->Print( nestlevel++, "(tool %s)\n",
137 aFormatter->Quotew( Pgm().App().GetAppName() +
138 wxChar(' ') + GetBuildVersion() ).c_str() );
139
140 return nestlevel;
141}
142
144 int aNestLevel ) const
145{
146 // Write regulators list:
147 aFormatter->Print( aNestLevel++, "(%s\n", getTokenName( T_regulators ) );
148
149 for( REGULATOR_DATA* item : m_list->m_List )
150 {
151 aFormatter->Print( aNestLevel, "(%s %s\n", getTokenName( T_regulator ),
152 aFormatter->Quotew( item->m_Name ).c_str() );
153
154 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_vref_min ),
155 item->m_VrefMin ).c_str() );
156 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_vref_typ ),
157 item->m_VrefTyp ).c_str() );
158 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_vref_max ),
159 item->m_VrefMax ).c_str() );
160
161 if( item->m_Type == 1 )
162 {
163 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_iadj_typ ),
164 item->m_IadjTyp ).c_str() );
165 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_iadj_max ),
166 item->m_IadjMax ).c_str() );
167 }
168
169 aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_reg_type ),
170 regtype_str[item->m_Type] );
171 aFormatter->Print( aNestLevel, ")\n" );
172 }
173
174 aFormatter->Print( --aNestLevel, ")\n" );
175}
176
177
179{
180 aParser->Parse( this );
181}
182
183
185 PCB_CALCULATOR_DATAFILE_LEXER( aReader )
186{
187}
188
189
191 const wxString& aSource ) :
192 PCB_CALCULATOR_DATAFILE_LEXER( aLine, aSource )
193{
194}
195
196
198{
199 T token;
200
201 while( ( token = NextTok() ) != T_EOF)
202 {
203 if( token == T_LEFT )
204 {
205 token = NextTok();
206
207 if( token == T_regulators )
208 {
209 ParseRegulatorDescr( aDataList );
210 continue;
211 }
212 }
213 }
214}
215
216
218{
219 T token;
220 wxString name;
221 double vrefmin, vreftyp, vrefmax = 0.0;
222 double iadjtyp, iadjmax = 0.0;
223
224 auto parseToken = [&]()
225 {
226 double val;
227 token = NextTok();
228
229 if( token != T_NUMBER )
230 Expecting( T_NUMBER );
231
232 wxString text = CurText();
233 text.Trim( true ).Trim( false );
234
235 text.ToCDouble( &val );
236 NeedRIGHT();
237 return val;
238 };
239
240 int type;
241
242 while( ( token = NextTok() ) != T_RIGHT )
243 {
244 if( token == T_EOF)
245 Unexpected( T_EOF );
246
247 if( token == T_LEFT )
248 token = NextTok();
249
250 if( token == T_regulator )
251 {
252 type = 0;
253 vrefmin = 0.0;
254 vreftyp = 0.0;
255 vrefmax = 0.0;
256 iadjtyp = 0.0;
257 iadjmax = 0.0;
258
259 // Read name
260 token = NextTok();
261 name = From_UTF8( CurText() );
262
263 while( ( token = NextTok() ) != T_RIGHT )
264 {
265 if( token == T_EOF)
266 Unexpected( T_EOF );
267
268 if( token == T_LEFT )
269 token = NextTok();
270
271 switch( token )
272 {
273 // Parse legacy entry
274 case T_reg_vref:
275 vreftyp = parseToken();
276 vrefmin = vreftyp;
277 vrefmax = vreftyp;
278 break;
279
280 case T_reg_vref_min: vrefmin = parseToken(); break;
281 case T_reg_vref_typ: vreftyp = parseToken(); break;
282 case T_reg_vref_max: vrefmax = parseToken(); break;
283
284 // Parse legacy entry
285 case T_reg_iadj:
286 iadjtyp = parseToken();
287 iadjmax = iadjtyp;
288 break;
289
290 case T_reg_iadj_typ: iadjtyp = parseToken(); break;
291 case T_reg_iadj_max: iadjmax = parseToken(); break;
292
293 case T_reg_type: // type: normal or 3 terminal reg
294 token = NextTok();
295
296 if( strcasecmp( CurText(), regtype_str[0] ) == 0 )
297 type = 0;
298 else if( strcasecmp( CurText(), regtype_str[1] ) == 0 )
299 type = 1;
300 else
301 Unexpected( CurText() );
302
303 NeedRIGHT();
304 break;
305
306 default:
307 Unexpected( CurText() );
308 break;
309 }
310 }
311
312 if( ! name.IsEmpty() )
313 {
314 REGULATOR_DATA* new_item = new REGULATOR_DATA( name, vrefmin, vreftyp, vrefmax,
315 type, iadjtyp, iadjmax );
316 aDataList->m_list->Add( new_item );
317 }
318 }
319 }
320}
const char * name
Definition: DXF_plotter.cpp:62
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:491
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
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:548
int PRINTF_FUNC_N Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:463
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:893
see class PGM_BASE
wxString From_UTF8(const char *cstring)
wxString GetISO8601CurrentDateTime()