KiCad PCB EDA Suite
DSN::SPECCTRA_DB Class Reference

A DSN data tree, usually coming from a DSN file. More...

#include <specctra.h>

Inheritance diagram for DSN::SPECCTRA_DB:

Public Member Functions

 SPECCTRA_DB ()
 
virtual ~SPECCTRA_DB ()
 
void SetPCB (PCB *aPcb)
 Delete any existing PCB and replaces it with the given one. More...
 
PCBGetPCB ()
 
void SetSESSION (SESSION *aSession)
 Delete any existing SESSION and replaces it with the given one. More...
 
SESSIONGetSESSION ()
 
void LoadPCB (const wxString &aFilename)
 A recursive descent parser for a SPECCTRA DSN "design" file. More...
 
void LoadSESSION (const wxString &aFilename)
 A recursive descent parser for a SPECCTRA DSN "session" file. More...
 
void ExportPCB (const wxString &aFilename, bool aNameChange=false)
 Write the internal PCB instance out as a SPECTRA DSN format file. More...
 
void FromBOARD (BOARD *aBoard)
 Add the entire BOARD to the PCB but does not write it out. More...
 
void FromSESSION (BOARD *aBoard)
 Add the entire #SESSION info to a BOARD but does not write it out. More...
 
void ExportSESSION (const wxString &aFilename)
 Write the internal #SESSION instance out as a #SPECTRA DSN format file. More...
 
bool BuiltBoardOutlines (BOARD *aBoard)
 Build the board outlines and store it in m_brd_outlines. More...
 
void FlipFOOTPRINTs (BOARD *aBoard)
 Flip the footprints which are on the back side of the board to the front. More...
 
void RevertFOOTPRINTs (BOARD *aBoard)
 Flip the footprints which were on the back side of the board back to the back. More...
 

Static Public Member Functions

static PCBMakePCB ()
 Make a PCB with all the default ELEMs and parts on the heap. More...
 

Private Member Functions

void buildLayerMaps (BOARD *aBoard)
 Create a few data translation structures for layer name and number mapping between the DSN::PCB structure and the KiCad BOARD structure. More...
 
int findLayerName (const std::string &aLayerName) const
 Return the PCB layer index for a given layer name, within the specctra sessionfile. More...
 
void readCOMPnPIN (std::string *component_id, std::string *pid_id)
 Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen. More...
 
void readTIME (time_t *time_stamp)
 Read a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : second year". More...
 
void doPCB (PCB *growth)
 
void doPARSER (PARSER *growth)
 
void doRESOLUTION (UNIT_RES *growth)
 
void doUNIT (UNIT_RES *growth)
 
void doSTRUCTURE (STRUCTURE *growth)
 
void doSTRUCTURE_OUT (STRUCTURE_OUT *growth)
 
void doLAYER_NOISE_WEIGHT (LAYER_NOISE_WEIGHT *growth)
 
void doSPECCTRA_LAYER_PAIR (SPECCTRA_LAYER_PAIR *growth)
 
void doBOUNDARY (BOUNDARY *growth)
 
void doRECTANGLE (RECTANGLE *growth)
 
void doPATH (PATH *growth)
 
void doSTRINGPROP (STRINGPROP *growth)
 
void doTOKPROP (TOKPROP *growth)
 
void doVIA (VIA *growth)
 
void doCONTROL (CONTROL *growth)
 
void doLAYER (LAYER *growth)
 
void doRULE (RULE *growth)
 
void doKEEPOUT (KEEPOUT *growth)
 
void doCIRCLE (CIRCLE *growth)
 
void doQARC (QARC *growth)
 
void doWINDOW (WINDOW *growth)
 
void doCONNECT (CONNECT *growth)
 
void doREGION (REGION *growth)
 
void doCLASS_CLASS (CLASS_CLASS *growth)
 
void doLAYER_RULE (LAYER_RULE *growth)
 
void doCLASSES (CLASSES *growth)
 
void doGRID (GRID *growth)
 
void doPLACE (PLACE *growth)
 
void doCOMPONENT (COMPONENT *growth)
 
void doPLACEMENT (PLACEMENT *growth)
 
void doPROPERTIES (PROPERTIES *growth)
 
void doPADSTACK (PADSTACK *growth)
 
void doSHAPE (SHAPE *growth)
 
void doIMAGE (IMAGE *growth)
 
void doLIBRARY (LIBRARY *growth)
 
void doPIN (PIN *growth)
 
void doNET (NET *growth)
 
void doNETWORK (NETWORK *growth)
 
void doCLASS (CLASS *growth)
 
void doTOPOLOGY (TOPOLOGY *growth)
 
void doFROMTO (FROMTO *growth)
 
void doCOMP_ORDER (COMP_ORDER *growth)
 
void doWIRE (WIRE *growth)
 
void doWIRE_VIA (WIRE_VIA *growth)
 
void doWIRING (WIRING *growth)
 
void doSESSION (SESSION *growth)
 
void doANCESTOR (ANCESTOR *growth)
 
void doHISTORY (HISTORY *growth)
 
void doROUTE (ROUTE *growth)
 
void doWAS_IS (WAS_IS *growth)
 
void doNET_OUT (NET_OUT *growth)
 
void doSUPPLY_PIN (SUPPLY_PIN *growth)
 
void fillBOUNDARY (BOARD *aBoard, BOUNDARY *aBoundary)
 Make the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tree. More...
 
IMAGEmakeIMAGE (BOARD *aBoard, FOOTPRINT *aFootprint)
 Allocates an I::MAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT. More...
 
PADSTACKmakePADSTACK (BOARD *aBoard, PAD *aPad)
 Create a #PADSTACK which matches the given pad. More...
 
