mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-15 02:33:15 +02:00
This required the additional compiler command line option "-std=c++0x". 2) Switch to unique_ptr from auto_ptr which is C++ deprecated. 3) Change to new English layer names per mailing list discussion, see class_board.cpp. 4) When saving to *.kicad_pcb or *.kicad_mod, identify opportunities to use wildcard layer sets, for pads so far. 5) Switch to two std::string hashtables in pcb_parser.cpp, away from one wxString based one for layer names and layer sets mapping. One hashtable holds the mask, the other the index. Layer sets are only in the mask table. 6) Move "LOCALE_IO toggle" into PCB_IO::Format() since it is a public API function and caller should find it as convenient as possible to use. LOCALE_IO should handle nesting OK in the case where public Format() is called from one of the Footprint*() functions. 7) Drop support for "export module to new library". Creating new libraries will have to be handled in concert with library table entries, and we've talked recently about creating a better footprint library manager, one that resides in a DLL/DSO. So this kind of functionality needs to be handled in there in the near future. 8) Change name of exported PCB_IO module/footprint to *.kicad_mod and not *.emp.
280 lines
7.9 KiB
C++
280 lines
7.9 KiB
C++
/**
|
|
* @file datafile_read_write.cpp
|
|
*/
|
|
|
|
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2012 Jean-Pierre Charras
|
|
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, you may find one here:
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <macros.h>
|
|
#include <common.h>
|
|
#include <kicad_string.h>
|
|
#include <appl_wxstruct.h>
|
|
#include <pcb_calculator.h>
|
|
#include <pcb_calculator_datafile_lexer.h>
|
|
#include <class_regulator_data.h>
|
|
#include <datafile_read_write.h>
|
|
#include <build_version.h>
|
|
|
|
|
|
using namespace PCBCALC_DATA_T;
|
|
|
|
|
|
static const char* getTokenName( T aTok )
|
|
{
|
|
return PCB_CALCULATOR_DATAFILE_LEXER::TokenName( aTok );
|
|
}
|
|
|
|
|
|
bool PCB_CALCULATOR_FRAME::ReadDataFile()
|
|
{
|
|
FILE* file = wxFopen( GetDataFilename(), wxT( "rt" ) );
|
|
|
|
if( file == NULL )
|
|
return false;
|
|
|
|
// Switch the locale to standard C (needed to read/write floating point numbers
|
|
LOCALE_IO toggle;
|
|
|
|
PCB_CALCULATOR_DATAFILE * datafile = new PCB_CALCULATOR_DATAFILE( &m_RegulatorList );
|
|
|
|
// dataReader dtor will close file
|
|
FILE_LINE_READER dataReader( file, GetDataFilename() );
|
|
PCB_CALCULATOR_DATAFILE_PARSER datafile_parser( &dataReader );
|
|
|
|
try
|
|
{
|
|
datafile_parser.Parse( datafile );
|
|
}
|
|
catch( IO_ERROR& ioe )
|
|
{
|
|
delete datafile;
|
|
ioe.errorText += '\n';
|
|
ioe.errorText += _("Data file error.");
|
|
|
|
wxMessageBox( ioe.errorText );
|
|
return false;
|
|
}
|
|
|
|
delete datafile;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool PCB_CALCULATOR_FRAME::WriteDataFile()
|
|
{
|
|
// Switch the locale to standard C (needed to read/write floating point numbers
|
|
LOCALE_IO toggle;
|
|
|
|
std::unique_ptr<PCB_CALCULATOR_DATAFILE> datafile( new PCB_CALCULATOR_DATAFILE( &m_RegulatorList ) );
|
|
|
|
try
|
|
{
|
|
FILE_OUTPUTFORMATTER formatter( GetDataFilename() );
|
|
|
|
int nestlevel = datafile->WriteHeader( &formatter );
|
|
|
|
datafile->Format( &formatter, nestlevel );
|
|
|
|
while( nestlevel-- )
|
|
formatter.Print( nestlevel, ")\n" );
|
|
}
|
|
catch( IO_ERROR ioe )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_RegulatorListChanged = false;
|
|
return true;
|
|
}
|
|
|
|
|
|
PCB_CALCULATOR_DATAFILE::PCB_CALCULATOR_DATAFILE( REGULATOR_LIST * aList )
|
|
{
|
|
m_list = aList;
|
|
}
|
|
|
|
static const char* regtype_str[] =
|
|
{
|
|
"normal", "3terminal"
|
|
};
|
|
|
|
int PCB_CALCULATOR_DATAFILE::WriteHeader( OUTPUTFORMATTER* aFormatter ) const throw( IO_ERROR )
|
|
{
|
|
int nestlevel = 0;
|
|
aFormatter->Print( nestlevel++, "(datafile\n");
|
|
aFormatter->Print( nestlevel++, "(version 1)\n" );
|
|
aFormatter->Print( nestlevel++, "(date %s)\n",
|
|
aFormatter->Quotew( DateAndTime() ).c_str() );
|
|
aFormatter->Print( nestlevel++, "(tool %s)\n",
|
|
aFormatter->Quotew( wxGetApp().GetAppName() +
|
|
wxChar(' ') + GetBuildVersion() ).c_str() );
|
|
|
|
return nestlevel;
|
|
}
|
|
|
|
void PCB_CALCULATOR_DATAFILE::Format( OUTPUTFORMATTER* aFormatter,
|
|
int aNestLevel ) const throw( IO_ERROR )
|
|
{
|
|
// Write regulators list:
|
|
aFormatter->Print( aNestLevel++, "(%s\n", getTokenName( T_regulators ) );
|
|
for( unsigned ii = 0; ii < m_list->m_List.size(); ii++ )
|
|
{
|
|
REGULATOR_DATA * item = m_list->m_List[ii];
|
|
aFormatter->Print( aNestLevel, "(%s %s\n", getTokenName( T_regulator ),
|
|
aFormatter->Quotew(item->m_Name ).c_str() );
|
|
aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_vref ),
|
|
item->m_Vref );
|
|
if( item->m_Iadj != 0 && item->m_Type == 1)
|
|
{
|
|
aFormatter->Print( aNestLevel+1, "(%s %g)\n", getTokenName( T_reg_iadj ),
|
|
item->m_Iadj );
|
|
}
|
|
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_reg_type ),
|
|
regtype_str[item->m_Type] );
|
|
aFormatter->Print( aNestLevel, ")\n" );
|
|
}
|
|
aFormatter->Print( --aNestLevel, ")\n" );
|
|
}
|
|
|
|
|
|
void PCB_CALCULATOR_DATAFILE::Parse( PCB_CALCULATOR_DATAFILE_PARSER* aParser )
|
|
throw( IO_ERROR, PARSE_ERROR )
|
|
{
|
|
aParser->Parse( this );
|
|
}
|
|
|
|
|
|
|
|
// PCB_CALCULATOR_DATAFILE_PARSER
|
|
|
|
PCB_CALCULATOR_DATAFILE_PARSER::PCB_CALCULATOR_DATAFILE_PARSER( LINE_READER* aReader ) :
|
|
PCB_CALCULATOR_DATAFILE_LEXER( aReader )
|
|
{
|
|
}
|
|
|
|
|
|
PCB_CALCULATOR_DATAFILE_PARSER::PCB_CALCULATOR_DATAFILE_PARSER( char* aLine, wxString aSource ) :
|
|
PCB_CALCULATOR_DATAFILE_LEXER( aLine, aSource )
|
|
{
|
|
}
|
|
|
|
|
|
void PCB_CALCULATOR_DATAFILE_PARSER::Parse( PCB_CALCULATOR_DATAFILE* aDataList ) throw( IO_ERROR, PARSE_ERROR )
|
|
{
|
|
T token;
|
|
while( ( token = NextTok() ) != T_EOF)
|
|
{
|
|
|
|
if( token == T_LEFT )
|
|
{
|
|
token = NextTok();
|
|
|
|
if( token == T_regulators )
|
|
{
|
|
ParseRegulatorDescr( aDataList );
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void PCB_CALCULATOR_DATAFILE_PARSER::ParseRegulatorDescr( PCB_CALCULATOR_DATAFILE* aDataList )
|
|
throw( IO_ERROR, PARSE_ERROR )
|
|
{
|
|
T token;
|
|
wxString name;
|
|
double vref, iadj;
|
|
int type;
|
|
|
|
while( ( token = NextTok() ) != T_RIGHT )
|
|
{
|
|
if( token == T_EOF)
|
|
Unexpected( T_EOF );
|
|
|
|
if( token == T_LEFT )
|
|
token = NextTok();
|
|
|
|
if( token == T_regulator )
|
|
{
|
|
type = 0;
|
|
vref = 0.0;
|
|
|
|
// Read name
|
|
token = NextTok();
|
|
name = FROM_UTF8( CurText() );
|
|
|
|
while( ( token = NextTok() ) != T_RIGHT )
|
|
{
|
|
if( token == T_EOF)
|
|
Unexpected( T_EOF );
|
|
|
|
if( token == T_LEFT )
|
|
token = NextTok();
|
|
|
|
switch( token )
|
|
{
|
|
case T_reg_vref: // the voltage reference value
|
|
token = NextTok();
|
|
if( token != T_NUMBER )
|
|
Expecting( T_NUMBER );
|
|
sscanf( CurText(), "%lf" , &vref);
|
|
NeedRIGHT();
|
|
break;
|
|
|
|
case T_reg_iadj: // the Iadj reference value
|
|
token = NextTok();
|
|
if( token != T_NUMBER )
|
|
Expecting( T_NUMBER );
|
|
sscanf( CurText(), "%lf" , &iadj);
|
|
NeedRIGHT();
|
|
break;
|
|
|
|
case T_reg_type: // type: normal or 3 terminal reg
|
|
token = NextTok();
|
|
if( stricmp( CurText(), regtype_str[0] ) == 0 )
|
|
type = 0;
|
|
else if( stricmp( CurText(), regtype_str[1] ) == 0 )
|
|
type = 1;
|
|
else
|
|
Unexpected( CurText() );
|
|
NeedRIGHT();
|
|
break;
|
|
|
|
default:
|
|
Unexpected( CurText() );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ! name.IsEmpty() )
|
|
{
|
|
if( type != 1 )
|
|
iadj = 0.0;
|
|
REGULATOR_DATA * new_item = new REGULATOR_DATA(name, vref, type, iadj );
|
|
aDataList->m_list->Add( new_item );
|
|
}
|
|
}
|
|
}
|
|
}
|