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 FlipMODULEs (BOARD *aBoard)
 Function FlipMODULEs flips the modules which are on the back side of the board to the front. More...
 
void RevertMODULEs (BOARD *aBoard)
 Function RevertMODULEs flips the modules 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, MODULE *aModule)
 Function makeIMAGE allocates an IMAGE on the heap and creates all the PINs according to the D_PADs in the MODULE. More...
 
PADSTACKmakePADSTACK (BOARD *aBoard, D_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

PCBpcb
 
SESSIONsession
 
wxString filename
 
std::string quote_char
 
bool modulesAreFlipped
 
STRING_FORMATTER sf
 
STRINGS layerIds
 indexed by PCB layer number More...
 
std::vector< int > kicadLayer2pcb
 maps BOARD layer number to PCB layer numbers More...
 
std::vector< PCB_LAYER_IDpcbLayer2kicad
 maps PCB layer number to BOARD layer numbers More...
 
UNIT_RESrouteResolution
 used during FromSESSION() only, memory for it is not owned here. More...
 
BOARDsessionBoard
 a copy to avoid passing as an argument, memory for it is not owned here. More...
 
PADSTACKSET padstackset
 
std::vector< NET * > 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 unsigned keywordCount
 
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 3607 of file specctra.h.

Constructor & Destructor Documentation

◆ SPECCTRA_DB()

DSN::SPECCTRA_DB::SPECCTRA_DB ( )
inline

Definition at line 3845 of file specctra.h.

3845  :
3846  SPECCTRA_LEXER( 0 ) // LINE_READER* == NULL, no DSNLEXER::PushReader()
3847  {
3848  // The LINE_READER will be pushed from an automatic instantiation,
3849  // we don't own it:
3850  wxASSERT( !iOwnReaders );
3851 
3852  pcb = 0;
3853  session = 0;
3854  quote_char += '"';
3855  modulesAreFlipped = false;
3856 
3857  SetSpecctraMode( true );
3858 
3859  // Avoid not initialized members:
3861  sessionBoard = NULL;
3862  m_top_via_layer = 0;
3863  m_bot_via_layer = 0;
3864  }
std::string quote_char
Definition: specctra.h:3616
#define NULL
int m_top_via_layer
specctra cu layers, 0 based index:
Definition: specctra.h:3644
SESSION * session
Definition: specctra.h:3614
bool modulesAreFlipped
Definition: specctra.h:3618
BOARD * sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3634
UNIT_RES * routeResolution
used during FromSESSION() only, memory for it is not owned here.
Definition: specctra.h:3631

References m_bot_via_layer, m_top_via_layer, modulesAreFlipped, NULL, pcb, quote_char, routeResolution, session, and sessionBoard.

◆ ~SPECCTRA_DB()

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

Definition at line 3866 of file specctra.h.

3867  {
3868  delete pcb;
3869  delete session;
3870 
3871  deleteNETs();
3872  }
void deleteNETs()
Function deleteNETs deletes all the NETs that may be in here.
Definition: specctra.h:3810
SESSION * session
Definition: specctra.h:3614

References deleteNETs(), pcb, and 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  layerIds.clear();
82  pcbLayer2kicad.resize( layerCount );
83  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 < kicadLayer2pcb.size(); ++i )
103  {
104  if( i < layerCount-1 )
105  kicadLayer2pcb[i] = i;
106  else
107  kicadLayer2pcb[i] = layerCount - 1;
108  }
109 
110  for( unsigned i = 0; i < pcbLayer2kicad.size(); ++i )
111  {
112  PCB_LAYER_ID id = ( i < layerCount-1 ) ? ToLAYER_ID( i ) : B_Cu;
113 
114  pcbLayer2kicad[i] = id;
115 
116  // save the specctra layer name in SPECCTRA_DB::layerIds for later.
117  layerIds.push_back( TO_UTF8( aBoard->GetLayerName( id ) ) );
118  }
119 
120 #endif
121 }
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer.
PCB_LAYER_ID
A quick note on layer IDs:
std::vector< int > kicadLayer2pcb
maps BOARD layer number to PCB layer numbers
Definition: specctra.h:3625
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
#define FIRST_LAYER
STRINGS layerIds
indexed by PCB layer number
Definition: specctra.h:3622
int GetCopperLayerCount() const
Function GetCopperLayerCount.
#define TO_UTF8(wxstring)
std::vector< PCB_LAYER_ID > pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
Definition: specctra.h:3628
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:849

