KiCad PCB EDA Suite
DSN::SPECCTRA_DB Class Reference

Class 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

Class 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

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:
3860  routeResolution = NULL;
3861  sessionBoard = NULL;
3862  m_top_via_layer = 0;
3863  m_bot_via_layer = 0;
3864  }
std::string quote_char
Definition: specctra.h:3616
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
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

Member Function Documentation

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.

References B_Cu, F_Cu, FIRST_LAYER, BOARD::GetCopperLayerCount(), BOARD::GetLayerName(), i, kicadLayer2pcb, layerIds, pcbLayer2kicad, TO_UTF8, and ToLAYER_ID().

Referenced by FromBOARD(), and FromSESSION().

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 }
int GetCopperLayerCount() const
Function GetCopperLayerCount.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
PCB_LAYER_ID
A quick note on layer IDs:
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
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
size_t i
Definition: json11.cpp:597
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:796
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.

Referenced by FromBOARD().

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&#39;t want ownership here permanently, so we don&#39;t use boost::ptr_vector
Definition: specctra.h:3641
void DSN::SPECCTRA_DB::doANCESTOR ( ANCESTOR growth)
private

Definition at line 3039 of file specctra.cpp.

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

Referenced by doHISTORY().

3040 {
3041  T tok;
3042 
3043  /* <ancestor_file_descriptor >::=
3044  (ancestor <file_path_name> (created_time <time_stamp> )
3045  [(comment <comment_string> )])
3046  */
3047 
3048  NeedSYMBOL();
3049  growth->filename = CurText();
3050 
3051  while( (tok = NextTok()) != T_RIGHT )
3052  {
3053  if( tok != T_LEFT )
3054  Expecting( T_LEFT );
3055 
3056  tok = NextTok();
3057  switch( tok )
3058  {
3059  case T_created_time:
3060  readTIME( &growth->time_stamp );
3061  NeedRIGHT();
3062  break;
3063 
3064  case T_comment:
3065  NeedSYMBOL();
3066  growth->comment = CurText();
3067  NeedRIGHT();
3068  break;
3069 
3070  default:
3071  Unexpected( CurText() );
3072  }
3073  }
3074 }
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
void DSN::SPECCTRA_DB::doBOUNDARY ( BOUNDARY growth)
private

Definition at line 965 of file specctra.cpp.

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

Referenced by doSTRUCTURE().

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

Definition at line 1085 of file specctra.cpp.

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

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

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

Definition at line 2498 of file specctra.cpp.

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

Referenced by doNETWORK().

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

Definition at line 1580 of file specctra.cpp.

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

Referenced by doREGION().

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

Definition at line 1625 of file specctra.cpp.

References DSN::CLASSES::class_ids.

Referenced by doCLASS_CLASS().

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

Definition at line 2653 of file specctra.cpp.

References DSN::COMP_ORDER::placement_ids.

Referenced by doNET(), and doTOPOLOGY().

2654 {
2655  T tok;
2656 
2657  /* <component_order_descriptor >::=
2658  (comp_order {<placement_id> })
2659  */
2660 
2661  while( IsSymbol(tok = NextTok()) )
2662  {
2663  growth->placement_ids.push_back( CurText() );
2664  }
2665 
2666  if( tok != T_RIGHT )
2667  Expecting( T_RIGHT );
2668 }
void DSN::SPECCTRA_DB::doCOMPONENT ( COMPONENT growth)
private

Definition at line 1853 of file specctra.cpp.

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

Referenced by doPLACEMENT().

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

Definition at line 877 of file specctra.cpp.

Referenced by doWIRE().

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

Definition at line 1187 of file specctra.cpp.

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

Referenced by doSTRUCTURE().

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

Definition at line 2671 of file specctra.cpp.

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

Referenced by doNET(), and doTOPOLOGY().

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

Definition at line 1648 of file specctra.cpp.

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

Referenced by doSTRUCTURE().

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

Definition at line 3077 of file specctra.cpp.

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

Referenced by doSESSION().

3078 {
3079  T tok;
3080 
3081  /* <history_descriptor >::=
3082  (history [{<ancestor_file_descriptor> }] <self_descriptor> )
3083  */
3084 
3085  while( (tok = NextTok()) != T_RIGHT )
3086  {
3087  if( tok != T_LEFT )
3088  Expecting( T_LEFT );
3089 
3090  tok = NextTok();
3091  switch( tok )
3092  {
3093  case T_ancestor:
3094  ANCESTOR* ancestor;
3095  ancestor = new ANCESTOR( growth );
3096  growth->ancestors.push_back( ancestor );
3097  doANCESTOR( ancestor );
3098  break;
3099 
3100  case T_self:
3101  while( (tok = NextTok()) != T_RIGHT )
3102  {
3103  if( tok != T_LEFT )
3104  Expecting( T_LEFT );
3105 
3106  tok = NextTok();
3107  switch( tok )
3108  {
3109  case T_created_time:
3110  readTIME( &growth->time_stamp );
3111  NeedRIGHT();
3112  break;
3113 
3114  case T_comment:
3115  NeedSYMBOL();
3116  growth->comments.push_back( CurText() );
3117  NeedRIGHT();
3118  break;
3119 
3120  default:
3121  Unexpected( CurText() );
3122  }
3123  }
3124  break;
3125 
3126  default:
3127  Unexpected( CurText() );
3128  }
3129  }
3130 }
void doANCESTOR(ANCESTOR *growth)
Definition: specctra.cpp:3039
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
void DSN::SPECCTRA_DB::doIMAGE ( IMAGE growth)
private

Definition at line 2123 of file specctra.cpp.

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

Referenced by doLIBRARY().

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

Definition at line 787 of file specctra.cpp.

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

Referenced by doIMAGE(), and doSTRUCTURE().

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;
845  // Fall through
846  case T_path:
847  case T_polygon:
848  if( growth->shape )
849  Unexpected( tok );
850  growth->shape = new PATH( growth, tok );
851  doPATH( (PATH*) growth->shape );
852  break;
853 
854  case T_qarc:
855  if( growth->shape )
856  Unexpected( tok );
857  growth->shape = new QARC( growth );
858  doQARC( (QARC*) growth->shape );
859  break;
860 
861  case T_window:
862  WINDOW* window;
863  window = new WINDOW( growth );
864  growth->windows.push_back( window );
865  doWINDOW( window );
866  break;
867 
868  default:
869  Unexpected( CurText() );
870  }
871 
872  tok = NextTok();
873  }
874 }
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:912
void doRULE(RULE *growth)
Definition: specctra.cpp:1379
void doPATH(PATH *growth)
Definition: specctra.cpp:1012
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1060
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1085
void doQARC(QARC *growth)
Definition: specctra.cpp:1113
void DSN::SPECCTRA_DB::doLAYER ( LAYER growth)
private

Definition at line 1257 of file specctra.cpp.

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

Referenced by doSTRUCTURE(), and doSTRUCTURE_OUT().

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

Definition at line 590 of file specctra.cpp.

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

Referenced by doSTRUCTURE().

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
void DSN::SPECCTRA_DB::doLAYER_RULE ( LAYER_RULE growth)
private

Definition at line 1713 of file specctra.cpp.

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

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

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

Definition at line 2266 of file specctra.cpp.

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

Referenced by doPCB(), and doROUTE().

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

Definition at line 2320 of file specctra.cpp.

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(), DSN::NET::rules, DSN::NET::source, DSN::NET::terminator, DSN::NET::type, and DSN::NET::unassigned.

Referenced by doNETWORK().

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

Definition at line 3334 of file specctra.cpp.

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

Referenced by doROUTE().

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

Definition at line 2608 of file specctra.cpp.

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

Referenced by doPCB().

