kicad/eeschema/sch_plugins/cadstar/cadstar_sch_archive_parser.cpp

1280 lines
38 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020-2021 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.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 3 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, see <http://www.gnu.org/licenses/>.
*/
/**
* @file cadstar_sch_archive_parser.cpp
* @brief Reads in a CADSTAR Schematic Archive (*.csa) file
*/
#include <base_units.h>
#include <macros.h>
#include <sch_plugins/cadstar/cadstar_sch_archive_parser.h>
#include <progress_reporter.h>
#include <wx/translation.h>
void CADSTAR_SCH_ARCHIVE_PARSER::Parse()
{
if( m_progressReporter )
m_progressReporter->BeginPhase( 0 ); // Read file
m_rootNode = LoadArchiveFile( Filename, wxT( "CADSTARSCM" ), m_progressReporter );
if( m_progressReporter )
{
m_progressReporter->BeginPhase( 1 ); // Parse File
std::vector<wxString> subNodeChildrenToCount = { wxT( "LIBRARY" ), wxT( "PARTS" ),
wxT( "SCHEMATIC" ) };
long numOfSteps = GetNumberOfStepsForReporting( m_rootNode, subNodeChildrenToCount );
m_progressReporter->SetMaxProgress( numOfSteps );
}
m_context.CheckPointCallback = [&](){ checkPoint(); };
XNODE* cNode = m_rootNode->GetChildren();
if( !cNode )
THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARSCM" ) );
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "HEADER" ) )
{
Header.Parse( cNode, &m_context );
switch( Header.Resolution )
{
case RESOLUTION::HUNDREDTH_MICRON:
KiCadUnitDivider = (long) 1e5 / (long) SCH_IU_PER_MM;
break;
default:
wxASSERT_MSG( true, wxT( "Unknown File Resolution" ) );
break;
}
}
else if( cNode->GetName() == wxT( "ASSIGNMENTS" ) )
{
Assignments.Parse( cNode, &m_context );
}
else if( cNode->GetName() == wxT( "LIBRARY" ) )
{
Library.Parse( cNode, &m_context );
}
else if( cNode->GetName() == wxT( "DEFAULTS" ) )
{
// No design information here (no need to parse)
// Only contains CADSTAR configuration data such as default shapes, text and units
// In future some of this could be converted to KiCad but limited value
}
else if( cNode->GetName() == wxT( "PARTS" ) )
{
Parts.Parse( cNode, &m_context );
}
else if( cNode->GetName() == wxT( "SHEETS" ) )
{
Sheets.Parse( cNode, &m_context );
}
else if( cNode->GetName() == wxT( "SCHEMATIC" ) )
{
Schematic.Parse( cNode, &m_context );
}
else if( cNode->GetName() == wxT( "DISPLAY" ) )
{
// For now only interested in Attribute visibilities, in order to set field visibilities
// in the imported design
XNODE* subNode = cNode->GetChildren();
for( ; subNode; subNode = subNode->GetNext() )
{
if( subNode->GetName() == wxT( "ATTRCOLORS" ) )
{
AttrColors.Parse( subNode, &m_context );
}
else if( subNode->GetName() == wxT( "SCMITEMCOLORS" ) )
{
XNODE* sub2Node = subNode->GetChildren();
for( ; sub2Node; sub2Node = sub2Node->GetNext() )
{
if( sub2Node->GetName() == wxT( "SYMCOL" ) )
{
XNODE* sub3Node = sub2Node->GetChildren();
for( ; sub3Node; sub3Node = sub3Node->GetNext() )
{
if( sub3Node->GetName() == wxT( "PARTNAMECOL" ) )
SymbolPartNameColor.Parse( sub3Node, &m_context );
}
}
}
}
else
{
// No design information here
// Contains CADSTAR Display settings such as layer/element colours and visibility.
// In the future these settings could be converted to KiCad
}
}
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), wxT( "[root]" ) );
}
checkPoint();
}
delete m_rootNode;
m_rootNode = nullptr;
}
CADSTAR_SCH_ARCHIVE_PARSER::TERMINAL_SHAPE_TYPE CADSTAR_SCH_ARCHIVE_PARSER::ParseTermShapeType(
const wxString& aShapeStr )
{
if( aShapeStr == wxT( "ANNULUS" ) )
return TERMINAL_SHAPE_TYPE::ANNULUS;
else if( aShapeStr == wxT( "BOX" ) )
return TERMINAL_SHAPE_TYPE::BOX;
else if( aShapeStr == wxT( "BULLET" ) )
return TERMINAL_SHAPE_TYPE::BULLET;
else if( aShapeStr == wxT( "ROUND" ) )
return TERMINAL_SHAPE_TYPE::CIRCLE;
else if( aShapeStr == wxT( "CROSS" ) )
return TERMINAL_SHAPE_TYPE::CROSS;
else if( aShapeStr == wxT( "DIAMOND" ) )
return TERMINAL_SHAPE_TYPE::DIAMOND;
else if( aShapeStr == wxT( "FINGER" ) )
return TERMINAL_SHAPE_TYPE::FINGER;
else if( aShapeStr == wxT( "OCTAGON" ) )
return TERMINAL_SHAPE_TYPE::OCTAGON;
else if( aShapeStr == wxT( "PLUS" ) )
return TERMINAL_SHAPE_TYPE::PLUS;
else if( aShapeStr == wxT( "POINTER" ) )
return TERMINAL_SHAPE_TYPE::POINTER;
else if( aShapeStr == wxT( "RECTANGLE" ) )
return TERMINAL_SHAPE_TYPE::RECTANGLE;
else if( aShapeStr == wxT( "ROUNDED" ) )
return TERMINAL_SHAPE_TYPE::ROUNDED_RECT;
else if( aShapeStr == wxT( "SQUARE" ) )
return TERMINAL_SHAPE_TYPE::SQUARE;
else if( aShapeStr == wxT( "STAR" ) )
return TERMINAL_SHAPE_TYPE::STAR;
else if( aShapeStr == wxT( "TRIANGLE" ) )
return TERMINAL_SHAPE_TYPE::TRIANGLE;
else
return TERMINAL_SHAPE_TYPE::UNDEFINED;
}
bool CADSTAR_SCH_ARCHIVE_PARSER::TERMINAL_SHAPE::IsTermShape( XNODE* aNode )
{
return ParseTermShapeType( aNode->GetName() ) != TERMINAL_SHAPE_TYPE::UNDEFINED;
}
void CADSTAR_SCH_ARCHIVE_PARSER::TERMINAL_SHAPE::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( IsTermShape( aNode ), );
ShapeType = ParseTermShapeType( aNode->GetName() );
Size = GetXmlAttributeIDLong( aNode, 0 );
switch( ShapeType )
{
case TERMINAL_SHAPE_TYPE::ANNULUS:
case TERMINAL_SHAPE_TYPE::BOX:
case TERMINAL_SHAPE_TYPE::CROSS:
case TERMINAL_SHAPE_TYPE::PLUS:
case TERMINAL_SHAPE_TYPE::STAR:
InternalFeature = GetXmlAttributeIDLong( aNode, 1 );
break;
case TERMINAL_SHAPE_TYPE::ROUNDED_RECT:
InternalFeature = GetXmlAttributeIDLong( aNode, 3 );
KI_FALLTHROUGH;
case TERMINAL_SHAPE_TYPE::BULLET:
case TERMINAL_SHAPE_TYPE::FINGER:
case TERMINAL_SHAPE_TYPE::POINTER:
case TERMINAL_SHAPE_TYPE::RECTANGLE:
case TERMINAL_SHAPE_TYPE::TRIANGLE:
RightLength = GetXmlAttributeIDLong( aNode, 2, false ); // Optional
LeftLength = GetXmlAttributeIDLong( aNode, 1 );
break;
case TERMINAL_SHAPE_TYPE::CIRCLE:
case TERMINAL_SHAPE_TYPE::DIAMOND:
case TERMINAL_SHAPE_TYPE::OCTAGON:
case TERMINAL_SHAPE_TYPE::SQUARE:
//don't do anything
break;
case TERMINAL_SHAPE_TYPE::UNDEFINED:
wxASSERT_MSG( false, "Unknown terminal shape type" );
break;
}
if( aNode->GetChildren() )
{
if( aNode->GetChildren()->GetName() == wxT( "ORIENT" ) )
{
OrientAngle = GetXmlAttributeIDLong( aNode->GetChildren(), 0 );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( aNode->GetChildren()->GetName(), aNode->GetName() );
}
CheckNoNextNodes( aNode->GetChildren() );
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::TERMINALCODE::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "TERMINALCODE" ), );
ID = GetXmlAttributeIDString( aNode, 0 );
Name = GetXmlAttributeIDString( aNode, 1 );
XNODE* cNode = aNode->GetChildren();
wxString location = wxString::Format( "TERMINALCODE -> %s", Name );
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( TERMINAL_SHAPE::IsTermShape( cNode ) )
Shape.Parse( cNode, aContext );
else if( cNodeName == wxT( "FILLED" ) )
Filled = true;
else
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::CODEDEFS_SCM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "CODEDEFS" ), );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString nodeName = cNode->GetName();
if( ParseSubNode( cNode, aContext ) ) // in CADSTAR_ARCHIVE_PARSER::CODEDEFS
{
continue;
}
else if( nodeName == wxT( "TERMINALCODE" ) )
{
TERMINALCODE termcode;
termcode.Parse( cNode, aContext );
TerminalCodes.insert( std::make_pair( termcode.ID, termcode ) );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( nodeName, aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::ASSIGNMENTS_SCM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "ASSIGNMENTS" ), );
XNODE* cNode = aNode->GetChildren();
bool settingsParsed = false;
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "CODEDEFS" ) )
{
Codedefs.Parse( cNode, aContext );
}
else if( cNode->GetName() == wxT( "SETTINGS" ) )
{
settingsParsed = true;
Settings.Parse( cNode, aContext );
}
else if( cNode->GetName() == wxT( "GRIDS" ) )
{
Grids.Parse( cNode, aContext );
}
else if( cNode->GetName() == wxT( "NETCLASSEDITATTRIBSETTINGS" ) )
{
NetclassEditAttributeSettings = true;
}
else if( cNode->GetName() == wxT( "SPCCLASSEDITATTRIBSETTINGS" ) )
{
SpacingclassEditAttributeSettings = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
if( !settingsParsed )
THROW_MISSING_NODE_IO_ERROR( wxT( "SETTINGS" ), wxT( "ASSIGNMENTS" ) );
}
void CADSTAR_SCH_ARCHIVE_PARSER::TERMINAL::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "TERMINAL" ), );
ID = GetXmlAttributeIDLong( aNode, 0 );
TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
XNODE* cNode = aNode->GetChildren();
wxString location = wxString::Format( "TERMINAL %ld", ID );
if( !cNode )
THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), location );
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "ORIENT" ) )
OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
else if( cNodeName == wxT( "PT" ) )
Position.Parse( cNode, aContext );
else
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::PIN_NUM_LABEL_LOC::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "PINLABELLOC" )
|| aNode->GetName() == wxT( "PINNUMNAMELOC" ), );
TerminalID = GetXmlAttributeIDLong( aNode, 0 );
TextCodeID = GetXmlAttributeIDString( aNode, 1 );
//Parse child nodes
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( ParseSubNode( cNode, aContext ) )
continue;
else
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
if( Position.x == UNDEFINED_VALUE || Position.y == UNDEFINED_VALUE )
THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
}
void CADSTAR_SCH_ARCHIVE_PARSER::SYMDEF_SCM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SYMDEF" ), );
ParseIdentifiers( aNode, aContext );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( ParseSubNode( cNode, aContext ) )
{
continue;
}
else if( cNodeName == wxT( "TERMINAL" ) )
{
TERMINAL term;
term.Parse( cNode, aContext );
Terminals.insert( std::make_pair( term.ID, term ) );
}
else if( cNodeName == wxT( "PINLABELLOC" ) )
{
PIN_NUM_LABEL_LOC loc;
loc.Parse( cNode, aContext );
PinLabelLocations.insert( std::make_pair( loc.TerminalID, loc ) );
}
else if( cNodeName == wxT( "PINNUMNAMELOC" ) )
{
PIN_NUM_LABEL_LOC loc;
loc.Parse( cNode, aContext );
PinNumberLocations.insert( std::make_pair( loc.TerminalID, loc ) );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
if( !Stub && ( Origin.x == UNDEFINED_VALUE || Origin.y == UNDEFINED_VALUE ) )
THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
}
void CADSTAR_SCH_ARCHIVE_PARSER::LIBRARY_SCM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "LIBRARY" ), );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "SYMDEF" ) )
{
SYMDEF_SCM symdef;
symdef.Parse( cNode, aContext );
SymbolDefinitions.insert( std::make_pair( symdef.ID, symdef ) );
}
else if( cNodeName == wxT( "HIERARCHY" ) )
{
// Ignore for now
//
// This node doesn't have any equivalent in KiCad so for now we ignore it. In
// future, we could parse it in detail, to obtain the tree-structure of
// symbols in a cadstar library
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
aContext->CheckPointCallback();
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::SHEETS::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SHEETS" ), );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "SHEET" ) )
{
LAYER_ID id = GetXmlAttributeIDString( cNode, 0 );
SHEET_NAME name = GetXmlAttributeIDString( cNode, 1 );
SheetNames.insert( std::make_pair( id, name ) );
SheetOrder.push_back( id );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::COMP::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "COMP" ), );
Designator = GetXmlAttributeIDString( aNode, 0 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "READONLY" ) )
{
ReadOnly = true;
}
else if( cNode->GetName() == wxT( "ATTRLOC" ) )
{
AttrLoc.Parse( cNode, aContext );
HasLocation = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::PARTREF::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "PARTREF" ), );
RefID = GetXmlAttributeIDString( aNode, 0 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "READONLY" ) )
{
ReadOnly = true;
}
else if( cNode->GetName() == wxT( "ATTRLOC" ) )
{
AttrLoc.Parse( cNode, aContext );
HasLocation = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::TERMATTR::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "TERMATTR" ), /* void */ );
TerminalID = GetXmlAttributeIDLong( aNode, 0 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "ATTR" ) )
{
ATTRIBUTE_VALUE val;
val.Parse( cNode, aContext );
Attributes.push_back( val );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::SYMPINNAME_LABEL::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SYMPINNAME" ) || aNode->GetName() == wxT( "SYMPINLABEL" ), );
TerminalID = GetXmlAttributeIDLong( aNode, 0 );
NameOrLabel = GetXmlAttributeIDString( aNode, 1 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "ATTRLOC" ) )
{
AttrLoc.Parse( cNode, aContext );
HasLocation = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOL::PIN_NUM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "PINNUM" ), );
TerminalID = GetXmlAttributeIDLong( aNode, 0 );
PinNum = GetXmlAttributeIDLong( aNode, 1 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( cNode->GetName() == wxT( "ATTRLOC" ) )
{
AttrLoc.Parse( cNode, aContext );
HasLocation = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOLVARIANT::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SYMBOLVARIANT" ), );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "SIGNALREF" ) )
{
Type = TYPE::SIGNALREF;
CheckNoNextNodes( cNode );
}
else if( cNodeName == wxT( "GLOBALSIGNAL" ) )
{
Type = TYPE::GLOBALSIGNAL;
Reference = GetXmlAttributeIDString( cNode, 0 );
}
else if( cNodeName == wxT( "TESTPOINT" ) )
{
Type = TYPE::TESTPOINT;
CheckNoNextNodes( cNode );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::SIGNALREFERENCELINK::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SIGNALREFERENCELINK" ), );
TextCodeID = GetXmlAttributeIDString( aNode, 0 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
//Parse child nodes
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( ParseSubNode( cNode, aContext ) )
continue;
else if( cNode->GetName() == wxT( "SIGREFTEXT" ) )
Text = GetXmlAttributeIDString( aNode, 0 );
else
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
if( Position.x == UNDEFINED_VALUE || Position.y == UNDEFINED_VALUE )
THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
}
void CADSTAR_SCH_ARCHIVE_PARSER::SYMBOL::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SYMBOL" ), );
ID = GetXmlAttributeIDString( aNode, 0 );
SymdefID = GetXmlAttributeIDString( aNode, 1 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
bool originParsed = false;
wxString location = wxString::Format( "SYMBOL -> %s", ID );
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( !originParsed && cNodeName == wxT( "PT" ) )
{
Origin.Parse( cNode, aContext );
originParsed = true;
}
else if( cNodeName == wxT( "COMP" ) )
{
ComponentRef.Parse( cNode, aContext );
IsComponent = true;
}
else if( cNodeName == wxT( "PARTREF" ) )
{
PartRef.Parse( cNode, aContext );
HasPartRef = true;
}
else if( cNodeName == wxT( "PARTNAMENOTVISIBLE" ) )
{
PartNameVisible = false;
}
else if( cNodeName == wxT( "VSYMMASTER" ) )
{
VariantParentSymbolID = GetXmlAttributeIDString( cNode, 0 );
VariantID = GetXmlAttributeIDString( cNode, 1 );
}
else if( cNodeName == wxT( "GROUPREF" ) )
{
GroupID = GetXmlAttributeIDString( cNode, 0 );
}
else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
{
ReuseBlockRef.Parse( cNode, aContext );
}
else if( cNodeName == wxT( "SIGNALREFERENCELINK" ) )
{
SigRefLink.Parse( cNode, aContext );
}
else if( cNodeName == wxT( "ORIENT" ) )
{
OrientAngle = GetXmlAttributeIDLong( cNode, 0 );
}
else if( cNodeName == wxT( "MIRROR" ) )
{
Mirror = true;
}
else if( cNodeName == wxT( "FIX" ) )
{
Fixed = true;
}
else if( cNodeName == wxT( "SCALE" ) )
{
ScaleRatioNumerator = GetXmlAttributeIDLong( cNode, 0 );
ScaleRatioDenominator = GetXmlAttributeIDLong( cNode, 1 );
}
else if( cNodeName == wxT( "READABILITY" ) )
{
Readability = ParseReadability( cNode );
}
else if( cNodeName == wxT( "GATE" ) )
{
GateID = GetXmlAttributeIDString( cNode, 0 );
}
else if( cNodeName == wxT( "SYMBOLVARIANT" ) )
{
IsSymbolVariant = true;
SymbolVariant.Parse( cNode, aContext );
}
else if( cNodeName == wxT( "TERMATTR" ) )
{
TERMATTR termattr;
termattr.Parse( cNode, aContext );
TerminalAttributes.insert( std::make_pair( termattr.TerminalID, termattr ) );
}
else if( cNodeName == wxT( "SYMPINLABEL" ) )
{
SYMPINNAME_LABEL sympinname;
sympinname.Parse( cNode, aContext );
PinLabels.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
}
else if( cNodeName == wxT( "SYMPINNAME" ) )
{
SYMPINNAME_LABEL sympinname;
sympinname.Parse( cNode, aContext );
PinNames.insert( std::make_pair( sympinname.TerminalID, sympinname ) );
}
else if( cNodeName == wxT( "PINNUM" ) )
{
PIN_NUM pinNum;
pinNum.Parse( cNode, aContext );
PinNumbers.insert( std::make_pair( pinNum.TerminalID, pinNum ) );
}
else if( cNodeName == wxT( "ATTR" ) )
{
ATTRIBUTE_VALUE attrVal;
attrVal.Parse( cNode, aContext );
AttributeValues.insert( std::make_pair( attrVal.AttributeID, attrVal ) );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, location );
}
}
if( !originParsed )
THROW_MISSING_PARAMETER_IO_ERROR( wxT( "PT" ), aNode->GetName() );
}
void CADSTAR_SCH_ARCHIVE_PARSER::SIGLOC::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SIGLOC" ), );
TextCodeID = GetXmlAttributeIDString( aNode, 0 );
//Parse child nodes
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( ParseSubNode( cNode, aContext ) )
continue;
else
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
if( Position.x == UNDEFINED_VALUE || Position.y == UNDEFINED_VALUE )
THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
}
void CADSTAR_SCH_ARCHIVE_PARSER::BUS::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "BUS" ), );
ID = GetXmlAttributeIDString( aNode, 0 );
LineCodeID = GetXmlAttributeIDString( aNode, 1 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( SHAPE::IsShape( cNode ) )
{
Shape.Parse( cNode, aContext );
}
else if( cNodeName == wxT( "BUSNAME" ) )
{
Name = GetXmlAttributeIDString( cNode, 0 );
XNODE* subNode = cNode->GetChildren();
if( subNode )
{
if( subNode->GetName() == wxT( "SIGLOC" ) )
{
BusLabel.Parse( subNode, aContext );
HasBusLabel = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
}
}
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::BLOCK::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "BLOCK" ), );
ID = GetXmlAttributeIDString( aNode, 0 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "CLONE" ) )
{
Type = TYPE::CLONE;
}
else if( cNodeName == wxT( "PARENT" ) )
{
Type = TYPE::PARENT;
AssocLayerID = GetXmlAttributeIDString( cNode, 0 );
}
else if( cNodeName == wxT( "CHILD" ) )
{
Type = TYPE::CHILD;
AssocLayerID = GetXmlAttributeIDString( cNode, 0 );
}
else if( cNodeName == wxT( "BLOCKNAME" ) )
{
Name = GetXmlAttributeIDString( cNode, 0 );
XNODE* subNode = cNode->GetChildren();
if( subNode )
{
if( subNode->GetName() == wxT( "ATTRLOC" ) )
{
BlockLabel.Parse( subNode, aContext );
HasBlockLabel = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( subNode->GetName(), cNode->GetName() );
}
}
}
else if( cNodeName == wxT( "TERMINAL" ) )
{
TERMINAL term;
term.Parse( cNode, aContext );
Terminals.insert( std::make_pair( term.ID, term ) );
}
else if( cNodeName == wxT( "FIGURE" ) )
{
FIGURE figure;
figure.Parse( cNode, aContext );
Figures.insert( std::make_pair( figure.ID, figure ) );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::SYM_TERM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxASSERT( aNode->GetName() == wxT( "TERM" ) );
ID = GetXmlAttributeIDString( aNode, 0 );
SymbolID = GetXmlAttributeIDString( aNode, 1 );
TerminalID = GetXmlAttributeIDLong( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "SIGLOC" ) )
{
NetLabel.Parse( cNode, aContext );
HasNetLabel = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::BUS_TERM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxASSERT( aNode->GetName() == wxT( "BUSTERM" ) );
ID = GetXmlAttributeIDString( aNode, 0 );
BusID = GetXmlAttributeIDString( aNode, 1 );
XNODE* cNode = aNode->GetChildren();
bool firstPointParsed = false;
bool secondPointParsed = false;
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "SIGLOC" ) )
{
NetLabel.Parse( cNode, aContext );
HasNetLabel = true;
}
else if( cNodeName == wxT( "PT" ) )
{
if( !firstPointParsed )
{
FirstPoint.Parse( cNode, aContext );
firstPointParsed = true;
}
else if( !secondPointParsed )
{
SecondPoint.Parse( cNode, aContext );
secondPointParsed = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
if( !firstPointParsed || !secondPointParsed )
THROW_MISSING_NODE_IO_ERROR( wxT( "PT" ), aNode->GetName() );
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::BLOCK_TERM::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxASSERT( aNode->GetName() == wxT( "BLOCKTERM" ) );
ID = GetXmlAttributeIDString( aNode, 0 );
BlockID = GetXmlAttributeIDString( aNode, 1 );
TerminalID = GetXmlAttributeIDLong( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "SIGLOC" ) )
{
NetLabel.Parse( cNode, aContext );
HasNetLabel = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::CONNECTION_SCH::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
ParseIdentifiers( aNode, aContext );
LayerID = GetXmlAttributeIDString( aNode, 3 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( ParseSubNode( cNode, aContext ) )
{
continue;
}
else if( cNodeName == wxT( "PATH" ) )
{
Path = ParseAllChildPoints( cNode, aContext, true );
}
else if( cNodeName == wxT( "GROUPREF" ) )
{
GroupID = GetXmlAttributeIDString( cNode, 0 );
}
else if( cNodeName == wxT( "REUSEBLOCKREF" ) )
{
ReuseBlockRef.Parse( cNode, aContext );
}
else if( cNodeName == wxT( "CONLINECODE" ) )
{
ConnectionLineCode = GetXmlAttributeIDString( cNode, 0 );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "CONN" ) );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
ParseIdentifiers( aNode, aContext );
//Parse child nodes
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "JPT" ) )
{
JUNCTION_SCH jpt;
jpt.Parse( cNode, aContext );
Junctions.insert( std::make_pair( jpt.ID, jpt ) );
}
else if( ParseSubNode( cNode, aContext ) )
{
continue;
}
else if( cNodeName == wxT( "TERM" ) )
{
SYM_TERM pin;
pin.Parse( cNode, aContext );
Terminals.insert( std::make_pair( pin.ID, pin ) );
}
else if( cNodeName == wxT( "BUSTERM" ) )
{
BUS_TERM bt;
bt.Parse( cNode, aContext );
BusTerminals.insert( std::make_pair( bt.ID, bt ) );
}
else if( cNodeName == wxT( "BLOCKTERM" ) )
{
BLOCK_TERM bt;
bt.Parse( cNode, aContext );
BlockTerminals.insert( std::make_pair( bt.ID, bt ) );
}
else if( cNodeName == wxT( "DANGLER" ) )
{
DANGLER dang;
dang.Parse( cNode, aContext );
Danglers.insert( std::make_pair( dang.ID, dang ) );
}
else if( cNodeName == wxT( "CONN" ) )
{
CONNECTION_SCH conn;
conn.Parse( cNode, aContext );
Connections.push_back( conn );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, wxT( "NET" ) );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::CADSTAR_SCHEMATIC::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxCHECK( aNode->GetName() == wxT( "SCHEMATIC" ), );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "GROUP" ) )
{
GROUP group;
group.Parse( cNode, aContext );
Groups.insert( std::make_pair( group.ID, group ) );
}
else if( cNodeName == wxT( "REUSEBLOCK" ) )
{
REUSEBLOCK reuseblock;
reuseblock.Parse( cNode, aContext );
ReuseBlocks.insert( std::make_pair( reuseblock.ID, reuseblock ) );
}
else if( cNodeName == wxT( "FIGURE" ) )
{
FIGURE figure;
figure.Parse( cNode, aContext );
Figures.insert( std::make_pair( figure.ID, figure ) );
}
else if( cNodeName == wxT( "SYMBOL" ) )
{
SYMBOL sym;
sym.Parse( cNode, aContext );
Symbols.insert( std::make_pair( sym.ID, sym ) );
}
else if( cNodeName == wxT( "BUS" ) )
{
BUS bus;
bus.Parse( cNode, aContext );
Buses.insert( std::make_pair( bus.ID, bus ) );
}
else if( cNodeName == wxT( "BLOCK" ) )
{
BLOCK block;
block.Parse( cNode, aContext );
Blocks.insert( std::make_pair( block.ID, block ) );
}
else if( cNodeName == wxT( "NET" ) )
{
NET_SCH net;
net.Parse( cNode, aContext );
Nets.insert( std::make_pair( net.ID, net ) );
}
else if( cNodeName == wxT( "TEXT" ) )
{
TEXT txt;
txt.Parse( cNode, aContext );
Texts.insert( std::make_pair( txt.ID, txt ) );
}
else if( cNodeName == wxT( "DOCSYMBOL" ) )
{
DOCUMENTATION_SYMBOL docsym;
docsym.Parse( cNode, aContext );
DocumentationSymbols.insert( std::make_pair( docsym.ID, docsym ) );
}
else if( cNodeName == wxT( "VHIERARCHY" ) )
{
VariantHierarchy.Parse( cNode, aContext );
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
aContext->CheckPointCallback();
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::JUNCTION_SCH::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
ParseIdentifiers( aNode, aContext );
TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
for( ; cNode; cNode = cNode->GetNext() )
{
if( ParseSubNode( cNode, aContext ) )
{
continue;
}
else if( cNode->GetName() == wxT( "SIGLOC" ) )
{
NetLabel.Parse( cNode, aContext );
HasNetLabel = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNode->GetName(), aNode->GetName() );
}
}
}
void CADSTAR_SCH_ARCHIVE_PARSER::NET_SCH::DANGLER::Parse( XNODE* aNode, PARSER_CONTEXT* aContext )
{
wxASSERT( aNode->GetName() == wxT( "DANGLER" ) );
ID = GetXmlAttributeIDString( aNode, 0 );
TerminalCodeID = GetXmlAttributeIDString( aNode, 1 );
LayerID = GetXmlAttributeIDString( aNode, 2 );
XNODE* cNode = aNode->GetChildren();
bool positionParsed = false;
for( ; cNode; cNode = cNode->GetNext() )
{
wxString cNodeName = cNode->GetName();
if( cNodeName == wxT( "SIGLOC" ) )
{
NetLabel.Parse( cNode, aContext );
HasNetLabel = true;
}
else if( !positionParsed && cNodeName == wxT( "PT" ) )
{
Position.Parse( cNode, aContext );
positionParsed = true;
}
else
{
THROW_UNKNOWN_NODE_IO_ERROR( cNodeName, aNode->GetName() );
}
}
}