References B_Cu, F_Cu, FIRST_LAYER, BOARD::GetCopperLayerCount(), BOARD::GetLayerName(), kicadLayer2pcb, layerIds, 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 3810 of file specctra.h.

3811  {
3812  for( unsigned n=0; n<nets.size(); ++n )
3813  delete nets[n];
3814 
3815  nets.clear();
3816  }
std::vector< NET * > nets
we don't want ownership here permanently, so we don't use boost::ptr_vector
Definition: specctra.h:3641

References 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 }
T
enum T contains all this lexer's tokens.
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(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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 }
T
enum T contains all this lexer's tokens.
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062

References doPATH(), doRECTANGLE(), DSN::BOUNDARY::paths, DSN::BOUNDARY::rectangle, DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

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 }
T
enum T contains all this lexer's tokens.

References DSN::CIRCLE::diameter, DSN::CIRCLE::layer_id, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, 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 += quote_char;
2580 
2581  builder += CurText();
2582 
2583  if( tok==T_STRING )
2584  builder += 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 }
std::string quote_char
Definition: specctra.h:3616
T
enum T contains all this lexer's tokens.
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

References DSN::CLASS::circuit, DSN::CLASS::class_id, doLAYER_RULE(), doRULE(), doTOPOLOGY(), DSN::CLASS::layer_rules, DSN::CLASS::net_ids, quote_char, RULE, DSN::CLASS::rules, DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_NONE, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, DRCRULE_T::T_STRING, 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 }
T
enum T contains all this lexer's tokens.
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, DRCRULE_T::T_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 }
T
enum T contains all this lexer's tokens.

References DSN::CLASSES::class_ids, and DRCRULE_T::T_RIGHT.

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 }
T
enum T contains all this lexer's tokens.

References DSN::COMP_ORDER::placement_ids, and DRCRULE_T::T_RIGHT.

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
T
enum T contains all this lexer's tokens.

References doPLACE(), DSN::COMPONENT::image_id, DSN::COMPONENT::places, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, and DRCRULE_T::T_RIGHT.

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 }
T
enum T contains all this lexer's tokens.

References DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

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
T
enum T contains all this lexer's tokens.

References DSN::ELEM_HOLDER::Append(), doTOKPROP(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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 }
T
enum T contains all this lexer's tokens.
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, DRCRULE_T::T_SYMBOL, DRCRULE_T::T_type, 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 }
T
enum T contains all this lexer's tokens.

References DSN::GRID::dimension, DSN::GRID::direction, DSN::GRID::grid_type, DSN::GRID::image_type, DSN::GRID::offset, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, and DRCRULE_T::T_RIGHT.

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 }
T
enum T contains all this lexer's tokens.
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(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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
T
enum T contains all this lexer's tokens.
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
SHAPE.
Definition: shape.h:74
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, 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
T
enum T contains all this lexer's tokens.
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
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, RULE, DSN::KEEPOUT::rules, DSN::KEEPOUT::sequence_number, DSN::KEEPOUT::shape, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, 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
T
enum T contains all this lexer's tokens.
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, DRCRULE_T::T_SYMBOL, DRCRULE_T::T_type, 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
T
enum T contains all this lexer's tokens.

References doSPECCTRA_LAYER_PAIR(), DSN::LAYER_NOISE_WEIGHT::layer_pairs, DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

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 }
T
enum T contains all this lexer's tokens.
void doRULE(RULE *growth)
Definition: specctra.cpp:1381