2609 {
2610  T tok;
2611 
2612  /* <network_descriptor >::=
2613  (network
2614  {<net_descriptor>}
2615  [{<class_descriptor> }]
2616  [{<class_class_descriptor> }]
2617  [{<group_descriptor> }]
2618  [{<group_set_descriptor> }]
2619  [{<pair_descriptor> }]
2620  [{<bundle_descriptor> }]
2621  )
2622  */
2623 
2624  while( (tok = NextTok()) != T_RIGHT )
2625  {
2626  if( tok != T_LEFT )
2627  Expecting( T_LEFT );
2628 
2629  tok = NextTok();
2630  switch( tok )
2631  {
2632  case T_net:
2633  NET* net;
2634  net = new NET( growth );
2635  growth->nets.push_back( net );
2636  doNET( net );
2637  break;
2638 
2639  case T_class:
2640  CLASS* myclass;
2641  myclass = new CLASS( growth );
2642  growth->classes.push_back( myclass );
2643  doCLASS( myclass );
2644  break;
2645 
2646  default:
2647  Unexpected( CurText() );
2648  }
2649  }
2650 }
void doNET(NET *growth)
Definition: specctra.cpp:2320
void doCLASS(CLASS *growth)
Definition: specctra.cpp:2498
Definition: hash_eda.h:43
void DSN::SPECCTRA_DB::doPADSTACK ( PADSTACK growth)
private

Definition at line 1938 of file specctra.cpp.

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

Referenced by doLIBRARY().

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

Definition at line 387 of file specctra.cpp.

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, and DSN::PARSER::via_rotate_first.

Referenced by doPCB(), and doROUTE().

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
void DSN::SPECCTRA_DB::doPATH ( PATH growth)
private

Definition at line 1012 of file specctra.cpp.

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

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

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

Definition at line 282 of file specctra.cpp.

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

Referenced by LoadPCB().

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:2983
void doLIBRARY(LIBRARY *growth)
Definition: specctra.cpp:2266
void doSTRUCTURE(STRUCTURE *growth)
Definition: specctra.cpp:610
void doPLACEMENT(PLACEMENT *growth)
Definition: specctra.cpp:1883
void doNETWORK(NETWORK *growth)
Definition: specctra.cpp:2608
void doPARSER(PARSER *growth)
Definition: specctra.cpp:387
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553
void DSN::SPECCTRA_DB::doPIN ( PIN growth)
private

Definition at line 2219 of file specctra.cpp.

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

Referenced by doIMAGE().

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

Definition at line 1738 of file specctra.cpp.

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, DSN::PLACE::region, DSN::PLACE::rules, DSN::PLACE::SetRotation(), DSN::PLACE::SetVertex(), DSN::PLACE::side, DSN::PLACE::status, DSN::POINT::x, and DSN::POINT::y.

Referenced by doCOMPONENT().

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

Definition at line 1883 of file specctra.cpp.

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

Referenced by doPCB(), and doSESSION().

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

Definition at line 1234 of file specctra.cpp.

Referenced by doLAYER(), and doPLACE().

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

Definition at line 1113 of file specctra.cpp.

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

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

1114 {
1115  NeedSYMBOL();
1116  growth->layer_id = CurText();
1117 
1118  if( NextTok() != T_NUMBER )
1119  Expecting( T_NUMBER );
1120  growth->aperture_width = strtod( CurText(), 0 );
1121 
1122  for( int i=0; i<3; ++i )
1123  {
1124  if( NextTok() != T_NUMBER )
1125  Expecting( T_NUMBER );
1126  growth->vertex[i].x = strtod( CurText(), 0 );
1127 
1128  if( NextTok() != T_NUMBER )
1129  Expecting( T_NUMBER );
1130  growth->vertex[i].y = strtod( CurText(), 0 );
1131  }
1132 
1133  NeedRIGHT();
1134 }
size_t i
Definition: json11.cpp:597
void DSN::SPECCTRA_DB::doRECTANGLE ( RECTANGLE growth)
private

Definition at line 1060 of file specctra.cpp.

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

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

1061 {
1062  NeedSYMBOL();
1063  growth->layer_id = CurText();
1064 
1065  if( NextTok() != T_NUMBER )
1066  Expecting( T_NUMBER );
1067  growth->point0.x = strtod( CurText(), NULL );
1068 
1069  if( NextTok() != T_NUMBER )
1070  Expecting( T_NUMBER );
1071  growth->point0.y = strtod( CurText(), NULL );
1072 
1073  if( NextTok() != T_NUMBER )
1074  Expecting( T_NUMBER );
1075  growth->point1.x = strtod( CurText(), NULL );
1076 
1077  if( NextTok() != T_NUMBER )
1078  Expecting( T_NUMBER );
1079  growth->point1.y = strtod( CurText(), NULL );
1080 
1081  NeedRIGHT();
1082 }
void DSN::SPECCTRA_DB::doREGION ( REGION growth)
private

Definition at line 1511 of file specctra.cpp.

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

Referenced by doPLACE(), and doSTRUCTURE().

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

Definition at line 526 of file specctra.cpp.

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

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

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 }
void DSN::SPECCTRA_DB::doROUTE ( ROUTE growth)
private

Definition at line 3251 of file specctra.cpp.

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

Referenced by doSESSION().

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

Definition at line 1379 of file specctra.cpp.

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

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

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

Definition at line 3133 of file specctra.cpp.

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

Referenced by LoadSESSION().

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

Definition at line 2038 of file specctra.cpp.

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

Referenced by doIMAGE(), and doPADSTACK().

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

Definition at line 574 of file specctra.cpp.

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

Referenced by doLAYER_NOISE_WEIGHT().

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 }
void DSN::SPECCTRA_DB::doSTRINGPROP ( STRINGPROP growth)
private

Definition at line 1137 of file specctra.cpp.

References DSN::STRINGPROP::value.

Referenced by doREGION(), and doSTRUCTURE().

1138 {
1139  NeedSYMBOL();
1140  growth->value = CurText();
1141  NeedRIGHT();
1142 }
void DSN::SPECCTRA_DB::doSTRUCTURE ( STRUCTURE growth)
private

Definition at line 610 of file specctra.cpp.

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, LAYER, DSN::STRUCTURE::layer_noise_weight, DSN::STRUCTURE::layers, DSN::STRUCTURE::place_boundary, DSN::STRUCTURE::place_rules, DSN::STRUCTURE::planes, DSN::STRUCTURE::regions, DSN::STRUCTURE::rules, DSN::STRUCTURE::unit, VIA, and DSN::STRUCTURE::via.

Referenced by doPCB(), and doSESSION().

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:1648
Definition: hash_eda.h:42
void doCONTROL(CONTROL *growth)
Definition: specctra.cpp:1187
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1257
void doVIA(VIA *growth)
Definition: specctra.cpp:1158
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:526
void doREGION(REGION *growth)
Definition: specctra.cpp:1511
void doRULE(RULE *growth)
Definition: specctra.cpp:1379
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1137
Class LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:85
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:553
void doBOUNDARY(BOUNDARY *growth)
Definition: specctra.cpp:965
void DSN::SPECCTRA_DB::doSTRUCTURE_OUT ( STRUCTURE_OUT growth)
private

Definition at line 744 of file specctra.cpp.

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

Referenced by doROUTE().

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 }
Definition: hash_eda.h:42
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1257
void doRULE(RULE *growth)
Definition: specctra.cpp:1379
Class LAYER holds information pertinent to a layer of a BOARD.
Definition: class_board.h:85
void DSN::SPECCTRA_DB::doSUPPLY_PIN ( SUPPLY_PIN growth)
private

Definition at line 3402 of file specctra.cpp.

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

Referenced by doNET_OUT().

