/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020-2021 Roberto Fernandez Bautista * Copyright (C) 2020-2021 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 . */ /** * @file cadstar_pcb_archive_parser.cpp * @brief Reads in a CADSTAR Schematic Archive (*.csa) file */ #ifndef CADSTAR_SCH_ARCHIVE_PARSER_H_ #define CADSTAR_SCH_ARCHIVE_PARSER_H_ #include /** * @brief Represents a CADSTAR Schematic Archive (*.csa) file */ class CADSTAR_SCH_ARCHIVE_PARSER : public CADSTAR_ARCHIVE_PARSER { public: explicit CADSTAR_SCH_ARCHIVE_PARSER( wxString aFilename ) : CADSTAR_ARCHIVE_PARSER(), Filename( aFilename ), KiCadUnitDivider( 10 ) { } /** * @brief Parses the file * @throw IO_ERROR if file could not be opened or there was * an error while parsing */ void Parse(); typedef wxString TERMINALCODE_ID; typedef wxString SYMBOL_ID; typedef wxString BUS_ID; typedef wxString BLOCK_ID; typedef wxString SHEET_NAME; enum class TERMINAL_SHAPE_TYPE { ANNULUS, BOX, BULLET, CIRCLE, ///< Keyword "ROUND" CROSS, DIAMOND, FINGER, OCTAGON, PLUS, POINTER, RECTANGLE, ROUNDED_RECT, ///< Keyword "ROUNDED" SQUARE, STAR, TRIANGLE, UNDEFINED ///< Only used for error checking (not a real shape) }; static TERMINAL_SHAPE_TYPE ParseTermShapeType( const wxString& aShapeStr ); struct TERMINAL_SHAPE : PARSER { TERMINAL_SHAPE_TYPE ShapeType; long Size = UNDEFINED_VALUE; // Note in the CADSTAR GUI, it only talks about "length", but the file seems to // split it in "left length" and "right length" (similar to PADCODE in the PCB) // for some terminal shapes such as RECTANGLE but not for others, such as TRIANGLE long LeftLength = UNDEFINED_VALUE; ///< Might also be total length long RightLength = UNDEFINED_VALUE; ///< Could be blank long InternalFeature = UNDEFINED_VALUE; long OrientAngle = 0; ///< 1/1000 of a Degree static bool IsTermShape( XNODE* aNode ); void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct TERMINALCODE : PARSER { TERMINALCODE_ID ID; wxString Name; TERMINAL_SHAPE Shape; bool Filled = false; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct CODEDEFS_SCM : CADSTAR_ARCHIVE_PARSER::CODEDEFS { std::map TerminalCodes; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct ASSIGNMENTS_SCM : PARSER { CODEDEFS_SCM Codedefs; GRIDS Grids; SETTINGS Settings; bool NetclassEditAttributeSettings = false; //< Unclear what this does bool SpacingclassEditAttributeSettings = false; //< Unclear what this does void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct TERMINAL : PARSER { TERMINAL_ID ID; TERMINALCODE_ID TerminalCodeID; POINT Position; ///< Pad position within the component's coordinate frame. long OrientAngle = 0; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct PIN_NUM_LABEL_LOC : CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION { TERMINAL_ID TerminalID; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct SYMDEF_SCM : CADSTAR_ARCHIVE_PARSER::SYMDEF { std::map Terminals; std::map PinLabelLocations; std::map PinNumberLocations; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct LIBRARY_SCM : PARSER { std::map SymbolDefinitions; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct SHEETS : PARSER { std::map SheetNames; std::vector SheetOrder; ///< A vector to also store the order in which ///< sheets are to be displayed void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct COMP : PARSER { wxString Designator = wxEmptyString; bool ReadOnly = false; bool HasLocation = false; ATTRIBUTE_LOCATION AttrLoc; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct PARTREF : PARSER { PART_ID RefID = wxEmptyString; bool ReadOnly = false; bool HasLocation = false; ATTRIBUTE_LOCATION AttrLoc; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct TERMATTR : PARSER { TERMINAL_ID TerminalID; ATTRIBUTE_VALUE Value; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct SYMPINNAME_LABEL : PARSER { TERMINAL_ID TerminalID; wxString NameOrLabel; bool HasLocation = false; ATTRIBUTE_LOCATION AttrLoc; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct SYMBOLVARIANT : PARSER { enum class TYPE { GLOBALSIGNAL, SIGNALREF, TESTPOINT //TODO: there might be others }; TYPE Type; wxString Reference = wxEmptyString; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct SIGNALREFERENCELINK : CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION { wxString Text; ///< This contains the numbers of the other sheets where the ///< signal reference is present separated by commas void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct SYMBOL : PARSER { struct PIN_NUM : PARSER { TERMINAL_ID TerminalID; long PinNum; bool HasLocation = false; ATTRIBUTE_LOCATION AttrLoc; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; SYMBOL_ID ID; SYMDEF_ID SymdefID; LAYER_ID LayerID; ///< Sheet on which symbol is located POINT Origin; GROUP_ID GroupID = wxEmptyString; ///< If not empty, this symbol is part of a group REUSEBLOCKREF ReuseBlockRef; long OrientAngle = 0; bool Mirror = false; bool Fixed = false; long ScaleRatioNumerator = 1; ///< Symbols can be arbitrarily scaled in CADSTAR long ScaleRatioDenominator = 1; READABILITY Readability = READABILITY::BOTTOM_TO_TOP; bool IsComponent = false; COMP ComponentRef; bool HasPartRef = false; PARTREF PartRef; bool PartNameVisible = true; GATE_ID GateID; ///< The gate this symbol represents within the associated Part bool IsSymbolVariant = false; SYMBOLVARIANT SymbolVariant; SIGNALREFERENCELINK SigRefLink; ///< Signal References (a special form of global signal) ///< have annotations showing the location of all the ///< other sheets where the signal is present SYMBOL_ID VariantParentSymbolID = wxEmptyString; VARIANT_ID VariantID = wxEmptyString; std::map TerminalAttributes; std::map PinLabels; ///< Equivalent to KiCad's Pin Name std::map PinNames; ///< Identifier of the pin in the PCB ///< Equivalent to KiCad's Pin Number std::map PinNumbers; ///< This seems to only appear in older ///< designs and is similar to PinNames ///< but only allowing numerical values std::map AttributeValues; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; /** * @brief Net name or bus name label */ struct SIGLOC : CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION { void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct BUS : PARSER { BUS_ID ID; LINECODE_ID LineCodeID; LAYER_ID LayerID; ///< Sheet on which bus is located SHAPE Shape; wxString Name = wxEmptyString; bool HasBusLabel = false; SIGLOC BusLabel; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct BLOCK : PARSER { enum class TYPE { CLONE, ///< the block is referring to the sheet it is on. PARENT, CHILD }; BLOCK_ID ID; TYPE Type; ///< Determines what the associated layer is, whether parent, child or clone LAYER_ID LayerID = wxEmptyString; ///< The sheet block is on (TODO: verify this is true) LAYER_ID AssocLayerID = wxEmptyString; ///< Parent or Child linked sheet wxString Name = wxEmptyString; bool HasBlockLabel = false; ATTRIBUTE_LOCATION BlockLabel; std::map Terminals; std::map Figures; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct NET_SCH : CADSTAR_ARCHIVE_PARSER::NET { struct JUNCTION_SCH : CADSTAR_ARCHIVE_PARSER::NET::JUNCTION ///< "JPT" nodename. { TERMINALCODE_ID TerminalCodeID; ///< Usually a circle, but size can be varied bool HasNetLabel = false; SIGLOC NetLabel; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct SYM_TERM : PARSER ///< "TERM" nodename (represents a pin in a SCH symbol) { NETELEMENT_ID ID; ///< First character is "P" SYMBOL_ID SymbolID; TERMINAL_ID TerminalID; bool HasNetLabel = false; SIGLOC NetLabel; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct BUS_TERM : PARSER ///< "BUSTERM" nodename (represents a connetion to a bus) { NETELEMENT_ID ID; ///< First two characters "BT" BUS_ID BusID; POINT FirstPoint; ///< Point on the bus itself POINT SecondPoint; ///< Start point for any wires bool HasNetLabel = false; SIGLOC NetLabel; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct BLOCK_TERM : PARSER ///< "BLOCKTERM" nodename (represents a connetion to a block) { NETELEMENT_ID ID; ///< First four characters "BLKT" BLOCK_ID BlockID; TERMINAL_ID TerminalID; bool HasNetLabel = false; SIGLOC NetLabel; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct DANGLER : PARSER ///< "DANGLER" nodename (represents a dangling wire) { NETELEMENT_ID ID; ///< First character "D" TERMINALCODE_ID TerminalCodeID; LAYER_ID LayerID; POINT Position; bool HasNetLabel = false; SIGLOC NetLabel; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct CONNECTION_SCH : CADSTAR_ARCHIVE_PARSER::NET::CONNECTION ///< "CONN" nodename { LAYER_ID LayerID; ///< Sheet on which the connection is drawn std::vector Path; GROUP_ID GroupID = wxEmptyString; REUSEBLOCKREF ReuseBlockRef; LINECODE_ID ConnectionLineCode; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; std::map Junctions; std::map Terminals; std::map BusTerminals; std::map BlockTerminals; std::map Danglers; std::vector Connections; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; struct CADSTAR_SCHEMATIC : PARSER { std::map Groups; std::map ReuseBlocks; std::map Figures; std::map Symbols; std::map Buses; std::map Blocks; std::map Nets; std::map Texts; std::map DocumentationSymbols; VARIANT_HIERARCHY VariantHierarchy; std::map AttributeValues; void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; }; wxString Filename; HEADER Header; ASSIGNMENTS_SCM Assignments; LIBRARY_SCM Library; PARTS Parts; SHEETS Sheets; CADSTAR_SCHEMATIC Schematic; ATTRCOLORS AttrColors; PARTNAMECOL SymbolPartNameColor; int KiCadUnitDivider; ///