244 lines
6.7 KiB
C++
244 lines
6.7 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2020 CERN
|
|
*
|
|
* @author Wayne Stambaugh <stambaughw@gmail.com>
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
/**
|
|
* @file sch_sexpr_parser.h
|
|
* @brief Schematic and symbol library s-expression file format parser definitions.
|
|
*/
|
|
|
|
#ifndef __SCH_SEXPR_PARSER_H__
|
|
#define __SCH_SEXPR_PARSER_H__
|
|
|
|
#include <convert_to_biu.h> // IU_PER_MM
|
|
#include <math/util.h> // KiROUND, Clamp
|
|
|
|
#include <class_library.h>
|
|
#include <general.h>
|
|
#include <schematic_lexer.h>
|
|
|
|
|
|
class LIB_ARC;
|
|
class LIB_BEZIER;
|
|
class LIB_CIRCLE;
|
|
class LIB_ITEM;
|
|
class LIB_PIN;
|
|
class LIB_POLYLINE;
|
|
class LIB_TEXT;
|
|
class PAGE_INFO;
|
|
class SCH_BITMAP;
|
|
class SCH_BUS_WIRE_ENTRY;
|
|
class SCH_COMPONENT;
|
|
class SCH_FIELD;
|
|
class SCH_JUNCTION;
|
|
class SCH_LINE;
|
|
class SCH_NO_CONNECT;
|
|
class SCH_SCREEN;
|
|
class SCH_SHEET;
|
|
class SCH_SHEET_PIN;
|
|
class SCH_TEXT;
|
|
class TITLE_BLOCK;
|
|
|
|
|
|
/**
|
|
* Simple container to manage line stroke parameters.
|
|
*/
|
|
class STROKE_PARAMS
|
|
{
|
|
public:
|
|
int m_Width;
|
|
PLOT_DASH_TYPE m_Type;
|
|
COLOR4D m_Color;
|
|
|
|
STROKE_PARAMS( int aWidth = Mils2iu( DEFAULT_LINE_WIDTH ),
|
|
PLOT_DASH_TYPE aType = PLOT_DASH_TYPE::DEFAULT,
|
|
const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) :
|
|
m_Width( aWidth ),
|
|
m_Type( aType ),
|
|
m_Color( aColor )
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
* Simple container to manage fill parameters.
|
|
*/
|
|
class FILL_PARAMS
|
|
{
|
|
public:
|
|
FILL_T m_FillType;
|
|
COLOR4D m_Color;
|
|
};
|
|
|
|
|
|
/**
|
|
* Object to parser s-expression symbol library and schematic file formats.
|
|
*/
|
|
class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
|
|
{
|
|
int m_requiredVersion; ///< Set to the symbol library file version required.
|
|
int m_fieldId; ///< The current field ID.
|
|
int m_unit; ///< The current unit being parsed.
|
|
int m_convert; ///< The current body style being parsed.
|
|
wxString m_symbolName; ///< The current symbol name.
|
|
|
|
void parseHeader( TSCHEMATIC_T::T aHeaderType, int aFileVersion );
|
|
|
|
inline long parseHex()
|
|
{
|
|
NextTok();
|
|
return strtol( CurText(), NULL, 16 );
|
|
}
|
|
|
|
inline int parseInt()
|
|
{
|
|
return (int)strtol( CurText(), NULL, 10 );
|
|
}
|
|
|
|
inline int parseInt( const char* aExpected )
|
|
{
|
|
NeedNUMBER( aExpected );
|
|
return parseInt();
|
|
}
|
|
|
|
/**
|
|
* Parse the current token as an ASCII numeric string with possible leading
|
|
* whitespace into a double precision floating point number.
|
|
*
|
|
* @throw IO_ERROR if an error occurs attempting to convert the current token.
|
|
* @return The result of the parsed token.
|
|
*/
|
|
double parseDouble();
|
|
|
|
inline double parseDouble( const char* aExpected )
|
|
{
|
|
NeedNUMBER( aExpected );
|
|
return parseDouble();
|
|
}
|
|
|
|
inline double parseDouble( TSCHEMATIC_T::T aToken )
|
|
{
|
|
return parseDouble( GetTokenText( aToken ) );
|
|
}
|
|
|
|
inline int parseInternalUnits()
|
|
{
|
|
auto retval = parseDouble() * IU_PER_MM;
|
|
|
|
// Schematic internal units are represented as integers. Any values that are
|
|
// larger or smaller than the schematic units represent undefined behavior for
|
|
// the system. Limit values to the largest that can be displayed on the screen.
|
|
double int_limit = std::numeric_limits<int>::max() * 0.7071; // 0.7071 = roughly 1/sqrt(2)
|
|
|
|
return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
|
|
}
|
|
|
|
inline int parseInternalUnits( const char* aExpected )
|
|
{
|
|
auto retval = parseDouble( aExpected ) * IU_PER_MM;
|
|
|
|
double int_limit = std::numeric_limits<int>::max() * 0.7071;
|
|
|
|
return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
|
|
}
|
|
|
|
inline int parseInternalUnits( TSCHEMATIC_T::T aToken )
|
|
{
|
|
return parseInternalUnits( GetTokenText( aToken ) );
|
|
}
|
|
|
|
inline wxPoint parseXY()
|
|
{
|
|
wxPoint xy;
|
|
|
|
xy.x = parseInternalUnits( "X coordinate" );
|
|
xy.y = parseInternalUnits( "Y coordinate" );
|
|
|
|
return xy;
|
|
}
|
|
|
|
/**
|
|
* Parse stroke definition \a aStroke.
|
|
*
|
|
* @param aStrokeDef A reference to the #STROKE_PARAMS structure to write to.
|
|
*/
|
|
void parseStroke( STROKE_PARAMS& aStroke );
|
|
|
|
void parseFill( FILL_PARAMS& aFill );
|
|
|
|
void parseEDA_TEXT( EDA_TEXT* aText );
|
|
void parsePinNames( std::unique_ptr<LIB_PART>& aSymbol );
|
|
|
|
void parseProperty( std::unique_ptr<LIB_PART>& aSymbol );
|
|
|
|
LIB_ARC* parseArc();
|
|
LIB_BEZIER* parseBezier();
|
|
LIB_CIRCLE* parseCircle();
|
|
LIB_PIN* parsePin();
|
|
LIB_POLYLINE* parsePolyLine();
|
|
LIB_RECTANGLE* parseRectangle();
|
|
LIB_TEXT* parseText();
|
|
|
|
void parsePAGE_INFO( PAGE_INFO& aPageInfo );
|
|
void parseTITLE_BLOCK( TITLE_BLOCK& aTitleBlock );
|
|
void parseSchSymbolInstances( std::unique_ptr<SCH_COMPONENT>& aSymbol );
|
|
|
|
SCH_SHEET_PIN* parseSchSheetPin( SCH_SHEET* aSheet );
|
|
SCH_FIELD* parseSchField();
|
|
SCH_COMPONENT* parseSchematicSymbol();
|
|
SCH_BITMAP* parseImage();
|
|
SCH_SHEET* parseSheet();
|
|
SCH_JUNCTION* parseJunction();
|
|
SCH_NO_CONNECT* parseNoConnect();
|
|
SCH_BUS_WIRE_ENTRY* parseBusEntry();
|
|
SCH_LINE* parseLine();
|
|
SCH_TEXT* parseSchText();
|
|
|
|
public:
|
|
SCH_SEXPR_PARSER( LINE_READER* aLineReader = nullptr );
|
|
|
|
void ParseLib( LIB_PART_MAP& aSymbolLibMap );
|
|
|
|
LIB_PART* ParseSymbol( LIB_PART_MAP& aSymbolLibMap );
|
|
|
|
LIB_ITEM* ParseDrawItem();
|
|
|
|
/**
|
|
* Parse a single schematic file into \a aScreen.
|
|
*
|
|
* @note This does not load any sub-sheets or decent complex sheet hierarchies.
|
|
*
|
|
* @param aScreen The #SCH_SCREEN object to store the parsed schematic file.
|
|
*/
|
|
void ParseSchematic( SCH_SCREEN* aScreen );
|
|
|
|
/**
|
|
* Return whether a version number, if any was parsed, was too recent
|
|
*/
|
|
bool IsTooRecent() const;
|
|
};
|
|
|
|
#endif // __SCH_SEXPR_PARSER_H__
|