3403 {
3404  T tok;
3405  PIN_REF empty(growth);
3406 
3407  /* <supply_pin_descriptor >::=
3408  (supply_pin {<pin_reference> } [(net <net_id >)])
3409  */
3410 
3411  NeedSYMBOL();
3412  growth->net_id = CurText();
3413 
3414  while( (tok = NextTok()) != T_RIGHT )
3415  {
3416  if( IsSymbol(tok) )
3417  {
3418  growth->pin_refs.push_back( empty );
3419 
3420  PIN_REF* pin_ref = &growth->pin_refs.back();
3421 
3422  readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
3423  }
3424  else if( tok == T_LEFT )
3425  {
3426  tok = NextTok();
3427  if( tok != T_net )
3428  Expecting( T_net );
3429  growth->net_id = CurText();
3430  NeedRIGHT();
3431  }
3432  else
3433  Unexpected( CurText() );
3434  }
3435 }
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)
void DSN::SPECCTRA_DB::doTOKPROP ( TOKPROP growth)
private

Definition at line 1145 of file specctra.cpp.

References DSN::TOKPROP::value.

Referenced by doCONTROL().

1146 {
1147  T tok = NextTok();
1148 
1149  if( tok<0 )
1150  Unexpected( CurText() );
1151 
1152  growth->value = tok;
1153 
1154  NeedRIGHT();
1155 }
void DSN::SPECCTRA_DB::doTOPOLOGY ( TOPOLOGY growth)
private

Definition at line 2460 of file specctra.cpp.

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

Referenced by doCLASS().

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

Definition at line 553 of file specctra.cpp.

References DSN::UNIT_RES::units.

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

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 }
void DSN::SPECCTRA_DB::doVIA ( VIA growth)
private

Definition at line 1158 of file specctra.cpp.

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

Referenced by doSTRUCTURE().

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

Definition at line 3210 of file specctra.cpp.

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

Referenced by doSESSION().

3211 {
3212  T tok;
3213  PIN_PAIR empty( growth );
3214  PIN_PAIR* pin_pair;
3215 
3216  /* <was_is_descriptor >::=
3217  (was_is {(pins <pin_reference> <pin_reference> )})
3218  */
3219 
3220  // none of the pins is ok too
3221  while( (tok = NextTok()) != T_RIGHT )
3222  {
3223 
3224  if( tok != T_LEFT )
3225  Expecting( T_LEFT );
3226 
3227  tok = NextTok();
3228  switch( tok )
3229  {
3230  case T_pins:
3231  // copy the empty one, then fill its copy later thru pin_pair.
3232  growth->pin_pairs.push_back( empty );
3233  pin_pair= &growth->pin_pairs.back();
3234 
3235  NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3236  readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
3237 
3238  NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3239  readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
3240 
3241  NeedRIGHT();
3242  break;
3243 
3244  default:
3245  Unexpected( CurText() );
3246  }
3247  }
3248 }
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)
void DSN::SPECCTRA_DB::doWINDOW ( WINDOW growth)
private

Definition at line 912 of file specctra.cpp.

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

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

913 {
914  T tok = NextTok();
915 
916  while( tok != T_RIGHT )
917  {
918  if( tok!=T_LEFT )
919  Expecting( T_LEFT );
920 
921  tok = NextTok();
922  switch( tok )
923  {
924  case T_rect:
925  if( growth->shape )
926  Unexpected( tok );
927  growth->shape = new RECTANGLE( growth );
928  doRECTANGLE( (RECTANGLE*) growth->shape );
929  break;
930 
931  case T_circle:
932  if( growth->shape )
933  Unexpected( tok );
934  growth->shape = new CIRCLE( growth );
935  doCIRCLE( (CIRCLE*) growth->shape );
936  break;
937 
938  case T_polyline_path:
939  tok = T_path;
940  // Fall through
941  case T_path:
942  case T_polygon:
943  if( growth->shape )
944  Unexpected( tok );
945  growth->shape = new PATH( growth, tok );
946  doPATH( (PATH*) growth->shape );
947  break;
948 
949  case T_qarc:
950  if( growth->shape )
951  Unexpected( tok );
952  growth->shape = new QARC( growth );
953  doQARC( (QARC*) growth->shape );
954  break;
955 
956  default:
957  Unexpected( CurText() );
958  }
959 
960  tok = NextTok();
961  }
962 }
void doPATH(PATH *growth)
Definition: specctra.cpp:1012
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1060
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1085
void doQARC(QARC *growth)
Definition: specctra.cpp:1113
void DSN::SPECCTRA_DB::doWIRE ( WIRE growth)
private

Definition at line 2757 of file specctra.cpp.

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

Referenced by doNET_OUT(), and doWIRING().

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

Definition at line 2879 of file specctra.cpp.

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

Referenced by doNET_OUT(), and doWIRING().

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

Definition at line 2983 of file specctra.cpp.

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

Referenced by doPCB().

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

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(), and TO_UTF8.

Referenced by FromBOARD().

1680 {
1681  /* From page 11 of specctra spec:
1682  *
1683  * Routing and Placement Rule Hierarchies
1684  *
1685  * Routing and placement rules can be defined at multiple levels of design
1686  * specification. When a routing or placement rule is defined for an object at
1687  * multiple levels, a predefined routing or placement precedence order
1688  * automatically determines which rule to apply to the object. The routing rule
1689  * precedence order is
1690  *
1691  * pcb < layer < class < class layer < group_set < group_set layer < net <
1692  * net layer < group < group layer < fromto < fromto layer < class_class <
1693  * class_class layer < padstack < region < class region < net region <
1694  * class_class region
1695  *
1696  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1697  * hierarchy. A class-to-class region rule has the highest precedence. Rules
1698  * set at one level of the hierarchy override conflicting rules set at lower
1699  * levels. The placement rule precedence order is
1700  *
1701  * pcb < image_set < image < component < super cluster < room <
1702  * room_image_set < family_family < image_image
1703  *
1704  * A pcb rule (global rule for the PCB design) has the lowest precedence in the
1705  * hierarchy. An image-to-image rule has the highest precedence. Rules set at
1706  * one level of the hierarchy override conflicting rules set at lower levels.
1707  */
1708 
1709  char text[256];
1710 
1711  CLASS* clazz = new CLASS( pcb->network );
1712 
1713  pcb->network->classes.push_back( clazz );
1714 
1715  // freerouter creates a class named 'default' anyway, and if we
1716  // try and use that, we end up with two 'default' via rules so use
1717  // something else as the name of our default class.
1718  clazz->class_id = TO_UTF8( aNetClass->GetName() );
1719 
1720  for( NETCLASS::iterator net = aNetClass->begin(); net != aNetClass->end(); ++net )
1721  clazz->net_ids.push_back( TO_UTF8( *net ) );
1722 
1723  clazz->rules = new RULE( clazz, T_rule );
1724 
1725  // output the track width.
1726  int trackWidth = aNetClass->GetTrackWidth();
1727  sprintf( text, "(width %.6g)", scale( trackWidth ) );
1728  clazz->rules->rules.push_back( text );
1729 
1730  // output the clearance.
1731  int clearance = aNetClass->GetClearance();
1732  sprintf( text, "(clearance %.6g)", scale( clearance ) + safetyMargin );
1733  clazz->rules->rules.push_back( text );
1734 
1735  if( aNetClass->GetName() == NETCLASS::Default )
1736  {
1737  clazz->class_id = "kicad_default";
1738  }
1739 
1740  // the easiest way to get the via name is to create a via (which generates
1741  // the name internal to the PADSTACK), and then grab the name and then
1742  // delete the via. There are not that many netclasses so
1743  // this should never become a performance issue.
1744 
1745  PADSTACK* via = makeVia( aNetClass->GetViaDiameter(), aNetClass->GetViaDrill(),
1747 
1748  snprintf( text, sizeof(text), "(use_via %s)", via->GetPadstackId().c_str() );
1749  clazz->circuit.push_back( text );
1750 
1751  delete via;
1752 }
STRINGS circuit
circuit descriptor list
Definition: specctra.h:2730
static const double safetyMargin
Class CLASS corresponds to the <class_descriptor> in the specctra spec.
Definition: specctra.h:2721
std::string class_id
Definition: specctra.h:2725
Class RULE corresponds to the <rule_descriptor> in the specctra dsn spec.
Definition: specctra.h:492
const std::string & GetPadstackId()
Definition: specctra.h:2139
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
STRINGSET::iterator iterator
Definition: netclass.h:141
static const char Default[]
the name of the default NETCLASS
Definition: netclass.h:90
Class 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...
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
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 3438 of file specctra.cpp.

References DSN::PCB::Format(), pcb, DSN::PCB::pcbname, quote_char, and TO_UTF8.

Referenced by PCB_EDIT_FRAME::ExportSpecctraFile().

3439 {
3440  if( pcb )
3441  {
3442  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), quote_char[0] );
3443 
3444  if( aNameChange )
3445  pcb->pcbname = TO_UTF8( aFilename );
3446 
3447  pcb->Format( &formatter, 0 );
3448  }
3449 }
std::string quote_char
Definition: specctra.h:3616
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
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
Class FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
std::string pcbname
Definition: specctra.h:3139
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 3452 of file specctra.cpp.

