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 3605 of file specctra.h.

Constructor & Destructor Documentation

◆ SPECCTRA_DB()

DSN::SPECCTRA_DB::SPECCTRA_DB ( )
inline

Definition at line 3838 of file specctra.h.

3838  :
3839  SPECCTRA_LEXER( 0 ) // LINE_READER* == NULL, no DSNLEXER::PushReader()
3840  {
3841  // The LINE_READER will be pushed from an automatic instantiation,
3842  // we don't own it:
3843  wxASSERT( !iOwnReaders );
3844 
3845  m_pcb = 0;
3846  m_session = 0;
3847  m_quote_char += '"';
3848  m_footprintsAreFlipped = false;
3849 
3850  SetSpecctraMode( true );
3851 
3852  // Avoid not initialized members:
3854  m_sessionBoard = NULL;
3855  m_top_via_layer = 0;
3856  m_bot_via_layer = 0;
3857  }
BOARD * m_sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3628
bool m_footprintsAreFlipped
Definition: specctra.h:3615
#define NULL
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:3638
UNIT_RES * m_routeResolution
used during FromSESSION() only, memory for it is not owned here.
Definition: specctra.h:3625
SESSION * m_session
Definition: specctra.h:3611
std::string m_quote_char
Definition: specctra.h:3613

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 3859 of file specctra.h.

3860  {
3861  delete m_pcb;
3862  delete m_session;
3863 
3864  deleteNETs();
3865  }
void deleteNETs()
Function deleteNETs deletes all the NETs that may be in here.
Definition: specctra.h:3803
SESSION * m_session
Definition: specctra.h:3611

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:343
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3619
#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:3621
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:3622
#define FIRST_LAYER
int GetCopperLayerCount() const
Definition: board.cpp:436
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:898

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 3803 of file specctra.h.

3804  {
3805  for( unsigned n=0; n < m_nets.size(); ++n )
3806  delete m_nets[n];
3807 
3808  m_nets.clear();
3809  }
std::vector< NET * > m_nets
we don't want ownership here permanently, so we don't use boost::ptr_vector
Definition: specctra.h:3635

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(), 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:3613

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, 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, 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:2458
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:3613

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
COMPONENT is used to store components and all of their related information found in a netlist.
Definition: pcb_netlist.h:85
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:3613

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:75
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(), 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:75

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 1661 of file specctra_export.cpp.

1662 {
1663  /* From page 11 of specctra spec:
1664  *
1665  * Routing and Placement Rule Hierarchies
1666  *
1667  * Routing and placement rules can be defined at multiple levels of design
1668  * specification. When a routing or placement rule is defined for an object at
1669  * multiple levels, a predefined routing or placement precedence order
1670  * automatically determines which rule to apply to the object. The routing rule
1671  * precedence order is
1672  *
1673  * pcb < layer < class < class layer < group_set < group_set layer < net <
1674  * net layer < group < group layer < fromto < fromto layer < class_class <
1675  * class_class layer < padstack < region < class region < net region <
1676  * class_class region
1677  *
1678  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1679  * hierarchy. A class-to-class region rule has the highest precedence. Rules
1680  * set at one level of the hierarchy override conflicting rules set at lower
1681  * levels. The placement rule precedence order is
1682  *
1683  * pcb < image_set < image < component < super cluster < room <
1684  * room_image_set < family_family < image_image
1685  *
1686  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1687  * hierarchy. An image-to-image rule has the highest precedence. Rules set at
1688  * one level of the hierarchy override conflicting rules set at lower levels.
1689  */
1690 
1691  char text[256];
1692 
1693  CLASS* clazz = new CLASS( m_pcb->network );
1694 
1695  m_pcb->network->classes.push_back( clazz );
1696 
1697  // freerouter creates a class named 'default' anyway, and if we
1698  // try and use that, we end up with two 'default' via rules so use
1699  // something else as the name of our default class.
1700  clazz->class_id = TO_UTF8( aNetClass->GetName() );
1701 
1702  for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net )
1703  clazz->net_ids.push_back( TO_UTF8( *net ) );
1704 
1705  clazz->rules = new RULE( clazz, T_rule );
1706 
1707  // output the track width.
1708  int trackWidth = aNetClass->GetTrackWidth();
1709  sprintf( text, "(width %.6g)", scale( trackWidth ) );
1710  clazz->rules->rules.push_back( text );
1711 
1712  // output the clearance.
1713  int clearance = aNetClass->GetClearance();
1714  sprintf( text, "(clearance %.6g)", scale( clearance ) + safetyMargin );
1715  clazz->rules->rules.push_back( text );
1716 
1717  if( aNetClass->GetName() == NETCLASS::Default )
1718  {
1719  clazz->class_id = "kicad_default";
1720  }
1721 
1722  // the easiest way to get the via name is to create a via (which generates
1723  // the name internal to the PADSTACK), and then grab the name and then
1724  // delete the via. There are not that many netclasses so
1725  // this should never become a performance issue.
1726 
1727  PADSTACK* via = makeVia( aNetClass->GetViaDiameter(), aNetClass->GetViaDrill(),
1729 
1730  snprintf( text, sizeof(text), "(use_via %s)", via->GetPadstackId().c_str() );
1731  clazz->circuit.push_back( text );
1732 
1733  delete via;
1734 }
STRINGS circuit
circuit descriptor list
Definition: specctra.h:2729
static const double safetyMargin
CLASS corresponds to the <class_descriptor> in the specctra spec.
Definition: specctra.h:2720
std::string class_id
Definition: specctra.h:2724
const std::string & GetPadstackId()
Definition: specctra.h:2138
#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:2097
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:3638
CLASSLIST classes
Definition: specctra.h:2811
RULE * rules
Definition: specctra.h:2731
static double scale(int kicadDist)
Function scale converts a distance from PCBNEW internal units to the reported specctra dsn units in f...
STRINGS net_ids
Definition: specctra.h:2726
NETWORK * network
Definition: specctra.h:3145
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:495

References DSN::CLASS::circuit, DSN::CLASS::class_id, DSN::NETWORK::classes, NETCLASS::Default, DSN::PADSTACK::GetPadstackId(), 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(), and TO_UTF8.

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:3175
Used for text file output.
Definition: richio.h:453
std::string pcbname
Definition: specctra.h:3138
std::string m_quote_char
Definition: specctra.h:3613

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:3571
SESSION * m_session
Definition: specctra.h:3611
Used for text file output.
Definition: richio.h:453
std::string m_quote_char
Definition: specctra.h:3613

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 835 of file specctra_export.cpp.