References doRULE(), DSN::LAYER_RULE::layer_ids, RULE, DSN::LAYER_RULE::rule, DRCRULE_T::T_LEFT, and DRCRULE_T::T_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 }
T
enum T contains all this lexer's tokens.
void doIMAGE(IMAGE *growth)
Definition: specctra.cpp:2126
void doPADSTACK(PADSTACK *growth)
Definition: specctra.cpp:1940
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

References DSN::LIBRARY::AddPadstack(), doIMAGE(), doPADSTACK(), doUNIT(), DSN::LIBRARY::images, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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 }
T
enum T contains all this lexer's tokens.
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:2459
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, DRCRULE_T::T_type, 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
T
enum T contains all this lexer's tokens.
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, 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
T
enum T contains all this lexer's tokens.
void doCLASS(CLASS *growth)
Definition: specctra.cpp:2501
This item represents a net.

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

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 }
T
enum T contains all this lexer's tokens.
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
SHAPE.
Definition: shape.h:74
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, 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  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 quote_char
Definition: specctra.h:3616
T
enum T contains all this lexer's tokens.

References DSN::PARSER::case_sensitive, DSN::PARSER::constants, DSN::PARSER::generated_by_freeroute, DSN::PARSER::host_cad, DSN::PARSER::host_version, 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, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_QUOTE_DEF, DRCRULE_T::T_RIGHT, DRCRULE_T::T_STRING_QUOTE, DRCRULE_T::T_SYMBOL, 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 }
T
enum T contains all this lexer's tokens.
#define NULL

References DSN::PATH::aperture_type, DSN::PATH::aperture_width, DSN::PATH::layer_id, NULL, DSN::PATH::points, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, 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
T
enum T contains all this lexer's tokens.
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, DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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 }
T
enum T contains all this lexer's tokens.

References DSN::PIN::padstack_id, DSN::PIN::pin_id, DSN::PIN::SetRotation(), DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, 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
T
enum T contains all this lexer's tokens.
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, 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
T
enum T contains all this lexer's tokens.
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:80
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553

References DSN::PLACEMENT::components, doCOMPONENT(), doRESOLUTION(), doUNIT(), DSN::PLACEMENT::flip_style, DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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 }
T
enum T contains all this lexer's tokens.

References DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

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, DRCRULE_T::T_NUMBER, 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, DRCRULE_T::T_NUMBER, 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
T
enum T contains all this lexer's tokens.
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, DSN::REGION::rectangle, DSN::REGION::region_id, RULE, DSN::REGION::rules, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and DRCRULE_T::T_rule.

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 }
T
enum T contains all this lexer's tokens.

References DRCRULE_T::T_NUMBER, 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
T
enum T contains all this lexer's tokens.
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, DSN::ROUTE::structure_out, DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

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 += quote_char;
1404 
1405  builder += CurText();
1406 
1407  if( tok==T_STRING )
1408  builder += 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 quote_char
Definition: specctra.h:3616
T
enum T contains all this lexer's tokens.

References quote_char, DSN::RULE::rules, DRCRULE_T::T_EOF, DRCRULE_T::T_LEFT, DRCRULE_T::T_NONE, DRCRULE_T::T_RIGHT, and DRCRULE_T::T_STRING.

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
T
enum T contains all this lexer's tokens.
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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
T
enum T contains all this lexer's tokens.
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:913
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
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, DSN::WINDOW::shape, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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, DSN::SPECCTRA_LAYER_PAIR::layer_weight, and DRCRULE_T::T_NUMBER.

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
T
enum T contains all this lexer's tokens.
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1139
LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:80
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, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, DRCRULE_T::T_rule, 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
T
enum T contains all this lexer's tokens.
void doRULE(RULE *growth)
Definition: specctra.cpp:1381
LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:80