References DSN::SESSION::Format(), quote_char, and session.

3453 {
3454  if( session )
3455  {
3456  FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), quote_char[0] );
3457 
3458  session->Format( &formatter, 0 );
3459  }
3460 }
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
Class FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
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 855 of file specctra_export.cpp.

References DSN::PATH::AppendPoint(), BOARD::GetBoardPolygonOutlines(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), DSN::STRUCTURE::keepouts, DSN::PATH::layer_id, DSN::mapPt(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), DSN::BOUNDARY::paths, pcb, SHAPE_LINE_CHAIN::Point(), SHAPE_LINE_CHAIN::PointCount(), DSN::PATH::SetLayerId(), DSN::KEEPOUT::SetShape(), DSN::PCB::structure, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by FromBOARD().

856 {
857  wxString errMessage;
858  SHAPE_POLY_SET outlines;
859 
860  aBoard->GetBoardPolygonOutlines( outlines, &errMessage );
861 
862  for( int cnt = 0; cnt < outlines.OutlineCount(); cnt++ ) // Should be one outline
863  {
864  PATH* path = new PATH( boundary );
865  boundary->paths.push_back( path );
866  path->layer_id = "pcb";
867 
868  SHAPE_LINE_CHAIN& outline = outlines.Outline( cnt );
869 
870  for( int ii = 0; ii < outline.PointCount(); ii++ )
871  {
872  wxPoint pos( outline.Point( ii ).x, outline.Point( ii ).y );
873  path->AppendPoint( mapPt( pos ) );
874  }
875 
876  // Close polygon:
877  wxPoint pos0( outline.Point( 0 ).x, outline.Point( 0 ).y );
878  path->AppendPoint( mapPt( pos0 ) );
879 
880  // Generate holes as keepout:
881  for( int ii = 0; ii < outlines.HoleCount( cnt ); ii++ )
882  {
883  // emit a signal layers keepout for every interior polygon left...
884  KEEPOUT* keepout = new KEEPOUT( NULL, T_keepout );
885  PATH* poly_ko = new PATH( NULL, T_polygon );
886 
887  keepout->SetShape( poly_ko );
888  poly_ko->SetLayerId( "signal" );
889  pcb->structure->keepouts.push_back( keepout );
890 
891  SHAPE_LINE_CHAIN& hole = outlines.Hole( cnt, ii );
892 
893  for( int jj = 0; jj < hole.PointCount(); jj++ )
894  {
895  wxPoint pos( hole.Point( jj ).x, hole.Point( jj ).y );
896  poly_ko->AppendPoint( mapPt( pos ) );
897  }
898 
899  // Close polygon:
900  wxPoint pos( hole.Point( 0 ).x, hole.Point( 0 ).y );
901  poly_ko->AppendPoint( mapPt( pos ) );
902  }
903  }
904 
905  if( !errMessage.IsEmpty() )
906  wxLogMessage( errMessage );
907 }
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, wxString *aErrorText=NULL)
Function GetBoardPolygonOutlines Extracts the board outlines and build a closed polygon from lines...
int PointCount() const
Function PointCount()
static POINT mapPt(const wxPoint &pt)
Function mapPt converts a KiCad point into a DSN file point.
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
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 OutlineCount() const
Returns the number of outlines in the set
std::string layer_id
Definition: specctra.h:580
Class PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec...
Definition: specctra.h:576
void SetShape(ELEM *aShape)
Definition: specctra.h:929
Class SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
Class SHAPE_LINE_CHAIN.
VECTOR2I & Point(int aIndex)
Function Point()
Class KEEPOUT is used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:884
KEEPOUTS keepouts
Definition: specctra.h:1541
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.

References i, and layerIds.

Referenced by makeTRACK(), and makeVIA().

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
size_t i
Definition: json11.cpp:597
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 1755 of file specctra_export.cpp.

References B_Cu, BOARD::m_Modules, modulesAreFlipped, and MODULE::Next().

Referenced by PCB_EDIT_FRAME::ExportSpecctraFile().

1756 {
1757  for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
1758  {
1759  module->SetFlag( 0 );
1760  if( module->GetLayer() == B_Cu )
1761  {
1762  module->Flip( module->GetPosition() );
1763  module->SetFlag( 1 );
1764  }
1765  }
1766 
1767  modulesAreFlipped = true;
1768 }
MODULE * Next() const
Definition: class_module.h:121
bool modulesAreFlipped
Definition: specctra.h:3618
DLIST< MODULE > m_Modules
Definition: class_board.h:247
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 void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event ) for how this can be done before calling this function.

Parameters
aBoardThe BOARD to convert to a PCB.

