1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2020-2021 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com> 5 * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors. 6 * 7 * This program is free software: you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation, either version 3 of the License, or (at your 10 * option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 /** 22 * @file cadstar_pcb_archive_parser.cpp 23 * @brief Reads in a CADSTAR Schematic Archive (*.csa) file 24 */ 25 26 #ifndef CADSTAR_SCH_ARCHIVE_PARSER_H_ 27 #define CADSTAR_SCH_ARCHIVE_PARSER_H_ 28 29 #include <plugins/cadstar/cadstar_archive_parser.h> 30 31 32 /** 33 * @brief Represents a CADSTAR Schematic Archive (*.csa) file 34 */ 35 class CADSTAR_SCH_ARCHIVE_PARSER : public CADSTAR_ARCHIVE_PARSER 36 { 37 public: CADSTAR_SCH_ARCHIVE_PARSER(wxString aFilename)38 explicit CADSTAR_SCH_ARCHIVE_PARSER( wxString aFilename ) 39 : CADSTAR_ARCHIVE_PARSER(), Filename( aFilename ), Header(), Assignments(), KiCadUnitDivider( 10 ) 40 { 41 } 42 43 /** 44 * @brief Parses the file 45 * @throw IO_ERROR if file could not be opened or there was 46 * an error while parsing 47 */ 48 void Parse(); 49 50 51 typedef wxString TERMINALCODE_ID; 52 typedef wxString SYMBOL_ID; 53 typedef wxString BUS_ID; 54 typedef wxString BLOCK_ID; 55 typedef wxString SHEET_NAME; 56 57 58 enum class TERMINAL_SHAPE_TYPE 59 { 60 ANNULUS, 61 BOX, 62 BULLET, 63 CIRCLE, ///< Keyword "ROUND" 64 CROSS, 65 DIAMOND, 66 FINGER, 67 OCTAGON, 68 PLUS, 69 POINTER, 70 RECTANGLE, 71 ROUNDED_RECT, ///< Keyword "ROUNDED" 72 SQUARE, 73 STAR, 74 TRIANGLE, 75 UNDEFINED ///< Only used for error checking (not a real shape) 76 }; 77 78 79 static TERMINAL_SHAPE_TYPE ParseTermShapeType( const wxString& aShapeStr ); 80 81 82 struct TERMINAL_SHAPE : PARSER 83 { 84 TERMINAL_SHAPE_TYPE ShapeType; 85 long Size = UNDEFINED_VALUE; 86 // Note in the CADSTAR GUI, it only talks about "length", but the file seems to 87 // split it in "left length" and "right length" (similar to PADCODE in the PCB) 88 // for some terminal shapes such as RECTANGLE but not for others, such as TRIANGLE 89 long LeftLength = UNDEFINED_VALUE; ///< Might also be total length 90 long RightLength = UNDEFINED_VALUE; ///< Could be blank 91 long InternalFeature = UNDEFINED_VALUE; 92 long OrientAngle = 0; ///< 1/1000 of a Degree 93 94 static bool IsTermShape( XNODE* aNode ); 95 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 96 }; 97 98 99 struct TERMINALCODE : PARSER 100 { 101 TERMINALCODE_ID ID; 102 wxString Name; 103 TERMINAL_SHAPE Shape; 104 bool Filled = false; 105 106 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 107 }; 108 109 110 struct CODEDEFS_SCM : CADSTAR_ARCHIVE_PARSER::CODEDEFS 111 { 112 std::map<TERMINALCODE_ID, TERMINALCODE> TerminalCodes; 113 114 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 115 }; 116 117 118 struct ASSIGNMENTS_SCM : PARSER 119 { 120 CODEDEFS_SCM Codedefs; 121 GRIDS Grids; 122 SETTINGS Settings; 123 bool NetclassEditAttributeSettings = false; //< Unclear what this does 124 bool SpacingclassEditAttributeSettings = false; //< Unclear what this does 125 126 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 127 }; 128 129 130 struct TERMINAL : PARSER 131 { 132 TERMINAL_ID ID; 133 TERMINALCODE_ID TerminalCodeID; 134 POINT Position; ///< Pad position within the component's coordinate frame. 135 long OrientAngle = 0; 136 137 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 138 }; 139 140 141 struct PIN_NUM_LABEL_LOC : CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION 142 { 143 TERMINAL_ID TerminalID; 144 145 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 146 }; 147 148 149 struct SYMDEF_SCM : CADSTAR_ARCHIVE_PARSER::SYMDEF 150 { 151 std::map<TERMINAL_ID, TERMINAL> Terminals; 152 std::map<TERMINAL_ID, PIN_NUM_LABEL_LOC> PinLabelLocations; 153 std::map<TERMINAL_ID, PIN_NUM_LABEL_LOC> PinNumberLocations; 154 155 156 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 157 }; 158 159 160 struct LIBRARY_SCM : PARSER 161 { 162 std::map<SYMDEF_ID, SYMDEF_SCM> SymbolDefinitions; 163 164 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 165 }; 166 167 168 struct SHEETS : PARSER 169 { 170 std::map<LAYER_ID, SHEET_NAME> SheetNames; 171 std::vector<LAYER_ID> SheetOrder; ///< A vector to also store the order in which 172 ///< sheets are to be displayed 173 174 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 175 }; 176 177 178 struct COMP : PARSER 179 { 180 wxString Designator = wxEmptyString; 181 bool ReadOnly = false; 182 bool HasLocation = false; 183 ATTRIBUTE_LOCATION AttrLoc; 184 185 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 186 }; 187 188 189 struct PARTREF : PARSER 190 { 191 PART_ID RefID = wxEmptyString; 192 bool ReadOnly = false; 193 bool HasLocation = false; 194 ATTRIBUTE_LOCATION AttrLoc; 195 196 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 197 }; 198 199 200 struct TERMATTR : PARSER 201 { 202 TERMINAL_ID TerminalID; 203 ATTRIBUTE_VALUE Value; 204 205 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 206 }; 207 208 209 struct SYMPINNAME_LABEL : PARSER 210 { 211 TERMINAL_ID TerminalID; 212 wxString NameOrLabel; 213 bool HasLocation = false; 214 ATTRIBUTE_LOCATION AttrLoc; 215 216 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 217 }; 218 219 220 struct SYMBOLVARIANT : PARSER 221 { 222 enum class TYPE 223 { 224 GLOBALSIGNAL, 225 SIGNALREF, 226 TESTPOINT 227 //TODO: there might be others 228 }; 229 230 TYPE Type; 231 wxString Reference = wxEmptyString; 232 233 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 234 }; 235 236 237 struct SIGNALREFERENCELINK : CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION 238 { 239 wxString Text; ///< This contains the numbers of the other sheets where the 240 ///< signal reference is present separated by commas 241 242 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 243 }; 244 245 246 struct SYMBOL : PARSER 247 { 248 struct PIN_NUM : PARSER 249 { 250 TERMINAL_ID TerminalID; 251 long PinNum; 252 bool HasLocation = false; 253 ATTRIBUTE_LOCATION AttrLoc; 254 255 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 256 }; 257 258 SYMBOL_ID ID; 259 SYMDEF_ID SymdefID; 260 LAYER_ID LayerID; ///< Sheet on which symbol is located 261 POINT Origin; 262 GROUP_ID GroupID = wxEmptyString; ///< If not empty, this symbol is part of a group 263 REUSEBLOCKREF ReuseBlockRef; 264 long OrientAngle = 0; 265 bool Mirror = false; 266 bool Fixed = false; 267 long ScaleRatioNumerator = 1; ///< Symbols can be arbitrarily scaled in CADSTAR 268 long ScaleRatioDenominator = 1; 269 READABILITY Readability = READABILITY::BOTTOM_TO_TOP; 270 271 bool IsComponent = false; 272 COMP ComponentRef; 273 bool HasPartRef = false; 274 PARTREF PartRef; 275 bool PartNameVisible = true; 276 GATE_ID GateID; ///< The gate this symbol represents within the associated Part 277 278 bool IsSymbolVariant = false; 279 SYMBOLVARIANT SymbolVariant; 280 SIGNALREFERENCELINK SigRefLink; ///< Signal References (a special form of global signal) 281 ///< have annotations showing the location of all the 282 ///< other sheets where the signal is present 283 284 SYMBOL_ID VariantParentSymbolID = wxEmptyString; 285 VARIANT_ID VariantID = wxEmptyString; 286 287 std::map<TERMINAL_ID, TERMATTR> TerminalAttributes; 288 std::map<TERMINAL_ID, SYMPINNAME_LABEL> PinLabels; ///< Equivalent to KiCad's Pin Name 289 std::map<TERMINAL_ID, SYMPINNAME_LABEL> PinNames; ///< Identifier of the pin in the PCB 290 ///< Equivalent to KiCad's Pin Number 291 std::map<TERMINAL_ID, PIN_NUM> PinNumbers; ///< This seems to only appear in older 292 ///< designs and is similar to PinNames 293 ///< but only allowing numerical values 294 std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues; 295 296 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 297 }; 298 299 300 /** 301 * @brief Net name or bus name label 302 */ 303 struct SIGLOC : CADSTAR_ARCHIVE_PARSER::ATTRIBUTE_LOCATION 304 { 305 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 306 }; 307 308 309 struct BUS : PARSER 310 { 311 BUS_ID ID; 312 LINECODE_ID LineCodeID; 313 LAYER_ID LayerID; ///< Sheet on which bus is located 314 SHAPE Shape; 315 wxString Name = wxEmptyString; 316 bool HasBusLabel = false; 317 SIGLOC BusLabel; 318 319 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 320 }; 321 322 323 struct BLOCK : PARSER 324 { 325 enum class TYPE 326 { 327 CLONE, ///< the block is referring to the sheet it is on. 328 PARENT, 329 CHILD 330 }; 331 332 BLOCK_ID ID; 333 TYPE Type; ///< Determines what the associated layer is, whether parent, child or clone 334 LAYER_ID LayerID = wxEmptyString; ///< The sheet block is on (TODO: verify this is true) 335 LAYER_ID AssocLayerID = wxEmptyString; ///< Parent or Child linked sheet 336 wxString Name = wxEmptyString; 337 bool HasBlockLabel = false; 338 ATTRIBUTE_LOCATION BlockLabel; 339 340 std::map<TERMINAL_ID, TERMINAL> Terminals; 341 std::map<FIGURE_ID, FIGURE> Figures; 342 343 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 344 }; 345 346 347 struct NET_SCH : CADSTAR_ARCHIVE_PARSER::NET 348 { 349 struct JUNCTION_SCH : CADSTAR_ARCHIVE_PARSER::NET::JUNCTION ///< "JPT" nodename. 350 { 351 TERMINALCODE_ID TerminalCodeID; ///< Usually a circle, but size can be varied 352 bool HasNetLabel = false; 353 SIGLOC NetLabel; 354 355 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 356 }; 357 358 struct SYM_TERM : PARSER ///< "TERM" nodename (represents a pin in a SCH symbol) 359 { 360 NETELEMENT_ID ID; ///< First character is "P" 361 SYMBOL_ID SymbolID; 362 TERMINAL_ID TerminalID; 363 bool HasNetLabel = false; 364 SIGLOC NetLabel; 365 366 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 367 }; 368 369 struct BUS_TERM : PARSER ///< "BUSTERM" nodename (represents a connection to a bus) 370 { 371 NETELEMENT_ID ID; ///< First two characters "BT" 372 BUS_ID BusID; 373 POINT FirstPoint; ///< Point on the bus itself 374 POINT SecondPoint; ///< Start point for any wires 375 bool HasNetLabel = false; 376 SIGLOC NetLabel; 377 378 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 379 }; 380 381 struct BLOCK_TERM : PARSER ///< "BLOCKTERM" nodename (represents a connection to a block) 382 { 383 NETELEMENT_ID ID; ///< First four characters "BLKT" 384 BLOCK_ID BlockID; 385 TERMINAL_ID TerminalID; 386 bool HasNetLabel = false; 387 SIGLOC NetLabel; 388 389 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 390 }; 391 392 393 struct DANGLER : PARSER ///< "DANGLER" nodename (represents a dangling wire) 394 { 395 NETELEMENT_ID ID; ///< First character "D" 396 TERMINALCODE_ID TerminalCodeID; 397 LAYER_ID LayerID; 398 POINT Position; 399 bool HasNetLabel = false; 400 SIGLOC NetLabel; 401 402 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 403 }; 404 405 struct CONNECTION_SCH : CADSTAR_ARCHIVE_PARSER::NET::CONNECTION ///< "CONN" nodename 406 { 407 LAYER_ID LayerID; ///< Sheet on which the connection is drawn 408 std::vector<POINT> Path; 409 GROUP_ID GroupID = wxEmptyString; 410 REUSEBLOCKREF ReuseBlockRef; 411 LINECODE_ID ConnectionLineCode; 412 413 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 414 }; 415 416 std::map<NETELEMENT_ID, JUNCTION_SCH> Junctions; 417 std::map<NETELEMENT_ID, SYM_TERM> Terminals; 418 std::map<NETELEMENT_ID, BUS_TERM> BusTerminals; 419 std::map<NETELEMENT_ID, BLOCK_TERM> BlockTerminals; 420 std::map<NETELEMENT_ID, DANGLER> Danglers; 421 std::vector<CONNECTION_SCH> Connections; 422 423 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 424 }; 425 426 427 struct CADSTAR_SCHEMATIC : PARSER 428 { 429 std::map<GROUP_ID, GROUP> Groups; 430 std::map<REUSEBLOCK_ID, REUSEBLOCK> ReuseBlocks; 431 std::map<FIGURE_ID, FIGURE> Figures; 432 std::map<SYMBOL_ID, SYMBOL> Symbols; 433 std::map<BUS_ID, BUS> Buses; 434 std::map<BLOCK_ID, BLOCK> Blocks; 435 std::map<NET_ID, NET_SCH> Nets; 436 std::map<TEXT_ID, TEXT> Texts; 437 std::map<DOCUMENTATION_SYMBOL_ID, DOCUMENTATION_SYMBOL> DocumentationSymbols; 438 VARIANT_HIERARCHY VariantHierarchy; 439 std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues; 440 441 void Parse( XNODE* aNode, PARSER_CONTEXT* aContext ) override; 442 }; 443 444 445 wxString Filename; 446 HEADER Header; 447 ASSIGNMENTS_SCM Assignments; 448 LIBRARY_SCM Library; 449 PARTS Parts; 450 SHEETS Sheets; 451 CADSTAR_SCHEMATIC Schematic; 452 ATTRCOLORS AttrColors; 453 PARTNAMECOL SymbolPartNameColor; 454 455 int KiCadUnitDivider; ///<Use this value to convert units in this CSA file to KiCad units 456 457 }; //CADSTAR_SCH_ARCHIVE_PARSER 458 459 #endif // CADSTAR_SCH_ARCHIVE_PARSER_H_ 460