References doLAYER(), doRULE(), DSN::STRUCTURE_OUT::layers, RULE, DSN::STRUCTURE_OUT::rules, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and DRCRULE_T::T_rule.

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 }
T
enum T contains all this lexer's tokens.
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, readCOMPnPIN(), DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

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 }
T
enum T contains all this lexer's tokens.

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 }
T
enum T contains all this lexer's tokens.
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(), DSN::TOPOLOGY::fromtos, DRCRULE_T::T_LEFT, and DRCRULE_T::T_RIGHT.

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 }
T
enum T contains all this lexer's tokens.

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 }
T
enum T contains all this lexer's tokens.

References DSN::VIA::padstacks, DSN::VIA::spares, DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, and DRCRULE_T::T_SYMBOL.

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 }
T
enum T contains all this lexer's tokens.
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(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, 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
T
enum T contains all this lexer's tokens.
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1087
void doQARC(QARC *growth)
Definition: specctra.cpp:1115

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

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
T
enum T contains all this lexer's tokens.
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:913
void doPATH(PATH *growth)
Definition: specctra.cpp:1014
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1062
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, DSN::WIRE::shape, DSN::WIRE::shield, DSN::WIRE::supply, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_type, 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 }
T
enum T contains all this lexer's tokens.

References DSN::WIRE_VIA::attr, DSN::WIRE_VIA::contact_layers, DSN::WIRE_VIA::net_id, DSN::WIRE_VIA::padstack_id, DSN::WIRE_VIA::supply, DRCRULE_T::T_LEFT, DRCRULE_T::T_NUMBER, DRCRULE_T::T_RIGHT, DRCRULE_T::T_SYMBOL, DRCRULE_T::T_type, 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
T
enum T contains all this lexer's tokens.
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(), DRCRULE_T::T_LEFT, DRCRULE_T::T_RIGHT, DSN::WIRING::unit, 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 1656 of file specctra_export.cpp.

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

References DSN::CLASS::circuit, DSN::CLASS::class_id, DSN::NETWORK::classes, NETCLASS::Default, DSN::PADSTACK::GetPadstackId(), m_bot_via_layer, m_top_via_layer, makeVia(), DSN::CLASS::net_ids, DSN::PCB::network, pcb, DSN::RULE::rules, DSN::CLASS::rules, safetyMargin, DSN::scale(), DRCRULE_T::T_rule, 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( pcb )
3445  {
3446  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), quote_char[0] );
3447 
3448  if( aNameChange )
3449  pcb->pcbname = TO_UTF8( aFilename );
3450 
3451  pcb->Format( &formatter, 0 );
3452  }
3453 }
std::string quote_char
Definition: specctra.h:3616
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:3176
#define TO_UTF8(wxstring)
FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
std::string pcbname
Definition: specctra.h:3139

References DSN::PCB::Format(), pcb, DSN::PCB::pcbname, quote_char, 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( session )
3459  {
3460  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), quote_char[0] );
3461 
3462  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:3572
std::string quote_char
Definition: specctra.h:3616
SESSION * session
Definition: specctra.h:3614
FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492

References DSN::SESSION::Format(), quote_char, and 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 833 of file specctra_export.cpp.

