KiCad PCB EDA Suite
DSN::SPECCTRA_DB Class Reference

SPECCTRA_DB holds 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)
 Function SetPCB deletes any existing PCB and replaces it with the given one. More...
 
PCBGetPCB ()
 
void SetSESSION (SESSION *aSession)
 Function SetSESSION deletes any existing SESSION and replaces it with the given one. More...
 
SESSIONGetSESSION ()
 
void LoadPCB (const wxString &aFilename)
 Function LoadPCB is a recursive descent parser for a SPECCTRA DSN "design" file. More...
 
void LoadSESSION (const wxString &aFilename)
 Function LoadSESSION is a recursive descent parser for a SPECCTRA DSN "session" file. More...
 
void ExportPCB (const wxString &aFilename, bool aNameChange=false)
 Function ExportPCB writes the internal PCB instance out as a SPECTRA DSN format file. More...
 
void FromBOARD (BOARD *aBoard)
 Function FromBOARD adds the entire BOARD to the PCB but does not write it out. More...
 
void FromSESSION (BOARD *aBoard)
 Function FromSESSION adds the entire SESSION info to a BOARD but does not write it out. More...
 
void ExportSESSION (const wxString &aFilename)
 Function ExportSESSION writes the internal SESSION instance out as a SPECTRA DSN format file. More...
 
void FlipFOOTPRINTs (BOARD *aBoard)
 Function FlipFOOTPRINTs flips the footprints which are on the back side of the board to the front. More...
 
void RevertFOOTPRINTs (BOARD *aBoard)
 Function RevertFOOTPRINTs flips the footprints which were on the back side of the board back to the back. More...
 

Static Public Member Functions

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

Private Member Functions

void buildLayerMaps (BOARD *aBoard)
 Function buildLayerMaps creates 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
 Function findLayerName returns the PCB layer index for a given layer name, within the specctra session file. More...
 
void readCOMPnPIN (std::string *component_id, std::string *pid_id)
 Function readCOMPnPIN reads 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)
 Function readTIME reads 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)
 Function fillBOUNDARY makes the board perimeter for the DSN file by filling the BOUNDARY element in the specctra element tree. More...
 
IMAGEmakeIMAGE (BOARD *aBoard, FOOTPRINT *aFootprint)
 Function makeIMAGE allocates an IMAGE on the heap and creates all the PINs according to the PADs in the FOOTPRINT. More...
 
PADSTACKmakePADSTACK (BOARD *aBoard, PAD *aPad)
 Function makePADSTACK creates a PADSTACK which matches the given pad. More...
 