836 {
837  SHAPE_POLY_SET outlines;
838 
839  if( !aBoard->GetBoardPolygonOutlines( outlines ) )
840  {
841  wxLogWarning( _( "Board outline is malformed. Run DRC for a full analysis." ) );
842  }
843 
844  for( int cnt = 0; cnt < outlines.OutlineCount(); cnt++ ) // Should be one outline
845  {
846  PATH* path = new PATH( boundary );
847  boundary->paths.push_back( path );
848  path->layer_id = "pcb";
849 
850  SHAPE_LINE_CHAIN& outline = outlines.Outline( cnt );
851 
852  for( int ii = 0; ii < outline.PointCount(); ii++ )
853  {
854  wxPoint pos( outline.CPoint( ii ).x, outline.CPoint( ii ).y );
855  path->AppendPoint( mapPt( pos ) );
856  }
857 
858  // Close polygon:
859  wxPoint pos0( outline.CPoint( 0 ).x, outline.CPoint( 0 ).y );
860  path->AppendPoint( mapPt( pos0 ) );
861 
862  // Generate holes as keepout:
863  for( int ii = 0; ii < outlines.HoleCount( cnt ); ii++ )
864  {
865  // emit a signal layers keepout for every interior polygon left...
866  KEEPOUT* keepout = new KEEPOUT( NULL, T_keepout );
867  PATH* poly_ko = new PATH( NULL, T_polygon );
868 
869  keepout->SetShape( poly_ko );
870  poly_ko->SetLayerId( "signal" );
871  m_pcb->structure->keepouts.push_back( keepout );
872 
873  SHAPE_LINE_CHAIN& hole = outlines.Hole( cnt, ii );
874 
875  for( int jj = 0; jj < hole.PointCount(); jj++ )
876  {
877  wxPoint pos( hole.CPoint( jj ).x, hole.CPoint( jj ).y );
878  poly_ko->AppendPoint( mapPt( pos ) );
879  }
880 
881  // Close polygon:
882  wxPoint pos( hole.CPoint( 0 ).x, hole.CPoint( 0 ).y );
883  poly_ko->AppendPoint( mapPt( pos ) );
884  }
885  }
886 }
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:1856
static POINT mapPt(const wxPoint &pt)
Function mapPt converts a KiCad point into a DSN file point.
void SetLayerId(const char *aLayerId)
Definition: specctra.h:601
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:594
STRUCTURE * structure
Definition: specctra.h:3142
int PointCount() const
Function PointCount()
std::string layer_id
Definition: specctra.h:579
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:575
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void SetShape(ELEM *aShape)
Definition: specctra.h:928
#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:883
KEEPOUTS keepouts
Definition: specctra.h:1540

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

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 1737 of file specctra_export.cpp.

1738 {
1739  // DSN Images (=KiCad FOOTPRINTs and PADs) must be presented from the
1740  // top view.
1741  // Note: to export footprints, the footprints must be flipped around the X axis,
1742  // otherwise the rotation angle is not good
1743  for( FOOTPRINT* footprint : aBoard->Footprints() )
1744  {
1745  footprint->SetFlag( 0 );
1746  if( footprint->GetLayer() == B_Cu )
1747  {
1748  footprint->Flip( footprint->GetPosition(), false );
1749  footprint->SetFlag( 1 );
1750  }
1751  }
1752 
1753  m_footprintsAreFlipped = true;
1754 }
bool m_footprintsAreFlipped
Definition: specctra.h:3615
FOOTPRINTS & Footprints()
Definition: board.h:286

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 893 of file specctra_export.cpp.

