KiCad PCB EDA Suite
Loading...
Searching...
No Matches
datafile_read_write.cpp
Go to the documentation of this file.
1
4
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
57 m_RegulatorList.Clear();
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
83 m_choiceRegulatorSelector->Append( m_RegulatorList.GetRegList() );
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 formatter.Finish();
108 }
109 catch( const IO_ERROR& )
110 {
111 return false;
112 }
113
115 return true;
116}
117
118
123
124
125static const char* regtype_str[] =
126{
127 "normal", "3terminal"
128};
129
130
132{
133 int nestlevel = 0;
134 aFormatter->Print( nestlevel++, "(datafile\n");
135 aFormatter->Print( nestlevel++, "(version 2)\n" );
136 aFormatter->Print( nestlevel++, "(date %s)\n",
137 aFormatter->Quotew( GetISO8601CurrentDateTime() ).c_str() );
138 aFormatter->Print( nestlevel++, "(tool %s)\n",
139 aFormatter->Quotew( Pgm().App().GetAppName() +
140 wxChar(' ') + GetBuildVersion() ).c_str() );
141
142 return nestlevel;
143}
144
146 int aNestLevel ) const
147{
148 // Write regulators list:
149 aFormatter->Print( aNestLevel++, "(%s\n", getTokenName( T_regulators ) );
150
151 for( REGULATOR_DATA* item : m_list->m_List )
152 {
153 aFormatter->Print( aNestLevel, "(%s %s\n", getTokenName( T_regulator ),
154 aFormatter->Quotew( item->m_Name ).c_str() );
155
156 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_vref_min ),
157 item->m_VrefMin ).c_str() );
158 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_vref_typ ),
159 item->m_VrefTyp ).c_str() );
160 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_vref_max ),
161 item->m_VrefMax ).c_str() );
162
163 if( item->m_Type == 1 )
164 {
165 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_iadj_typ ),
166 item->m_IadjTyp ).c_str() );
167 aFormatter->Print( aNestLevel + 1, "%s", fmt::format( "({} {:g})\n", getTokenName( T_reg_iadj_max ),
168 item->m_IadjMax ).c_str() );
169 }
170
171 aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_reg_type ),
172 regtype_str[item->m_Type] );
173 aFormatter->Print( aNestLevel, ")\n" );
174 }
175
176 aFormatter->Print( --aNestLevel, ")\n" );
177}
178
179
181{
182 aParser->Parse( this );
183}
184
185
187 PCB_CALCULATOR_DATAFILE_LEXER( aReader )
188{
189}
190
191
193 const wxString& aSource ) :
194 PCB_CALCULATOR_DATAFILE_LEXER( aLine, aSource )
195{
196}
197
198
200{
201 T token;
202
203 while( ( token = NextTok() ) != T_EOF)
204 {
205 if( token == T_LEFT )
206 {
207 token = NextTok();
208
209 if( token == T_regulators )
210 {
211 ParseRegulatorDescr( aDataList );
212 continue;
213 }
214 }
215 }
216}
217
218
220{
221 T token;
222 wxString name;
223 double vrefmin, vreftyp, vrefmax = 0.0;
224 double iadjtyp, iadjmax = 0.0;
225
226 auto parseToken = [&]()
227 {
228 double val;
229 token = NextTok();
230
231 if( token != T_NUMBER )
232 Expecting( T_NUMBER );
233
234 wxString text = CurText();
235 text.Trim( true ).Trim( false );
236
237 text.ToCDouble( &val );
238 NeedRIGHT();
239 return val;
240 };
241
242 int type;
243
244 while( ( token = NextTok() ) != T_RIGHT )
245 {
246 if( token == T_EOF)
247 Unexpected( T_EOF );
248
249 if( token == T_LEFT )
250 token = NextTok();
251
252 if( token == T_regulator )
253 {
254 type = 0;
255 vrefmin = 0.0;
256 vreftyp = 0.0;
257 vrefmax = 0.0;
258 iadjtyp = 0.0;
259 iadjmax = 0.0;
260
261 // Read name
262 token = NextTok();
263 name = From_UTF8( CurText() );
264
265 while( ( token = NextTok() ) != T_RIGHT )
266 {
267 if( token == T_EOF)
268 Unexpected( T_EOF );
269
270 if( token == T_LEFT )
271 token = NextTok();
272
273 switch( token )
274 {
275 // Parse legacy entry
276 case T_reg_vref:
277 vreftyp = parseToken();
278 vrefmin = vreftyp;
279 vrefmax = vreftyp;
280 break;
281
282 case T_reg_vref_min: vrefmin = parseToken(); break;
283 case T_reg_vref_typ: vreftyp = parseToken(); break;
284 case T_reg_vref_max: vrefmax = parseToken(); break;
285
286 // Parse legacy entry
287 case T_reg_iadj:
288 iadjtyp = parseToken();
289 iadjmax = iadjtyp;
290 break;
291
292 case T_reg_iadj_typ: iadjtyp = parseToken(); break;
293 case T_reg_iadj_max: iadjmax = parseToken(); break;
294
295 case T_reg_type: // type: normal or 3 terminal reg
296 token = NextTok();
297
298 if( strcasecmp( CurText(), regtype_str[0] ) == 0 )
299 type = 0;
300 else if( strcasecmp( CurText(), regtype_str[1] ) == 0 )
301 type = 1;
302 else
303 Unexpected( CurText() );
304
305 NeedRIGHT();
306 break;
307
308 default:
309 Unexpected( CurText() );
310 break;
311 }
312 }
313
314 if( ! name.IsEmpty() )
315 {
316 REGULATOR_DATA* new_item = new REGULATOR_DATA( name, vrefmin, vreftyp, vrefmax,
317 type, iadjtyp, iadjmax );
318 aDataList->m_list->Add( new_item );
319 }
320 }
321 }
322}
const char * name
wxString GetBuildVersion()
Get the full KiCad version string.
A LINE_READER that reads from an open file.
Definition richio.h:158
Used for text file output.
Definition richio.h:474
bool Finish() override
Flushes the temp file to disk and atomically renames it over the final target path.
Definition richio.cpp:646
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition richio.h:66
An interface used to output 8 bit text in a convenient way.
Definition richio.h:295
std::string Quotew(const wxString &aWrapee) const
Definition richio.cpp:511
int PRINTF_FUNC_N Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition richio.cpp:426
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
friend class PCB_CALCULATOR_DATAFILE_PARSER
int WriteHeader(OUTPUTFORMATTER *aFormatter) const
PCB_CALCULATOR_DATAFILE(REGULATOR_LIST *aList)
void Add(REGULATOR_DATA *aItem)
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.
see class PGM_BASE
wxString From_UTF8(const char *cstring)
wxString GetISO8601CurrentDateTime()