PADSTACKmakeVia (int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
 Function makeVia makes a round through hole PADSTACK using the given KiCad diameter in deci-mils. More...
 
PADSTACKmakeVia (const ::VIA *aVia)
 Function makeVia makes any kind of PADSTACK using the given KiCad VIA. More...
 
void deleteNETs ()
 Function deleteNETs deletes all the NETs that may be in here. More...
 
void exportNETCLASS (const std::shared_ptr< NETCLASS > &aNetClass, BOARD *aBoard)
 Function exportNETCLASS exports aNetClass to the DSN file. More...
 
TRACKmakeTRACK (PATH *aPath, int aPointIndex, int aNetcode)
 Function makeTRACK creates a TRACK form the PATH and BOARD info. More...
 
::VIAmakeVIA (PADSTACK *aPadstack, const POINT &aPoint, int aNetCode, int aViaDrillDefault)
 Function makeVIA instantiates 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
 
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

SPECCTRA_DB holds a DSN data tree, usually coming from a DSN file.

Is essentially a SPECCTRA_PARSER class.

Definition at line 3632 of file specctra.h.

Constructor & Destructor Documentation

◆ SPECCTRA_DB()

DSN::SPECCTRA_DB::SPECCTRA_DB ( )
inline

Definition at line 3865 of file specctra.h.

3865  :
3866  SPECCTRA_LEXER( 0 ) // LINE_READER* == NULL, no DSNLEXER::PushReader()
3867  {
3868  // The LINE_READER will be pushed from an automatic instantiation,
3869  // we don't own it:
3870  wxASSERT( !iOwnReaders );
3871 
3872  m_pcb = 0;
3873  m_session = 0;
3874  m_quote_char += '"';
3875  m_footprintsAreFlipped = false;
3876 
3877  SetSpecctraMode( true );
3878 
3879  // Avoid not initialized members:
3881  m_sessionBoard = NULL;
3882  m_top_via_layer = 0;
3883  m_bot_via_layer = 0;
3884  }
BOARD * m_sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3655
bool m_footprintsAreFlipped
Definition: specctra.h:3642
#define NULL
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:3665
UNIT_RES * m_routeResolution
used during FromSESSION() only, memory for it is not owned here.
Definition: specctra.h:3652
SESSION * m_session
Definition: specctra.h:3638
std::string m_quote_char
Definition: specctra.h:3640

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

◆ ~SPECCTRA_DB()

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

Definition at line 3886 of file specctra.h.

3887  {
3888  delete m_pcb;
3889  delete m_session;
3890 
3891  deleteNETs();
3892  }
void deleteNETs()
Function deleteNETs deletes all the NETs that may be in here.
Definition: specctra.h:3830
SESSION * m_session
Definition: specctra.h:3638

References deleteNETs(), m_pcb, and m_session.

Member Function Documentation

◆ buildLayerMaps()

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

Function buildLayerMaps creates 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 74 of file specctra.cpp.

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

◆ deleteNETs()

void DSN::SPECCTRA_DB::deleteNETs ( )
inlineprivate

Function deleteNETs deletes all the NETs that may be in here.

Definition at line 3830 of file specctra.h.

3831  {
3832  for( unsigned n=0; n < m_nets.size(); ++n )
3833  delete m_nets[n];
3834 
3835  m_nets.clear();
3836  }
std::vector< NET * > m_nets
we don't want ownership here permanently, so we don't use boost::ptr_vector
Definition: specctra.h:3662

References m_nets.

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

◆ doANCESTOR()

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

Definition at line 3043 of file specctra.cpp.

3044 {
3045  T tok;
3046 
3047  /* <ancestor_file_descriptor >::=
3048  (ancestor <file_path_name> (created_time <time_stamp> )
3049  [(comment <comment_string> )])
3050  */
3051 
3052  NeedSYMBOL();
3053  growth->filename = CurText();
3054 
3055  while( (tok = NextTok()) != T_RIGHT )
3056  {
3057  if( tok != T_LEFT )
3058  Expecting( T_LEFT );
3059 
3060  tok = NextTok();
3061  switch( tok )
3062  {
3063  case T_created_time:
3064  readTIME( &growth->time_stamp );
3065  NeedRIGHT();
3066  break;
3067 
3068  case T_comment:
3069  NeedSYMBOL();
3070  growth->comment = CurText();
3071  NeedRIGHT();
3072  break;
3073 
3074  default:
3075  Unexpected( CurText() );
3076  }
3077  }
3078 }
void readTIME(time_t *time_stamp)
Function readTIME reads a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : ...
Definition: specctra.cpp:177

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 967 of file specctra.cpp.

968 {
969  T tok = NextTok();
970 
971  if( tok != T_LEFT )
972  Expecting( T_LEFT );
973 
974  tok = NextTok();
975  if( tok == T_rect )
976  {
977  if( growth->paths.size() )
978  Unexpected( "rect when path already encountered" );
979 
980  growth->rectangle = new RECTANGLE( growth );
981  doRECTANGLE( growth->rectangle );
982  NeedRIGHT();
983  }
984  else if( tok == T_path )
985  {
986  if( growth->rectangle )
987  Unexpected( "path when rect already encountered" );
988 
989  for(;;)
990  {
991  if( tok != T_path )
992  Expecting( T_path );
993 
994  PATH* path = new PATH( growth, T_path );
995  growth->paths.push_back( path );
996 
997  doPATH( path );
998 
999  tok = NextTok();
1000  if( tok == T_RIGHT )
1001  break;
1002 
1003  if( tok != T_LEFT )
1004  Expecting(T_LEFT);
1005 
1006  tok = NextTok();
1007  }
1008  }
1009  else
1010  Expecting( "rect|path" );
1011 }
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062

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 1087 of file specctra.cpp.

1088 {
1089  T tok;
1090 
1091  NeedSYMBOLorNUMBER();
1092  growth->layer_id = CurText();
1093 
1094  if( NextTok() != T_NUMBER )
1095  Expecting( T_NUMBER );
1096  growth->diameter = strtod( CurText(), 0 );
1097 
1098  tok = NextTok();
1099  if( tok == T_NUMBER )
1100  {
1101  growth->vertex.x = strtod( CurText(), 0 );
1102 
1103  if( NextTok() != T_NUMBER )
1104  Expecting( T_NUMBER );
1105  growth->vertex.y = strtod( CurText(), 0 );
1106 
1107  tok = NextTok();
1108  }
1109 
1110  if( tok != T_RIGHT )
1111  Expecting( T_RIGHT );
1112 }

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 2501 of file specctra.cpp.

2502 {
2503  T tok;
2504 
2505  /* <class_descriptor >::=
2506  (class
2507  <class_id > {[{<net_id >} | {<composite_name_list> }]}
2508  [<circuit_descriptor> ]
2509  [<rule_descriptor> ]
2510  [{<layer_rule_descriptor> }]
2511  [<topology_descriptor> ]
2512  )
2513  */
2514 
2515  NeedSYMBOL();
2516 
2517  growth->class_id = CurText();
2518 
2519  // do net_ids, do not support <composite_name_list>s at this time
2520  while( IsSymbol(tok = NextTok()) )
2521  {
2522  growth->net_ids.push_back( CurText() );
2523  }
2524 
2525 
2526  while( tok != T_RIGHT )
2527  {
2528  if( tok != T_LEFT )
2529  Expecting( T_LEFT );
2530 
2531  tok = NextTok();
2532  switch( tok )
2533  {
2534  case T_rule:
2535  if( growth->rules )
2536  Unexpected( tok );
2537  growth->rules = new RULE( growth, T_rule );
2538  doRULE( growth->rules );
2539  break;
2540 
2541  case T_layer_rule:
2542  LAYER_RULE* layer_rule;
2543  layer_rule = new LAYER_RULE( growth );
2544  growth->layer_rules.push_back( layer_rule );
2545  doLAYER_RULE( layer_rule );
2546  break;
2547 
2548  case T_topology:
2549  if( growth->topology )
2550  Unexpected( tok );
2551  growth->topology = new TOPOLOGY( growth );
2552  doTOPOLOGY( growth->topology );
2553  break;
2554 
2555  case T_circuit: // handle all the circuit_descriptor here as strings
2556  {
2557  std::string builder;
2558  int bracketNesting = 1; // we already saw the opening T_LEFT
2559  tok = T_NONE;
2560 
2561  while( bracketNesting!=0 && tok!=T_EOF )
2562  {
2563  tok = NextTok();
2564 
2565  if( tok==T_LEFT)
2566  ++bracketNesting;
2567 
2568  else if( tok==T_RIGHT )
2569  --bracketNesting;
2570 
2571  if( bracketNesting >= 1 )
2572  {
2573  T previousTok = (T) PrevTok();
2574 
2575  if( previousTok!=T_LEFT && previousTok!=T_circuit && tok!=T_RIGHT )
2576  builder += ' ';
2577 
2578  if( tok==T_STRING )
2579  builder += m_quote_char;
2580 
2581  builder += CurText();
2582 
2583  if( tok==T_STRING )
2584  builder += m_quote_char;
2585  }
2586 
2587  // When the nested rule is closed with a T_RIGHT and we are back down
2588  // to bracketNesting == 0, then save the builder and break;
2589  if( bracketNesting == 0 )
2590  {
2591  growth->circuit.push_back( builder );
2592  break;
2593  }
2594  }
2595 
2596  if( tok==T_EOF )
2597  Unexpected( T_EOF );
2598  } // scope bracket
2599  break;
2600 
2601  default:
2602  Unexpected( CurText() );
2603  } // switch
2604 
2605  tok = NextTok();
2606 
2607  } // while
2608 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doTOPOLOGY(TOPOLOGY *growth)
Definition: specctra.cpp:2463
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1715
std::string m_quote_char
Definition: specctra.h:3640

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 1582 of file specctra.cpp.

1583 {
1584  T tok = NextTok();
1585 
1586  if( tok != T_LEFT )
1587  Expecting( T_LEFT );
1588 
1589  while( (tok = NextTok()) != T_RIGHT )
1590  {
1591  switch( tok )
1592  {
1593  case T_classes:
1594  if( growth->classes )
1595  Unexpected( tok );
1596  growth->classes = new CLASSES( growth );
1597  doCLASSES( growth->classes );
1598  break;
1599 
1600  case T_rule:
1601  // only T_class_class takes a T_rule
1602  if( growth->Type() == T_region_class_class )
1603  Unexpected( tok );
1604  RULE* rule;
1605  rule = new RULE( growth, T_rule );
1606  growth->Append( rule );
1607  doRULE( rule );
1608  break;
1609 
1610  case T_layer_rule:
1611  // only T_class_class takes a T_layer_rule
1612  if( growth->Type() == T_region_class_class )
1613  Unexpected( tok );
1614  LAYER_RULE* layer_rule;
1615  layer_rule = new LAYER_RULE( growth );
1616  growth->Append( layer_rule );
1617  doLAYER_RULE( layer_rule );
1618  break;
1619 
1620  default:
1621  Unexpected( tok );
1622  }
1623  }
1624 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doCLASSES(CLASSES *growth)
Definition: specctra.cpp:1627
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1715

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 1627 of file specctra.cpp.

1628 {
1629  T tok = NextTok();
1630 
1631  // require at least 2 class_ids
1632 
1633  if( !IsSymbol( tok ) )
1634  Expecting( "class_id" );
1635 
1636  growth->class_ids.push_back( CurText() );
1637 
1638  do
1639  {
1640  tok = NextTok();
1641  if( !IsSymbol( tok ) )
1642  Expecting( "class_id" );
1643 
1644  growth->class_ids.push_back( CurText() );
1645 
1646  } while( (tok = NextTok()) != T_RIGHT );
1647 }

References DSN::CLASSES::class_ids.

Referenced by doCLASS_CLASS().

◆ doCOMP_ORDER()

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

Definition at line 2656 of file specctra.cpp.

2657 {
2658  T tok;
2659 
2660  /* <component_order_descriptor >::=
2661  (comp_order {<placement_id> })
2662  */
2663 
2664  while( IsSymbol(tok = NextTok()) )
2665  {
2666  growth->placement_ids.push_back( CurText() );
2667  }
2668 
2669  if( tok != T_RIGHT )
2670  Expecting( T_RIGHT );
2671 }

References DSN::COMP_ORDER::placement_ids.

Referenced by doNET(), and doTOPOLOGY().

◆ doCOMPONENT()

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

Definition at line 1855 of file specctra.cpp.

1856 {
1857  T tok = NextTok();
1858 
1859  if( !IsSymbol( tok ) && tok != T_NUMBER )
1860  Expecting( "image_id" );
1861  growth->image_id = CurText();
1862 
1863  while( (tok = NextTok()) != T_RIGHT )
1864  {
1865  if( tok != T_LEFT )
1866  Expecting( T_LEFT );
1867 
1868  tok = NextTok();
1869  switch( tok )
1870  {
1871  case T_place:
1872  PLACE* place;
1873  place = new PLACE( growth );
1874  growth->places.push_back( place );
1875  doPLACE( place );
1876  break;
1877 
1878  default:
1879  Unexpected(tok);
1880  }
1881  }
1882 }
void doPLACE(PLACE *growth)
Definition: specctra.cpp:1740

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 878 of file specctra.cpp.

879 {
880  /* from page 143 of specctra spec:
881 
882  (connect
883  {(terminal <object_type> [<pin_reference> ])}
884  )
885  */
886 
887  T tok = NextTok();
888 
889  while( tok != T_RIGHT )
890  {
891  if( tok!=T_LEFT )
892  Expecting( T_LEFT );
893 
894  tok = NextTok();
895 
896  switch( tok )
897  {
898  case T_terminal:
899  // since we do not use the terminal information, simlpy toss it.
900  while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
901  ;
902  break;
903 
904  default:
905  Unexpected( CurText() );
906  }
907 
908  tok = NextTok();
909  }
910 }

Referenced by doWIRE().

◆ doCONTROL()

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

Definition at line 1189 of file specctra.cpp.

1190 {
1191  T tok;
1192 
1193  while( (tok = NextTok()) != T_RIGHT )
1194  {
1195  if( tok != T_LEFT )
1196  Expecting( T_LEFT );
1197 
1198  tok = NextTok();
1199  switch( tok )
1200  {
1201  case T_via_at_smd:
1202  tok = NextTok();
1203  if( tok!=T_on && tok!=T_off )
1204  Expecting( "on|off" );
1205  growth->via_at_smd = (tok==T_on);
1206  NeedRIGHT();
1207  break;
1208 
1209  case T_off_grid:
1210  case T_route_to_fanout_only:
1211  case T_force_to_terminal_point:
1212  case T_same_net_checking:
1213  case T_checking_trim_by_pin:
1214  case T_noise_calculation:
1215  case T_noise_accumulation:
1216  case T_include_pins_in_crosstalk:
1217  case T_bbv_ctr2ctr:
1218  case T_average_pair_length:
1219  case T_crosstalk_model:
1220  case T_roundoff_rotation:
1221  case T_microvia:
1222  case T_reroute_order_viols:
1223  TOKPROP* tokprop;
1224  tokprop = new TOKPROP( growth, tok );
1225  growth->Append( tokprop );
1226  doTOKPROP( tokprop );
1227  break;
1228 
1229  default:
1230  Unexpected( CurText() );
1231  }
1232  }
1233 }
void doTOKPROP(TOKPROP *growth)
Definition: specctra.cpp:1147

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 2674 of file specctra.cpp.

2675 {
2676  T tok;
2677 
2678  /* <fromto_descriptor >::=
2679  {(fromto
2680  [<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
2681  [<pin_reference> | <virtual_pin_descriptor> | <component_id >]
2682  [(type [fix | normal | soft])]
2683  [(net <net_id >)]
2684  [<rule_descriptor> ]
2685  [<circuit_descriptor> ]
2686  [{<layer_rule_descriptor> }]
2687  )}
2688  */
2689 
2690 
2691  // read the first two grammar items in as 2 single tokens, i.e. do not
2692  // split apart the <pin_reference>s into 3 separate tokens. Do this by
2693  // turning off the string delimiter in the lexer.
2694 
2695  char old = SetStringDelimiter( 0 );
2696 
2697  if( !IsSymbol(NextTok() ) )
2698  {
2699  SetStringDelimiter( old );
2700  Expecting( T_SYMBOL );
2701  }
2702  growth->fromText = CurText();
2703 
2704  if( !IsSymbol(NextTok() ) )
2705  {
2706  SetStringDelimiter( old );
2707  Expecting( T_SYMBOL );
2708  }
2709  growth->toText = CurText();
2710 
2711  SetStringDelimiter( old );
2712 
2713  while( (tok = NextTok()) != T_RIGHT )
2714  {
2715  if( tok != T_LEFT )
2716  Expecting( T_LEFT );
2717 
2718  tok = NextTok();
2719  switch( tok )
2720  {
2721  case T_type:
2722  tok = NextTok();
2723  if( tok!=T_fix && tok!=T_normal && tok!=T_soft )
2724  Expecting( "fix|normal|soft" );
2725  growth->fromto_type = tok;
2726  NeedRIGHT();
2727  break;
2728 
2729  case T_rule:
2730  if( growth->rules )
2731  Unexpected( tok );
2732  growth->rules = new RULE( growth, T_rule );
2733  doRULE( growth->rules );
2734  break;
2735 
2736  case T_layer_rule:
2737  LAYER_RULE* layer_rule;
2738  layer_rule = new LAYER_RULE( growth );
2739  growth->layer_rules.push_back( layer_rule );
2740  doLAYER_RULE( layer_rule );
2741  break;
2742 
2743  case T_net:
2744  if( growth->net_id.size() )
2745  Unexpected( tok );
2746  NeedSYMBOL();
2747  growth->net_id = CurText();
2748  NeedRIGHT();
2749  break;
2750 
2751  // circuit descriptor not supported at this time
2752 
2753  default:
2754  Unexpected( CurText() );
2755  }
2756  }
2757 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1715

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 1650 of file specctra.cpp.

1651 {
1652  T tok = NextTok();
1653 
1654  switch( tok )
1655  {
1656  case T_via:
1657  case T_wire:
1658  case T_via_keepout:
1659  case T_snap:
1660  case T_place:
1661  growth->grid_type = tok;
1662  if( NextTok() != T_NUMBER )
1663  Expecting( T_NUMBER );
1664  growth->dimension = strtod( CurText(), 0 );
1665  tok = NextTok();
1666  if( tok == T_LEFT )
1667  {
1668  while( (tok=NextTok()) != T_RIGHT )
1669  {
1670  if( tok==T_direction )
1671  {
1672  if( growth->grid_type == T_place )
1673  Unexpected( tok );
1674  tok = NextTok();
1675  if( tok!=T_x && tok!=T_y )
1676  Unexpected( CurText() );
1677  growth->direction = tok;
1678  if( NextTok() != T_RIGHT )
1679  Expecting(T_RIGHT);
1680  }
1681  else if( tok==T_offset )
1682  {
1683  if( growth->grid_type == T_place )
1684  Unexpected( tok );
1685 
1686  if( NextTok() != T_NUMBER )
1687  Expecting( T_NUMBER );
1688 
1689  growth->offset = strtod( CurText(), 0 );
1690 
1691  if( NextTok() != T_RIGHT )
1692  Expecting(T_RIGHT);
1693  }
1694  else if( tok==T_image_type )
1695  {
1696  if( growth->grid_type != T_place )
1697  Unexpected( tok );
1698  tok = NextTok();
1699  if( tok!=T_smd && tok!=T_pin )
1700  Unexpected( CurText() );
1701  growth->image_type = tok;
1702  if( NextTok() != T_RIGHT )
1703  Expecting(T_RIGHT);
1704  }
1705  }
1706  }
1707  break;
1708 
1709  default:
1710  Unexpected( tok );
1711  }
1712 }

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 3081 of file specctra.cpp.

3082 {
3083  T tok;
3084 
3085  /* <history_descriptor >::=
3086  (history [{<ancestor_file_descriptor> }] <self_descriptor> )
3087  */
3088 
3089  while( (tok = NextTok()) != T_RIGHT )
3090  {
3091  if( tok != T_LEFT )
3092  Expecting( T_LEFT );
3093 
3094  tok = NextTok();
3095  switch( tok )
3096  {
3097  case T_ancestor:
3098  ANCESTOR* ancestor;
3099  ancestor = new ANCESTOR( growth );
3100  growth->ancestors.push_back( ancestor );
3101  doANCESTOR( ancestor );
3102  break;
3103 
3104  case T_self:
3105  while( (tok = NextTok()) != T_RIGHT )
3106  {
3107  if( tok != T_LEFT )
3108  Expecting( T_LEFT );
3109 
3110  tok = NextTok();
3111  switch( tok )
3112  {
3113  case T_created_time:
3114  readTIME( &growth->time_stamp );
3115  NeedRIGHT();
3116  break;
3117 
3118  case T_comment:
3119  NeedSYMBOL();
3120  growth->comments.push_back( CurText() );
3121  NeedRIGHT();
3122  break;
3123 
3124  default:
3125  Unexpected( CurText() );
3126  }
3127  }
3128  break;
3129 
3130  default:
3131  Unexpected( CurText() );
3132  }
3133  }
3134 }
void doANCESTOR(ANCESTOR *growth)
Definition: specctra.cpp:3043
void readTIME(time_t *time_stamp)
Function readTIME reads a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : ...
Definition: specctra.cpp:177

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 2126 of file specctra.cpp.

2127 {
2128  T tok = NextTok();
2129 
2130  /* <image_descriptor >::=
2131  (image <image_id >
2132  [(side [front | back | both])]
2133  [<unit_descriptor> ]
2134  [<outline_descriptor> ]
2135  {(pin <padstack_id > [(rotate <rotation> )]
2136  [<reference_descriptor> | <pin_array_descriptor> ]
2137  [<user_property_descriptor> ])}
2138  [{<conductor_shape_descriptor> }]
2139  [{<conductor_via_descriptor> }]
2140  [<rule_descriptor> ]
2141  [<place_rule_descriptor> ]
2142  [{<keepout_descriptor> }]
2143  [<image_property_descriptor> ]
2144  )
2145  */
2146 
2147  if( !IsSymbol( tok ) && tok != T_NUMBER )
2148  Expecting( "image_id" );
2149 
2150  growth->image_id = CurText();
2151 
2152  while( (tok = NextTok()) != T_RIGHT )
2153  {
2154  if( tok != T_LEFT )
2155  Expecting( T_LEFT );
2156 
2157  tok = NextTok();
2158  switch( tok )
2159  {
2160  case T_unit:
2161  if( growth->unit )
2162  Unexpected( tok );
2163  growth->unit = new UNIT_RES( growth, tok );
2164  doUNIT( growth->unit );
2165  break;
2166 
2167  case T_side:
2168  tok = NextTok();
2169  if( tok!=T_front && tok!=T_back && tok!=T_both )
2170  Expecting( "front|back|both" );
2171  growth->side = tok;
2172  NeedRIGHT();
2173  break;
2174 
2175  case T_outline:
2176  SHAPE* outline;
2177  outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
2178  growth->Append( outline );
2179  doSHAPE( outline );
2180  break;
2181 
2182  case T_pin:
2183  PIN* pin;
2184  pin = new PIN( growth );
2185  growth->pins.push_back( pin );
2186  doPIN( pin );
2187  break;
2188 
2189  case T_rule:
2190  if( growth->rules )
2191  Unexpected( tok );
2192  growth->rules = new RULE( growth, tok );
2193  doRULE( growth->rules );
2194  break;
2195 
2196  case T_place_rule:
2197  if( growth->place_rules )
2198  Unexpected( tok );
2199  growth->place_rules = new RULE( growth, tok );
2200  doRULE( growth->place_rules );
2201  break;
2202 
2203  case T_keepout:
2204  case T_place_keepout:
2205  case T_via_keepout:
2206  case T_wire_keepout:
2207  case T_bend_keepout:
2208  case T_elongate_keepout:
2209  KEEPOUT* keepout;
2210  keepout = new KEEPOUT( growth, tok );
2211  growth->keepouts.push_back( keepout );
2212  doKEEPOUT( keepout );
2213  break;
2214 
2215  default:
2216  Unexpected( CurText() );
2217  }
2218  }
2219 }
void doKEEPOUT(KEEPOUT *growth)
Definition: specctra.cpp:787
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
An abstract shape on 2D plane.
Definition: shape.h:116
void doPIN(PIN *growth)
Definition: specctra.cpp:2222
void doSHAPE(SHAPE *growth)
Definition: specctra.cpp:2040
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

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 787 of file specctra.cpp.

788 {
789  T tok = NextTok();
790 
791  if( IsSymbol(tok) )
792  {
793  growth->name = CurText();
794  tok = NextTok();
795  }
796 
797  if( tok!=T_LEFT )
798  Expecting( T_LEFT );
799 
800  while( tok != T_RIGHT )
801  {
802  if( tok!=T_LEFT )
803  Expecting( T_LEFT );
804 
805  tok = NextTok();
806  switch( tok )
807  {
808  case T_sequence_number:
809  if( NextTok() != T_NUMBER )
810  Expecting( T_NUMBER );
811  growth->sequence_number = atoi( CurText() );
812  NeedRIGHT();
813  break;
814 
815  case T_rule:
816  if( growth->rules )
817  Unexpected( tok );
818  growth->rules = new RULE( growth, T_rule );
819  doRULE( growth->rules );
820  break;
821 
822  case T_place_rule:
823  if( growth->place_rules )
824  Unexpected( tok );
825  growth->place_rules = new RULE( growth, T_place_rule );
826  doRULE( growth->place_rules );
827  break;
828 
829  case T_rect:
830  if( growth->shape )
831  Unexpected( tok );
832  growth->shape = new RECTANGLE( growth );
833  doRECTANGLE( (RECTANGLE*) growth->shape );
834  break;
835 
836  case T_circle:
837  if( growth->shape )
838  Unexpected( tok );
839  growth->shape = new CIRCLE( growth );
840  doCIRCLE( (CIRCLE*) growth->shape );
841  break;
842 
843  case T_polyline_path:
844  tok = T_path;
846 
847  case T_path:
848  case T_polygon:
849  if( growth->shape )
850  Unexpected( tok );
851  growth->shape = new PATH( growth, tok );
852  doPATH( (PATH*) growth->shape );
853  break;
854 
855  case T_qarc:
856  if( growth->shape )
857  Unexpected( tok );
858  growth->shape = new QARC( growth );
859  doQARC( (QARC*) growth->shape );
860  break;
861 
862  case T_window:
863  WINDOW* window;
864  window = new WINDOW( growth );
865  growth->windows.push_back( window );
866  doWINDOW( window );
867  break;
868 
869  default:
870  Unexpected( CurText() );
871  }
872 
873  tok = NextTok();
874  }
875 }
#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:913
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
Class Circle Represents basic circle geometry with utility geometry functions.
Definition: circle.h:33
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1087
void doQARC(QARC *growth)
Definition: specctra.cpp:1115

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 1259 of file specctra.cpp.

1260 {
1261  T tok = NextTok();
1262 
1263  if( !IsSymbol(tok) )
1264  Expecting(T_SYMBOL);
1265 
1266  growth->name = CurText();
1267 
1268  while( (tok = NextTok()) != T_RIGHT )
1269  {
1270  if( tok != T_LEFT )
1271  Expecting( T_LEFT );
1272 
1273  tok = NextTok();
1274  switch( tok )
1275  {
1276  case T_type:
1277  tok = NextTok();
1278  if( tok!=T_signal && tok!=T_power && tok!=T_mixed && tok!=T_jumper )
1279  Expecting( "signal|power|mixed|jumper" );
1280  growth->layer_type = tok;
1281  if( NextTok()!=T_RIGHT )
1282  Expecting(T_RIGHT);
1283  break;
1284 
1285  case T_rule:
1286  growth->rules = new RULE( growth, T_rule );
1287  doRULE( growth->rules );
1288  break;
1289 
1290  case T_property:
1291  doPROPERTIES( &growth->properties );
1292  break;
1293 
1294  case T_direction:
1295  tok = NextTok();
1296  switch( tok )
1297  {
1298  case T_horizontal:
1299  case T_vertical:
1300  case T_orthogonal:
1301  case T_positive_diagonal:
1302  case T_negative_diagonal:
1303  case T_diagonal:
1304  case T_off:
1305  growth->direction = tok;
1306  break;
1307  default:
1308  // the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
1309  if( !strcmp( "hori", CurText() ) )
1310  {
1311  growth->direction = T_horizontal;
1312  break;
1313  }
1314  else if( !strcmp( "vert", CurText() ) )
1315  {
1316  growth->direction = T_vertical;
1317  break;
1318  }
1319  Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|diagonal|off" );
1320  }
1321  if( NextTok()!=T_RIGHT )
1322  Expecting(T_RIGHT);
1323  break;
1324 
1325  case T_cost:
1326  tok = NextTok();
1327  switch( tok )
1328  {
1329  case T_forbidden:
1330  case T_high:
1331  case T_medium:
1332  case T_low:
1333  case T_free:
1334  growth->cost = tok;
1335  break;
1336  case T_NUMBER:
1337  // store as negative so we can differentiate between
1338  // T (positive) and T_NUMBER (negative)
1339  growth->cost = -atoi( CurText() );
1340  break;
1341  default:
1342  Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
1343  }
1344  tok = NextTok();
1345  if( tok == T_LEFT )
1346  {
1347  if( NextTok() != T_type )
1348  Unexpected( CurText() );
1349 
1350  tok = NextTok();
1351  if( tok!=T_length && tok!=T_way )
1352  Expecting( "length|way" );
1353 
1354  growth->cost_type = tok;
1355  if( NextTok()!=T_RIGHT )
1356  Expecting(T_RIGHT);
1357 
1358  tok = NextTok();
1359  }
1360  if( tok!=T_RIGHT )
1361  Expecting(T_RIGHT);
1362  break;
1363 
1364  case T_use_net:
1365  while( (tok = NextTok()) != T_RIGHT )
1366  {
1367  if( !IsSymbol(tok) )
1368  Expecting( T_SYMBOL );
1369 
1370  growth->use_net.push_back( CurText() );
1371  }
1372  break;
1373 
1374  default:
1375  Unexpected( CurText() );
1376  }
1377  }
1378 }
void doPROPERTIES(PROPERTIES *growth)
Definition: specctra.cpp:1236
void doRULE(RULE *growth)
Definition: specctra.cpp:1381

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 590 of file specctra.cpp.

592 {
593  T tok;
594 
595  while( (tok = NextTok()) != T_RIGHT )
596  {
597  if( tok != T_LEFT )
598  Expecting( T_LEFT );
599 
600  if( NextTok() != T_layer_pair )
601  Expecting( T_layer_pair );
602 
603  SPECCTRA_LAYER_PAIR* layer_pair = new SPECCTRA_LAYER_PAIR( growth );
604  growth->layer_pairs.push_back( layer_pair );
605  doSPECCTRA_LAYER_PAIR( layer_pair );
606  }
607 }
void doSPECCTRA_LAYER_PAIR(SPECCTRA_LAYER_PAIR *growth)
Definition: specctra.cpp:574

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 1715 of file specctra.cpp.

1716 {
1717  T tok;
1718 
1719  NeedSYMBOL();
1720 
1721  do
1722  {
1723  growth->layer_ids.push_back( CurText() );
1724 
1725  } while( IsSymbol(tok = NextTok()) );
1726 
1727  if( tok != T_LEFT )
1728  Expecting( T_LEFT );
1729 
1730  if( NextTok() != T_rule )
1731  Expecting( T_rule );
1732 
1733  growth->rule = new RULE( growth, T_rule );
1734  doRULE( growth->rule );
1735 
1736  NeedRIGHT();
1737 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1381

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 2269 of file specctra.cpp.

2270 {
2271  T tok;
2272 
2273  /* <library_descriptor >::=
2274  (library
2275  [<unit_descriptor> ]
2276  {<image_descriptor> }
2277  [{<jumper_descriptor> }]
2278  {<padstack_descriptor> }
2279  {<via_array_template_descriptor> }
2280  [<directory_descriptor> ]
2281  [<extra_image_directory_descriptor> ]
2282  [{<family_family_descriptor> }]
2283  [{<image_image_descriptor> }]
2284  )
2285  */
2286 
2287  while( (tok = NextTok()) != T_RIGHT )
2288  {
2289  if( tok != T_LEFT )
2290  Expecting( T_LEFT );
2291 
2292  tok = NextTok();
2293  switch( tok )
2294  {
2295  case T_unit:
2296  if( growth->unit )
2297  Unexpected( tok );
2298  growth->unit = new UNIT_RES( growth, tok );
2299  doUNIT( growth->unit );
2300  break;
2301 
2302  case T_padstack:
2303  PADSTACK* padstack;
2304  padstack = new PADSTACK();
2305  growth->AddPadstack( padstack );
2306  doPADSTACK( padstack );
2307  break;
2308 
2309  case T_image:
2310  IMAGE* image;
2311  image = new IMAGE( growth );
2312  growth->images.push_back( image );
2313  doIMAGE( image );
2314  break;
2315 
2316  default:
2317  Unexpected( CurText() );
2318  }
2319  }
2320 }
void doIMAGE(IMAGE *growth)
Definition: specctra.cpp:2126
void doPADSTACK(PADSTACK *growth)
Definition: specctra.cpp:1940
Manage an 8-bit channel image.
Definition: image.h:89
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

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 2323 of file specctra.cpp.

2324 {
2325  T tok = NextTok();
2326  PIN_REFS* pin_refs;
2327 
2328  /* <net_descriptor >::=
2329  (net <net_id >
2330  [(unassigned)]
2331  [(net_number <integer >)]
2332  [(pins {<pin_reference> }) | (order {<pin_reference> })]
2333  [<component_order_descriptor> ]
2334  [(type [fix | normal])]
2335  [<user_property_descriptor> ]
2336  [<circuit_descriptor> ]
2337  [<rule_descriptor> ]
2338  [{<layer_rule_descriptor> }]
2339  [<fromto_descriptor> ]
2340  [(expose {<pin_reference> })]
2341  [(noexpose {<pin_reference> })]
2342  [(source {<pin_reference> })]
2343  [(load {<pin_reference> })]
2344  [(terminator {<pin_reference> })]
2345  [(supply [power | ground])]
2346  )
2347  */
2348 
2349  if( !IsSymbol( tok ) )
2350  Expecting( "net_id" );
2351 
2352  growth->net_id = CurText();
2353 
2354  while( (tok = NextTok()) != T_RIGHT )
2355  {
2356  if( tok != T_LEFT )
2357  Expecting( T_LEFT );
2358 
2359  tok = NextTok();
2360  switch( tok )
2361  {
2362  case T_unassigned:
2363  growth->unassigned = true;
2364  NeedRIGHT();
2365  break;
2366 
2367  case T_net_number:
2368  if( NextTok() != T_NUMBER )
2369  Expecting( T_NUMBER );
2370  growth->net_number = atoi( CurText() );
2371  NeedRIGHT();
2372  break;
2373 
2374  case T_pins:
2375  case T_order:
2376  growth->pins_type = tok;
2377  pin_refs = &growth->pins;
2378  goto L_pins;
2379 
2380  case T_expose:
2381  pin_refs = &growth->expose;
2382  goto L_pins;
2383 
2384  case T_noexpose:
2385  pin_refs = &growth->noexpose;
2386  goto L_pins;
2387 
2388  case T_source:
2389  pin_refs = &growth->source;
2390  goto L_pins;
2391 
2392  case T_load:
2393  pin_refs = &growth->load;
2394  goto L_pins;
2395 
2396  case T_terminator:
2397  pin_refs = &growth->terminator;
2398  //goto L_pins;
2399 
2400 L_pins:
2401  {
2402  PIN_REF empty( growth );
2403  while( (tok = NextTok()) != T_RIGHT )
2404  {
2405  // copy the empty one, then fill its copy later thru pin_ref.
2406  pin_refs->push_back( empty );
2407 
2408  PIN_REF* pin_ref = &pin_refs->back();
2409 
2410  readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
2411  }
2412  }
2413  break;
2414 
2415  case T_comp_order:
2416  if( growth->comp_order )
2417  Unexpected( tok );
2418  growth->comp_order = new COMP_ORDER( growth );
2419  doCOMP_ORDER( growth->comp_order );
2420  break;
2421 
2422  case T_type:
2423  tok = NextTok();
2424  if( tok!=T_fix && tok!=T_normal )
2425  Expecting( "fix|normal" );
2426  growth->type = tok;
2427  NeedRIGHT();
2428  break;
2429 
2430 /* @todo
2431  case T_circuit:
2432  break;
2433 */
2434 
2435  case T_rule:
2436  if( growth->rules )
2437  Unexpected( tok );
2438  growth->rules = new RULE( growth, T_rule );
2439  doRULE( growth->rules );
2440  break;
2441 
2442  case T_layer_rule:
2443  LAYER_RULE* layer_rule;
2444  layer_rule = new LAYER_RULE( growth );
2445  growth->layer_rules.push_back( layer_rule );
2446  doLAYER_RULE( layer_rule );
2447  break;
2448 
2449  case T_fromto:
2450  FROMTO* fromto;
2451  fromto = new FROMTO( growth );
2452  growth->fromtos.push_back( fromto );
2453  doFROMTO( fromto );
2454  break;
2455 
2456  default:
2457  Unexpected( CurText() );
2458  }
2459  }
2460 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doCOMP_ORDER(COMP_ORDER *growth)
Definition: specctra.cpp:2656
std::vector< PIN_REF > PIN_REFS
Definition: specctra.h:2480
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Function readCOMPnPIN reads a <pin_reference> and splits it into the two parts which are on either si...
Definition: specctra.cpp:134
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1715
static bool empty(const wxTextEntryBase *aCtrl)
void doFROMTO(FROMTO *growth)
Definition: specctra.cpp:2674

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 3338 of file specctra.cpp.

3339 {
3340  T tok;
3341 
3342  /* <net_out_descriptor >::=
3343  (net <net_id >
3344  [(net_number <integer >)]
3345  [<rule_descriptor> ]
3346  {[<wire_shape_descriptor> | <wire_guide_descriptor> |
3347  <wire_via_descriptor> | <bond_shape_descriptor> ]}
3348  {[<supply_pin_descriptor> ]}
3349  )
3350  */
3351 
3352  NeedSYMBOLorNUMBER();
3353  growth->net_id = CurText();
3354 
3355  while( (tok = NextTok()) != T_RIGHT )
3356  {
3357  if( tok != T_LEFT )
3358  Expecting( T_LEFT );
3359 
3360  tok = NextTok();
3361  switch( tok )
3362  {
3363  case T_net_number:
3364  tok = NextTok();
3365  if( tok!= T_NUMBER )
3366  Expecting( T_NUMBER );
3367  growth->net_number = atoi( CurText() );
3368  NeedRIGHT();
3369  break;
3370 
3371  case T_rule:
3372  if( growth->rules )
3373  Unexpected( tok );
3374  growth->rules = new RULE( growth, tok );
3375  doRULE( growth->rules );
3376  break;
3377 
3378  case T_wire:
3379  WIRE* wire;
3380  wire = new WIRE( growth );
3381  growth->wires.push_back( wire );
3382  doWIRE( wire );
3383  break;
3384 
3385  case T_via:
3386  WIRE_VIA* wire_via;
3387  wire_via = new WIRE_VIA( growth );
3388  growth->wire_vias.push_back( wire_via );
3389  doWIRE_VIA( wire_via );
3390  break;
3391 
3392  case T_supply_pin:
3393  SUPPLY_PIN* supply_pin;
3394  supply_pin = new SUPPLY_PIN( growth );
3395  growth->supply_pins.push_back( supply_pin );
3396  doSUPPLY_PIN( supply_pin );
3397  break;
3398 
3399  default:
3400  Unexpected( CurText() );
3401  }
3402  }
3403 }
void doWIRE(WIRE *growth)
Definition: specctra.cpp:2760
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doSUPPLY_PIN(SUPPLY_PIN *growth)
Definition: specctra.cpp:3406
void doWIRE_VIA(WIRE_VIA *growth)
Definition: specctra.cpp:2883

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 2611 of file specctra.cpp.

2612 {
2613  T tok;
2614 
2615  /* <network_descriptor >::=
2616  (network
2617  {<net_descriptor>}
2618  [{<class_descriptor> }]
2619  [{<class_class_descriptor> }]
2620  [{<group_descriptor> }]
2621  [{<group_set_descriptor> }]
2622  [{<pair_descriptor> }]
2623  [{<bundle_descriptor> }]
2624  )
2625  */
2626 
2627  while( (tok = NextTok()) != T_RIGHT )
2628  {
2629  if( tok != T_LEFT )
2630  Expecting( T_LEFT );
2631 
2632  tok = NextTok();
2633  switch( tok )
2634  {
2635  case T_net:
2636  NET* net;
2637  net = new NET( growth );
2638  growth->nets.push_back( net );
2639  doNET( net );
2640  break;
2641 
2642  case T_class:
2643  CLASS* myclass;
2644  myclass = new CLASS( growth );
2645  growth->classes.push_back( myclass );
2646  doCLASS( myclass );
2647  break;
2648 
2649  default:
2650  Unexpected( CurText() );
2651  }
2652  }
2653 }
void doNET(NET *growth)
Definition: specctra.cpp:2323
void doCLASS(CLASS *growth)
Definition: specctra.cpp:2501
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 1940 of file specctra.cpp.

1941 {
1942  T tok = NextTok();
1943 
1944  /* (padstack <padstack_id >
1945  [<unit_descriptor> ]
1946  {(shape <shape_descriptor>
1947  [<reduced_shape_descriptor> ]
1948  [(connect [on | off])]
1949  [{<window_descriptor> }]
1950  )}
1951  [<attach_descriptor> ]
1952  [{<pad_via_site_descriptor> }]
1953  [(rotate [on | off])]
1954  [(absolute [on | off])]
1955  [(rule <clearance_descriptor> )])
1956  */
1957 
1958  // padstack_id may be a number
1959  if( !IsSymbol( tok ) && tok!=T_NUMBER )
1960  Expecting( "padstack_id" );
1961 
1962  growth->padstack_id = CurText();
1963 
1964  while( (tok = NextTok()) != T_RIGHT )
1965  {
1966  if( tok != T_LEFT )
1967  Expecting( T_LEFT );
1968 
1969  tok = NextTok();
1970  switch( tok )
1971  {
1972  case T_unit:
1973  if( growth->unit )
1974  Unexpected( tok );
1975  growth->unit = new UNIT_RES( growth, tok );
1976  doUNIT( growth->unit );
1977  break;
1978 
1979  case T_rotate:
1980  tok = NextTok();
1981  if( tok!=T_on && tok!=T_off )
1982  Expecting( "on|off" );
1983  growth->rotate = tok;
1984  NeedRIGHT();
1985  break;
1986 
1987  case T_absolute:
1988  tok = NextTok();
1989  if( tok!=T_on && tok!=T_off )
1990  Expecting( "on|off" );
1991  growth->absolute = tok;
1992  NeedRIGHT();
1993  break;
1994 
1995  case T_shape:
1996  SHAPE* shape;
1997  shape = new SHAPE( growth );
1998  growth->Append( shape );
1999  doSHAPE( shape );
2000  break;
2001 
2002  case T_attach:
2003  tok = NextTok();
2004  if( tok!=T_off && tok!=T_on )
2005  Expecting( "off|on" );
2006  growth->attach = tok;
2007  tok = NextTok();
2008  if( tok == T_LEFT )
2009  {
2010  if( NextTok() != T_use_via )
2011  Expecting( T_use_via );
2012 
2013  NeedSYMBOL();
2014  growth->via_id = CurText();
2015 
2016  NeedRIGHT();
2017  NeedRIGHT();
2018  }
2019  break;
2020 
2021  /*
2022  case T_via_site: not supported
2023  break;
2024  */
2025 
2026  case T_rule:
2027  if( growth->rules )
2028  Unexpected( tok );
2029  growth->rules = new RULE( growth, T_rule );
2030  doRULE( growth->rules );
2031  break;
2032 
2033  default:
2034  Unexpected( CurText() );
2035  }
2036  }
2037 }
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
An abstract shape on 2D plane.
Definition: shape.h:116
void doSHAPE(SHAPE *growth)
Definition: specctra.cpp:2040
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

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 387 of file specctra.cpp.

388 {
389  T tok;
390  std::string const1;
391  std::string const2;
392 
393  /* <parser_descriptor >::=
394  (parser
395  [(string_quote <quote_char >)]
396  (space_in_quoted_tokens [on | off])
397  [(host_cad <id >)]
398  [(host_version <id >)]
399  [{(constant <id > <id >)}]
400  [(write_resolution] {<character> <positive_integer >})]
401  [(routes_include {[testpoint | guides |
402  image_conductor]})]
403  [(wires_include testpoint)]
404  [(case_sensitive [on | off])]
405  [(via_rotate_first [on | off])]
406  )
407  */
408 
409  while( (tok = NextTok()) != T_RIGHT )
410  {
411  if( tok != T_LEFT )
412  Expecting( T_LEFT );
413 
414  tok = NextTok();
415  switch( tok )
416  {
417  case T_STRING_QUOTE:
418  tok = NextTok();
419  if( tok != T_QUOTE_DEF )
420  Expecting( T_QUOTE_DEF );
421  SetStringDelimiter( (unsigned char) *CurText() );
422  growth->string_quote = *CurText();
423  m_quote_char = CurText();
424  NeedRIGHT();
425  break;
426 
427  case T_space_in_quoted_tokens:
428  tok = NextTok();
429  if( tok!=T_on && tok!=T_off )
430  Expecting( "on|off" );
431  SetSpaceInQuotedTokens( tok==T_on );
432  growth->space_in_quoted_tokens = (tok==T_on);
433  NeedRIGHT();
434  break;
435 
436  case T_host_cad:
437  NeedSYMBOL();
438  growth->host_cad = CurText();
439  NeedRIGHT();
440  break;
441 
442  case T_host_version:
443  NeedSYMBOLorNUMBER();
444  growth->host_version = CurText();
445  NeedRIGHT();
446  break;
447 
448  case T_constant:
449  NeedSYMBOLorNUMBER();
450  const1 = CurText();
451  NeedSYMBOLorNUMBER();
452  const2 = CurText();
453  NeedRIGHT();
454  growth->constants.push_back( const1 );
455  growth->constants.push_back( const2 );
456  break;
457 
458  case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
459  while( (tok = NextTok()) != T_RIGHT )
460  {
461  if( tok!=T_SYMBOL )
462  Expecting( T_SYMBOL );
463  tok = NextTok();
464  if( tok!=T_NUMBER )
465  Expecting( T_NUMBER );
466  // @todo
467  }
468  break;
469 
470  case T_routes_include: // [(routes_include {[testpoint | guides | image_conductor]})]
471  while( (tok = NextTok()) != T_RIGHT )
472  {
473  switch( tok )
474  {
475  case T_testpoint:
476  growth->routes_include_testpoint = true;
477  break;
478  case T_guide:
479  growth->routes_include_guides = true;
480  break;
481  case T_image_conductor:
482  growth->routes_include_image_conductor = true;
483  break;
484  default:
485  Expecting( "testpoint|guides|image_conductor" );
486  }
487  }
488  break;
489 
490  case T_wires_include: // [(wires_include testpoint)]
491  tok = NextTok();
492  if( tok != T_testpoint )
493  Expecting( T_testpoint );
494  growth->routes_include_testpoint = true;
495  NeedRIGHT();
496  break;
497 
498  case T_case_sensitive:
499  tok = NextTok();
500  if( tok!=T_on && tok!=T_off )
501  Expecting( "on|off" );
502  growth->case_sensitive = (tok==T_on);
503  NeedRIGHT();
504  break;
505 
506  case T_via_rotate_first: // [(via_rotate_first [on | off])]
507  tok = NextTok();
508  if( tok!=T_on && tok!=T_off )
509  Expecting( "on|off" );
510  growth->via_rotate_first = (tok==T_on);
511  NeedRIGHT();
512  break;
513 
514  case T_generated_by_freeroute:
515  growth->generated_by_freeroute = true;
516  NeedRIGHT();
517  break;
518 
519  default:
520  Unexpected( CurText() );
521  }
522  }
523 }
std::string m_quote_char
Definition: specctra.h:3640

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 1014 of file specctra.cpp.

1015 {
1016  T tok = NextTok();
1017 
1018  if( !IsSymbol( tok ) && tok != T_NUMBER ) // a layer name can be like a number like +12
1019  Expecting( "layer_id" );
1020 
1021  growth->layer_id = CurText();
1022 
1023  if( NextTok() != T_NUMBER )
1024  Expecting( "aperture_width" );
1025 
1026  growth->aperture_width = strtod( CurText(), NULL );
1027 
1028  POINT ptTemp;
1029 
1030  tok = NextTok();
1031 
1032  do
1033  {
1034  if( tok != T_NUMBER )
1035  Expecting( T_NUMBER );
1036  ptTemp.x = strtod( CurText(), NULL );
1037 
1038  if( NextTok() != T_NUMBER )
1039  Expecting( T_NUMBER );
1040  ptTemp.y = strtod( CurText(), NULL );
1041 
1042  growth->points.push_back( ptTemp );
1043 
1044  } while( (tok = NextTok())!=T_RIGHT && tok!=T_LEFT );
1045 
1046  if( tok == T_LEFT )
1047  {
1048  if( NextTok() != T_aperture_type )
1049  Expecting( T_aperture_type );
1050 
1051  tok = NextTok();
1052  if( tok!=T_round && tok!=T_square )
1053  Expecting( "round|square" );
1054 
1055  growth->aperture_type = tok;
1056 
1057  NeedRIGHT();
1058  }
1059 }
#define NULL

References DSN::PATH::aperture_type, DSN::PATH::aperture_width, DSN::PATH::layer_id, NULL, 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 282 of file specctra.cpp.

283 {
284  T tok;
285 
286  /* <design_descriptor >::=
287  (pcb <pcb_id >
288  [<parser_descriptor> ]
289  [<capacitance_resolution_descriptor> ]
290  [<conductance_resolution_descriptor> ]
291  [<current_resolution_descriptor> ]
292  [<inductance_resolution_descriptor> ]
293  [<resistance_resolution_descriptor> ]
294  [<resolution_descriptor> ]
295  [<time_resolution_descriptor> ]
296  [<voltage_resolution_descriptor> ]
297  [<unit_descriptor> ]
298  [<structure_descriptor> | <file_descriptor> ]
299  [<placement_descriptor> | <file_descriptor> ]
300  [<library_descriptor> | <file_descriptor> ]
301  [<floor_plan_descriptor> | <file_descriptor> ]
302  [<part_library_descriptor> | <file_descriptor> ]
303  [<network_descriptor> | <file_descriptor> ]
304  [<wiring_descriptor> ]
305  [<color_descriptor> ]
306  )
307  */
308 
309  NeedSYMBOL();
310  growth->pcbname = CurText();
311 
312  while( (tok = NextTok()) != T_RIGHT )
313  {
314  if( tok != T_LEFT )
315  Expecting( T_LEFT );
316 
317  tok = NextTok();
318  switch( tok )
319  {
320  case T_parser:
321  if( growth->parser )
322  Unexpected( tok );
323  growth->parser = new PARSER( growth );
324  doPARSER( growth->parser );
325  break;
326 
327  case T_unit:
328  if( growth->unit )
329  Unexpected( tok );
330  growth->unit = new UNIT_RES( growth, tok );
331  doUNIT( growth->unit );
332  break;
333 
334  case T_resolution:
335  if( growth->resolution )
336  Unexpected( tok );
337  growth->resolution = new UNIT_RES( growth, tok );
338  doRESOLUTION( growth->resolution );
339  break;
340 
341  case T_structure:
342  if( growth->structure )
343  Unexpected( tok );
344  growth->structure = new STRUCTURE( growth );
345  doSTRUCTURE( growth->structure );
346  break;
347 
348  case T_placement:
349  if( growth->placement )
350  Unexpected( tok );
351  growth->placement = new PLACEMENT( growth );
352  doPLACEMENT( growth->placement );
353  break;
354 
355  case T_library:
356  if( growth->library )
357  Unexpected( tok );
358  growth->library = new LIBRARY( growth );
359  doLIBRARY( growth->library );
360  break;
361 
362  case T_network:
363  if( growth->network )
364  Unexpected( tok );
365  growth->network = new NETWORK( growth );
366  doNETWORK( growth->network );
367  break;
368 
369  case T_wiring:
370  if( growth->wiring )
371  Unexpected( tok );
372  growth->wiring = new WIRING( growth );
373  doWIRING( growth->wiring );
374  break;
375 
376  default:
377  Unexpected( CurText() );
378  }
379  }
380 
381  tok = NextTok();
382  if( tok != T_EOF )
383  Expecting( T_EOF );
384 }
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:526
void doWIRING(WIRING *growth)
Definition: specctra.cpp:2987
void doLIBRARY(LIBRARY *growth)
Definition: specctra.cpp:2269
void doSTRUCTURE(STRUCTURE *growth)
Definition: specctra.cpp:610
void doPLACEMENT(PLACEMENT *growth)
Definition: specctra.cpp:1885
void doNETWORK(NETWORK *growth)
Definition: specctra.cpp:2611
void doPARSER(PARSER *growth)
Definition: specctra.cpp:387
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

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 2222 of file specctra.cpp.

2223 {
2224  T tok = NextTok();
2225 
2226  /* (pin <padstack_id > [(rotate <rotation> )]
2227  [<reference_descriptor> | <pin_array_descriptor> ]
2228  [<user_property_descriptor> ])
2229  */
2230 
2231  // a padstack_id may be a number
2232  if( !IsSymbol( tok ) && tok!=T_NUMBER )
2233  Expecting( "padstack_id" );
2234 
2235  growth->padstack_id = CurText();
2236 
2237  while( (tok = NextTok()) != T_RIGHT )
2238  {
2239  if( tok == T_LEFT )
2240  {
2241  tok = NextTok();
2242  if( tok != T_rotate )
2243  Expecting( T_rotate );
2244 
2245  if( NextTok() != T_NUMBER )
2246  Expecting( T_NUMBER );
2247  growth->SetRotation( strtod( CurText(), 0 ) );
2248  NeedRIGHT();
2249  }
2250  else
2251  {
2252  if( !IsSymbol(tok) && tok!=T_NUMBER )
2253  Expecting( "pin_id" );
2254 
2255  growth->pin_id = CurText();
2256 
2257  if( NextTok() != T_NUMBER )
2258  Expecting( T_NUMBER );
2259  growth->vertex.x = strtod( CurText(), 0 );
2260 
2261  if( NextTok() != T_NUMBER )
2262  Expecting( T_NUMBER );
2263  growth->vertex.y = strtod( CurText(), 0 );
2264  }
2265  }
2266 }

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 1740 of file specctra.cpp.

1741 {
1742  T tok = NextTok();
1743 
1744  if( !IsSymbol( tok ) )
1745  Expecting( "component_id" );
1746 
1747  growth->component_id = CurText();
1748 
1749  tok = NextTok();
1750  if( tok == T_NUMBER )
1751  {
1752  POINT point;
1753 
1754  point.x = strtod( CurText(), 0 );
1755 
1756  if( NextTok() != T_NUMBER )
1757  Expecting( T_NUMBER );
1758  point.y = strtod( CurText(), 0 );
1759 
1760  growth->SetVertex( point );
1761 
1762  tok = NextTok();
1763  if( tok!=T_front && tok!=T_back )
1764  Expecting( "front|back" );
1765  growth->side = tok;
1766 
1767  if( NextTok() != T_NUMBER )
1768  Expecting( "rotation" );
1769  growth->SetRotation( strtod( CurText(), 0) );
1770  }
1771 
1772  while( (tok = NextTok()) != T_RIGHT )
1773  {
1774  if( tok != T_LEFT )
1775  Expecting( T_LEFT );
1776 
1777  tok = NextTok();
1778  switch( tok )
1779  {
1780  case T_mirror:
1781  tok = NextTok();
1782  if( tok==T_x || tok==T_y || tok==T_xy || tok==T_off )
1783  growth->mirror = tok;
1784  else
1785  Expecting("x|y|xy|off");
1786  break;
1787 
1788  case T_status:
1789  tok = NextTok();
1790  if( tok==T_added || tok==T_deleted || tok==T_substituted )
1791  growth->status = tok;
1792  else
1793  Expecting("added|deleted|substituted");
1794  break;
1795 
1796  case T_logical_part:
1797  if( growth->logical_part.size() )
1798  Unexpected( tok );
1799  tok = NextTok();
1800  if( !IsSymbol( tok ) )
1801  Expecting( "logical_part_id");
1802  growth->logical_part = CurText();
1803  break;
1804 
1805  case T_place_rule:
1806  if( growth->place_rules )
1807  Unexpected( tok );
1808  growth->place_rules = new RULE( growth, T_place_rule );
1809  doRULE( growth->place_rules );
1810  break;
1811 
1812  case T_property:
1813  if( growth->properties.size() )
1814  Unexpected( tok );
1815  doPROPERTIES( &growth->properties );
1816  break;
1817 
1818  case T_lock_type:
1819  tok = NextTok();
1820  if( tok==T_position || tok==T_gate || tok==T_subgate || tok==T_pin )
1821  growth->lock_type = tok;
1822  else
1823  Expecting("position|gate|subgate|pin");
1824  break;
1825 
1826  case T_rule:
1827  if( growth->rules || growth->region )
1828  Unexpected( tok );
1829  growth->rules = new RULE( growth, T_rule );
1830  doRULE( growth->rules );
1831  break;
1832 
1833  case T_region:
1834  if( growth->rules || growth->region )
1835  Unexpected( tok );
1836  growth->region = new REGION( growth );
1837  doREGION( growth->region );
1838  break;
1839 
1840  case T_pn:
1841  if( growth->part_number.size() )
1842  Unexpected( tok );
1843  NeedSYMBOLorNUMBER();
1844  growth->part_number = CurText();
1845  NeedRIGHT();
1846  break;
1847 
1848  default:
1849  Unexpected( tok );
1850  }
1851  }
1852 }
void doPROPERTIES(PROPERTIES *growth)
Definition: specctra.cpp:1236
void doREGION(REGION *growth)
Definition: specctra.cpp:1513
void doRULE(RULE *growth)
Definition: specctra.cpp:1381

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 1885 of file specctra.cpp.

1886 {
1887  T tok;
1888 
1889  while( (tok = NextTok()) != T_RIGHT )
1890  {
1891  if( tok == T_EOF )
1892  Unexpected( T_EOF );
1893 
1894  if( tok != T_LEFT )
1895  Expecting( T_LEFT );
1896 
1897  tok = NextTok();
1898 
1899  switch( tok )
1900  {
1901  case T_unit:
1902  case T_resolution:
1903  growth->unit = new UNIT_RES( growth, tok );
1904  if( tok==T_resolution )
1905  doRESOLUTION( growth->unit );
1906  else
1907  doUNIT( growth->unit );
1908  break;
1909 
1910  case T_place_control:
1911  NeedRIGHT();
1912  tok = NextTok();
1913  if( tok != T_flip_style )
1914  Expecting( T_flip_style );
1915 
1916  tok = NextTok();
1917  if( tok==T_mirror_first || tok==T_rotate_first )
1918  growth->flip_style = tok;
1919  else
1920  Expecting( "mirror_first|rotate_first" );
1921 
1922  NeedRIGHT();
1923  NeedRIGHT();
1924  break;
1925 
1926  case T_component:
1927  COMPONENT* component;
1928  component = new COMPONENT( growth );
1929  growth->components.push_back( component );
1930  doCOMPONENT( component );
1931  break;
1932 
1933  default:
1934  Unexpected( tok );
1935  }
1936  }
1937 }
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:526
void doCOMPONENT(COMPONENT *growth)
Definition: specctra.cpp:1855
Store all of the related footprint information found in a netlist.
Definition: pcb_netlist.h:83
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

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 1236 of file specctra.cpp.

1237 {
1238  T tok;
1239  PROPERTY property; // construct it once here, append multiple times.
1240 
1241  while( (tok = NextTok()) != T_RIGHT )
1242  {
1243  if( tok != T_LEFT )
1244  Expecting( T_LEFT );
1245 
1246  NeedSYMBOLorNUMBER();
1247  property.name = CurText();
1248 
1249  NeedSYMBOLorNUMBER();
1250  property.value = CurText();
1251 
1252  growth->push_back( property );
1253 
1254  NeedRIGHT();
1255  }
1256 }

Referenced by doLAYER(), and doPLACE().

◆ doQARC()

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

Definition at line 1115 of file specctra.cpp.

1116 {
1117  NeedSYMBOL();
1118  growth->layer_id = CurText();
1119 
1120  if( NextTok() != T_NUMBER )
1121  Expecting( T_NUMBER );
1122  growth->aperture_width = strtod( CurText(), 0 );
1123 
1124  for( int i=0; i<3; ++i )
1125  {
1126  if( NextTok() != T_NUMBER )
1127  Expecting( T_NUMBER );
1128  growth->vertex[i].x = strtod( CurText(), 0 );
1129 
1130  if( NextTok() != T_NUMBER )
1131  Expecting( T_NUMBER );
1132  growth->vertex[i].y = strtod( CurText(), 0 );
1133  }
1134 
1135  NeedRIGHT();
1136 }

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 1062 of file specctra.cpp.

1063 {
1064  NeedSYMBOL();
1065  growth->layer_id = CurText();
1066 
1067  if( NextTok() != T_NUMBER )
1068  Expecting( T_NUMBER );
1069  growth->point0.x = strtod( CurText(), NULL );
1070 
1071  if( NextTok() != T_NUMBER )
1072  Expecting( T_NUMBER );
1073  growth->point0.y = strtod( CurText(), NULL );
1074 
1075  if( NextTok() != T_NUMBER )
1076  Expecting( T_NUMBER );
1077  growth->point1.x = strtod( CurText(), NULL );
1078 
1079  if( NextTok() != T_NUMBER )
1080  Expecting( T_NUMBER );
1081  growth->point1.y = strtod( CurText(), NULL );
1082 
1083  NeedRIGHT();
1084 }
#define NULL

References DSN::RECTANGLE::layer_id, NULL, 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 1513 of file specctra.cpp.

1514 {
1515  T tok = NextTok();
1516 
1517  if( IsSymbol(tok) )
1518  {
1519  growth->region_id = CurText();
1520  tok = NextTok();
1521  }
1522 
1523  for(;;)
1524  {
1525  if( tok != T_LEFT )
1526  Expecting( T_LEFT );
1527 
1528  tok = NextTok();
1529  switch( tok )
1530  {
1531  case T_rect:
1532  if( growth->rectangle )
1533  Unexpected( tok );
1534  growth->rectangle = new RECTANGLE( growth );
1535  doRECTANGLE( growth->rectangle );
1536  break;
1537 
1538  case T_polygon:
1539  if( growth->polygon )
1540  Unexpected( tok );
1541  growth->polygon = new PATH( growth, T_polygon );
1542  doPATH( growth->polygon );
1543  break;
1544 
1545  case T_region_net:
1546  case T_region_class:
1547  STRINGPROP* stringprop;
1548  stringprop = new STRINGPROP( growth, tok );
1549  growth->Append( stringprop );
1550  doSTRINGPROP( stringprop );
1551  break;
1552 
1553  case T_region_class_class:
1554  CLASS_CLASS* class_class;
1555  class_class = new CLASS_CLASS( growth, tok );
1556  growth->Append( class_class );
1557  doCLASS_CLASS( class_class );
1558  break;
1559 
1560  case T_rule:
1561  if( growth->rules )
1562  Unexpected( tok );
1563  growth->rules = new RULE( growth, T_rule );
1564  doRULE( growth->rules );
1565  break;
1566 
1567  default:
1568  Unexpected( CurText() );
1569  }
1570 
1571  tok = NextTok();
1572  if( tok == T_RIGHT )
1573  {
1574  if( !growth->rules )
1575  Expecting( T_rule );
1576  break;
1577  }
1578  }
1579 }
void doCLASS_CLASS(CLASS_CLASS *growth)
Definition: specctra.cpp:1582
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1139

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 526 of file specctra.cpp.

527 {
528  T tok = NextTok();
529 
530  switch( tok )
531  {
532  case T_inch:
533  case T_mil:
534  case T_cm:
535  case T_mm:
536  case T_um:
537  growth->units = tok;
538  break;
539  default:
540  Expecting( "inch|mil|cm|mm|um" );
541  }
542 
543  tok = NextTok();
544  if( tok != T_NUMBER )
545  Expecting( T_NUMBER );
546 
547  growth->value = atoi( CurText() );
548 
549  NeedRIGHT();
550 }

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 3255 of file specctra.cpp.

3256 {
3257  T tok;
3258 
3259  /* <route_descriptor >::=
3260  (routes
3261  <resolution_descriptor>
3262  <parser_descriptor>
3263  <structure_out_descriptor>
3264  <library_out_descriptor>
3265  <network_out_descriptor>
3266  <test_points_descriptor>
3267  )
3268  */
3269 
3270  while( (tok = NextTok()) != T_RIGHT )
3271  {
3272  if( tok != T_LEFT )
3273  Expecting( T_LEFT );
3274 
3275  tok = NextTok();
3276  switch( tok )
3277  {
3278  case T_resolution:
3279  if( growth->resolution )
3280  Unexpected( tok );
3281  growth->resolution = new UNIT_RES( growth, tok );
3282  doRESOLUTION( growth->resolution );
3283  break;
3284 
3285  case T_parser:
3286  if( growth->parser )
3287  {
3288 #if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
3289  // Work around their bug for now.
3290  Unexpected( tok );
3291 #else
3292  delete growth->parser;
3293 #endif
3294  }
3295  growth->parser = new PARSER( growth );
3296  doPARSER( growth->parser );
3297  break;
3298 
3299  case T_structure_out:
3300  if( growth->structure_out )
3301  Unexpected( tok );
3302  growth->structure_out = new STRUCTURE_OUT( growth );
3303  doSTRUCTURE_OUT( growth->structure_out );
3304  break;
3305 
3306  case T_library_out:
3307  if( growth->library )
3308  Unexpected( tok );
3309  growth->library = new LIBRARY( growth, tok );
3310  doLIBRARY( growth->library );
3311  break;
3312 
3313  case T_network_out:
3314  while( (tok = NextTok()) != T_RIGHT )
3315  {
3316  if( tok != T_LEFT )
3317  Expecting( T_LEFT );
3318 
3319  tok = NextTok();
3320  if( tok != T_net ) // it is class NET_OUT, but token T_net
3321  Unexpected( CurText() );
3322 
3323  NET_OUT* net_out;
3324  net_out = new NET_OUT( growth );
3325 
3326  growth->net_outs.push_back( net_out );
3327  doNET_OUT( net_out );
3328  }
3329  break;
3330 
3331  default:
3332  Unexpected( CurText() );
3333  }
3334  }
3335 }
void doSTRUCTURE_OUT(STRUCTURE_OUT *growth)
Definition: specctra.cpp:744
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:526
void doLIBRARY(LIBRARY *growth)
Definition: specctra.cpp:2269
void doNET_OUT(NET_OUT *growth)
Definition: specctra.cpp:3338
void doPARSER(PARSER *growth)
Definition: specctra.cpp:387

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 1381 of file specctra.cpp.

1382 {
1383  std::string builder;
1384  int bracketNesting = 1; // we already saw the opening T_LEFT
1385  T tok = T_NONE;
1386 
1387  while( bracketNesting!=0 && tok!=T_EOF )
1388  {
1389  tok = NextTok();
1390 
1391  if( tok==T_LEFT)
1392  ++bracketNesting;
1393 
1394  else if( tok==T_RIGHT )
1395  --bracketNesting;
1396 
1397  if( bracketNesting >= 1 )
1398  {
1399  if( PrevTok()!=T_LEFT && tok!=T_RIGHT && (tok!=T_LEFT || bracketNesting>2) )
1400  builder += ' ';
1401 
1402  if( tok==T_STRING )
1403  builder += m_quote_char;
1404 
1405  builder += CurText();
1406 
1407  if( tok==T_STRING )
1408  builder += m_quote_char;
1409  }
1410 
1411  // When the nested rule is closed with a T_RIGHT and we are back down
1412  // to bracketNesting == 1, (inside the <rule_descriptor> but outside
1413  // the last rule). Then save the last rule and clear the string builder.
1414  if( bracketNesting == 1 )
1415  {
1416  growth->rules.push_back( builder );
1417  builder.clear();
1418  }
1419  }
1420 
1421  if( tok==T_EOF )
1422  Unexpected( T_EOF );
1423 }
std::string m_quote_char
Definition: specctra.h:3640

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 3137 of file specctra.cpp.

3138 {
3139  T tok;
3140 
3141  /* <session_file_descriptor >::=
3142  (session <session_id >
3143  (base_design <path/filename >)
3144  [<history_descriptor> ]
3145  [<session_structure_descriptor> ]
3146  [<placement_descriptor> ]
3147  [<floor_plan_descriptor> ]
3148  [<net_pin_changes_descriptor> ]
3149  [<was_is_descriptor> ]
3150  <swap_history_descriptor> ]
3151  [<route_descriptor> ]
3152  )
3153  */
3154 
3155  NeedSYMBOL();
3156  growth->session_id = CurText();
3157 
3158  while( (tok = NextTok()) != T_RIGHT )
3159  {
3160  if( tok != T_LEFT )
3161  Expecting( T_LEFT );
3162 
3163  tok = NextTok();
3164  switch( tok )
3165  {
3166  case T_base_design:
3167  NeedSYMBOL();
3168  growth->base_design = CurText();
3169  NeedRIGHT();
3170  break;
3171 
3172  case T_history:
3173  if( growth->history )
3174  Unexpected( tok );
3175  growth->history = new HISTORY( growth );
3176  doHISTORY( growth->history );
3177  break;
3178 
3179  case T_structure:
3180  if( growth->structure )
3181  Unexpected( tok );
3182  growth->structure = new STRUCTURE( growth );
3183  doSTRUCTURE( growth->structure );
3184  break;
3185 
3186  case T_placement:
3187  if( growth->placement )
3188  Unexpected( tok );
3189  growth->placement = new PLACEMENT( growth );
3190  doPLACEMENT( growth->placement );
3191  break;
3192 
3193  case T_was_is:
3194  if( growth->was_is )
3195  Unexpected( tok );
3196  growth->was_is = new WAS_IS( growth );
3197  doWAS_IS( growth->was_is );
3198  break;
3199 
3200  case T_routes:
3201  if( growth->route )
3202  Unexpected( tok );
3203  growth->route = new ROUTE( growth );
3204  doROUTE( growth->route );
3205  break;
3206 
3207  default:
3208  Unexpected( CurText() );
3209  }
3210  }
3211 }
void doROUTE(ROUTE *growth)
Definition: specctra.cpp:3255
void doHISTORY(HISTORY *growth)
Definition: specctra.cpp:3081
void doSTRUCTURE(STRUCTURE *growth)
Definition: specctra.cpp:610
void doPLACEMENT(PLACEMENT *growth)
Definition: specctra.cpp:1885
void doWAS_IS(WAS_IS *growth)
Definition: specctra.cpp:3214

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 2040 of file specctra.cpp.

2041 {
2042  T tok;
2043 
2044  /* (shape <shape_descriptor>
2045  [<reduced_shape_descriptor> ]
2046  [(connect [on | off])]
2047  [{<window_descriptor> }])
2048  */
2049 
2050  while( (tok = NextTok()) != T_RIGHT )
2051  {
2052  if( tok != T_LEFT )
2053  Expecting( T_LEFT );
2054 
2055  tok = NextTok();
2056  switch( tok )
2057  {
2058  case T_polyline_path:
2059  tok = T_path;
2061 
2062  case T_rect:
2063  case T_circle:
2064  case T_path:
2065  case T_polygon:
2066  case T_qarc:
2067 L_done_that:
2068  if( growth->shape )
2069  Unexpected( tok );
2070  break;
2071 
2072  default:
2073  // the example in the spec uses "circ" instead of "circle". Bad!
2074  if( !strcmp( "circ", CurText() ) )
2075  {
2076  tok = T_circle;
2077  goto L_done_that;
2078  }
2079  }
2080 
2081  switch( tok )
2082  {
2083  case T_rect:
2084  growth->shape = new RECTANGLE( growth );
2085  doRECTANGLE( (RECTANGLE*) growth->shape );
2086  break;
2087 
2088  case T_circle:
2089  growth->shape = new CIRCLE( growth );
2090  doCIRCLE( (CIRCLE*)growth->shape );
2091  break;
2092 
2093  case T_path:
2094  case T_polygon:
2095  growth->shape = new PATH( growth, tok );
2096  doPATH( (PATH*)growth->shape );
2097  break;
2098 
2099  case T_qarc:
2100  growth->shape = new QARC( growth );
2101  doQARC( (QARC*)growth->shape );
2102  break;
2103 
2104  case T_connect:
2105  tok = NextTok();
2106  if( tok!=T_on && tok!=T_off )
2107  Expecting( "on|off" );
2108  growth->connect = tok;
2109  NeedRIGHT();
2110  break;
2111 
2112  case T_window:
2113  WINDOW* window;
2114  window = new WINDOW( growth );
2115  growth->windows.push_back( window );
2116  doWINDOW( window );
2117  break;
2118 
2119  default:
2120  Unexpected( CurText() );
2121  }
2122  }
2123 }
#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:913
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
Class Circle Represents basic circle geometry with utility geometry functions.
Definition: circle.h:33
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1087
void doQARC(QARC *growth)
Definition: specctra.cpp:1115

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 574 of file specctra.cpp.

575 {
576  NeedSYMBOL();
577  growth->layer_id0 = CurText();
578 
579  NeedSYMBOL();
580  growth->layer_id1 = CurText();
581 
582  if( NextTok() != T_NUMBER )
583  Expecting( T_NUMBER );
584  growth->layer_weight = strtod( CurText(), 0 );
585 
586  NeedRIGHT();
587 }

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 1139 of file specctra.cpp.

1140 {
1141  NeedSYMBOL();
1142  growth->value = CurText();
1143  NeedRIGHT();
1144 }

References DSN::STRINGPROP::value.

Referenced by doREGION(), and doSTRUCTURE().

◆ doSTRUCTURE()

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

Definition at line 610 of file specctra.cpp.

611 {
612  T tok;
613 
614  while( (tok = NextTok()) != T_RIGHT )
615  {
616  if( tok != T_LEFT )
617  Expecting( T_LEFT );
618 
619  tok = NextTok();
620  switch( tok )
621  {
622  case T_unit:
623  if( growth->unit )
624  Unexpected( tok );
625  growth->unit = new UNIT_RES( growth, tok );
626  doUNIT( growth->unit );
627  break;
628 
629  case T_resolution:
630  if( growth->unit )
631  Unexpected( tok );
632  growth->unit = new UNIT_RES( growth, tok );
633  doRESOLUTION( growth->unit );
634  break;
635 
636  case T_layer_noise_weight:
637  if( growth->layer_noise_weight )
638  Unexpected( tok );
639  growth->layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
640  doLAYER_NOISE_WEIGHT( growth->layer_noise_weight );
641  break;
642 
643  case T_place_boundary:
644 L_place:
645  if( growth->place_boundary )
646  Unexpected( tok );
647  growth->place_boundary = new BOUNDARY( growth, T_place_boundary );
648  doBOUNDARY( growth->place_boundary );
649  break;
650 
651  case T_boundary:
652  if( growth->boundary )
653  {
654  if( growth->place_boundary )
655  Unexpected( tok );
656  goto L_place;
657  }
658  growth->boundary = new BOUNDARY( growth );
659  doBOUNDARY( growth->boundary );
660  break;
661 
662  case T_plane:
663  COPPER_PLANE* plane;
664  plane = new COPPER_PLANE( growth );
665  growth->planes.push_back( plane );
666  doKEEPOUT( plane );
667  break;
668 
669  case T_region:
670  REGION* region;
671  region = new REGION( growth );
672  growth->regions.push_back( region );
673  doREGION( region );
674  break;
675 
676  case T_snap_angle:
677  STRINGPROP* stringprop;
678  stringprop = new STRINGPROP( growth, T_snap_angle );
679  growth->Append( stringprop );
680  doSTRINGPROP( stringprop );
681  break;
682 
683  case T_via:
684  if( growth->via )
685  Unexpected( tok );
686  growth->via = new VIA( growth );
687  doVIA( growth->via );
688  break;
689 
690  case T_control:
691  if( growth->control )
692  Unexpected( tok );
693  growth->control = new CONTROL( growth );
694  doCONTROL( growth->control );
695  break;
696 
697  case T_layer:
698  LAYER* layer;
699  layer = new LAYER( growth );
700  growth->layers.push_back( layer );
701  doLAYER( layer );
702  break;
703 
704  case T_rule:
705  if( growth->rules )
706  Unexpected( tok );
707  growth->rules = new RULE( growth, T_rule );
708  doRULE( growth->rules );
709  break;
710 
711  case T_place_rule:
712  if( growth->place_rules )
713  Unexpected( tok );
714  growth->place_rules = new RULE( growth, T_place_rule );
715  doRULE( growth->place_rules );
716  break;
717 
718  case T_keepout:
719  case T_place_keepout:
720  case T_via_keepout:
721  case T_wire_keepout:
722  case T_bend_keepout:
723  case T_elongate_keepout:
724  KEEPOUT* keepout;
725  keepout = new KEEPOUT( growth, tok );
726  growth->keepouts.push_back( keepout );
727  doKEEPOUT( keepout );
728  break;
729 
730  case T_grid:
731  GRID* grid;
732  grid = new GRID( growth );
733  growth->grids.push_back( grid );
734  doGRID( grid );
735  break;
736 
737  default:
738  Unexpected( CurText() );
739  }
740  }
741 }
void doLAYER_NOISE_WEIGHT(LAYER_NOISE_WEIGHT *growth)
Definition: specctra.cpp:590
void doKEEPOUT(KEEPOUT *growth)
Definition: specctra.cpp:787
void doGRID(GRID *growth)
Definition: specctra.cpp:1650
void doCONTROL(CONTROL *growth)
Definition: specctra.cpp:1189
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1259
void doVIA(VIA *growth)
Definition: specctra.cpp:1160
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:526
void doREGION(REGION *growth)
Definition: specctra.cpp:1513
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1139
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:76
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553
void doBOUNDARY(BOUNDARY *growth)
Definition: specctra.cpp:967

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 744 of file specctra.cpp.

745 {
746  /*
747  <structure_out_descriptor >::=
748  (structure_out
749  {<layer_descriptor> }
750  [<rule_descriptor> ]
751  )
752  */
753 
754  T tok = NextTok();
755 
756  while( tok != T_RIGHT )
757  {
758  if( tok != T_LEFT )
759  Expecting( T_LEFT );
760 
761  tok = NextTok();
762  switch( tok )
763  {
764  case T_layer:
765  LAYER* layer;
766  layer = new LAYER( growth );
767  growth->layers.push_back( layer );
768  doLAYER( layer );
769  break;
770 
771  case T_rule:
772  if( growth->rules )
773  Unexpected( tok );
774  growth->rules = new RULE( growth, T_rule );
775  doRULE( growth->rules );
776  break;
777 
778  default:
779  Unexpected( CurText() );
780  }
781 
782  tok = NextTok();
783  }
784 }
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1259
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
Container to hold information pertinent to a layer of a BOARD.
Definition: board.h:76

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 3406 of file specctra.cpp.

3407 {
3408  T tok;
3409  PIN_REF empty(growth);
3410 
3411  /* <supply_pin_descriptor >::=
3412  (supply_pin {<pin_reference> } [(net <net_id >)])
3413  */
3414 
3415  NeedSYMBOL();
3416  growth->net_id = CurText();
3417 
3418  while( (tok = NextTok()) != T_RIGHT )
3419  {
3420  if( IsSymbol(tok) )
3421  {
3422  growth->pin_refs.push_back( empty );
3423 
3424  PIN_REF* pin_ref = &growth->pin_refs.back();
3425 
3426  readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
3427  }
3428  else if( tok == T_LEFT )
3429  {
3430  tok = NextTok();
3431  if( tok != T_net )
3432  Expecting( T_net );
3433  growth->net_id = CurText();
3434  NeedRIGHT();
3435  }
3436  else
3437  Unexpected( CurText() );
3438  }
3439 }
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Function readCOMPnPIN reads a <pin_reference> and splits it into the two parts which are on either si...
Definition: specctra.cpp:134
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 1147 of file specctra.cpp.

1148 {
1149  T tok = NextTok();
1150 
1151  if( tok<0 )
1152  Unexpected( CurText() );
1153 
1154  growth->value = tok;
1155 
1156  NeedRIGHT();
1157 }

References DSN::TOKPROP::value.

Referenced by doCONTROL().

◆ doTOPOLOGY()

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

Definition at line 2463 of file specctra.cpp.

2464 {
2465  T tok;
2466 
2467  /* <topology_descriptor >::=
2468  (topology {[<fromto_descriptor> |
2469  <component_order_descriptor> ]})
2470  */
2471 
2472  while( (tok = NextTok()) != T_RIGHT )
2473  {
2474  if( tok != T_LEFT )
2475  Expecting( T_LEFT );
2476 
2477  tok = NextTok();
2478  switch( tok )
2479  {
2480  case T_fromto:
2481  FROMTO* fromto;
2482  fromto = new FROMTO( growth );
2483  growth->fromtos.push_back( fromto );
2484  doFROMTO( fromto );
2485  break;
2486 
2487  case T_comp_order:
2488  COMP_ORDER* comp_order;
2489  comp_order = new COMP_ORDER( growth );
2490  growth->comp_orders.push_back( comp_order );
2491  doCOMP_ORDER( comp_order );
2492  break;
2493 
2494  default:
2495  Unexpected( CurText() );
2496  }
2497  }
2498 }
void doCOMP_ORDER(COMP_ORDER *growth)
Definition: specctra.cpp:2656
void doFROMTO(FROMTO *growth)
Definition: specctra.cpp:2674

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 553 of file specctra.cpp.

554 {
555  T tok = NextTok();
556 
557  switch( tok )
558  {
559  case T_inch:
560  case T_mil:
561  case T_cm:
562  case T_mm:
563  case T_um:
564  growth->units = tok;
565  break;
566  default:
567  Expecting( "inch|mil|cm|mm|um" );
568  }
569 
570  NeedRIGHT();
571 }

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 1160 of file specctra.cpp.

1161 {
1162  T tok;
1163 
1164  while( (tok = NextTok()) != T_RIGHT )
1165  {
1166  if( tok == T_LEFT )
1167  {
1168  if( NextTok() != T_spare )
1169  Expecting( T_spare );
1170 
1171  while( (tok = NextTok()) != T_RIGHT )
1172  {
1173  if( !IsSymbol( tok ) )
1174  Expecting( T_SYMBOL );
1175 
1176  growth->spares.push_back( CurText() );
1177  }
1178  }
1179  else if( IsSymbol( tok ) )
1180  {
1181  growth->padstacks.push_back( CurText() );
1182  }
1183  else
1184  Unexpected( CurText() );
1185  }
1186 }

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 3214 of file specctra.cpp.

3215 {
3216  T tok;
3217  PIN_PAIR empty( growth );
3218  PIN_PAIR* pin_pair;
3219 
3220  /* <was_is_descriptor >::=
3221  (was_is {(pins <pin_reference> <pin_reference> )})
3222  */
3223 
3224  // none of the pins is ok too
3225  while( (tok = NextTok()) != T_RIGHT )
3226  {
3227 
3228  if( tok != T_LEFT )
3229  Expecting( T_LEFT );
3230 
3231  tok = NextTok();
3232  switch( tok )
3233  {
3234  case T_pins:
3235  // copy the empty one, then fill its copy later thru pin_pair.
3236  growth->pin_pairs.push_back( empty );
3237  pin_pair= &growth->pin_pairs.back();
3238 
3239  NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3240  readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
3241 
3242  NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3243  readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
3244 
3245  NeedRIGHT();
3246  break;
3247 
3248  default:
3249  Unexpected( CurText() );
3250  }
3251  }
3252 }
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Function readCOMPnPIN reads a <pin_reference> and splits it into the two parts which are on either si...
Definition: specctra.cpp:134
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 913 of file specctra.cpp.

914 {
915  T tok = NextTok();
916 
917  while( tok != T_RIGHT )
918  {
919  if( tok!=T_LEFT )
920  Expecting( T_LEFT );
921 
922  tok = NextTok();
923  switch( tok )
924  {
925  case T_rect:
926  if( growth->shape )
927  Unexpected( tok );
928  growth->shape = new RECTANGLE( growth );
929  doRECTANGLE( (RECTANGLE*) growth->shape );
930  break;
931 
932  case T_circle:
933  if( growth->shape )
934  Unexpected( tok );
935  growth->shape = new CIRCLE( growth );
936  doCIRCLE( (CIRCLE*) growth->shape );
937  break;
938 
939  case T_polyline_path:
940  tok = T_path;
942 
943  case T_path:
944  case T_polygon:
945  if( growth->shape )
946  Unexpected( tok );
947  growth->shape = new PATH( growth, tok );
948  doPATH( (PATH*) growth->shape );
949  break;
950 
951  case T_qarc:
952  if( growth->shape )
953  Unexpected( tok );
954  growth->shape = new QARC( growth );
955  doQARC( (QARC*) growth->shape );
956  break;
957 
958  default:
959  Unexpected( CurText() );
960  }
961 
962  tok = NextTok();
963  }
964 }
#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:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
Class Circle Represents basic circle geometry with utility geometry functions.
Definition: circle.h:33
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1087
void doQARC(QARC *growth)
Definition: specctra.cpp:1115

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 2760 of file specctra.cpp.

2761 {
2762  T tok;
2763 
2764  /* <wire_shape_descriptor >::=
2765  (wire
2766  <shape_descriptor>
2767  [(net <net_id >)]
2768  [(turret <turret#> )]
2769  [(type [fix | route | normal | protect])]
2770  [(attr [test | fanout | bus | jumper])]
2771  [(shield <net_id >)]
2772  [{<window_descriptor> }]
2773  [(connect
2774  (terminal <object_type> [<pin_reference> ])
2775  (terminal <object_type> [<pin_reference> ])
2776  )]
2777  [(supply)]
2778  )
2779  */
2780 
2781  while( (tok = NextTok()) != T_RIGHT )
2782  {
2783  if( tok != T_LEFT )
2784  Expecting( T_LEFT );
2785 
2786  tok = NextTok();
2787  switch( tok )
2788  {
2789  case T_rect:
2790  if( growth->shape )
2791  Unexpected( tok );
2792  growth->shape = new RECTANGLE( growth );
2793  doRECTANGLE( (RECTANGLE*) growth->shape );
2794  break;
2795 
2796  case T_circle:
2797  if( growth->shape )
2798  Unexpected( tok );
2799  growth->shape = new CIRCLE( growth );
2800  doCIRCLE( (CIRCLE*) growth->shape );
2801  break;
2802 
2803  case T_polyline_path:
2804  tok = T_path;
2806 
2807  case T_path:
2808  case T_polygon:
2809  if( growth->shape )
2810  Unexpected( tok );
2811  growth->shape = new PATH( growth, tok );
2812  doPATH( (PATH*) growth->shape );
2813  break;
2814 
2815  case T_qarc:
2816  if( growth->shape )
2817  Unexpected( tok );
2818  growth->shape = new QARC( growth );
2819  doQARC( (QARC*) growth->shape );
2820  break;
2821 
2822  case T_net:
2823  NeedSYMBOLorNUMBER();
2824  growth->net_id = CurText();
2825  NeedRIGHT();
2826  break;
2827 
2828  case T_turret:
2829  if( NextTok() != T_NUMBER )
2830  Expecting( T_NUMBER );
2831  growth->turret = atoi( CurText() );
2832  NeedRIGHT();
2833  break;
2834 
2835  case T_type:
2836  tok = NextTok();
2837  if( tok!=T_fix && tok!=T_route && tok!=T_normal && tok!=T_protect )
2838  Expecting( "fix|route|normal|protect" );
2839  growth->wire_type = tok;
2840  NeedRIGHT();
2841  break;
2842 
2843  case T_attr:
2844  tok = NextTok();
2845  if( tok!=T_test && tok!=T_fanout && tok!=T_bus && tok!=T_jumper )
2846  Expecting( "test|fanout|bus|jumper" );
2847  growth->attr = tok;
2848  NeedRIGHT();
2849  break;
2850 
2851  case T_shield:
2852  NeedSYMBOL();
2853  growth->shield = CurText();
2854  NeedRIGHT();
2855  break;
2856 
2857  case T_window:
2858  WINDOW* window;
2859  window = new WINDOW( growth );
2860  growth->windows.push_back( window );
2861  doWINDOW( window );
2862  break;
2863 
2864  case T_connect:
2865  if( growth->connect )
2866  Unexpected( tok );
2867  growth->connect = new CONNECT( growth );
2868  doCONNECT( growth->connect );
2869  break;
2870 
2871  case T_supply:
2872  growth->supply = true;
2873  NeedRIGHT();
2874  break;
2875 
2876  default:
2877  Unexpected( CurText() );
2878  }
2879  }
2880 }
#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:913
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
Class Circle Represents basic circle geometry with utility geometry functions.
Definition: circle.h:33
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1087
void doCONNECT(CONNECT *growth)
Definition: specctra.cpp:878
void doQARC(QARC *growth)
Definition: specctra.cpp:1115

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 2883 of file specctra.cpp.

2884 {
2885  T tok;
2886  POINT point;
2887 
2888  /* <wire_via_descriptor >::=
2889  (via
2890  <padstack_id > {<vertex> }
2891  [(net <net_id >)]
2892  [(via_number <via#> )]
2893  [(type [fix | route | normal | protect])]
2894  [(attr [test | fanout | jumper |
2895  virtual_pin <virtual_pin_name> ])]
2896  [(contact {<layer_id >})]
2897  [(supply)]
2898  )
2899  (virtual_pin
2900  <virtual_pin_name> <vertex> (net <net_id >)
2901  )
2902  */
2903 
2904  NeedSYMBOL();
2905  growth->padstack_id = CurText();
2906 
2907  while( (tok = NextTok()) == T_NUMBER )
2908  {
2909  point.x = strtod( CurText(), 0 );
2910 
2911  if( NextTok() != T_NUMBER )
2912  Expecting( "vertex.y" );
2913 
2914  point.y = strtod( CurText(), 0 );
2915 
2916  growth->vertexes.push_back( point );
2917  }
2918 
2919  while( tok != T_RIGHT )
2920  {
2921  if( tok != T_LEFT )
2922  Expecting( T_LEFT );
2923 
2924  tok = NextTok();
2925  switch( tok )
2926  {
2927  case T_net:
2928  NeedSYMBOL();
2929  growth->net_id = CurText();
2930  NeedRIGHT();
2931  break;
2932 
2933  case T_via_number:
2934  if( NextTok() != T_NUMBER )
2935  Expecting( "<via#>" );
2936  growth->via_number = atoi( CurText() );
2937  NeedRIGHT();
2938  break;
2939 
2940  case T_type:
2941  tok = NextTok();
2942  if( tok!=T_fix && tok!=T_route && tok!=T_normal && tok!=T_protect )
2943  Expecting( "fix|route|normal|protect" );
2944  growth->via_type = tok;
2945  NeedRIGHT();
2946  break;
2947 
2948  case T_attr:
2949  tok = NextTok();
2950  if( tok!=T_test && tok!=T_fanout && tok!=T_jumper && tok!=T_virtual_pin )
2951  Expecting( "test|fanout|jumper|virtual_pin" );
2952  growth->attr = tok;
2953  if( tok == T_virtual_pin )
2954  {
2955  NeedSYMBOL();
2956  growth->virtual_pin_name = CurText();
2957  }
2958  NeedRIGHT();
2959  break;
2960 
2961  case T_contact:
2962  NeedSYMBOL();
2963  tok = T_SYMBOL;
2964  while( IsSymbol(tok) )
2965  {
2966  growth->contact_layers.push_back( CurText() );
2967  tok = NextTok();
2968  }
2969  if( tok != T_RIGHT )
2970  Expecting( T_RIGHT );
2971  break;
2972 
2973  case T_supply:
2974  growth->supply = true;
2975  NeedRIGHT();
2976  break;
2977 
2978  default:
2979  Unexpected( CurText() );
2980  }
2981 
2982  tok = NextTok();
2983  }
2984 }

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 2987 of file specctra.cpp.

2988 {
2989  T tok;
2990 
2991  /* <wiring_descriptor >::=
2992  (wiring
2993  [<unit_descriptor> | <resolution_descriptor> | null]
2994  {<wire_descriptor> }
2995  [<test_points_descriptor> ]
2996  {[<supply_pin_descriptor> ]}
2997  )
2998  */
2999 
3000  while( (tok = NextTok()) != T_RIGHT )
3001  {
3002  if( tok != T_LEFT )
3003  Expecting( T_LEFT );
3004 
3005  tok = NextTok();
3006  switch( tok )
3007  {
3008  case T_unit:
3009  if( growth->unit )
3010  Unexpected( tok );
3011  growth->unit = new UNIT_RES( growth, tok );
3012  doUNIT( growth->unit );
3013  break;
3014 
3015  case T_resolution:
3016  if( growth->unit )
3017  Unexpected( tok );
3018  growth->unit = new UNIT_RES( growth, tok );
3019  doRESOLUTION( growth->unit );
3020  break;
3021 
3022  case T_wire:
3023  WIRE* wire;
3024  wire = new WIRE( growth );
3025  growth->wires.push_back( wire );
3026  doWIRE( wire );
3027  break;
3028 
3029  case T_via:
3030  WIRE_VIA* wire_via;
3031  wire_via = new WIRE_VIA( growth );
3032  growth->wire_vias.push_back( wire_via );
3033  doWIRE_VIA( wire_via );
3034  break;
3035 
3036  default:
3037  Unexpected( CurText() );
3038  }
3039  }
3040 }
void doWIRE(WIRE *growth)
Definition: specctra.cpp:2760
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:526
void doWIRE_VIA(WIRE_VIA *growth)
Definition: specctra.cpp:2883
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

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

Function exportNETCLASS exports aNetClass to the DSN file.

Definition at line 1699 of file specctra_export.cpp.

1700 {
1701  /* From page 11 of specctra spec:
1702  *
1703  * Routing and Placement Rule Hierarchies
1704  *
1705  * Routing and placement rules can be defined at multiple levels of design
1706  * specification. When a routing or placement rule is defined for an object at
1707  * multiple levels, a predefined routing or placement precedence order
1708  * automatically determines which rule to apply to the object. The routing rule
1709  * precedence order is
1710  *
1711  * pcb < layer < class < class layer < group_set < group_set layer < net <
1712  * net layer < group < group layer < fromto < fromto layer < class_class <
1713  * class_class layer < padstack < region < class region < net region <
1714  * class_class region
1715  *
1716  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1717  * hierarchy. A class-to-class region rule has the highest precedence. Rules
1718  * set at one level of the hierarchy override conflicting rules set at lower
1719  * levels. The placement rule precedence order is
1720  *
1721  * pcb < image_set < image < component < super cluster < room <
1722  * room_image_set < family_family < image_image
1723  *
1724  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1725  * hierarchy. An image-to-image rule has the highest precedence. Rules set at
1726  * one level of the hierarchy override conflicting rules set at lower levels.
1727  */
1728 
1729  char text[256];
1730 
1731  CLASS* clazz = new CLASS( m_pcb->network );
1732 
1733  m_pcb->network->classes.push_back( clazz );
1734 
1735  // freerouter creates a class named 'default' anyway, and if we
1736  // try and use that, we end up with two 'default' via rules so use
1737  // something else as the name of our default class.
1738  clazz->class_id = TO_UTF8( aNetClass->GetName() );
1739 
1740  for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net )
1741  clazz->net_ids.push_back( TO_UTF8( *net ) );
1742 
1743  clazz->rules = new RULE( clazz, T_rule );
1744 
1745  // output the track width.
1746  int trackWidth = aNetClass->GetTrackWidth();
1747  sprintf( text, "(width %.6g)", scale( trackWidth ) );
1748  clazz->rules->rules.push_back( text );
1749 
1750  // output the clearance.
1751  int clearance = aNetClass->GetClearance();
1752  sprintf( text, "(clearance %.6g)", scale( clearance ) + safetyMargin );
1753  clazz->rules->rules.push_back( text );
1754 
1755  if( aNetClass->GetName() == NETCLASS::Default )
1756  {
1757  clazz->class_id = "kicad_default";
1758  }
1759 
1760  // the easiest way to get the via name is to create a via (which generates
1761  // the name internal to the PADSTACK), and then grab the name and then
1762  // delete the via. There are not that many netclasses so
1763  // this should never become a performance issue.
1764 
1765  PADSTACK* via = makeVia( aNetClass->GetViaDiameter(), aNetClass->GetViaDrill(),
1767 
1768  snprintf( text, sizeof(text), "(use_via %s)", via->GetPadstackId().c_str() );
1769  clazz->circuit.push_back( text );
1770 
1771  delete via;
1772 }
STRINGS circuit
circuit descriptor list
Definition: specctra.h:2756
static const double safetyMargin
CLASS corresponds to the <class_descriptor> in the specctra spec.
Definition: specctra.h:2747
std::string class_id
Definition: specctra.h:2751
#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
PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2114
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:3665
CLASSLIST classes
Definition: specctra.h:2838
RULE * rules
Definition: specctra.h:2758
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:2753
NETWORK * network
Definition: specctra.h:3172
PADSTACK * makeVia(int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
Function makeVia makes 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:492

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 
)

Function ExportPCB writes 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 3442 of file specctra.cpp.

3443 {
3444  if( m_pcb )
3445  {
3446  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3447 
3448  if( aNameChange )
3449  m_pcb->pcbname = TO_UTF8( aFilename );
3450 
3451  m_pcb->Format( &formatter, 0 );
3452  }
3453 }
#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
Function Format writes this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN f...
Definition: specctra.h:3202
Used for text file output.
Definition: richio.h:453
std::string pcbname
Definition: specctra.h:3165
std::string m_quote_char
Definition: specctra.h:3640

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

Referenced by PCB_EDIT_FRAME::ExportSpecctraFile().

◆ ExportSESSION()

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

Function ExportSESSION writes the internal SESSION instance out as a SPECTRA DSN format file.

Parameters
aFilenameThe file to save to.

Definition at line 3456 of file specctra.cpp.

3457 {
3458  if( m_session )
3459  {
3460  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3461 
3462  m_session->Format( &formatter, 0 );
3463  }
3464 }
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Function Format writes this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN f...
Definition: specctra.h:3598
SESSION * m_session
Definition: specctra.h:3638
Used for text file output.
Definition: richio.h:453
std::string m_quote_char
Definition: specctra.h:3640

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

◆ fillBOUNDARY()

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

Function fillBOUNDARY makes 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 947 of file specctra_export.cpp.

948 {
949  SHAPE_POLY_SET outlines;
950 
951  if( !aBoard->GetBoardPolygonOutlines( outlines ) )
952  {
953  wxLogWarning( _( "Board outline is malformed. Run DRC for a full analysis." ) );
954  }
955 
956  for( int cnt = 0; cnt < outlines.OutlineCount(); cnt++ ) // Should be one outline
957  {
958  PATH* path = new PATH( boundary );
959  boundary->paths.push_back( path );
960  path->layer_id = "pcb";
961 
962  SHAPE_LINE_CHAIN& outline = outlines.Outline( cnt );
963 
964  for( int ii = 0; ii < outline.PointCount(); ii++ )
965  {
966  wxPoint pos( outline.CPoint( ii ).x, outline.CPoint( ii ).y );
967  path->AppendPoint( mapPt( pos ) );
968  }
969 
970  // Close polygon:
971  wxPoint pos0( outline.CPoint( 0 ).x, outline.CPoint( 0 ).y );
972  path->AppendPoint( mapPt( pos0 ) );
973 
974  // Generate holes as keepout:
975  for( int ii = 0; ii < outlines.HoleCount( cnt ); ii++ )
976  {
977  // emit a signal layers keepout for every interior polygon left...
978  KEEPOUT* keepout = new KEEPOUT( NULL, T_keepout );
979  PATH* poly_ko = new PATH( NULL, T_polygon );
980 
981  keepout->SetShape( poly_ko );
982  poly_ko->SetLayerId( "signal" );
983  m_pcb->structure->keepouts.push_back( keepout );
984 
985  SHAPE_LINE_CHAIN& hole = outlines.Hole( cnt, ii );
986 
987  for( int jj = 0; jj < hole.PointCount(); jj++ )
988  {
989  wxPoint pos( hole.CPoint( jj ).x, hole.CPoint( jj ).y );
990  poly_ko->AppendPoint( mapPt( pos ) );
991  }
992 
993  // Close polygon:
994  wxPoint pos( hole.CPoint( 0 ).x, hole.CPoint( 0 ).y );
995  poly_ko->AppendPoint( mapPt( pos ) );
996  }
997  }
998 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
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:1922
static POINT mapPt(const wxPoint &pt)
Convert a KiCad point into a DSN file point.
void SetLayerId(const char *aLayerId)
Definition: specctra.h:604
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:597
STRUCTURE * structure
Definition: specctra.h:3169
int PointCount() const
Function PointCount()
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:578
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void SetShape(ELEM *aShape)
Definition: specctra.h:940
#define NULL
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
KEEPOUT is used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:895
KEEPOUTS keepouts
Definition: specctra.h:1556

References _, DSN::PATH::AppendPoint(), SHAPE_LINE_CHAIN::CPoint(), BOARD::GetBoardPolygonOutlines(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), DSN::STRUCTURE::keepouts, m_pcb, DSN::mapPt(), NULL, 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

Function findLayerName returns the PCB layer index for a given layer name, within the specctra session file.

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

Definition at line 124 of file specctra.cpp.

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

References m_layerIds.

Referenced by makeTRACK(), and makeVIA().

◆ FlipFOOTPRINTs()

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

Function FlipFOOTPRINTs flips the footprints which are on the back side of the board to the front.

Definition at line 1775 of file specctra_export.cpp.

1776 {
1777  // DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the
1778  // top view.
1779  // Note: to export footprints, the footprints must be flipped around the X axis,
1780  // otherwise the rotation angle is not good
1781  for( FOOTPRINT* footprint : aBoard->Footprints() )
1782  {
1783  footprint->SetFlag( 0 );
1784 
1785  if( footprint->GetLayer() == B_Cu )
1786  {
1787  footprint->Flip( footprint->GetPosition(), false );
1788  footprint->SetFlag( 1 );
1789  }
1790  }
1791 
1792  m_footprintsAreFlipped = true;
1793 }
bool m_footprintsAreFlipped
Definition: specctra.h:3642
FOOTPRINTS & Footprints()
Definition: board.h:305

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

Referenced by PCB_EDIT_FRAME::ExportSpecctraFile().

◆ FromBOARD()

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

Function FromBOARD adds the entire BOARD to the PCB but does not write it out.

Note that the BOARD given to this function must have all the FOOTPRINTs on the component side of the BOARD.

See PCB_EDIT_FRAME::ExportToSpecctra() for an example before calling this function.

Parameters
aBoardThe BOARD to convert to a PCB.

Definition at line 1005 of file specctra_export.cpp.

1006 {
1007  PCB_TYPE_COLLECTOR items;
1008 
1009  static const KICAD_T scanMODULEs[] = { PCB_FOOTPRINT_T, EOT };
1010 
1011  // Not all boards are exportable. Check that all reference Ids are unique.
1012  // Unless they are unique, we cannot import the session file which comes
1013  // back to us later from the router.
1014  {
1015  items.Collect( aBoard, scanMODULEs );
1016 
1017  STRINGSET refs; // holds footprint reference designators
1018 
1019  for( int i=0; i<items.GetCount(); ++i )
1020  {
1021  FOOTPRINT* footprint = (FOOTPRINT*) items[i];
1022 
1023  if( footprint->GetReference() == wxEmptyString )
1024  {
1026  _( "Symbol with value of \"%s\" has empty reference id." ),
1027  footprint->GetValue() ) );
1028  }
1029 
1030  // if we cannot insert OK, that means the reference has been seen before.
1031  STRINGSET_PAIR refpair = refs.insert( TO_UTF8( footprint->GetReference() ) );
1032 
1033  if( !refpair.second ) // insert failed
1034  {
1036  _( "Multiple symbols have identical reference IDs of \"%s\"." ),
1037  footprint->GetReference() ) );
1038  }
1039  }
1040  }
1041 
1042  if( !m_pcb )
1044 
1045  //-----<layer_descriptor>-----------------------------------------------
1046  {
1047  // specctra wants top physical layer first, then going down to the
1048  // bottom most physical layer in physical sequence.
1049  // @question : why does KiCad not display layers in that order?
1050 
1051  buildLayerMaps( aBoard );
1052 
1053  int layerCount = aBoard->GetCopperLayerCount();
1054 
1055  for( int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
1056  {
1057  LAYER* layer = new LAYER( m_pcb->structure );
1058 
1059  m_pcb->structure->layers.push_back( layer );
1060 
1061  layer->name = m_layerIds[pcbNdx];
1062 
1063  DSN_T layerType;
1064 
1065  switch( aBoard->GetLayerType( m_pcbLayer2kicad[pcbNdx] ) )
1066  {
1067  default:
1068  case LT_SIGNAL: layerType = T_signal; break;
1069  case LT_POWER: layerType = T_power; break;
1070 
1071  // Freerouter does not support type "mixed", only signal and power.
1072  // Remap "mixed" to "signal".
1073  case LT_MIXED: layerType = T_signal; break;
1074  case LT_JUMPER: layerType = T_jumper; break;
1075  }
1076 
1077  layer->layer_type = layerType;
1078 
1079  layer->properties.push_back( PROPERTY() );
1080  PROPERTY* property = &layer->properties.back();
1081  property->name = "index";
1082  char temp[32];
1083  sprintf( temp, "%d", pcbNdx );
1084  property->value = temp;
1085  }
1086  }
1087 
1088  // a space in a quoted token is NOT a terminator, true establishes this.
1090 
1091  //-----<unit_descriptor> & <resolution_descriptor>--------------------
1092  {
1093  // tell freerouter to use "tenths of micrometers",
1094  // which is 100 nm resolution. Possibly more resolution is possible
1095  // in freerouter, but it would need testing.
1096 
1097  m_pcb->unit->units = T_um;
1098  m_pcb->resolution->units = T_um;
1099  m_pcb->resolution->value = 10; // tenths of a um
1100  }
1101 
1102  //-----<boundary_descriptor>------------------------------------------
1103  {
1104  // Because fillBOUNDARY() can throw an exception, we link in an
1105  // empty boundary so the BOUNDARY does not get lost in the event of
1106  // of an exception.
1107  BOUNDARY* boundary = new BOUNDARY( 0 );
1108 
1109  m_pcb->structure->SetBOUNDARY( boundary );
1110  fillBOUNDARY( aBoard, boundary );
1111  }
1112 
1113  //-----<rules>--------------------------------------------------------
1114  {
1115  char rule[80];
1116  NETCLASS* defaultClass = aBoard->GetDesignSettings().GetDefault();
1117 
1118  int defaultTrackWidth = defaultClass->GetTrackWidth();
1119  int defaultClearance = defaultClass->GetClearance();
1120 
1121  double clearance = scale( defaultClearance );
1122 
1123  STRINGS& rules = m_pcb->structure->rules->rules;
1124 
1125  sprintf( rule, "(width %.6g)", scale( defaultTrackWidth ) );
1126  rules.push_back( rule );
1127 
1128  sprintf( rule, "(clearance %.6g)", clearance + safetyMargin );
1129  rules.push_back( rule );
1130 
1131  // On a high density board (a board with 4 mil tracks, 4 mil spacing)
1132  // a typical solder mask clearance will be 2-3 mils.
1133  // This exposes 2 to 3 mils of bare board around each pad, and would
1134  // leave only 1 to 2 mils of solder mask between the solder mask's boundary
1135  // to the edge of any trace within "clearance" of the pad. So we need at least
1136  // 2 mils *extra* clearance for traces which would come near a pad on
1137  // a different net. So if the baseline trace to trace clearance was say 4 mils, then
1138  // the SMD to trace clearance should be at least 6 mils.
1139  double default_smd = clearance + safetyMargin;
1140 
1141  if( default_smd <= 6.0 )
1142  default_smd = 6.0;
1143 
1144  sprintf( rule, "(clearance %.6g (type default_smd))", default_smd );
1145 
1146  rules.push_back( rule );
1147 
1148  // Pad to pad spacing on a single SMT part can be closer than our
1149  // clearance, we don't want freerouter complaining about that, so
1150  // output a significantly smaller pad to pad clearance to freerouter.
1151  clearance = scale( defaultClearance ) / 4;
1152 
1153  sprintf( rule, "(clearance %.6g (type smd_smd))", clearance );
1154  rules.push_back( rule );
1155  }
1156 
1157  //-----<zones (not keepout areas) become planes>--------------------------------
1158  // Note: only zones are output here, keepout areas are created later.
1159  {
1160  int netlessZones = 0;
1161 
1162  static const KICAD_T scanZONEs[] = { PCB_ZONE_T, EOT };
1163  items.Collect( aBoard, scanZONEs );
1164 
1165  for( int i = 0; i<items.GetCount(); ++i )
1166  {
1167  ZONE* item = (ZONE*) items[i];
1168 
1169  if( item->GetIsRuleArea() )
1170  continue;
1171 
1172  // Currently, we export only copper layers
1173  if( ! IsCopperLayer( item->GetLayer() ) )
1174  continue;
1175 
1176  COPPER_PLANE* plane = new COPPER_PLANE( m_pcb->structure );
1177 
1178  m_pcb->structure->planes.push_back( plane );
1179 
1180  PATH* mainPolygon = new PATH( plane, T_polygon );
1181 
1182  plane->SetShape( mainPolygon );
1183 
1184  plane->name = TO_UTF8( item->GetNetname() );
1185 
1186  if( plane->name.size() == 0 )
1187  {
1188  char name[32];
1189 
1190  // This is one of those no connection zones, netcode=0, and it has no name.
1191  // Create a unique, bogus netname.
1192  NET* no_net = new NET( m_pcb->network );
1193 
1194  sprintf( name, "@:no_net_%d", netlessZones++ );
1195  no_net->net_id = name;
1196 
1197  // add the bogus net name to network->nets.
1198  m_pcb->network->nets.push_back( no_net );
1199 
1200  // use the bogus net name in the netless zone.
1201  plane->name = no_net->net_id;
1202  }
1203 
1204  mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1205 
1206  // Handle the main outlines
1207  SHAPE_POLY_SET::ITERATOR iterator;
1208  wxPoint startpoint;
1209  bool is_first_point = true;
1210 
1211  for( iterator = item->IterateWithHoles(); iterator; iterator++ )
1212  {
1213  wxPoint point( iterator->x, iterator->y );
1214 
1215  if( is_first_point )
1216  {
1217  startpoint = point;
1218  is_first_point = false;
1219  }
1220 
1221  mainPolygon->AppendPoint( mapPt( point ) );
1222 
1223  // this was the end of the main polygon
1224  if( iterator.IsEndContour() )
1225  {
1226  // Close polygon
1227  mainPolygon->AppendPoint( mapPt( startpoint ) );
1228  break;
1229  }
1230  }
1231 
1232  WINDOW* window = 0;
1233  PATH* cutout = 0;
1234 
1235  bool isStartContour = true;
1236 
1237  // handle the cutouts
1238  for( iterator++; iterator; iterator++ )
1239  {
1240  if( isStartContour )
1241  {
1242  is_first_point = true;
1243  window = new WINDOW( plane );
1244 
1245  plane->AddWindow( window );
1246 
1247  cutout = new PATH( window, T_polygon );
1248 
1249  window->SetShape( cutout );
1250 
1251  cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1252  }
1253 
1254  // If the point in this iteration is the last of the contour, the next iteration
1255  // will start with a new contour.
1256  isStartContour = iterator.IsEndContour();
1257 
1258  wxASSERT( window );
1259  wxASSERT( cutout );
1260 
1261  wxPoint point(iterator->x, iterator->y );
1262 
1263  if( is_first_point )
1264  {
1265  startpoint = point;
1266  is_first_point = false;
1267  }
1268 
1269  cutout->AppendPoint( mapPt( point ) );
1270 
1271  // Close the polygon
1272  if( iterator.IsEndContour() )
1273  cutout->AppendPoint( mapPt( startpoint ) );
1274  }
1275  }
1276  }
1277 
1278  //-----<zones flagged keepout areas become keepout>--------------------------------
1279  {
1280  static const KICAD_T scanZONEs[] = { PCB_ZONE_T, EOT };
1281  items.Collect( aBoard, scanZONEs );
1282 
1283  for( int i=0; i<items.GetCount(); ++i )
1284  {
1285  ZONE* item = (ZONE*) items[i];
1286 
1287  if( !item->GetIsRuleArea() )
1288  continue;
1289 
1290  // keepout areas have a type. types are
1291  // T_place_keepout, T_via_keepout, T_wire_keepout,
1292  // T_bend_keepout, T_elongate_keepout, T_keepout.
1293  // Pcbnew knows only T_keepout, T_via_keepout and T_wire_keepout
1294  DSN_T keepout_type;
1295 
1296  if( item->GetDoNotAllowVias() && item->GetDoNotAllowTracks() )
1297  keepout_type = T_keepout;
1298  else if( item->GetDoNotAllowVias() )
1299  keepout_type = T_via_keepout;
1300  else if( item->GetDoNotAllowTracks() )
1301  keepout_type = T_wire_keepout;
1302  else
1303  keepout_type = T_keepout;
1304 
1305  // Now, build keepout polygon on each copper layer where the item
1306  // keepout is living (keepout zones can live on many copper layers)
1307  const int copperCount = aBoard->GetCopperLayerCount();
1308 
1309  for( int layer = 0; layer < copperCount; layer++ )
1310  {
1311  if( layer == copperCount - 1 )
1312  layer = B_Cu;
1313 
1314  if( !item->IsOnLayer( PCB_LAYER_ID( layer ) ) )
1315  continue;
1316 
1317  KEEPOUT* keepout = new KEEPOUT( m_pcb->structure, keepout_type );
1318  m_pcb->structure->keepouts.push_back( keepout );
1319 
1320  PATH* mainPolygon = new PATH( keepout, T_polygon );
1321  keepout->SetShape( mainPolygon );
1322 
1323  mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ];
1324 
1325  // Handle the main outlines
1326  SHAPE_POLY_SET::ITERATOR iterator;
1327  bool is_first_point = true;
1328  wxPoint startpoint;
1329 
1330  for( iterator = item->IterateWithHoles(); iterator; iterator++ )
1331  {
1332  wxPoint point( iterator->x, iterator->y );
1333 
1334  if( is_first_point )
1335  {
1336  startpoint = point;
1337  is_first_point = false;
1338  }
1339 
1340  mainPolygon->AppendPoint( mapPt( point ) );
1341 
1342  // this was the end of the main polygon
1343  if( iterator.IsEndContour() )
1344  {
1345  mainPolygon->AppendPoint( mapPt( startpoint ) );
1346  break;
1347  }
1348  }
1349 
1350  WINDOW* window = nullptr;
1351  PATH* cutout = nullptr;
1352 
1353  bool isStartContour = true;
1354 
1355  // handle the cutouts
1356  for( iterator++; iterator; iterator++ )
1357  {
1358  if( isStartContour )
1359  {
1360  is_first_point = true;
1361  window = new WINDOW( keepout );
1362  keepout->AddWindow( window );
1363 
1364  cutout = new PATH( window, T_polygon );
1365 
1366  window->SetShape( cutout );
1367 
1368  cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1369  }
1370 
1371  isStartContour = iterator.IsEndContour();
1372 
1373  wxASSERT( window );
1374  wxASSERT( cutout );
1375 
1376  wxPoint point(iterator->x, iterator->y );
1377 
1378  if( is_first_point )
1379  {
1380  startpoint = point;
1381  is_first_point = false;
1382  }
1383 
1384  cutout->AppendPoint( mapPt(point) );
1385 
1386  // Close the polygon
1387  if( iterator.IsEndContour() )
1388  cutout->AppendPoint( mapPt( startpoint ) );
1389  }
1390  }
1391  }
1392  }
1393 
1394  //-----<build the images, components, and netlist>-----------------------
1395  {
1396  PIN_REF empty( m_pcb->network );
1397 
1398  std::string componentId;
1399 
1400  // find the highest numbered netCode within the board.
1401  int highestNetCode = 0;
1402  NETINFO_LIST& netInfo = aBoard->GetNetInfo();
1403 
1404  for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1405  highestNetCode = std::max( highestNetCode, i->GetNetCode() );
1406 
1407  deleteNETs();
1408 
1409  // expand the net vector to highestNetCode+1, setting empty to NULL
1410  m_nets.resize( highestNetCode + 1, NULL );
1411 
1412  for( unsigned i = 1 /* skip "No Net" at [0] */; i < m_nets.size(); ++i )
1413  m_nets[i] = new NET( m_pcb->network );
1414 
1415  for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1416  {
1417  if( i->GetNetCode() > 0 )
1418  m_nets[i->GetNetCode()]->net_id = TO_UTF8( i->GetNetname() );
1419  }
1420 
1421  items.Collect( aBoard, scanMODULEs );
1422 
1423  m_padstackset.clear();
1424 
1425  for( int m = 0; m<items.GetCount(); ++m )
1426  {
1427  FOOTPRINT* footprint = (FOOTPRINT*) items[m];
1428 
1429  IMAGE* image = makeIMAGE( aBoard, footprint );
1430 
1431  componentId = TO_UTF8( footprint->GetReference() );
1432 
1433  // create a net list entry for all the actual pins in the image
1434  // for the current footprint. location of this code is critical
1435  // because we fabricated some pin names to ensure unique-ness
1436  // of pin names within a footprint, do not move this code because
1437  // the life of this 'IMAGE* image' is not necessarily long. The
1438  // exported netlist will have some fabricated pin names in it.
1439  // If you don't like fabricated pin names, then make sure all pads
1440  // within your FOOTPRINTs are uniquely named!
1441  for( unsigned p = 0; p<image->pins.size(); ++p )
1442  {
1443  PIN* pin = &image->pins[p];
1444 
1445  int netcode = pin->kiNetCode;
1446 
1447  if( netcode > 0 )
1448  {
1449  NET* net = m_nets[netcode];
1450 
1451  net->pins.push_back( empty );
1452 
1453  PIN_REF& pin_ref = net->pins.back();
1454 
1455  pin_ref.component_id = componentId;
1456  pin_ref.pin_id = pin->pin_id;
1457  }
1458  }
1459 
1461 
1462  if( registered != image )
1463  {
1464  // If our new 'image' is not a unique IMAGE, delete it.
1465  // and use the registered one, known as 'image' after this.
1466  delete image;
1467  image = registered;
1468  }
1469 
1470  COMPONENT* comp = m_pcb->placement->LookupCOMPONENT( image->GetImageId() );
1471 
1472  PLACE* place = new PLACE( comp );
1473 
1474  comp->places.push_back( place );
1475 
1476  place->SetRotation( footprint->GetOrientationDegrees() );
1477  place->SetVertex( mapPt( footprint->GetPosition() ) );
1478  place->component_id = componentId;
1479  place->part_number = TO_UTF8( footprint->GetValue() );
1480 
1481  // footprint is flipped from bottom side, set side to T_back
1482  if( footprint->GetFlag() )
1483  {
1484  double angle = 180.0 - footprint->GetOrientationDegrees();
1486  place->SetRotation( angle );
1487 
1488  place->side = T_back;
1489  }
1490  }
1491 
1492  // copy the SPECCTRA_DB::padstackset to the LIBRARY. Since we are
1493  // removing, do not increment the iterator
1494  for( PADSTACKSET::iterator i = m_padstackset.begin(); i != m_padstackset.end();
1495  i = m_padstackset.begin() )
1496  {
1497  PADSTACKSET::auto_type ps = m_padstackset.release( i );
1498  PADSTACK* padstack = ps.release();
1499 
1500  m_pcb->library->AddPadstack( padstack );
1501  }
1502 
1503  // copy our SPECCTRA_DB::nets to the pcb->network
1504  for( unsigned n = 1; n < m_nets.size(); ++n )
1505  {
1506  NET* net = m_nets[n];
1507 
1508  if( net->pins.size() )
1509  {
1510  // give ownership to pcb->network
1511  m_pcb->network->nets.push_back( net );
1512  m_nets[n] = 0;
1513  }
1514  }
1515  }
1516 
1517  //-----< output vias used in netclasses >-----------------------------------
1518  {
1519  NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
1520 
1521  // Assume the netclass vias are all the same kind of thru, blind, or buried vias.
1522  // This is in lieu of either having each netclass via have its own layer pair in
1523  // the netclass dialog, or such control in the specctra export dialog.
1524 
1525 
1526  m_top_via_layer = 0; // first specctra cu layer is number zero.
1527  m_bot_via_layer = aBoard->GetCopperLayerCount()-1;
1528 
1529  // Add the via from the Default netclass first. The via container
1530  // in pcb->library preserves the sequence of addition.
1531 
1532  NETCLASSPTR netclass = nclasses.GetDefault();
1533 
1534  PADSTACK* via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
1536 
1537  // we AppendVia() this first one, there is no way it can be a duplicate,
1538  // the pcb->library via container is empty at this point. After this,
1539  // we'll have to use LookupVia().
1540  wxASSERT( m_pcb->library->vias.size() == 0 );
1541  m_pcb->library->AppendVia( via );
1542 
1543  // set the "spare via" index at the start of the
1544  // pcb->library->spareViaIndex = pcb->library->vias.size();
1545 
1546  // output the non-Default netclass vias
1547  for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
1548  {
1549  netclass = nc->second;
1550 
1551  via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
1553 
1554  // maybe add 'via' to the library, but only if unique.
1556 
1557  if( registered != via )
1558  delete via;
1559  }
1560  }
1561 
1562  //-----<create the wires from tracks>-----------------------------------
1563  {
1564  // export all of them for now, later we'll decide what controls we need
1565  // on this.
1566  static const KICAD_T scanTRACKs[] = { PCB_TRACE_T, EOT };
1567 
1568  items.Collect( aBoard, scanTRACKs );
1569 
1570  std::string netname;
1571  WIRING* wiring = m_pcb->wiring;
1572  PATH* path = 0;
1573 
1574  int old_netcode = -1;
1575  int old_width = -1;
1576  LAYER_NUM old_layer = UNDEFINED_LAYER;
1577 
1578  for( int i=0; i<items.GetCount(); ++i )
1579  {
1580  TRACK* track = (TRACK*) items[i];
1581 
1582  int netcode = track->GetNetCode();
1583 
1584  if( netcode == 0 )
1585  continue;
1586 
1587  if( old_netcode != netcode || old_width != track->GetWidth() ||
1588  old_layer != track->GetLayer() ||
1589  ( path && path->points.back() != mapPt(track->GetStart() ) ) )
1590  {
1591  old_width = track->GetWidth();
1592  old_layer = track->GetLayer();
1593 
1594  if( old_netcode != netcode )
1595  {
1596  old_netcode = netcode;
1597  NETINFO_ITEM* net = aBoard->FindNet( netcode );
1598  wxASSERT( net );
1599  netname = TO_UTF8( net->GetNetname() );
1600  }
1601 
1602  WIRE* wire = new WIRE( wiring );
1603 
1604  wiring->wires.push_back( wire );
1605  wire->net_id = netname;
1606 
1607  wire->wire_type = T_protect; // @todo, this should be configurable
1608 
1609  LAYER_NUM kiLayer = track->GetLayer();
1610  int pcbLayer = m_kicadLayer2pcb[kiLayer];
1611 
1612  path = new PATH( wire );
1613 
1614  wire->SetShape( path );
1615 
1616  path->layer_id = m_layerIds[pcbLayer];
1617  path->aperture_width = scale( old_width );
1618 
1619  path->AppendPoint( mapPt( track->GetStart() ) );
1620  }
1621 
1622  if( path ) // Should not occur
1623  path->AppendPoint( mapPt( track->GetEnd() ) );
1624  }
1625  }
1626 
1627  //-----<export the existing real BOARD instantiated vias>-----------------
1628  {
1629  // Export all vias, once per unique size and drill diameter combo.
1630  static const KICAD_T scanVIAs[] = { PCB_VIA_T, EOT };
1631 
1632  items.Collect( aBoard, scanVIAs );
1633 
1634  for( int i = 0; i<items.GetCount(); ++i )
1635  {
1636  ::VIA* via = (::VIA*) items[i];
1637  wxASSERT( via->Type() == PCB_VIA_T );
1638 
1639  int netcode = via->GetNetCode();
1640 
1641  if( netcode == 0 )
1642  continue;
1643 
1644  PADSTACK* padstack = makeVia( via );
1645  PADSTACK* registered = m_pcb->library->LookupVia( padstack );
1646 
1647  // if the one looked up is not our padstack, then delete our padstack
1648  // since it was a duplicate of one already registered.
1649  if( padstack != registered )
1650  {
1651  delete padstack;
1652  }
1653 
1654  WIRE_VIA* dsnVia = new WIRE_VIA( m_pcb->wiring );
1655 
1656  m_pcb->wiring->wire_vias.push_back( dsnVia );
1657 
1658  dsnVia->padstack_id = registered->padstack_id;
1659  dsnVia->vertexes.push_back( mapPt( via->GetPosition() ) );
1660 
1661  NETINFO_ITEM* net = aBoard->FindNet( netcode );
1662  wxASSERT( net );
1663 
1664  dsnVia->net_id = TO_UTF8( net->GetNetname() );
1665 
1666  dsnVia->via_type = T_protect; // @todo, this should be configurable
1667  }
1668  }
1669 
1670  //-----<via_descriptor>-------------------------------------------------
1671  {
1672  // The pcb->library will output <padstack_descriptors> which is a combined
1673  // list of part padstacks and via padstacks. specctra dsn uses the
1674  // <via_descriptors> to say which of those padstacks are vias.
1675 
1676  // Output the vias in the padstack list here, by name only. This must
1677  // be done after exporting existing vias as WIRE_VIAs.
1678  VIA* vias = m_pcb->structure->via;
1679 
1680  for( unsigned viaNdx = 0; viaNdx < m_pcb->library->vias.size(); ++viaNdx )
1681  {
1682  vias->AppendVia( m_pcb->library->vias[viaNdx].padstack_id.c_str() );
1683  }
1684  }
1685 
1686  //-----<output NETCLASSs>----------------------------------------------------
1687  NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
1688 
1689  exportNETCLASS( nclasses.GetDefault(), aBoard );
1690 
1691  for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
1692  {
1693  NETCLASSPTR netclass = nc->second;
1694  exportNETCLASS( netclass, aBoard );
1695  }
1696 }
DSN_T units
Definition: specctra.h:404
iterator end() const
Definition: netinfo.h:441
VIA corresponds to the <via_descriptor> in the specctra dsn spec.
Definition: specctra.h:1024
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1289
PIN_REF corresponds to the <pin_reference> definition in the specctra dsn spec.
Definition: specctra.h:2449
bool space_in_quoted_tokens
Definition: specctra.h:371
void buildLayerMaps(BOARD *aBoard)
Function buildLayerMaps creates a few data translation structures for layer name and number mapping b...
Definition: specctra.cpp:74
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:540
void exportNETCLASS(const std::shared_ptr< NETCLASS > &aNetClass, BOARD *aBoard)
Function exportNETCLASS exports aNetClass to the DSN file.
NET corresponds to a <net_descriptor> in the DSN spec.
Definition: specctra.h:2591
COPPER_PLANES planes
Definition: specctra.h:1558
const wxString & GetValue() const
Definition: footprint.h:448
std::string net_id
Definition: specctra.h:2595
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:730
std::string component_id
Definition: specctra.h:2451
Definition: board.h:67
RULE * rules
Definition: specctra.h:1554
static const double safetyMargin
const wxPoint & GetStart() const
Definition: track.h:116
bool GetDoNotAllowVias() const
Definition: zone.h:732
std::string part_number
Definition: specctra.h:1703
PADSTACKS vias
Definition: specctra.h:2259
static POINT mapPt(const wxPoint &pt)
Convert a KiCad point into a DSN file point.
IMAGE * LookupIMAGE(IMAGE *aImage)
Function LookupIMAGE will add the image only if one exactly like it does not already exist in the ima...
Definition: specctra.h:2337
static bool registered
Definition: coroutines.cpp:128
POINTS vertexes
Definition: specctra.h:2988
void fillBOUNDARY(BOARD *aBoard, BOUNDARY *aBoundary)
Function fillBOUNDARY makes the board perimeter for the DSN file by filling the BOUNDARY element in t...
UNIT_RES * resolution
Definition: specctra.h:3167
wxString GetNetname() const
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3646
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:314
IMAGE * makeIMAGE(BOARD *aBoard, FOOTPRINT *aFootprint)
Function makeIMAGE allocates an IMAGE on the heap and creates all the PINs according to the PADs in t...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:754
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:597
iterator end()
Definition: netclass.h:236
PLACES places
Definition: specctra.h:1761
void NORMALIZE_ANGLE_DEGREES_POS(double &Angle)
Definition: trigo.h:306
STRUCTURE * structure
Definition: specctra.h:3169
WIRING * wiring
Definition: specctra.h:3173
static PCB * MakePCB()
Function MakePCB makes a PCB with all the default ELEMs and parts on the heap.
Definition: specctra.cpp:3467
std::string net_id
Definition: specctra.h:2989
std::string layer_id
Definition: specctra.h:582
DSN_T via_type
Definition: specctra.h:2991
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:1733
std::set< std::string > STRINGSET
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void SetShape(ELEM *aShape)
Definition: specctra.h:861
Definition: board.h:68
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:578
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:3662
#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:1191
NETCLASS_MAP::iterator iterator
Definition: netclass.h:234
void SetShape(ELEM *aShape)
Definition: specctra.h:940
WIRES wires
Definition: specctra.h:3124
int GetFlag() const
Definition: footprint.h:236
PCB_LAYER_ID
A quick note on layer IDs:
int GetTrackWidth() const
Definition: netclass.h:128
std::vector< int > m_kicadLayer2pcb
maps BOARD layer number to PCB layer numbers
Definition: specctra.h:3648
iterator begin()
Definition: netclass.h:235
A container for NETCLASS instances.
Definition: netclass.h:218
std::string name
Definition: specctra.h:1190
#define NULL
void AddWindow(WINDOW *aWindow)
Definition: specctra.h:957
COPPER_PLANE corresponds to a <plane_descriptor> in the specctra dsn spec.
Definition: specctra.h:1338
void deleteNETs()
Function deleteNETs deletes all the NETs that may be in here.
Definition: specctra.h:3830
Container for NETINFO_ITEM elements, which are the nets.
Definition: netinfo.h:315
std::string padstack_id
Definition: specctra.h:2987
DSN_T side
Definition: specctra.h:1680
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: zone.cpp:216
iterator begin() const
Definition: netinfo.h:436
PLACE implements the <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1674
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:46
bool GetDoNotAllowTracks() const
Definition: zone.h:733
const wxString & GetNetname() const
Definition: netinfo.h:119
void AddPadstack(PADSTACK *aPadstack)
Definition: specctra.h:2274
const wxString & GetReference() const
Definition: footprint.h:426
std::string component_id
reference designator
Definition: specctra.h:1678
PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2114
NETCLASSES & GetNetClasses() const
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
WIRE_VIAS wire_vias
Definition: specctra.h:3125
class ZONE, a copper pour area
Definition: typeinfo.h:105
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:3665
std::vector< std::string > STRINGS
Definition: specctra.h:157
COMPONENT * LookupCOMPONENT(const std::string &imageName)
Function LookupCOMPONENT looks up a COMPONENT by name.
Definition: specctra.h:1832
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:605
PARSER * parser
Definition: specctra.h:3166
This item represents a net.
void SetRotation(double aRotation)
Definition: specctra.h:1740
int LAYER_NUM
This can be replaced with int and removed.
LIBRARY * library
Definition: specctra.h:3171
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:376
double GetOrientationDegrees() const
Definition: footprint.h:187
Handle the data for a net.
Definition: netinfo.h:64
PADSTACK * LookupVia(PADSTACK *aVia)
Function LookupVia will add the via only if one exactly like it does not already exist in the padstac...
Definition: specctra.h:2392
COMPONENT implements the <component_descriptor> in the specctra dsn spec.
Definition: specctra.h:1754
std::vector< PCB_LAYER_ID > m_pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
Definition: specctra.h:3649
int GetWidth() const
Definition: track.h:110
WIRE corresponds to <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2873
const char * name
Definition: DXF_plotter.cpp:59
void AppendVia(PADSTACK *aVia)
Function AppendVia adds aVia to the internal via container.
Definition: specctra.h:2367
#define _(s)
Definition: 3d_actions.cpp:33
int GetClearance() const
Definition: netclass.h:124
PLACEMENT * placement
Definition: specctra.h:3170
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:435
NETCLASS * GetDefault() const
void SetShape(ELEM *aShape)
Definition: specctra.h:2914
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:1595
wxPoint GetPosition() const override
Definition: footprint.h:182
const wxPoint & GetEnd() const
Definition: track.h:113
void AppendVia(const char *aViaName)
Definition: specctra.h:1038
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
UNIT_RES * unit
Definition: specctra.h:3168
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
LAYERS layers
Definition: specctra.h:1546
PIN_REFS pins
Definition: specctra.h:2600
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
WIRE_VIA corresponds to <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2983
std::string pin_id
Definition: specctra.h:2452
DSN_T wire_type
Definition: specctra.h:2888
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition: collectors.h:618
PROPERTIES properties
Definition: specctra.h:1198
PADSTACKSET m_padstackset
Definition: specctra.h:3659
KEEPOUT is used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:895
std::string name
Definition: specctra.h:900
NETWORK * network
Definition: specctra.h:3172
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
WIRING corresponds to <wiring_descriptor> in the specctra dsn spec.
Definition: specctra.h:3119
Definition: track.h:83
std::string net_id
Definition: specctra.h:2886
PADSTACK * makeVia(int aCopperDiameter, int aDrillDiameter, int aTopLayer, int aBotLayer)
Function makeVia makes 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:492
KEEPOUTS keepouts
Definition: specctra.h:1556

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(), TRACK::GetEnd(), FOOTPRINT::GetFlag(), ZONE::GetIsRuleArea(), ZONE::GetLayer(), BOARD_ITEM::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(), TRACK::GetStart(), NETCLASS::GetTrackWidth(), FOOTPRINT::GetValue(), 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(), NULL, DSN::WIRE_VIA::padstack_id, DSN::PCB::parser, DSN::PLACE::part_number, path, 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 PCB_EDIT_FRAME::ExportSpecctraFile().

◆ FromSESSION()

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

Function FromSESSION adds 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 319 of file specctra_import.cpp.

320 {
321  m_sessionBoard = aBoard; // not owned here
322 
323  if( !m_session )
324  THROW_IO_ERROR( _("Session file is missing the \"session\" section") );
325 
326  if( !m_session->route )
327  THROW_IO_ERROR( _("Session file is missing the \"routes\" section") );
328 
329  if( !m_session->route->library )
330  THROW_IO_ERROR( _("Session file is missing the \"library_out\" section") );
331 
332  // delete all the old tracks and vias
333  aBoard->Tracks().clear();
334 
335  aBoard->DeleteMARKERs();
336 
337  buildLayerMaps( aBoard );
338 
339  if( m_session->placement )
340  {
341  // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
342  // each COMPONENT, reposition and re-orient each component and put on
343  // correct side of the board.
344  COMPONENTS& components = m_session->placement->components;
345  for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp )
346  {
347  PLACES& places = comp->places;
348  for( unsigned i=0; i<places.size(); ++i )
349  {
350  PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
351 
352  wxString reference = FROM_UTF8( place->component_id.c_str() );
353  FOOTPRINT* footprint = aBoard->FindFootprintByReference( reference );
354 
355  if( !footprint )
356  {
357  THROW_IO_ERROR( wxString::Format( _( "Reference '%s' not found." ),
358  reference ) );
359  }
360 
361  if( !place->hasVertex )
362  continue;
363 
364  UNIT_RES* resolution = place->GetUnits();
365  wxASSERT( resolution );
366 
367  wxPoint newPos = mapPt( place->vertex, resolution );
368  footprint->SetPosition( newPos );
369 
370  if( place->side == T_front )
371  {
372  // convert from degrees to tenths of degrees used in KiCad.
373  int orientation = KiROUND( place->rotation * 10.0 );
374 
375  if( footprint->GetLayer() != F_Cu )
376  {
377  // footprint is on copper layer (back)
378  footprint->Flip( footprint->GetPosition(), false );
379  }
380 
381  footprint->SetOrientation( orientation );
382  }
383  else if( place->side == T_back )
384  {
385  int orientation = KiROUND( (place->rotation + 180.0) * 10.0 );
386 
387  if( footprint->GetLayer() != B_Cu )
388  {
389  // footprint is on component layer (front)
390  footprint->Flip( footprint->GetPosition(), false );
391  }
392 
393  footprint->SetOrientation( orientation );
394  }
395  else
396  {
397  // as I write this, the PARSER *is* catching this, so we should never see below:
398  wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") );
399  }
400  }
401  }
402  }
403 
405 
406  // Walk the NET_OUTs and create tracks and vias anew.
407  NET_OUTS& net_outs = m_session->route->net_outs;
408  for( NET_OUTS::iterator net = net_outs.begin(); net!=net_outs.end(); ++net )
409  {
410  int netoutCode = 0;
411 
412  // page 143 of spec says wire's net_id is optional
413  if( net->net_id.size() )
414  {
415  wxString netName = FROM_UTF8( net->net_id.c_str() );
416  NETINFO_ITEM* netinfo = aBoard->FindNet( netName );
417 
418  if( netinfo )
419  {
420  netoutCode = netinfo->GetNetCode();
421  }
422  else // else netCode remains 0
423  {
424  // int breakhere = 1;
425  }
426  }
427 
428  WIRES& wires = net->wires;
429  for( unsigned i = 0; i<wires.size(); ++i )
430  {
431  WIRE* wire = &wires[i];
432  DSN_T shape = wire->shape->Type();
433 
434  if( shape != T_path )
435  {
436  /* shape == T_polygon is expected from freerouter if you have
437  a zone on a non "power" type layer, i.e. a T_signal layer
438  and the design does a round trip back in as session here.
439  We kept our own zones in the BOARD, so ignore this so called
440  'wire'.
441 
442  wxString netId = FROM_UTF8( wire->net_id.c_str() );
443  THROW_IO_ERROR( wxString::Format( _("Unsupported wire shape: \"%s\" for net: \"%s\""),
444  DLEX::GetTokenString(shape).GetData(),
445  netId.GetData()
446  ) );
447  */
448  }
449  else
450  {
451  PATH* path = (PATH*) wire->shape;
452  for( unsigned pt=0; pt<path->points.size()-1; ++pt )
453  {
454  TRACK* track = makeTRACK( path, pt, netoutCode );
455  aBoard->Add( track );
456  }
457  }
458  }
459 
460  WIRE_VIAS& wire_vias = net->wire_vias;
462  for( unsigned i=0; i<wire_vias.size(); ++i )
463  {
464  int netCode = 0;
465 
466  // page 144 of spec says wire_via's net_id is optional
467  if( net->net_id.size() )
468  {
469  wxString netName = FROM_UTF8( net->net_id.c_str() );
470  NETINFO_ITEM* netvia = aBoard->FindNet( netName );
471 
472  if( netvia )
473  netCode = netvia->GetNetCode();
474 
475  // else netCode remains 0
476  }
477 
478  WIRE_VIA* wire_via = &wire_vias[i];
479 
480  // example: (via Via_15:8_mil 149000 -71000 )
481 
482  PADSTACK* padstack = library.FindPADSTACK( wire_via->GetPadstackId() );
483  if( !padstack )
484  {
485  // Dick Feb 29, 2008:
486  // Freerouter has a bug where it will not round trip all vias.
487  // Vias which have a (use_via) element will be round tripped.
488  // Vias which do not, don't come back in in the session library,
489  // even though they may be actually used in the pre-routed,
490  // protected wire_vias. So until that is fixed, create the
491  // padstack from its name as a work around.
492 
493 
494  // Could use a STRING_FORMATTER here and convert the entire
495  // wire_via to text and put that text into the exception.
496  wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) );
497 
499  _( "A wire_via references a missing padstack \"%s\"" ), psid ) );
500  }
501 
502  NETCLASSPTR netclass = aBoard->GetDesignSettings().GetNetClasses().GetDefault();
503 
504  int via_drill_default = netclass->GetViaDrill();
505 
506  for( unsigned v=0; v<wire_via->vertexes.size(); ++v )
507  {
508  ::VIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode, via_drill_default );
509  aBoard->Add( via );
510  }
511  }
512  }
513 }
VIA corresponds to the <via_descriptor> in the specctra dsn spec.
Definition: specctra.h:1024
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1289
TRACK * makeTRACK(PATH *aPath, int aPointIndex, int aNetcode)
Function makeTRACK creates a TRACK form the PATH and BOARD info.
void buildLayerMaps(BOARD *aBoard)
Function buildLayerMaps creates a few data translation structures for layer name and number mapping b...
Definition: specctra.cpp:74
BOARD * m_sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3655
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:3112
NET_OUTS net_outs
Definition: specctra.h:3448
static POINT mapPt(const wxPoint &pt)
Convert a KiCad point into a DSN file point.
POINTS vertexes
Definition: specctra.h:2988
UNIT_RES is a holder for either a T_unit or T_resolution object which are usually mutually exclusive ...
Definition: specctra.h:400
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
boost::ptr_vector< NET_OUT > NET_OUTS
Definition: specctra.h:3437
POINT vertex
Definition: specctra.h:1685
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:578
double rotation
Definition: specctra.h:1682
bool hasVertex
Definition: specctra.h:1684
ELEM * shape
Definition: specctra.h:2884
UNIT_RES * GetUnits() const override
Function GetUnits returns the units for this section.
Definition: specctra.h:3470
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:563
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:781
DSN_T side
Definition: specctra.h:1680
PLACE implements the <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1674
LIBRARY * library
Definition: specctra.h:3447
::VIA * makeVIA(PADSTACK *aPadstack, const POINT &aPoint, int aNetCode, int aViaDrillDefault)
Function makeVIA instantiates a KiCad VIA on the heap and initializes it with internal values consist...
std::string component_id
reference designator
Definition: specctra.h:1678
PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2114
NETCLASSES & GetNetClasses() const
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:3652
PLACEMENT * placement
Definition: specctra.h:3568
const std::string & GetPadstackId()
Definition: specctra.h:3008
Handle the data for a net.
Definition: netinfo.h:64
LIBRARY corresponds to the <library_descriptor> in the specctra dsn specification.
Definition: specctra.h:2251
WIRE corresponds to <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2873
boost::ptr_vector< PLACE > PLACES
Definition: specctra.h:1747
DSN_T Type() const
Definition: specctra.h:230
#define _(s)
Definition: 3d_actions.cpp:33
SESSION * m_session
Definition: specctra.h:3638
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:68
ROUTE * route
Definition: specctra.h:3570
virtual UNIT_RES * GetUnits() const
Function GetUnits returns the units for this section.
Definition: specctra.cpp:3510
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2976
WIRE_VIA corresponds to <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2983
boost::ptr_vector< COMPONENT > COMPONENTS
Definition: pcb_netlist.h:198
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
COMPONENTS components
Definition: specctra.h:1810
TRACKS & Tracks()
Definition: board.h:302
Definition: track.h:83
FOOTPRINT * FindFootprintByReference(const wxString &aReference) const
Search for a FOOTPRINT within this board with the given reference designator.
Definition: board.cpp:1310
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 3909 of file specctra.h.