834 {
835  wxString errMessage;
836  SHAPE_POLY_SET outlines;
837 
838  aBoard->GetBoardPolygonOutlines( outlines, &errMessage );
839 
840  for( int cnt = 0; cnt < outlines.OutlineCount(); cnt++ ) // Should be one outline
841  {
842  PATH* path = new PATH( boundary );
843  boundary->paths.push_back( path );
844  path->layer_id = "pcb";
845 
846  SHAPE_LINE_CHAIN& outline = outlines.Outline( cnt );
847 
848  for( int ii = 0; ii < outline.PointCount(); ii++ )
849  {
850  wxPoint pos( outline.CPoint( ii ).x, outline.CPoint( ii ).y );
851  path->AppendPoint( mapPt( pos ) );
852  }
853 
854  // Close polygon:
855  wxPoint pos0( outline.CPoint( 0 ).x, outline.CPoint( 0 ).y );
856  path->AppendPoint( mapPt( pos0 ) );
857 
858  // Generate holes as keepout:
859  for( int ii = 0; ii < outlines.HoleCount( cnt ); ii++ )
860  {
861  // emit a signal layers keepout for every interior polygon left...
862  KEEPOUT* keepout = new KEEPOUT( NULL, T_keepout );
863  PATH* poly_ko = new PATH( NULL, T_polygon );
864 
865  keepout->SetShape( poly_ko );
866  poly_ko->SetLayerId( "signal" );
867  pcb->structure->keepouts.push_back( keepout );
868 
869  SHAPE_LINE_CHAIN& hole = outlines.Hole( cnt, ii );
870 
871  for( int jj = 0; jj < hole.PointCount(); jj++ )
872  {
873  wxPoint pos( hole.CPoint( jj ).x, hole.CPoint( jj ).y );
874  poly_ko->AppendPoint( mapPt( pos ) );
875  }
876 
877  // Close polygon:
878  wxPoint pos( hole.CPoint( 0 ).x, hole.CPoint( 0 ).y );
879  poly_ko->AppendPoint( mapPt( pos ) );
880  }
881  }
882 
883  if( !errMessage.IsEmpty() )
884  wxLogMessage( errMessage );
885 }
int OutlineCount() const
Returns the number of outlines in the set
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:602
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Returns the reference to aHole-th hole in the aIndex-th outline
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:595
STRUCTURE * structure
Definition: specctra.h:3143
int PointCount() const
Function PointCount()
std::string layer_id
Definition: specctra.h:580
PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:576
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void SetShape(ELEM *aShape)
Definition: specctra.h:929
#define NULL
SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, wxString *aErrorText=nullptr, wxPoint *aErrorLocation=nullptr)
Function GetBoardPolygonOutlines Extracts the board outlines and build a closed polygon from lines,...
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
SHAPE_LINE_CHAIN.
KEEPOUT is used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:884
KEEPOUTS keepouts
Definition: specctra.h:1541

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, DSN::mapPt(), NULL, SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), DSN::BOUNDARY::paths, pcb, 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(layerIds.size()); ++i )
127  {
128  if( 0 == aLayerName.compare( layerIds[i] ) )
129  return i;
130  }
131  return -1;
132 }
STRINGS layerIds
indexed by PCB layer number
Definition: specctra.h:3622

References layerIds.

Referenced by makeTRACK(), and makeVIA().

◆ FlipMODULEs()

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

Function FlipMODULEs flips the modules which are on the back side of the board to the front.

Definition at line 1732 of file specctra_export.cpp.

1733 {
1734  // DSN Images (=KiCad MODULES and pads) must be presented from the
1735  // top view.
1736  // Note: to export footprints, the footprints must be flipped around the X axis,
1737  // otherwise the rotation angle is not good
1738  for( auto module : aBoard->Modules() )
1739  {
1740  module->SetFlag( 0 );
1741  if( module->GetLayer() == B_Cu )
1742  {
1743  module->Flip( module->GetPosition(), false );
1744  module->SetFlag( 1 );
1745  }
1746  }
1747 
1748  modulesAreFlipped = true;
1749 }
MODULES & Modules()
Definition: class_board.h:266
bool modulesAreFlipped
Definition: specctra.h:3618