894 {
895  PCB_TYPE_COLLECTOR items;
896 
897  static const KICAD_T scanMODULEs[] = { PCB_FOOTPRINT_T, EOT };
898 
899  // Not all boards are exportable. Check that all reference Ids are unique.
900  // Unless they are unique, we cannot import the session file which comes
901  // back to us later from the router.
902  {
903  items.Collect( aBoard, scanMODULEs );
904 
905  STRINGSET refs; // holds footprint reference designators
906 
907  for( int i=0; i<items.GetCount(); ++i )
908  {
909  FOOTPRINT* footprint = (FOOTPRINT*) items[i];
910 
911  if( footprint->GetReference() == wxEmptyString )
912  {
914  _( "Symbol with value of \"%s\" has empty reference id." ),
915  footprint->GetValue() ) );
916  }
917 
918  // if we cannot insert OK, that means the reference has been seen before.
919  STRINGSET_PAIR refpair = refs.insert( TO_UTF8( footprint->GetReference() ) );
920 
921  if( !refpair.second ) // insert failed
922  {
924  _( "Multiple symbols have identical reference IDs of \"%s\"." ),
925  footprint->GetReference() ) );
926  }
927  }
928  }
929 
930  if( !m_pcb )
932 
933  //-----<layer_descriptor>-----------------------------------------------
934  {
935  // specctra wants top physical layer first, then going down to the
936  // bottom most physical layer in physical sequence.
937  // @question : why does KiCad not display layers in that order?
938 
939  buildLayerMaps( aBoard );
940 
941  int layerCount = aBoard->GetCopperLayerCount();
942 
943  for( int pcbNdx=0; pcbNdx<layerCount; ++pcbNdx )
944  {
945  LAYER* layer = new LAYER( m_pcb->structure );
946 
947  m_pcb->structure->layers.push_back( layer );
948 
949  layer->name = m_layerIds[pcbNdx];
950 
951  DSN_T layerType;
952 
953  switch( aBoard->GetLayerType( m_pcbLayer2kicad[pcbNdx] ) )
954  {
955  default:
956  case LT_SIGNAL: layerType = T_signal; break;
957  case LT_POWER: layerType = T_power; break;
958 
959 #if 1 // Freerouter does not support type "mixed", only signal and power.
960  // Remap "mixed" to "signal".
961  case LT_MIXED: layerType = T_signal; break;
962 #else
963  case LT_MIXED: layerType = T_mixed; break;
964 #endif
965  case LT_JUMPER: layerType = T_jumper; break;
966  }
967 
968  layer->layer_type = layerType;
969 
970  layer->properties.push_back( PROPERTY() );
971  PROPERTY* property = &layer->properties.back();
972  property->name = "index";
973  char temp[32];
974  sprintf( temp, "%d", pcbNdx );
975  property->value = temp;
976  }
977  }
978 
979  // a space in a quoted token is NOT a terminator, true establishes this.
981 
982  //-----<unit_descriptor> & <resolution_descriptor>--------------------
983  {
984  // tell freerouter to use "tenths of micrometers",
985  // which is 100 nm resolution. Possibly more resolution is possible
986  // in freerouter, but it would need testing.
987 
988  m_pcb->unit->units = T_um;
989  m_pcb->resolution->units = T_um;
990  m_pcb->resolution->value = 10; // tenths of a um
991  // pcb->resolution->value = 1000; // "thousandths of a um" (i.e. "nm")
992  }
993 
994  //-----<boundary_descriptor>------------------------------------------
995  {
996  // Because fillBOUNDARY() can throw an exception, we link in an
997  // empty boundary so the BOUNDARY does not get lost in the event of
998  // of an exception.
999  BOUNDARY* boundary = new BOUNDARY( 0 );
1000 
1001  m_pcb->structure->SetBOUNDARY( boundary );
1002  fillBOUNDARY( aBoard, boundary );
1003  }
1004 
1005 
1006  //-----<rules>--------------------------------------------------------
1007  {
1008  char rule[80];
1009  NETCLASS* defaultClass = aBoard->GetDesignSettings().GetDefault();
1010 
1011  int defaultTrackWidth = defaultClass->GetTrackWidth();
1012  int defaultClearance = defaultClass->GetClearance();
1013 
1014  double clearance = scale( defaultClearance );
1015 
1016  STRINGS& rules = m_pcb->structure->rules->rules;
1017 
1018  sprintf( rule, "(width %.6g)", scale( defaultTrackWidth ) );
1019  rules.push_back( rule );
1020 
1021  sprintf( rule, "(clearance %.6g)", clearance + safetyMargin );
1022  rules.push_back( rule );
1023 
1024  // On a high density board (a board with 4 mil tracks, 4 mil spacing)
1025  // a typical solder mask clearance will be 2-3 mils.
1026  // This exposes 2 to 3 mils of bare board around each pad, and would
1027  // leave only 1 to 2 mils of solder mask between the solder mask's boundary
1028  // to the edge of any trace within "clearance" of the pad. So we need at least
1029  // 2 mils *extra* clearance for traces which would come near a pad on
1030  // a different net. So if the baseline trace to trace clearance was say 4 mils, then
1031  // the SMD to trace clearance should be at least 6 mils.
1032  double default_smd = clearance + safetyMargin;
1033 
1034  if( default_smd <= 6.0 )
1035  default_smd = 6.0;
1036 
1037  sprintf( rule, "(clearance %.6g (type default_smd))", default_smd );
1038 
1039  rules.push_back( rule );
1040 
1041  /* see: http://www.freerouting.net/usren/viewtopic.php?f=5&t=339#p474
1042  sprintf( rule, "(clearance %.6g (type pad_to_turn_gap))", clearance + safetyMargin );
1043  rules.push_back( rule );
1044 
1045  sprintf( rule, "(clearance %.6g (type smd_to_turn_gap))", clearance + safetyMargin );
1046  rules.push_back( rule );
1047 
1048  sprintf( rule, "(clearance %.6g (type via_via))", clearance + safetyMargin );
1049  rules.push_back( rule );
1050 
1051  sprintf( rule, "(clearance %.6g (type via_smd))", clearance + safetyMargin );
1052  rules.push_back( rule );
1053 
1054  sprintf( rule, "(clearance %.6g (type via_pin))", clearance + safetyMargin );
1055  rules.push_back( rule );
1056 
1057  sprintf( rule, "(clearance %.6g (type pin_pin))", clearance + safetyMargin );
1058  rules.push_back( rule );
1059 
1060  sprintf( rule, "(clearance %.6g (type smd_pin))", clearance + safetyMargin );
1061  rules.push_back( rule );
1062  */
1063 
1064  // Pad to pad spacing on a single SMT part can be closer than our
1065  // clearance, we don't want freerouter complaining about that, so
1066  // output a significantly smaller pad to pad clearance to freerouter.
1067  clearance = scale( defaultClearance ) / 4;
1068 
1069  sprintf( rule, "(clearance %.6g (type smd_smd))", clearance );
1070  rules.push_back( rule );
1071  }
1072 
1073 
1074  //-----<zones (not keepout areas) become planes>--------------------------------
1075  // Note: only zones are output here, keepout areas be be created later
1076  {
1077  int netlessZones = 0;
1078 
1079  static const KICAD_T scanZONEs[] = { PCB_ZONE_T, EOT };
1080  items.Collect( aBoard, scanZONEs );
1081 
1082  for( int i = 0; i<items.GetCount(); ++i )
1083  {
1084  ZONE* item = (ZONE*) items[i];
1085 
1086  if( item->GetIsRuleArea() )
1087  continue;
1088 
1089  // Currently, we export only copper layers
1090  if( ! IsCopperLayer( item->GetLayer() ) )
1091  continue;
1092 
1093  COPPER_PLANE* plane = new COPPER_PLANE( m_pcb->structure );
1094 
1095  m_pcb->structure->planes.push_back( plane );
1096 
1097  PATH* mainPolygon = new PATH( plane, T_polygon );
1098 
1099  plane->SetShape( mainPolygon );
1100 
1101  plane->name = TO_UTF8( item->GetNetname() );
1102 
1103  if( plane->name.size() == 0 )
1104  {
1105  char name[32];
1106 
1107  // This is one of those no connection zones, netcode=0, and it has no name.
1108  // Create a unique, bogus netname.
1109  NET* no_net = new NET( m_pcb->network );
1110 
1111  sprintf( name, "@:no_net_%d", netlessZones++ );
1112  no_net->net_id = name;
1113 
1114  // add the bogus net name to network->nets.
1115  m_pcb->network->nets.push_back( no_net );
1116 
1117  // use the bogus net name in the netless zone.
1118  plane->name = no_net->net_id;
1119  }
1120 
1121  mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1122 
1123  // Handle the main outlines
1124  SHAPE_POLY_SET::ITERATOR iterator;
1125  wxPoint startpoint;
1126  bool is_first_point = true;
1127 
1128  for( iterator = item->IterateWithHoles(); iterator; iterator++ )
1129  {
1130  wxPoint point( iterator->x, iterator->y );
1131 
1132  if( is_first_point )
1133  {
1134  startpoint = point;
1135  is_first_point = false;
1136  }
1137 
1138  mainPolygon->AppendPoint( mapPt( point ) );
1139 
1140  // this was the end of the main polygon
1141  if( iterator.IsEndContour() )
1142  {
1143  // Close polygon
1144  mainPolygon->AppendPoint( mapPt( startpoint ) );
1145  break;
1146  }
1147  }
1148 
1149  WINDOW* window = 0;
1150  PATH* cutout = 0;
1151 
1152  bool isStartContour = true;
1153 
1154  // handle the cutouts
1155  for( iterator++; iterator; iterator++ )
1156  {
1157  if( isStartContour )
1158  {
1159  is_first_point = true;
1160  window = new WINDOW( plane );
1161 
1162  plane->AddWindow( window );
1163 
1164  cutout = new PATH( window, T_polygon );
1165 
1166  window->SetShape( cutout );
1167 
1168  cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1169  }
1170 
1171  // If the point in this iteration is the last of the contour, the next iteration
1172  // will start with a new contour.
1173  isStartContour = iterator.IsEndContour();
1174 
1175  wxASSERT( window );
1176  wxASSERT( cutout );
1177 
1178  wxPoint point(iterator->x, iterator->y );
1179 
1180  if( is_first_point )
1181  {
1182  startpoint = point;
1183  is_first_point = false;
1184  }
1185 
1186  cutout->AppendPoint( mapPt(point) );
1187 
1188  // Close the polygon
1189  if( iterator.IsEndContour() )
1190  cutout->AppendPoint( mapPt( startpoint ) );
1191  }
1192  }
1193  }
1194 
1195  //-----<zones flagged keepout areas become keepout>--------------------------------
1196  {
1197  static const KICAD_T scanZONEs[] = { PCB_ZONE_T, EOT };
1198  items.Collect( aBoard, scanZONEs );
1199 
1200  for( int i=0; i<items.GetCount(); ++i )
1201  {
1202  ZONE* item = (ZONE*) items[i];
1203 
1204  if( !item->GetIsRuleArea() )
1205  continue;
1206 
1207  // keepout areas have a type. types are
1208  // T_place_keepout, T_via_keepout, T_wire_keepout,
1209  // T_bend_keepout, T_elongate_keepout, T_keepout.
1210  // Pcbnew knows only T_keepout, T_via_keepout and T_wire_keepout
1211  DSN_T keepout_type;
1212 
1213  if( item->GetDoNotAllowVias() && item->GetDoNotAllowTracks() )
1214  keepout_type = T_keepout;
1215  else if( item->GetDoNotAllowVias() )
1216  keepout_type = T_via_keepout;
1217  else if( item->GetDoNotAllowTracks() )
1218  keepout_type = T_wire_keepout;
1219  else
1220  keepout_type = T_keepout;
1221 
1222  // Now, build keepout polygon on each copper layer where the item
1223  // keepout is living (keepout zones can live on many copper layers)
1224  const int copperCount = aBoard->GetCopperLayerCount();
1225 
1226  for( int layer = 0; layer < copperCount; layer++ )
1227  {
1228  if( layer == copperCount-1)
1229  layer = B_Cu;
1230 
1231  if( !item->IsOnLayer( PCB_LAYER_ID( layer ) ) )
1232  continue;
1233 
1234  KEEPOUT* keepout = new KEEPOUT( m_pcb->structure, keepout_type );
1235  m_pcb->structure->keepouts.push_back( keepout );
1236 
1237  PATH* mainPolygon = new PATH( keepout, T_polygon );
1238  keepout->SetShape( mainPolygon );
1239 
1240  mainPolygon->layer_id = m_layerIds[ m_kicadLayer2pcb[ layer ] ];
1241 
1242  // Handle the main outlines
1243  SHAPE_POLY_SET::ITERATOR iterator;
1244  bool is_first_point = true;
1245  wxPoint startpoint;
1246 
1247  for( iterator = item->IterateWithHoles(); iterator; iterator++ )
1248  {
1249  wxPoint point( iterator->x, iterator->y );
1250 
1251  if( is_first_point )
1252  {
1253  startpoint = point;
1254  is_first_point = false;
1255  }
1256 
1257  mainPolygon->AppendPoint( mapPt(point) );
1258 
1259  // this was the end of the main polygon
1260  if( iterator.IsEndContour() )
1261  {
1262  mainPolygon->AppendPoint( mapPt( startpoint ) );
1263  break;
1264  }
1265  }
1266 
1267  WINDOW* window = nullptr;
1268  PATH* cutout = nullptr;
1269 
1270  bool isStartContour = true;
1271 
1272  // handle the cutouts
1273  for( iterator++; iterator; iterator++ )
1274  {
1275  if( isStartContour )
1276  {
1277  is_first_point = true;
1278  window = new WINDOW( keepout );
1279  keepout->AddWindow( window );
1280 
1281  cutout = new PATH( window, T_polygon );
1282 
1283  window->SetShape( cutout );
1284 
1285  cutout->layer_id = m_layerIds[ m_kicadLayer2pcb[ item->GetLayer() ] ];
1286  }
1287 
1288  isStartContour = iterator.IsEndContour();
1289 
1290  wxASSERT( window );
1291  wxASSERT( cutout );
1292 
1293  wxPoint point(iterator->x, iterator->y );
1294 
1295  if( is_first_point )
1296  {
1297  startpoint = point;
1298  is_first_point = false;
1299  }
1300 
1301  cutout->AppendPoint( mapPt(point) );
1302 
1303  // Close the polygon
1304  if( iterator.IsEndContour() )
1305  cutout->AppendPoint( mapPt( startpoint ) );
1306  }
1307  }
1308  }
1309  }
1310 
1311  //-----<build the images, components, and netlist>-----------------------
1312  {
1313  PIN_REF empty( m_pcb->network );
1314 
1315  std::string componentId;
1316 
1317  // find the highest numbered netCode within the board.
1318  int highestNetCode = 0;
1319  NETINFO_LIST& netInfo = aBoard->GetNetInfo();
1320 
1321  for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1322  highestNetCode = std::max( highestNetCode, i->GetNetCode() );
1323 
1324  deleteNETs();
1325 
1326  // expand the net vector to highestNetCode+1, setting empty to NULL
1327  m_nets.resize( highestNetCode + 1, NULL );
1328 
1329  for( unsigned i = 1 /* skip "No Net" at [0] */; i < m_nets.size(); ++i )
1330  m_nets[i] = new NET( m_pcb->network );
1331 
1332  for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i )
1333  {
1334  if( i->GetNetCode() > 0 )
1335  m_nets[i->GetNetCode()]->net_id = TO_UTF8( i->GetNetname() );
1336  }
1337 
1338  items.Collect( aBoard, scanMODULEs );
1339 
1340  m_padstackset.clear();
1341 
1342  for( int m = 0; m<items.GetCount(); ++m )
1343  {
1344  FOOTPRINT* footprint = (FOOTPRINT*) items[m];
1345 
1346  IMAGE* image = makeIMAGE( aBoard, footprint );
1347 
1348  componentId = TO_UTF8( footprint->GetReference() );
1349 
1350  // create a net list entry for all the actual pins in the image
1351  // for the current footprint. location of this code is critical
1352  // because we fabricated some pin names to ensure unique-ness
1353  // of pin names within a footprint, do not move this code because
1354  // the life of this 'IMAGE* image' is not necessarily long. The
1355  // exported netlist will have some fabricated pin names in it.
1356  // If you don't like fabricated pin names, then make sure all pads
1357  // within your FOOTPRINTs are uniquely named!
1358  for( unsigned p = 0; p<image->pins.size(); ++p )
1359  {
1360  PIN* pin = &image->pins[p];
1361 
1362  int netcode = pin->kiNetCode;
1363 
1364  if( netcode > 0 )
1365  {
1366  NET* net = m_nets[netcode];
1367 
1368  net->pins.push_back( empty );
1369 
1370  PIN_REF& pin_ref = net->pins.back();
1371 
1372  pin_ref.component_id = componentId;
1373  pin_ref.pin_id = pin->pin_id;
1374  }
1375  }
1376 
1377 
1378  IMAGE* registered = m_pcb->library->LookupIMAGE( image );
1379 
1380  if( registered != image )
1381  {
1382  // If our new 'image' is not a unique IMAGE, delete it.
1383  // and use the registered one, known as 'image' after this.
1384  delete image;
1385  image = registered;
1386  }
1387 
1388  COMPONENT* comp = m_pcb->placement->LookupCOMPONENT( image->GetImageId() );
1389 
1390  PLACE* place = new PLACE( comp );
1391 
1392  comp->places.push_back( place );
1393 
1394  place->SetRotation( footprint->GetOrientationDegrees() );
1395  place->SetVertex( mapPt( footprint->GetPosition() ) );
1396  place->component_id = componentId;
1397  place->part_number = TO_UTF8( footprint->GetValue() );
1398 
1399  // footprint is flipped from bottom side, set side to T_back
1400  if( footprint->GetFlag() )
1401  {
1402  double angle = 180.0 - footprint->GetOrientationDegrees();
1404  place->SetRotation( angle );
1405 
1406  place->side = T_back;
1407  }
1408  }
1409 
1410  // copy the SPECCTRA_DB::padstackset to the LIBRARY. Since we are
1411  // removing, do not increment the iterator
1412  for( PADSTACKSET::iterator i = m_padstackset.begin(); i != m_padstackset.end();
1413  i = m_padstackset.begin() )
1414  {
1415  PADSTACKSET::auto_type ps = m_padstackset.release( i );
1416  PADSTACK* padstack = ps.release();
1417 
1418  m_pcb->library->AddPadstack( padstack );
1419  }
1420 
1421  // copy our SPECCTRA_DB::nets to the pcb->network
1422  for( unsigned n = 1; n < m_nets.size(); ++n )
1423  {
1424  NET* net = m_nets[n];
1425 
1426  if( net->pins.size() )
1427  {
1428  // give ownership to pcb->network
1429  m_pcb->network->nets.push_back( net );
1430  m_nets[n] = 0;
1431  }
1432  }
1433  }
1434 
1435 
1436  //-----< output vias used in netclasses >-----------------------------------
1437  {
1438  NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
1439 
1440  // Assume the netclass vias are all the same kind of thru, blind, or buried vias.
1441  // This is in lieu of either having each netclass via have its own layer pair in
1442  // the netclass dialog, or such control in the specctra export dialog.
1443 
1444 
1445  // if( aBoard->GetDesignSettings().m_CurrentViaType == VIA_THROUGH )
1446  {
1447  m_top_via_layer = 0; // first specctra cu layer is number zero.
1448  m_bot_via_layer = aBoard->GetCopperLayerCount()-1;
1449  }
1450  /*
1451  else
1452  {
1453  // again, should be in the BOARD:
1454  topLayer = kicadLayer2pcb[ GetScreen()->m_Route_Layer_TOP ];
1455  botLayer = kicadLayer2pcb[ GetScreen()->m_Route_Layer_BOTTOM ];
1456  }
1457  */
1458 
1459  // Add the via from the Default netclass first. The via container
1460  // in pcb->library preserves the sequence of addition.
1461 
1462  NETCLASSPTR netclass = nclasses.GetDefault();
1463 
1464  PADSTACK* via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
1466 
1467  // we AppendVia() this first one, there is no way it can be a duplicate,
1468  // the pcb->library via container is empty at this point. After this,
1469  // we'll have to use LookupVia().
1470  wxASSERT( m_pcb->library->vias.size() == 0 );
1471  m_pcb->library->AppendVia( via );
1472 
1473 #if 0
1474  // I've seen no way to make stock vias useable by freerouter. Also the
1475  // zero based diameter was leading to duplicates in the LookupVia() function.
1476  // User should use netclass based vias when going to freerouter.
1477 
1478  // Output the stock vias, but preserve uniqueness in the via container by
1479  // using LookupVia().
1480  for( unsigned i = 0; i < aBoard->m_ViasDimensionsList.size(); ++i )
1481  {
1482  int viaSize = aBoard->m_ViasDimensionsList[i].m_Diameter;
1483  int viaDrill = aBoard->m_ViasDimensionsList[i].m_Drill;
1484 
1485  via = makeVia( viaSize, viaDrill,
1487 
1488  // maybe add 'via' to the library, but only if unique.
1489  PADSTACK* registered = pcb->library->LookupVia( via );
1490 
1491  if( registered != via )
1492  delete via;
1493  }
1494 #endif
1495 
1496  // set the "spare via" index at the start of the
1497  // pcb->library->spareViaIndex = pcb->library->vias.size();
1498 
1499  // output the non-Default netclass vias
1500  for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
1501  {
1502  netclass = nc->second;
1503 
1504  via = makeVia( netclass->GetViaDiameter(), netclass->GetViaDrill(),
1506 
1507  // maybe add 'via' to the library, but only if unique.
1509 
1510  if( registered != via )
1511  delete via;
1512  }
1513  }
1514 
1515 
1516 #if 1 // do existing wires and vias
1517 
1518  //-----<create the wires from tracks>-----------------------------------
1519  {
1520  // export all of them for now, later we'll decide what controls we need
1521  // on this.
1522  static const KICAD_T scanTRACKs[] = { PCB_TRACE_T, EOT };
1523 
1524  items.Collect( aBoard, scanTRACKs );
1525 
1526  std::string netname;
1527  WIRING* wiring = m_pcb->wiring;
1528  PATH* path = 0;
1529 
1530  int old_netcode = -1;
1531  int old_width = -1;
1532  LAYER_NUM old_layer = UNDEFINED_LAYER;
1533 
1534  for( int i=0; i<items.GetCount(); ++i )
1535  {
1536  TRACK* track = (TRACK*) items[i];
1537 
1538  int netcode = track->GetNetCode();
1539 
1540  if( netcode == 0 )
1541  continue;
1542 
1543  if( old_netcode != netcode ||
1544  old_width != track->GetWidth() ||
1545  old_layer != track->GetLayer() ||
1546  (path && path->points.back() != mapPt(track->GetStart()) )
1547  )
1548  {
1549  old_width = track->GetWidth();
1550  old_layer = track->GetLayer();
1551 
1552  if( old_netcode != netcode )
1553  {
1554  old_netcode = netcode;
1555  NETINFO_ITEM* net = aBoard->FindNet( netcode );
1556  wxASSERT( net );
1557  netname = TO_UTF8( net->GetNetname() );
1558  }
1559 
1560  WIRE* wire = new WIRE( wiring );
1561 
1562  wiring->wires.push_back( wire );
1563  wire->net_id = netname;
1564 
1565  wire->wire_type = T_protect; // @todo, this should be configurable
1566 
1567  LAYER_NUM kiLayer = track->GetLayer();
1568  int pcbLayer = m_kicadLayer2pcb[kiLayer];
1569 
1570  path = new PATH( wire );
1571 
1572  wire->SetShape( path );
1573 
1574  path->layer_id = m_layerIds[pcbLayer];
1575  path->aperture_width = scale( old_width );
1576 
1577  path->AppendPoint( mapPt( track->GetStart() ) );
1578  }
1579 
1580  if( path ) // Should not occur
1581  path->AppendPoint( mapPt( track->GetEnd() ) );
1582  }
1583  }
1584 
1585 
1586  //-----<export the existing real BOARD instantiated vias>-----------------
1587  {
1588  // Export all vias, once per unique size and drill diameter combo.
1589  static const KICAD_T scanVIAs[] = { PCB_VIA_T, EOT };
1590 
1591  items.Collect( aBoard, scanVIAs );
1592 
1593  for( int i = 0; i<items.GetCount(); ++i )
1594  {
1595  ::VIA* via = (::VIA*) items[i];
1596  wxASSERT( via->Type() == PCB_VIA_T );
1597 
1598  int netcode = via->GetNetCode();
1599 
1600  if( netcode == 0 )
1601  continue;
1602 
1603  PADSTACK* padstack = makeVia( via );
1604  PADSTACK* registered = m_pcb->library->LookupVia( padstack );
1605 
1606  // if the one looked up is not our padstack, then delete our padstack
1607  // since it was a duplicate of one already registered.
1608  if( padstack != registered )
1609  {
1610  delete padstack;
1611  }
1612 
1613  WIRE_VIA* dsnVia = new WIRE_VIA( m_pcb->wiring );
1614 
1615  m_pcb->wiring->wire_vias.push_back( dsnVia );
1616 
1617  dsnVia->padstack_id = registered->padstack_id;
1618  dsnVia->vertexes.push_back( mapPt( via->GetPosition() ) );
1619 
1620  NETINFO_ITEM* net = aBoard->FindNet( netcode );
1621  wxASSERT( net );
1622 
1623  dsnVia->net_id = TO_UTF8( net->GetNetname() );
1624 
1625  dsnVia->via_type = T_protect; // @todo, this should be configurable
1626  }
1627  }
1628 
1629 #endif // do existing wires and vias
1630 
1631  //-----<via_descriptor>-------------------------------------------------
1632  {
1633  // The pcb->library will output <padstack_descriptors> which is a combined
1634  // list of part padstacks and via padstacks. specctra dsn uses the
1635  // <via_descriptors> to say which of those padstacks are vias.
1636 
1637  // Output the vias in the padstack list here, by name only. This must
1638  // be done after exporting existing vias as WIRE_VIAs.
1639  VIA* vias = m_pcb->structure->via;
1640 
1641  for( unsigned viaNdx = 0; viaNdx < m_pcb->library->vias.size(); ++viaNdx )
1642  {
1643  vias->AppendVia( m_pcb->library->vias[viaNdx].padstack_id.c_str() );
1644  }
1645  }
1646 
1647 
1648  //-----<output NETCLASSs>----------------------------------------------------
1649  NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
1650 
1651  exportNETCLASS( nclasses.GetDefault(), aBoard );
1652 
1653  for( NETCLASSES::iterator nc = nclasses.begin(); nc != nclasses.end(); ++nc )
1654  {
1655  NETCLASSPTR netclass = nc->second;
1656  exportNETCLASS( netclass, aBoard );
1657  }
1658 }
DSN_T units
Definition: specctra.h:404
iterator end() const
Definition: netinfo.h:458
VIA corresponds to the <via_descriptor> in the specctra dsn spec.
Definition: specctra.h:1010
Wrapper class, so you can iterate through NETINFO_ITEM*s, not std::pair<int/wxString,...
Definition: netinfo.h:407
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1262
PIN_REF corresponds to the <pin_reference> definition in the specctra dsn spec.
Definition: specctra.h:2427
bool space_in_quoted_tokens
Definition: specctra.h:371
std::string pin_id
Definition: specctra.h:1928
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()
Function IterateWithHoles returns an iterator to visit all points of the zone's main outline with hol...
Definition: zone.h:550
int GetNetCode() const
Function GetNetCode.
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:2567
COPPER_PLANES planes
Definition: specctra.h:1542
std::string net_id
Definition: specctra.h:2571
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:755
std::string component_id
Definition: specctra.h:2429
const wxString GetValue() const
Function GetValue.
Definition: footprint.h:467
Definition: board.h:66
RULE * rules
Definition: specctra.h:1538
static const double safetyMargin
const wxPoint & GetStart() const
Definition: track.h:116
PINS pins
Definition: specctra.h:1991
bool GetDoNotAllowVias() const
Definition: zone.h:757
std::string part_number
Definition: specctra.h:1687
PADSTACKS vias
Definition: specctra.h:2238
static POINT mapPt(const wxPoint &pt)
Function mapPt converts 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:2316
static bool registered
Definition: coroutines.cpp:128
POINTS vertexes
Definition: specctra.h:2961
int kiNetCode
KiCad netcode.
Definition: specctra.h:1931
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:3140
wxString GetNetname() const
Function GetNetname.
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3619
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:313
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:574
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:735
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:594
iterator end()
Definition: netclass.h:236
PLACES places
Definition: specctra.h:1745
void NORMALIZE_ANGLE_DEGREES_POS(double &Angle)
Definition: trigo.h:306
STRUCTURE * structure
Definition: specctra.h:3142
WIRING * wiring
Definition: specctra.h:3146
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:2962
std::string layer_id
Definition: specctra.h:579
DSN_T via_type
Definition: specctra.h:2964
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:1717
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:851
Definition: board.h:67
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:575
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:3635
#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:1180
NETCLASS_MAP::iterator iterator
Definition: netclass.h:234
void SetShape(ELEM *aShape)
Definition: specctra.h:928
WIRES wires
Definition: specctra.h:3097
int GetFlag() const
Definition: footprint.h:254
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:3621
iterator begin()
Definition: netclass.h:235
A container for NETCLASS instances.
Definition: netclass.h:218
std::string name
Definition: specctra.h:1179
#define NULL
void AddWindow(WINDOW *aWindow)
Definition: specctra.h:943
COPPER_PLANE corresponds to a <plane_descriptor> in the specctra dsn spec.
Definition: specctra.h:1324
void deleteNETs()
Function deleteNETs deletes all the NETs that may be in here.
Definition: specctra.h:3803
NETINFO_LIST is a container class for NETINFO_ITEM elements, which are the nets.
Definition: netinfo.h:326
std::string padstack_id
Definition: specctra.h:2960
DSN_T side
Definition: specctra.h:1664
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: zone.cpp:215
iterator begin() const
Definition: netinfo.h:453
PLACE implements the <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1658
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:46
bool GetDoNotAllowTracks() const
Definition: zone.h:758
const wxString & GetNetname() const
Function GetNetname.
Definition: netinfo.h:138
void AddPadstack(PADSTACK *aPadstack)
Definition: specctra.h:2253
std::string component_id
reference designator
Definition: specctra.h:1662
PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2097
NETCLASSES & GetNetClasses() const
ZONE handles a list of polygons defining a copper zone.
Definition: zone.h:57
WIRE_VIAS wire_vias
Definition: specctra.h:3098
class ZONE, a copper pour area
Definition: typeinfo.h:105
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:3638
std::vector< std::string > STRINGS
Definition: specctra.h:157
const wxString GetReference() const
Function GetReference.
Definition: footprint.h:442
COMPONENT * LookupCOMPONENT(const std::string &imageName)
Function LookupCOMPONENT looks up a COMPONENT by name.
Definition: specctra.h:1816
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:598
PARSER * parser
Definition: specctra.h:3139
This item represents a net.
void SetRotation(double aRotation)
Definition: specctra.h:1724
int LAYER_NUM
This can be replaced with int and removed.
LIBRARY * library
Definition: specctra.h:3144
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
std::string GetImageId()
Definition: specctra.h:2024
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:377
double GetOrientationDegrees() const
Definition: footprint.h:205
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
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:2371
COMPONENT implements the <component_descriptor> in the specctra dsn spec.
Definition: specctra.h:1738
std::vector< PCB_LAYER_ID > m_pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
Definition: specctra.h:3622
int GetWidth() const
Definition: track.h:110
WIRE corresponds to <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2846
const char * name
Definition: DXF_plotter.cpp:59
void AppendVia(PADSTACK *aVia)
Function AppendVia adds aVia to the internal via container.
Definition: specctra.h:2346
DSN_T Type() const
Definition: specctra.h:230
POINTS points
Definition: specctra.h:582
#define _(s)
Definition: 3d_actions.cpp:33
int GetClearance() const
Definition: netclass.h:124
PLACEMENT * placement
Definition: specctra.h:3143
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:436
NETCLASS * GetDefault() const
void SetShape(ELEM *aShape)
Definition: specctra.h:2887
static bool empty(const wxTextEntryBase *aCtrl)
static double scale(int kicadDist)
Function scale converts a distance from PCBNEW internal units to the reported specctra dsn units in f...
double aperture_width
Definition: specctra.h:580
void SetBOUNDARY(BOUNDARY *aBoundary)
Definition: specctra.h:1579
wxPoint GetPosition() const override
Definition: footprint.h:200
const wxPoint & GetEnd() const
Definition: track.h:113
void AppendVia(const char *aViaName)
Definition: specctra.h:1024
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
UNIT_RES * unit
Definition: specctra.h:3141
NETCLASSPTR GetDefault() const
Definition: netclass.h:253
LAYERS layers
Definition: specctra.h:1530
PIN_REFS pins
Definition: specctra.h:2576
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:2956
std::string pin_id
Definition: specctra.h:2430
DSN_T wire_type
Definition: specctra.h:2861
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition: collectors.h:613
PROPERTIES properties
Definition: specctra.h:1187
PADSTACKSET m_padstackset
Definition: specctra.h:3632
KEEPOUT is used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:883
std::string name
Definition: specctra.h:888
NETWORK * network
Definition: specctra.h:3145
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:3092
Definition: track.h:83
std::string net_id
Definition: specctra.h:2859
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:495
KEEPOUTS keepouts
Definition: specctra.h:1540

References _, DSN::LIBRARY::AddPadstack(), DSN::KEEPOUT::AddWindow(), PNS::angle(), DSN::PATH::aperture_width, 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(), DSN::IMAGE::GetImageId(), ZONE::GetIsRuleArea(), BOARD_ITEM::GetLayer(), ZONE::GetLayer(), BOARD::GetLayerType(), BOARD_DESIGN_SETTINGS::GetNetClasses(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD::GetNetInfo(), BOARD_CONNECTED_ITEM::GetNetname(), NETINFO_ITEM::GetNetname(), FOOTPRINT::GetOrientationDegrees(), FOOTPRINT::GetPosition(), FOOTPRINT::GetReference(), TRACK::GetStart(), NETCLASS::GetTrackWidth(), FOOTPRINT::GetValue(), TRACK::GetWidth(), IsCopperLayer(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::IsEndContour(), ZONE::IsOnLayer(), ZONE::IterateWithHoles(), DSN::STRUCTURE::keepouts, DSN::PIN::kiNetCode, 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, PCB_FOOTPRINT_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, DSN::PIN::pin_id, DSN::PIN_REF::pin_id, DSN::IMAGE::pins, DSN::NET::pins, DSN::PCB::placement, DSN::COMPONENT::places, DSN::STRUCTURE::planes, DSN::PATH::points, 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, DSN::ELEM::Type(), UNDEFINED_LAYER, DSN::PCB::unit, DSN::UNIT_RES::units, DSN::UNIT_RES::value, DSN::WIRE_VIA::vertexes, 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;
461  LIBRARY& library = *m_session->route->library;
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:1010
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1262
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:3628
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:3085
NET_OUTS net_outs
Definition: specctra.h:3421
static POINT mapPt(const wxPoint &pt)
Function mapPt converts a KiCad point into a DSN file point.
POINTS vertexes
Definition: specctra.h:2961
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:574
boost::ptr_vector< NET_OUT > NET_OUTS
Definition: specctra.h:3410
POINT vertex
Definition: specctra.h:1669
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:575
double rotation
Definition: specctra.h:1666
bool hasVertex
Definition: specctra.h:1668
ELEM * shape
Definition: specctra.h:2857
UNIT_RES * GetUnits() const override
Function GetUnits returns the units for this section.
Definition: specctra.h:3443
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT) override
Adds an item to the container.
Definition: board.cpp:564
PADSTACK * FindPADSTACK(const std::string &aPadstackId)
Function FindPADSTACK searches the padstack container by name.
Definition: specctra.h:2387
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:754
DSN_T side
Definition: specctra.h:1664
PLACE implements the <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1658
LIBRARY * library
Definition: specctra.h:3420
::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:1662
PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2097
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:3625
PLACEMENT * placement
Definition: specctra.h:3541
const std::string & GetPadstackId()
Definition: specctra.h:2981
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
LIBRARY corresponds to the <library_descriptor> in the specctra dsn specification.
Definition: specctra.h:2230
WIRE corresponds to <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2846
boost::ptr_vector< PLACE > PLACES
Definition: specctra.h:1731
DSN_T Type() const
Definition: specctra.h:230
#define _(s)
Definition: 3d_actions.cpp:33
SESSION * m_session
Definition: specctra.h:3611
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:3543
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:2949
WIRE_VIA corresponds to <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2956
boost::ptr_vector< COMPONENT > COMPONENTS
Definition: pcb_netlist.h:192
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
COMPONENTS components
Definition: specctra.h:1794
TRACKS & Tracks()
Definition: board.h:283
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:1283
int GetNetCode() const
Definition: netinfo.h:131

References _, BOARD::Add(), B_Cu, buildLayerMaps(), DSN::PLACE::component_id, DSN::PLACEMENT::components, BOARD::DeleteMARKERs(), F_Cu, BOARD::FindFootprintByReference(), BOARD::FindNet(), DSN::LIBRARY::FindPADSTACK(), 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(), DSN::ROUTE::library, m_routeResolution, m_session, m_sessionBoard, makeTRACK(), makeVIA(), DSN::mapPt(), DSN::ROUTE::net_outs, 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, and DSN::WIRE_VIA::vertexes.

Referenced by PCB_EDIT_FRAME::ImportSpecctraSession().

◆ GetPCB()

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

Definition at line 3882 of file specctra.h.

3882 { return m_pcb; }

References m_pcb.

Referenced by main().

◆ GetSESSION()

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

Definition at line 3893 of file specctra.h.

3893 { return m_session; }
SESSION * m_session
Definition: specctra.h:3611

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:3877
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:3888
A LINE_READER that reads from an open file.
Definition: richio.h:172
SESSION * m_session
Definition: specctra.h:3611
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 599 of file specctra_export.cpp.

600 {
601  PINMAP pinmap;
602  wxString padName;
603 
604  PCB_TYPE_COLLECTOR fpItems;
605 
606  // get all the FOOTPRINT's pads.
607  fpItems.Collect( aFootprint, scanPADs );
608 
609  IMAGE* image = new IMAGE(0);
610 
611  image->image_id = aFootprint->GetFPID().Format().c_str();
612 
613  // from the pads, and make an IMAGE using collated padstacks.
614  for( int p=0; p < fpItems.GetCount(); ++p )
615  {
616  PAD* pad = (PAD*) fpItems[p];
617 
618  // see if this pad is a through hole with no copper on its perimeter
619  if( isRoundKeepout( pad ) )
620  {
621  double diameter = scale( pad->GetDrillSize().x );
622  POINT vertex = mapPt( pad->GetPos0() );
623 
624  int layerCount = aBoard->GetCopperLayerCount();
625 
626  for( int layer=0; layer<layerCount; ++layer )
627  {
628  KEEPOUT* keepout = new KEEPOUT( image, T_keepout );
629 
630  image->keepouts.push_back( keepout );
631 
632  CIRCLE* circle = new CIRCLE( keepout );
633 
634  keepout->SetShape( circle );
635 
636  circle->SetDiameter( diameter );
637  circle->SetVertex( vertex );
638  circle->SetLayerId( m_layerIds[layer].c_str() );
639  }
640  }
641  // else if() could there be a square keepout here?
642 
643  else
644  {
645  // Pads not on copper layers (i.e. only on tech layers) are ignored
646  // because they create invalid pads in .dsn file for freeroute
647  LSET mask_copper_layers = pad->GetLayerSet() & LSET::AllCuMask();
648 
649  if( !mask_copper_layers.any() )
650  continue;
651 
652  PADSTACK* padstack = makePADSTACK( aBoard, pad );
653  PADSTACKSET::iterator iter = m_padstackset.find( *padstack );
654 
655  if( iter != m_padstackset.end() )
656  {
657  // padstack is a duplicate, delete it and use the original
658  delete padstack;
659  padstack = (PADSTACK*) *iter.base(); // folklore, be careful here
660  }
661  else
662  {
663  m_padstackset.insert( padstack );
664  }
665 
666  PIN* pin = new PIN( image );
667 
668  padName = pad->GetName();
669  pin->pin_id = TO_UTF8( padName );
670 
671  if( padName!=wxEmptyString && pinmap.find( padName )==pinmap.end() )
672  {
673  pinmap[ padName ] = 0;
674  }
675  else // pad name is a duplicate within this footprint
676  {
677  char buf[32];
678 
679  int duplicates = ++pinmap[ padName ];
680 
681  sprintf( buf, "@%d", duplicates );
682 
683  pin->pin_id += buf; // append "@1" or "@2", etc. to pin name
684  }
685 
686  pin->kiNetCode = pad->GetNetCode();
687 
688  image->pins.push_back( pin );
689 
690  pin->padstack_id = padstack->padstack_id;
691 
692  double angle = pad->GetOrientationDegrees() - aFootprint->GetOrientationDegrees();
694  pin->SetRotation( angle );
695 
696  wxPoint pos( pad->GetPos0() );
697 
698  pin->SetVertex( mapPt( pos ) );
699  }
700  }
701 
702 #if 1 // enable image (outline) scopes.
703  static const KICAD_T scanEDGEs[] = { PCB_FP_SHAPE_T, EOT };
704 
705  // get all the FOOTPRINT's FP_SHAPEs and convert those to DSN outlines.
706  fpItems.Collect( aFootprint, scanEDGEs );
707 
708  for( int i = 0; i < fpItems.GetCount(); ++i )
709  {
710  FP_SHAPE* graphic = (FP_SHAPE*) fpItems[i];
711  SHAPE* outline;
712  PATH* path;
713 
714  switch( graphic->GetShape() )
715  {
716  case S_SEGMENT:
717  outline = new SHAPE( image, T_outline );
718 
719  image->Append( outline );
720  path = new PATH( outline );
721 
722  outline->SetShape( path );
723  path->SetAperture( scale( graphic->GetWidth() ) );
724  path->SetLayerId( "signal" );
725  path->AppendPoint( mapPt( graphic->GetStart0() ) );
726  path->AppendPoint( mapPt( graphic->GetEnd0() ) );
727  break;
728 
729  case S_CIRCLE:
730  {
731  // this is best done by 4 QARC's but freerouter does not yet support QARCs.
732  // for now, support by using line segments.
733 
734  outline = new SHAPE( image, T_outline );
735 
736  image->Append( outline );
737  path = new PATH( outline );
738 
739  outline->SetShape( path );
740  path->SetAperture( scale( graphic->GetWidth() ) );
741  path->SetLayerId( "signal" );
742 
743  // Do the math using KiCad units, that way we stay out of the
744  // scientific notation range of floating point numbers in the
745  // DSN file. We do not parse scientific notation in our own
746  // lexer/beautifier, and the spec is not clear that this is
747  // required. Fixed point floats are all that should be needed.
748 
749  double radius = GetLineLength( graphic->GetStart(), graphic->GetEnd() );
750 
751  // seg count to approximate circle by line segments
752  int seg_per_circle = GetArcToSegmentCount( radius, ARC_LOW_DEF, 360.0 );
753 
754  for( int ii = 0; ii < seg_per_circle; ++ii )
755  {
756  double radians = 2*M_PI / seg_per_circle * ii;
757  wxPoint point( KiROUND( radius * cos( radians ) ),
758  KiROUND( radius * sin( radians ) ) );
759 
760  point += graphic->m_Start0; // an offset
761 
762  path->AppendPoint( mapPt( point ) );
763  }
764  // The shape must be closed
765  wxPoint point( radius , 0 );
766  point += graphic->m_Start0;
767  path->AppendPoint( mapPt( point ) );
768  }
769  break;
770 
771  case S_RECT:
772  case S_ARC:
773  default:
774  continue;
775  }
776  }
777 
778 #endif
779 
780  return image;
781 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
void SetAperture(double aWidth)
Definition: specctra.h:606
std::string pin_id
Definition: specctra.h:1928
int GetNetCode() const
Function GetNetCode.
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)
Function isRoundKeepout decides if the pad is a copper-less through hole which needs to be made into ...
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:155
KEEPOUTS keepouts
Definition: specctra.h:1996
PINS pins
Definition: specctra.h:1991
static POINT mapPt(const wxPoint &pt)
Function mapPt converts a KiCad point into a DSN file point.
int GetWidth() const
Definition: pcb_shape.h:118
void SetLayerId(const char *aLayerId)
Definition: specctra.h:601
void SetLayerId(const char *aLayerId)
Definition: specctra.h:752
int kiNetCode
KiCad netcode.
Definition: specctra.h:1931
const wxPoint & GetStart0() const
Definition: fp_shape.h:106
usual segment : line with rounded ends
Definition: board_item.h:50
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3619
Arcs (with rounded ends)
Definition: board_item.h:52
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:594
void NORMALIZE_ANGLE_DEGREES_POS(double &Angle)
Definition: trigo.h:306
void SetRotation(double aRotation)
Definition: specctra.h:1943
segment with non rounded ends
Definition: board_item.h:51
void SetVertex(const POINT &aPoint)
Definition: specctra.h:1949
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 SetShape(ELEM *aShape)
Definition: specctra.h:851
static const KICAD_T scanPADs[]
Definition: specctra.h:3630
const char * c_str() const
Definition: utf8.h:102
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:575
#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
void SetShape(ELEM *aShape)
Definition: specctra.h:928
const wxSize & GetDrillSize() const
Definition: pad.h:245
LSET is a set of PCB_LAYER_IDs.
std::string image_id
Definition: specctra.h:1982
const int seg_per_circle
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:144
const wxString & GetName() const
Definition: pad.h:130
wxPoint m_Start0
Start point or center, relative to footprint origin, orient 0.
Definition: fp_shape.h:152
PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2097
void Append(ELEM *aElem)
Definition: specctra.h:320
const LIB_ID & GetFPID() const
Definition: footprint.h:208
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:362
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:598
std::string padstack_id
Definition: specctra.h:1925
UTF8 Format() const
Definition: lib_id.cpp:233
PADSTACK * makePADSTACK(BOARD *aBoard, PAD *aPad)
Function makePADSTACK creates a PADSTACK which matches the given pad.
SHAPE corresponds to the "(shape ..)" element in the specctra dsn spec.
Definition: specctra.h:1862
const wxPoint & GetPos0() const
Definition: pad.h:229
double GetOrientationDegrees() const
Definition: footprint.h:205