3909 { return m_pcb; }

References m_pcb.

Referenced by main().

◆ GetSESSION()

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

Definition at line 3920 of file specctra.h.

3920 { return m_session; }
SESSION * m_session
Definition: specctra.h:3638

References m_session.

Referenced by main().

◆ LoadPCB()

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

Function LoadPCB is 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 243 of file specctra.cpp.

244 {
245  FILE_LINE_READER curr_reader( aFilename );
246 
247  PushReader( &curr_reader );
248 
249  if( NextTok() != T_LEFT )
250  Expecting( T_LEFT );
251 
252  if( NextTok() != T_pcb )
253  Expecting( T_pcb );
254 
255  SetPCB( new PCB() );
256 
257  doPCB( m_pcb );
258  PopReader();
259 }
void SetPCB(PCB *aPcb)
Function SetPCB deletes any existing PCB and replaces it with the given one.
Definition: specctra.h:3904
A LINE_READER that reads from an open file.
Definition: richio.h:172
void doPCB(PCB *growth)
Definition: specctra.cpp:282

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

◆ LoadSESSION()

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

Function LoadSESSION is 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 262 of file specctra.cpp.

263 {
264  FILE_LINE_READER curr_reader( aFilename );
265 
266  PushReader( &curr_reader );
267 
268  if( NextTok() != T_LEFT )
269  Expecting( T_LEFT );
270 
271  if( NextTok() != T_session )
272  Expecting( T_session );
273 
274  SetSESSION( new SESSION() );
275 
276  doSESSION( m_session );
277 
278  PopReader();
279 }
void SetSESSION(SESSION *aSession)
Function SetSESSION deletes any existing SESSION and replaces it with the given one.
Definition: specctra.h:3915
A LINE_READER that reads from an open file.
Definition: richio.h:172
SESSION * m_session
Definition: specctra.h:3638
void doSESSION(SESSION *growth)
Definition: specctra.cpp:3137

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

