You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4023 lines
92 KiB

18 years ago
4 years ago
4 years ago
12 years ago
9 years ago
18 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
18 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2007-2021 KiCad Developers, see change_log.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /*
  25. * This source file implements export and import capabilities to the
  26. * specctra dsn file format. The grammar for that file format is documented
  27. * fairly well. There are classes for each major type of descriptor in the
  28. * spec.
  29. *
  30. * Since there are so many classes in here, it may be helpful to generate
  31. * the Doxygen directory:
  32. *
  33. * $ cd <kicadSourceRoot>
  34. * $ doxygen
  35. *
  36. * Then you can view the html documentation in the <kicadSourceRoot>/doxygen
  37. * directory. The main class in this file is SPECCTRA_DB and its main
  38. * functions are LoadPCB(), LoadSESSION(), and ExportPCB().
  39. *
  40. * Wide use is made of boost::ptr_vector<> and std::vector<> template classes.
  41. * If the contained object is small, then std::vector tends to be used.
  42. * If the contained object is large, variable size, or would require writing
  43. * an assignment operator() or copy constructor, then boost::ptr_vector
  44. * cannot be beat.
  45. */
  46. #include <cstdarg>
  47. #include <cstdio>
  48. #include <build_version.h>
  49. #include <board.h>
  50. #include <pcb_track.h>
  51. #include "specctra.h"
  52. #include <macros.h>
  53. namespace DSN {
  54. #define NESTWIDTH 2 ///< how many spaces per nestLevel
  55. //-----<SPECCTRA_DB>-------------------------------------------------
  56. const char* GetTokenText( T aTok )
  57. {
  58. return SPECCTRA_LEXER::TokenName( aTok );
  59. }
  60. void SPECCTRA_DB::buildLayerMaps( BOARD* aBoard )
  61. {
  62. // specctra wants top physical layer first, then going down to the
  63. // bottom most physical layer in physical sequence.
  64. // Same as KiCad now except for B_Cu
  65. unsigned layerCount = aBoard->GetCopperLayerCount();
  66. m_layerIds.clear();
  67. m_pcbLayer2kicad.resize( layerCount );
  68. m_kicadLayer2pcb.resize( B_Cu + 1 );
  69. #if 0 // was:
  70. for( int kiNdx = layerCount - 1, pcbNdx=FIRST_LAYER; kiNdx >= 0; --kiNdx, ++pcbNdx )
  71. {
  72. int kilayer = (kiNdx>0 && kiNdx==layerCount-1) ? F_Cu : kiNdx;
  73. // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
  74. pcbLayer2kicad[pcbNdx] = kilayer;
  75. kicadLayer2pcb[kilayer] = pcbNdx;
  76. // save the specctra layer name in SPECCTRA_DB::layerIds for later.
  77. layerIds.push_back( TO_UTF8( aBoard->GetLayerName( ToLAYER_ID( kilayer ) ) ) );
  78. }
  79. #else
  80. // establish bi-directional mapping between KiCad's BOARD layer and PCB layer
  81. for( unsigned i = 0; i < m_kicadLayer2pcb.size(); ++i )
  82. {
  83. if( i < layerCount-1 )
  84. m_kicadLayer2pcb[i] = i;
  85. else
  86. m_kicadLayer2pcb[i] = layerCount - 1;
  87. }
  88. for( unsigned i = 0; i < m_pcbLayer2kicad.size(); ++i )
  89. {
  90. PCB_LAYER_ID id = ( i < layerCount-1 ) ? ToLAYER_ID( i ) : B_Cu;
  91. m_pcbLayer2kicad[i] = id;
  92. // save the specctra layer name in SPECCTRA_DB::layerIds for later.
  93. m_layerIds.push_back(TO_UTF8( aBoard->GetLayerName( id ) ) );
  94. }
  95. #endif
  96. }
  97. int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const
  98. {
  99. for( int i = 0; i < int( m_layerIds.size() ); ++i )
  100. {
  101. if( 0 == aLayerName.compare( m_layerIds[i] ) )
  102. return i;
  103. }
  104. return -1;
  105. }
  106. void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id )
  107. {
  108. T tok;
  109. static const char pin_def[] = "<pin_reference>::=<component_id>-<pin_id>";
  110. if( !IsSymbol( (T) CurTok() ) )
  111. Expecting( pin_def );
  112. // case for: A12-14, i.e. no wrapping quotes. This should be a single
  113. // token, so split it.
  114. if( CurTok() != T_STRING )
  115. {
  116. const char* toktext = CurText();
  117. const char* dash = strchr( toktext, '-' );
  118. if( !dash )
  119. Expecting( pin_def );
  120. while( toktext != dash )
  121. *component_id += *toktext++;
  122. ++toktext; // skip the dash
  123. while( *toktext )
  124. *pin_id += *toktext++;
  125. }
  126. else // quoted string: "U12"-"14" or "U12"-14, 3 tokens in either case
  127. {
  128. *component_id = CurText();
  129. tok = NextTok();
  130. if( tok!=T_DASH )
  131. Expecting( pin_def );
  132. NextTok(); // accept anything after the dash.
  133. *pin_id = CurText();
  134. }
  135. }
  136. void SPECCTRA_DB::readTIME( time_t* time_stamp )
  137. {
  138. T tok;
  139. struct tm mytime;
  140. static const char time_toks[] = "<month> <day> <hour> : <minute> : <second> <year>";
  141. static const char* months[] = { // index 0 = Jan
  142. "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  143. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", nullptr
  144. };
  145. NeedSYMBOL(); // month
  146. const char* ptok = CurText();
  147. mytime.tm_mon = 0; // remains if we don't find a month match.
  148. for( int m = 0; months[m]; ++m )
  149. {
  150. if( !strcasecmp( months[m], ptok ) )
  151. {
  152. mytime.tm_mon = m;
  153. break;
  154. }
  155. }
  156. tok = NextTok(); // day
  157. if( tok != T_NUMBER )
  158. Expecting( time_toks );
  159. mytime.tm_mday = atoi( CurText() );
  160. tok = NextTok(); // hour
  161. if( tok != T_NUMBER )
  162. Expecting( time_toks );
  163. mytime.tm_hour = atoi( CurText() );
  164. // : colon
  165. NeedSYMBOL();
  166. if( *CurText() != ':' || strlen( CurText() )!=1 )
  167. Expecting( time_toks );
  168. tok = NextTok(); // minute
  169. if( tok != T_NUMBER )
  170. Expecting( time_toks );
  171. mytime.tm_min = atoi( CurText() );
  172. // : colon
  173. NeedSYMBOL();
  174. if( *CurText() != ':' || strlen( CurText() )!=1 )
  175. Expecting( time_toks );
  176. tok = NextTok(); // second
  177. if( tok != T_NUMBER )
  178. Expecting( time_toks );
  179. mytime.tm_sec = atoi( CurText() );
  180. tok = NextTok(); // year
  181. if( tok != T_NUMBER )
  182. Expecting( time_toks );
  183. mytime.tm_year = atoi( CurText() ) - 1900;
  184. *time_stamp = mktime( &mytime );
  185. }
  186. void SPECCTRA_DB::LoadPCB( const wxString& aFilename )
  187. {
  188. FILE_LINE_READER curr_reader( aFilename );
  189. PushReader( &curr_reader );
  190. if( NextTok() != T_LEFT )
  191. Expecting( T_LEFT );
  192. if( NextTok() != T_pcb )
  193. Expecting( T_pcb );
  194. SetPCB( new PCB() );
  195. doPCB( m_pcb );
  196. PopReader();
  197. }
  198. void SPECCTRA_DB::LoadSESSION( const wxString& aFilename )
  199. {
  200. FILE_LINE_READER curr_reader( aFilename );
  201. PushReader( &curr_reader );
  202. if( NextTok() != T_LEFT )
  203. Expecting( T_LEFT );
  204. if( NextTok() != T_session )
  205. Expecting( T_session );
  206. SetSESSION( new SESSION() );
  207. doSESSION( m_session );
  208. PopReader();
  209. }
  210. void SPECCTRA_DB::doPCB( PCB* growth )
  211. {
  212. T tok;
  213. /* <design_descriptor >::=
  214. (pcb <pcb_id >
  215. [<parser_descriptor> ]
  216. [<capacitance_resolution_descriptor> ]
  217. [<conductance_resolution_descriptor> ]
  218. [<current_resolution_descriptor> ]
  219. [<inductance_resolution_descriptor> ]
  220. [<resistance_resolution_descriptor> ]
  221. [<resolution_descriptor> ]
  222. [<time_resolution_descriptor> ]
  223. [<voltage_resolution_descriptor> ]
  224. [<unit_descriptor> ]
  225. [<structure_descriptor> | <file_descriptor> ]
  226. [<placement_descriptor> | <file_descriptor> ]
  227. [<library_descriptor> | <file_descriptor> ]
  228. [<floor_plan_descriptor> | <file_descriptor> ]
  229. [<part_library_descriptor> | <file_descriptor> ]
  230. [<network_descriptor> | <file_descriptor> ]
  231. [<wiring_descriptor> ]
  232. [<color_descriptor> ]
  233. )
  234. */
  235. NeedSYMBOL();
  236. growth->pcbname = CurText();
  237. while( (tok = NextTok()) != T_RIGHT )
  238. {
  239. if( tok != T_LEFT )
  240. Expecting( T_LEFT );
  241. tok = NextTok();
  242. switch( tok )
  243. {
  244. case T_parser:
  245. if( growth->parser )
  246. Unexpected( tok );
  247. growth->parser = new PARSER( growth );
  248. doPARSER( growth->parser );
  249. break;
  250. case T_unit:
  251. if( growth->unit )
  252. Unexpected( tok );
  253. growth->unit = new UNIT_RES( growth, tok );
  254. doUNIT( growth->unit );
  255. break;
  256. case T_resolution:
  257. if( growth->resolution )
  258. Unexpected( tok );
  259. growth->resolution = new UNIT_RES( growth, tok );
  260. doRESOLUTION( growth->resolution );
  261. break;
  262. case T_structure:
  263. if( growth->structure )
  264. Unexpected( tok );
  265. growth->structure = new STRUCTURE( growth );
  266. doSTRUCTURE( growth->structure );
  267. break;
  268. case T_placement:
  269. if( growth->placement )
  270. Unexpected( tok );
  271. growth->placement = new PLACEMENT( growth );
  272. doPLACEMENT( growth->placement );
  273. break;
  274. case T_library:
  275. if( growth->library )
  276. Unexpected( tok );
  277. growth->library = new LIBRARY( growth );
  278. doLIBRARY( growth->library );
  279. break;
  280. case T_network:
  281. if( growth->network )
  282. Unexpected( tok );
  283. growth->network = new NETWORK( growth );
  284. doNETWORK( growth->network );
  285. break;
  286. case T_wiring:
  287. if( growth->wiring )
  288. Unexpected( tok );
  289. growth->wiring = new WIRING( growth );
  290. doWIRING( growth->wiring );
  291. break;
  292. default:
  293. Unexpected( CurText() );
  294. }
  295. }
  296. tok = NextTok();
  297. if( tok != T_EOF )
  298. Expecting( T_EOF );
  299. }
  300. void SPECCTRA_DB::doPARSER( PARSER* growth )
  301. {
  302. T tok;
  303. std::string const1;
  304. std::string const2;
  305. /* <parser_descriptor >::=
  306. (parser
  307. [(string_quote <quote_char >)]
  308. (space_in_quoted_tokens [on | off])
  309. [(host_cad <id >)]
  310. [(host_version <id >)]
  311. [{(constant <id > <id >)}]
  312. [(write_resolution] {<character> <positive_integer >})]
  313. [(routes_include {[testpoint | guides |
  314. image_conductor]})]
  315. [(wires_include testpoint)]
  316. [(case_sensitive [on | off])]
  317. [(via_rotate_first [on | off])]
  318. )
  319. */
  320. while( (tok = NextTok()) != T_RIGHT )
  321. {
  322. if( tok != T_LEFT )
  323. Expecting( T_LEFT );
  324. tok = NextTok();
  325. switch( tok )
  326. {
  327. case T_STRING_QUOTE:
  328. tok = NextTok();
  329. if( tok != T_QUOTE_DEF )
  330. Expecting( T_QUOTE_DEF );
  331. SetStringDelimiter( (unsigned char) *CurText() );
  332. growth->string_quote = *CurText();
  333. m_quote_char = CurText();
  334. NeedRIGHT();
  335. break;
  336. case T_space_in_quoted_tokens:
  337. tok = NextTok();
  338. if( tok!=T_on && tok!=T_off )
  339. Expecting( "on|off" );
  340. SetSpaceInQuotedTokens( tok==T_on );
  341. growth->space_in_quoted_tokens = (tok==T_on);
  342. NeedRIGHT();
  343. break;
  344. case T_host_cad:
  345. NeedSYMBOL();
  346. growth->host_cad = CurText();
  347. NeedRIGHT();
  348. break;
  349. case T_host_version:
  350. NeedSYMBOLorNUMBER();
  351. growth->host_version = CurText();
  352. NeedRIGHT();
  353. break;
  354. case T_constant:
  355. NeedSYMBOLorNUMBER();
  356. const1 = CurText();
  357. NeedSYMBOLorNUMBER();
  358. const2 = CurText();
  359. NeedRIGHT();
  360. growth->constants.push_back( const1 );
  361. growth->constants.push_back( const2 );
  362. break;
  363. case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
  364. while( (tok = NextTok()) != T_RIGHT )
  365. {
  366. if( tok!=T_SYMBOL )
  367. Expecting( T_SYMBOL );
  368. tok = NextTok();
  369. if( tok!=T_NUMBER )
  370. Expecting( T_NUMBER );
  371. // @todo
  372. }
  373. break;
  374. case T_routes_include: // [(routes_include {[testpoint | guides | image_conductor]})]
  375. while( (tok = NextTok()) != T_RIGHT )
  376. {
  377. switch( tok )
  378. {
  379. case T_testpoint:
  380. growth->routes_include_testpoint = true;
  381. break;
  382. case T_guide:
  383. growth->routes_include_guides = true;
  384. break;
  385. case T_image_conductor:
  386. growth->routes_include_image_conductor = true;
  387. break;
  388. default:
  389. Expecting( "testpoint|guides|image_conductor" );
  390. }
  391. }
  392. break;
  393. case T_wires_include: // [(wires_include testpoint)]
  394. tok = NextTok();
  395. if( tok != T_testpoint )
  396. Expecting( T_testpoint );
  397. growth->routes_include_testpoint = true;
  398. NeedRIGHT();
  399. break;
  400. case T_case_sensitive:
  401. tok = NextTok();
  402. if( tok!=T_on && tok!=T_off )
  403. Expecting( "on|off" );
  404. growth->case_sensitive = (tok==T_on);
  405. NeedRIGHT();
  406. break;
  407. case T_via_rotate_first: // [(via_rotate_first [on | off])]
  408. tok = NextTok();
  409. if( tok!=T_on && tok!=T_off )
  410. Expecting( "on|off" );
  411. growth->via_rotate_first = (tok==T_on);
  412. NeedRIGHT();
  413. break;
  414. case T_generated_by_freeroute:
  415. growth->generated_by_freeroute = true;
  416. NeedRIGHT();
  417. break;
  418. default:
  419. Unexpected( CurText() );
  420. }
  421. }
  422. }
  423. void SPECCTRA_DB::doRESOLUTION( UNIT_RES* growth )
  424. {
  425. T tok = NextTok();
  426. switch( tok )
  427. {
  428. case T_inch:
  429. case T_mil:
  430. case T_cm:
  431. case T_mm:
  432. case T_um:
  433. growth->units = tok;
  434. break;
  435. default:
  436. Expecting( "inch|mil|cm|mm|um" );
  437. }
  438. tok = NextTok();
  439. if( tok != T_NUMBER )
  440. Expecting( T_NUMBER );
  441. growth->value = atoi( CurText() );
  442. NeedRIGHT();
  443. }
  444. void SPECCTRA_DB::doUNIT( UNIT_RES* growth )
  445. {
  446. T tok = NextTok();
  447. switch( tok )
  448. {
  449. case T_inch:
  450. case T_mil:
  451. case T_cm:
  452. case T_mm:
  453. case T_um:
  454. growth->units = tok;
  455. break;
  456. default:
  457. Expecting( "inch|mil|cm|mm|um" );
  458. }
  459. NeedRIGHT();
  460. }
  461. void SPECCTRA_DB::doSPECCTRA_LAYER_PAIR( SPECCTRA_LAYER_PAIR* growth )
  462. {
  463. NeedSYMBOL();
  464. growth->layer_id0 = CurText();
  465. NeedSYMBOL();
  466. growth->layer_id1 = CurText();
  467. if( NextTok() != T_NUMBER )
  468. Expecting( T_NUMBER );
  469. growth->layer_weight = strtod( CurText(), 0 );
  470. NeedRIGHT();
  471. }
  472. void SPECCTRA_DB::doLAYER_NOISE_WEIGHT( LAYER_NOISE_WEIGHT* growth )
  473. {
  474. T tok;
  475. while( ( tok = NextTok() ) != T_RIGHT )
  476. {
  477. if( tok != T_LEFT )
  478. Expecting( T_LEFT );
  479. if( NextTok() != T_layer_pair )
  480. Expecting( T_layer_pair );
  481. SPECCTRA_LAYER_PAIR* layer_pair = new SPECCTRA_LAYER_PAIR( growth );
  482. growth->layer_pairs.push_back( layer_pair );
  483. doSPECCTRA_LAYER_PAIR( layer_pair );
  484. }
  485. }
  486. void SPECCTRA_DB::doSTRUCTURE( STRUCTURE* growth )
  487. {
  488. T tok;
  489. while( ( tok = NextTok() ) != T_RIGHT )
  490. {
  491. if( tok != T_LEFT )
  492. Expecting( T_LEFT );
  493. tok = NextTok();
  494. switch( tok )
  495. {
  496. case T_unit:
  497. if( growth->unit )
  498. Unexpected( tok );
  499. growth->unit = new UNIT_RES( growth, tok );
  500. doUNIT( growth->unit );
  501. break;
  502. case T_resolution:
  503. if( growth->unit )
  504. Unexpected( tok );
  505. growth->unit = new UNIT_RES( growth, tok );
  506. doRESOLUTION( growth->unit );
  507. break;
  508. case T_layer_noise_weight:
  509. if( growth->layer_noise_weight )
  510. Unexpected( tok );
  511. growth->layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
  512. doLAYER_NOISE_WEIGHT( growth->layer_noise_weight );
  513. break;
  514. case T_place_boundary:
  515. L_place:
  516. if( growth->place_boundary )
  517. Unexpected( tok );
  518. growth->place_boundary = new BOUNDARY( growth, T_place_boundary );
  519. doBOUNDARY( growth->place_boundary );
  520. break;
  521. case T_boundary:
  522. if( growth->boundary )
  523. {
  524. if( growth->place_boundary )
  525. Unexpected( tok );
  526. goto L_place;
  527. }
  528. growth->boundary = new BOUNDARY( growth );
  529. doBOUNDARY( growth->boundary );
  530. break;
  531. case T_plane:
  532. COPPER_PLANE* plane;
  533. plane = new COPPER_PLANE( growth );
  534. growth->planes.push_back( plane );
  535. doKEEPOUT( plane );
  536. break;
  537. case T_region:
  538. REGION* region;
  539. region = new REGION( growth );
  540. growth->regions.push_back( region );
  541. doREGION( region );
  542. break;
  543. case T_snap_angle:
  544. STRINGPROP* stringprop;
  545. stringprop = new STRINGPROP( growth, T_snap_angle );
  546. growth->Append( stringprop );
  547. doSTRINGPROP( stringprop );
  548. break;
  549. case T_via:
  550. if( growth->via )
  551. Unexpected( tok );
  552. growth->via = new VIA( growth );
  553. doVIA( growth->via );
  554. break;
  555. case T_control:
  556. if( growth->control )
  557. Unexpected( tok );
  558. growth->control = new CONTROL( growth );
  559. doCONTROL( growth->control );
  560. break;
  561. case T_layer:
  562. LAYER* layer;
  563. layer = new LAYER( growth );
  564. growth->layers.push_back( layer );
  565. doLAYER( layer );
  566. break;
  567. case T_rule:
  568. if( growth->rules )
  569. Unexpected( tok );
  570. growth->rules = new RULE( growth, T_rule );
  571. doRULE( growth->rules );
  572. break;
  573. case T_place_rule:
  574. if( growth->place_rules )
  575. Unexpected( tok );
  576. growth->place_rules = new RULE( growth, T_place_rule );
  577. doRULE( growth->place_rules );
  578. break;
  579. case T_keepout:
  580. case T_place_keepout:
  581. case T_via_keepout:
  582. case T_wire_keepout:
  583. case T_bend_keepout:
  584. case T_elongate_keepout:
  585. KEEPOUT* keepout;
  586. keepout = new KEEPOUT( growth, tok );
  587. growth->keepouts.push_back( keepout );
  588. doKEEPOUT( keepout );
  589. break;
  590. case T_grid:
  591. GRID* grid;
  592. grid = new GRID( growth );
  593. growth->grids.push_back( grid );
  594. doGRID( grid );
  595. break;
  596. default:
  597. Unexpected( CurText() );
  598. }
  599. }
  600. }
  601. void SPECCTRA_DB::doSTRUCTURE_OUT( STRUCTURE_OUT* growth )
  602. {
  603. /*
  604. <structure_out_descriptor >::=
  605. (structure_out
  606. {<layer_descriptor> }
  607. [<rule_descriptor> ]
  608. )
  609. */
  610. T tok = NextTok();
  611. while( tok != T_RIGHT )
  612. {
  613. if( tok != T_LEFT )
  614. Expecting( T_LEFT );
  615. tok = NextTok();
  616. switch( tok )
  617. {
  618. case T_layer:
  619. LAYER* layer;
  620. layer = new LAYER( growth );
  621. growth->layers.push_back( layer );
  622. doLAYER( layer );
  623. break;
  624. case T_rule:
  625. if( growth->rules )
  626. Unexpected( tok );
  627. growth->rules = new RULE( growth, T_rule );
  628. doRULE( growth->rules );
  629. break;
  630. default:
  631. Unexpected( CurText() );
  632. }
  633. tok = NextTok();
  634. }
  635. }
  636. void SPECCTRA_DB::doKEEPOUT( KEEPOUT* growth )
  637. {
  638. T tok = NextTok();
  639. if( IsSymbol(tok) )
  640. {
  641. growth->name = CurText();
  642. tok = NextTok();
  643. }
  644. if( tok!=T_LEFT )
  645. Expecting( T_LEFT );
  646. while( tok != T_RIGHT )
  647. {
  648. if( tok!=T_LEFT )
  649. Expecting( T_LEFT );
  650. tok = NextTok();
  651. switch( tok )
  652. {
  653. case T_sequence_number:
  654. if( NextTok() != T_NUMBER )
  655. Expecting( T_NUMBER );
  656. growth->sequence_number = atoi( CurText() );
  657. NeedRIGHT();
  658. break;
  659. case T_rule:
  660. if( growth->rules )
  661. Unexpected( tok );
  662. growth->rules = new RULE( growth, T_rule );
  663. doRULE( growth->rules );
  664. break;
  665. case T_place_rule:
  666. if( growth->place_rules )
  667. Unexpected( tok );
  668. growth->place_rules = new RULE( growth, T_place_rule );
  669. doRULE( growth->place_rules );
  670. break;
  671. case T_rect:
  672. if( growth->shape )
  673. Unexpected( tok );
  674. growth->shape = new RECTANGLE( growth );
  675. doRECTANGLE( (RECTANGLE*) growth->shape );
  676. break;
  677. case T_circle:
  678. if( growth->shape )
  679. Unexpected( tok );
  680. growth->shape = new CIRCLE( growth );
  681. doCIRCLE( (CIRCLE*) growth->shape );
  682. break;
  683. case T_polyline_path:
  684. tok = T_path;
  685. KI_FALLTHROUGH;
  686. case T_path:
  687. case T_polygon:
  688. if( growth->shape )
  689. Unexpected( tok );
  690. growth->shape = new PATH( growth, tok );
  691. doPATH( (PATH*) growth->shape );
  692. break;
  693. case T_qarc:
  694. if( growth->shape )
  695. Unexpected( tok );
  696. growth->shape = new QARC( growth );
  697. doQARC( (QARC*) growth->shape );
  698. break;
  699. case T_window:
  700. WINDOW* window;
  701. window = new WINDOW( growth );
  702. growth->windows.push_back( window );
  703. doWINDOW( window );
  704. break;
  705. default:
  706. Unexpected( CurText() );
  707. }
  708. tok = NextTok();
  709. }
  710. }
  711. void SPECCTRA_DB::doCONNECT( CONNECT* growth )
  712. {
  713. /* from page 143 of specctra spec:
  714. (connect
  715. {(terminal <object_type> [<pin_reference> ])}
  716. )
  717. */
  718. T tok = NextTok();
  719. while( tok != T_RIGHT )
  720. {
  721. if( tok!=T_LEFT )
  722. Expecting( T_LEFT );
  723. tok = NextTok();
  724. switch( tok )
  725. {
  726. case T_terminal:
  727. // since we do not use the terminal information, simply toss it.
  728. while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
  729. ;
  730. break;
  731. default:
  732. Unexpected( CurText() );
  733. }
  734. tok = NextTok();
  735. }
  736. }
  737. void SPECCTRA_DB::doWINDOW( WINDOW* growth )
  738. {
  739. T tok = NextTok();
  740. while( tok != T_RIGHT )
  741. {
  742. if( tok!=T_LEFT )
  743. Expecting( T_LEFT );
  744. tok = NextTok();
  745. switch( tok )
  746. {
  747. case T_rect:
  748. if( growth->shape )
  749. Unexpected( tok );
  750. growth->shape = new RECTANGLE( growth );
  751. doRECTANGLE( (RECTANGLE*) growth->shape );
  752. break;
  753. case T_circle:
  754. if( growth->shape )
  755. Unexpected( tok );
  756. growth->shape = new CIRCLE( growth );
  757. doCIRCLE( (CIRCLE*) growth->shape );
  758. break;
  759. case T_polyline_path:
  760. tok = T_path;
  761. KI_FALLTHROUGH;
  762. case T_path:
  763. case T_polygon:
  764. if( growth->shape )
  765. Unexpected( tok );
  766. growth->shape = new PATH( growth, tok );
  767. doPATH( (PATH*) growth->shape );
  768. break;
  769. case T_qarc:
  770. if( growth->shape )
  771. Unexpected( tok );
  772. growth->shape = new QARC( growth );
  773. doQARC( (QARC*) growth->shape );
  774. break;
  775. default:
  776. Unexpected( CurText() );
  777. }
  778. tok = NextTok();
  779. }
  780. }
  781. void SPECCTRA_DB::doBOUNDARY( BOUNDARY* growth )
  782. {
  783. T tok = NextTok();
  784. if( tok != T_LEFT )
  785. Expecting( T_LEFT );
  786. tok = NextTok();
  787. if( tok == T_rect )
  788. {
  789. if( growth->paths.size() )
  790. Unexpected( "rect when path already encountered" );
  791. growth->rectangle = new RECTANGLE( growth );
  792. doRECTANGLE( growth->rectangle );
  793. NeedRIGHT();
  794. }
  795. else if( tok == T_path )
  796. {
  797. if( growth->rectangle )
  798. Unexpected( "path when rect already encountered" );
  799. for(;;)
  800. {
  801. if( tok != T_path )
  802. Expecting( T_path );
  803. PATH* path = new PATH( growth, T_path );
  804. growth->paths.push_back( path );
  805. doPATH( path );
  806. tok = NextTok();
  807. if( tok == T_RIGHT )
  808. break;
  809. if( tok != T_LEFT )
  810. Expecting(T_LEFT);
  811. tok = NextTok();
  812. }
  813. }
  814. else
  815. {
  816. Expecting( "rect|path" );
  817. }
  818. }
  819. void SPECCTRA_DB::doPATH( PATH* growth )
  820. {
  821. T tok = NextTok();
  822. if( !IsSymbol( tok ) && tok != T_NUMBER ) // a layer name can be like a number like +12
  823. Expecting( "layer_id" );
  824. growth->layer_id = CurText();
  825. if( NextTok() != T_NUMBER )
  826. Expecting( "aperture_width" );
  827. growth->aperture_width = strtod( CurText(), nullptr );
  828. POINT ptTemp;
  829. tok = NextTok();
  830. do
  831. {
  832. if( tok != T_NUMBER )
  833. Expecting( T_NUMBER );
  834. ptTemp.x = strtod( CurText(), nullptr );
  835. if( NextTok() != T_NUMBER )
  836. Expecting( T_NUMBER );
  837. ptTemp.y = strtod( CurText(), nullptr );
  838. growth->points.push_back( ptTemp );
  839. } while( ( tok = NextTok() ) != T_RIGHT && tok != T_LEFT );
  840. if( tok == T_LEFT )
  841. {
  842. if( NextTok() != T_aperture_type )
  843. Expecting( T_aperture_type );
  844. tok = NextTok();
  845. if( tok!=T_round && tok!=T_square )
  846. Expecting( "round|square" );
  847. growth->aperture_type = tok;
  848. NeedRIGHT();
  849. }
  850. }
  851. void SPECCTRA_DB::doRECTANGLE( RECTANGLE* growth )
  852. {
  853. NeedSYMBOL();
  854. growth->layer_id = CurText();
  855. if( NextTok() != T_NUMBER )
  856. Expecting( T_NUMBER );
  857. growth->point0.x = strtod( CurText(), nullptr );
  858. if( NextTok() != T_NUMBER )
  859. Expecting( T_NUMBER );
  860. growth->point0.y = strtod( CurText(), nullptr );
  861. if( NextTok() != T_NUMBER )
  862. Expecting( T_NUMBER );
  863. growth->point1.x = strtod( CurText(), nullptr );
  864. if( NextTok() != T_NUMBER )
  865. Expecting( T_NUMBER );
  866. growth->point1.y = strtod( CurText(), nullptr );
  867. NeedRIGHT();
  868. }
  869. void SPECCTRA_DB::doCIRCLE( CIRCLE* growth )
  870. {
  871. T tok;
  872. NeedSYMBOLorNUMBER();
  873. growth->layer_id = CurText();
  874. if( NextTok() != T_NUMBER )
  875. Expecting( T_NUMBER );
  876. growth->diameter = strtod( CurText(), 0 );
  877. tok = NextTok();
  878. if( tok == T_NUMBER )
  879. {
  880. growth->vertex.x = strtod( CurText(), 0 );
  881. if( NextTok() != T_NUMBER )
  882. Expecting( T_NUMBER );
  883. growth->vertex.y = strtod( CurText(), 0 );
  884. tok = NextTok();
  885. }
  886. if( tok != T_RIGHT )
  887. Expecting( T_RIGHT );
  888. }
  889. void SPECCTRA_DB::doQARC( QARC* growth )
  890. {
  891. NeedSYMBOL();
  892. growth->layer_id = CurText();
  893. if( NextTok() != T_NUMBER )
  894. Expecting( T_NUMBER );
  895. growth->aperture_width = strtod( CurText(), 0 );
  896. for( int i = 0; i < 3; ++i )
  897. {
  898. if( NextTok() != T_NUMBER )
  899. Expecting( T_NUMBER );
  900. growth->vertex[i].x = strtod( CurText(), 0 );
  901. if( NextTok() != T_NUMBER )
  902. Expecting( T_NUMBER );
  903. growth->vertex[i].y = strtod( CurText(), 0 );
  904. }
  905. NeedRIGHT();
  906. }
  907. void SPECCTRA_DB::doSTRINGPROP( STRINGPROP* growth )
  908. {
  909. NeedSYMBOL();
  910. growth->value = CurText();
  911. NeedRIGHT();
  912. }
  913. void SPECCTRA_DB::doTOKPROP( TOKPROP* growth )
  914. {
  915. T tok = NextTok();
  916. if( tok<0 )
  917. Unexpected( CurText() );
  918. growth->value = tok;
  919. NeedRIGHT();
  920. }
  921. void SPECCTRA_DB::doVIA( VIA* growth )
  922. {
  923. T tok;
  924. while( ( tok = NextTok() ) != T_RIGHT )
  925. {
  926. if( tok == T_LEFT )
  927. {
  928. if( NextTok() != T_spare )
  929. Expecting( T_spare );
  930. while( (tok = NextTok()) != T_RIGHT )
  931. {
  932. if( !IsSymbol( tok ) )
  933. Expecting( T_SYMBOL );
  934. growth->spares.push_back( CurText() );
  935. }
  936. }
  937. else if( IsSymbol( tok ) )
  938. {
  939. growth->padstacks.push_back( CurText() );
  940. }
  941. else
  942. {
  943. Unexpected( CurText() );
  944. }
  945. }
  946. }
  947. void SPECCTRA_DB::doCONTROL( CONTROL* growth )
  948. {
  949. T tok;
  950. while( (tok = NextTok()) != T_RIGHT )
  951. {
  952. if( tok != T_LEFT )
  953. Expecting( T_LEFT );
  954. tok = NextTok();
  955. switch( tok )
  956. {
  957. case T_via_at_smd:
  958. tok = NextTok();
  959. if( tok!=T_on && tok!=T_off )
  960. Expecting( "on|off" );
  961. growth->via_at_smd = (tok==T_on);
  962. NeedRIGHT();
  963. break;
  964. case T_off_grid:
  965. case T_route_to_fanout_only:
  966. case T_force_to_terminal_point:
  967. case T_same_net_checking:
  968. case T_checking_trim_by_pin:
  969. case T_noise_calculation:
  970. case T_noise_accumulation:
  971. case T_include_pins_in_crosstalk:
  972. case T_bbv_ctr2ctr:
  973. case T_average_pair_length:
  974. case T_crosstalk_model:
  975. case T_roundoff_rotation:
  976. case T_microvia:
  977. case T_reroute_order_viols:
  978. TOKPROP* tokprop;
  979. tokprop = new TOKPROP( growth, tok );
  980. growth->Append( tokprop );
  981. doTOKPROP( tokprop );
  982. break;
  983. default:
  984. Unexpected( CurText() );
  985. }
  986. }
  987. }
  988. void SPECCTRA_DB::doPROPERTIES( PROPERTIES* growth )
  989. {
  990. T tok;
  991. PROPERTY property; // construct it once here, append multiple times.
  992. while( ( tok = NextTok() ) != T_RIGHT )
  993. {
  994. if( tok != T_LEFT )
  995. Expecting( T_LEFT );
  996. NeedSYMBOLorNUMBER();
  997. property.name = CurText();
  998. NeedSYMBOLorNUMBER();
  999. property.value = CurText();
  1000. growth->push_back( property );
  1001. NeedRIGHT();
  1002. }
  1003. }
  1004. void SPECCTRA_DB::doLAYER( LAYER* growth )
  1005. {
  1006. T tok = NextTok();
  1007. if( !IsSymbol( tok ) )
  1008. Expecting( T_SYMBOL );
  1009. growth->name = CurText();
  1010. while( ( tok = NextTok() ) != T_RIGHT )
  1011. {
  1012. if( tok != T_LEFT )
  1013. Expecting( T_LEFT );
  1014. tok = NextTok();
  1015. switch( tok )
  1016. {
  1017. case T_type:
  1018. tok = NextTok();
  1019. if( tok != T_signal && tok != T_power && tok != T_mixed && tok != T_jumper )
  1020. Expecting( "signal|power|mixed|jumper" );
  1021. growth->layer_type = tok;
  1022. if( NextTok()!=T_RIGHT )
  1023. Expecting(T_RIGHT);
  1024. break;
  1025. case T_rule:
  1026. growth->rules = new RULE( growth, T_rule );
  1027. doRULE( growth->rules );
  1028. break;
  1029. case T_property:
  1030. doPROPERTIES( &growth->properties );
  1031. break;
  1032. case T_direction:
  1033. tok = NextTok();
  1034. switch( tok )
  1035. {
  1036. case T_horizontal:
  1037. case T_vertical:
  1038. case T_orthogonal:
  1039. case T_positive_diagonal:
  1040. case T_negative_diagonal:
  1041. case T_diagonal:
  1042. case T_off:
  1043. growth->direction = tok;
  1044. break;
  1045. default:
  1046. // the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
  1047. if( !strcmp( "hori", CurText() ) )
  1048. {
  1049. growth->direction = T_horizontal;
  1050. break;
  1051. }
  1052. else if( !strcmp( "vert", CurText() ) )
  1053. {
  1054. growth->direction = T_vertical;
  1055. break;
  1056. }
  1057. Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|"
  1058. "diagonal|off" );
  1059. }
  1060. if( NextTok() != T_RIGHT )
  1061. Expecting( T_RIGHT );
  1062. break;
  1063. case T_cost:
  1064. tok = NextTok();
  1065. switch( tok )
  1066. {
  1067. case T_forbidden:
  1068. case T_high:
  1069. case T_medium:
  1070. case T_low:
  1071. case T_free:
  1072. growth->cost = tok;
  1073. break;
  1074. case T_NUMBER:
  1075. // store as negative so we can differentiate between
  1076. // T (positive) and T_NUMBER (negative)
  1077. growth->cost = -atoi( CurText() );
  1078. break;
  1079. default:
  1080. Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
  1081. }
  1082. tok = NextTok();
  1083. if( tok == T_LEFT )
  1084. {
  1085. if( NextTok() != T_type )
  1086. Unexpected( CurText() );
  1087. tok = NextTok();
  1088. if( tok!=T_length && tok!=T_way )
  1089. Expecting( "length|way" );
  1090. growth->cost_type = tok;
  1091. if( NextTok()!=T_RIGHT )
  1092. Expecting( T_RIGHT );
  1093. tok = NextTok();
  1094. }
  1095. if( tok != T_RIGHT )
  1096. Expecting( T_RIGHT );
  1097. break;
  1098. case T_use_net:
  1099. while( ( tok = NextTok() ) != T_RIGHT )
  1100. {
  1101. if( !IsSymbol( tok ) )
  1102. Expecting( T_SYMBOL );
  1103. growth->use_net.push_back( CurText() );
  1104. }
  1105. break;
  1106. default:
  1107. Unexpected( CurText() );
  1108. }
  1109. }
  1110. }
  1111. void SPECCTRA_DB::doRULE( RULE* growth )
  1112. {
  1113. std::string builder;
  1114. int bracketNesting = 1; // we already saw the opening T_LEFT
  1115. T tok = T_NONE;
  1116. while( bracketNesting != 0 && tok != T_EOF )
  1117. {
  1118. tok = NextTok();
  1119. if( tok==T_LEFT)
  1120. ++bracketNesting;
  1121. else if( tok==T_RIGHT )
  1122. --bracketNesting;
  1123. if( bracketNesting >= 1 )
  1124. {
  1125. if( PrevTok() != T_LEFT && tok != T_RIGHT && ( tok != T_LEFT || bracketNesting > 2 ) )
  1126. builder += ' ';
  1127. if( tok == T_STRING )
  1128. builder += m_quote_char;
  1129. builder += CurText();
  1130. if( tok == T_STRING )
  1131. builder += m_quote_char;
  1132. }
  1133. // When the nested rule is closed with a T_RIGHT and we are back down
  1134. // to bracketNesting == 1, (inside the <rule_descriptor> but outside
  1135. // the last rule). Then save the last rule and clear the string builder.
  1136. if( bracketNesting == 1 )
  1137. {
  1138. growth->rules.push_back( builder );
  1139. builder.clear();
  1140. }
  1141. }
  1142. if( tok==T_EOF )
  1143. Unexpected( T_EOF );
  1144. }
  1145. #if 0
  1146. void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type )
  1147. {
  1148. /* (place_rule [<structure_place_rule_object> ]
  1149. {[<spacing_descriptor> |
  1150. <permit_orient_descriptor> |
  1151. <permit_side_descriptor> |
  1152. <opposite_side_descriptor> ]}
  1153. )
  1154. */
  1155. T tok = NextTok();
  1156. if( tok != T_LEFT )
  1157. Expecting( T_LEFT );
  1158. tok = NextTok();
  1159. if( tok == T_object_type )
  1160. {
  1161. if( !expect_object_type )
  1162. Unexpected( tok );
  1163. /* [(object_type
  1164. [pcb |
  1165. image_set [large | small | discrete | capacitor | resistor]
  1166. [(image_type [smd | pin])]]
  1167. )]
  1168. */
  1169. tok = NextTok();
  1170. switch( tok )
  1171. {
  1172. case T_pcb:
  1173. growth->object_type = tok;
  1174. break;
  1175. case T_image_set:
  1176. tok = NextTok();
  1177. switch( tok )
  1178. {
  1179. case T_large:
  1180. case T_small:
  1181. case T_discrete:
  1182. case T_capacitor:
  1183. case T_resistor:
  1184. growth->object_type = tok;
  1185. break;
  1186. default:
  1187. Unexpected( CurText() );
  1188. }
  1189. break;
  1190. default:
  1191. Unexpected( CurText() );
  1192. }
  1193. tok = NextTok();
  1194. if( tok == T_LEFT )
  1195. {
  1196. tok = NextTok();
  1197. if( tok != T_image_type )
  1198. Expecting( T_image_type );
  1199. tok = NextTok();
  1200. if( tok!=T_smd && tok!=T_pin )
  1201. Expecting( "smd|pin" );
  1202. NeedRIGHT();
  1203. tok = NextTok();
  1204. }
  1205. if( tok != T_RIGHT )
  1206. Expecting( T_RIGHT );
  1207. tok = NextTok();
  1208. }
  1209. /* {[<spacing_descriptor> |
  1210. <permit_orient_descriptor> |
  1211. <permit_side_descriptor> | <opposite_side_descriptor> ]}
  1212. */
  1213. doRULE( growth );
  1214. }
  1215. #endif
  1216. void SPECCTRA_DB::doREGION( REGION* growth )
  1217. {
  1218. T tok = NextTok();
  1219. if( IsSymbol( tok ) )
  1220. {
  1221. growth->region_id = CurText();
  1222. tok = NextTok();
  1223. }
  1224. for(;;)
  1225. {
  1226. if( tok != T_LEFT )
  1227. Expecting( T_LEFT );
  1228. tok = NextTok();
  1229. switch( tok )
  1230. {
  1231. case T_rect:
  1232. if( growth->rectangle )
  1233. Unexpected( tok );
  1234. growth->rectangle = new RECTANGLE( growth );
  1235. doRECTANGLE( growth->rectangle );
  1236. break;
  1237. case T_polygon:
  1238. if( growth->polygon )
  1239. Unexpected( tok );
  1240. growth->polygon = new PATH( growth, T_polygon );
  1241. doPATH( growth->polygon );
  1242. break;
  1243. case T_region_net:
  1244. case T_region_class:
  1245. STRINGPROP* stringprop;
  1246. stringprop = new STRINGPROP( growth, tok );
  1247. growth->Append( stringprop );
  1248. doSTRINGPROP( stringprop );
  1249. break;
  1250. case T_region_class_class:
  1251. CLASS_CLASS* class_class;
  1252. class_class = new CLASS_CLASS( growth, tok );
  1253. growth->Append( class_class );
  1254. doCLASS_CLASS( class_class );
  1255. break;
  1256. case T_rule:
  1257. if( growth->rules )
  1258. Unexpected( tok );
  1259. growth->rules = new RULE( growth, T_rule );
  1260. doRULE( growth->rules );
  1261. break;
  1262. default:
  1263. Unexpected( CurText() );
  1264. }
  1265. tok = NextTok();
  1266. if( tok == T_RIGHT )
  1267. {
  1268. if( !growth->rules )
  1269. Expecting( T_rule );
  1270. break;
  1271. }
  1272. }
  1273. }
  1274. void SPECCTRA_DB::doCLASS_CLASS( CLASS_CLASS* growth )
  1275. {
  1276. T tok = NextTok();
  1277. if( tok != T_LEFT )
  1278. Expecting( T_LEFT );
  1279. while( ( tok = NextTok() ) != T_RIGHT )
  1280. {
  1281. switch( tok )
  1282. {
  1283. case T_classes:
  1284. if( growth->classes )
  1285. Unexpected( tok );
  1286. growth->classes = new CLASSES( growth );
  1287. doCLASSES( growth->classes );
  1288. break;
  1289. case T_rule:
  1290. // only T_class_class takes a T_rule
  1291. if( growth->Type() == T_region_class_class )
  1292. Unexpected( tok );
  1293. RULE* rule;
  1294. rule = new RULE( growth, T_rule );
  1295. growth->Append( rule );
  1296. doRULE( rule );
  1297. break;
  1298. case T_layer_rule:
  1299. // only T_class_class takes a T_layer_rule
  1300. if( growth->Type() == T_region_class_class )
  1301. Unexpected( tok );
  1302. LAYER_RULE* layer_rule;
  1303. layer_rule = new LAYER_RULE( growth );
  1304. growth->Append( layer_rule );
  1305. doLAYER_RULE( layer_rule );
  1306. break;
  1307. default:
  1308. Unexpected( tok );
  1309. }
  1310. }
  1311. }
  1312. void SPECCTRA_DB::doCLASSES( CLASSES* growth )
  1313. {
  1314. T tok = NextTok();
  1315. // require at least 2 class_ids
  1316. if( !IsSymbol( tok ) )
  1317. Expecting( "class_id" );
  1318. growth->class_ids.push_back( CurText() );
  1319. do
  1320. {
  1321. tok = NextTok();
  1322. if( !IsSymbol( tok ) )
  1323. Expecting( "class_id" );
  1324. growth->class_ids.push_back( CurText() );
  1325. } while( ( tok = NextTok() ) != T_RIGHT );
  1326. }
  1327. void SPECCTRA_DB::doGRID( GRID* growth )
  1328. {
  1329. T tok = NextTok();
  1330. switch( tok )
  1331. {
  1332. case T_via:
  1333. case T_wire:
  1334. case T_via_keepout:
  1335. case T_snap:
  1336. case T_place:
  1337. growth->grid_type = tok;
  1338. if( NextTok() != T_NUMBER )
  1339. Expecting( T_NUMBER );
  1340. growth->dimension = strtod( CurText(), 0 );
  1341. tok = NextTok();
  1342. if( tok == T_LEFT )
  1343. {
  1344. while( ( tok = NextTok() ) != T_RIGHT )
  1345. {
  1346. if( tok == T_direction )
  1347. {
  1348. if( growth->grid_type == T_place )
  1349. Unexpected( tok );
  1350. tok = NextTok();
  1351. if( tok != T_x && tok != T_y )
  1352. Unexpected( CurText() );
  1353. growth->direction = tok;
  1354. if( NextTok() != T_RIGHT )
  1355. Expecting(T_RIGHT);
  1356. }
  1357. else if( tok == T_offset )
  1358. {
  1359. if( growth->grid_type == T_place )
  1360. Unexpected( tok );
  1361. if( NextTok() != T_NUMBER )
  1362. Expecting( T_NUMBER );
  1363. growth->offset = strtod( CurText(), 0 );
  1364. if( NextTok() != T_RIGHT )
  1365. Expecting( T_RIGHT );
  1366. }
  1367. else if( tok == T_image_type )
  1368. {
  1369. if( growth->grid_type != T_place )
  1370. Unexpected( tok );
  1371. tok = NextTok();
  1372. if( tok != T_smd && tok != T_pin )
  1373. Unexpected( CurText() );
  1374. growth->image_type = tok;
  1375. if( NextTok() != T_RIGHT )
  1376. Expecting( T_RIGHT );
  1377. }
  1378. }
  1379. }
  1380. break;
  1381. default:
  1382. Unexpected( tok );
  1383. }
  1384. }
  1385. void SPECCTRA_DB::doLAYER_RULE( LAYER_RULE* growth )
  1386. {
  1387. T tok;
  1388. NeedSYMBOL();
  1389. do
  1390. {
  1391. growth->layer_ids.push_back( CurText() );
  1392. } while( IsSymbol( tok = NextTok() ) );
  1393. if( tok != T_LEFT )
  1394. Expecting( T_LEFT );
  1395. if( NextTok() != T_rule )
  1396. Expecting( T_rule );
  1397. growth->rule = new RULE( growth, T_rule );
  1398. doRULE( growth->rule );
  1399. NeedRIGHT();
  1400. }
  1401. void SPECCTRA_DB::doPLACE( PLACE* growth )
  1402. {
  1403. T tok = NextTok();
  1404. if( !IsSymbol( tok ) )
  1405. Expecting( "component_id" );
  1406. growth->component_id = CurText();
  1407. tok = NextTok();
  1408. if( tok == T_NUMBER )
  1409. {
  1410. POINT point;
  1411. point.x = strtod( CurText(), 0 );
  1412. if( NextTok() != T_NUMBER )
  1413. Expecting( T_NUMBER );
  1414. point.y = strtod( CurText(), 0 );
  1415. growth->SetVertex( point );
  1416. tok = NextTok();
  1417. if( tok != T_front && tok != T_back )
  1418. Expecting( "front|back" );
  1419. growth->side = tok;
  1420. if( NextTok() != T_NUMBER )
  1421. Expecting( "rotation" );
  1422. growth->SetRotation( strtod( CurText(), 0 ) );
  1423. }
  1424. while( ( tok = NextTok() ) != T_RIGHT )
  1425. {
  1426. if( tok != T_LEFT )
  1427. Expecting( T_LEFT );
  1428. tok = NextTok();
  1429. switch( tok )
  1430. {
  1431. case T_mirror:
  1432. tok = NextTok();
  1433. if( tok == T_x || tok == T_y || tok == T_xy || tok == T_off )
  1434. growth->mirror = tok;
  1435. else
  1436. Expecting( "x|y|xy|off" );
  1437. break;
  1438. case T_status:
  1439. tok = NextTok();
  1440. if( tok==T_added || tok==T_deleted || tok==T_substituted )
  1441. growth->status = tok;
  1442. else
  1443. Expecting("added|deleted|substituted");
  1444. break;
  1445. case T_logical_part:
  1446. if( growth->logical_part.size() )
  1447. Unexpected( tok );
  1448. tok = NextTok();
  1449. if( !IsSymbol( tok ) )
  1450. Expecting( "logical_part_id");
  1451. growth->logical_part = CurText();
  1452. break;
  1453. case T_place_rule:
  1454. if( growth->place_rules )
  1455. Unexpected( tok );
  1456. growth->place_rules = new RULE( growth, T_place_rule );
  1457. doRULE( growth->place_rules );
  1458. break;
  1459. case T_property:
  1460. if( growth->properties.size() )
  1461. Unexpected( tok );
  1462. doPROPERTIES( &growth->properties );
  1463. break;
  1464. case T_lock_type:
  1465. tok = NextTok();
  1466. if( tok == T_position || tok == T_gate || tok == T_subgate || tok == T_pin )
  1467. growth->lock_type = tok;
  1468. else
  1469. Expecting( "position|gate|subgate|pin" );
  1470. break;
  1471. case T_rule:
  1472. if( growth->rules || growth->region )
  1473. Unexpected( tok );
  1474. growth->rules = new RULE( growth, T_rule );
  1475. doRULE( growth->rules );
  1476. break;
  1477. case T_region:
  1478. if( growth->rules || growth->region )
  1479. Unexpected( tok );
  1480. growth->region = new REGION( growth );
  1481. doREGION( growth->region );
  1482. break;
  1483. case T_pn:
  1484. if( growth->part_number.size() )
  1485. Unexpected( tok );
  1486. NeedSYMBOLorNUMBER();
  1487. growth->part_number = CurText();
  1488. NeedRIGHT();
  1489. break;
  1490. default:
  1491. Unexpected( tok );
  1492. }
  1493. }
  1494. }
  1495. void SPECCTRA_DB::doCOMPONENT( COMPONENT* growth )
  1496. {
  1497. T tok = NextTok();
  1498. if( !IsSymbol( tok ) && tok != T_NUMBER )
  1499. Expecting( "image_id" );
  1500. growth->image_id = CurText();
  1501. while( ( tok = NextTok() ) != T_RIGHT )
  1502. {
  1503. if( tok != T_LEFT )
  1504. Expecting( T_LEFT );
  1505. tok = NextTok();
  1506. switch( tok )
  1507. {
  1508. case T_place:
  1509. PLACE* place;
  1510. place = new PLACE( growth );
  1511. growth->places.push_back( place );
  1512. doPLACE( place );
  1513. break;
  1514. default:
  1515. Unexpected( tok );
  1516. }
  1517. }
  1518. }
  1519. void SPECCTRA_DB::doPLACEMENT( PLACEMENT* growth )
  1520. {
  1521. T tok;
  1522. while( ( tok = NextTok() ) != T_RIGHT )
  1523. {
  1524. if( tok == T_EOF )
  1525. Unexpected( T_EOF );
  1526. if( tok != T_LEFT )
  1527. Expecting( T_LEFT );
  1528. tok = NextTok();
  1529. switch( tok )
  1530. {
  1531. case T_unit:
  1532. case T_resolution:
  1533. growth->unit = new UNIT_RES( growth, tok );
  1534. if( tok == T_resolution )
  1535. doRESOLUTION( growth->unit );
  1536. else
  1537. doUNIT( growth->unit );
  1538. break;
  1539. case T_place_control:
  1540. NeedRIGHT();
  1541. tok = NextTok();
  1542. if( tok != T_flip_style )
  1543. Expecting( T_flip_style );
  1544. tok = NextTok();
  1545. if( tok == T_mirror_first || tok == T_rotate_first )
  1546. growth->flip_style = tok;
  1547. else
  1548. Expecting( "mirror_first|rotate_first" );
  1549. NeedRIGHT();
  1550. NeedRIGHT();
  1551. break;
  1552. case T_component:
  1553. COMPONENT* component;
  1554. component = new COMPONENT( growth );
  1555. growth->components.push_back( component );
  1556. doCOMPONENT( component );
  1557. break;
  1558. default:
  1559. Unexpected( tok );
  1560. }
  1561. }
  1562. }
  1563. void SPECCTRA_DB::doPADSTACK( PADSTACK* growth )
  1564. {
  1565. T tok = NextTok();
  1566. /* (padstack <padstack_id >
  1567. [<unit_descriptor> ]
  1568. {(shape <shape_descriptor>
  1569. [<reduced_shape_descriptor> ]
  1570. [(connect [on | off])]
  1571. [{<window_descriptor> }]
  1572. )}
  1573. [<attach_descriptor> ]
  1574. [{<pad_via_site_descriptor> }]
  1575. [(rotate [on | off])]
  1576. [(absolute [on | off])]
  1577. [(rule <clearance_descriptor> )])
  1578. */
  1579. // padstack_id may be a number
  1580. if( !IsSymbol( tok ) && tok != T_NUMBER )
  1581. Expecting( "padstack_id" );
  1582. growth->padstack_id = CurText();
  1583. while( ( tok = NextTok() ) != T_RIGHT )
  1584. {
  1585. if( tok != T_LEFT )
  1586. Expecting( T_LEFT );
  1587. tok = NextTok();
  1588. switch( tok )
  1589. {
  1590. case T_unit:
  1591. if( growth->unit )
  1592. Unexpected( tok );
  1593. growth->unit = new UNIT_RES( growth, tok );
  1594. doUNIT( growth->unit );
  1595. break;
  1596. case T_rotate:
  1597. tok = NextTok();
  1598. if( tok != T_on && tok != T_off )
  1599. Expecting( "on|off" );
  1600. growth->rotate = tok;
  1601. NeedRIGHT();
  1602. break;
  1603. case T_absolute:
  1604. tok = NextTok();
  1605. if( tok != T_on && tok != T_off )
  1606. Expecting( "on|off" );
  1607. growth->absolute = tok;
  1608. NeedRIGHT();
  1609. break;
  1610. case T_shape:
  1611. SHAPE* shape;
  1612. shape = new SHAPE( growth );
  1613. growth->Append( shape );
  1614. doSHAPE( shape );
  1615. break;
  1616. case T_attach:
  1617. tok = NextTok();
  1618. if( tok != T_off && tok != T_on )
  1619. Expecting( "off|on" );
  1620. growth->attach = tok;
  1621. tok = NextTok();
  1622. if( tok == T_LEFT )
  1623. {
  1624. if( NextTok() != T_use_via )
  1625. Expecting( T_use_via );
  1626. NeedSYMBOL();
  1627. growth->via_id = CurText();
  1628. NeedRIGHT();
  1629. NeedRIGHT();
  1630. }
  1631. break;
  1632. /*
  1633. case T_via_site: not supported
  1634. break;
  1635. */
  1636. case T_rule:
  1637. if( growth->rules )
  1638. Unexpected( tok );
  1639. growth->rules = new RULE( growth, T_rule );
  1640. doRULE( growth->rules );
  1641. break;
  1642. default:
  1643. Unexpected( CurText() );
  1644. }
  1645. }
  1646. }
  1647. void SPECCTRA_DB::doSHAPE( SHAPE* growth )
  1648. {
  1649. T tok;
  1650. /* (shape <shape_descriptor>
  1651. [<reduced_shape_descriptor> ]
  1652. [(connect [on | off])]
  1653. [{<window_descriptor> }])
  1654. */
  1655. while( ( tok = NextTok() ) != T_RIGHT )
  1656. {
  1657. if( tok != T_LEFT )
  1658. Expecting( T_LEFT );
  1659. tok = NextTok();
  1660. switch( tok )
  1661. {
  1662. case T_polyline_path:
  1663. tok = T_path;
  1664. KI_FALLTHROUGH;
  1665. case T_rect:
  1666. case T_circle:
  1667. case T_path:
  1668. case T_polygon:
  1669. case T_qarc:
  1670. L_done_that:
  1671. if( growth->shape )
  1672. Unexpected( tok );
  1673. break;
  1674. default:
  1675. // the example in the spec uses "circ" instead of "circle". Bad!
  1676. if( !strcmp( "circ", CurText() ) )
  1677. {
  1678. tok = T_circle;
  1679. goto L_done_that;
  1680. }
  1681. }
  1682. switch( tok )
  1683. {
  1684. case T_rect:
  1685. growth->shape = new RECTANGLE( growth );
  1686. doRECTANGLE( (RECTANGLE*) growth->shape );
  1687. break;
  1688. case T_circle:
  1689. growth->shape = new CIRCLE( growth );
  1690. doCIRCLE( (CIRCLE*)growth->shape );
  1691. break;
  1692. case T_path:
  1693. case T_polygon:
  1694. growth->shape = new PATH( growth, tok );
  1695. doPATH( (PATH*)growth->shape );
  1696. break;
  1697. case T_qarc:
  1698. growth->shape = new QARC( growth );
  1699. doQARC( (QARC*)growth->shape );
  1700. break;
  1701. case T_connect:
  1702. tok = NextTok();
  1703. if( tok!=T_on && tok!=T_off )
  1704. Expecting( "on|off" );
  1705. growth->connect = tok;
  1706. NeedRIGHT();
  1707. break;
  1708. case T_window:
  1709. WINDOW* window;
  1710. window = new WINDOW( growth );
  1711. growth->windows.push_back( window );
  1712. doWINDOW( window );
  1713. break;
  1714. default:
  1715. Unexpected( CurText() );
  1716. }
  1717. }
  1718. }
  1719. void SPECCTRA_DB::doIMAGE( IMAGE* growth )
  1720. {
  1721. T tok = NextTok();
  1722. /* <image_descriptor >::=
  1723. (image <image_id >
  1724. [(side [front | back | both])]
  1725. [<unit_descriptor> ]
  1726. [<outline_descriptor> ]
  1727. {(pin <padstack_id > [(rotate <rotation> )]
  1728. [<reference_descriptor> | <pin_array_descriptor> ]
  1729. [<user_property_descriptor> ])}
  1730. [{<conductor_shape_descriptor> }]
  1731. [{<conductor_via_descriptor> }]
  1732. [<rule_descriptor> ]
  1733. [<place_rule_descriptor> ]
  1734. [{<keepout_descriptor> }]
  1735. [<image_property_descriptor> ]
  1736. )
  1737. */
  1738. if( !IsSymbol( tok ) && tok != T_NUMBER )
  1739. Expecting( "image_id" );
  1740. growth->image_id = CurText();
  1741. while( ( tok = NextTok() ) != T_RIGHT )
  1742. {
  1743. if( tok != T_LEFT )
  1744. Expecting( T_LEFT );
  1745. tok = NextTok();
  1746. switch( tok )
  1747. {
  1748. case T_unit:
  1749. if( growth->unit )
  1750. Unexpected( tok );
  1751. growth->unit = new UNIT_RES( growth, tok );
  1752. doUNIT( growth->unit );
  1753. break;
  1754. case T_side:
  1755. tok = NextTok();
  1756. if( tok != T_front && tok != T_back && tok != T_both )
  1757. Expecting( "front|back|both" );
  1758. growth->side = tok;
  1759. NeedRIGHT();
  1760. break;
  1761. case T_outline:
  1762. SHAPE* outline;
  1763. outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
  1764. growth->Append( outline );
  1765. doSHAPE( outline );
  1766. break;
  1767. case T_pin:
  1768. PIN* pin;
  1769. pin = new PIN( growth );
  1770. growth->pins.push_back( pin );
  1771. doPIN( pin );
  1772. break;
  1773. case T_rule:
  1774. if( growth->rules )
  1775. Unexpected( tok );
  1776. growth->rules = new RULE( growth, tok );
  1777. doRULE( growth->rules );
  1778. break;
  1779. case T_place_rule:
  1780. if( growth->place_rules )
  1781. Unexpected( tok );
  1782. growth->place_rules = new RULE( growth, tok );
  1783. doRULE( growth->place_rules );
  1784. break;
  1785. case T_keepout:
  1786. case T_place_keepout:
  1787. case T_via_keepout:
  1788. case T_wire_keepout:
  1789. case T_bend_keepout:
  1790. case T_elongate_keepout:
  1791. KEEPOUT* keepout;
  1792. keepout = new KEEPOUT( growth, tok );
  1793. growth->keepouts.push_back( keepout );
  1794. doKEEPOUT( keepout );
  1795. break;
  1796. default:
  1797. Unexpected( CurText() );
  1798. }
  1799. }
  1800. }
  1801. void SPECCTRA_DB::doPIN( PIN* growth )
  1802. {
  1803. T tok = NextTok();
  1804. /* (pin <padstack_id > [(rotate <rotation> )]
  1805. [<reference_descriptor> | <pin_array_descriptor> ]
  1806. [<user_property_descriptor> ])
  1807. */
  1808. // a padstack_id may be a number
  1809. if( !IsSymbol( tok ) && tok!=T_NUMBER )
  1810. Expecting( "padstack_id" );
  1811. growth->padstack_id = CurText();
  1812. while( ( tok = NextTok() ) != T_RIGHT )
  1813. {
  1814. if( tok == T_LEFT )
  1815. {
  1816. tok = NextTok();
  1817. if( tok != T_rotate )
  1818. Expecting( T_rotate );
  1819. if( NextTok() != T_NUMBER )
  1820. Expecting( T_NUMBER );
  1821. growth->SetRotation( strtod( CurText(), 0 ) );
  1822. NeedRIGHT();
  1823. }
  1824. else
  1825. {
  1826. if( !IsSymbol( tok ) && tok != T_NUMBER )
  1827. Expecting( "pin_id" );
  1828. growth->pin_id = CurText();
  1829. if( NextTok() != T_NUMBER )
  1830. Expecting( T_NUMBER );
  1831. growth->vertex.x = strtod( CurText(), 0 );
  1832. if( NextTok() != T_NUMBER )
  1833. Expecting( T_NUMBER );
  1834. growth->vertex.y = strtod( CurText(), 0 );
  1835. }
  1836. }
  1837. }
  1838. void SPECCTRA_DB::doLIBRARY( LIBRARY* growth )
  1839. {
  1840. T tok;
  1841. /* <library_descriptor >::=
  1842. (library
  1843. [<unit_descriptor> ]
  1844. {<image_descriptor> }
  1845. [{<jumper_descriptor> }]
  1846. {<padstack_descriptor> }
  1847. {<via_array_template_descriptor> }
  1848. [<directory_descriptor> ]
  1849. [<extra_image_directory_descriptor> ]
  1850. [{<family_family_descriptor> }]
  1851. [{<image_image_descriptor> }]
  1852. )
  1853. */
  1854. while( ( tok = NextTok() ) != T_RIGHT )
  1855. {
  1856. if( tok != T_LEFT )
  1857. Expecting( T_LEFT );
  1858. tok = NextTok();
  1859. switch( tok )
  1860. {
  1861. case T_unit:
  1862. if( growth->unit )
  1863. Unexpected( tok );
  1864. growth->unit = new UNIT_RES( growth, tok );
  1865. doUNIT( growth->unit );
  1866. break;
  1867. case T_padstack:
  1868. PADSTACK* padstack;
  1869. padstack = new PADSTACK();
  1870. growth->AddPadstack( padstack );
  1871. doPADSTACK( padstack );
  1872. break;
  1873. case T_image:
  1874. IMAGE* image;
  1875. image = new IMAGE( growth );
  1876. growth->images.push_back( image );
  1877. doIMAGE( image );
  1878. break;
  1879. default:
  1880. Unexpected( CurText() );
  1881. }
  1882. }
  1883. }
  1884. void SPECCTRA_DB::doNET( NET* growth )
  1885. {
  1886. T tok = NextTok();
  1887. PIN_REFS* pin_refs;
  1888. /* <net_descriptor >::=
  1889. (net <net_id >
  1890. [(unassigned)]
  1891. [(net_number <integer >)]
  1892. [(pins {<pin_reference> }) | (order {<pin_reference> })]
  1893. [<component_order_descriptor> ]
  1894. [(type [fix | normal])]
  1895. [<user_property_descriptor> ]
  1896. [<circuit_descriptor> ]
  1897. [<rule_descriptor> ]
  1898. [{<layer_rule_descriptor> }]
  1899. [<fromto_descriptor> ]
  1900. [(expose {<pin_reference> })]
  1901. [(noexpose {<pin_reference> })]
  1902. [(source {<pin_reference> })]
  1903. [(load {<pin_reference> })]
  1904. [(terminator {<pin_reference> })]
  1905. [(supply [power | ground])]
  1906. )
  1907. */
  1908. if( !IsSymbol( tok ) )
  1909. Expecting( "net_id" );
  1910. growth->net_id = CurText();
  1911. while( ( tok = NextTok() ) != T_RIGHT )
  1912. {
  1913. if( tok != T_LEFT )
  1914. Expecting( T_LEFT );
  1915. tok = NextTok();
  1916. switch( tok )
  1917. {
  1918. case T_unassigned:
  1919. growth->unassigned = true;
  1920. NeedRIGHT();
  1921. break;
  1922. case T_net_number:
  1923. if( NextTok() != T_NUMBER )
  1924. Expecting( T_NUMBER );
  1925. growth->net_number = atoi( CurText() );
  1926. NeedRIGHT();
  1927. break;
  1928. case T_pins:
  1929. case T_order:
  1930. growth->pins_type = tok;
  1931. pin_refs = &growth->pins;
  1932. goto L_pins;
  1933. case T_expose:
  1934. pin_refs = &growth->expose;
  1935. goto L_pins;
  1936. case T_noexpose:
  1937. pin_refs = &growth->noexpose;
  1938. goto L_pins;
  1939. case T_source:
  1940. pin_refs = &growth->source;
  1941. goto L_pins;
  1942. case T_load:
  1943. pin_refs = &growth->load;
  1944. goto L_pins;
  1945. case T_terminator:
  1946. pin_refs = &growth->terminator;
  1947. //goto L_pins;
  1948. L_pins:
  1949. {
  1950. PIN_REF empty( growth );
  1951. while( ( tok = NextTok() ) != T_RIGHT )
  1952. {
  1953. // copy the empty one, then fill its copy later thru pin_ref.
  1954. pin_refs->push_back( empty );
  1955. PIN_REF* pin_ref = &pin_refs->back();
  1956. readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
  1957. }
  1958. }
  1959. break;
  1960. case T_comp_order:
  1961. if( growth->comp_order )
  1962. Unexpected( tok );
  1963. growth->comp_order = new COMP_ORDER( growth );
  1964. doCOMP_ORDER( growth->comp_order );
  1965. break;
  1966. case T_type:
  1967. tok = NextTok();
  1968. if( tok!=T_fix && tok!=T_normal )
  1969. Expecting( "fix|normal" );
  1970. growth->type = tok;
  1971. NeedRIGHT();
  1972. break;
  1973. /* @todo
  1974. case T_circuit:
  1975. break;
  1976. */
  1977. case T_rule:
  1978. if( growth->rules )
  1979. Unexpected( tok );
  1980. growth->rules = new RULE( growth, T_rule );
  1981. doRULE( growth->rules );
  1982. break;
  1983. case T_layer_rule:
  1984. LAYER_RULE* layer_rule;
  1985. layer_rule = new LAYER_RULE( growth );
  1986. growth->layer_rules.push_back( layer_rule );
  1987. doLAYER_RULE( layer_rule );
  1988. break;
  1989. case T_fromto:
  1990. FROMTO* fromto;
  1991. fromto = new FROMTO( growth );
  1992. growth->fromtos.push_back( fromto );
  1993. doFROMTO( fromto );
  1994. break;
  1995. default:
  1996. Unexpected( CurText() );
  1997. }
  1998. }
  1999. }
  2000. void SPECCTRA_DB::doTOPOLOGY( TOPOLOGY* growth )
  2001. {
  2002. T tok;
  2003. /* <topology_descriptor >::=
  2004. (topology {[<fromto_descriptor> |
  2005. <component_order_descriptor> ]})
  2006. */
  2007. while( ( tok = NextTok() ) != T_RIGHT )
  2008. {
  2009. if( tok != T_LEFT )
  2010. Expecting( T_LEFT );
  2011. tok = NextTok();
  2012. switch( tok )
  2013. {
  2014. case T_fromto:
  2015. FROMTO* fromto;
  2016. fromto = new FROMTO( growth );
  2017. growth->fromtos.push_back( fromto );
  2018. doFROMTO( fromto );
  2019. break;
  2020. case T_comp_order:
  2021. COMP_ORDER* comp_order;
  2022. comp_order = new COMP_ORDER( growth );
  2023. growth->comp_orders.push_back( comp_order );
  2024. doCOMP_ORDER( comp_order );
  2025. break;
  2026. default:
  2027. Unexpected( CurText() );
  2028. }
  2029. }
  2030. }
  2031. void SPECCTRA_DB::doCLASS( CLASS* growth )
  2032. {
  2033. T tok;
  2034. /* <class_descriptor >::=
  2035. (class
  2036. <class_id > {[{<net_id >} | {<composite_name_list> }]}
  2037. [<circuit_descriptor> ]
  2038. [<rule_descriptor> ]
  2039. [{<layer_rule_descriptor> }]
  2040. [<topology_descriptor> ]
  2041. )
  2042. */
  2043. NeedSYMBOL();
  2044. growth->class_id = CurText();
  2045. // do net_ids, do not support <composite_name_list>s at this time
  2046. while( IsSymbol( tok = NextTok() ) )
  2047. {
  2048. growth->net_ids.push_back( CurText() );
  2049. }
  2050. while( tok != T_RIGHT )
  2051. {
  2052. if( tok != T_LEFT )
  2053. Expecting( T_LEFT );
  2054. tok = NextTok();
  2055. switch( tok )
  2056. {
  2057. case T_rule:
  2058. if( growth->rules )
  2059. Unexpected( tok );
  2060. growth->rules = new RULE( growth, T_rule );
  2061. doRULE( growth->rules );
  2062. break;
  2063. case T_layer_rule:
  2064. LAYER_RULE* layer_rule;
  2065. layer_rule = new LAYER_RULE( growth );
  2066. growth->layer_rules.push_back( layer_rule );
  2067. doLAYER_RULE( layer_rule );
  2068. break;
  2069. case T_topology:
  2070. if( growth->topology )
  2071. Unexpected( tok );
  2072. growth->topology = new TOPOLOGY( growth );
  2073. doTOPOLOGY( growth->topology );
  2074. break;
  2075. case T_circuit: // handle all the circuit_descriptor here as strings
  2076. {
  2077. std::string builder;
  2078. int bracketNesting = 1; // we already saw the opening T_LEFT
  2079. tok = T_NONE;
  2080. while( bracketNesting != 0 && tok != T_EOF )
  2081. {
  2082. tok = NextTok();
  2083. if( tok == T_LEFT )
  2084. ++bracketNesting;
  2085. else if( tok == T_RIGHT )
  2086. --bracketNesting;
  2087. if( bracketNesting >= 1 )
  2088. {
  2089. T previousTok = (T) PrevTok();
  2090. if( previousTok != T_LEFT && previousTok != T_circuit && tok != T_RIGHT )
  2091. builder += ' ';
  2092. if( tok == T_STRING )
  2093. builder += m_quote_char;
  2094. builder += CurText();
  2095. if( tok == T_STRING )
  2096. builder += m_quote_char;
  2097. }
  2098. // When the nested rule is closed with a T_RIGHT and we are back down
  2099. // to bracketNesting == 0, then save the builder and break;
  2100. if( bracketNesting == 0 )
  2101. {
  2102. growth->circuit.push_back( builder );
  2103. break;
  2104. }
  2105. }
  2106. if( tok == T_EOF )
  2107. Unexpected( T_EOF );
  2108. break;
  2109. } // scope bracket
  2110. default:
  2111. Unexpected( CurText() );
  2112. } // switch
  2113. tok = NextTok();
  2114. } // while
  2115. }
  2116. void SPECCTRA_DB::doNETWORK( NETWORK* growth )
  2117. {
  2118. T tok;
  2119. /* <network_descriptor >::=
  2120. (network
  2121. {<net_descriptor>}
  2122. [{<class_descriptor> }]
  2123. [{<class_class_descriptor> }]
  2124. [{<group_descriptor> }]
  2125. [{<group_set_descriptor> }]
  2126. [{<pair_descriptor> }]
  2127. [{<bundle_descriptor> }]
  2128. )
  2129. */
  2130. while( ( tok = NextTok() ) != T_RIGHT )
  2131. {
  2132. if( tok != T_LEFT )
  2133. Expecting( T_LEFT );
  2134. tok = NextTok();
  2135. switch( tok )
  2136. {
  2137. case T_net:
  2138. NET* net;
  2139. net = new NET( growth );
  2140. growth->nets.push_back( net );
  2141. doNET( net );
  2142. break;
  2143. case T_class:
  2144. CLASS* myclass;
  2145. myclass = new CLASS( growth );
  2146. growth->classes.push_back( myclass );
  2147. doCLASS( myclass );
  2148. break;
  2149. default:
  2150. Unexpected( CurText() );
  2151. }
  2152. }
  2153. }
  2154. void SPECCTRA_DB::doCOMP_ORDER( COMP_ORDER* growth )
  2155. {
  2156. T tok;
  2157. /* <component_order_descriptor >::=
  2158. (comp_order {<placement_id> })
  2159. */
  2160. while( IsSymbol( tok = NextTok() ) )
  2161. {
  2162. growth->placement_ids.push_back( CurText() );
  2163. }
  2164. if( tok != T_RIGHT )
  2165. Expecting( T_RIGHT );
  2166. }
  2167. void SPECCTRA_DB::doFROMTO( FROMTO* growth )
  2168. {
  2169. T tok;
  2170. /* <fromto_descriptor >::=
  2171. {(fromto
  2172. [<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
  2173. [<pin_reference> | <virtual_pin_descriptor> | <component_id >]
  2174. [(type [fix | normal | soft])]
  2175. [(net <net_id >)]
  2176. [<rule_descriptor> ]
  2177. [<circuit_descriptor> ]
  2178. [{<layer_rule_descriptor> }]
  2179. )}
  2180. */
  2181. // read the first two grammar items in as 2 single tokens, i.e. do not
  2182. // split apart the <pin_reference>s into 3 separate tokens. Do this by
  2183. // turning off the string delimiter in the lexer.
  2184. char old = SetStringDelimiter( 0 );
  2185. if( !IsSymbol(NextTok() ) )
  2186. {
  2187. SetStringDelimiter( old );
  2188. Expecting( T_SYMBOL );
  2189. }
  2190. growth->fromText = CurText();
  2191. if( !IsSymbol(NextTok() ) )
  2192. {
  2193. SetStringDelimiter( old );
  2194. Expecting( T_SYMBOL );
  2195. }
  2196. growth->toText = CurText();
  2197. SetStringDelimiter( old );
  2198. while( ( tok = NextTok() ) != T_RIGHT )
  2199. {
  2200. if( tok != T_LEFT )
  2201. Expecting( T_LEFT );
  2202. tok = NextTok();
  2203. switch( tok )
  2204. {
  2205. case T_type:
  2206. tok = NextTok();
  2207. if( tok != T_fix && tok != T_normal && tok != T_soft )
  2208. Expecting( "fix|normal|soft" );
  2209. growth->fromto_type = tok;
  2210. NeedRIGHT();
  2211. break;
  2212. case T_rule:
  2213. if( growth->rules )
  2214. Unexpected( tok );
  2215. growth->rules = new RULE( growth, T_rule );
  2216. doRULE( growth->rules );
  2217. break;
  2218. case T_layer_rule:
  2219. LAYER_RULE* layer_rule;
  2220. layer_rule = new LAYER_RULE( growth );
  2221. growth->layer_rules.push_back( layer_rule );
  2222. doLAYER_RULE( layer_rule );
  2223. break;
  2224. case T_net:
  2225. if( growth->net_id.size() )
  2226. Unexpected( tok );
  2227. NeedSYMBOL();
  2228. growth->net_id = CurText();
  2229. NeedRIGHT();
  2230. break;
  2231. // circuit descriptor not supported at this time
  2232. default:
  2233. Unexpected( CurText() );
  2234. }
  2235. }
  2236. }
  2237. void SPECCTRA_DB::doWIRE( WIRE* growth )
  2238. {
  2239. T tok;
  2240. /* <wire_shape_descriptor >::=
  2241. (wire
  2242. <shape_descriptor>
  2243. [(net <net_id >)]
  2244. [(turret <turret#> )]
  2245. [(type [fix | route | normal | protect])]
  2246. [(attr [test | fanout | bus | jumper])]
  2247. [(shield <net_id >)]
  2248. [{<window_descriptor> }]
  2249. [(connect
  2250. (terminal <object_type> [<pin_reference> ])
  2251. (terminal <object_type> [<pin_reference> ])
  2252. )]
  2253. [(supply)]
  2254. )
  2255. */
  2256. while( ( tok = NextTok() ) != T_RIGHT )
  2257. {
  2258. if( tok != T_LEFT )
  2259. Expecting( T_LEFT );
  2260. tok = NextTok();
  2261. switch( tok )
  2262. {
  2263. case T_rect:
  2264. if( growth->shape )
  2265. Unexpected( tok );
  2266. growth->shape = new RECTANGLE( growth );
  2267. doRECTANGLE( (RECTANGLE*) growth->shape );
  2268. break;
  2269. case T_circle:
  2270. if( growth->shape )
  2271. Unexpected( tok );
  2272. growth->shape = new CIRCLE( growth );
  2273. doCIRCLE( (CIRCLE*) growth->shape );
  2274. break;
  2275. case T_polyline_path:
  2276. tok = T_path;
  2277. KI_FALLTHROUGH;
  2278. case T_path:
  2279. case T_polygon:
  2280. if( growth->shape )
  2281. Unexpected( tok );
  2282. growth->shape = new PATH( growth, tok );
  2283. doPATH( (PATH*) growth->shape );
  2284. break;
  2285. case T_qarc:
  2286. if( growth->shape )
  2287. Unexpected( tok );
  2288. growth->shape = new QARC( growth );
  2289. doQARC( (QARC*) growth->shape );
  2290. break;
  2291. case T_net:
  2292. NeedSYMBOLorNUMBER();
  2293. growth->net_id = CurText();
  2294. NeedRIGHT();
  2295. break;
  2296. case T_turret:
  2297. if( NextTok() != T_NUMBER )
  2298. Expecting( T_NUMBER );
  2299. growth->turret = atoi( CurText() );
  2300. NeedRIGHT();
  2301. break;
  2302. case T_type:
  2303. tok = NextTok();
  2304. if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
  2305. Expecting( "fix|route|normal|protect" );
  2306. growth->wire_type = tok;
  2307. NeedRIGHT();
  2308. break;
  2309. case T_attr:
  2310. tok = NextTok();
  2311. if( tok != T_test && tok != T_fanout && tok != T_bus && tok != T_jumper )
  2312. Expecting( "test|fanout|bus|jumper" );
  2313. growth->attr = tok;
  2314. NeedRIGHT();
  2315. break;
  2316. case T_shield:
  2317. NeedSYMBOL();
  2318. growth->shield = CurText();
  2319. NeedRIGHT();
  2320. break;
  2321. case T_window:
  2322. WINDOW* window;
  2323. window = new WINDOW( growth );
  2324. growth->windows.push_back( window );
  2325. doWINDOW( window );
  2326. break;
  2327. case T_connect:
  2328. if( growth->connect )
  2329. Unexpected( tok );
  2330. growth->connect = new CONNECT( growth );
  2331. doCONNECT( growth->connect );
  2332. break;
  2333. case T_supply:
  2334. growth->supply = true;
  2335. NeedRIGHT();
  2336. break;
  2337. default:
  2338. Unexpected( CurText() );
  2339. }
  2340. }
  2341. }
  2342. void SPECCTRA_DB::doWIRE_VIA( WIRE_VIA* growth )
  2343. {
  2344. T tok;
  2345. POINT point;
  2346. /* <wire_via_descriptor >::=
  2347. (via
  2348. <padstack_id > {<vertex> }
  2349. [(net <net_id >)]
  2350. [(via_number <via#> )]
  2351. [(type [fix | route | normal | protect])]
  2352. [(attr [test | fanout | jumper |
  2353. virtual_pin <virtual_pin_name> ])]
  2354. [(contact {<layer_id >})]
  2355. [(supply)]
  2356. )
  2357. (virtual_pin
  2358. <virtual_pin_name> <vertex> (net <net_id >)
  2359. )
  2360. */
  2361. NeedSYMBOL();
  2362. growth->padstack_id = CurText();
  2363. while( ( tok = NextTok() ) == T_NUMBER )
  2364. {
  2365. point.x = strtod( CurText(), 0 );
  2366. if( NextTok() != T_NUMBER )
  2367. Expecting( "vertex.y" );
  2368. point.y = strtod( CurText(), 0 );
  2369. growth->vertexes.push_back( point );
  2370. }
  2371. while( tok != T_RIGHT )
  2372. {
  2373. if( tok != T_LEFT )
  2374. Expecting( T_LEFT );
  2375. tok = NextTok();
  2376. switch( tok )
  2377. {
  2378. case T_net:
  2379. NeedSYMBOL();
  2380. growth->net_id = CurText();
  2381. NeedRIGHT();
  2382. break;
  2383. case T_via_number:
  2384. if( NextTok() != T_NUMBER )
  2385. Expecting( "<via#>" );
  2386. growth->via_number = atoi( CurText() );
  2387. NeedRIGHT();
  2388. break;
  2389. case T_type:
  2390. tok = NextTok();
  2391. if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
  2392. Expecting( "fix|route|normal|protect" );
  2393. growth->via_type = tok;
  2394. NeedRIGHT();
  2395. break;
  2396. case T_attr:
  2397. tok = NextTok();
  2398. if( tok != T_test && tok != T_fanout && tok != T_jumper && tok != T_virtual_pin )
  2399. Expecting( "test|fanout|jumper|virtual_pin" );
  2400. growth->attr = tok;
  2401. if( tok == T_virtual_pin )
  2402. {
  2403. NeedSYMBOL();
  2404. growth->virtual_pin_name = CurText();
  2405. }
  2406. NeedRIGHT();
  2407. break;
  2408. case T_contact:
  2409. NeedSYMBOL();
  2410. tok = T_SYMBOL;
  2411. while( IsSymbol( tok ) )
  2412. {
  2413. growth->contact_layers.push_back( CurText() );
  2414. tok = NextTok();
  2415. }
  2416. if( tok != T_RIGHT )
  2417. Expecting( T_RIGHT );
  2418. break;
  2419. case T_supply:
  2420. growth->supply = true;
  2421. NeedRIGHT();
  2422. break;
  2423. default:
  2424. Unexpected( CurText() );
  2425. }
  2426. tok = NextTok();
  2427. }
  2428. }
  2429. void SPECCTRA_DB::doWIRING( WIRING* growth )
  2430. {
  2431. T tok;
  2432. /* <wiring_descriptor >::=
  2433. (wiring
  2434. [<unit_descriptor> | <resolution_descriptor> | null]
  2435. {<wire_descriptor> }
  2436. [<test_points_descriptor> ]
  2437. {[<supply_pin_descriptor> ]}
  2438. )
  2439. */
  2440. while( ( tok = NextTok() ) != T_RIGHT )
  2441. {
  2442. if( tok != T_LEFT )
  2443. Expecting( T_LEFT );
  2444. tok = NextTok();
  2445. switch( tok )
  2446. {
  2447. case T_unit:
  2448. if( growth->unit )
  2449. Unexpected( tok );
  2450. growth->unit = new UNIT_RES( growth, tok );
  2451. doUNIT( growth->unit );
  2452. break;
  2453. case T_resolution:
  2454. if( growth->unit )
  2455. Unexpected( tok );
  2456. growth->unit = new UNIT_RES( growth, tok );
  2457. doRESOLUTION( growth->unit );
  2458. break;
  2459. case T_wire:
  2460. WIRE* wire;
  2461. wire = new WIRE( growth );
  2462. growth->wires.push_back( wire );
  2463. doWIRE( wire );
  2464. break;
  2465. case T_via:
  2466. WIRE_VIA* wire_via;
  2467. wire_via = new WIRE_VIA( growth );
  2468. growth->wire_vias.push_back( wire_via );
  2469. doWIRE_VIA( wire_via );
  2470. break;
  2471. default:
  2472. Unexpected( CurText() );
  2473. }
  2474. }
  2475. }
  2476. void SPECCTRA_DB::doANCESTOR( ANCESTOR* growth )
  2477. {
  2478. T tok;
  2479. /* <ancestor_file_descriptor >::=
  2480. (ancestor <file_path_name> (created_time <time_stamp> )
  2481. [(comment <comment_string> )])
  2482. */
  2483. NeedSYMBOL();
  2484. growth->filename = CurText();
  2485. while( ( tok = NextTok() ) != T_RIGHT )
  2486. {
  2487. if( tok != T_LEFT )
  2488. Expecting( T_LEFT );
  2489. tok = NextTok();
  2490. switch( tok )
  2491. {
  2492. case T_created_time:
  2493. readTIME( &growth->time_stamp );
  2494. NeedRIGHT();
  2495. break;
  2496. case T_comment:
  2497. NeedSYMBOL();
  2498. growth->comment = CurText();
  2499. NeedRIGHT();
  2500. break;
  2501. default:
  2502. Unexpected( CurText() );
  2503. }
  2504. }
  2505. }
  2506. void SPECCTRA_DB::doHISTORY( HISTORY* growth )
  2507. {
  2508. T tok;
  2509. /* <history_descriptor >::=
  2510. (history [{<ancestor_file_descriptor> }] <self_descriptor> )
  2511. */
  2512. while( ( tok = NextTok() ) != T_RIGHT )
  2513. {
  2514. if( tok != T_LEFT )
  2515. Expecting( T_LEFT );
  2516. tok = NextTok();
  2517. switch( tok )
  2518. {
  2519. case T_ancestor:
  2520. ANCESTOR* ancestor;
  2521. ancestor = new ANCESTOR( growth );
  2522. growth->ancestors.push_back( ancestor );
  2523. doANCESTOR( ancestor );
  2524. break;
  2525. case T_self:
  2526. while( ( tok = NextTok() ) != T_RIGHT )
  2527. {
  2528. if( tok != T_LEFT )
  2529. Expecting( T_LEFT );
  2530. tok = NextTok();
  2531. switch( tok )
  2532. {
  2533. case T_created_time:
  2534. readTIME( &growth->time_stamp );
  2535. NeedRIGHT();
  2536. break;
  2537. case T_comment:
  2538. NeedSYMBOL();
  2539. growth->comments.push_back( CurText() );
  2540. NeedRIGHT();
  2541. break;
  2542. default:
  2543. Unexpected( CurText() );
  2544. }
  2545. }
  2546. break;
  2547. default:
  2548. Unexpected( CurText() );
  2549. }
  2550. }
  2551. }
  2552. void SPECCTRA_DB::doSESSION( SESSION* growth )
  2553. {
  2554. T tok;
  2555. /* <session_file_descriptor >::=
  2556. (session <session_id >
  2557. (base_design <path/filename >)
  2558. [<history_descriptor> ]
  2559. [<session_structure_descriptor> ]
  2560. [<placement_descriptor> ]
  2561. [<floor_plan_descriptor> ]
  2562. [<net_pin_changes_descriptor> ]
  2563. [<was_is_descriptor> ]
  2564. <swap_history_descriptor> ]
  2565. [<route_descriptor> ]
  2566. )
  2567. */
  2568. NeedSYMBOL();
  2569. growth->session_id = CurText();
  2570. while( ( tok = NextTok() ) != T_RIGHT )
  2571. {
  2572. if( tok != T_LEFT )
  2573. Expecting( T_LEFT );
  2574. tok = NextTok();
  2575. switch( tok )
  2576. {
  2577. case T_base_design:
  2578. NeedSYMBOL();
  2579. growth->base_design = CurText();
  2580. NeedRIGHT();
  2581. break;
  2582. case T_history:
  2583. if( growth->history )
  2584. Unexpected( tok );
  2585. growth->history = new HISTORY( growth );
  2586. doHISTORY( growth->history );
  2587. break;
  2588. case T_structure:
  2589. if( growth->structure )
  2590. Unexpected( tok );
  2591. growth->structure = new STRUCTURE( growth );
  2592. doSTRUCTURE( growth->structure );
  2593. break;
  2594. case T_placement:
  2595. if( growth->placement )
  2596. Unexpected( tok );
  2597. growth->placement = new PLACEMENT( growth );
  2598. doPLACEMENT( growth->placement );
  2599. break;
  2600. case T_was_is:
  2601. if( growth->was_is )
  2602. Unexpected( tok );
  2603. growth->was_is = new WAS_IS( growth );
  2604. doWAS_IS( growth->was_is );
  2605. break;
  2606. case T_routes:
  2607. if( growth->route )
  2608. Unexpected( tok );
  2609. growth->route = new ROUTE( growth );
  2610. doROUTE( growth->route );
  2611. break;
  2612. default:
  2613. Unexpected( CurText() );
  2614. }
  2615. }
  2616. }
  2617. void SPECCTRA_DB::doWAS_IS( WAS_IS* growth )
  2618. {
  2619. T tok;
  2620. PIN_PAIR empty( growth );
  2621. PIN_PAIR* pin_pair;
  2622. /* <was_is_descriptor >::=
  2623. (was_is {(pins <pin_reference> <pin_reference> )})
  2624. */
  2625. // none of the pins is ok too
  2626. while( ( tok = NextTok() ) != T_RIGHT )
  2627. {
  2628. if( tok != T_LEFT )
  2629. Expecting( T_LEFT );
  2630. tok = NextTok();
  2631. switch( tok )
  2632. {
  2633. case T_pins:
  2634. // copy the empty one, then fill its copy later thru pin_pair.
  2635. growth->pin_pairs.push_back( empty );
  2636. pin_pair= &growth->pin_pairs.back();
  2637. NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
  2638. readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
  2639. NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
  2640. readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
  2641. NeedRIGHT();
  2642. break;
  2643. default:
  2644. Unexpected( CurText() );
  2645. }
  2646. }
  2647. }
  2648. void SPECCTRA_DB::doROUTE( ROUTE* growth )
  2649. {
  2650. T tok;
  2651. /* <route_descriptor >::=
  2652. (routes
  2653. <resolution_descriptor>
  2654. <parser_descriptor>
  2655. <structure_out_descriptor>
  2656. <library_out_descriptor>
  2657. <network_out_descriptor>
  2658. <test_points_descriptor>
  2659. )
  2660. */
  2661. while( ( tok = NextTok() ) != T_RIGHT )
  2662. {
  2663. if( tok != T_LEFT )
  2664. Expecting( T_LEFT );
  2665. tok = NextTok();
  2666. switch( tok )
  2667. {
  2668. case T_resolution:
  2669. if( growth->resolution )
  2670. Unexpected( tok );
  2671. growth->resolution = new UNIT_RES( growth, tok );
  2672. doRESOLUTION( growth->resolution );
  2673. break;
  2674. case T_parser:
  2675. if( growth->parser )
  2676. {
  2677. #if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
  2678. // Work around their bug for now.
  2679. Unexpected( tok );
  2680. #else
  2681. delete growth->parser;
  2682. #endif
  2683. }
  2684. growth->parser = new PARSER( growth );
  2685. doPARSER( growth->parser );
  2686. break;
  2687. case T_structure_out:
  2688. if( growth->structure_out )
  2689. Unexpected( tok );
  2690. growth->structure_out = new STRUCTURE_OUT( growth );
  2691. doSTRUCTURE_OUT( growth->structure_out );
  2692. break;
  2693. case T_library_out:
  2694. if( growth->library )
  2695. Unexpected( tok );
  2696. growth->library = new LIBRARY( growth, tok );
  2697. doLIBRARY( growth->library );
  2698. break;
  2699. case T_network_out:
  2700. while( ( tok = NextTok() ) != T_RIGHT )
  2701. {
  2702. if( tok != T_LEFT )
  2703. Expecting( T_LEFT );
  2704. tok = NextTok();
  2705. if( tok != T_net ) // it is class NET_OUT, but token T_net
  2706. Unexpected( CurText() );
  2707. NET_OUT* net_out;
  2708. net_out = new NET_OUT( growth );
  2709. growth->net_outs.push_back( net_out );
  2710. doNET_OUT( net_out );
  2711. }
  2712. break;
  2713. default:
  2714. Unexpected( CurText() );
  2715. }
  2716. }
  2717. }
  2718. void SPECCTRA_DB::doNET_OUT( NET_OUT* growth )
  2719. {
  2720. T tok;
  2721. /* <net_out_descriptor >::=
  2722. (net <net_id >
  2723. [(net_number <integer >)]
  2724. [<rule_descriptor> ]
  2725. {[<wire_shape_descriptor> | <wire_guide_descriptor> |
  2726. <wire_via_descriptor> | <bond_shape_descriptor> ]}
  2727. {[<supply_pin_descriptor> ]}
  2728. )
  2729. */
  2730. NeedSYMBOLorNUMBER();
  2731. growth->net_id = CurText();
  2732. while( ( tok = NextTok() ) != T_RIGHT )
  2733. {
  2734. if( tok != T_LEFT )
  2735. Expecting( T_LEFT );
  2736. tok = NextTok();
  2737. switch( tok )
  2738. {
  2739. case T_net_number:
  2740. tok = NextTok();
  2741. if( tok!= T_NUMBER )
  2742. Expecting( T_NUMBER );
  2743. growth->net_number = atoi( CurText() );
  2744. NeedRIGHT();
  2745. break;
  2746. case T_rule:
  2747. if( growth->rules )
  2748. Unexpected( tok );
  2749. growth->rules = new RULE( growth, tok );
  2750. doRULE( growth->rules );
  2751. break;
  2752. case T_wire:
  2753. WIRE* wire;
  2754. wire = new WIRE( growth );
  2755. growth->wires.push_back( wire );
  2756. doWIRE( wire );
  2757. break;
  2758. case T_via:
  2759. WIRE_VIA* wire_via;
  2760. wire_via = new WIRE_VIA( growth );
  2761. growth->wire_vias.push_back( wire_via );
  2762. doWIRE_VIA( wire_via );
  2763. break;
  2764. case T_supply_pin:
  2765. SUPPLY_PIN* supply_pin;
  2766. supply_pin = new SUPPLY_PIN( growth );
  2767. growth->supply_pins.push_back( supply_pin );
  2768. doSUPPLY_PIN( supply_pin );
  2769. break;
  2770. default:
  2771. Unexpected( CurText() );
  2772. }
  2773. }
  2774. }
  2775. void SPECCTRA_DB::doSUPPLY_PIN( SUPPLY_PIN* growth )
  2776. {
  2777. T tok;
  2778. PIN_REF empty(growth);
  2779. /* <supply_pin_descriptor >::=
  2780. (supply_pin {<pin_reference> } [(net <net_id >)])
  2781. */
  2782. NeedSYMBOL();
  2783. growth->net_id = CurText();
  2784. while( ( tok = NextTok() ) != T_RIGHT )
  2785. {
  2786. if( IsSymbol(tok) )
  2787. {
  2788. growth->pin_refs.push_back( empty );
  2789. PIN_REF* pin_ref = &growth->pin_refs.back();
  2790. readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
  2791. }
  2792. else if( tok == T_LEFT )
  2793. {
  2794. tok = NextTok();
  2795. if( tok != T_net )
  2796. Expecting( T_net );
  2797. growth->net_id = CurText();
  2798. NeedRIGHT();
  2799. }
  2800. else
  2801. Unexpected( CurText() );
  2802. }
  2803. }
  2804. void SPECCTRA_DB::ExportPCB( const wxString& aFilename, bool aNameChange )
  2805. {
  2806. if( m_pcb )
  2807. {
  2808. FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
  2809. if( aNameChange )
  2810. m_pcb->pcbname = TO_UTF8( aFilename );
  2811. m_pcb->Format( &formatter, 0 );
  2812. }
  2813. }
  2814. void SPECCTRA_DB::ExportSESSION( const wxString& aFilename )
  2815. {
  2816. if( m_session )
  2817. {
  2818. FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
  2819. m_session->Format( &formatter, 0 );
  2820. }
  2821. }
  2822. PCB* SPECCTRA_DB::MakePCB()
  2823. {
  2824. PCB* pcb = new PCB();
  2825. pcb->parser = new PARSER( pcb );
  2826. pcb->resolution = new UNIT_RES( pcb, T_resolution );
  2827. pcb->unit = new UNIT_RES( pcb, T_unit );
  2828. pcb->structure = new STRUCTURE( pcb );
  2829. pcb->structure->boundary = new BOUNDARY( pcb->structure );
  2830. pcb->structure->via = new VIA( pcb->structure );
  2831. pcb->structure->rules = new RULE( pcb->structure, T_rule );
  2832. pcb->placement = new PLACEMENT( pcb );
  2833. pcb->library = new LIBRARY( pcb );
  2834. pcb->network = new NETWORK( pcb );
  2835. pcb->wiring = new WIRING( pcb );
  2836. return pcb;
  2837. }
  2838. //-----<ELEM>---------------------------------------------------------------
  2839. ELEM::ELEM( T aType, ELEM* aParent ) :
  2840. type( aType ),
  2841. parent( aParent )
  2842. {
  2843. }
  2844. ELEM::~ELEM()
  2845. {
  2846. }
  2847. const char* ELEM::Name() const
  2848. {
  2849. return SPECCTRA_DB::TokenName( type );
  2850. }
  2851. UNIT_RES* ELEM::GetUnits() const
  2852. {
  2853. if( parent )
  2854. return parent->GetUnits();
  2855. return &UNIT_RES::Default;
  2856. }
  2857. void ELEM::Format( OUTPUTFORMATTER* out, int nestLevel )
  2858. {
  2859. out->Print( nestLevel, "(%s\n", Name() );
  2860. FormatContents( out, nestLevel+1 );
  2861. out->Print( nestLevel, ")\n" );
  2862. }
  2863. void ELEM_HOLDER::FormatContents( OUTPUTFORMATTER* out, int nestLevel )
  2864. {
  2865. for( int i = 0; i < Length(); ++i )
  2866. At(i)->Format( out, nestLevel );
  2867. }
  2868. int ELEM_HOLDER::FindElem( T aType, int instanceNum )
  2869. {
  2870. int repeats=0;
  2871. for( unsigned i = 0; i < kids.size(); ++i )
  2872. {
  2873. if( kids[i].Type() == aType )
  2874. {
  2875. if( repeats == instanceNum )
  2876. return i;
  2877. ++repeats;
  2878. }
  2879. }
  2880. return -1;
  2881. }
  2882. // a reasonably small memory price to pay for improved performance
  2883. STRING_FORMATTER ELEM::sf;
  2884. UNIT_RES UNIT_RES::Default( nullptr, T_resolution );
  2885. int PADSTACK::Compare( PADSTACK* lhs, PADSTACK* rhs )
  2886. {
  2887. if( !lhs->hash.size() )
  2888. lhs->hash = lhs->makeHash();
  2889. if( !rhs->hash.size() )
  2890. rhs->hash = rhs->makeHash();
  2891. int result = lhs->hash.compare( rhs->hash );
  2892. if( result )
  2893. return result;
  2894. // Via names hold the drill diameters, so we have to include those to discern
  2895. // between two vias with same copper size but with different drill sizes.
  2896. result = lhs->padstack_id.compare( rhs->padstack_id );
  2897. return result;
  2898. }
  2899. int IMAGE::Compare( IMAGE* lhs, IMAGE* rhs )
  2900. {
  2901. if( !lhs->hash.size() )
  2902. lhs->hash = lhs->makeHash();
  2903. if( !rhs->hash.size() )
  2904. rhs->hash = rhs->makeHash();
  2905. int result = lhs->hash.compare( rhs->hash );
  2906. return result;
  2907. }
  2908. /*
  2909. int COMPONENT::Compare( COMPONENT* lhs, COMPONENT* rhs )
  2910. {
  2911. if( !lhs->hash.size() )
  2912. lhs->hash = lhs->makeHash();
  2913. if( !rhs->hash.size() )
  2914. rhs->hash = rhs->makeHash();
  2915. int result = lhs->hash.compare( rhs->hash );
  2916. return result;
  2917. }
  2918. */
  2919. PARSER::PARSER( ELEM* aParent ) :
  2920. ELEM( T_parser, aParent )
  2921. {
  2922. string_quote = '"';
  2923. space_in_quoted_tokens = false;
  2924. case_sensitive = false;
  2925. wires_include_testpoint = false;
  2926. routes_include_testpoint = false;
  2927. routes_include_guides = false;
  2928. routes_include_image_conductor = false;
  2929. via_rotate_first = true;
  2930. generated_by_freeroute = false;
  2931. host_cad = "KiCad's Pcbnew";
  2932. wxString msg = GetBuildVersion();
  2933. host_version = TO_UTF8(msg);
  2934. }
  2935. void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel )
  2936. {
  2937. out->Print( nestLevel, "(string_quote %c)\n", string_quote );
  2938. out->Print( nestLevel, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
  2939. out->Print( nestLevel, "(host_cad \"%s\")\n", host_cad.c_str() );
  2940. out->Print( nestLevel, "(host_version \"%s\")\n", host_version.c_str() );
  2941. for( STRINGS::iterator i = constants.begin(); i != constants.end(); )
  2942. {
  2943. const std::string& s1 = *i++;
  2944. const std::string& s2 = *i++;
  2945. const char* q1 = out->GetQuoteChar( s1.c_str() );
  2946. const char* q2 = out->GetQuoteChar( s2.c_str() );
  2947. out->Print( nestLevel, "(constant %s%s%s %s%s%s)\n",
  2948. q1, s1.c_str(), q1, q2, s2.c_str(), q2 );
  2949. }
  2950. if( routes_include_testpoint || routes_include_guides || routes_include_image_conductor )
  2951. {
  2952. out->Print( nestLevel, "(routes_include%s%s%s)\n",
  2953. routes_include_testpoint ? " testpoint" : "",
  2954. routes_include_guides ? " guides" : "",
  2955. routes_include_image_conductor ? " image_conductor" : "" );
  2956. }
  2957. if( wires_include_testpoint )
  2958. out->Print( nestLevel, "(wires_include testpoint)\n" );
  2959. if( !via_rotate_first )
  2960. out->Print( nestLevel, "(via_rotate_first off)\n" );
  2961. if( case_sensitive )
  2962. out->Print( nestLevel, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
  2963. }
  2964. void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel )
  2965. {
  2966. bool useMultiLine;
  2967. const char* quote = out->GetQuoteChar( component_id.c_str() );
  2968. if( place_rules || properties.size() || rules || region )
  2969. {
  2970. useMultiLine = true;
  2971. out->Print( nestLevel, "(%s %s%s%s\n", Name(), quote, component_id.c_str(), quote );
  2972. out->Print( nestLevel+1, "%s", "" );
  2973. }
  2974. else
  2975. {
  2976. useMultiLine = false;
  2977. out->Print( nestLevel, "(%s %s%s%s", Name(), quote, component_id.c_str(), quote );
  2978. }
  2979. if( hasVertex )
  2980. {
  2981. out->Print( 0, " %.6f %.6f", vertex.x, vertex.y );
  2982. out->Print( 0, " %s", GetTokenText( side ) );
  2983. out->Print( 0, " %.6f", rotation );
  2984. }
  2985. const char* space = " "; // one space, as c string.
  2986. if( mirror != T_NONE )
  2987. {
  2988. out->Print( 0, "%s(mirror %s)", space, GetTokenText( mirror ) );
  2989. space = "";
  2990. }
  2991. if( status != T_NONE )
  2992. {
  2993. out->Print( 0, "%s(status %s)", space, GetTokenText( status ) );
  2994. space = "";
  2995. }
  2996. if( logical_part.size() )
  2997. {
  2998. quote = out->GetQuoteChar( logical_part.c_str() );
  2999. out->Print( 0, "%s(logical_part %s%s%s)", space, quote, logical_part.c_str(), quote );
  3000. space = "";
  3001. }
  3002. if( useMultiLine )
  3003. {
  3004. out->Print( 0, "\n" );
  3005. if( place_rules )
  3006. {
  3007. place_rules->Format( out, nestLevel+1 );
  3008. }
  3009. if( properties.size() )
  3010. {
  3011. out->Print( nestLevel + 1, "(property \n" );
  3012. for( PROPERTIES::const_iterator i = properties.begin(); i != properties.end(); ++i )
  3013. i->Format( out, nestLevel + 2 );
  3014. out->Print( nestLevel + 1, ")\n" );
  3015. }
  3016. if( lock_type != T_NONE )
  3017. out->Print( nestLevel + 1, "(lock_type %s)\n", GetTokenText( lock_type ) );
  3018. if( rules )
  3019. rules->Format( out, nestLevel+1 );
  3020. if( region )
  3021. region->Format( out, nestLevel+1 );
  3022. if( part_number.size() )
  3023. {
  3024. quote = out->GetQuoteChar( part_number.c_str() );
  3025. out->Print( nestLevel + 1, "(PN %s%s%s)\n", quote, part_number.c_str(), quote );
  3026. }
  3027. }
  3028. else
  3029. {
  3030. if( lock_type != T_NONE )
  3031. {
  3032. out->Print( 0, "%s(lock_type %s)", space, GetTokenText( lock_type ) );
  3033. space = "";
  3034. }
  3035. if( part_number.size() )
  3036. {
  3037. quote = out->GetQuoteChar( part_number.c_str() );
  3038. out->Print( 0, "%s(PN %s%s%s)", space, quote, part_number.c_str(), quote );
  3039. }
  3040. }
  3041. out->Print( 0, ")\n" );
  3042. }
  3043. } // namespace DSN