PADSTACKmakeVia (int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
 Make a round through hole #PADSTACK using the given KiCad diameter in deci-mils. More...
 
PADSTACKmakeVia (const ::PCB_VIA *aVia)
 Make any kind of #PADSTACK using the given KiCad #VIA. More...
 
void deleteNETs ()
 Delete all the NETs that may be in here. More...
 
void exportNETCLASS (const std::shared_ptr< NETCLASS > &aNetClass, BOARD *aBoard)
 Export aNetClass to the DSN file. More...
 
PCB_TRACKmakeTRACK (PATH *aPath, int aPointIndex, int aNetcode)
 Create a #TRACK form the #PATH and BOARD info. More...
 
PCB_VIAmakeVIA (PADSTACK *aPadstack, const POINT &aPoint, int aNetCode, int aViaDrillDefault)
 Instantiate a KiCad #VIA on the heap and initializes it with internal values consistent with the given #PADSTACK, #POINT, and netcode. More...
 

Private Attributes

PCBm_pcb
 
SHAPE_POLY_SET m_brd_outlines
 
SESSIONm_session
 
wxString m_filename
 
std::string m_quote_char
 
bool m_footprintsAreFlipped
 
STRING_FORMATTER m_sf
 
STRINGS m_layerIds
 indexed by PCB layer number More...
 
std::vector< int > m_kicadLayer2pcb
 maps BOARD layer number to PCB layer numbers More...
 
std::vector< PCB_LAYER_IDm_pcbLayer2kicad
 maps PCB layer number to BOARD layer numbers More...
 
UNIT_RESm_routeResolution
 used during FromSESSION() only, memory for it is not owned here. More...
 
BOARDm_sessionBoard
 a copy to avoid passing as an argument, memory for it is not owned here. More...
 
PADSTACKSET m_padstackset
 
std::vector< NET * > m_nets
 we don't want ownership here permanently, so we don't use boost::ptr_vector More...
 
int m_top_via_layer
 specctra cu layers, 0 based index: More...
 
int m_bot_via_layer
 

Static Private Attributes

static const KEYWORD keywords []
 specctra DSN keywords More...
 
static const KICAD_T scanPADs [] = { PCB_PAD_T, EOT }
 

Detailed Description

A DSN data tree, usually coming from a DSN file.

Is essentially a SPECCTRA_PARSER class.

Definition at line 3647 of file specctra.h.

Constructor & Destructor Documentation

◆ SPECCTRA_DB()

DSN::SPECCTRA_DB::SPECCTRA_DB ( )
inline

Definition at line 3651 of file specctra.h.

3651  :
3652  SPECCTRA_LEXER( 0 ) // LINE_READER* == nullptr, no DSNLEXER::PushReader()
3653  {
3654  // The LINE_READER will be pushed from an automatic instantiation,
3655  // we don't own it:
3656  wxASSERT( !iOwnReaders );
3657 
3658  m_pcb = 0;
3659  m_session = 0;
3660  m_quote_char += '"';
3661  m_footprintsAreFlipped = false;
3662 
3663  SetSpecctraMode( true );
3664 
3665  // Avoid not initialized members:
3666  m_routeResolution = nullptr;
3667  m_sessionBoard = nullptr;
3668  m_top_via_layer = 0;
3669  m_bot_via_layer = 0;
3670  }
BOARD * m_sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3998
bool m_footprintsAreFlipped
Definition: specctra.h:3985
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:4008
UNIT_RES * m_routeResolution
used during FromSESSION() only, memory for it is not owned here.
Definition: specctra.h:3995
SESSION * m_session
Definition: specctra.h:3981
std::string m_quote_char
Definition: specctra.h:3983

References m_bot_via_layer, m_footprintsAreFlipped, m_pcb, m_quote_char, m_routeResolution, m_session, m_sessionBoard, and m_top_via_layer.

◆ ~SPECCTRA_DB()

virtual DSN::SPECCTRA_DB::~SPECCTRA_DB ( )
inlinevirtual

Definition at line 3672 of file specctra.h.

3673  {
3674  delete m_pcb;
3675  delete m_session;
3676 
3677  deleteNETs();
3678  }
void deleteNETs()
Delete all the NETs that may be in here.
Definition: specctra.h:3945
SESSION * m_session
Definition: specctra.h:3981

References deleteNETs(), m_pcb, and m_session.

Member Function Documentation

◆ buildLayerMaps()

void DSN::SPECCTRA_DB::buildLayerMaps ( BOARD aBoard)
private

Create a few data translation structures for layer name and number mapping between the DSN::PCB structure and the KiCad BOARD structure.

Parameters
aBoardThe BOARD to create the maps for.

Definition at line 76 of file specctra.cpp.

77 {
78  // specctra wants top physical layer first, then going down to the
79  // bottom most physical layer in physical sequence.
80  // Same as KiCad now except for B_Cu
81  unsigned layerCount = aBoard->GetCopperLayerCount();
82 
83  m_layerIds.clear();
84  m_pcbLayer2kicad.resize( layerCount );
85  m_kicadLayer2pcb.resize( B_Cu + 1 );
86 
87 #if 0 // was:
88  for( LAYER_NUM kiNdx = layerCount - 1, pcbNdx=FIRST_LAYER; kiNdx >= 0; --kiNdx, ++pcbNdx )
89  {
90  LAYER_NUM kilayer = (kiNdx>0 && kiNdx==layerCount-1) ? F_Cu : kiNdx;
91 
92  // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
93  pcbLayer2kicad[pcbNdx] = kilayer;
94  kicadLayer2pcb[kilayer] = pcbNdx;
95 
96  // save the specctra layer name in SPECCTRA_DB::layerIds for later.
97  layerIds.push_back( TO_UTF8( aBoard->GetLayerName( ToLAYER_ID( kilayer ) ) ) );
98  }
99 #else
100 
101  // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
102 
103  for( unsigned i = 0; i < m_kicadLayer2pcb.size(); ++i )
104  {
105  if( i < layerCount-1 )
106  m_kicadLayer2pcb[i] = i;
107  else
108  m_kicadLayer2pcb[i] = layerCount - 1;
109  }
110 
111  for( unsigned i = 0; i < m_pcbLayer2kicad.size(); ++i )
112  {
113  PCB_LAYER_ID id = ( i < layerCount-1 ) ? ToLAYER_ID( i ) : B_Cu;
114 
115  m_pcbLayer2kicad[i] = id;
116 
117  // save the specctra layer name in SPECCTRA_DB::layerIds for later.
118  m_layerIds.push_back(TO_UTF8( aBoard->GetLayerName( id ) ) );
119  }
120 
121 #endif
122 }
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:361
int LAYER_NUM
This can be replaced with int and removed.
Definition: layer_ids.h:40
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3989
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
std::vector< int > m_kicadLayer2pcb
maps BOARD layer number to PCB layer numbers
Definition: specctra.h:3991
std::vector< PCB_LAYER_ID > m_pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
Definition: specctra.h:3992
#define FIRST_LAYER
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:64
Definition: layer_ids.h:70
int GetCopperLayerCount() const
Definition: board.cpp:454
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905

References B_Cu, F_Cu, FIRST_LAYER, BOARD::GetCopperLayerCount(), BOARD::GetLayerName(), m_kicadLayer2pcb, m_layerIds, m_pcbLayer2kicad, TO_UTF8, and ToLAYER_ID().

Referenced by FromBOARD(), and FromSESSION().

◆ BuiltBoardOutlines()

bool DSN::SPECCTRA_DB::BuiltBoardOutlines ( BOARD aBoard)

Build the board outlines and store it in m_brd_outlines.

Because it calls GetBoardPolygonOutlines() it must be called before flipping footprints

Returns
false if the board outlines cannot be built (not closed outlines)

Definition at line 246 of file specctra_export.cpp.

247 {
248  return aBoard->GetBoardPolygonOutlines( m_brd_outlines );
249 }
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1899
SHAPE_POLY_SET m_brd_outlines
Definition: specctra.h:3980

References BOARD::GetBoardPolygonOutlines(), and m_brd_outlines.

Referenced by ExportBoardToSpecctraFile().

◆ deleteNETs()

void DSN::SPECCTRA_DB::deleteNETs ( )
inlineprivate

Delete all the NETs that may be in here.

Definition at line 3945 of file specctra.h.

3946  {
3947  for( unsigned n = 0; n < m_nets.size(); ++n )
3948  delete m_nets[n];
3949 
3950  m_nets.clear();
3951  }
std::vector< NET * > m_nets
we don't want ownership here permanently, so we don't use boost::ptr_vector
Definition: specctra.h:4005

References m_nets.

Referenced by FromBOARD(), and ~SPECCTRA_DB().

◆ doANCESTOR()

void DSN::SPECCTRA_DB::doANCESTOR ( ANCESTOR growth)
private

Definition at line 3275 of file specctra.cpp.

3276 {
3277  T tok;
3278 
3279  /* <ancestor_file_descriptor >::=
3280  (ancestor <file_path_name> (created_time <time_stamp> )
3281  [(comment <comment_string> )])
3282  */
3283 
3284  NeedSYMBOL();
3285  growth->filename = CurText();
3286 
3287  while( ( tok = NextTok() ) != T_RIGHT )
3288  {
3289  if( tok != T_LEFT )
3290  Expecting( T_LEFT );
3291 
3292  tok = NextTok();
3293 
3294  switch( tok )
3295  {
3296  case T_created_time:
3297  readTIME( &growth->time_stamp );
3298  NeedRIGHT();
3299  break;
3300 
3301  case T_comment:
3302  NeedSYMBOL();
3303  growth->comment = CurText();
3304  NeedRIGHT();
3305  break;
3306 
3307  default:
3308  Unexpected( CurText() );
3309  }
3310  }
3311 }
void readTIME(time_t *time_stamp)
Read a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : second year".
Definition: specctra.cpp:179

References DSN::ANCESTOR::comment, DSN::ANCESTOR::filename, readTIME(), and DSN::ANCESTOR::time_stamp.

Referenced by doHISTORY().

◆ doBOUNDARY()

void DSN::SPECCTRA_DB::doBOUNDARY ( BOUNDARY growth)
private

Definition at line 1036 of file specctra.cpp.

1037 {
1038  T tok = NextTok();
1039 
1040  if( tok != T_LEFT )
1041  Expecting( T_LEFT );
1042 
1043  tok = NextTok();
1044 
1045  if( tok == T_rect )
1046  {
1047  if( growth->paths.size() )
1048  Unexpected( "rect when path already encountered" );
1049 
1050  growth->rectangle = new RECTANGLE( growth );
1051  doRECTANGLE( growth->rectangle );
1052  NeedRIGHT();
1053  }
1054  else if( tok == T_path )
1055  {
1056  if( growth->rectangle )
1057  Unexpected( "path when rect already encountered" );
1058 
1059  for(;;)
1060  {
1061  if( tok != T_path )
1062  Expecting( T_path );
1063 
1064  PATH* path = new PATH( growth, T_path );
1065  growth->paths.push_back( path );
1066 
1067  doPATH( path );
1068 
1069  tok = NextTok();
1070  if( tok == T_RIGHT )
1071  break;
1072 
1073  if( tok != T_LEFT )
1074  Expecting(T_LEFT);
1075 
1076  tok = NextTok();
1077  }
1078  }
1079  else
1080  {
1081  Expecting( "rect|path" );
1082  }
1083 }
void doPATH(PATH *growth)
Definition: specctra.cpp:1086
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1137

References doPATH(), doRECTANGLE(), path, DSN::BOUNDARY::paths, RECTANGLE, and DSN::BOUNDARY::rectangle.

Referenced by doSTRUCTURE().

◆ doCIRCLE()

void DSN::SPECCTRA_DB::doCIRCLE ( CIRCLE growth)
private

Definition at line 1166 of file specctra.cpp.

1167 {
1168  T tok;
1169 
1170  NeedSYMBOLorNUMBER();
1171  growth->layer_id = CurText();
1172 
1173  if( NextTok() != T_NUMBER )
1174  Expecting( T_NUMBER );
1175 
1176  growth->diameter = strtod( CurText(), 0 );
1177 
1178  tok = NextTok();
1179 
1180  if( tok == T_NUMBER )
1181  {
1182  growth->vertex.x = strtod( CurText(), 0 );
1183 
1184  if( NextTok() != T_NUMBER )
1185  Expecting( T_NUMBER );
1186 
1187  growth->vertex.y = strtod( CurText(), 0 );
1188 
1189  tok = NextTok();
1190  }
1191 
1192  if( tok != T_RIGHT )
1193  Expecting( T_RIGHT );
1194 }

References DSN::CIRCLE::diameter, DSN::CIRCLE::layer_id, DSN::CIRCLE::vertex, DSN::POINT::x, and DSN::POINT::y.

Referenced by doKEEPOUT(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doCLASS()

void DSN::SPECCTRA_DB::doCLASS ( CLASS growth)
private

Definition at line 2697 of file specctra.cpp.

2698 {
2699  T tok;
2700 
2701  /* <class_descriptor >::=
2702  (class
2703  <class_id > {[{<net_id >} | {<composite_name_list> }]}
2704  [<circuit_descriptor> ]
2705  [<rule_descriptor> ]
2706  [{<layer_rule_descriptor> }]
2707  [<topology_descriptor> ]
2708  )
2709  */
2710 
2711  NeedSYMBOL();
2712 
2713  growth->class_id = CurText();
2714 
2715  // do net_ids, do not support <composite_name_list>s at this time
2716  while( IsSymbol( tok = NextTok() ) )
2717  {
2718  growth->net_ids.push_back( CurText() );
2719  }
2720 
2721 
2722  while( tok != T_RIGHT )
2723  {
2724  if( tok != T_LEFT )
2725  Expecting( T_LEFT );
2726 
2727  tok = NextTok();
2728 
2729  switch( tok )
2730  {
2731  case T_rule:
2732  if( growth->rules )
2733  Unexpected( tok );
2734 
2735  growth->rules = new RULE( growth, T_rule );
2736  doRULE( growth->rules );
2737  break;
2738 
2739  case T_layer_rule:
2740  LAYER_RULE* layer_rule;
2741  layer_rule = new LAYER_RULE( growth );
2742  growth->layer_rules.push_back( layer_rule );
2743  doLAYER_RULE( layer_rule );
2744  break;
2745 
2746  case T_topology:
2747  if( growth->topology )
2748  Unexpected( tok );
2749 
2750  growth->topology = new TOPOLOGY( growth );
2751  doTOPOLOGY( growth->topology );
2752  break;
2753 
2754  case T_circuit: // handle all the circuit_descriptor here as strings
2755  {
2756  std::string builder;
2757  int bracketNesting = 1; // we already saw the opening T_LEFT
2758  tok = T_NONE;
2759 
2760  while( bracketNesting != 0 && tok != T_EOF )
2761  {
2762  tok = NextTok();
2763 
2764  if( tok == T_LEFT )
2765  ++bracketNesting;
2766  else if( tok == T_RIGHT )
2767  --bracketNesting;
2768 
2769  if( bracketNesting >= 1 )
2770  {
2771  T previousTok = (T) PrevTok();
2772 
2773  if( previousTok != T_LEFT && previousTok != T_circuit && tok != T_RIGHT )
2774  builder += ' ';
2775 
2776  if( tok == T_STRING )
2777  builder += m_quote_char;
2778 
2779  builder += CurText();
2780 
2781  if( tok == T_STRING )
2782  builder += m_quote_char;
2783  }
2784 
2785  // When the nested rule is closed with a T_RIGHT and we are back down
2786  // to bracketNesting == 0, then save the builder and break;
2787  if( bracketNesting == 0 )
2788  {
2789  growth->circuit.push_back( builder );
2790  break;
2791  }
2792  }
2793 
2794  if( tok == T_EOF )
2795  Unexpected( T_EOF );
2796 
2797  break;
2798  } // scope bracket
2799 
2800  default:
2801  Unexpected( CurText() );
2802  } // switch
2803 
2804  tok = NextTok();
2805 
2806  } // while
2807 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doTOPOLOGY(TOPOLOGY *growth)
Definition: specctra.cpp:2658
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1851
std::string m_quote_char
Definition: specctra.h:3983

References DSN::CLASS::circuit, DSN::CLASS::class_id, doLAYER_RULE(), doRULE(), doTOPOLOGY(), DSN::CLASS::layer_rules, m_quote_char, DSN::CLASS::net_ids, RULE, DSN::CLASS::rules, and DSN::CLASS::topology.

Referenced by doNETWORK().

◆ doCLASS_CLASS()

void DSN::SPECCTRA_DB::doCLASS_CLASS ( CLASS_CLASS growth)
private

Definition at line 1702 of file specctra.cpp.

1703 {
1704  T tok = NextTok();
1705 
1706  if( tok != T_LEFT )
1707  Expecting( T_LEFT );
1708 
1709  while( ( tok = NextTok() ) != T_RIGHT )
1710  {
1711  switch( tok )
1712  {
1713  case T_classes:
1714  if( growth->classes )
1715  Unexpected( tok );
1716 
1717  growth->classes = new CLASSES( growth );
1718  doCLASSES( growth->classes );
1719  break;
1720 
1721  case T_rule:
1722  // only T_class_class takes a T_rule
1723  if( growth->Type() == T_region_class_class )
1724  Unexpected( tok );
1725 
1726  RULE* rule;
1727  rule = new RULE( growth, T_rule );
1728  growth->Append( rule );
1729  doRULE( rule );
1730  break;
1731 
1732  case T_layer_rule:
1733  // only T_class_class takes a T_layer_rule
1734  if( growth->Type() == T_region_class_class )
1735  Unexpected( tok );
1736 
1737  LAYER_RULE* layer_rule;
1738  layer_rule = new LAYER_RULE( growth );
1739  growth->Append( layer_rule );
1740  doLAYER_RULE( layer_rule );
1741  break;
1742 
1743  default:
1744  Unexpected( tok );
1745  }
1746  }
1747 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doCLASSES(CLASSES *growth)
Definition: specctra.cpp:1750
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1851

References DSN::ELEM_HOLDER::Append(), DSN::CLASS_CLASS::classes, doCLASSES(), doLAYER_RULE(), doRULE(), RULE, and DSN::ELEM::Type().

Referenced by doREGION().

◆ doCLASSES()

void DSN::SPECCTRA_DB::doCLASSES ( CLASSES growth)
private

Definition at line 1750 of file specctra.cpp.

1751 {
1752  T tok = NextTok();
1753 
1754  // require at least 2 class_ids
1755 
1756  if( !IsSymbol( tok ) )
1757  Expecting( "class_id" );
1758 
1759  growth->class_ids.push_back( CurText() );
1760 
1761  do
1762  {
1763  tok = NextTok();
1764 
1765  if( !IsSymbol( tok ) )
1766  Expecting( "class_id" );
1767 
1768  growth->class_ids.push_back( CurText() );
1769 
1770  } while( ( tok = NextTok() ) != T_RIGHT );
1771 }

References DSN::CLASSES::class_ids.

Referenced by doCLASS_CLASS().

◆ doCOMP_ORDER()

void DSN::SPECCTRA_DB::doCOMP_ORDER ( COMP_ORDER growth)
private

Definition at line 2856 of file specctra.cpp.

2857 {
2858  T tok;
2859 
2860  /* <component_order_descriptor >::=
2861  (comp_order {<placement_id> })
2862  */
2863 
2864  while( IsSymbol( tok = NextTok() ) )
2865  {
2866  growth->placement_ids.push_back( CurText() );
2867  }
2868 
2869  if( tok != T_RIGHT )
2870  Expecting( T_RIGHT );
2871 }

References DSN::COMP_ORDER::placement_ids.

Referenced by doNET(), and doTOPOLOGY().

◆ doCOMPONENT()

void DSN::SPECCTRA_DB::doCOMPONENT ( COMPONENT growth)
private

Definition at line 2011 of file specctra.cpp.

2012 {
2013  T tok = NextTok();
2014 
2015  if( !IsSymbol( tok ) && tok != T_NUMBER )
2016  Expecting( "image_id" );
2017 
2018  growth->image_id = CurText();
2019 
2020  while( ( tok = NextTok() ) != T_RIGHT )
2021  {
2022  if( tok != T_LEFT )
2023  Expecting( T_LEFT );
2024 
2025  tok = NextTok();
2026 
2027  switch( tok )
2028  {
2029  case T_place:
2030  PLACE* place;
2031  place = new PLACE( growth );
2032  growth->places.push_back( place );
2033  doPLACE( place );
2034  break;
2035 
2036  default:
2037  Unexpected( tok );
2038  }
2039  }
2040 }
void doPLACE(PLACE *growth)
Definition: specctra.cpp:1876

References doPLACE(), DSN::COMPONENT::image_id, PLACE, and DSN::COMPONENT::places.

Referenced by doPLACEMENT().

◆ doCONNECT()

void DSN::SPECCTRA_DB::doCONNECT ( CONNECT growth)
private

Definition at line 942 of file specctra.cpp.

943 {
944  /* from page 143 of specctra spec:
945 
946  (connect
947  {(terminal <object_type> [<pin_reference> ])}
948  )
949  */
950 
951  T tok = NextTok();
952 
953  while( tok != T_RIGHT )
954  {
955  if( tok!=T_LEFT )
956  Expecting( T_LEFT );
957 
958  tok = NextTok();
959 
960  switch( tok )
961  {
962  case T_terminal:
963  // since we do not use the terminal information, simply toss it.
964  while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
965  ;
966  break;
967 
968  default:
969  Unexpected( CurText() );
970  }
971 
972  tok = NextTok();
973  }
974 }

Referenced by doWIRE().

◆ doCONTROL()

void DSN::SPECCTRA_DB::doCONTROL ( CONTROL growth)
private

Definition at line 1276 of file specctra.cpp.

1277 {
1278  T tok;
1279 
1280  while( (tok = NextTok()) != T_RIGHT )
1281  {
1282  if( tok != T_LEFT )
1283  Expecting( T_LEFT );
1284 
1285  tok = NextTok();
1286 
1287  switch( tok )
1288  {
1289  case T_via_at_smd:
1290  tok = NextTok();
1291 
1292  if( tok!=T_on && tok!=T_off )
1293  Expecting( "on|off" );
1294 
1295  growth->via_at_smd = (tok==T_on);
1296  NeedRIGHT();
1297  break;
1298 
1299  case T_off_grid:
1300  case T_route_to_fanout_only:
1301  case T_force_to_terminal_point:
1302  case T_same_net_checking:
1303  case T_checking_trim_by_pin:
1304  case T_noise_calculation:
1305  case T_noise_accumulation:
1306  case T_include_pins_in_crosstalk:
1307  case T_bbv_ctr2ctr:
1308  case T_average_pair_length:
1309  case T_crosstalk_model:
1310  case T_roundoff_rotation:
1311  case T_microvia:
1312  case T_reroute_order_viols:
1313  TOKPROP* tokprop;
1314  tokprop = new TOKPROP( growth, tok );
1315  growth->Append( tokprop );
1316  doTOKPROP( tokprop );
1317  break;
1318 
1319  default:
1320  Unexpected( CurText() );
1321  }
1322  }
1323 }
void doTOKPROP(TOKPROP *growth)
Definition: specctra.cpp:1232

References DSN::ELEM_HOLDER::Append(), doTOKPROP(), and DSN::CONTROL::via_at_smd.

Referenced by doSTRUCTURE().

◆ doFROMTO()

void DSN::SPECCTRA_DB::doFROMTO ( FROMTO growth)
private

Definition at line 2874 of file specctra.cpp.

2875 {
2876  T tok;
2877 
2878  /* <fromto_descriptor >::=
2879  {(fromto
2880  [<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
2881  [<pin_reference> | <virtual_pin_descriptor> | <component_id >]
2882  [(type [fix | normal | soft])]
2883  [(net <net_id >)]
2884  [<rule_descriptor> ]
2885  [<circuit_descriptor> ]
2886  [{<layer_rule_descriptor> }]
2887  )}
2888  */
2889 
2890 
2891  // read the first two grammar items in as 2 single tokens, i.e. do not
2892  // split apart the <pin_reference>s into 3 separate tokens. Do this by
2893  // turning off the string delimiter in the lexer.
2894 
2895  char old = SetStringDelimiter( 0 );
2896 
2897  if( !IsSymbol(NextTok() ) )
2898  {
2899  SetStringDelimiter( old );
2900  Expecting( T_SYMBOL );
2901  }
2902 
2903  growth->fromText = CurText();
2904 
2905  if( !IsSymbol(NextTok() ) )
2906  {
2907  SetStringDelimiter( old );
2908  Expecting( T_SYMBOL );
2909  }
2910 
2911  growth->toText = CurText();
2912 
2913  SetStringDelimiter( old );
2914 
2915  while( ( tok = NextTok() ) != T_RIGHT )
2916  {
2917  if( tok != T_LEFT )
2918  Expecting( T_LEFT );
2919 
2920  tok = NextTok();
2921 
2922  switch( tok )
2923  {
2924  case T_type:
2925  tok = NextTok();
2926 
2927  if( tok != T_fix && tok != T_normal && tok != T_soft )
2928  Expecting( "fix|normal|soft" );
2929 
2930  growth->fromto_type = tok;
2931  NeedRIGHT();
2932  break;
2933 
2934  case T_rule:
2935  if( growth->rules )
2936  Unexpected( tok );
2937 
2938  growth->rules = new RULE( growth, T_rule );
2939  doRULE( growth->rules );
2940  break;
2941 
2942  case T_layer_rule:
2943  LAYER_RULE* layer_rule;
2944  layer_rule = new LAYER_RULE( growth );
2945  growth->layer_rules.push_back( layer_rule );
2946  doLAYER_RULE( layer_rule );
2947  break;
2948 
2949  case T_net:
2950  if( growth->net_id.size() )
2951  Unexpected( tok );
2952 
2953  NeedSYMBOL();
2954  growth->net_id = CurText();
2955  NeedRIGHT();
2956  break;
2957 
2958  // circuit descriptor not supported at this time
2959 
2960  default:
2961  Unexpected( CurText() );
2962  }
2963  }
2964 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1851

References doLAYER_RULE(), doRULE(), DSN::FROMTO::fromText, DSN::FROMTO::fromto_type, DSN::FROMTO::layer_rules, DSN::FROMTO::net_id, RULE, DSN::FROMTO::rules, and DSN::FROMTO::toText.

Referenced by doNET(), and doTOPOLOGY().

◆ doGRID()

void DSN::SPECCTRA_DB::doGRID ( GRID growth)
private

Definition at line 1774 of file specctra.cpp.

1775 {
1776  T tok = NextTok();
1777 
1778  switch( tok )
1779  {
1780  case T_via:
1781  case T_wire:
1782  case T_via_keepout:
1783  case T_snap:
1784  case T_place:
1785  growth->grid_type = tok;
1786 
1787  if( NextTok() != T_NUMBER )
1788  Expecting( T_NUMBER );
1789 
1790  growth->dimension = strtod( CurText(), 0 );
1791  tok = NextTok();
1792 
1793  if( tok == T_LEFT )
1794  {
1795  while( ( tok = NextTok() ) != T_RIGHT )
1796  {
1797  if( tok == T_direction )
1798  {
1799  if( growth->grid_type == T_place )
1800  Unexpected( tok );
1801 
1802  tok = NextTok();
1803 
1804  if( tok != T_x && tok != T_y )
1805  Unexpected( CurText() );
1806 
1807  growth->direction = tok;
1808 
1809  if( NextTok() != T_RIGHT )
1810  Expecting(T_RIGHT);
1811  }
1812  else if( tok == T_offset )
1813  {
1814  if( growth->grid_type == T_place )
1815  Unexpected( tok );
1816 
1817  if( NextTok() != T_NUMBER )
1818  Expecting( T_NUMBER );
1819 
1820  growth->offset = strtod( CurText(), 0 );
1821 
1822  if( NextTok() != T_RIGHT )
1823  Expecting( T_RIGHT );
1824  }
1825  else if( tok == T_image_type )
1826  {
1827  if( growth->grid_type != T_place )
1828  Unexpected( tok );
1829 
1830  tok = NextTok();
1831 
1832  if( tok != T_smd && tok != T_pin )
1833  Unexpected( CurText() );
1834 
1835  growth->image_type = tok;
1836 
1837  if( NextTok() != T_RIGHT )
1838  Expecting( T_RIGHT );
1839  }
1840  }
1841  }
1842 
1843  break;
1844 
1845  default:
1846  Unexpected( tok );
1847  }
1848 }

References DSN::GRID::dimension, DSN::GRID::direction, DSN::GRID::grid_type, DSN::GRID::image_type, and DSN::GRID::offset.

Referenced by doSTRUCTURE().

◆ doHISTORY()

void DSN::SPECCTRA_DB::doHISTORY ( HISTORY growth)
private

Definition at line 3314 of file specctra.cpp.

3315 {
3316  T tok;
3317 
3318  /* <history_descriptor >::=
3319  (history [{<ancestor_file_descriptor> }] <self_descriptor> )
3320  */
3321 
3322  while( ( tok = NextTok() ) != T_RIGHT )
3323  {
3324  if( tok != T_LEFT )
3325  Expecting( T_LEFT );
3326 
3327  tok = NextTok();
3328 
3329  switch( tok )
3330  {
3331  case T_ancestor:
3332  ANCESTOR* ancestor;
3333  ancestor = new ANCESTOR( growth );
3334  growth->ancestors.push_back( ancestor );
3335  doANCESTOR( ancestor );
3336  break;
3337 
3338  case T_self:
3339  while( ( tok = NextTok() ) != T_RIGHT )
3340  {
3341  if( tok != T_LEFT )
3342  Expecting( T_LEFT );
3343 
3344  tok = NextTok();
3345 
3346  switch( tok )
3347  {
3348  case T_created_time:
3349  readTIME( &growth->time_stamp );
3350  NeedRIGHT();
3351  break;
3352 
3353  case T_comment:
3354  NeedSYMBOL();
3355  growth->comments.push_back( CurText() );
3356  NeedRIGHT();
3357  break;
3358 
3359  default:
3360  Unexpected( CurText() );
3361  }
3362  }
3363 
3364  break;
3365 
3366  default:
3367  Unexpected( CurText() );
3368  }
3369  }
3370 }
void doANCESTOR(ANCESTOR *growth)
Definition: specctra.cpp:3275
void readTIME(time_t *time_stamp)
Read a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : second year".
Definition: specctra.cpp:179

References DSN::HISTORY::ancestors, DSN::HISTORY::comments, doANCESTOR(), readTIME(), and DSN::HISTORY::time_stamp.

Referenced by doSESSION().

◆ doIMAGE()

void DSN::SPECCTRA_DB::doIMAGE ( IMAGE growth)
private

Definition at line 2301 of file specctra.cpp.

2302 {
2303  T tok = NextTok();
2304 
2305  /* <image_descriptor >::=
2306  (image <image_id >
2307  [(side [front | back | both])]
2308  [<unit_descriptor> ]
2309  [<outline_descriptor> ]
2310  {(pin <padstack_id > [(rotate <rotation> )]
2311  [<reference_descriptor> | <pin_array_descriptor> ]
2312  [<user_property_descriptor> ])}
2313  [{<conductor_shape_descriptor> }]
2314  [{<conductor_via_descriptor> }]
2315  [<rule_descriptor> ]
2316  [<place_rule_descriptor> ]
2317  [{<keepout_descriptor> }]
2318  [<image_property_descriptor> ]
2319  )
2320  */
2321 
2322  if( !IsSymbol( tok ) && tok != T_NUMBER )
2323  Expecting( "image_id" );
2324 
2325  growth->image_id = CurText();
2326 
2327  while( ( tok = NextTok() ) != T_RIGHT )
2328  {
2329  if( tok != T_LEFT )
2330  Expecting( T_LEFT );
2331 
2332  tok = NextTok();
2333 
2334  switch( tok )
2335  {
2336  case T_unit:
2337  if( growth->unit )
2338  Unexpected( tok );
2339 
2340  growth->unit = new UNIT_RES( growth, tok );
2341  doUNIT( growth->unit );
2342  break;
2343 
2344  case T_side:
2345  tok = NextTok();
2346 
2347  if( tok != T_front && tok != T_back && tok != T_both )
2348  Expecting( "front|back|both" );
2349 
2350  growth->side = tok;
2351  NeedRIGHT();
2352  break;
2353 
2354  case T_outline:
2355  SHAPE* outline;
2356  outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
2357  growth->Append( outline );
2358  doSHAPE( outline );
2359  break;
2360 
2361  case T_pin:
2362  PIN* pin;
2363  pin = new PIN( growth );
2364  growth->pins.push_back( pin );
2365  doPIN( pin );
2366  break;
2367 
2368  case T_rule:
2369  if( growth->rules )
2370  Unexpected( tok );
2371 
2372  growth->rules = new RULE( growth, tok );
2373  doRULE( growth->rules );
2374  break;
2375 
2376  case T_place_rule:
2377  if( growth->place_rules )
2378  Unexpected( tok );
2379 
2380  growth->place_rules = new RULE( growth, tok );
2381  doRULE( growth->place_rules );
2382  break;
2383 
2384  case T_keepout:
2385  case T_place_keepout:
2386  case T_via_keepout:
2387  case T_wire_keepout:
2388  case T_bend_keepout:
2389  case T_elongate_keepout:
2390  KEEPOUT* keepout;
2391  keepout = new KEEPOUT( growth, tok );
2392  growth->keepouts.push_back( keepout );
2393  doKEEPOUT( keepout );
2394  break;
2395 
2396  default:
2397  Unexpected( CurText() );
2398  }
2399  }
2400 }
void doKEEPOUT(KEEPOUT *growth)
Definition: specctra.cpp:843
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
An abstract shape on 2D plane.
Definition: shape.h:116
void doPIN(PIN *growth)
Definition: specctra.cpp:2403
void doSHAPE(SHAPE *growth)
Definition: specctra.cpp:2213
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595

References DSN::ELEM_HOLDER::Append(), doKEEPOUT(), doPIN(), doRULE(), doSHAPE(), doUNIT(), DSN::IMAGE::image_id, DSN::IMAGE::keepouts, PIN, pin, DSN::IMAGE::pins, DSN::IMAGE::place_rules, RULE, DSN::IMAGE::rules, DSN::IMAGE::side, and DSN::IMAGE::unit.

Referenced by doLIBRARY().

◆ doKEEPOUT()

void DSN::SPECCTRA_DB::doKEEPOUT ( KEEPOUT growth)
private

Definition at line 843 of file specctra.cpp.

844 {
845  T tok = NextTok();
846 
847  if( IsSymbol(tok) )
848  {
849  growth->name = CurText();
850  tok = NextTok();
851  }
852 
853  if( tok!=T_LEFT )
854  Expecting( T_LEFT );
855 
856  while( tok != T_RIGHT )
857  {
858  if( tok!=T_LEFT )
859  Expecting( T_LEFT );
860 
861  tok = NextTok();
862 
863  switch( tok )
864  {
865  case T_sequence_number:
866  if( NextTok() != T_NUMBER )
867  Expecting( T_NUMBER );
868 
869  growth->sequence_number = atoi( CurText() );
870  NeedRIGHT();
871  break;
872 
873  case T_rule:
874  if( growth->rules )
875  Unexpected( tok );
876 
877  growth->rules = new RULE( growth, T_rule );
878  doRULE( growth->rules );
879  break;
880 
881  case T_place_rule:
882  if( growth->place_rules )
883  Unexpected( tok );
884 
885  growth->place_rules = new RULE( growth, T_place_rule );
886  doRULE( growth->place_rules );
887  break;
888 
889  case T_rect:
890  if( growth->shape )
891  Unexpected( tok );
892 
893  growth->shape = new RECTANGLE( growth );
894  doRECTANGLE( (RECTANGLE*) growth->shape );
895  break;
896 
897  case T_circle:
898  if( growth->shape )
899  Unexpected( tok );
900 
901  growth->shape = new CIRCLE( growth );
902  doCIRCLE( (CIRCLE*) growth->shape );
903  break;
904 
905  case T_polyline_path:
906  tok = T_path;
908 
909  case T_path:
910  case T_polygon:
911  if( growth->shape )
912  Unexpected( tok );
913 
914  growth->shape = new PATH( growth, tok );
915  doPATH( (PATH*) growth->shape );
916  break;
917 
918  case T_qarc:
919  if( growth->shape )
920  Unexpected( tok );
921 
922  growth->shape = new QARC( growth );
923  doQARC( (QARC*) growth->shape );
924  break;
925 
926  case T_window:
927  WINDOW* window;
928  window = new WINDOW( growth );
929  growth->windows.push_back( window );
930  doWINDOW( window );
931  break;
932 
933  default:
934  Unexpected( CurText() );
935  }
936 
937  tok = NextTok();
938  }
939 }
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:977
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doPATH(PATH *growth)
Definition: specctra.cpp:1086
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1137
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:32
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1166
void doQARC(QARC *growth)
Definition: specctra.cpp:1197

References CIRCLE, doCIRCLE(), doPATH(), doQARC(), doRECTANGLE(), doRULE(), doWINDOW(), KI_FALLTHROUGH, DSN::KEEPOUT::name, DSN::KEEPOUT::place_rules, RECTANGLE, RULE, DSN::KEEPOUT::rules, DSN::KEEPOUT::sequence_number, DSN::KEEPOUT::shape, and DSN::KEEPOUT::windows.

Referenced by doIMAGE(), and doSTRUCTURE().

◆ doLAYER()

void DSN::SPECCTRA_DB::doLAYER ( LAYER growth)
private

Definition at line 1349 of file specctra.cpp.

1350 {
1351  T tok = NextTok();
1352 
1353  if( !IsSymbol( tok ) )
1354  Expecting( T_SYMBOL );
1355 
1356  growth->name = CurText();
1357 
1358  while( ( tok = NextTok() ) != T_RIGHT )
1359  {
1360  if( tok != T_LEFT )
1361  Expecting( T_LEFT );
1362 
1363  tok = NextTok();
1364 
1365  switch( tok )
1366  {
1367  case T_type:
1368  tok = NextTok();
1369 
1370  if( tok != T_signal && tok != T_power && tok != T_mixed && tok != T_jumper )
1371  Expecting( "signal|power|mixed|jumper" );
1372 
1373  growth->layer_type = tok;
1374 
1375  if( NextTok()!=T_RIGHT )
1376  Expecting(T_RIGHT);
1377 
1378  break;
1379 
1380  case T_rule:
1381  growth->rules = new RULE( growth, T_rule );
1382  doRULE( growth->rules );
1383  break;
1384 
1385  case T_property:
1386  doPROPERTIES( &growth->properties );
1387  break;
1388 
1389  case T_direction:
1390  tok = NextTok();
1391 
1392  switch( tok )
1393  {
1394  case T_horizontal:
1395  case T_vertical:
1396  case T_orthogonal:
1397  case T_positive_diagonal:
1398  case T_negative_diagonal:
1399  case T_diagonal:
1400  case T_off:
1401  growth->direction = tok;
1402  break;
1403  default:
1404  // the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
1405  if( !strcmp( "hori", CurText() ) )
1406  {
1407  growth->direction = T_horizontal;
1408  break;
1409  }
1410  else if( !strcmp( "vert", CurText() ) )
1411  {
1412  growth->direction = T_vertical;
1413  break;
1414  }
1415 
1416  Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|"
1417  "diagonal|off" );
1418  }
1419 
1420  if( NextTok() != T_RIGHT )
1421  Expecting( T_RIGHT );
1422 
1423  break;
1424 
1425  case T_cost:
1426  tok = NextTok();
1427 
1428  switch( tok )
1429  {
1430  case T_forbidden:
1431  case T_high:
1432  case T_medium:
1433  case T_low:
1434  case T_free:
1435  growth->cost = tok;
1436  break;
1437  case T_NUMBER:
1438  // store as negative so we can differentiate between
1439  // T (positive) and T_NUMBER (negative)
1440  growth->cost = -atoi( CurText() );
1441  break;
1442  default:
1443  Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
1444  }
1445 
1446  tok = NextTok();
1447 
1448  if( tok == T_LEFT )
1449  {
1450  if( NextTok() != T_type )
1451  Unexpected( CurText() );
1452 
1453  tok = NextTok();
1454 
1455  if( tok!=T_length && tok!=T_way )
1456  Expecting( "length|way" );
1457 
1458  growth->cost_type = tok;
1459 
1460  if( NextTok()!=T_RIGHT )
1461  Expecting( T_RIGHT );
1462 
1463  tok = NextTok();
1464  }
1465 
1466  if( tok != T_RIGHT )
1467  Expecting( T_RIGHT );
1468 
1469  break;
1470 
1471  case T_use_net:
1472  while( ( tok = NextTok() ) != T_RIGHT )
1473  {
1474  if( !IsSymbol( tok ) )
1475  Expecting( T_SYMBOL );
1476 
1477  growth->use_net.push_back( CurText() );
1478  }
1479 
1480  break;
1481 
1482  default:
1483  Unexpected( CurText() );
1484  }
1485  }
1486 }
void doPROPERTIES(PROPERTIES *growth)
Definition: specctra.cpp:1326
void doRULE(RULE *growth)
Definition: specctra.cpp:1489

References DSN::LAYER::cost, DSN::LAYER::cost_type, DSN::LAYER::direction, doPROPERTIES(), doRULE(), DSN::LAYER::layer_type, DSN::LAYER::name, DSN::LAYER::properties, RULE, DSN::LAYER::rules, and DSN::LAYER::use_net.

Referenced by doSTRUCTURE(), and doSTRUCTURE_OUT().

◆ doLAYER_NOISE_WEIGHT()

void DSN::SPECCTRA_DB::doLAYER_NOISE_WEIGHT ( LAYER_NOISE_WEIGHT growth)
private

Definition at line 633 of file specctra.cpp.

635 {
636  T tok;
637 
638  while( ( tok = NextTok() ) != T_RIGHT )
639  {
640  if( tok != T_LEFT )
641  Expecting( T_LEFT );
642 
643  if( NextTok() != T_layer_pair )
644  Expecting( T_layer_pair );
645 
646  SPECCTRA_LAYER_PAIR* layer_pair = new SPECCTRA_LAYER_PAIR( growth );
647  growth->layer_pairs.push_back( layer_pair );
648  doSPECCTRA_LAYER_PAIR( layer_pair );
649  }
650 }
void doSPECCTRA_LAYER_PAIR(SPECCTRA_LAYER_PAIR *growth)
Definition: specctra.cpp:616

References doSPECCTRA_LAYER_PAIR(), and DSN::LAYER_NOISE_WEIGHT::layer_pairs.

Referenced by doSTRUCTURE().

◆ doLAYER_RULE()

void DSN::SPECCTRA_DB::doLAYER_RULE ( LAYER_RULE growth)
private

Definition at line 1851 of file specctra.cpp.

1852 {
1853  T tok;
1854 
1855  NeedSYMBOL();
1856 
1857  do
1858  {
1859  growth->layer_ids.push_back( CurText() );
1860 
1861  } while( IsSymbol( tok = NextTok() ) );
1862 
1863  if( tok != T_LEFT )
1864  Expecting( T_LEFT );
1865 
1866  if( NextTok() != T_rule )
1867  Expecting( T_rule );
1868 
1869  growth->rule = new RULE( growth, T_rule );
1870  doRULE( growth->rule );
1871 
1872  NeedRIGHT();
1873 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1489

References doRULE(), DSN::LAYER_RULE::layer_ids, RULE, and DSN::LAYER_RULE::rule.

Referenced by doCLASS(), doCLASS_CLASS(), doFROMTO(), and doNET().

◆ doLIBRARY()

void DSN::SPECCTRA_DB::doLIBRARY ( LIBRARY growth)
private

Definition at line 2454 of file specctra.cpp.

2455 {
2456  T tok;
2457 
2458  /* <library_descriptor >::=
2459  (library
2460  [<unit_descriptor> ]
2461  {<image_descriptor> }
2462  [{<jumper_descriptor> }]
2463  {<padstack_descriptor> }
2464  {<via_array_template_descriptor> }
2465  [<directory_descriptor> ]
2466  [<extra_image_directory_descriptor> ]
2467  [{<family_family_descriptor> }]
2468  [{<image_image_descriptor> }]
2469  )
2470  */
2471 
2472  while( ( tok = NextTok() ) != T_RIGHT )
2473  {
2474  if( tok != T_LEFT )
2475  Expecting( T_LEFT );
2476 
2477  tok = NextTok();
2478 
2479  switch( tok )
2480  {
2481  case T_unit:
2482  if( growth->unit )
2483  Unexpected( tok );
2484 
2485  growth->unit = new UNIT_RES( growth, tok );
2486  doUNIT( growth->unit );
2487  break;
2488 
2489  case T_padstack:
2490  PADSTACK* padstack;
2491  padstack = new PADSTACK();
2492  growth->AddPadstack( padstack );
2493  doPADSTACK( padstack );
2494  break;
2495 
2496  case T_image:
2497  IMAGE* image;
2498  image = new IMAGE( growth );
2499  growth->images.push_back( image );
2500  doIMAGE( image );
2501  break;
2502 
2503  default:
2504  Unexpected( CurText() );
2505  }
2506  }
2507 }
void doIMAGE(IMAGE *growth)
Definition: specctra.cpp:2301
void doPADSTACK(PADSTACK *growth)
Definition: specctra.cpp:2101
Manage an 8-bit channel image.
Definition: image.h:89
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595

References DSN::LIBRARY::AddPadstack(), doIMAGE(), doPADSTACK(), doUNIT(), IMAGE, image, DSN::LIBRARY::images, and DSN::LIBRARY::unit.

Referenced by doPCB(), and doROUTE().

◆ doNET()

void DSN::SPECCTRA_DB::doNET ( NET growth)
private

Definition at line 2510 of file specctra.cpp.

2511 {
2512  T tok = NextTok();
2513  PIN_REFS* pin_refs;
2514 
2515  /* <net_descriptor >::=
2516  (net <net_id >
2517  [(unassigned)]
2518  [(net_number <integer >)]
2519  [(pins {<pin_reference> }) | (order {<pin_reference> })]
2520  [<component_order_descriptor> ]
2521  [(type [fix | normal])]
2522  [<user_property_descriptor> ]
2523  [<circuit_descriptor> ]
2524  [<rule_descriptor> ]
2525  [{<layer_rule_descriptor> }]
2526  [<fromto_descriptor> ]
2527  [(expose {<pin_reference> })]
2528  [(noexpose {<pin_reference> })]
2529  [(source {<pin_reference> })]
2530  [(load {<pin_reference> })]
2531  [(terminator {<pin_reference> })]
2532  [(supply [power | ground])]
2533  )
2534  */
2535 
2536  if( !IsSymbol( tok ) )
2537  Expecting( "net_id" );
2538 
2539  growth->net_id = CurText();
2540 
2541  while( ( tok = NextTok() ) != T_RIGHT )
2542  {
2543  if( tok != T_LEFT )
2544  Expecting( T_LEFT );
2545 
2546  tok = NextTok();
2547 
2548  switch( tok )
2549  {
2550  case T_unassigned:
2551  growth->unassigned = true;
2552  NeedRIGHT();
2553  break;
2554 
2555  case T_net_number:
2556  if( NextTok() != T_NUMBER )
2557  Expecting( T_NUMBER );
2558 
2559  growth->net_number = atoi( CurText() );
2560  NeedRIGHT();
2561  break;
2562 
2563  case T_pins:
2564  case T_order:
2565  growth->pins_type = tok;
2566  pin_refs = &growth->pins;
2567  goto L_pins;
2568 
2569  case T_expose:
2570  pin_refs = &growth->expose;
2571  goto L_pins;
2572 
2573  case T_noexpose:
2574  pin_refs = &growth->noexpose;
2575  goto L_pins;
2576 
2577  case T_source:
2578  pin_refs = &growth->source;
2579  goto L_pins;
2580 
2581  case T_load:
2582  pin_refs = &growth->load;
2583  goto L_pins;
2584 
2585  case T_terminator:
2586  pin_refs = &growth->terminator;
2587  //goto L_pins;
2588 
2589 L_pins:
2590  {
2591  PIN_REF empty( growth );
2592 
2593  while( ( tok = NextTok() ) != T_RIGHT )
2594  {
2595  // copy the empty one, then fill its copy later thru pin_ref.
2596  pin_refs->push_back( empty );
2597 
2598  PIN_REF* pin_ref = &pin_refs->back();
2599 
2600  readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
2601  }
2602  }
2603 
2604  break;
2605 
2606  case T_comp_order:
2607  if( growth->comp_order )
2608  Unexpected( tok );
2609 
2610  growth->comp_order = new COMP_ORDER( growth );
2611  doCOMP_ORDER( growth->comp_order );
2612  break;
2613 
2614  case T_type:
2615  tok = NextTok();
2616 
2617  if( tok!=T_fix && tok!=T_normal )
2618  Expecting( "fix|normal" );
2619 
2620  growth->type = tok;
2621  NeedRIGHT();
2622  break;
2623 
2624 /* @todo
2625  case T_circuit:
2626  break;
2627 */
2628 
2629  case T_rule:
2630  if( growth->rules )
2631  Unexpected( tok );
2632 
2633  growth->rules = new RULE( growth, T_rule );
2634  doRULE( growth->rules );
2635  break;
2636 
2637  case T_layer_rule:
2638  LAYER_RULE* layer_rule;
2639  layer_rule = new LAYER_RULE( growth );
2640  growth->layer_rules.push_back( layer_rule );
2641  doLAYER_RULE( layer_rule );
2642  break;
2643 
2644  case T_fromto:
2645  FROMTO* fromto;
2646  fromto = new FROMTO( growth );
2647  growth->fromtos.push_back( fromto );
2648  doFROMTO( fromto );
2649  break;
2650 
2651  default:
2652  Unexpected( CurText() );
2653  }
2654  }
2655 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doCOMP_ORDER(COMP_ORDER *growth)
Definition: specctra.cpp:2856
std::vector< PIN_REF > PIN_REFS
Definition: specctra.h:2485
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen.
Definition: specctra.cpp:137
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1851
static bool empty(const wxTextEntryBase *aCtrl)
void doFROMTO(FROMTO *growth)
Definition: specctra.cpp:2874

References DSN::NET::comp_order, DSN::PIN_REF::component_id, doCOMP_ORDER(), doFROMTO(), doLAYER_RULE(), doRULE(), empty(), DSN::NET::expose, DSN::NET::fromtos, DSN::NET::layer_rules, DSN::NET::load, DSN::NET::net_id, DSN::NET::net_number, DSN::NET::noexpose, DSN::PIN_REF::pin_id, DSN::NET::pins, DSN::NET::pins_type, readCOMPnPIN(), RULE, DSN::NET::rules, DSN::NET::source, DSN::NET::terminator, DSN::NET::type, and DSN::NET::unassigned.

Referenced by doNETWORK().

◆ doNET_OUT()

void DSN::SPECCTRA_DB::doNET_OUT ( NET_OUT growth)
private

Definition at line 3587 of file specctra.cpp.

3588 {
3589  T tok;
3590 
3591  /* <net_out_descriptor >::=
3592  (net <net_id >
3593  [(net_number <integer >)]
3594  [<rule_descriptor> ]
3595  {[<wire_shape_descriptor> | <wire_guide_descriptor> |
3596  <wire_via_descriptor> | <bond_shape_descriptor> ]}
3597  {[<supply_pin_descriptor> ]}
3598  )
3599  */
3600 
3601  NeedSYMBOLorNUMBER();
3602  growth->net_id = CurText();
3603 
3604  while( ( tok = NextTok() ) != T_RIGHT )
3605  {
3606  if( tok != T_LEFT )
3607  Expecting( T_LEFT );
3608 
3609  tok = NextTok();
3610 
3611  switch( tok )
3612  {
3613  case T_net_number:
3614  tok = NextTok();
3615 
3616  if( tok!= T_NUMBER )
3617  Expecting( T_NUMBER );
3618 
3619  growth->net_number = atoi( CurText() );
3620  NeedRIGHT();
3621  break;
3622 
3623  case T_rule:
3624  if( growth->rules )
3625  Unexpected( tok );
3626 
3627  growth->rules = new RULE( growth, tok );
3628  doRULE( growth->rules );
3629  break;
3630 
3631  case T_wire:
3632  WIRE* wire;
3633  wire = new WIRE( growth );
3634  growth->wires.push_back( wire );
3635  doWIRE( wire );
3636  break;
3637 
3638  case T_via:
3639  WIRE_VIA* wire_via;
3640  wire_via = new WIRE_VIA( growth );
3641  growth->wire_vias.push_back( wire_via );
3642  doWIRE_VIA( wire_via );
3643  break;
3644 
3645  case T_supply_pin:
3646  SUPPLY_PIN* supply_pin;
3647  supply_pin = new SUPPLY_PIN( growth );
3648  growth->supply_pins.push_back( supply_pin );
3649  doSUPPLY_PIN( supply_pin );
3650  break;
3651 
3652  default:
3653  Unexpected( CurText() );
3654  }
3655  }
3656 }
void doWIRE(WIRE *growth)
Definition: specctra.cpp:2967
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doSUPPLY_PIN(SUPPLY_PIN *growth)
Definition: specctra.cpp:3659
void doWIRE_VIA(WIRE_VIA *growth)
Definition: specctra.cpp:3101

References doRULE(), doSUPPLY_PIN(), doWIRE(), doWIRE_VIA(), DSN::NET_OUT::net_id, DSN::NET_OUT::net_number, RULE, DSN::NET_OUT::rules, DSN::NET_OUT::supply_pins, WIRE, DSN::NET_OUT::wire_vias, and DSN::NET_OUT::wires.

Referenced by doROUTE().

◆ doNETWORK()

void DSN::SPECCTRA_DB::doNETWORK ( NETWORK growth)
private

Definition at line 2810 of file specctra.cpp.

2811 {
2812  T tok;
2813 
2814  /* <network_descriptor >::=
2815  (network
2816  {<net_descriptor>}
2817  [{<class_descriptor> }]
2818  [{<class_class_descriptor> }]
2819  [{<group_descriptor> }]
2820  [{<group_set_descriptor> }]
2821  [{<pair_descriptor> }]
2822  [{<bundle_descriptor> }]
2823  )
2824  */
2825 
2826  while( ( tok = NextTok() ) != T_RIGHT )
2827  {
2828  if( tok != T_LEFT )
2829  Expecting( T_LEFT );
2830 
2831  tok = NextTok();
2832 
2833  switch( tok )
2834  {
2835  case T_net:
2836  NET* net;
2837  net = new NET( growth );
2838  growth->nets.push_back( net );
2839  doNET( net );
2840  break;
2841 
2842  case T_class:
2843  CLASS* myclass;
2844  myclass = new CLASS( growth );
2845  growth->classes.push_back( myclass );
2846  doCLASS( myclass );
2847  break;
2848 
2849  default:
2850  Unexpected( CurText() );
2851  }
2852  }
2853 }
void doNET(NET *growth)
Definition: specctra.cpp:2510
void doCLASS(CLASS *growth)
Definition: specctra.cpp:2697
This item represents a net.

References DSN::NETWORK::classes, doCLASS(), doNET(), NET, and DSN::NETWORK::nets.

Referenced by doPCB().

◆ doPADSTACK()

void DSN::SPECCTRA_DB::doPADSTACK ( PADSTACK growth)
private

Definition at line 2101 of file specctra.cpp.

2102 {
2103  T tok = NextTok();
2104 
2105  /* (padstack <padstack_id >
2106  [<unit_descriptor> ]
2107  {(shape <shape_descriptor>
2108  [<reduced_shape_descriptor> ]
2109  [(connect [on | off])]
2110  [{<window_descriptor> }]
2111  )}
2112  [<attach_descriptor> ]
2113  [{<pad_via_site_descriptor> }]
2114  [(rotate [on | off])]
2115  [(absolute [on | off])]
2116  [(rule <clearance_descriptor> )])
2117  */
2118 
2119  // padstack_id may be a number
2120  if( !IsSymbol( tok ) && tok != T_NUMBER )
2121  Expecting( "padstack_id" );
2122 
2123  growth->padstack_id = CurText();
2124 
2125  while( ( tok = NextTok() ) != T_RIGHT )
2126  {
2127  if( tok != T_LEFT )
2128  Expecting( T_LEFT );
2129 
2130  tok = NextTok();
2131 
2132  switch( tok )
2133  {
2134  case T_unit:
2135  if( growth->unit )
2136  Unexpected( tok );
2137 
2138  growth->unit = new UNIT_RES( growth, tok );
2139  doUNIT( growth->unit );
2140  break;
2141 
2142  case T_rotate:
2143  tok = NextTok();
2144 
2145  if( tok != T_on && tok != T_off )
2146  Expecting( "on|off" );
2147 
2148  growth->rotate = tok;
2149  NeedRIGHT();
2150  break;
2151 
2152  case T_absolute:
2153  tok = NextTok();
2154 
2155  if( tok != T_on && tok != T_off )
2156  Expecting( "on|off" );
2157 
2158  growth->absolute = tok;
2159  NeedRIGHT();
2160  break;
2161 
2162  case T_shape:
2163  SHAPE* shape;
2164  shape = new SHAPE( growth );
2165  growth->Append( shape );
2166  doSHAPE( shape );
2167  break;
2168 
2169  case T_attach:
2170  tok = NextTok();
2171 
2172  if( tok != T_off && tok != T_on )
2173  Expecting( "off|on" );
2174 
2175  growth->attach = tok;
2176  tok = NextTok();
2177 
2178  if( tok == T_LEFT )
2179  {
2180  if( NextTok() != T_use_via )
2181  Expecting( T_use_via );
2182 
2183  NeedSYMBOL();
2184  growth->via_id = CurText();
2185 
2186  NeedRIGHT();
2187  NeedRIGHT();
2188  }
2189 
2190  break;
2191 
2192  /*
2193  case T_via_site: not supported
2194  break;
2195  */
2196 
2197  case T_rule:
2198 
2199  if( growth->rules )
2200  Unexpected( tok );
2201 
2202  growth->rules = new RULE( growth, T_rule );
2203  doRULE( growth->rules );
2204  break;
2205 
2206  default:
2207  Unexpected( CurText() );
2208  }
2209  }
2210 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
An abstract shape on 2D plane.
Definition: shape.h:116
void doSHAPE(SHAPE *growth)
Definition: specctra.cpp:2213
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595

References DSN::PADSTACK::absolute, DSN::ELEM_HOLDER::Append(), DSN::PADSTACK::attach, doRULE(), doSHAPE(), doUNIT(), DSN::PADSTACK::padstack_id, DSN::PADSTACK::rotate, RULE, DSN::PADSTACK::rules, DSN::PADSTACK::unit, and DSN::PADSTACK::via_id.

Referenced by doLIBRARY().

◆ doPARSER()

void DSN::SPECCTRA_DB::doPARSER ( PARSER growth)
private

Definition at line 412 of file specctra.cpp.

413 {
414  T tok;
415  std::string const1;
416  std::string const2;
417 
418  /* <parser_descriptor >::=
419  (parser
420  [(string_quote <quote_char >)]
421  (space_in_quoted_tokens [on | off])
422  [(host_cad <id >)]
423  [(host_version <id >)]
424  [{(constant <id > <id >)}]
425  [(write_resolution] {<character> <positive_integer >})]
426  [(routes_include {[testpoint | guides |
427  image_conductor]})]
428  [(wires_include testpoint)]
429  [(case_sensitive [on | off])]
430  [(via_rotate_first [on | off])]
431  )
432  */
433 
434  while( (tok = NextTok()) != T_RIGHT )
435  {
436  if( tok != T_LEFT )
437  Expecting( T_LEFT );
438 
439  tok = NextTok();
440 
441  switch( tok )
442  {
443  case T_STRING_QUOTE:
444  tok = NextTok();
445 
446  if( tok != T_QUOTE_DEF )
447  Expecting( T_QUOTE_DEF );
448 
449  SetStringDelimiter( (unsigned char) *CurText() );
450  growth->string_quote = *CurText();
451  m_quote_char = CurText();
452  NeedRIGHT();
453  break;
454 
455  case T_space_in_quoted_tokens:
456  tok = NextTok();
457 
458  if( tok!=T_on && tok!=T_off )
459  Expecting( "on|off" );
460 
461  SetSpaceInQuotedTokens( tok==T_on );
462  growth->space_in_quoted_tokens = (tok==T_on);
463  NeedRIGHT();
464  break;
465 
466  case T_host_cad:
467  NeedSYMBOL();
468  growth->host_cad = CurText();
469  NeedRIGHT();
470  break;
471 
472  case T_host_version:
473  NeedSYMBOLorNUMBER();
474  growth->host_version = CurText();
475  NeedRIGHT();
476  break;
477 
478  case T_constant:
479  NeedSYMBOLorNUMBER();
480  const1 = CurText();
481  NeedSYMBOLorNUMBER();
482  const2 = CurText();
483  NeedRIGHT();
484  growth->constants.push_back( const1 );
485  growth->constants.push_back( const2 );
486  break;
487 
488  case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
489  while( (tok = NextTok()) != T_RIGHT )
490  {
491  if( tok!=T_SYMBOL )
492  Expecting( T_SYMBOL );
493 
494  tok = NextTok();
495 
496  if( tok!=T_NUMBER )
497  Expecting( T_NUMBER );
498 
499  // @todo
500  }
501 
502  break;
503 
504  case T_routes_include: // [(routes_include {[testpoint | guides | image_conductor]})]
505  while( (tok = NextTok()) != T_RIGHT )
506  {
507  switch( tok )
508  {
509  case T_testpoint:
510  growth->routes_include_testpoint = true;
511  break;
512  case T_guide:
513  growth->routes_include_guides = true;
514  break;
515  case T_image_conductor:
516  growth->routes_include_image_conductor = true;
517  break;
518  default:
519  Expecting( "testpoint|guides|image_conductor" );
520  }
521  }
522 
523  break;
524 
525  case T_wires_include: // [(wires_include testpoint)]
526  tok = NextTok();
527 
528  if( tok != T_testpoint )
529  Expecting( T_testpoint );
530 
531  growth->routes_include_testpoint = true;
532  NeedRIGHT();
533  break;
534 
535  case T_case_sensitive:
536  tok = NextTok();
537 
538  if( tok!=T_on && tok!=T_off )
539  Expecting( "on|off" );
540 
541  growth->case_sensitive = (tok==T_on);
542  NeedRIGHT();
543  break;
544 
545  case T_via_rotate_first: // [(via_rotate_first [on | off])]
546  tok = NextTok();
547 
548  if( tok!=T_on && tok!=T_off )
549  Expecting( "on|off" );
550 
551  growth->via_rotate_first = (tok==T_on);
552  NeedRIGHT();
553  break;
554 
555  case T_generated_by_freeroute:
556  growth->generated_by_freeroute = true;
557  NeedRIGHT();
558  break;
559 
560  default:
561  Unexpected( CurText() );
562  }
563  }
564 }
std::string m_quote_char
Definition: specctra.h:3983

References DSN::PARSER::case_sensitive, DSN::PARSER::constants, DSN::PARSER::generated_by_freeroute, DSN::PARSER::host_cad, DSN::PARSER::host_version, m_quote_char, DSN::PARSER::routes_include_guides, DSN::PARSER::routes_include_image_conductor, DSN::PARSER::routes_include_testpoint, DSN::PARSER::space_in_quoted_tokens, DSN::PARSER::string_quote, and DSN::PARSER::via_rotate_first.

Referenced by doPCB(), and doROUTE().

◆ doPATH()

void DSN::SPECCTRA_DB::doPATH ( PATH growth)
private

Definition at line 1086 of file specctra.cpp.

1087 {
1088  T tok = NextTok();
1089 
1090  if( !IsSymbol( tok ) && tok != T_NUMBER ) // a layer name can be like a number like +12
1091  Expecting( "layer_id" );
1092 
1093  growth->layer_id = CurText();
1094 
1095  if( NextTok() != T_NUMBER )
1096  Expecting( "aperture_width" );
1097 
1098  growth->aperture_width = strtod( CurText(), nullptr );
1099 
1100  POINT ptTemp;
1101 
1102  tok = NextTok();
1103 
1104  do
1105  {
1106  if( tok != T_NUMBER )
1107  Expecting( T_NUMBER );
1108 
1109  ptTemp.x = strtod( CurText(), nullptr );
1110 
1111  if( NextTok() != T_NUMBER )
1112  Expecting( T_NUMBER );
1113 
1114  ptTemp.y = strtod( CurText(), nullptr );
1115 
1116  growth->points.push_back( ptTemp );
1117 
1118  } while( ( tok = NextTok() ) != T_RIGHT && tok != T_LEFT );
1119 
1120  if( tok == T_LEFT )
1121  {
1122  if( NextTok() != T_aperture_type )
1123  Expecting( T_aperture_type );
1124 
1125  tok = NextTok();
1126 
1127  if( tok!=T_round && tok!=T_square )
1128  Expecting( "round|square" );
1129 
1130  growth->aperture_type = tok;
1131 
1132  NeedRIGHT();
1133  }
1134 }

References DSN::PATH::aperture_type, DSN::PATH::aperture_width, DSN::PATH::layer_id, DSN::PATH::points, DSN::POINT::x, and DSN::POINT::y.

Referenced by doBOUNDARY(), doKEEPOUT(), doREGION(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doPCB()

void DSN::SPECCTRA_DB::doPCB ( PCB growth)
private

Definition at line 297 of file specctra.cpp.

298 {
299  T tok;
300 
301  /* <design_descriptor >::=
302  (pcb <pcb_id >
303  [<parser_descriptor> ]
304  [<capacitance_resolution_descriptor> ]
305  [<conductance_resolution_descriptor> ]
306  [<current_resolution_descriptor> ]
307  [<inductance_resolution_descriptor> ]
308  [<resistance_resolution_descriptor> ]
309  [<resolution_descriptor> ]
310  [<time_resolution_descriptor> ]
311  [<voltage_resolution_descriptor> ]
312  [<unit_descriptor> ]
313  [<structure_descriptor> | <file_descriptor> ]
314  [<placement_descriptor> | <file_descriptor> ]
315  [<library_descriptor> | <file_descriptor> ]
316  [<floor_plan_descriptor> | <file_descriptor> ]
317  [<part_library_descriptor> | <file_descriptor> ]
318  [<network_descriptor> | <file_descriptor> ]
319  [<wiring_descriptor> ]
320  [<color_descriptor> ]
321  )
322  */
323 
324  NeedSYMBOL();
325  growth->pcbname = CurText();
326 
327  while( (tok = NextTok()) != T_RIGHT )
328  {
329  if( tok != T_LEFT )
330  Expecting( T_LEFT );
331 
332  tok = NextTok();
333 
334  switch( tok )
335  {
336  case T_parser:
337  if( growth->parser )
338  Unexpected( tok );
339 
340  growth->parser = new PARSER( growth );
341  doPARSER( growth->parser );
342  break;
343 
344  case T_unit:
345  if( growth->unit )
346  Unexpected( tok );
347 
348  growth->unit = new UNIT_RES( growth, tok );
349  doUNIT( growth->unit );
350  break;
351 
352  case T_resolution:
353  if( growth->resolution )
354  Unexpected( tok );
355 
356  growth->resolution = new UNIT_RES( growth, tok );
357  doRESOLUTION( growth->resolution );
358  break;
359 
360  case T_structure:
361  if( growth->structure )
362  Unexpected( tok );
363 
364  growth->structure = new STRUCTURE( growth );
365  doSTRUCTURE( growth->structure );
366  break;
367 
368  case T_placement:
369  if( growth->placement )
370  Unexpected( tok );
371 
372  growth->placement = new PLACEMENT( growth );
373  doPLACEMENT( growth->placement );
374  break;
375 
376  case T_library:
377  if( growth->library )
378  Unexpected( tok );
379 
380  growth->library = new LIBRARY( growth );
381  doLIBRARY( growth->library );
382  break;
383 
384  case T_network:
385  if( growth->network )
386  Unexpected( tok );
387 
388  growth->network = new NETWORK( growth );
389  doNETWORK( growth->network );
390  break;
391 
392  case T_wiring:
393  if( growth->wiring )
394  Unexpected( tok );
395 
396  growth->wiring = new WIRING( growth );
397  doWIRING( growth->wiring );
398  break;
399 
400  default:
401  Unexpected( CurText() );
402  }
403  }
404 
405  tok = NextTok();
406 
407  if( tok != T_EOF )
408  Expecting( T_EOF );
409 }
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:567
void doWIRING(WIRING *growth)
Definition: specctra.cpp:3216
void doLIBRARY(LIBRARY *growth)
Definition: specctra.cpp:2454
void doSTRUCTURE(STRUCTURE *growth)
Definition: specctra.cpp:653
void doPLACEMENT(PLACEMENT *growth)
Definition: specctra.cpp:2043
void doNETWORK(NETWORK *growth)
Definition: specctra.cpp:2810
void doPARSER(PARSER *growth)
Definition: specctra.cpp:412
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595

References doLIBRARY(), doNETWORK(), doPARSER(), doPLACEMENT(), doRESOLUTION(), doSTRUCTURE(), doUNIT(), doWIRING(), DSN::PCB::library, DSN::PCB::network, DSN::PCB::parser, DSN::PCB::pcbname, DSN::PCB::placement, DSN::PCB::resolution, DSN::PCB::structure, DSN::PCB::unit, and DSN::PCB::wiring.

Referenced by LoadPCB().

◆ doPIN()

void DSN::SPECCTRA_DB::doPIN ( PIN growth)
private

Definition at line 2403 of file specctra.cpp.

2404 {
2405  T tok = NextTok();
2406 
2407  /* (pin <padstack_id > [(rotate <rotation> )]
2408  [<reference_descriptor> | <pin_array_descriptor> ]
2409  [<user_property_descriptor> ])
2410  */
2411 
2412  // a padstack_id may be a number
2413  if( !IsSymbol( tok ) && tok!=T_NUMBER )
2414  Expecting( "padstack_id" );
2415 
2416  growth->padstack_id = CurText();
2417 
2418  while( ( tok = NextTok() ) != T_RIGHT )
2419  {
2420  if( tok == T_LEFT )
2421  {
2422  tok = NextTok();
2423 
2424  if( tok != T_rotate )
2425  Expecting( T_rotate );
2426 
2427  if( NextTok() != T_NUMBER )
2428  Expecting( T_NUMBER );
2429 
2430  growth->SetRotation( strtod( CurText(), 0 ) );
2431  NeedRIGHT();
2432  }
2433  else
2434  {
2435  if( !IsSymbol( tok ) && tok != T_NUMBER )
2436  Expecting( "pin_id" );
2437 
2438  growth->pin_id = CurText();
2439 
2440  if( NextTok() != T_NUMBER )
2441  Expecting( T_NUMBER );
2442 
2443  growth->vertex.x = strtod( CurText(), 0 );
2444 
2445  if( NextTok() != T_NUMBER )
2446  Expecting( T_NUMBER );
2447 
2448  growth->vertex.y = strtod( CurText(), 0 );
2449  }
2450  }
2451 }

References DSN::PIN::padstack_id, DSN::PIN::pin_id, DSN::PIN::SetRotation(), DSN::PIN::vertex, DSN::POINT::x, and DSN::POINT::y.

Referenced by doIMAGE().

◆ doPLACE()

void DSN::SPECCTRA_DB::doPLACE ( PLACE growth)
private

Definition at line 1876 of file specctra.cpp.

1877 {
1878  T tok = NextTok();
1879 
1880  if( !IsSymbol( tok ) )
1881  Expecting( "component_id" );
1882 
1883  growth->component_id = CurText();
1884 
1885  tok = NextTok();
1886 
1887  if( tok == T_NUMBER )
1888  {
1889  POINT point;
1890 
1891  point.x = strtod( CurText(), 0 );
1892 
1893  if( NextTok() != T_NUMBER )
1894  Expecting( T_NUMBER );
1895 
1896  point.y = strtod( CurText(), 0 );
1897 
1898  growth->SetVertex( point );
1899 
1900  tok = NextTok();
1901 
1902  if( tok != T_front && tok != T_back )
1903  Expecting( "front|back" );
1904 
1905  growth->side = tok;
1906 
1907  if( NextTok() != T_NUMBER )
1908  Expecting( "rotation" );
1909 
1910  growth->SetRotation( strtod( CurText(), 0 ) );
1911  }
1912 
1913  while( ( tok = NextTok() ) != T_RIGHT )
1914  {
1915  if( tok != T_LEFT )
1916  Expecting( T_LEFT );
1917 
1918  tok = NextTok();
1919 
1920  switch( tok )
1921  {
1922  case T_mirror:
1923  tok = NextTok();
1924 
1925  if( tok == T_x || tok == T_y || tok == T_xy || tok == T_off )
1926  growth->mirror = tok;
1927  else
1928  Expecting( "x|y|xy|off" );
1929 
1930  break;
1931 
1932  case T_status:
1933  tok = NextTok();
1934 
1935  if( tok==T_added || tok==T_deleted || tok==T_substituted )
1936  growth->status = tok;
1937  else
1938  Expecting("added|deleted|substituted");
1939 
1940  break;
1941 
1942  case T_logical_part:
1943  if( growth->logical_part.size() )
1944  Unexpected( tok );
1945 
1946  tok = NextTok();
1947 
1948  if( !IsSymbol( tok ) )
1949  Expecting( "logical_part_id");
1950 
1951  growth->logical_part = CurText();
1952  break;
1953 
1954  case T_place_rule:
1955  if( growth->place_rules )
1956  Unexpected( tok );
1957 
1958  growth->place_rules = new RULE( growth, T_place_rule );
1959  doRULE( growth->place_rules );
1960  break;
1961 
1962  case T_property:
1963  if( growth->properties.size() )
1964  Unexpected( tok );
1965 
1966  doPROPERTIES( &growth->properties );
1967  break;
1968 
1969  case T_lock_type:
1970  tok = NextTok();
1971 
1972  if( tok == T_position || tok == T_gate || tok == T_subgate || tok == T_pin )
1973  growth->lock_type = tok;
1974  else
1975  Expecting( "position|gate|subgate|pin" );
1976 
1977  break;
1978 
1979  case T_rule:
1980  if( growth->rules || growth->region )
1981  Unexpected( tok );
1982 
1983  growth->rules = new RULE( growth, T_rule );
1984  doRULE( growth->rules );
1985  break;
1986 
1987  case T_region:
1988  if( growth->rules || growth->region )
1989  Unexpected( tok );
1990 
1991  growth->region = new REGION( growth );
1992  doREGION( growth->region );
1993  break;
1994 
1995  case T_pn:
1996  if( growth->part_number.size() )
1997  Unexpected( tok );
1998 
1999  NeedSYMBOLorNUMBER();
2000  growth->part_number = CurText();
2001  NeedRIGHT();
2002  break;
2003 
2004  default:
2005  Unexpected( tok );
2006  }
2007  }
2008 }
void doPROPERTIES(PROPERTIES *growth)
Definition: specctra.cpp:1326
void doREGION(REGION *growth)
Definition: specctra.cpp:1627
void doRULE(RULE *growth)
Definition: specctra.cpp:1489

References DSN::PLACE::component_id, doPROPERTIES(), doREGION(), doRULE(), DSN::PLACE::lock_type, DSN::PLACE::logical_part, DSN::PLACE::mirror, DSN::PLACE::part_number, DSN::PLACE::place_rules, DSN::PLACE::properties, REGION, DSN::PLACE::region, RULE, DSN::PLACE::rules, DSN::PLACE::SetRotation(), DSN::PLACE::SetVertex(), DSN::PLACE::side, DSN::PLACE::status, DSN::POINT::x, and DSN::POINT::y.

Referenced by doCOMPONENT().

◆ doPLACEMENT()

void DSN::SPECCTRA_DB::doPLACEMENT ( PLACEMENT growth)
private

Definition at line 2043 of file specctra.cpp.

2044 {
2045  T tok;
2046 
2047  while( ( tok = NextTok() ) != T_RIGHT )
2048  {
2049  if( tok == T_EOF )
2050  Unexpected( T_EOF );
2051 
2052  if( tok != T_LEFT )
2053  Expecting( T_LEFT );
2054 
2055  tok = NextTok();
2056 
2057  switch( tok )
2058  {
2059  case T_unit:
2060  case T_resolution:
2061  growth->unit = new UNIT_RES( growth, tok );
2062 
2063  if( tok == T_resolution )
2064  doRESOLUTION( growth->unit );
2065  else
2066  doUNIT( growth->unit );
2067  break;
2068 
2069  case T_place_control:
2070  NeedRIGHT();
2071  tok = NextTok();
2072 
2073  if( tok != T_flip_style )
2074  Expecting( T_flip_style );
2075 
2076  tok = NextTok();
2077 
2078  if( tok == T_mirror_first || tok == T_rotate_first )
2079  growth->flip_style = tok;
2080  else
2081  Expecting( "mirror_first|rotate_first" );
2082 
2083  NeedRIGHT();
2084  NeedRIGHT();
2085  break;
2086 
2087  case T_component:
2088  COMPONENT* component;
2089  component = new COMPONENT( growth );
2090  growth->components.push_back( component );
2091  doCOMPONENT( component );
2092  break;
2093 
2094  default:
2095  Unexpected( tok );
2096  }
2097  }
2098 }
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:567
void doCOMPONENT(COMPONENT *growth)
Definition: specctra.cpp:2011
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:84
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595

References COMPONENT, DSN::PLACEMENT::components, doCOMPONENT(), doRESOLUTION(), doUNIT(), DSN::PLACEMENT::flip_style, and DSN::PLACEMENT::unit.

Referenced by doPCB(), and doSESSION().

◆ doPROPERTIES()

void DSN::SPECCTRA_DB::doPROPERTIES ( PROPERTIES growth)
private

Definition at line 1326 of file specctra.cpp.

1327 {
1328  T tok;
1329  PROPERTY property; // construct it once here, append multiple times.
1330 
1331  while( ( tok = NextTok() ) != T_RIGHT )
1332  {
1333  if( tok != T_LEFT )
1334  Expecting( T_LEFT );
1335 
1336  NeedSYMBOLorNUMBER();
1337  property.name = CurText();
1338 
1339  NeedSYMBOLorNUMBER();
1340  property.value = CurText();
1341 
1342  growth->push_back( property );
1343 
1344  NeedRIGHT();
1345  }
1346 }

Referenced by doLAYER(), and doPLACE().

◆ doQARC()

void DSN::SPECCTRA_DB::doQARC ( QARC growth)
private

Definition at line 1197 of file specctra.cpp.

1198 {
1199  NeedSYMBOL();
1200  growth->layer_id = CurText();
1201 
1202  if( NextTok() != T_NUMBER )
1203  Expecting( T_NUMBER );
1204 
1205  growth->aperture_width = strtod( CurText(), 0 );
1206 
1207  for( int i = 0; i < 3; ++i )
1208  {
1209  if( NextTok() != T_NUMBER )
1210  Expecting( T_NUMBER );
1211 
1212  growth->vertex[i].x = strtod( CurText(), 0 );
1213 
1214  if( NextTok() != T_NUMBER )
1215  Expecting( T_NUMBER );
1216 
1217  growth->vertex[i].y = strtod( CurText(), 0 );
1218  }
1219 
1220  NeedRIGHT();
1221 }

References DSN::QARC::aperture_width, DSN::QARC::layer_id, DSN::QARC::vertex, DSN::POINT::x, and DSN::POINT::y.

Referenced by doKEEPOUT(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doRECTANGLE()

void DSN::SPECCTRA_DB::doRECTANGLE ( RECTANGLE growth)
private

Definition at line 1137 of file specctra.cpp.

1138 {
1139  NeedSYMBOL();
1140  growth->layer_id = CurText();
1141 
1142  if( NextTok() != T_NUMBER )
1143  Expecting( T_NUMBER );
1144 
1145  growth->point0.x = strtod( CurText(), nullptr );
1146 
1147  if( NextTok() != T_NUMBER )
1148  Expecting( T_NUMBER );
1149 
1150  growth->point0.y = strtod( CurText(), nullptr );
1151 
1152  if( NextTok() != T_NUMBER )
1153  Expecting( T_NUMBER );
1154 
1155  growth->point1.x = strtod( CurText(), nullptr );
1156 
1157  if( NextTok() != T_NUMBER )
1158  Expecting( T_NUMBER );
1159 
1160  growth->point1.y = strtod( CurText(), nullptr );
1161 
1162  NeedRIGHT();
1163 }

References DSN::RECTANGLE::layer_id, DSN::RECTANGLE::point0, DSN::RECTANGLE::point1, DSN::POINT::x, and DSN::POINT::y.

Referenced by doBOUNDARY(), doKEEPOUT(), doREGION(), doSHAPE(), doWINDOW(), and doWIRE().

◆ doREGION()

void DSN::SPECCTRA_DB::doREGION ( REGION growth)
private

Definition at line 1627 of file specctra.cpp.

1628 {
1629  T tok = NextTok();
1630 
1631  if( IsSymbol( tok ) )
1632  {
1633  growth->region_id = CurText();
1634  tok = NextTok();
1635  }
1636 
1637  for(;;)
1638  {
1639  if( tok != T_LEFT )
1640  Expecting( T_LEFT );
1641 
1642  tok = NextTok();
1643 
1644  switch( tok )
1645  {
1646  case T_rect:
1647  if( growth->rectangle )
1648  Unexpected( tok );
1649 
1650  growth->rectangle = new RECTANGLE( growth );
1651  doRECTANGLE( growth->rectangle );
1652  break;
1653 
1654  case T_polygon:
1655  if( growth->polygon )
1656  Unexpected( tok );
1657 
1658  growth->polygon = new PATH( growth, T_polygon );
1659  doPATH( growth->polygon );
1660  break;
1661 
1662  case T_region_net:
1663  case T_region_class:
1664  STRINGPROP* stringprop;
1665  stringprop = new STRINGPROP( growth, tok );
1666  growth->Append( stringprop );
1667  doSTRINGPROP( stringprop );
1668  break;
1669 
1670  case T_region_class_class:
1671  CLASS_CLASS* class_class;
1672  class_class = new CLASS_CLASS( growth, tok );
1673  growth->Append( class_class );
1674  doCLASS_CLASS( class_class );
1675  break;
1676 
1677  case T_rule:
1678  if( growth->rules )
1679  Unexpected( tok );
1680 
1681  growth->rules = new RULE( growth, T_rule );
1682  doRULE( growth->rules );
1683  break;
1684 
1685  default:
1686  Unexpected( CurText() );
1687  }
1688 
1689  tok = NextTok();
1690 
1691  if( tok == T_RIGHT )
1692  {
1693  if( !growth->rules )
1694  Expecting( T_rule );
1695 
1696  break;
1697  }
1698  }
1699 }
void doCLASS_CLASS(CLASS_CLASS *growth)
Definition: specctra.cpp:1702
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doPATH(PATH *growth)
Definition: specctra.cpp:1086
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1137
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1224

References DSN::ELEM_HOLDER::Append(), doCLASS_CLASS(), doPATH(), doRECTANGLE(), doRULE(), doSTRINGPROP(), DSN::REGION::polygon, RECTANGLE, DSN::REGION::rectangle, DSN::REGION::region_id, RULE, and DSN::REGION::rules.

Referenced by doPLACE(), and doSTRUCTURE().

◆ doRESOLUTION()

void DSN::SPECCTRA_DB::doRESOLUTION ( UNIT_RES growth)
private

Definition at line 567 of file specctra.cpp.

568 {
569  T tok = NextTok();
570 
571  switch( tok )
572  {
573  case T_inch:
574  case T_mil:
575  case T_cm:
576  case T_mm:
577  case T_um:
578  growth->units = tok;
579  break;
580  default:
581  Expecting( "inch|mil|cm|mm|um" );
582  }
583 
584  tok = NextTok();
585 
586  if( tok != T_NUMBER )
587  Expecting( T_NUMBER );
588 
589  growth->value = atoi( CurText() );
590 
591  NeedRIGHT();
592 }

References DSN::UNIT_RES::units, and DSN::UNIT_RES::value.

Referenced by doPCB(), doPLACEMENT(), doROUTE(), doSTRUCTURE(), and doWIRING().

◆ doROUTE()

void DSN::SPECCTRA_DB::doROUTE ( ROUTE growth)
private

Definition at line 3497 of file specctra.cpp.

3498 {
3499  T tok;
3500 
3501  /* <route_descriptor >::=
3502  (routes
3503  <resolution_descriptor>
3504  <parser_descriptor>
3505  <structure_out_descriptor>
3506  <library_out_descriptor>
3507  <network_out_descriptor>
3508  <test_points_descriptor>
3509  )
3510  */
3511 
3512  while( ( tok = NextTok() ) != T_RIGHT )
3513  {
3514  if( tok != T_LEFT )
3515  Expecting( T_LEFT );
3516 
3517  tok = NextTok();
3518 
3519  switch( tok )
3520  {
3521  case T_resolution:
3522  if( growth->resolution )
3523  Unexpected( tok );
3524 
3525  growth->resolution = new UNIT_RES( growth, tok );
3526  doRESOLUTION( growth->resolution );
3527  break;
3528 
3529  case T_parser:
3530  if( growth->parser )
3531  {
3532 #if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
3533  // Work around their bug for now.
3534  Unexpected( tok );
3535 #else
3536  delete growth->parser;
3537 #endif
3538  }
3539 
3540  growth->parser = new PARSER( growth );
3541  doPARSER( growth->parser );
3542  break;
3543 
3544  case T_structure_out:
3545  if( growth->structure_out )
3546  Unexpected( tok );
3547 
3548  growth->structure_out = new STRUCTURE_OUT( growth );
3549  doSTRUCTURE_OUT( growth->structure_out );
3550  break;
3551 
3552  case T_library_out:
3553  if( growth->library )
3554  Unexpected( tok );
3555 
3556  growth->library = new LIBRARY( growth, tok );
3557  doLIBRARY( growth->library );
3558  break;
3559 
3560  case T_network_out:
3561  while( ( tok = NextTok() ) != T_RIGHT )
3562  {
3563  if( tok != T_LEFT )
3564  Expecting( T_LEFT );
3565 
3566  tok = NextTok();
3567 
3568  if( tok != T_net ) // it is class NET_OUT, but token T_net
3569  Unexpected( CurText() );
3570 
3571  NET_OUT* net_out;
3572  net_out = new NET_OUT( growth );
3573 
3574  growth->net_outs.push_back( net_out );
3575  doNET_OUT( net_out );
3576  }
3577 
3578  break;
3579 
3580  default:
3581  Unexpected( CurText() );
3582  }
3583  }
3584 }
void doSTRUCTURE_OUT(STRUCTURE_OUT *growth)
Definition: specctra.cpp:798
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:567
void doLIBRARY(LIBRARY *growth)
Definition: specctra.cpp:2454
void doNET_OUT(NET_OUT *growth)
Definition: specctra.cpp:3587
void doPARSER(PARSER *growth)
Definition: specctra.cpp:412

References doLIBRARY(), doNET_OUT(), doPARSER(), doRESOLUTION(), doSTRUCTURE_OUT(), DSN::ROUTE::library, DSN::ROUTE::net_outs, DSN::ROUTE::parser, DSN::ROUTE::resolution, and DSN::ROUTE::structure_out.

Referenced by doSESSION().

◆ doRULE()

void DSN::SPECCTRA_DB::doRULE ( RULE growth)
private

Definition at line 1489 of file specctra.cpp.

1490 {
1491  std::string builder;
1492  int bracketNesting = 1; // we already saw the opening T_LEFT
1493  T tok = T_NONE;
1494 
1495  while( bracketNesting != 0 && tok != T_EOF )
1496  {
1497  tok = NextTok();
1498 
1499  if( tok==T_LEFT)
1500  ++bracketNesting;
1501  else if( tok==T_RIGHT )
1502  --bracketNesting;
1503 
1504  if( bracketNesting >= 1 )
1505  {
1506  if( PrevTok() != T_LEFT && tok != T_RIGHT && ( tok != T_LEFT || bracketNesting > 2 ) )
1507  builder += ' ';
1508 
1509  if( tok == T_STRING )
1510  builder += m_quote_char;
1511 
1512  builder += CurText();
1513 
1514  if( tok == T_STRING )
1515  builder += m_quote_char;
1516  }
1517 
1518  // When the nested rule is closed with a T_RIGHT and we are back down
1519  // to bracketNesting == 1, (inside the <rule_descriptor> but outside
1520  // the last rule). Then save the last rule and clear the string builder.
1521  if( bracketNesting == 1 )
1522  {
1523  growth->rules.push_back( builder );
1524  builder.clear();
1525  }
1526  }
1527 
1528  if( tok==T_EOF )
1529  Unexpected( T_EOF );
1530 }
std::string m_quote_char
Definition: specctra.h:3983

References m_quote_char, and DSN::RULE::rules.

Referenced by doCLASS(), doCLASS_CLASS(), doFROMTO(), doIMAGE(), doKEEPOUT(), doLAYER(), doLAYER_RULE(), doNET(), doNET_OUT(), doPADSTACK(), doPLACE(), doREGION(), doSTRUCTURE(), and doSTRUCTURE_OUT().

◆ doSESSION()

void DSN::SPECCTRA_DB::doSESSION ( SESSION growth)
private

Definition at line 3373 of file specctra.cpp.

3374 {
3375  T tok;
3376 
3377  /* <session_file_descriptor >::=
3378  (session <session_id >
3379  (base_design <path/filename >)
3380  [<history_descriptor> ]
3381  [<session_structure_descriptor> ]
3382  [<placement_descriptor> ]
3383  [<floor_plan_descriptor> ]
3384  [<net_pin_changes_descriptor> ]
3385  [<was_is_descriptor> ]
3386  <swap_history_descriptor> ]
3387  [<route_descriptor> ]
3388  )
3389  */
3390 
3391  NeedSYMBOL();
3392  growth->session_id = CurText();
3393 
3394  while( ( tok = NextTok() ) != T_RIGHT )
3395  {
3396  if( tok != T_LEFT )
3397  Expecting( T_LEFT );
3398 
3399  tok = NextTok();
3400 
3401  switch( tok )
3402  {
3403  case T_base_design:
3404  NeedSYMBOL();
3405  growth->base_design = CurText();
3406  NeedRIGHT();
3407  break;
3408 
3409  case T_history:
3410  if( growth->history )
3411  Unexpected( tok );
3412 
3413  growth->history = new HISTORY( growth );
3414  doHISTORY( growth->history );
3415  break;
3416 
3417  case T_structure:
3418  if( growth->structure )
3419  Unexpected( tok );
3420 
3421  growth->structure = new STRUCTURE( growth );
3422  doSTRUCTURE( growth->structure );
3423  break;
3424 
3425  case T_placement:
3426  if( growth->placement )
3427  Unexpected( tok );
3428 
3429  growth->placement = new PLACEMENT( growth );
3430  doPLACEMENT( growth->placement );
3431  break;
3432 
3433  case T_was_is:
3434  if( growth->was_is )
3435  Unexpected( tok );
3436 
3437  growth->was_is = new WAS_IS( growth );
3438  doWAS_IS( growth->was_is );
3439  break;
3440 
3441  case T_routes:
3442  if( growth->route )
3443  Unexpected( tok );
3444 
3445  growth->route = new ROUTE( growth );
3446  doROUTE( growth->route );
3447  break;
3448 
3449  default:
3450  Unexpected( CurText() );
3451  }
3452  }
3453 }
void doROUTE(ROUTE *growth)
Definition: specctra.cpp:3497
void doHISTORY(HISTORY *growth)
Definition: specctra.cpp:3314
void doSTRUCTURE(STRUCTURE *growth)
Definition: specctra.cpp:653
void doPLACEMENT(PLACEMENT *growth)
Definition: specctra.cpp:2043
void doWAS_IS(WAS_IS *growth)
Definition: specctra.cpp:3456

References DSN::SESSION::base_design, doHISTORY(), doPLACEMENT(), doROUTE(), doSTRUCTURE(), doWAS_IS(), DSN::SESSION::history, DSN::SESSION::placement, DSN::SESSION::route, DSN::SESSION::session_id, DSN::SESSION::structure, and DSN::SESSION::was_is.

Referenced by LoadSESSION().

◆ doSHAPE()

void DSN::SPECCTRA_DB::doSHAPE ( SHAPE growth)
private

Definition at line 2213 of file specctra.cpp.

2214 {
2215  T tok;
2216 
2217  /* (shape <shape_descriptor>
2218  [<reduced_shape_descriptor> ]
2219  [(connect [on | off])]
2220  [{<window_descriptor> }])
2221  */
2222 
2223  while( ( tok = NextTok() ) != T_RIGHT )
2224  {
2225  if( tok != T_LEFT )
2226  Expecting( T_LEFT );
2227 
2228  tok = NextTok();
2229 
2230  switch( tok )
2231  {
2232  case T_polyline_path:
2233  tok = T_path;
2235 
2236  case T_rect:
2237  case T_circle:
2238  case T_path:
2239  case T_polygon:
2240  case T_qarc:
2241 L_done_that:
2242  if( growth->shape )
2243  Unexpected( tok );
2244 
2245  break;
2246 
2247  default:
2248  // the example in the spec uses "circ" instead of "circle". Bad!
2249  if( !strcmp( "circ", CurText() ) )
2250  {
2251  tok = T_circle;
2252  goto L_done_that;
2253  }
2254  }
2255 
2256  switch( tok )
2257  {
2258  case T_rect:
2259  growth->shape = new RECTANGLE( growth );
2260  doRECTANGLE( (RECTANGLE*) growth->shape );
2261  break;
2262 
2263  case T_circle:
2264  growth->shape = new CIRCLE( growth );
2265  doCIRCLE( (CIRCLE*)growth->shape );
2266  break;
2267 
2268  case T_path:
2269  case T_polygon:
2270  growth->shape = new PATH( growth, tok );
2271  doPATH( (PATH*)growth->shape );
2272  break;
2273 
2274  case T_qarc:
2275  growth->shape = new QARC( growth );
2276  doQARC( (QARC*)growth->shape );
2277  break;
2278 
2279  case T_connect:
2280  tok = NextTok();
2281  if( tok!=T_on && tok!=T_off )
2282  Expecting( "on|off" );
2283  growth->connect = tok;
2284  NeedRIGHT();
2285  break;
2286 
2287  case T_window:
2288  WINDOW* window;
2289  window = new WINDOW( growth );
2290  growth->windows.push_back( window );
2291  doWINDOW( window );
2292  break;
2293 
2294  default:
2295  Unexpected( CurText() );
2296  }
2297  }
2298 }
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:977
void doPATH(PATH *growth)
Definition: specctra.cpp:1086
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1137
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:32
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1166
void doQARC(QARC *growth)
Definition: specctra.cpp:1197

References CIRCLE, DSN::SHAPE::connect, doCIRCLE(), doPATH(), doQARC(), doRECTANGLE(), doWINDOW(), KI_FALLTHROUGH, RECTANGLE, DSN::WINDOW::shape, and DSN::SHAPE::windows.

Referenced by doIMAGE(), and doPADSTACK().

◆ doSPECCTRA_LAYER_PAIR()

void DSN::SPECCTRA_DB::doSPECCTRA_LAYER_PAIR ( SPECCTRA_LAYER_PAIR growth)
private

Definition at line 616 of file specctra.cpp.

617 {
618  NeedSYMBOL();
619  growth->layer_id0 = CurText();
620 
621  NeedSYMBOL();
622  growth->layer_id1 = CurText();
623 
624  if( NextTok() != T_NUMBER )
625  Expecting( T_NUMBER );
626 
627  growth->layer_weight = strtod( CurText(), 0 );
628 
629  NeedRIGHT();
630 }

References DSN::SPECCTRA_LAYER_PAIR::layer_id0, DSN::SPECCTRA_LAYER_PAIR::layer_id1, and DSN::SPECCTRA_LAYER_PAIR::layer_weight.

Referenced by doLAYER_NOISE_WEIGHT().

◆ doSTRINGPROP()

void DSN::SPECCTRA_DB::doSTRINGPROP ( STRINGPROP growth)
private

Definition at line 1224 of file specctra.cpp.

1225 {
1226  NeedSYMBOL();
1227  growth->value = CurText();
1228  NeedRIGHT();
1229 }

References DSN::STRINGPROP::value.

Referenced by doREGION(), and doSTRUCTURE().

◆ doSTRUCTURE()

void DSN::SPECCTRA_DB::doSTRUCTURE ( STRUCTURE growth)
private

Definition at line 653 of file specctra.cpp.

654 {
655  T tok;
656 
657  while( ( tok = NextTok() ) != T_RIGHT )
658  {
659  if( tok != T_LEFT )
660  Expecting( T_LEFT );
661 
662  tok = NextTok();
663 
664  switch( tok )
665  {
666  case T_unit:
667  if( growth->unit )
668  Unexpected( tok );
669 
670  growth->unit = new UNIT_RES( growth, tok );
671  doUNIT( growth->unit );
672  break;
673 
674  case T_resolution:
675  if( growth->unit )
676  Unexpected( tok );
677 
678  growth->unit = new UNIT_RES( growth, tok );
679  doRESOLUTION( growth->unit );
680  break;
681 
682  case T_layer_noise_weight:
683  if( growth->layer_noise_weight )
684  Unexpected( tok );
685 
686  growth->layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
687  doLAYER_NOISE_WEIGHT( growth->layer_noise_weight );
688  break;
689 
690  case T_place_boundary:
691 L_place:
692  if( growth->place_boundary )
693  Unexpected( tok );
694 
695  growth->place_boundary = new BOUNDARY( growth, T_place_boundary );
696  doBOUNDARY( growth->place_boundary );
697  break;
698 
699  case T_boundary:
700  if( growth->boundary )
701  {
702  if( growth->place_boundary )
703  Unexpected( tok );
704 
705  goto L_place;
706  }
707 
708  growth->boundary = new BOUNDARY( growth );
709  doBOUNDARY( growth->boundary );
710  break;
711 
712  case T_plane:
713  COPPER_PLANE* plane;
714  plane = new COPPER_PLANE( growth );
715  growth->planes.push_back( plane );
716  doKEEPOUT( plane );
717  break;
718 
719  case T_region:
720  REGION* region;
721  region = new REGION( growth );
722  growth->regions.push_back( region );
723  doREGION( region );
724  break;
725 
726  case T_snap_angle:
727  STRINGPROP* stringprop;
728  stringprop = new STRINGPROP( growth, T_snap_angle );
729  growth->Append( stringprop );
730  doSTRINGPROP( stringprop );
731  break;
732 
733  case T_via:
734  if( growth->via )
735  Unexpected( tok );
736 
737  growth->via = new VIA( growth );
738  doVIA( growth->via );
739  break;
740 
741  case T_control:
742  if( growth->control )
743  Unexpected( tok );
744 
745  growth->control = new CONTROL( growth );
746  doCONTROL( growth->control );
747  break;
748 
749  case T_layer:
750  LAYER* layer;
751  layer = new LAYER( growth );
752  growth->layers.push_back( layer );
753  doLAYER( layer );
754  break;
755 
756  case T_rule:
757  if( growth->rules )
758  Unexpected( tok );
759 
760  growth->rules = new RULE( growth, T_rule );
761  doRULE( growth->rules );
762  break;
763 
764  case T_place_rule:
765  if( growth->place_rules )
766  Unexpected( tok );
767 
768  growth->place_rules = new RULE( growth, T_place_rule );
769  doRULE( growth->place_rules );
770  break;
771 
772  case T_keepout:
773  case T_place_keepout:
774  case T_via_keepout:
775  case T_wire_keepout:
776  case T_bend_keepout:
777  case T_elongate_keepout:
778  KEEPOUT* keepout;
779  keepout = new KEEPOUT( growth, tok );
780  growth->keepouts.push_back( keepout );
781  doKEEPOUT( keepout );
782  break;
783 
784  case T_grid:
785  GRID* grid;
786  grid = new GRID( growth );
787  growth->grids.push_back( grid );
788  doGRID( grid );
789  break;
790 
791  default:
792  Unexpected( CurText() );
793  }
794  }
795 }
void doLAYER_NOISE_WEIGHT(LAYER_NOISE_WEIGHT *growth)
Definition: specctra.cpp:633
void doKEEPOUT(KEEPOUT *growth)
Definition: specctra.cpp:843
void doGRID(GRID *growth)
Definition: specctra.cpp:1774
void doCONTROL(CONTROL *growth)
Definition: specctra.cpp:1276
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1349
void doVIA(VIA *growth)
Definition: specctra.cpp:1245
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:567
void doREGION(REGION *growth)
Definition: specctra.cpp:1627
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1224
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:81
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595
void doBOUNDARY(BOUNDARY *growth)
Definition: specctra.cpp:1036

References DSN::ELEM_HOLDER::Append(), DSN::STRUCTURE::boundary, DSN::STRUCTURE::control, doBOUNDARY(), doCONTROL(), doGRID(), doKEEPOUT(), doLAYER(), doLAYER_NOISE_WEIGHT(), doREGION(), doRESOLUTION(), doRULE(), doSTRINGPROP(), doUNIT(), doVIA(), grid, DSN::STRUCTURE::grids, DSN::STRUCTURE::keepouts, DSN::STRUCTURE::layer_noise_weight, DSN::STRUCTURE::layers, DSN::STRUCTURE::place_boundary, DSN::STRUCTURE::place_rules, DSN::STRUCTURE::planes, REGION, DSN::STRUCTURE::regions, RULE, DSN::STRUCTURE::rules, DSN::STRUCTURE::unit, VIA, and DSN::STRUCTURE::via.

Referenced by doPCB(), and doSESSION().

◆ doSTRUCTURE_OUT()

void DSN::SPECCTRA_DB::doSTRUCTURE_OUT ( STRUCTURE_OUT growth)
private

Definition at line 798 of file specctra.cpp.

799 {
800  /*
801  <structure_out_descriptor >::=
802  (structure_out
803  {<layer_descriptor> }
804  [<rule_descriptor> ]
805  )
806  */
807 
808  T tok = NextTok();
809 
810  while( tok != T_RIGHT )
811  {
812  if( tok != T_LEFT )
813  Expecting( T_LEFT );
814 
815  tok = NextTok();
816 
817  switch( tok )
818  {
819  case T_layer:
820  LAYER* layer;
821  layer = new LAYER( growth );
822  growth->layers.push_back( layer );
823  doLAYER( layer );
824  break;
825 
826  case T_rule:
827  if( growth->rules )
828  Unexpected( tok );
829 
830  growth->rules = new RULE( growth, T_rule );
831  doRULE( growth->rules );
832  break;
833 
834  default:
835  Unexpected( CurText() );
836  }
837 
838  tok = NextTok();
839  }
840 }
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1349
void doRULE(RULE *growth)
Definition: specctra.cpp:1489
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:81

References doLAYER(), doRULE(), DSN::STRUCTURE_OUT::layers, RULE, and DSN::STRUCTURE_OUT::rules.

Referenced by doROUTE().

◆ doSUPPLY_PIN()

void DSN::SPECCTRA_DB::doSUPPLY_PIN ( SUPPLY_PIN growth)
private

Definition at line 3659 of file specctra.cpp.

3660 {
3661  T tok;
3662  PIN_REF empty(growth);
3663 
3664  /* <supply_pin_descriptor >::=
3665  (supply_pin {<pin_reference> } [(net <net_id >)])
3666  */
3667 
3668  NeedSYMBOL();
3669  growth->net_id = CurText();
3670 
3671  while( ( tok = NextTok() ) != T_RIGHT )
3672  {
3673  if( IsSymbol(tok) )
3674  {
3675  growth->pin_refs.push_back( empty );
3676 
3677  PIN_REF* pin_ref = &growth->pin_refs.back();
3678 
3679  readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
3680  }
3681  else if( tok == T_LEFT )
3682  {
3683  tok = NextTok();
3684 
3685  if( tok != T_net )
3686  Expecting( T_net );
3687 
3688  growth->net_id = CurText();
3689  NeedRIGHT();
3690  }
3691  else
3692  Unexpected( CurText() );
3693  }
3694 }
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen.
Definition: specctra.cpp:137
static bool empty(const wxTextEntryBase *aCtrl)

References DSN::PIN_REF::component_id, empty(), DSN::SUPPLY_PIN::net_id, DSN::PIN_REF::pin_id, DSN::SUPPLY_PIN::pin_refs, and readCOMPnPIN().

Referenced by doNET_OUT().

◆ doTOKPROP()

void DSN::SPECCTRA_DB::doTOKPROP ( TOKPROP growth)
private

Definition at line 1232 of file specctra.cpp.

1233 {
1234  T tok = NextTok();
1235 
1236  if( tok<0 )
1237  Unexpected( CurText() );
1238 
1239  growth->value = tok;
1240 
1241  NeedRIGHT();
1242 }

References DSN::TOKPROP::value.

Referenced by doCONTROL().

◆ doTOPOLOGY()

void DSN::SPECCTRA_DB::doTOPOLOGY ( TOPOLOGY growth)
private

Definition at line 2658 of file specctra.cpp.

2659 {
2660  T tok;
2661 
2662  /* <topology_descriptor >::=
2663  (topology {[<fromto_descriptor> |
2664  <component_order_descriptor> ]})
2665  */
2666 
2667  while( ( tok = NextTok() ) != T_RIGHT )
2668  {
2669  if( tok != T_LEFT )
2670  Expecting( T_LEFT );
2671 
2672  tok = NextTok();
2673 
2674  switch( tok )
2675  {
2676  case T_fromto:
2677  FROMTO* fromto;
2678  fromto = new FROMTO( growth );
2679  growth->fromtos.push_back( fromto );
2680  doFROMTO( fromto );
2681  break;
2682 
2683  case T_comp_order:
2684  COMP_ORDER* comp_order;
2685  comp_order = new COMP_ORDER( growth );
2686  growth->comp_orders.push_back( comp_order );
2687  doCOMP_ORDER( comp_order );
2688  break;
2689 
2690  default:
2691  Unexpected( CurText() );
2692  }
2693  }
2694 }
void doCOMP_ORDER(COMP_ORDER *growth)
Definition: specctra.cpp:2856
void doFROMTO(FROMTO *growth)
Definition: specctra.cpp:2874

References DSN::TOPOLOGY::comp_orders, doCOMP_ORDER(), doFROMTO(), and DSN::TOPOLOGY::fromtos.

Referenced by doCLASS().

◆ doUNIT()

void DSN::SPECCTRA_DB::doUNIT ( UNIT_RES growth)
private

Definition at line 595 of file specctra.cpp.

596 {
597  T tok = NextTok();
598 
599  switch( tok )
600  {
601  case T_inch:
602  case T_mil:
603  case T_cm:
604  case T_mm:
605  case T_um:
606  growth->units = tok;
607  break;
608  default:
609  Expecting( "inch|mil|cm|mm|um" );
610  }
611 
612  NeedRIGHT();
613 }

References DSN::UNIT_RES::units.

Referenced by doIMAGE(), doLIBRARY(), doPADSTACK(), doPCB(), doPLACEMENT(), doSTRUCTURE(), and doWIRING().

◆ doVIA()

void DSN::SPECCTRA_DB::doVIA ( VIA growth)
private

Definition at line 1245 of file specctra.cpp.

1246 {
1247  T tok;
1248 
1249  while( ( tok = NextTok() ) != T_RIGHT )
1250  {
1251  if( tok == T_LEFT )
1252  {
1253  if( NextTok() != T_spare )
1254  Expecting( T_spare );
1255 
1256  while( (tok = NextTok()) != T_RIGHT )
1257  {
1258  if( !IsSymbol( tok ) )
1259  Expecting( T_SYMBOL );
1260 
1261  growth->spares.push_back( CurText() );
1262  }
1263  }
1264  else if( IsSymbol( tok ) )
1265  {
1266  growth->padstacks.push_back( CurText() );
1267  }
1268  else
1269  {
1270  Unexpected( CurText() );
1271  }
1272  }
1273 }

References DSN::VIA::padstacks, and DSN::VIA::spares.

Referenced by doSTRUCTURE().

◆ doWAS_IS()

void DSN::SPECCTRA_DB::doWAS_IS ( WAS_IS growth)
private

Definition at line 3456 of file specctra.cpp.

3457 {
3458  T tok;
3459  PIN_PAIR empty( growth );
3460  PIN_PAIR* pin_pair;
3461 
3462  /* <was_is_descriptor >::=
3463  (was_is {(pins <pin_reference> <pin_reference> )})
3464  */
3465 
3466  // none of the pins is ok too
3467  while( ( tok = NextTok() ) != T_RIGHT )
3468  {
3469  if( tok != T_LEFT )
3470  Expecting( T_LEFT );
3471 
3472  tok = NextTok();
3473 
3474  switch( tok )
3475  {
3476  case T_pins:
3477  // copy the empty one, then fill its copy later thru pin_pair.
3478  growth->pin_pairs.push_back( empty );
3479  pin_pair= &growth->pin_pairs.back();
3480 
3481  NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3482  readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
3483 
3484  NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3485  readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
3486 
3487  NeedRIGHT();
3488  break;
3489 
3490  default:
3491  Unexpected( CurText() );
3492  }
3493  }
3494 }
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen.
Definition: specctra.cpp:137
static bool empty(const wxTextEntryBase *aCtrl)

References DSN::PIN_REF::component_id, empty(), DSN::PIN_PAIR::is, DSN::PIN_REF::pin_id, DSN::WAS_IS::pin_pairs, readCOMPnPIN(), and DSN::PIN_PAIR::was.

Referenced by doSESSION().

◆ doWINDOW()

void DSN::SPECCTRA_DB::doWINDOW ( WINDOW growth)
private

Definition at line 977 of file specctra.cpp.

978 {
979  T tok = NextTok();
980 
981  while( tok != T_RIGHT )
982  {
983  if( tok!=T_LEFT )
984  Expecting( T_LEFT );
985 
986  tok = NextTok();
987 
988  switch( tok )
989  {
990  case T_rect:
991  if( growth->shape )
992  Unexpected( tok );
993 
994  growth->shape = new RECTANGLE( growth );
995  doRECTANGLE( (RECTANGLE*) growth->shape );
996  break;
997 
998  case T_circle:
999  if( growth->shape )
1000  Unexpected( tok );
1001 
1002  growth->shape = new CIRCLE( growth );
1003  doCIRCLE( (CIRCLE*) growth->shape );
1004  break;
1005 
1006  case T_polyline_path:
1007  tok = T_path;
1009 
1010  case T_path:
1011  case T_polygon:
1012  if( growth->shape )
1013  Unexpected( tok );
1014 
1015  growth->shape = new PATH( growth, tok );
1016  doPATH( (PATH*) growth->shape );
1017  break;
1018 
1019  case T_qarc:
1020  if( growth->shape )
1021  Unexpected( tok );
1022 
1023  growth->shape = new QARC( growth );
1024  doQARC( (QARC*) growth->shape );
1025  break;
1026 
1027  default:
1028  Unexpected( CurText() );
1029  }
1030 
1031  tok = NextTok();
1032  }
1033 }
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
void doPATH(PATH *growth)
Definition: specctra.cpp:1086
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1137
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:32
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1166
void doQARC(QARC *growth)
Definition: specctra.cpp:1197

References CIRCLE, doCIRCLE(), doPATH(), doQARC(), doRECTANGLE(), KI_FALLTHROUGH, RECTANGLE, and DSN::WINDOW::shape.

Referenced by doKEEPOUT(), doSHAPE(), and doWIRE().

◆ doWIRE()

void DSN::SPECCTRA_DB::doWIRE ( WIRE growth)
private

Definition at line 2967 of file specctra.cpp.

2968 {
2969  T tok;
2970 
2971  /* <wire_shape_descriptor >::=
2972  (wire
2973  <shape_descriptor>
2974  [(net <net_id >)]
2975  [(turret <turret#> )]
2976  [(type [fix | route | normal | protect])]
2977  [(attr [test | fanout | bus | jumper])]
2978  [(shield <net_id >)]
2979  [{<window_descriptor> }]
2980  [(connect
2981  (terminal <object_type> [<pin_reference> ])
2982  (terminal <object_type> [<pin_reference> ])
2983  )]
2984  [(supply)]
2985  )
2986  */
2987 
2988  while( ( tok = NextTok() ) != T_RIGHT )
2989  {
2990  if( tok != T_LEFT )
2991  Expecting( T_LEFT );
2992 
2993  tok = NextTok();
2994 
2995  switch( tok )
2996  {
2997  case T_rect:
2998  if( growth->shape )
2999  Unexpected( tok );
3000 
3001  growth->shape = new RECTANGLE( growth );
3002  doRECTANGLE( (RECTANGLE*) growth->shape );
3003  break;
3004 
3005  case T_circle:
3006  if( growth->shape )
3007  Unexpected( tok );
3008 
3009  growth->shape = new CIRCLE( growth );
3010  doCIRCLE( (CIRCLE*) growth->shape );
3011  break;
3012 
3013  case T_polyline_path:
3014  tok = T_path;
3016 
3017  case T_path:
3018  case T_polygon:
3019  if( growth->shape )
3020  Unexpected( tok );
3021 
3022  growth->shape = new PATH( growth, tok );
3023  doPATH( (PATH*) growth->shape );
3024  break;
3025 
3026  case T_qarc:
3027  if( growth->shape )
3028  Unexpected( tok );
3029 
3030  growth->shape = new QARC( growth );
3031  doQARC( (QARC*) growth->shape );
3032  break;
3033 
3034  case T_net:
3035  NeedSYMBOLorNUMBER();
3036  growth->net_id = CurText();
3037  NeedRIGHT();
3038  break;
3039 
3040  case T_turret:
3041  if( NextTok() != T_NUMBER )
3042  Expecting( T_NUMBER );
3043 
3044  growth->turret = atoi( CurText() );
3045  NeedRIGHT();
3046  break;
3047 
3048  case T_type:
3049  tok = NextTok();
3050 
3051  if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3052  Expecting( "fix|route|normal|protect" );
3053 
3054  growth->wire_type = tok;
3055  NeedRIGHT();
3056  break;
3057 
3058  case T_attr:
3059  tok = NextTok();
3060 
3061  if( tok != T_test && tok != T_fanout && tok != T_bus && tok != T_jumper )
3062  Expecting( "test|fanout|bus|jumper" );
3063 
3064  growth->attr = tok;
3065  NeedRIGHT();
3066  break;
3067 
3068  case T_shield:
3069  NeedSYMBOL();
3070  growth->shield = CurText();
3071  NeedRIGHT();
3072  break;
3073 
3074  case T_window:
3075  WINDOW* window;
3076  window = new WINDOW( growth );
3077  growth->windows.push_back( window );
3078  doWINDOW( window );
3079  break;
3080 
3081  case T_connect:
3082  if( growth->connect )
3083  Unexpected( tok );
3084 
3085  growth->connect = new CONNECT( growth );
3086  doCONNECT( growth->connect );
3087  break;
3088 
3089  case T_supply:
3090  growth->supply = true;
3091  NeedRIGHT();
3092  break;
3093 
3094  default:
3095  Unexpected( CurText() );
3096  }
3097  }
3098 }
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:977
void doPATH(PATH *growth)
Definition: specctra.cpp:1086
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1137
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:32
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1166
void doCONNECT(CONNECT *growth)
Definition: specctra.cpp:942
void doQARC(QARC *growth)
Definition: specctra.cpp:1197

References DSN::WIRE::attr, CIRCLE, DSN::WIRE::connect, doCIRCLE(), doCONNECT(), doPATH(), doQARC(), doRECTANGLE(), doWINDOW(), KI_FALLTHROUGH, DSN::WIRE::net_id, RECTANGLE, DSN::WIRE::shape, DSN::WIRE::shield, DSN::WIRE::supply, DSN::WIRE::turret, DSN::WIRE::windows, and DSN::WIRE::wire_type.

Referenced by doNET_OUT(), and doWIRING().

◆ doWIRE_VIA()

void DSN::SPECCTRA_DB::doWIRE_VIA ( WIRE_VIA growth)
private

Definition at line 3101 of file specctra.cpp.

3102 {
3103  T tok;
3104  POINT point;
3105 
3106  /* <wire_via_descriptor >::=
3107  (via
3108  <padstack_id > {<vertex> }
3109  [(net <net_id >)]
3110  [(via_number <via#> )]
3111  [(type [fix | route | normal | protect])]
3112  [(attr [test | fanout | jumper |
3113  virtual_pin <virtual_pin_name> ])]
3114  [(contact {<layer_id >})]
3115  [(supply)]
3116  )
3117  (virtual_pin
3118  <virtual_pin_name> <vertex> (net <net_id >)
3119  )
3120  */
3121 
3122  NeedSYMBOL();
3123  growth->padstack_id = CurText();
3124 
3125  while( ( tok = NextTok() ) == T_NUMBER )
3126  {
3127  point.x = strtod( CurText(), 0 );
3128 
3129  if( NextTok() != T_NUMBER )
3130  Expecting( "vertex.y" );
3131 
3132  point.y = strtod( CurText(), 0 );
3133 
3134  growth->vertexes.push_back( point );
3135  }
3136 
3137  while( tok != T_RIGHT )
3138  {
3139  if( tok != T_LEFT )
3140  Expecting( T_LEFT );
3141 
3142  tok = NextTok();
3143 
3144  switch( tok )
3145  {
3146  case T_net:
3147  NeedSYMBOL();
3148  growth->net_id = CurText();
3149  NeedRIGHT();
3150  break;
3151 
3152  case T_via_number:
3153  if( NextTok() != T_NUMBER )
3154  Expecting( "<via#>" );
3155 
3156  growth->via_number = atoi( CurText() );
3157  NeedRIGHT();
3158  break;
3159 
3160  case T_type:
3161  tok = NextTok();
3162 
3163  if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3164  Expecting( "fix|route|normal|protect" );
3165 
3166  growth->via_type = tok;
3167  NeedRIGHT();
3168  break;
3169 
3170  case T_attr:
3171  tok = NextTok();
3172 
3173  if( tok != T_test && tok != T_fanout && tok != T_jumper && tok != T_virtual_pin )
3174  Expecting( "test|fanout|jumper|virtual_pin" );
3175 
3176  growth->attr = tok;
3177 
3178  if( tok == T_virtual_pin )
3179  {
3180  NeedSYMBOL();
3181  growth->virtual_pin_name = CurText();
3182  }
3183 
3184  NeedRIGHT();
3185  break;
3186 
3187  case T_contact:
3188  NeedSYMBOL();
3189  tok = T_SYMBOL;
3190 
3191  while( IsSymbol( tok ) )
3192  {
3193  growth->contact_layers.push_back( CurText() );
3194  tok = NextTok();
3195  }
3196 
3197  if( tok != T_RIGHT )
3198  Expecting( T_RIGHT );
3199 
3200  break;
3201 
3202  case T_supply:
3203  growth->supply = true;
3204  NeedRIGHT();
3205  break;
3206 
3207  default:
3208  Unexpected( CurText() );
3209  }
3210 
3211  tok = NextTok();
3212  }
3213 }

References DSN::WIRE_VIA::attr, DSN::WIRE_VIA::contact_layers, DSN::WIRE_VIA::net_id, DSN::WIRE_VIA::padstack_id, DSN::WIRE_VIA::supply, DSN::WIRE_VIA::vertexes, DSN::WIRE_VIA::via_number, DSN::WIRE_VIA::via_type, DSN::WIRE_VIA::virtual_pin_name, DSN::POINT::x, and DSN::POINT::y.

Referenced by doNET_OUT(), and doWIRING().

◆ doWIRING()

void DSN::SPECCTRA_DB::doWIRING ( WIRING growth)
private

Definition at line 3216 of file specctra.cpp.

3217 {
3218  T tok;
3219 
3220  /* <wiring_descriptor >::=
3221  (wiring
3222  [<unit_descriptor> | <resolution_descriptor> | null]
3223  {<wire_descriptor> }
3224  [<test_points_descriptor> ]
3225  {[<supply_pin_descriptor> ]}
3226  )
3227  */
3228 
3229  while( ( tok = NextTok() ) != T_RIGHT )
3230  {
3231  if( tok != T_LEFT )
3232  Expecting( T_LEFT );
3233 
3234  tok = NextTok();
3235 
3236  switch( tok )
3237  {
3238  case T_unit:
3239  if( growth->unit )
3240  Unexpected( tok );
3241 
3242  growth->unit = new UNIT_RES( growth, tok );
3243  doUNIT( growth->unit );
3244  break;
3245 
3246  case T_resolution:
3247  if( growth->unit )
3248  Unexpected( tok );
3249 
3250  growth->unit = new UNIT_RES( growth, tok );
3251  doRESOLUTION( growth->unit );
3252  break;
3253 
3254  case T_wire:
3255  WIRE* wire;
3256  wire = new WIRE( growth );
3257  growth->wires.push_back( wire );
3258  doWIRE( wire );
3259  break;
3260 
3261  case T_via:
3262  WIRE_VIA* wire_via;
3263  wire_via = new WIRE_VIA( growth );
3264  growth->wire_vias.push_back( wire_via );
3265  doWIRE_VIA( wire_via );
3266  break;
3267 
3268  default:
3269  Unexpected( CurText() );
3270  }
3271  }
3272 }
void doWIRE(WIRE *growth)
Definition: specctra.cpp:2967
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:567
void doWIRE_VIA(WIRE_VIA *growth)
Definition: specctra.cpp:3101
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:595

References doRESOLUTION(), doUNIT(), doWIRE(), doWIRE_VIA(), DSN::WIRING::unit, WIRE, DSN::WIRING::wire_vias, and DSN::WIRING::wires.

Referenced by doPCB().

◆ exportNETCLASS()

void DSN::SPECCTRA_DB::exportNETCLASS ( const std::shared_ptr< NETCLASS > &  aNetClass,
BOARD aBoard 
)
private

Export aNetClass to the DSN file.

Definition at line 1783 of file specctra_export.cpp.

1784 {
1785  /* From page 11 of specctra spec:
1786  *
1787  * Routing and Placement Rule Hierarchies
1788  *
1789  * Routing and placement rules can be defined at multiple levels of design
1790  * specification. When a routing or placement rule is defined for an object at
1791  * multiple levels, a predefined routing or placement precedence order
1792  * automatically determines which rule to apply to the object. The routing rule
1793  * precedence order is
1794  *
1795  * pcb < layer < class < class layer < group_set < group_set layer < net <
1796  * net layer < group < group layer < fromto < fromto layer < class_class <
1797  * class_class layer < padstack < region < class region < net region <
1798  * class_class region
1799  *
1800  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1801  * hierarchy. A class-to-class region rule has the highest precedence. Rules
1802  * set at one level of the hierarchy override conflicting rules set at lower
1803  * levels. The placement rule precedence order is
1804  *
1805  * pcb < image_set < image < component < super cluster < room <
1806  * room_image_set < family_family < image_image
1807  *
1808  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1809  * hierarchy. An image-to-image rule has the highest precedence. Rules set at
1810  * one level of the hierarchy override conflicting rules set at lower levels.
1811  */
1812 
1813  char text[256];
1814 
1815  CLASS* clazz = new CLASS( m_pcb->network );
1816 
1817  m_pcb->network->classes.push_back( clazz );
1818 
1819  // freerouter creates a class named 'default' anyway, and if we
1820  // try and use that, we end up with two 'default' via rules so use
1821  // something else as the name of our default class.
1822  clazz->class_id = TO_UTF8( aNetClass->GetName() );
1823 
1824  for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net )
1825  clazz->net_ids.push_back( TO_UTF8( *net ) );
1826 
1827  clazz->rules = new RULE( clazz, T_rule );
1828 
1829  // output the track width.
1830  int trackWidth = aNetClass->GetTrackWidth();
1831  sprintf( text, "(width %.6g)", scale( trackWidth ) );
1832  clazz->rules->rules.push_back( text );
1833 
1834  // output the clearance.
1835  int clearance = aNetClass->GetClearance();
1836  sprintf( text, "(clearance %.6g)", scale( clearance ) + safetyMargin );
1837  clazz->rules->rules.push_back( text );
1838 
1839  if( aNetClass->GetName() == NETCLASS::Default )
1840  {
1841  clazz->class_id = "kicad_default";
1842  }
1843 
1844  // the easiest way to get the via name is to create a via (which generates
1845  // the name internal to the PADSTACK), and then grab the name and then
1846  // delete the via. There are not that many netclasses so
1847  // this should never become a performance issue.
1848 
1849  PADSTACK* via = makeVia( aNetClass->GetViaDiameter(), aNetClass->GetViaDrill(),
1851 
1852  snprintf( text, sizeof(text), "(use_via %s)", via->GetPadstackId().c_str() );
1853  clazz->circuit.push_back( text );
1854 
1855  delete via;
1856 }
STRINGS circuit
circuit descriptor list
Definition: specctra.h:2830
static const double safetyMargin
The <class_descriptor> in the specctra spec.
Definition: specctra.h:2753
std::string class_id
Definition: specctra.h:2825
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
STRINGSET::iterator iterator
Definition: netclass.h:94
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:49
Hold either a via or a pad definition.
Definition: specctra.h:2126
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:4008
CLASSLIST classes
Definition: specctra.h:2863
RULE * rules
Definition: specctra.h:2832
static double scale(int kicadDist)
Convert a distance from Pcbnew internal units to the reported Specctra DSN units in floating point fo...
STRINGS net_ids
Definition: specctra.h:2827
NETWORK * network
Definition: specctra.h:3261
PADSTACK * makeVia(int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
Make a round through hole #PADSTACK using the given KiCad diameter in deci-mils.
STRINGS rules
rules are saved in std::string form.
Definition: specctra.h:530

References DSN::CLASS::circuit, DSN::CLASS::class_id, DSN::NETWORK::classes, NETCLASS::Default, m_bot_via_layer, m_pcb, m_top_via_layer, makeVia(), DSN::CLASS::net_ids, DSN::PCB::network, DSN::RULE::rules, DSN::CLASS::rules, safetyMargin, DSN::scale(), text, TO_UTF8, and via.

Referenced by FromBOARD().

◆ ExportPCB()

void DSN::SPECCTRA_DB::ExportPCB ( const wxString &  aFilename,
bool  aNameChange = false 
)

Write the internal PCB instance out as a SPECTRA DSN format file.

Parameters
aFilenameThe file to save to.
aNameChangeIf true, causes the pcb's name to change to "aFilename" and also to to be changed in the output file.
Exceptions
IO_ERROR,ifan i/o error occurs saving the file.

Definition at line 3697 of file specctra.cpp.

3698 {
3699  if( m_pcb )
3700  {
3701  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3702 
3703  if( aNameChange )
3704  m_pcb->pcbname = TO_UTF8( aFilename );
3705 
3706  m_pcb->Format( &formatter, 0 );
3707  }
3708 }
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:3207
Used for text file output.
Definition: richio.h:456
std::string pcbname
Definition: specctra.h:3254
std::string m_quote_char
Definition: specctra.h:3983

References DSN::PCB::Format(), m_pcb, m_quote_char, DSN::PCB::pcbname, and TO_UTF8.

Referenced by ExportBoardToSpecctraFile().

◆ ExportSESSION()

void DSN::SPECCTRA_DB::ExportSESSION ( const wxString &  aFilename)

Write the internal #SESSION instance out as a #SPECTRA DSN format file.

Parameters
aFilenameThe file to save to.

Definition at line 3711 of file specctra.cpp.

3712 {
3713  if( m_session )
3714  {
3715  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3716 
3717  m_session->Format( &formatter, 0 );
3718  }
3719 }
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:3597
SESSION * m_session
Definition: specctra.h:3981
Used for text file output.
Definition: richio.h:456
std::string m_quote_char
Definition: specctra.h:3983

References DSN::SESSION::Format(), m_quote_char, and m_session.

◆ fillBOUNDARY()

void DSN::SPECCTRA_DB::fillBOUNDARY ( BOARD aBoard,
BOUNDARY aBoundary 
)
private

Make the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tree.

Parameters
aBoardThe BOARD to get information from in order to make the BOUNDARY.
aBoundaryThe empty BOUNDARY to fill in.

Definition at line 1039 of file specctra_export.cpp.

1040 {
1041  for( int cnt = 0; cnt < m_brd_outlines.OutlineCount(); cnt++ ) // Should be one outline
1042  {
1043  PATH* path = new PATH( boundary );
1044  boundary->paths.push_back( path );
1045  path->layer_id = "pcb";
1046 
1047  SHAPE_LINE_CHAIN& outline = m_brd_outlines.Outline( cnt );
1048 
1049  for( int ii = 0; ii < outline.PointCount(); ii++ )
1050  {
1051  wxPoint pos( outline.CPoint( ii ).x, outline.CPoint( ii ).y );
1052  path->AppendPoint( mapPt( pos ) );
1053  }
1054 
1055  // Close polygon:
1056  wxPoint pos0( outline.CPoint( 0 ).x, outline.CPoint( 0 ).y );
1057  path->AppendPoint( mapPt( pos0 ) );
1058 
1059  // Generate holes as keepout:
1060  for( int ii = 0; ii < m_brd_outlines.HoleCount( cnt ); ii++ )
1061  {
1062  // emit a signal layers keepout for every interior polygon left...
1063  KEEPOUT* keepout = new KEEPOUT( nullptr, T_keepout );
1064  PATH* poly_ko = new PATH( nullptr, T_polygon );
1065 
1066  keepout->SetShape( poly_ko );
1067  poly_ko->SetLayerId( "signal" );
1068  m_pcb->structure->keepouts.push_back( keepout );
1069 
1070  SHAPE_LINE_CHAIN& hole = m_brd_outlines.Hole( cnt, ii );
1071 
1072  for( int jj = 0; jj < hole.PointCount(); jj++ )
1073  {
1074  wxPoint pos( hole.CPoint( jj ).x, hole.CPoint( jj ).y );
1075  poly_ko->AppendPoint( mapPt( pos ) );
1076  }
1077 
1078  // Close polygon:
1079  wxPoint pos( hole.CPoint( 0 ).x, hole.CPoint( 0 ).y );
1080  poly_ko->AppendPoint( mapPt( pos ) );
1081  }
1082  }
1083 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
static POINT mapPt(const wxPoint &pt)
Convert a KiCad point into a DSN file point.
void SetLayerId(const char *aLayerId)
Definition: specctra.h:600
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:593
STRUCTURE * structure
Definition: specctra.h:3258
int PointCount() const
Return the number of points (vertices) in this line chain.
Support both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:582
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void SetShape(ELEM *aShape)
Definition: specctra.h:930
SHAPE_LINE_CHAIN & Outline(int aIndex)
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
Represent a polyline (an zero-thickness chain of connected line segments).
Used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:905
SHAPE_POLY_SET m_brd_outlines
Definition: specctra.h:3980
KEEPOUTS keepouts
Definition: specctra.h:1670

References DSN::PATH::AppendPoint(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), DSN::STRUCTURE::keepouts, m_brd_outlines, m_pcb, DSN::mapPt(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), path, DSN::BOUNDARY::paths, SHAPE_LINE_CHAIN::PointCount(), DSN::PATH::SetLayerId(), DSN::KEEPOUT::SetShape(), DSN::PCB::structure, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by FromBOARD().

◆ findLayerName()

int DSN::SPECCTRA_DB::findLayerName ( const std::string &  aLayerName) const
private

Return the PCB layer index for a given layer name, within the specctra sessionfile.

Returns
the layer index within the specctra session file, or -1 if aLayerName is not found.

Definition at line 125 of file specctra.cpp.

126 {
127  for( int i = 0; i < int( m_layerIds.size() ); ++i )
128  {
129  if( 0 == aLayerName.compare( m_layerIds[i] ) )
130  return i;
131  }
132 
133  return -1;
134 }
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3989

References m_layerIds.

Referenced by makeTRACK(), and makeVIA().

◆ FlipFOOTPRINTs()

void DSN::SPECCTRA_DB::FlipFOOTPRINTs ( BOARD aBoard)

Flip the footprints which are on the back side of the board to the front.

Definition at line 1859 of file specctra_export.cpp.

1860 {
1861  // DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the
1862  // top view.
1863  // Note: to export footprints, the footprints must be flipped around the X axis,
1864  // otherwise the rotation angle is not good
1865  for( FOOTPRINT* footprint : aBoard->Footprints() )
1866  {
1867  footprint->SetFlag( 0 );
1868 
1869  if( footprint->GetLayer() == B_Cu )
1870  {
1871  footprint->Flip( footprint->GetPosition(), false );
1872  footprint->SetFlag( 1 );
1873  }
1874  }
1875 
1876  m_footprintsAreFlipped = true;
1877 }
bool m_footprintsAreFlipped
Definition: specctra.h:3985
FOOTPRINTS & Footprints()
Definition: board.h:233

References B_Cu, BOARD::Footprints(), and m_footprintsAreFlipped.

Referenced by ExportBoardToSpecctraFile().

◆ FromBOARD()

void DSN::SPECCTRA_DB::FromBOARD ( BOARD aBoard)

Add the entire BOARD to the PCB but does not write it out.

Note
The BOARD given to this function must have all the FOOTPRINTs on the component side of the BOARD.
See also
PCB_EDIT_FRAME::ExportToSpecctra() for an example before calling this function.
Parameters
aBoardThe BOARD to convert to a PCB.

Definition at line 1090 of file specctra_export.cpp.

1091 {
1092  PCB_TYPE_COLLECTOR items;
1093 
1094  static const KICAD_T scanMODULEs[] = { PCB_FOOTPRINT_T, EOT };
1095 
1096  // Not all boards are exportable. Check that all reference Ids are unique.
1097  // Unless they are unique, we cannot import the session file which comes
1098  // back to us later from the router.
1099  {
1100  items.Collect( aBoard, scanMODULEs );
1101 
1102  STRINGSET refs; // holds footprint reference designators
1103 
1104  for( int i=0; i<items.GetCount(); ++i )
1105  {
1106  FOOTPRINT* footprint = (FOOTPRINT*) items[i];
1107 
1108  if( footprint->GetReference() == wxEmptyString )
1109  {
1111  _( "Symbol with value of '%s' has empty reference id." ),
1112  footprint->GetValue() ) );
1113  }
1114 
1115  // if we cannot insert OK, that means the reference has been seen before.
1116  STRINGSET_PAIR refpair = refs.insert( TO_UTF8( footprint->GetReference() ) );
1117 
1118  if( !refpair.second ) // insert failed
1119  {
1121  _( "Multiple symbols have identical reference IDs of '%s'." ),
1122  footprint->GetReference() ) );
1123  }
1124  }
1125  }
1126 
1127  if( !m_pcb )
1129 
1130  //-----<layer_descriptor>-----------------------------------------------
1131  {
1132  // specctra wants top physical layer first, then going down to the
1133  // bottom most physical layer in physical sequence.
1134  // @question : why does KiCad not display layers in that order?
1135 
1136  buildLayerMaps( aBoard );
1137 
1138  int layerCount = aBoard->GetCopperLayerCount();
1139 
1140  for( int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
1141  {
1142  LAYER* layer = new LAYER( m_pcb->structure );
1143 
1144  m_pcb->structure->layers.push_back( layer );
1145 
1146  layer->name = m_layerIds[pcbNdx];
1147 
1148  DSN_T layerType;
1149 
1150  switch( aBoard->GetLayerType( m_pcbLayer2kicad[pcbNdx] ) )
1151  {
1152  default:
1153  case LT_SIGNAL: layerType = T_signal; break;
1154  case LT_POWER: layerType = T_power; break;
1155 
1156  // Freerouter does not support type "mixed", only signal and power.
1157  // Remap "mixed" to "signal".
1158  case LT_MIXED: layerType = T_signal; break;
1159  case LT_JUMPER: layerType = T_jumper; break;
1160  }
1161 
1162  layer->layer_type = layerType;
1163 
1164  layer->properties.push_back( PROPERTY() );
1165  PROPERTY* property = &layer->properties.back();
1166  property->name = "index";
1167  char temp[32];
1168  sprintf( temp, "%d", pcbNdx );
1169  property->value = temp;
1170  }
1171  }
1172 
1173  // a space in a quoted token is NOT a terminator, true establishes this.
1175 
1176  //-----<unit_descriptor> & <resolution_descriptor>--------------------
1177  {
1178  // tell freerouter to use "tenths of micrometers",
1179  // which is 100 nm resolution. Possibly more resolution is possible
1180  // in freerouter, but it would need testing.
1181 
1182  m_pcb->unit->units = T_um;
1183  m_pcb->resolution->units = T_um;
1184  m_pcb->resolution->value = 10; // tenths of a um
1185  }
1186 
1187  //-----<boundary_descriptor>------------------------------------------
1188  {
1189  // Because fillBOUNDARY() can throw an exception, we link in an
1190  // empty boundary so the BOUNDARY does not get lost in the event of
1191  // of an exception.
1192  BOUNDARY* boundary = new BOUNDARY( 0 );
1193 
1194  m_pcb->structure->SetBOUNDARY( boundary );
1195  fillBOUNDARY( aBoard, boundary );
1196  }
1197 
1198  //-----<rules>--------------------------------------------------------
1199  {
1200  char rule[80];
1201  NETCLASS* defaultClass = aBoard->GetDesignSettings().GetDefault();
1202 
1203  int defaultTrackWidth = defaultClass->GetTrackWidth();
1204  int defaultClearance = defaultClass->GetClearance();
1205 
1206  double clearance = scale( defaultClearance );
1207 
1208  STRINGS& rules = m_pcb->structure->rules->rules;
1209 
1210  sprintf( rule, "(width %.6g)", scale( defaultTrackWidth ) );
1211  rules.push_back( rule );
1212 
1213  sprintf( rule, "(clearance %.6g)", clearance + safetyMargin );
1214  rules.push_back( rule );
1215 
1216  // On a high density board (a board with 4 mil tracks, 4 mil spacing)
1217  // a typical solder mask clearance will be 2-3 mils.
1218  // This exposes 2 to 3 mils of bare board around each pad, and would
1219  // leave only 1 to 2 mils of solder mask between the solder mask's boundary
1220  // to the edge of any trace within "clearance" of the pad. So we need at least
1221  // 2 mils *extra* clearance for traces which would come near a pad on
1222  // a different net. So if the baseline trace to trace clearance was say 4 mils, then
1223  // the SMD to trace clearance should be at least 6 mils.
1224  double default_smd = clearance + safetyMargin;
1225 
1226  if( default_smd <= 6.0 )
1227  default_smd = 6.0;
1228 
1229  sprintf( rule, "(clearance %.6g (type default_smd))", default_smd );
1230 
1231  rules.push_back( rule );
1232 
1233  // Pad to pad spacing on a single SMT part can be closer than our
1234  // clearance, we don't want freerouter complaining about that, so
1235  // output a significantly smaller pad to pad clearance to freerouter.
1236  clearance = scale( defaultClearance ) / 4;
1237 
1238  sprintf( rule, "(clearance %.6g (type smd_smd))", clearance );
1239  rules.push_back( rule );
1240  }
1241 
1242  //-----<zones (not keepout areas) become planes>--------------------------------
1243  // Note: only zones are output here, keepout areas are created later.
1244  {
1245  int netlessZones = 0;
1246 
1247  static const KICAD_T scanZONEs[] = { PCB_ZONE_T, EOT };
1248  items.Collect( aBoard, scanZONEs );
1249 
1250  for( int i = 0; i < items.GetCount(); ++i )
1251  {
1252  ZONE* item = (ZONE*) items[i];
1253 
1254  if( item->GetIsRuleArea() )
1255  continue;
1256 
1257  // Currently, we export only copper layers
1258  if( ! IsCopperLayer( item->GetLayer() ) )
1259  continue;
1260 
1261  COPPER_PLANE* plane = new COPPER_PLANE( m_pcb->structure );
1262 
1263  m_pcb->structure->planes.push_back( plane );
1264 
1265  PATH* mainPolygon = new PATH( plane, T_polygon );
1266 
1267  plane->SetShape( mainPolygon );
1268 
1269  plane->name = TO_UTF8( item->GetNetname() );
1270 
1271  if( plane->name.size() == 0 )
1272  {
1273  char name[32];
1274 
1275  // This is one of those no connection zones, netcode=0, and it has no name.
1276  // Create a unique, bogus netname.
1277  NET* no_net = new NET( m_pcb->network );
1278 
1279  sprintf( name, "@:no_net_%d", netlessZones++ );
1280  no_net->net_id = name;
1281 
1282  // add the bogus net name to network->nets.
1283  m_pcb->network->nets.push_back( no_net );
1284 
1285  // use the bogus net name in the netless zone.
1286  plane->name = no_net->net_id;
1287  }
1288 
1289  mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1290 
1291  // Handle the main outlines
1292  SHAPE_POLY_SET::ITERATOR iterator;
1293  wxPoint startpoint;
1294  bool is_first_point = true;
1295 
1296  for( iterator = item->IterateWithHoles(); iterator; iterator++ )
1297  {
1298  wxPoint point( iterator->x, iterator->y );
1299 
1300  if( is_first_point )
1301  {
1302  startpoint = point;
1303  is_first_point = false;
1304  }
1305 
1306  mainPolygon->AppendPoint( mapPt( point ) );
1307 
1308  // this was the end of the main polygon
1309  if( iterator.IsEndContour() )
1310  {
1311  // Close polygon
1312  mainPolygon->AppendPoint( mapPt( startpoint ) );
1313  break;
1314  }
1315  }
1316 
1317  WINDOW* window = 0;
1318  PATH* cutout = 0;
1319 
1320  bool isStartContour = true;
1321 
1322  // handle the cutouts
1323  for( iterator++; iterator; iterator++ )
1324  {
1325  if( isStartContour )
1326  {
1327  is_first_point = true;
1328  window = new WINDOW( plane );
1329 
1330  plane->AddWindow( window );
1331 
1332  cutout = new PATH( window, T_polygon );
1333 
1334  window->SetShape( cutout );
1335 
1336  cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1337  }
1338 
1339  // If the point in this iteration is the last of the contour, the next iteration
1340  // will start with a new contour.
1341  isStartContour = iterator.IsEndContour();
1342 
1343  wxASSERT( window );
1344  wxASSERT( cutout );
1345 
1346  wxPoint point(iterator->x, iterator->y );
1347 
1348  if( is_first_point )
1349  {
1350  startpoint = point;
1351  is_first_point = false;
1352  }
1353 
1354  cutout->AppendPoint( mapPt( point ) );
1355 
1356  // Close the polygon
1357  if( iterator.IsEndContour() )
1358  cutout->AppendPoint( mapPt( startpoint ) );
1359  }
1360  }
1361  }
1362 
1363  //-----<zones flagged keepout areas become keepout>--------------------------------
1364  {
1365  static const KICAD_T scanZONEs[] = { PCB_ZONE_T, EOT };
1366  items.Collect( aBoard, scanZONEs );
1367 
1368  for( int i = 0; i < items.GetCount(); ++i )
1369  {
1370  ZONE* item = (ZONE*) items[i];
1371 
1372  if( !item->GetIsRuleArea() )
1373  continue;
1374 
1375  // keepout areas have a type. types are
1376  // T_place_keepout, T_via_keepout, T_wire_keepout,
1377  // T_bend_keepout, T_elongate_keepout, T_keepout.
1378  // Pcbnew knows only T_keepout, T_via_keepout and T_wire_keepout
1379  DSN_T keepout_type;
1380 
1381  if( item->GetDoNotAllowVias() && item->GetDoNotAllowTracks() )
1382  keepout_type = T_keepout;
1383  else if( item->GetDoNotAllowVias() )
1384  keepout_type = T_via_keepout;
1385  else if( item->GetDoNotAllowTracks() )
1386  keepout_type = T_wire_keepout;
1387  else
1388  keepout_type = T_keepout;
1389 
1390  // Now, build keepout polygon on each copper layer where the item
1391  // keepout is living (keepout zones can live on many copper layers)
1392  const int copperCount = aBoard->GetCopperLayerCount();
1393 
1394  for( int layer = 0; layer < copperCount; layer++ )
1395  {
1396  if( layer == copperCount - 1 )
1397  layer = B_Cu;
1398 
1399  if( !item->IsOnLayer( PCB_LAYER_ID( layer ) ) )
1400  continue;
1401 
1402  KEEPOUT* keepout = new KEEPOUT( m_pcb->structure, keepout_type );
1403  m_pcb->structure->keepouts.push_back( keepout );
1404 
1405  PATH* mainPolygon = new PATH( keepout, T_polygon );
1406  keepout->SetShape( mainPolygon );
1407 
1408  mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ];
1409 
1410  // Handle the main outlines
1411  SHAPE_POLY_SET::ITERATOR iterator;
1412  bool is_first_point = true;
1413  wxPoint startpoint;
1414 
1415  for( iterator = item->IterateWithHoles(); iterator; iterator++ )
1416  {
1417  wxPoint point( iterator->x, iterator->y );
1418 
1419  if( is_first_point )
1420  {
1421  startpoint = point;
1422  is_first_point = false;
1423  }
1424 
1425  mainPolygon->AppendPoint( mapPt( point ) );
1426 
1427  // this was the end of the main polygon
1428  if( iterator.IsEndContour() )
1429  {
1430  mainPolygon->AppendPoint( mapPt( startpoint ) );
1431  break;
1432  }
1433  }
1434 
1435  WINDOW* window = nullptr;
1436  PATH* cutout = nullptr;
1437 
1438  bool isStartContour = true;
1439 
1440  // handle the cutouts
1441  for( iterator++; iterator; iterator++ )
1442  {
1443  if( isStartContour )
1444  {
1445  is_first_point = true;
1446  window = new WINDOW( keepout );
1447  keepout->AddWindow( window );
1448 
1449  cutout = new PATH( window, T_polygon );
1450 
1451  window->SetShape( cutout );
1452 
1453  cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1454  }
1455 
1456  isStartContour = iterator.IsEndContour();
1457 
1458  wxASSERT( window );
1459  wxASSERT( cutout );
1460 
1461  wxPoint point(iterator->x, iterator->y );
1462 
1463  if( is_first_point )
1464  {
1465  startpoint = point;
1466  is_first_point = false;
1467  }
1468 
1469  cutout->AppendPoint( mapPt(point) );
1470 
1471  // Close the polygon
1472  if( iterator.IsEndContour() )
1473  cutout->AppendPoint( mapPt( startpoint ) );
1474  }
1475  }
1476  }
1477  }
1478 
1479  //-----<build the images, components, and netlist>-----------------------
1480  {
1481  PIN_REF empty( m_pcb->network );
1482 
1483  std::string componentId;
1484 
1485  // find the highest numbered netCode within the board.
1486  int highestNetCode = 0;
1487  NETINFO_LIST& netInfo = aBoard->GetNetInfo();
1488 
1489  for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1490  highestNetCode = std::max( highestNetCode, i->GetNetCode() );
1491 
1492  deleteNETs();
1493 
1494  // expand the net vector to highestNetCode+1, setting empty to NULL
1495  m_nets.resize( highestNetCode + 1, nullptr );
1496 
1497  for( unsigned i = 1 /* skip "No Net" at [0] */; i < m_nets.size(); ++i )
1498  m_nets[i] = new NET( m_pcb->network );
1499 
1500  for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1501  {
1502  if( i->GetNetCode() > 0 )
1503  m_nets[i->GetNetCode()]->net_id = TO_UTF8( i->GetNetname() );
1504  }
1505 
1506  items.Collect( aBoard, scanMODULEs );
1507 
1508  m_padstackset.clear();
1509 
1510  for( int m = 0; m < items.GetCount(); ++m )
1511  {
1512  FOOTPRINT* footprint = (FOOTPRINT*) items[m];
1513 
1514  IMAGE* image = makeIMAGE( aBoard, footprint );
1515 
1516  componentId = TO_UTF8( footprint->GetReference() );
1517 
1518  // create a net list entry for all the actual pins in the image
1519  // for the current footprint. location of this code is critical
1520  // because we fabricated some pin names to ensure unique-ness
1521  // of pin names within a footprint, do not move this code because
1522  // the life of this 'IMAGE* image' is not necessarily long. The
1523  // exported netlist will have some fabricated pin names in it.
1524  // If you don't like fabricated pin names, then make sure all pads
1525  // within your FOOTPRINTs are uniquely named!
1526  for( unsigned p = 0; p < image->pins.size(); ++p )
1527  {
1528  PIN* pin = &image->pins[p];
1529 
1530  int netcode = pin->kiNetCode;
1531 
1532  if( netcode > 0 )
1533  {
1534  NET* net = m_nets[netcode];
1535 
1536  net->pins.push_back( empty );
1537 
1538  PIN_REF& pin_ref = net->pins.back();
1539 
1540  pin_ref.component_id = componentId;
1541  pin_ref.pin_id = pin->pin_id;
1542  }
1543  }
1544 
1546 
1547  if( registered != image )
1548  {
1549  // If our new 'image' is not a unique IMAGE, delete it.
1550  // and use the registered one, known as 'image' after this.
1551  delete image;
1552  image = registered;
1553  }
1554 
1555  COMPONENT* comp = m_pcb->placement->LookupCOMPONENT( image->GetImageId() );
1556 
1557  PLACE* place = new PLACE( comp );
1558 
1559  comp->places.push_back( place );
1560 
1561  place->SetRotation( footprint->GetOrientationDegrees() );
1562  place->SetVertex( mapPt( footprint->GetPosition() ) );
1563  place->component_id = componentId;
1564  place->part_number = TO_UTF8( footprint->GetValue() );
1565 
1566  // footprint is flipped from bottom side, set side to T_back
1567  if( footprint->GetFlag() )
1568  {
1569  double angle = 180.0 - footprint->GetOrientationDegrees();
1571  place->SetRotation( angle );
1572 
1573  place->side = T_back;
1574  }
1575  }
1576 
1577  // copy the SPECCTRA_DB::padstackset to the LIBRARY. Since we are
1578  // removing, do not increment the iterator
1579  for( PADSTACKSET::iterator i = m_padstackset.begin(); i != m_padstackset.end();
1580  i = m_padstackset.begin() )
1581  {
1582  PADSTACKSET::auto_type ps = m_padstackset.release( i );
1583  PADSTACK* padstack = ps.release();
1584 
1585  m_pcb->library->AddPadstack( padstack );
1586  }
1587 
1588  // copy our SPECCTRA_DB::nets to the pcb->network
1589  for( unsigned n = 1; n < m_nets.size(); ++n )
1590  {
1591  NET* net = m_nets[n];
1592 
1593  if( net->pins.size() )
1594  {
1595  // give ownership to pcb->network
1596  m_pcb->network->nets.push_back( net );
1597  m_nets[n] = 0;
1598  }
1599  }
1600  }
1601 
1602  //-----< output vias used in netclasses >-----------------------------------
1603  {
1604  NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
1605 
1606  // Assume the netclass vias are all the same kind of thru, blind, or buried vias.
1607  // This is in lieu of either having each netclass via have its own layer pair in
1608  // the netclass dialog, or such control in the specctra export dialog.
1609 
1610 
1611  m_top_via_layer = 0; // first specctra cu layer is number zero.
1612  m_bot_via_layer = aBoard->GetCopperLayerCount()-1;
1613 
1614  // Add the via from the Default netclass first. The via container
1615  // in pcb->library preserves the sequence of addition.
1616 
1617  NETCLASSPTR netclass = nclasses.GetDefault();
1618 
1619  PADSTACK* via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
1621 
1622  // we AppendVia() this first one, there is no way it can be a duplicate,
1623  // the pcb->library via container is empty at this point. After this,
1624  // we'll have to use LookupVia().
1625  wxASSERT( m_pcb->library->vias.size() == 0 );
1626  m_pcb->library->AppendVia( via );
1627 
1628  // set the "spare via" index at the start of the
1629  // pcb->library->spareViaIndex = pcb->library->vias.size();
1630 
1631  // output the non-Default netclass vias
1632  for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
1633  {
1634  netclass = nc->second;
1635 
1636  via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
1638 
1639  // maybe add 'via' to the library, but only if unique.
1641 
1642  if( registered != via )
1643  delete via;
1644  }
1645  }
1646 
1647  //-----<create the wires from tracks>-----------------------------------
1648  {
1649  // export all of them for now, later we'll decide what controls we need
1650  // on this.
1651  static const KICAD_T scanTRACKs[] = { PCB_TRACE_T, PCB_ARC_T, EOT };
1652 
1653  items.Collect( aBoard, scanTRACKs );
1654 
1655  std::string netname;
1656  WIRING* wiring = m_pcb->wiring;
1657  PATH* path = 0;
1658 
1659  int old_netcode = -1;
1660  int old_width = -1;
1661  LAYER_NUM old_layer = UNDEFINED_LAYER;
1662 
1663  for( int i = 0; i < items.GetCount(); ++i )
1664  {
1665  PCB_TRACK* track = static_cast<PCB_TRACK*>( items[i] );
1666  int netcode = track->GetNetCode();
1667 
1668  if( netcode == 0 )
1669  continue;
1670 
1671  if( old_netcode != netcode || old_width != track->GetWidth() ||
1672  old_layer != track->GetLayer() ||
1673  ( path && path->points.back() != mapPt(track->GetStart() ) ) )
1674  {
1675  old_width = track->GetWidth();
1676  old_layer = track->GetLayer();
1677 
1678  if( old_netcode != netcode )
1679  {
1680  old_netcode = netcode;
1681  NETINFO_ITEM* net = aBoard->FindNet( netcode );
1682  wxASSERT( net );
1683  netname = TO_UTF8( net->GetNetname() );
1684  }
1685 
1686  WIRE* wire = new WIRE( wiring );
1687 
1688  wiring->wires.push_back( wire );
1689  wire->net_id = netname;
1690 
1691  wire->wire_type = T_protect; // @todo, this should be configurable
1692 
1693  LAYER_NUM kiLayer = track->GetLayer();
1694  int pcbLayer = m_kicadLayer2pcb[kiLayer];
1695 
1696  path = new PATH( wire );
1697 
1698  wire->SetShape( path );
1699 
1700  path->layer_id = m_layerIds[pcbLayer];
1701  path->aperture_width = scale( old_width );
1702 
1703  path->AppendPoint( mapPt( track->GetStart() ) );
1704  }
1705 
1706  if( path ) // Should not occur
1707  path->AppendPoint( mapPt( track->GetEnd() ) );
1708  }
1709  }
1710 
1711  //-----<export the existing real BOARD instantiated vias>-----------------
1712  {
1713  // Export all vias, once per unique size and drill diameter combo.
1714  static const KICAD_T scanVIAs[] = { PCB_VIA_T, EOT };
1715 
1716  items.Collect( aBoard, scanVIAs );
1717 
1718  for( int i = 0; i<items.GetCount(); ++i )
1719  {
1720  PCB_VIA* via = static_cast<PCB_VIA*>( items[i] );
1721  wxASSERT( via->Type() == PCB_VIA_T );
1722 
1723  int netcode = via->GetNetCode();
1724 
1725  if( netcode == 0 )
1726  continue;
1727 
1728  PADSTACK* padstack = makeVia( via );
1729  PADSTACK* registered = m_pcb->library->LookupVia( padstack );
1730 
1731  // if the one looked up is not our padstack, then delete our padstack
1732  // since it was a duplicate of one already registered.
1733  if( padstack != registered )
1734  {
1735  delete padstack;
1736  }
1737 
1738  WIRE_VIA* dsnVia = new WIRE_VIA( m_pcb->wiring );
1739 
1740  m_pcb->wiring->wire_vias.push_back( dsnVia );
1741 
1742  dsnVia->padstack_id = registered->padstack_id;
1743  dsnVia->vertexes.push_back( mapPt( via->GetPosition() ) );
1744 
1745  NETINFO_ITEM* net = aBoard->FindNet( netcode );
1746  wxASSERT( net );
1747 
1748  dsnVia->net_id = TO_UTF8( net->GetNetname() );
1749 
1750  dsnVia->via_type = T_protect; // @todo, this should be configurable
1751  }
1752  }
1753 
1754  //-----<via_descriptor>-------------------------------------------------
1755  {
1756  // The pcb->library will output <padstack_descriptors> which is a combined
1757  // list of part padstacks and via padstacks. specctra dsn uses the
1758  // <via_descriptors> to say which of those padstacks are vias.
1759 
1760  // Output the vias in the padstack list here, by name only. This must
1761  // be done after exporting existing vias as WIRE_VIAs.
1762  VIA* vias = m_pcb->structure->via;
1763 
1764  for( unsigned viaNdx = 0; viaNdx < m_pcb->library->vias.size(); ++viaNdx )
1765  {
1766  vias->AppendVia( m_pcb->library->vias[viaNdx].padstack_id.c_str() );
1767  }
1768  }
1769 
1770  //-----<output NETCLASSs>----------------------------------------------------
1771  NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
1772 
1773  exportNETCLASS( nclasses.GetDefault(), aBoard );
1774 
1775  for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
1776  {
1777  NETCLASSPTR netclass = nc->second;
1778  exportNETCLASS( netclass, aBoard );
1779  }
1780 }
DSN_T units
Definition: specctra.h:433
iterator end() const
Definition: netinfo.h:441
A <via_descriptor> in the specctra dsn spec.
Definition: specctra.h:1038
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1344
A <pin_reference> definition in the specctra dsn spec.
Definition: specctra.h:2455
bool space_in_quoted_tokens
Definition: specctra.h:381
void buildLayerMaps(BOARD *aBoard)
Create a few data translation structures for layer name and number mapping between the DSN::PCB struc...
Definition: specctra.cpp:76
DSN::T DSN_T
Definition: specctra.h:46
SHAPE_POLY_SET::ITERATOR IterateWithHoles()
Return an iterator to visit all points of the zone's main outline with holes.
Definition: zone.h:543
void exportNETCLASS(const std::shared_ptr< NETCLASS > &aNetClass, BOARD *aBoard)
Export aNetClass to the DSN file.
A <net_descriptor> in the DSN spec.
Definition: specctra.h:2596
COPPER_PLANES planes
Definition: specctra.h:1672
const wxString & GetValue() const
Definition: footprint.h:452
const wxPoint & GetEnd() const
Definition: pcb_track.h:105
std::string net_id
Definition: specctra.h:2695
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:733
std::string component_id
Definition: specctra.h:2481
Definition: board.h:72
RULE * rules
Definition: specctra.h:1668
static const double safetyMargin
bool GetDoNotAllowVias() const
Definition: zone.h:735
std::string part_number
Definition: specctra.h:1758
PADSTACKS vias
Definition: specctra.h:2448
static POINT mapPt(const wxPoint &pt)
Convert a KiCad point into a DSN file point.
IMAGE * LookupIMAGE(IMAGE *aImage)
Add the image only if one exactly like it does not already exist in the image container.
Definition: specctra.h:2333
static bool registered
Definition: coroutines.cpp:128
POINTS vertexes
Definition: specctra.h:3120
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
void fillBOUNDARY(BOARD *aBoard, BOUNDARY *aBoundary)
Make the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tre...
int LAYER_NUM
This can be replaced with int and removed.
Definition: layer_ids.h:40
UNIT_RES * resolution
Definition: specctra.h:3256
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3989
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:316
IMAGE * makeIMAGE(BOARD *aBoard, FOOTPRINT *aFootprint)
Allocates an I::MAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT.
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:684
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:593
iterator end()
Definition: netclass.h:236
PLACES places
Definition: specctra.h:1809
void NORMALIZE_ANGLE_DEGREES_POS(double &Angle)
Definition: trigo.h:309
int GetWidth() const
Definition: pcb_track.h:102
STRUCTURE * structure
Definition: specctra.h:3258
WIRING * wiring
Definition: specctra.h:3262
static PCB * MakePCB()
Make a PCB with all the default ELEMs and parts on the heap.
Definition: specctra.cpp:3722
std::string net_id
Definition: specctra.h:3121
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:589
std::string layer_id
Definition: specctra.h:650
DSN_T via_type
Definition: specctra.h:3123
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
void SetVertex(const POINT &aVertex)
Definition: specctra.h:1716
std::set< std::string > STRINGSET
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void SetShape(ELEM *aShape)
Definition: specctra.h:858
Definition: board.h:73
Support both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:582
std::pair< STRINGSET::iterator, bool > STRINGSET_PAIR
std::vector< NET * > m_nets
we don't want ownership here permanently, so we don't use boost::ptr_vector
Definition: specctra.h:4005
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
DSN_T layer_type
one of: T_signal, T_power, T_mixed, T_jumper
Definition: specctra.h:1279
NETCLASS_MAP::iterator iterator
Definition: netclass.h:234
void SetShape(ELEM *aShape)
Definition: specctra.h:930
WIRES wires
Definition: specctra.h:3174
int GetFlag() const
Definition: footprint.h:240
int GetTrackWidth() const
Definition: netclass.h:128
std::vector< int > m_kicadLayer2pcb
maps BOARD layer number to PCB layer numbers
Definition: specctra.h:3991
iterator begin()
Definition: netclass.h:235
A container for NETCLASS instances.
Definition: netclass.h:218
std::string name
Definition: specctra.h:1278
void AddWindow(WINDOW *aWindow)
Definition: specctra.h:947
A <plane_descriptor> in the specctra dsn spec.
Definition: specctra.h:1352
void deleteNETs()
Delete all the NETs that may be in here.
Definition: specctra.h:3945
Container for NETINFO_ITEM elements, which are the nets.
Definition: netinfo.h:315
std::string padstack_id
Definition: specctra.h:3119
DSN_T side
Definition: specctra.h:1735
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: zone.cpp:218
iterator begin() const
Definition: netinfo.h:436
Implement a <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1687
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:46
bool GetDoNotAllowTracks() const
Definition: zone.h:736
const wxString & GetNetname() const
Definition: netinfo.h:119
void AddPadstack(PADSTACK *aPadstack)
Definition: specctra.h:2272
const wxString & GetReference() const
Definition: footprint.h:430
#define _(s)
std::string component_id
reference designator
Definition: specctra.h:1733
Hold either a via or a pad definition.
Definition: specctra.h:2126
NETCLASSES & GetNetClasses() const
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
WIRE_VIAS wire_vias
Definition: specctra.h:3175
class ZONE, a copper pour area
Definition: typeinfo.h:105
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:4008
std::vector< std::string > STRINGS
Definition: specctra.h:166
COMPONENT * LookupCOMPONENT(const std::string &imageName)
Look up a COMPONENT by name.
Definition: specctra.h:1838
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Collect BOARD_ITEM objects using this class's Inspector method, which does the collection.
Definition: collectors.cpp:609
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:787
PARSER * parser
Definition: specctra.h:3255
This item represents a net.
void SetRotation(double aRotation)
Definition: specctra.h:1723
LIBRARY * library
Definition: specctra.h:3260
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:395
double GetOrientationDegrees() const
Definition: footprint.h:191
Handle the data for a net.
Definition: netinfo.h:64
PADSTACK * LookupVia(PADSTACK *aVia)
Add the via only if one exactly like it does not already exist in the padstack container.
Definition: specctra.h:2387
Implement a <component_descriptor> in the specctra dsn spec.
Definition: specctra.h:1767
std::vector< PCB_LAYER_ID > m_pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
Definition: specctra.h:3992
A <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2880
const char * name
Definition: DXF_plotter.cpp:56
void AppendVia(PADSTACK *aVia)
Add aVia to the internal via container.
Definition: specctra.h:2365
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:64
int GetClearance() const
Definition: netclass.h:124
PLACEMENT * placement
Definition: specctra.h:3259
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
Base class for iterating over all vertices in a given SHAPE_POLY_SET.
int GetCopperLayerCount() const
Definition: board.cpp:454
NETCLASS * GetDefault() const
void SetShape(ELEM *aShape)
Definition: specctra.h:2901
static bool empty(const wxTextEntryBase *aCtrl)
static double scale(int kicadDist)
Convert a distance from Pcbnew internal units to the reported Specctra DSN units in floating point fo...
void SetBOUNDARY(BOUNDARY *aBoundary)
Definition: specctra.h:1582
wxPoint GetPosition() const override
Definition: footprint.h:186
void AppendVia(const char *aViaName)
Definition: specctra.h:1047
UNIT_RES * unit
Definition: specctra.h:3257
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
LAYERS layers
Definition: specctra.h:1660
PIN_REFS pins
Definition: specctra.h:2700
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
A <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2989
std::string pin_id
Definition: specctra.h:2482
DSN_T wire_type
Definition: specctra.h:2975
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition: collectors.h:614
PROPERTIES properties
Definition: specctra.h:1288
PADSTACKSET m_padstackset
Definition: specctra.h:4002
Used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:905
std::string name
Definition: specctra.h:1012
NETWORK * network
Definition: specctra.h:3261
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:171
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
A <wiring_descriptor> in the specctra dsn spec.
Definition: specctra.h:3136
std::string net_id
Definition: specctra.h:2973
const wxPoint & GetStart() const
Definition: pcb_track.h:108
PADSTACK * makeVia(int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
Make a round through hole #PADSTACK using the given KiCad diameter in deci-mils.
STRINGS rules
rules are saved in std::string form.
Definition: specctra.h:530
KEEPOUTS keepouts
Definition: specctra.h:1670

References _, DSN::LIBRARY::AddPadstack(), DSN::KEEPOUT::AddWindow(), PNS::angle(), DSN::PATH::AppendPoint(), DSN::VIA::AppendVia(), DSN::LIBRARY::AppendVia(), B_Cu, NETCLASSES::begin(), NETINFO_LIST::begin(), buildLayerMaps(), PCB_TYPE_COLLECTOR::Collect(), DSN::PLACE::component_id, DSN::PIN_REF::component_id, deleteNETs(), empty(), NETCLASSES::end(), NETINFO_LIST::end(), EOT, exportNETCLASS(), fillBOUNDARY(), BOARD::FindNet(), Format(), NETCLASS::GetClearance(), BOARD::GetCopperLayerCount(), COLLECTOR::GetCount(), NETCLASSES::GetDefault(), BOARD_DESIGN_SETTINGS::GetDefault(), BOARD::GetDesignSettings(), ZONE::GetDoNotAllowTracks(), ZONE::GetDoNotAllowVias(), PCB_TRACK::GetEnd(), FOOTPRINT::GetFlag(), ZONE::GetIsRuleArea(), BOARD_ITEM::GetLayer(), ZONE::GetLayer(), BOARD::GetLayerType(), BOARD_DESIGN_SETTINGS::GetNetClasses(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD::GetNetInfo(), BOARD_CONNECTED_ITEM::GetNetname(), NETINFO_ITEM::GetNetname(), FOOTPRINT::GetOrientationDegrees(), FOOTPRINT::GetPosition(), FOOTPRINT::GetReference(), PCB_TRACK::GetStart(), NETCLASS::GetTrackWidth(), FOOTPRINT::GetValue(), PCB_TRACK::GetWidth(), image, IsCopperLayer(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::IsEndContour(), ZONE::IsOnLayer(), ZONE::IterateWithHoles(), DSN::STRUCTURE::keepouts, DSN::PATH::layer_id, DSN::LAYER::layer_type, DSN::STRUCTURE::layers, DSN::PCB::library, DSN::PLACEMENT::LookupCOMPONENT(), DSN::LIBRARY::LookupIMAGE(), DSN::LIBRARY::LookupVia(), LT_JUMPER, LT_MIXED, LT_POWER, LT_SIGNAL, m_bot_via_layer, m_kicadLayer2pcb, m_layerIds, m_nets, m_padstackset, m_pcb, m_pcbLayer2kicad, m_top_via_layer, makeIMAGE(), MakePCB(), makeVia(), DSN::mapPt(), name, DSN::KEEPOUT::name, DSN::LAYER::name, DSN::NET::net_id, DSN::WIRE::net_id, DSN::WIRE_VIA::net_id, DSN::NETWORK::nets, DSN::PCB::network, NORMALIZE_ANGLE_DEGREES_POS(), DSN::WIRE_VIA::padstack_id, DSN::PCB::parser, DSN::PLACE::part_number, path, PCB_ARC_T, PCB_FOOTPRINT_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, pin, DSN::PIN_REF::pin_id, DSN::NET::pins, DSN::PCB::placement, DSN::COMPONENT::places, DSN::STRUCTURE::planes, DSN::LAYER::properties, registered, DSN::PCB::resolution, DSN::RULE::rules, DSN::STRUCTURE::rules, safetyMargin, DSN::scale(), DSN::STRUCTURE::SetBOUNDARY(), DSN::PLACE::SetRotation(), DSN::WINDOW::SetShape(), DSN::KEEPOUT::SetShape(), DSN::WIRE::SetShape(), DSN::PLACE::SetVertex(), DSN::PLACE::side, DSN::PARSER::space_in_quoted_tokens, DSN::PCB::structure, THROW_IO_ERROR, TO_UTF8, UNDEFINED_LAYER, DSN::PCB::unit, DSN::UNIT_RES::units, DSN::UNIT_RES::value, DSN::WIRE_VIA::vertexes, via, DSN::STRUCTURE::via, DSN::WIRE_VIA::via_type, DSN::LIBRARY::vias, DSN::WIRE::wire_type, DSN::WIRING::wire_vias, DSN::WIRING::wires, and DSN::PCB::wiring.

Referenced by ExportBoardToSpecctraFile().

◆ FromSESSION()

void DSN::SPECCTRA_DB::FromSESSION ( BOARD aBoard)

Add the entire #SESSION info to a BOARD but does not write it out.

The BOARD given to this function will have all its tracks and via's replaced, and all its components are subject to being moved.

Parameters
aBoardThe BOARD to merge the #SESSION information into.

Definition at line 321 of file specctra_import.cpp.

322 {
323  m_sessionBoard = aBoard; // not owned here
324 
325  if( !m_session )
326  THROW_IO_ERROR( _("Session file is missing the \"session\" section") );
327 
328  if( !m_session->route )
329  THROW_IO_ERROR( _("Session file is missing the \"routes\" section") );
330 
331  if( !m_session->route->library )
332  THROW_IO_ERROR( _("Session file is missing the \"library_out\" section") );
333 
334  // delete all the old tracks and vias
335  aBoard->Tracks().clear();
336 
337  aBoard->DeleteMARKERs();
338 
339  buildLayerMaps( aBoard );
340 
341  if( m_session->placement )
342  {
343  // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
344  // each COMPONENT, reposition and re-orient each component and put on
345  // correct side of the board.
346  COMPONENTS& components = m_session->placement->components;
347  for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp )
348  {
349  PLACES& places = comp->places;
350  for( unsigned i=0; i<places.size(); ++i )
351  {
352  PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
353 
354  wxString reference = FROM_UTF8( place->component_id.c_str() );
355  FOOTPRINT* footprint = aBoard->FindFootprintByReference( reference );
356 
357  if( !footprint )
358  {
359  THROW_IO_ERROR( wxString::Format( _( "Reference '%s' not found." ),
360  reference ) );
361  }
362 
363  if( !place->hasVertex )
364  continue;
365 
366  UNIT_RES* resolution = place->GetUnits();
367  wxASSERT( resolution );
368 
369  wxPoint newPos = mapPt( place->vertex, resolution );
370  footprint->SetPosition( newPos );
371 
372  if( place->side == T_front )
373  {
374  // convert from degrees to tenths of degrees used in KiCad.
375  int orientation = KiROUND( place->rotation * 10.0 );
376 
377  if( footprint->GetLayer() != F_Cu )
378  {
379  // footprint is on copper layer (back)
380  footprint->Flip( footprint->GetPosition(), false );
381  }
382 
383  footprint->SetOrientation( orientation );
384  }
385  else if( place->side == T_back )
386  {
387  int orientation = KiROUND( (place->rotation + 180.0) * 10.0 );
388 
389  if( footprint->GetLayer() != B_Cu )
390  {
391  // footprint is on component layer (front)
392  footprint->Flip( footprint->GetPosition(), false );
393  }
394 
395  footprint->SetOrientation( orientation );
396  }
397  else
398  {
399  // as I write this, the PARSER *is* catching this, so we should never see below:
400  wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") );
401  }
402  }
403  }
404  }
405 
407 
408  // Walk the NET_OUTs and create tracks and vias anew.
409  NET_OUTS& net_outs = m_session->route->net_outs;
410  for( NET_OUTS::iterator net = net_outs.begin(); net!=net_outs.end(); ++net )
411  {
412  int netoutCode = 0;
413 
414  // page 143 of spec says wire's net_id is optional
415  if( net->net_id.size() )
416  {
417  wxString netName = FROM_UTF8( net->net_id.c_str() );
418  NETINFO_ITEM* netinfo = aBoard->FindNet( netName );
419 
420  if( netinfo )
421  {
422  netoutCode = netinfo->GetNetCode();
423  }
424  else // else netCode remains 0
425  {
426  // int breakhere = 1;
427  }
428  }
429 
430  WIRES& wires = net->wires;
431  for( unsigned i = 0; i<wires.size(); ++i )
432  {
433  WIRE* wire = &wires[i];
434  DSN_T shape = wire->shape->Type();
435 
436  if( shape != T_path )
437  {
438  /* shape == T_polygon is expected from freerouter if you have
439  a zone on a non "power" type layer, i.e. a T_signal layer
440  and the design does a round trip back in as session here.
441  We kept our own zones in the BOARD, so ignore this so called
442  'wire'.
443 
444  wxString netId = FROM_UTF8( wire->net_id.c_str() );
445  THROW_IO_ERROR( wxString::Format( _("Unsupported wire shape: \"%s\" for net: \"%s\""),
446  DLEX::GetTokenString(shape).GetData(),
447  netId.GetData()
448  ) );
449  */
450  }
451  else
452  {
453  PATH* path = (PATH*) wire->shape;
454 
455  for( unsigned pt=0; pt<path->points.size()-1; ++pt )
456  {
457  PCB_TRACK* track = makeTRACK( path, pt, netoutCode );
458  aBoard->Add( track );
459  }
460  }
461  }
462 
463  WIRE_VIAS& wire_vias = net->wire_vias;
465  for( unsigned i=0; i<wire_vias.size(); ++i )
466  {
467  int netCode = 0;
468 
469  // page 144 of spec says wire_via's net_id is optional
470  if( net->net_id.size() )
471  {
472  wxString netName = FROM_UTF8( net->net_id.c_str() );
473  NETINFO_ITEM* netvia = aBoard->FindNet( netName );
474 
475  if( netvia )
476  netCode = netvia->GetNetCode();
477 
478  // else netCode remains 0
479  }
480 
481  WIRE_VIA* wire_via = &wire_vias[i];
482 
483  // example: (via Via_15:8_mil 149000 -71000 )
484 
485  PADSTACK* padstack = library.FindPADSTACK( wire_via->GetPadstackId() );
486  if( !padstack )
487  {
488  // Dick Feb 29, 2008:
489  // Freerouter has a bug where it will not round trip all vias.
490  // Vias which have a (use_via) element will be round tripped.
491  // Vias which do not, don't come back in in the session library,
492  // even though they may be actually used in the pre-routed,
493  // protected wire_vias. So until that is fixed, create the
494  // padstack from its name as a work around.
495 
496 
497  // Could use a STRING_FORMATTER here and convert the entire
498  // wire_via to text and put that text into the exception.
499  wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) );
500 
501  THROW_IO_ERROR( wxString::Format( _( "A wire_via refers to missing padstack '%s'." ),
502  psid ) );
503  }
504 
505  NETCLASSPTR netclass = aBoard->GetDesignSettings().GetNetClasses().GetDefault();
506 
507  int via_drill_default = netclass->GetViaDrill();
508 
509  for( unsigned v=0; v<wire_via->vertexes.size(); ++v )
510  {
511  PCB_VIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode,
512  via_drill_default );
513  aBoard->Add( via );
514  }
515  }
516  }
517 }
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1344
void buildLayerMaps(BOARD *aBoard)
Create a few data translation structures for layer name and number mapping between the DSN::PCB struc...
Definition: specctra.cpp:76
BOARD * m_sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3998
DSN::T DSN_T
Definition: specctra.h:46
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
boost::ptr_vector< WIRE_VIA > WIRE_VIAS
Definition: specctra.h:3130
NET_OUTS net_outs
Definition: specctra.h:3518
static POINT mapPt(const wxPoint &pt)
Convert a KiCad point into a DSN file point.
POINTS vertexes
Definition: specctra.h:3120
A holder for either a T_unit or T_resolution object which are usually mutually exclusive in the dsn g...
Definition: specctra.h:402
boost::ptr_vector< NET_OUT > NET_OUTS
Definition: specctra.h:3451
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:589
POINT vertex
Definition: specctra.h:1740
Support both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:582
double rotation
Definition: specctra.h:1737
bool hasVertex
Definition: specctra.h:1739
ELEM * shape
Definition: specctra.h:2971
UNIT_RES * GetUnits() const override
Return the units for this section.
Definition: specctra.h:3475
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:607
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:827
DSN_T side
Definition: specctra.h:1735
Implement a <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1687
LIBRARY * library
Definition: specctra.h:3517
#define _(s)
std::string component_id
reference designator
Definition: specctra.h:1733
Hold either a via or a pad definition.
Definition: specctra.h:2126
NETCLASSES & GetNetClasses() const
PCB_VIA * makeVIA(PADSTACK *aPadstack, const POINT &aPoint, int aNetCode, int aViaDrillDefault)
Instantiate a KiCad #VIA on the heap and initializes it with internal values consistent with the give...
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
UNIT_RES * m_routeResolution
used during FromSESSION() only, memory for it is not owned here.
Definition: specctra.h:3995
PLACEMENT * placement
Definition: specctra.h:3630
const std::string & GetPadstackId()
Definition: specctra.h:3001
Handle the data for a net.
Definition: netinfo.h:64
A <library_descriptor> in the specctra dsn specification.
Definition: specctra.h:2257
A <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2880
boost::ptr_vector< PLACE > PLACES
Definition: specctra.h:1761
DSN_T Type() const
Definition: specctra.h:210
PCB_TRACK * makeTRACK(PATH *aPath, int aPointIndex, int aNetcode)
Create a #TRACK form the #PATH and BOARD info.
Definition: layer_ids.h:70
SESSION * m_session
Definition: specctra.h:3981
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
ROUTE * route
Definition: specctra.h:3632
virtual UNIT_RES * GetUnits() const
Return the units for this section.
Definition: specctra.cpp:3765
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2983
A <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2989
boost::ptr_vector< COMPONENT > COMPONENTS
Definition: pcb_netlist.h:199
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
COMPONENTS components
Definition: specctra.h:1882
TRACKS & Tracks()
Definition: board.h:230
FOOTPRINT * FindFootprintByReference(const wxString &aReference) const
Search for a FOOTPRINT within this board with the given reference designator.
Definition: board.cpp:1365
int GetNetCode() const
Definition: netinfo.h:113

References _, BOARD::Add(), B_Cu, buildLayerMaps(), DSN::PLACE::component_id, DSN::PLACEMENT::components, BOARD::DeleteMARKERs(), F_Cu, BOARD::FindFootprintByReference(), BOARD::FindNet(), Format(), FROM_UTF8(), NETCLASSES::GetDefault(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetNetClasses(), NETINFO_ITEM::GetNetCode(), DSN::WIRE_VIA::GetPadstackId(), DSN::ELEM::GetUnits(), DSN::ROUTE::GetUnits(), DSN::PLACE::hasVertex, KiROUND(), library, DSN::ROUTE::library, m_routeResolution, m_session, m_sessionBoard, makeTRACK(), makeVIA(), DSN::mapPt(), DSN::ROUTE::net_outs, path, DSN::SESSION::placement, DSN::PLACE::rotation, DSN::SESSION::route, DSN::WIRE::shape, DSN::PLACE::side, THROW_IO_ERROR, BOARD::Tracks(), DSN::ELEM::Type(), DSN::PLACE::vertex, DSN::WIRE_VIA::vertexes, and via.

Referenced by PCB_EDIT_FRAME::ImportSpecctraSession().

◆ GetPCB()

PCB* DSN::SPECCTRA_DB::GetPCB ( )
inline

Definition at line 3694 of file specctra.h.

3694 { return m_pcb; }

References m_pcb.

Referenced by main().

◆ GetSESSION()

SESSION* DSN::SPECCTRA_DB::GetSESSION ( )
inline

Definition at line 3705 of file specctra.h.

3705 { return m_session; }
SESSION * m_session
Definition: specctra.h:3981

References m_session.

Referenced by main().

◆ LoadPCB()

void DSN::SPECCTRA_DB::LoadPCB ( const wxString &  aFilename)

A recursive descent parser for a SPECCTRA DSN "design" file.

A design file is nearly a full description of a PCB (seems to be missing only the silkscreen stuff).

Parameters
aFilenameThe name of the dsn file to load.
Exceptions
IO_ERRORif there is a lexer or parser error.

Definition at line 258 of file specctra.cpp.

259 {
260  FILE_LINE_READER curr_reader( aFilename );
261 
262  PushReader( &curr_reader );
263 
264  if( NextTok() != T_LEFT )
265  Expecting( T_LEFT );
266 
267  if( NextTok() != T_pcb )
268  Expecting( T_pcb );
269 
270  SetPCB( new PCB() );
271 
272  doPCB( m_pcb );
273  PopReader();
274 }
void SetPCB(PCB *aPcb)
Delete any existing PCB and replaces it with the given one.
Definition: specctra.h:3688
A LINE_READER that reads from an open file.
Definition: richio.h:172
void doPCB(PCB *growth)
Definition: specctra.cpp:297

References doPCB(), m_pcb, and SetPCB().

◆ LoadSESSION()

void DSN::SPECCTRA_DB::LoadSESSION ( const wxString &  aFilename)

A recursive descent parser for a SPECCTRA DSN "session" file.

A session file is a file that is fed back from the router to the layout tool (Pcbnew) and should be used to update a BOARD object with the new tracks, vias, and component locations.

Parameters
aFilenameThe name of the dsn file to load.
Exceptions
IO_ERRORif there is a lexer or parser error.

Definition at line 277 of file specctra.cpp.

278 {
279  FILE_LINE_READER curr_reader( aFilename );
280 
281  PushReader( &curr_reader );
282 
283  if( NextTok() != T_LEFT )
284  Expecting( T_LEFT );
285 
286  if( NextTok() != T_session )
287  Expecting( T_session );
288 
289  SetSESSION( new SESSION() );
290 
291  doSESSION( m_session );
292 
293  PopReader();
294 }
void SetSESSION(SESSION *aSession)
Delete any existing SESSION and replaces it with the given one.
Definition: specctra.h:3699
A LINE_READER that reads from an open file.
Definition: richio.h:172
SESSION * m_session
Definition: specctra.h:3981
void doSESSION(SESSION *growth)
Definition: specctra.cpp:3373

References doSESSION(), m_session, and SetSESSION().

Referenced by PCB_EDIT_FRAME::ImportSpecctraSession(), and main().

◆ makeIMAGE()

IMAGE * DSN::SPECCTRA_DB::makeIMAGE ( BOARD aBoard,
FOOTPRINT aFootprint 
)
private

Allocates an I::MAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT.

Parameters
aBoardThe owner of the FOOTPRINT.
aFootprintThe FOOTPRINT from which to build the IMAGE.
Returns
not tested for duplication yet.

Definition at line 612 of file specctra_export.cpp.

613 {
614  PINMAP pinmap;
615  wxString padNumber;
616 
617  PCB_TYPE_COLLECTOR fpItems;
618 
619  // get all the FOOTPRINT's pads.
620  fpItems.Collect( aFootprint, scanPADs );
621 
622  IMAGE* image = new IMAGE( 0 );
623 
624  image->image_id = aFootprint->GetFPID().Format().c_str();
625 
626  // from the pads, and make an IMAGE using collated padstacks.
627  for( int p = 0; p < fpItems.GetCount(); ++p )
628  {
629  PAD* pad = (PAD*) fpItems[p];
630 
631  // see if this pad is a through hole with no copper on its perimeter
632  if( isRoundKeepout( pad ) )
633  {
634  double diameter = scale( pad->GetDrillSize().x );
635  POINT vertex = mapPt( pad->GetPos0() );
636 
637  int layerCount = aBoard->GetCopperLayerCount();
638 
639  for( int layer=0; layer<layerCount; ++layer )
640  {
641  KEEPOUT* keepout = new KEEPOUT( image, T_keepout );
642 
643  image->keepouts.push_back( keepout );
644 
645  CIRCLE* circle = new CIRCLE( keepout );
646 
647  keepout->SetShape( circle );
648 
649  circle->SetDiameter( diameter );
650  circle->SetVertex( vertex );
651  circle->SetLayerId( m_layerIds[layer].c_str() );
652  }
653  }
654  else // else if() could there be a square keepout here?
655  {
656  // Pads not on copper layers (i.e. only on tech layers) are ignored
657  // because they create invalid pads in .dsn file for freeroute
658  LSET mask_copper_layers = pad->GetLayerSet() & LSET::AllCuMask();
659 
660  if( !mask_copper_layers.any() )
661  continue;
662 
663  PADSTACK* padstack = makePADSTACK( aBoard, pad );
664  PADSTACKSET::iterator iter = m_padstackset.find( *padstack );
665 
666  if( iter != m_padstackset.end() )
667  {
668  // padstack is a duplicate, delete it and use the original
669  delete padstack;
670  padstack = (PADSTACK*) *iter.base(); // folklore, be careful here
671  }
672  else
673  {
674  m_padstackset.insert( padstack );
675  }
676 
677  PIN* pin = new PIN( image );
678 
679  padNumber = pad->GetNumber();
680  pin->pin_id = TO_UTF8( padNumber );
681 
682  if( padNumber != wxEmptyString && pinmap.find( padNumber ) == pinmap.end() )
683  {
684  pinmap[ padNumber ] = 0;
685  }
686  else // pad name is a duplicate within this footprint
687  {
688  char buf[32];
689  int duplicates = ++pinmap[ padNumber ];
690 
691  sprintf( buf, "@%d", duplicates );
692 
693  pin->pin_id += buf; // append "@1" or "@2", etc. to pin name
694  }
695 
696  pin->kiNetCode = pad->GetNetCode();
697 
698  image->pins.push_back( pin );
699 
700  pin->padstack_id = padstack->padstack_id;
701 
702  double angle = pad->GetOrientationDegrees() - aFootprint->GetOrientationDegrees();
704  pin->SetRotation( angle );
705 
706  wxPoint pos( pad->GetPos0() );
707 
708  pin->SetVertex( mapPt( pos ) );
709  }
710  }
711 
712  static const KICAD_T scanEDGEs[] = { PCB_FP_SHAPE_T, EOT };
713 
714  // get all the FOOTPRINT's FP_SHAPEs and convert those to DSN outlines.
715  fpItems.Collect( aFootprint, scanEDGEs );
716 
717  for( int i = 0; i < fpItems.GetCount(); ++i )
718  {
719  FP_SHAPE* graphic = (FP_SHAPE*) fpItems[i];
720  SHAPE* outline;
721  PATH* path;
722 
723  switch( graphic->GetShape() )
724  {
725  case SHAPE_T::SEGMENT:
726  outline = new SHAPE( image, T_outline );
727 
728  image->Append( outline );
729  path = new PATH( outline );
730 
731  outline->SetShape( path );
732  path->SetAperture( scale( graphic->GetWidth() ) );
733  path->SetLayerId( "signal" );
734  path->AppendPoint( mapPt( graphic->GetStart0() ) );
735  path->AppendPoint( mapPt( graphic->GetEnd0() ) );
736  break;
737 
738  case SHAPE_T::CIRCLE:
739  {
740  // this is best done by 4 QARC's but freerouter does not yet support QARCs.
741  // for now, support by using line segments.
742  outline = new SHAPE( image, T_outline );
743  image->Append( outline );
744 
745  path = new PATH( outline );
746 
747  outline->SetShape( path );
748  path->SetAperture( scale( graphic->GetWidth() ) );
749  path->SetLayerId( "signal" );
750 
751  double radius = graphic->GetRadius();
752  wxPoint circle_centre = graphic->GetStart0();
753 
754  SHAPE_LINE_CHAIN polyline;
755  ConvertArcToPolyline( polyline, VECTOR2I( circle_centre ), radius, 0.0, 360.0,
756  ARC_HIGH_DEF, ERROR_INSIDE );
757 
758  for( int ii = 0; ii < polyline.PointCount(); ++ii )
759  {
760  wxPoint corner( polyline.CPoint( ii ).x, polyline.CPoint( ii ).y );
761  path->AppendPoint( mapPt( corner ) );
762  }
763 
764  break;
765  }
766 
767  case SHAPE_T::RECT:
768  {
769  outline = new SHAPE( image, T_outline );
770 
771  image->Append( outline );
772  path = new PATH( outline );
773 
774  outline->SetShape( path );
775  path->SetAperture( scale( graphic->GetWidth() ) );
776  path->SetLayerId( "signal" );
777  wxPoint corner = graphic->GetStart0();
778  path->AppendPoint( mapPt( corner ) );
779 
780  corner.x = graphic->GetEnd0().x;
781  path->AppendPoint( mapPt( corner ) );
782 
783  corner.y = graphic->GetEnd0().y;
784  path->AppendPoint( mapPt( corner ) );
785 
786  corner.x = graphic->GetStart0().x;
787  path->AppendPoint( mapPt( corner ) );
788  break;
789  }
790 
791  case SHAPE_T::ARC:
792  {
793  // this is best done by QARC's but freerouter does not yet support QARCs.
794  // for now, support by using line segments.
795  // So we use a polygon (PATH) to create a approximate arc shape
796  outline = new SHAPE( image, T_outline );
797 
798  image->Append( outline );
799  path = new PATH( outline );
800 
801  outline->SetShape( path );
802  path->SetAperture( 0 );//scale( graphic->GetWidth() ) );
803  path->SetLayerId( "signal" );
804 
805  wxPoint arc_centre = graphic->GetStart0();
806  double radius = graphic->GetRadius() + graphic->GetWidth() / 2;
807  double arcStartDeg = graphic->GetArcAngleStart() / 10.0;
808  double arcAngleDeg = graphic->GetAngle() / 10.0;
809 
810  // For some obscure reason, FreeRouter does not show the same polygonal
811  // shape for polygons CW and CCW. So used only the order of corners
812  // giving the best look.
813  if( arcAngleDeg < 0 )
814  {
815  arcStartDeg = graphic->GetArcAngleEnd() / 10.0;
816  arcAngleDeg = -arcAngleDeg;
817  }
818 
819  SHAPE_LINE_CHAIN polyline;
820  ConvertArcToPolyline( polyline,