Function makeIMAGE allocates an IMAGE 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
IMAGE* - not tested for duplication yet.

Definition at line 597 of file specctra_export.cpp.

598 {
599  PINMAP pinmap;
600  wxString padName;
601 
602  PCB_TYPE_COLLECTOR fpItems;
603 
604  // get all the FOOTPRINT's pads.
605  fpItems.Collect( aFootprint, scanPADs );
606 
607  IMAGE* image = new IMAGE( 0 );
608 
609  image->image_id = aFootprint->GetFPID().Format().c_str();
610 
611  // from the pads, and make an IMAGE using collated padstacks.
612  for( int p=0; p < fpItems.GetCount(); ++p )
613  {
614  PAD* pad = (PAD*) fpItems[p];
615 
616  // see if this pad is a through hole with no copper on its perimeter
617  if( isRoundKeepout( pad ) )
618  {
619  double diameter = scale( pad->GetDrillSize().x );
620  POINT vertex = mapPt( pad->GetPos0() );
621 
622  int layerCount = aBoard->GetCopperLayerCount();
623 
624  for( int layer=0; layer<layerCount; ++layer )
625  {
626  KEEPOUT* keepout = new KEEPOUT( image, T_keepout );
627 
628  image->keepouts.push_back( keepout );
629 
630  CIRCLE* circle = new CIRCLE( keepout );
631 
632  keepout->SetShape( circle );
633 
634  circle->SetDiameter( diameter );
635  circle->SetVertex( vertex );
636  circle->SetLayerId( m_layerIds[layer].c_str() );
637  }
638  }
639  // else if() could there be a square keepout here?
640 
641  else
642  {
643  // Pads not on copper layers (i.e. only on tech layers) are ignored
644  // because they create invalid pads in .dsn file for freeroute
645  LSET mask_copper_layers = pad->GetLayerSet() & LSET::AllCuMask();
646 
647  if( !mask_copper_layers.any() )
648  continue;
649 
650  PADSTACK* padstack = makePADSTACK( aBoard, pad );
651  PADSTACKSET::iterator iter = m_padstackset.find( *padstack );
652 
653  if( iter != m_padstackset.end() )
654  {
655  // padstack is a duplicate, delete it and use the original
656  delete padstack;
657  padstack = (PADSTACK*) *iter.base(); // folklore, be careful here
658  }
659  else
660  {
661  m_padstackset.insert( padstack );
662  }
663 
664  PIN* pin = new PIN( image );
665 
666  padName = pad->GetName();
667  pin->pin_id = TO_UTF8( padName );
668 
669  if( padName != wxEmptyString && pinmap.find( padName ) == pinmap.end() )
670  {
671  pinmap[ padName ] = 0;
672  }
673  else // pad name is a duplicate within this footprint
674  {
675  char buf[32];
676 
677  int duplicates = ++pinmap[ padName ];
678 
679  sprintf( buf, "@%d", duplicates );
680 
681  pin->pin_id += buf; // append "@1" or "@2", etc. to pin name
682  }
683 
684  pin->kiNetCode = pad->GetNetCode();
685 
686  image->pins.push_back( pin );
687 
688  pin->padstack_id = padstack->padstack_id;
689 
690  double angle = pad->GetOrientationDegrees() - aFootprint->GetOrientationDegrees();
692  pin->SetRotation( angle );
693 
694  wxPoint pos( pad->GetPos0() );
695 
696  pin->SetVertex( mapPt( pos ) );
697  }
698  }
699 
700  static const KICAD_T scanEDGEs[] = { PCB_FP_SHAPE_T, EOT };
701 
702  // get all the FOOTPRINT's FP_SHAPEs and convert those to DSN outlines.
703  fpItems.Collect( aFootprint, scanEDGEs );
704 
705  for( int i = 0; i < fpItems.GetCount(); ++i )
706  {
707  FP_SHAPE* graphic = (FP_SHAPE*) fpItems[i];
708  SHAPE* outline;
709  PATH* path;
710 
711  switch( graphic->GetShape() )
712  {
713  case S_SEGMENT:
714  outline = new SHAPE( image, T_outline );
715 
716  image->Append( outline );
717  path = new PATH( outline );
718 
719  outline->SetShape( path );
720  path->SetAperture( scale( graphic->GetWidth() ) );
721  path->SetLayerId( "signal" );
722  path->AppendPoint( mapPt( graphic->GetStart0() ) );
723  path->AppendPoint( mapPt( graphic->GetEnd0() ) );
724  break;
725 
726  case S_CIRCLE:
727  {
728  // this is best done by 4 QARC's but freerouter does not yet support QARCs.
729  // for now, support by using line segments.
730 
731  outline = new SHAPE( image, T_outline );
732 
733  image->Append( outline );
734  path = new PATH( outline );
735 
736  outline->SetShape( path );
737  path->SetAperture( scale( graphic->GetWidth() ) );
738  path->SetLayerId( "signal" );
739 
740  // Do the math using KiCad units, that way we stay out of the
741  // scientific notation range of floating point numbers in the
742  // DSN file. We do not parse scientific notation in our own
743  // lexer/beautifier, and the spec is not clear that this is
744  // required. Fixed point floats are all that should be needed.
745 
746  double radius = GetLineLength( graphic->GetStart(), graphic->GetEnd() );
747 
748  // seg count to approximate circle by line segments
749  int seg_per_circle = GetArcToSegmentCount( radius, ARC_LOW_DEF, 360.0 );
750 
751  for( int ii = 0; ii < seg_per_circle; ++ii )
752  {
753  double radians = 2*M_PI / seg_per_circle * ii;
754  wxPoint point( KiROUND( radius * cos( radians ) ),
755  KiROUND( radius * sin( radians ) ) );
756 
757  point += graphic->m_Start0; // an offset
758 
759  path->AppendPoint( mapPt( point ) );
760  }
761  // The shape must be closed
762  wxPoint point( radius , 0 );
763  point += graphic->m_Start0;
764  path->AppendPoint( mapPt( point ) );
765  }
766  break;
767 
768  case S_RECT:
769  case S_ARC:
770  default:
771  continue;
772  }
773  }
774 
775  for( FP_ZONE* zone : aFootprint->Zones() )
776  {
777  if( !zone->GetIsRuleArea() )
778  continue;
779 
780  // IMAGE object coordinates are relative to the IMAGE not absolute board coordinates.
781  ZONE untransformedZone( *zone );
782 
783  double angle = -aFootprint->GetOrientation();
785  untransformedZone.Rotate( aFootprint->GetPosition(), angle );
786 
787  // keepout areas have a type. types are
788  // T_place_keepout, T_via_keepout, T_wire_keepout,
789  // T_bend_keepout, T_elongate_keepout, T_keepout.
790  // Pcbnew knows only T_keepout, T_via_keepout and T_wire_keepout
791  DSN_T keepout_type;
792 
793  if( zone->GetDoNotAllowVias() && zone->GetDoNotAllowTracks() )
794  keepout_type = T_keepout;
795  else if( zone->GetDoNotAllowVias() )
796  keepout_type = T_via_keepout;
797  else if( zone->GetDoNotAllowTracks() )
798  keepout_type = T_wire_keepout;
799  else
800  keepout_type = T_keepout;
801 
802  // Now, build keepout polygon on each copper layer where the zone
803  // keepout is living (keepout zones can live on many copper layers)
804  const int copperCount = aBoard->GetCopperLayerCount();
805 
806  for( int layer = 0; layer < copperCount; layer++ )
807  {
808  if( layer == copperCount-1 )
809  layer = B_Cu;
810 
811  if( !zone->IsOnLayer( PCB_LAYER_ID( layer ) ) )
812  continue;
813 
814  KEEPOUT* keepout = new KEEPOUT( m_pcb->structure, keepout_type );
815  image->keepouts.push_back( keepout );
816 
817  PATH* mainPolygon = new PATH( keepout, T_polygon );
818  keepout->SetShape( mainPolygon );
819 
820  mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ];
821 
822  // Handle the main outlines
823  SHAPE_POLY_SET::ITERATOR iterator;
824  bool is_first_point = true;
825  wxPoint startpoint;
826 
827  for( iterator = untransformedZone.IterateWithHoles(); iterator; iterator++ )
828  {
829  wxPoint point( iterator->x, iterator->y );
830 
831  point -= aFootprint->GetPosition();
832 
833  if( is_first_point )
834  {
835  startpoint = point;
836  is_first_point = false;
837  }
838 
839  mainPolygon->AppendPoint( mapPt( point ) );
840 
841  // this was the end of the main polygon
842  if( iterator.IsEndContour() )
843  {
844  mainPolygon->AppendPoint( mapPt( startpoint ) );
845  break;
846  }
847  }
848 
849  WINDOW* window = nullptr;
850  PATH* cutout = nullptr;
851  bool isStartContour = true;
852 
853  // handle the cutouts
854  for( iterator++; iterator; iterator++ )
855  {
856  if( isStartContour )
857  {
858  is_first_point = true;
859  window = new WINDOW( keepout );
860  keepout->AddWindow( window );
861 
862  cutout = new PATH( window, T_polygon );
863 
864  window->SetShape( cutout );
865 
866  cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ zone->GetLayer() ] ];
867  }
868 
869  isStartContour = iterator.IsEndContour();
870 
871  wxASSERT( window );
872  wxASSERT( cutout );
873 
874  wxPoint point( iterator->x, iterator->y );
875 
876  point -= aFootprint->GetPosition();
877 
878  if( is_first_point )
879  {
880  startpoint = point;
881  is_first_point = false;
882  }
883 
884  cutout->AppendPoint( mapPt( point ) );
885 
886  // Close the polygon
887  if( iterator.IsEndContour() )
888  cutout->AppendPoint( mapPt( startpoint ) );
889  }
890  }
891  }
892 
893  return image;
894 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
DSN::T DSN_T
Definition: specctra.h:46
std::map< wxString, int > PINMAP
data type used to ensure unique-ness of pin names, holding (wxString and int)
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:223
static bool isRoundKeepout(PAD *aPad)
Decide if the pad is a copper-less through hole which needs to be made into a round keepout.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:156