Definition at line 914 of file specctra_export.cpp.

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(), exportNETCLASS(), fillBOUNDARY(), BOARD::FindNet(), Format(), GetChars(), BOARD::GetCopperLayerCount(), COLLECTOR::GetCount(), BOARD_DESIGN_SETTINGS::GetDefault(), NETCLASSES::GetDefault(), BOARD::GetDesignSettings(), ZONE_CONTAINER::GetDoNotAllowTracks(), ZONE_CONTAINER::GetDoNotAllowVias(), TRACK::GetEnd(), MODULE::GetFlag(), DSN::IMAGE::GetImageId(), ZONE_CONTAINER::GetIsKeepout(), BOARD_ITEM::GetLayer(), ZONE_CONTAINER::GetLayer(), BOARD::GetLayerType(), NETINFO_ITEM::GetNet(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD::GetNetCount(), BOARD_CONNECTED_ITEM::GetNetname(), NETINFO_ITEM::GetNetname(), MODULE::GetOrientationDegrees(), MODULE::GetPosition(), MODULE::GetReference(), TRACK::GetStart(), MODULE::GetValue(), TRACK::GetWidth(), i, IsCopperLayer(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::IsEndContour(), ZONE_CONTAINER::IsOnLayer(), ZONE_CONTAINER::IterateWithHoles(), DSN::STRUCTURE::keepouts, kicadLayer2pcb, DSN::PIN::kiNetCode, LAYER, 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, BOARD_DESIGN_SETTINGS::m_NetClasses, m_top_via_layer, makeIMAGE(), MakePCB(), makeVia(), DSN::mapPt(), name, DSN::KEEPOUT::name, DSN::LAYER::name, NET, DSN::NET::net_id, DSN::WIRE_VIA::net_id, DSN::NETWORK::nets, nets, DSN::PCB::network, NORMALIZE_ANGLE_DEGREES_POS(), DSN::PADSTACK::padstack_id, 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, 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::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::WIRING::wire_vias, DSN::WIRING::wires, and DSN::PCB::wiring.

Referenced by PCB_EDIT_FRAME::ExportSpecctraFile().

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

Function FromSESSION adds the entire SESSION info to a BOARD but does not write it out.

The 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 365 of file specctra_import.cpp.

References BOARD::Add(), B_Cu, buildLayerMaps(), DSN::PLACE::component_id, DSN::PLACEMENT::components, DHEAD::DeleteAll(), BOARD::DeleteMARKERs(), F_Cu, BOARD::FindModuleByReference(), BOARD::FindNet(), DSN::LIBRARY::FindPADSTACK(), Format(), FROM_UTF8(), GetChars(), NETCLASSES::GetDefault(), BOARD::GetDesignSettings(), NETINFO_ITEM::GetNet(), DSN::WIRE_VIA::GetPadstackId(), DSN::ELEM::GetUnits(), DSN::ROUTE::GetUnits(), DSN::PLACE::hasVertex, i, KiROUND(), DSN::ROUTE::library, BOARD_DESIGN_SETTINGS::m_NetClasses, BOARD::m_Track, makeTRACK(), makeVIA(), DSN::mapPt(), DSN::ROUTE::net_outs, DSN::SESSION::placement, DSN::PLACE::rotation, DSN::SESSION::route, routeResolution, session, sessionBoard, DSN::WIRE::shape, DSN::PLACE::side, THROW_IO_ERROR, DSN::ELEM::Type(), DSN::PLACE::vertex, and DSN::WIRE_VIA::vertexes.

Referenced by PCB_EDIT_FRAME::ImportSpecctraSession().

366 {
367  sessionBoard = aBoard; // not owned here
368 
369  if( !session )
370  THROW_IO_ERROR( _("Session file is missing the \"session\" section") );
371 
372  /* Dick 16-Jan-2012: session need not have a placement section.
373  if( !session->placement )
374  THROW_IO_ERROR( _("Session file is missing the \"placement\" section") );
375  */
376 
377  if( !session->route )
378  THROW_IO_ERROR( _("Session file is missing the \"routes\" section") );
379 
380  if( !session->route->library )
381  THROW_IO_ERROR( _("Session file is missing the \"library_out\" section") );
382 
383  // delete all the old tracks and vias
384  aBoard->m_Track.DeleteAll();
385 
386  aBoard->DeleteMARKERs();
387 
388  buildLayerMaps( aBoard );
389 
390  if( session->placement )
391  {
392  // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
393  // each COMPONENT, reposition and re-orient each component and put on
394  // correct side of the board.
395  COMPONENTS& components = session->placement->components;
396  for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp )
397  {
398  PLACES& places = comp->places;
399  for( unsigned i=0; i<places.size(); ++i )
400  {
401  PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
402 
403  wxString reference = FROM_UTF8( place->component_id.c_str() );
404  MODULE* module = aBoard->FindModuleByReference( reference );
405  if( !module )
406  {
407  THROW_IO_ERROR( wxString::Format( _("Session file has 'reference' to non-existent symbol \"%s\""),
408  GetChars( reference ) ) );
409  }
410 
411  if( !place->hasVertex )
412  continue;
413 
414  UNIT_RES* resolution = place->GetUnits();
415  wxASSERT( resolution );
416 
417  wxPoint newPos = mapPt( place->vertex, resolution );
418  module->SetPosition( newPos );
419 
420  if( place->side == T_front )
421  {
422  // convert from degrees to tenths of degrees used in KiCad.
423  int orientation = KiROUND( place->rotation * 10.0 );
424 
425  if( module->GetLayer() != F_Cu )
426  {
427  // module is on copper layer (back)
428  module->Flip( module->GetPosition() );
429  }
430 
431  module->SetOrientation( orientation );
432  }
433  else if( place->side == T_back )
434  {
435  int orientation = KiROUND( (place->rotation + 180.0) * 10.0 );
436 
437  if( module->GetLayer() != B_Cu )
438  {
439  // module is on component layer (front)
440  module->Flip( module->GetPosition() );
441  }
442 
443  module->SetOrientation( orientation );
444  }
445  else
446  {
447  // as I write this, the PARSER *is* catching this, so we should never see below:
448  wxFAIL_MSG( wxT("DSN::PARSER did not catch an illegal side := 'back|front'") );
449  }
450  }
451  }
452  }
453 
455 
456  // Walk the NET_OUTs and create tracks and vias anew.
457  NET_OUTS& net_outs = session->route->net_outs;
458  for( NET_OUTS::iterator net = net_outs.begin(); net!=net_outs.end(); ++net )
459  {
460  int netoutCode = 0;
461 
462  // page 143 of spec says wire's net_id is optional
463  if( net->net_id.size() )
464  {
465  wxString netName = FROM_UTF8( net->net_id.c_str() );
466  NETINFO_ITEM* netinfo = aBoard->FindNet( netName );
467 
468  if( netinfo )
469  netoutCode = netinfo->GetNet();
470  else // else netCode remains 0
471  {
472  // int breakhere = 1;
473  }
474  }
475 
476  WIRES& wires = net->wires;
477  for( unsigned i = 0; i<wires.size(); ++i )
478  {
479  WIRE* wire = &wires[i];
480  DSN_T shape = wire->shape->Type();
481 
482  if( shape != T_path )
483  {
484  /* shape == T_polygon is expected from freerouter if you have
485  a zone on a non "power" type layer, i.e. a T_signal layer
486  and the design does a round trip back in as session here.
487  We kept our own zones in the BOARD, so ignore this so called
488  'wire'.
489 
490  wxString netId = FROM_UTF8( wire->net_id.c_str() );
491  THROW_IO_ERROR( wxString::Format( _("Unsupported wire shape: \"%s\" for net: \"%s\""),
492  DLEX::GetTokenString(shape).GetData(),
493  netId.GetData()
494  ) );
495  */
496  }
497  else
498  {
499  PATH* path = (PATH*) wire->shape;
500  for( unsigned pt=0; pt<path->points.size()-1; ++pt )
501  {
502  TRACK* track = makeTRACK( path, pt, netoutCode );
503  aBoard->Add( track );
504  }
505  }
506  }
507 
508  WIRE_VIAS& wire_vias = net->wire_vias;
509  LIBRARY& library = *session->route->library;
510  for( unsigned i=0; i<wire_vias.size(); ++i )
511  {
512  int netCode = 0;
513 
514  // page 144 of spec says wire_via's net_id is optional
515  if( net->net_id.size() )
516  {
517  wxString netName = FROM_UTF8( net->net_id.c_str() );
518  NETINFO_ITEM* netvia = aBoard->FindNet( netName );
519 
520  if( netvia )
521  netCode = netvia->GetNet();
522 
523  // else netCode remains 0
524  }
525 
526  WIRE_VIA* wire_via = &wire_vias[i];
527 
528  // example: (via Via_15:8_mil 149000 -71000 )
529 
530  PADSTACK* padstack = library.FindPADSTACK( wire_via->GetPadstackId() );
531  if( !padstack )
532  {
533  // Dick Feb 29, 2008:
534  // Freerouter has a bug where it will not round trip all vias.
535  // Vias which have a (use_via) element will be round tripped.
536  // Vias which do not, don't come back in in the session library,
537  // even though they may be actually used in the pre-routed,
538  // protected wire_vias. So until that is fixed, create the
539  // padstack from its name as a work around.
540 
541 
542  // Could use a STRING_FORMATTER here and convert the entire
543  // wire_via to text and put that text into the exception.
544  wxString psid( FROM_UTF8( wire_via->GetPadstackId().c_str() ) );
545 
546  THROW_IO_ERROR( wxString::Format( _("A wire_via references a missing padstack \"%s\""),
547  GetChars( psid ) ) );
548  }
549 
550  NETCLASSPTR netclass = aBoard->GetDesignSettings().m_NetClasses.GetDefault();
551 
552  int via_drill_default = netclass->GetViaDrill();
553 
554  for( unsigned v=0; v<wire_via->vertexes.size(); ++v )
555  {
556  ::VIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode, via_drill_default );
557  aBoard->Add( via );
558  }
559  }
560  }
561 }
Class VIA corresponds to the <via_descriptor> in the specctra dsn spec.
Definition: specctra.h:1011
TRACK * makeTRACK(PATH *aPath, int aPointIndex, int aNetcode)
Function makeTRACK creates a TRACK form the PATH and BOARD info.
void buildLayerMaps(BOARD *aBoard)
Function buildLayerMaps creates a few data translation structures for layer name and number mapping b...
Definition: specctra.cpp:74
DSN::T DSN_T
Definition: specctra.h:47
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:106
boost::ptr_vector< WIRE_VIA > WIRE_VIAS
Definition: specctra.h:3086
virtual UNIT_RES * GetUnits() const
Function GetUnits returns the units for this section.
Definition: specctra.cpp:3506
NET_OUTS net_outs
Definition: specctra.h:3422
static POINT mapPt(const wxPoint &pt)
Function mapPt converts a KiCad point into a DSN file point.
POINTS vertexes
Definition: specctra.h:2962
Class UNIT_RES is a holder for either a T_unit or T_resolution object which are usually mutually excl...
Definition: specctra.h:401
MODULE * FindModuleByReference(const wxString &aReference) const
Function FindModuleByReference searches for a MODULE within this board with the given reference desig...
boost::ptr_vector< NET_OUT > NET_OUTS
Definition: specctra.h:3411
void DeleteAll()
Function DeleteAll deletes all items on the list and leaves the list empty.
Definition: dlist.cpp:44
POINT vertex
Definition: specctra.h:1670
Class PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec...
Definition: specctra.h:576
double rotation
Definition: specctra.h:1667
bool hasVertex
Definition: specctra.h:1669
ELEM * shape
Definition: specctra.h:2858
UNIT_RES * GetUnits() const override
Function GetUnits returns the units for this section.
Definition: specctra.h:3444
PADSTACK * FindPADSTACK(const std::string &aPadstackId)
Function FindPADSTACK searches the padstack container by name.
Definition: specctra.h:2388
void DeleteMARKERs()
Function DeleteMARKERs deletes ALL MARKERS from the board.
DSN_T side
Definition: specctra.h:1665
Class PLACE implements the <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1659
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
LIBRARY * library
Definition: specctra.h:3421
::VIA * makeVIA(PADSTACK *aPadstack, const POINT &aPoint, int aNetCode, int aViaDrillDefault)
Function makeVIA instantiates a KiCad VIA on the heap and initializes it with internal values consist...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:535
std::string component_id
reference designator
Definition: specctra.h:1663
Class PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2098
int GetNet() const
Function GetNet.
Definition: netinfo.h:227
SESSION * session
Definition: specctra.h:3614
PLACEMENT * placement
Definition: specctra.h:3542
const std::string & GetPadstackId()
Definition: specctra.h:2982
Class NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:69
Class LIBRARY corresponds to the <library_descriptor> in the specctra dsn specification.
Definition: specctra.h:2231
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:92
Class WIRE corresponds to <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2847
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
boost::ptr_vector< PLACE > PLACES
Definition: specctra.h:1732
NETCLASSPTR GetDefault() const
Function GetDefault.
Definition: netclass.h:275
size_t i
Definition: json11.cpp:597
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
ROUTE * route
Definition: specctra.h:3544
BOARD * sessionBoard
a copy to avoid passing as an argument, memory for it is not owned here.
Definition: specctra.h:3634
boost::ptr_vector< WIRE > WIRES
Definition: specctra.h:2950
Class WIRE_VIA corresponds to <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2957
DLIST< TRACK > m_Track
Definition: class_board.h:248
boost::ptr_vector< COMPONENT > COMPONENTS
Definition: pcb_netlist.h:204
DSN_T Type() const
Definition: specctra.h:231
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
UNIT_RES * routeResolution
used during FromSESSION() only, memory for it is not owned here.
Definition: specctra.h:3631
COMPONENTS components
Definition: specctra.h:1795
NETCLASSES m_NetClasses
List of current netclasses. There is always the default netclass.
PCB* DSN::SPECCTRA_DB::GetPCB ( )
inline