References B_Cu, BOARD::Modules(), and modulesAreFlipped.

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

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

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(), buildLayerMaps(), PCB_TYPE_COLLECTOR::Collect(), DSN::PLACE::component_id, DSN::PIN_REF::component_id, deleteNETs(), empty(), NETCLASSES::end(), EOT, exportNETCLASS(), fillBOUNDARY(), BOARD::FindNet(), Format(), GetChars(), NETCLASS::GetClearance(), BOARD::GetCopperLayerCount(), COLLECTOR::GetCount(), NETCLASSES::GetDefault(), BOARD_DESIGN_SETTINGS::GetDefault(), BOARD::GetDesignSettings(), ZONE_CONTAINER::GetDoNotAllowTracks(), ZONE_CONTAINER::GetDoNotAllowVias(), TRACK::GetEnd(), MODULE::GetFlag(), DSN::IMAGE::GetImageId(), ZONE_CONTAINER::GetIsKeepout(), ZONE_CONTAINER::GetLayer(), BOARD_ITEM::GetLayer(), BOARD::GetLayerType(), NETINFO_ITEM::GetNet(), BOARD_DESIGN_SETTINGS::GetNetClasses(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD::GetNetCount(), BOARD_CONNECTED_ITEM::GetNetname(), NETINFO_ITEM::GetNetname(), MODULE::GetOrientationDegrees(), MODULE::GetPosition(), MODULE::GetReference(), TRACK::GetStart(), NETCLASS::GetTrackWidth(), MODULE::GetValue(), TRACK::GetWidth(), IsCopperLayer(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::IsEndContour(), ZONE_CONTAINER::IsOnLayer(), ZONE_CONTAINER::IterateWithHoles(), DSN::STRUCTURE::keepouts, kicadLayer2pcb, DSN::PIN::kiNetCode, DSN::PATH::layer_id, DSN::LAYER::layer_type, layerIds, 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_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, nets, DSN::PCB::network, NORMALIZE_ANGLE_DEGREES_POS(), NULL, DSN::WIRE_VIA::padstack_id, padstackset, DSN::PCB::parser, DSN::PLACE::part_number, pcb, PCB_MODULE_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_AREA_T, pcbLayer2kicad, 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 321 of file specctra_import.cpp.

322 {
323  sessionBoard = aBoard; // not owned here
324 
325  if( !session )
326  THROW_IO_ERROR( _("Session file is missing the \"session\" section") );
327 
328  if( !session->route )
329  THROW_IO_ERROR( _("Session file is missing the \"routes\" section") );
330 
331  if( !session->route->library )
332  THROW_IO_ERROR( _("Session file is missing the \"library_out\" section") );
333 
334  // delete all the old tracks and vias
335  aBoard->Tracks().clear();
336 
337  aBoard->DeleteMARKERs();
338 
339  buildLayerMaps( aBoard );
340 
341  if( session->placement )
342  {
343  // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
344  // each COMPONENT, reposition and re-orient each component and put on
345  // correct side of the board.
346  COMPONENTS& components = session->placement->components;
347  for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp )
348  {
349  PLACES& places = comp->places;
350  for( unsigned i=0; i<places.size(); ++i )
351  {
352  PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
353 
354  wxString reference = FROM_UTF8( place->component_id.c_str() );
355  MODULE* module = aBoard->FindModuleByReference( reference );
356 
357  if( !module )
358  {
359  THROW_IO_ERROR( wxString::Format( _( "Reference '%s' not found." ),
360  reference ) );
361  }
362 
363  if( !place->hasVertex )
364  continue;
365 
366  UNIT_RES* resolution = place->GetUnits();
367  wxASSERT( resolution );
368 
369  wxPoint newPos = mapPt( place->vertex, resolution );
370  module->SetPosition( newPos );
371 
372  if( place->side == T_front )
373  {
374  // convert from degrees to tenths of degrees used in KiCad.
375  int orientation = KiROUND( place->rotation * 10.0 );
376 
377  if( module->GetLayer() != F_Cu )
378  {
379  // module is on copper layer (back)
380  module->Flip( module->GetPosition(), false );
381  }
382 
383  module->SetOrientation( orientation );
384  }
385  else if( place->side == T_back )
386  {
387  int orientation = KiROUND( (place->rotation + 180.0) * 10.0 );
388 
389  if( module->GetLayer() != B_Cu )
390  {
391