Definition at line 3889 of file specctra.h.

Referenced by main().

3889 { return pcb; }
SESSION* DSN::SPECCTRA_DB::GetSESSION ( )
inline

Definition at line 3900 of file specctra.h.

Referenced by main().

3900 { return session; }
SESSION * session
Definition: specctra.h:3614
void DSN::SPECCTRA_DB::LoadPCB ( const wxString &  aFilename)

Function LoadPCB is a recursive descent parser for a SPECCTRA DSN "design" file.

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

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

Definition at line 243 of file specctra.cpp.

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

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

Function LoadSESSION is a recursive descent parser for a SPECCTRA DSN "session" file.

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

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

Definition at line 262 of file specctra.cpp.

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

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

263 {
264  FILE_LINE_READER curr_reader( aFilename );
265 
266  PushReader( &curr_reader );
267 
268  if( NextTok() != T_LEFT )
269  Expecting( T_LEFT );
270 
271  if( NextTok() != T_session )
272  Expecting( T_session );
273 
274  SetSESSION( new SESSION() );
275 
276  doSESSION( session );
277 
278  PopReader();
279 }
void SetSESSION(SESSION *aSession)
Function SetSESSION deletes any existing SESSION and replaces it with the given one.
Definition: specctra.h:3895
Class FILE_LINE_READER is a LINE_READER that reads from an open file.
Definition: richio.h:180
SESSION * session
Definition: specctra.h:3614
void doSESSION(SESSION *growth)
Definition: specctra.cpp:3133
IMAGE * DSN::SPECCTRA_DB::makeIMAGE ( BOARD aBoard,
MODULE aModule 
)
private

Function makeIMAGE allocates an IMAGE on the heap and creates all the PINs according to the D_PADs in the MODULE.

Parameters
aBoardThe owner of the MODULE.
aModuleThe MODULE from which to build the IMAGE.
Returns
IMAGE* - not tested for duplication yet.

Definition at line 617 of file specctra_export.cpp.

References LSET::AllCuMask(), PNS::angle(), DSN::ELEM_HOLDER::Append(), DSN::PATH::AppendPoint(), UTF8::c_str(), PCB_TYPE_COLLECTOR::Collect(), DBG, LIB_ID::Format(), GetArcToSegmentCount(), BOARD::GetCopperLayerCount(), COLLECTOR::GetCount(), D_PAD::GetDrillSize(), DRAWSEGMENT::GetEnd(), EDGE_MODULE::GetEnd0(), MODULE::GetFPID(), D_PAD::GetLayerSet(), GetLineLength(), D_PAD::GetName(), BOARD_CONNECTED_ITEM::GetNetCode(), MODULE::GetOrientationDegrees(), D_PAD::GetOrientationDegrees(), D_PAD::GetPos0(), DRAWSEGMENT::GetShape(), DRAWSEGMENT::GetStart(), EDGE_MODULE::GetStart0(), DRAWSEGMENT::GetWidth(), i, DSN::IMAGE::image_id, DSN::isRoundKeepout(), DSN::IMAGE::keepouts, DSN::PIN::kiNetCode, KiROUND(), layerIds, EDGE_MODULE::m_Start0, makePADSTACK(), DSN::mapPt(), NORMALIZE_ANGLE_DEGREES_POS(), DSN::PIN::padstack_id, DSN::PADSTACK::padstack_id, padstackset, PCB_MODULE_EDGE_T, DSN::PIN::pin_id, DSN::IMAGE::pins, S_ARC, S_CIRCLE, S_RECT, S_SEGMENT, DSN::scale(), scanPADs, seg_per_circle, DSN::PATH::SetAperture(), DSN::CIRCLE::SetDiameter(), DSN::PATH::SetLayerId(), DSN::CIRCLE::SetLayerId(), DSN::PIN::SetRotation(), DSN::WINDOW::SetShape(), DSN::KEEPOUT::SetShape(), DSN::CIRCLE::SetVertex(), DSN::PIN::SetVertex(), BOARD_ITEM::ShowShape(), and TO_UTF8.

Referenced by FromBOARD().

618 {
619  PINMAP pinmap;
620  wxString padName;
621 
622  PCB_TYPE_COLLECTOR moduleItems;
623 
624  // get all the MODULE's pads.
625  moduleItems.Collect( aModule, scanPADs );
626 
627  IMAGE* image = new IMAGE(0);
628 
629  image->image_id = aModule->GetFPID().Format().c_str();
630 
631  // from the pads, and make an IMAGE using collated padstacks.
632  for( int p=0; p < moduleItems.GetCount(); ++p )
633  {
634  D_PAD* pad = (D_PAD*) moduleItems[p];
635 
636  // see if this pad is a through hole with no copper on its perimeter
637  if( isRoundKeepout( pad ) )
638  {
639  double diameter = scale( pad->GetDrillSize().x );
640  POINT vertex = mapPt( pad->GetPos0() );
641 
642  int layerCount = aBoard->GetCopperLayerCount();
643 
644  for( int layer=0; layer<layerCount; ++layer )
645  {
646  KEEPOUT* keepout = new KEEPOUT( image, T_keepout );
647 
648  image->keepouts.push_back( keepout );
649 
650  CIRCLE* circle = new CIRCLE( keepout );
651 
652  keepout->SetShape( circle );
653 
654  circle->SetDiameter( diameter );
655  circle->SetVertex( vertex );
656  circle->SetLayerId( layerIds[layer].c_str() );
657  }
658  }
659  // else if() could there be a square keepout here?
660 
661  else
662  {
663  // Pads not on copper layers (i.e. only on tech layers) are ignored
664  // because they create invalid pads in .dsn file for freeroute
665  LSET mask_copper_layers = pad->GetLayerSet() & LSET::AllCuMask();
666 
667  if( !mask_copper_layers.any() )
668  continue;
669 
670  PADSTACK* padstack = makePADSTACK( aBoard, pad );
671  PADSTACKSET::iterator iter = padstackset.find( *padstack );
672 
673  if( iter != padstackset.end() )
674  {
675  // padstack is a duplicate, delete it and use the original
676  delete padstack;
677  padstack = (PADSTACK*) *iter.base(); // folklore, be careful here
678  }
679  else
680  {
681  padstackset.insert( padstack );
682  }
683 
684  PIN* pin = new PIN( image );
685 
686  padName = pad->GetName();
687  pin->pin_id = TO_UTF8( padName );
688 
689  if( padName!=wxEmptyString && pinmap.find( padName )==pinmap.end() )
690  {
691  pinmap[ padName ] = 0;
692  }
693  else // pad name is a duplicate within this module
694  {
695  char buf[32];
696 
697  int duplicates = ++pinmap[ padName ];
698 
699  sprintf( buf, "@%d", duplicates );
700 
701  pin->pin_id += buf; // append "@1" or "@2", etc. to pin name
702  }
703 
704  pin->kiNetCode = pad->GetNetCode();
705 
706  image->pins.push_back( pin );
707 
708  pin->padstack_id = padstack->padstack_id;
709 
710  double angle = pad->GetOrientationDegrees() - aModule->GetOrientationDegrees();
712  pin->SetRotation( angle );
713 
714  wxPoint pos( pad->GetPos0() );
715 
716  pin->SetVertex( mapPt( pos ) );
717  }
718  }
719 
720 #if 1 // enable image (outline) scopes.
721  static const KICAD_T scanEDGEs[] = { PCB_MODULE_EDGE_T, EOT };
722 
723  // get all the MODULE's EDGE_MODULEs and convert those to DSN outlines.
724  moduleItems.Collect( aModule, scanEDGEs );
725 
726  for( int i = 0; i<moduleItems.GetCount(); ++i )
727  {
728  EDGE_MODULE* graphic = (EDGE_MODULE*) moduleItems[i];
729  SHAPE* outline;
730  PATH* path;
731 
732  switch( graphic->GetShape() )
733  {
734  case S_SEGMENT:
735  outline = new SHAPE( image, T_outline );
736 
737  image->Append( outline );
738  path = new PATH( outline );
739 
740  outline->SetShape( path );
741  path->SetAperture( scale( graphic->GetWidth() ) );
742  path->SetLayerId( "signal" );
743  path->AppendPoint( mapPt( graphic->GetStart0() ) );
744  path->AppendPoint( mapPt( graphic->GetEnd0() ) );
745  break;
746 
747  case S_CIRCLE:
748  {
749  // this is best done by 4 QARC's but freerouter does not yet support QARCs.
750  // for now, support by using line segments.
751 
752  outline = new SHAPE( image, T_outline );
753 
754  image->Append( outline );
755  path = new PATH( outline );
756 
757  outline->SetShape( path );
758  path->SetAperture( scale( graphic->GetWidth() ) );
759  path->SetLayerId( "signal" );
760 
761  // Do the math using KiCad units, that way we stay out of the
762  // scientific notation range of floating point numbers in the
763  // DSN file. We do not parse scientific notation in our own
764  // lexer/beautifier, and the spec is not clear that this is
765  // required. Fixed point floats are all that should be needed.
766 
767  double radius = GetLineLength( graphic->GetStart(), graphic->GetEnd() );
768 
769  // seg count to approximate circle by line segments
770  int seg_per_circle = GetArcToSegmentCount( radius, ARC_LOW_DEF, 360.0 );
771 
772  for( int ii = 0; ii < seg_per_circle; ++ii )
773  {
774  double radians = 2*M_PI / seg_per_circle * ii;
775  wxPoint point( KiROUND( radius * cos( radians ) ),
776  KiROUND( radius * sin( radians ) ) );
777 
778  point += graphic->m_Start0; // an offset
779 
780  path->AppendPoint( mapPt( point ) );
781  }
782  // The shape must be closed
783  wxPoint point( radius , 0 );
784  point += graphic->m_Start0;
785  path->AppendPoint( mapPt( point ) );
786  }
787  break;
788 
789  case S_RECT:
790  case S_ARC:
791  default:
792  DBG( printf( "makeIMAGE(): unsupported shape %s\n",
793  TO_UTF8( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) ); )
794  continue;
795  }
796  }
797 
798 #endif
799 
800  return image;
801 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:106
static wxString ShowShape(STROKE_T aShape)
Function ShowShape converts the enum STROKE_T integer value to a wxString.
void SetAperture(double aWidth)
Definition: specctra.h:607
std::string pin_id
Definition: specctra.h:1929
static bool isRoundKeepout(D_PAD *aPad)
Function isRoundKeepout decides if the pad is a copper-less through hole which needs to be made into ...
std::map< wxString, int > PINMAP
data type used to ensure unique-ness of pin names, holding (wxString and int)
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB...
Definition: trigo.h:191
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:106
KEEPOUTS keepouts
Definition: specctra.h:1997
PINS pins
Definition: specctra.h:1992
PADSTACKSET padstackset
Definition: specctra.h:3638
static POINT mapPt(const wxPoint &pt)
Function mapPt converts a KiCad point into a DSN file point.
const wxPoint & GetEnd0() const
int GetCopperLayerCount() const
Function GetCopperLayerCount.
void SetLayerId(const char *aLayerId)
Definition: specctra.h:602
void SetLayerId(const char *aLayerId)
Definition: specctra.h:753
int kiNetCode
KiCad netcode.
Definition: specctra.h:1932
const wxPoint & GetPos0() const
Definition: class_pad.h:263
usual segment : line with rounded ends
void AppendPoint(const POINT &aPoint)
Definition: specctra.h:595
void NORMALIZE_ANGLE_DEGREES_POS(double &Angle)
Definition: trigo.h:259
void SetRotation(double aRotation)
Definition: specctra.h:1944
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
void SetVertex(const POINT &aPoint)
Definition: specctra.h:1950
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
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 SetShape(ELEM *aShape)
Definition: specctra.h:852
PADSTACK * makePADSTACK(BOARD *aBoard, D_PAD *aPad)
Function makePADSTACK creates a PADSTACK which matches the given pad.
static const KICAD_T scanPADs[]
Definition: specctra.h:3636
Class PATH supports both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec...
Definition: specctra.h:576
const LIB_ID & GetFPID() const
Definition: class_module.h:191
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
segment with non rounded ends
void SetShape(ELEM *aShape)
Definition: specctra.h:929
STROKE_T GetShape() const
Class LSET is a set of PCB_LAYER_IDs.
std::string image_id
Definition: specctra.h:1983
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
double GetOrientationDegrees() const
Definition: class_module.h:188
Arcs (with rounded ends)
const int seg_per_circle
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:402
const wxString & GetName() const
Definition: class_pad.h:190
Class PADSTACK holds either a via or a pad definition.
Definition: specctra.h:2098
void Append(ELEM *aElem)
Definition: specctra.h:321
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Collect BOARD_ITEM objects using this class&#39;s Inspector method, which does the collection.
Definition: collectors.cpp:498
std::string padstack_id
Definition: specctra.h:1926
int GetNetCode() const
Function GetNetCode.
Class SHAPE corresponds to the "(shape ..)" element in the specctra dsn spec.
Definition: specctra.h:1863
Struct POINT is a holder for a point in the SPECCTRA DSN coordinate system.
Definition: specctra.h:94
const wxPoint & GetStart0() const
STRINGS layerIds
indexed by PCB layer number
Definition: specctra.h:3622
const char * c_str() const
Definition: utf8.h:107
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
size_t i
Definition: json11.cpp:597
static double scale(int kicadDist)
Function scale converts a distance from PCBNEW internal units to the reported specctra dsn units in f...
int GetWidth() const
std::string padstack_id
Definition: specctra.h:2104
UTF8 Format() const
Definition: lib_id.cpp:263
#define DBG(x)
Definition: fctsys.h:33
void SetVertex(const POINT &aVertex)
Definition: specctra.h:763
wxPoint m_Start0
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition: collectors.h:590
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Class KEEPOUT is used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:884
void SetDiameter(double aDiameter)
Definition: specctra.h:758
double GetOrientationDegrees() const
Definition: class_pad.h:383
PADSTACK * DSN::SPECCTRA_DB::makePADSTACK ( BOARD aBoard,
D_PAD aPad 
)
private

Function makePADSTACK creates a PADSTACK which matches the given pad.

Only pads which do not satisfy the function isKeepout() should be passed to this function.

Parameters
aBoardThe owner of the MODULE.
aPadThe D_PAD which needs to be made into a PADSTACK.
Returns
PADSTACK* - The created padstack, including its padstack_id.

Definition at line 261 of file specctra_export.cpp.

References abs, LSET::AllCuMask(), DSN::PATH::aperture_width, DSN::ELEM_HOLDER::Append(), DSN::PATH::AppendPoint(), BuildConvexHull(), SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), D_PAD::GetBoundingBox(), BOARD::GetCopperLayerCount(), D_PAD::GetCustomShapeAsPolygon(), D_PAD::GetDelta(), EDA_RECT::GetHeight(), D_PAD::GetLayerSet(), D_PAD::GetOffset(), D_PAD::GetRoundRectCornerRadius(), D_PAD::GetShape(), D_PAD::GetSize(), EDA_RECT::GetWidth(), D_PAD::IsOnLayer(), DSN::isRoundKeepout(), DSN::IU2um(), KiROUND(), layerIds, DSN::makePath(), DSN::mapPt(), MAX_CU_LAYERS, name, SHAPE_POLY_SET::Outline(), PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, pcbLayer2kicad, SHAPE_LINE_CHAIN::Point(), SHAPE_LINE_CHAIN::PointCount(), DSN::scale(), DSN::RECTANGLE::SetCorners(), DSN::CIRCLE::SetDiameter(), DSN::RECTANGLE::SetLayerId(), DSN::PATH::SetLayerId(), DSN::CIRCLE::SetLayerId(), DSN::PADSTACK::SetPadstackId(), DSN::WINDOW::SetShape(), DSN::CIRCLE::SetVertex(), TransformRoundRectToPolygon(), wxPoint::x, VECTOR2< T >::x, wxPoint::y, and VECTOR2< T >::y.

Referenced by makeIMAGE().

262 {
263  char name[256]; // padstack name builder
264  std::string uniqifier;
265 
266  // caller must do these checks before calling here.
267  wxASSERT( !isRoundKeepout( aPad ) );
268 
269  PADSTACK* padstack = new PADSTACK();
270 
271  int reportedLayers = 0; // how many in reported padstack
272  const char* layerName[MAX_CU_LAYERS];
273 
274  uniqifier = '[';
275 
276  static const LSET all_cu = LSET::AllCuMask();
277 
278  bool onAllCopperLayers = ( (aPad->GetLayerSet() & all_cu) == all_cu );
279 
280  if( onAllCopperLayers )
281  uniqifier += 'A'; // A for all layers
282 
283  const int copperCount = aBoard->GetCopperLayerCount();
284 
285  for( int layer=0; layer<copperCount; ++layer )
286  {
287  PCB_LAYER_ID kilayer = pcbLayer2kicad[layer];
288 
289  if( onAllCopperLayers || aPad->IsOnLayer( kilayer ) )
290  {
291  layerName[reportedLayers++] = layerIds[layer].c_str();
292 
293  if( !onAllCopperLayers )
294  {
295  if( layer == 0 )
296  uniqifier += 'T';
297  else if( layer == copperCount - 1 )
298  uniqifier += 'B';
299  else
300  uniqifier += char('0' + layer); // layer index char
301  }
302  }
303  }
304 
305  uniqifier += ']';
306 
307  POINT dsnOffset;
308 
309  if( aPad->GetOffset().x || aPad->GetOffset().y )
310  {
311  char offsetTxt[64];
312 
313  wxPoint offset( aPad->GetOffset().x, aPad->GetOffset().y );
314 
315  dsnOffset = mapPt( offset );
316 
317  // using '(' or ')' would cause padstack name to be quote wrapped,
318  // so use other brackets, and {} locks freerouter.
319  sprintf( offsetTxt, "[%.6g,%.6g]", dsnOffset.x, dsnOffset.y );
320 
321  uniqifier += offsetTxt;
322  }
323 
324  switch( aPad->GetShape() )
325  {
326  default:
327  case PAD_SHAPE_CIRCLE:
328  {
329  double diameter = scale( aPad->