KiCad PCB EDA Suite
Loading...
Searching...
No Matches
specctra.cpp
Go to the documentation of this file.
1
2/*
3 * This program source code file is part of KiCad, a free EDA CAD application.
4 *
5 * Copyright (C) 2007-2011 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26
27/*
28 * This source file implements export and import capabilities to the
29 * specctra dsn file format. The grammar for that file format is documented
30 * fairly well. There are classes for each major type of descriptor in the
31 * spec.
32 *
33 * Since there are so many classes in here, it may be helpful to generate
34 * the Doxygen directory:
35 *
36 * $ cd <kicadSourceRoot>
37 * $ doxygen
38 *
39 * Then you can view the html documentation in the <kicadSourceRoot>/doxygen
40 * directory. The main class in this file is SPECCTRA_DB and its main
41 * functions are LoadPCB(), LoadSESSION(), and ExportPCB().
42 *
43 * Wide use is made of boost::ptr_vector<> and std::vector<> template classes.
44 * If the contained object is small, then std::vector tends to be used.
45 * If the contained object is large, variable size, or would require writing
46 * an assignment operator() or copy constructor, then boost::ptr_vector
47 * cannot be beat.
48 */
49
50
51#include <cstdarg>
52#include <cstdio>
53
54#include <build_version.h>
55
56#include <board.h>
57#include <pcb_track.h>
58
59#include "specctra.h"
60#include <macros.h>
61
62
63namespace DSN {
64
65#define NESTWIDTH 2
66
67//-----<SPECCTRA_DB>-------------------------------------------------
68
69
70const char* GetTokenText( T aTok )
71{
72 return SPECCTRA_LEXER::TokenName( aTok );
73}
74
75
77{
78 m_layerIds.clear();
79
80 // specctra wants top physical layer first, then going down to the
81 // bottom most physical layer in physical sequence.
82
83 LSET layerset = aBoard->GetEnabledLayers() & LSET::AllCuMask();
84 int pcbLayer = 0;
85
86 for( PCB_LAYER_ID kiLayer : layerset.CuStack() )
87 {
88 m_kicadLayer2pcb[kiLayer] = pcbLayer;
89 m_pcbLayer2kicad[pcbLayer] = kiLayer;
90
91 // save the specctra layer name in SPECCTRA_DB::layerIds for later.
92 m_layerIds.push_back( TO_UTF8( aBoard->GetLayerName( kiLayer ) ) );
93
94 pcbLayer++;
95 }
96}
97
98
99int SPECCTRA_DB::findLayerName( const std::string& aLayerName ) const
100{
101 for( int i = 0; i < int( m_layerIds.size() ); ++i )
102 {
103 if( 0 == aLayerName.compare( m_layerIds[i] ) )
104 return i;
105 }
106
107 return -1;
108}
109
110
111void SPECCTRA_DB::readCOMPnPIN( std::string* component_id, std::string* pin_id )
112{
113 T tok;
114
115 static const char pin_def[] = "<pin_reference>::=<component_id>-<pin_id>";
116
117 if( !IsSymbol( (T) CurTok() ) )
118 Expecting( pin_def );
119
120 // case for: A12-14, i.e. no wrapping quotes. This should be a single
121 // token, so split it.
122 if( CurTok() != T_STRING )
123 {
124 const char* toktext = CurText();
125 const char* dash = strchr( toktext, '-' );
126
127 if( !dash )
128 Expecting( pin_def );
129
130 while( toktext != dash )
131 *component_id += *toktext++;
132
133 ++toktext; // skip the dash
134
135 while( *toktext )
136 *pin_id += *toktext++;
137 }
138 else // quoted string: "U12"-"14" or "U12"-14, 3 tokens in either case
139 {
140 *component_id = CurText();
141
142 tok = NextTok();
143
144 if( tok!=T_DASH )
145 Expecting( pin_def );
146
147 NextTok(); // accept anything after the dash.
148 *pin_id = CurText();
149 }
150}
151
152
153void SPECCTRA_DB::readTIME( time_t* time_stamp )
154{
155 T tok;
156
157 struct tm mytime;
158
159 mytime.tm_hour = 0;
160 mytime.tm_min = 0;
161 mytime.tm_sec = 0;
162 mytime.tm_isdst = 0; // useless param here.
163
164 static const char time_toks[] = "<month> <day> <hour> : <minute> : <second> <year> or <month> <day> <hour>:<minute>:<second> <year>";
165
166 static const char* months[] = { // index 0 = Jan
167 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
168 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", nullptr
169 };
170
171 NeedSYMBOL(); // month
172
173 const char* ptok = CurText();
174
175 mytime.tm_mon = 0; // remains if we don't find a month match.
176
177 for( int m = 0; months[m]; ++m )
178 {
179 if( !strcasecmp( months[m], ptok ) )
180 {
181 mytime.tm_mon = m;
182 break;
183 }
184 }
185
186 tok = NextTok(); // day
187
188 if( tok != T_NUMBER )
189 Expecting( time_toks );
190
191 mytime.tm_mday = atoi( CurText() );
192
193 tok = NextTok(); // hour or H:M:S
194
195 if( tok == T_NUMBER )
196 {
197 mytime.tm_hour = atoi( CurText() );
198
199 // : colon
200 NeedSYMBOL();
201
202 if( *CurText() != ':' || strlen( CurText() ) != 1 )
203 Expecting( time_toks );
204
205 tok = NextTok(); // minute
206
207 if( tok != T_NUMBER )
208 Expecting( time_toks );
209
210 mytime.tm_min = atoi( CurText() );
211
212 // : colon
213 NeedSYMBOL();
214
215 if( *CurText() != ':' || strlen( CurText() ) != 1 )
216 Expecting( time_toks );
217
218 tok = NextTok(); // second
219
220 if( tok != T_NUMBER )
221 Expecting( time_toks );
222
223 mytime.tm_sec = atoi( CurText() );
224 }
225 else if( tok == T_SYMBOL )
226 {
227 wxString str = wxString( CurText() );
228 wxArrayString arr = wxSplit( str, ':', '\0' );
229
230 if( arr.size() != 3 )
231 Expecting( time_toks );
232
233 mytime.tm_hour = wxAtoi( arr[0] );
234 mytime.tm_min = wxAtoi( arr[1] );
235 mytime.tm_sec = wxAtoi( arr[2] );
236 }
237
238 tok = NextTok(); // year
239
240 if( tok != T_NUMBER )
241 Expecting( time_toks );
242
243 mytime.tm_year = atoi( CurText() ) - 1900;
244
245 *time_stamp = mktime( &mytime );
246}
247
248
249void SPECCTRA_DB::LoadPCB( const wxString& aFilename )
250{
251 FILE_LINE_READER curr_reader( aFilename );
252
253 PushReader( &curr_reader );
254
255 if( NextTok() != T_LEFT )
256 Expecting( T_LEFT );
257
258 if( NextTok() != T_pcb )
259 Expecting( T_pcb );
260
261 SetPCB( new PCB() );
262
263 doPCB( m_pcb );
264 PopReader();
265}
266
267
268void SPECCTRA_DB::LoadSESSION( const wxString& aFilename )
269{
270 FILE_LINE_READER curr_reader( aFilename );
271
272 PushReader( &curr_reader );
273
274 if( NextTok() != T_LEFT )
275 Expecting( T_LEFT );
276
277 if( NextTok() != T_session )
278 Expecting( T_session );
279
280 SetSESSION( new SESSION() );
281
283
284 PopReader();
285}
286
287
288void SPECCTRA_DB::doPCB( PCB* growth )
289{
290 T tok;
291
292 /* <design_descriptor >::=
293 (pcb <pcb_id >
294 [<parser_descriptor> ]
295 [<capacitance_resolution_descriptor> ]
296 [<conductance_resolution_descriptor> ]
297 [<current_resolution_descriptor> ]
298 [<inductance_resolution_descriptor> ]
299 [<resistance_resolution_descriptor> ]
300 [<resolution_descriptor> ]
301 [<time_resolution_descriptor> ]
302 [<voltage_resolution_descriptor> ]
303 [<unit_descriptor> ]
304 [<structure_descriptor> | <file_descriptor> ]
305 [<placement_descriptor> | <file_descriptor> ]
306 [<library_descriptor> | <file_descriptor> ]
307 [<floor_plan_descriptor> | <file_descriptor> ]
308 [<part_library_descriptor> | <file_descriptor> ]
309 [<network_descriptor> | <file_descriptor> ]
310 [<wiring_descriptor> ]
311 [<color_descriptor> ]
312 )
313 */
314
315 NeedSYMBOL();
316 growth->m_pcbname = CurText();
317
318 while( (tok = NextTok()) != T_RIGHT )
319 {
320 if( tok != T_LEFT )
321 Expecting( T_LEFT );
322
323 tok = NextTok();
324
325 switch( tok )
326 {
327 case T_parser:
328 if( growth->m_parser )
329 Unexpected( tok );
330
331 growth->m_parser = new PARSER( growth );
332 doPARSER( growth->m_parser );
333 break;
334
335 case T_unit:
336 if( growth->m_unit )
337 Unexpected( tok );
338
339 growth->m_unit = new UNIT_RES( growth, tok );
340 doUNIT( growth->m_unit );
341 break;
342
343 case T_resolution:
344 if( growth->m_resolution )
345 Unexpected( tok );
346
347 growth->m_resolution = new UNIT_RES( growth, tok );
348 doRESOLUTION( growth->m_resolution );
349 break;
350
351 case T_structure:
352 if( growth->m_structure )
353 Unexpected( tok );
354
355 growth->m_structure = new STRUCTURE( growth );
356 doSTRUCTURE( growth->m_structure );
357 break;
358
359 case T_placement:
360 if( growth->m_placement )
361 Unexpected( tok );
362
363 growth->m_placement = new PLACEMENT( growth );
364 doPLACEMENT( growth->m_placement );
365 break;
366
367 case T_library:
368 if( growth->m_library )
369 Unexpected( tok );
370
371 growth->m_library = new LIBRARY( growth );
372 doLIBRARY( growth->m_library );
373 break;
374
375 case T_network:
376 if( growth->m_network )
377 Unexpected( tok );
378
379 growth->m_network = new NETWORK( growth );
380 doNETWORK( growth->m_network );
381 break;
382
383 case T_wiring:
384 if( growth->m_wiring )
385 Unexpected( tok );
386
387 growth->m_wiring = new WIRING( growth );
388 doWIRING( growth->m_wiring );
389 break;
390
391 default:
392 Unexpected( CurText() );
393 }
394 }
395
396 tok = NextTok();
397
398 if( tok != T_EOF )
399 Expecting( T_EOF );
400}
401
402
404{
405 T tok;
406 std::string const1;
407 std::string const2;
408
409 /* <parser_descriptor >::=
410 (parser
411 [(string_quote <quote_char >)]
412 (space_in_quoted_tokens [on | off])
413 [(host_cad <id >)]
414 [(host_version <id >)]
415 [{(constant <id > <id >)}]
416 [(write_resolution] {<character> <positive_integer >})]
417 [(routes_include {[testpoint | guides |
418 image_conductor]})]
419 [(wires_include testpoint)]
420 [(case_sensitive [on | off])]
421 [(via_rotate_first [on | off])]
422 )
423 */
424
425 while( (tok = NextTok()) != T_RIGHT )
426 {
427 if( tok != T_LEFT )
428 Expecting( T_LEFT );
429
430 tok = NextTok();
431
432 switch( tok )
433 {
434 case T_STRING_QUOTE:
435 tok = NextTok();
436
437 if( tok != T_QUOTE_DEF )
438 Expecting( T_QUOTE_DEF );
439
440 SetStringDelimiter( (unsigned char) *CurText() );
441 growth->string_quote = *CurText();
442 m_quote_char = CurText();
443 NeedRIGHT();
444 break;
445
446 case T_space_in_quoted_tokens:
447 tok = NextTok();
448
449 if( tok!=T_on && tok!=T_off )
450 Expecting( "on|off" );
451
452 SetSpaceInQuotedTokens( tok==T_on );
453 growth->space_in_quoted_tokens = (tok==T_on);
454 NeedRIGHT();
455 break;
456
457 case T_host_cad:
458 NeedSYMBOL();
459 growth->host_cad = CurText();
460 NeedRIGHT();
461 break;
462
463 case T_host_version:
464 NeedSYMBOLorNUMBER();
465 growth->host_version = CurText();
466 NeedRIGHT();
467 break;
468
469 case T_constant:
470 NeedSYMBOLorNUMBER();
471 const1 = CurText();
472 NeedSYMBOLorNUMBER();
473 const2 = CurText();
474 NeedRIGHT();
475 growth->constants.push_back( const1 );
476 growth->constants.push_back( const2 );
477 break;
478
479 case T_write_resolution: // [(writee_resolution {<character> <positive_integer >})]
480 while( (tok = NextTok()) != T_RIGHT )
481 {
482 if( tok!=T_SYMBOL )
483 Expecting( T_SYMBOL );
484
485 tok = NextTok();
486
487 if( tok!=T_NUMBER )
488 Expecting( T_NUMBER );
489
490 // @todo
491 }
492
493 break;
494
495 case T_routes_include: // [(routes_include {[testpoint | guides | image_conductor]})]
496 while( (tok = NextTok()) != T_RIGHT )
497 {
498 switch( tok )
499 {
500 case T_testpoint:
501 growth->routes_include_testpoint = true;
502 break;
503 case T_guide:
504 growth->routes_include_guides = true;
505 break;
506 case T_image_conductor:
507 growth->routes_include_image_conductor = true;
508 break;
509 default:
510 Expecting( "testpoint|guides|image_conductor" );
511 }
512 }
513
514 break;
515
516 case T_wires_include: // [(wires_include testpoint)]
517 tok = NextTok();
518
519 if( tok != T_testpoint )
520 Expecting( T_testpoint );
521
522 growth->routes_include_testpoint = true;
523 NeedRIGHT();
524 break;
525
526 case T_case_sensitive:
527 tok = NextTok();
528
529 if( tok!=T_on && tok!=T_off )
530 Expecting( "on|off" );
531
532 growth->case_sensitive = (tok==T_on);
533 NeedRIGHT();
534 break;
535
536 case T_via_rotate_first: // [(via_rotate_first [on | off])]
537 tok = NextTok();
538
539 if( tok!=T_on && tok!=T_off )
540 Expecting( "on|off" );
541
542 growth->via_rotate_first = (tok==T_on);
543 NeedRIGHT();
544 break;
545
546 case T_generated_by_freeroute:
547 growth->generated_by_freeroute = true;
548 NeedRIGHT();
549 break;
550
551 default:
552 Unexpected( CurText() );
553 }
554 }
555}
556
557
559{
560 NextTok();
561 wxString str = wxString( CurText() ).MakeLower();
562
563 if( str == wxS( "inch" ) )
564 growth->units = T_inch;
565 else if( str == wxS( "mil" ) )
566 growth->units = T_mil;
567 else if( str == wxS( "cm" ) )
568 growth->units = T_cm;
569 else if( str == wxS( "mm" ) )
570 growth->units = T_mm;
571 else if( str == wxS( "um" ) )
572 growth->units = T_um;
573 else
574 Expecting( "inch|mil|cm|mm|um" );
575
576 T tok = NextTok();
577
578 if( tok != T_NUMBER )
579 Expecting( T_NUMBER );
580
581 growth->value = atoi( CurText() );
582
583 NeedRIGHT();
584}
585
586
588{
589 T tok = NextTok();
590
591 switch( tok )
592 {
593 case T_inch:
594 case T_mil:
595 case T_cm:
596 case T_mm:
597 case T_um:
598 growth->units = tok;
599 break;
600 default:
601 Expecting( "inch|mil|cm|mm|um" );
602 }
603
604 NeedRIGHT();
605}
606
607
609{
610 NeedSYMBOL();
611 growth->layer_id0 = CurText();
612
613 NeedSYMBOL();
614 growth->layer_id1 = CurText();
615
616 if( NextTok() != T_NUMBER )
617 Expecting( T_NUMBER );
618
619 growth->layer_weight = strtod( CurText(), 0 );
620
621 NeedRIGHT();
622}
623
624
626
627{
628 T tok;
629
630 while( ( tok = NextTok() ) != T_RIGHT )
631 {
632 if( tok != T_LEFT )
633 Expecting( T_LEFT );
634
635 if( NextTok() != T_layer_pair )
636 Expecting( T_layer_pair );
637
638 SPECCTRA_LAYER_PAIR* layer_pair = new SPECCTRA_LAYER_PAIR( growth );
639 growth->layer_pairs.push_back( layer_pair );
640 doSPECCTRA_LAYER_PAIR( layer_pair );
641 }
642}
643
644
646{
647 T tok;
648
649 while( ( tok = NextTok() ) != T_RIGHT )
650 {
651 if( tok != T_LEFT )
652 Expecting( T_LEFT );
653
654 tok = NextTok();
655
656 switch( tok )
657 {
658 case T_unit:
659 if( growth->m_unit )
660 Unexpected( tok );
661
662 growth->m_unit = new UNIT_RES( growth, tok );
663 doUNIT( growth->m_unit );
664 break;
665
666 case T_resolution:
667 if( growth->m_unit )
668 Unexpected( tok );
669
670 growth->m_unit = new UNIT_RES( growth, tok );
671 doRESOLUTION( growth->m_unit );
672 break;
673
674 case T_layer_noise_weight:
675 if( growth->m_layer_noise_weight )
676 Unexpected( tok );
677
678 growth->m_layer_noise_weight = new LAYER_NOISE_WEIGHT( growth );
680 break;
681
682 case T_place_boundary:
683L_place:
684 if( growth->m_place_boundary )
685 Unexpected( tok );
686
687 growth->m_place_boundary = new BOUNDARY( growth, T_place_boundary );
688 doBOUNDARY( growth->m_place_boundary );
689 break;
690
691 case T_boundary:
692 if( growth->m_boundary )
693 {
694 if( growth->m_place_boundary )
695 Unexpected( tok );
696
697 goto L_place;
698 }
699
700 growth->m_boundary = new BOUNDARY( growth );
701 doBOUNDARY( growth->m_boundary );
702 break;
703
704 case T_plane:
705 COPPER_PLANE* plane;
706 plane = new COPPER_PLANE( growth );
707 growth->m_planes.push_back( plane );
708 doKEEPOUT( plane );
709 break;
710
711 case T_region:
712 REGION* region;
713 region = new REGION( growth );
714 growth->m_regions.push_back( region );
715 doREGION( region );
716 break;
717
718 case T_snap_angle:
719 STRINGPROP* stringprop;
720 stringprop = new STRINGPROP( growth, T_snap_angle );
721 growth->Append( stringprop );
722 doSTRINGPROP( stringprop );
723 break;
724
725 case T_via:
726 if( growth->m_via )
727 Unexpected( tok );
728
729 growth->m_via = new VIA( growth );
730 doVIA( growth->m_via );
731 break;
732
733 case T_control:
734 if( growth->m_control )
735 Unexpected( tok );
736
737 growth->m_control = new CONTROL( growth );
738 doCONTROL( growth->m_control );
739 break;
740
741 case T_layer:
742 LAYER* layer;
743 layer = new LAYER( growth );
744 growth->m_layers.push_back( layer );
745 doLAYER( layer );
746 break;
747
748 case T_rule:
749 if( growth->m_rules )
750 Unexpected( tok );
751
752 growth->m_rules = new RULE( growth, T_rule );
753 doRULE( growth->m_rules );
754 break;
755
756 case T_place_rule:
757 if( growth->m_place_rules )
758 Unexpected( tok );
759
760 growth->m_place_rules = new RULE( growth, T_place_rule );
761 doRULE( growth->m_place_rules );
762 break;
763
764 case T_keepout:
765 case T_place_keepout:
766 case T_via_keepout:
767 case T_wire_keepout:
768 case T_bend_keepout:
769 case T_elongate_keepout:
770 KEEPOUT* keepout;
771 keepout = new KEEPOUT( growth, tok );
772 growth->m_keepouts.push_back( keepout );
773 doKEEPOUT( keepout );
774 break;
775
776 case T_grid:
777 GRID* grid;
778 grid = new GRID( growth );
779 growth->m_grids.push_back( grid );
780 doGRID( grid );
781 break;
782
783 default:
784 Unexpected( CurText() );
785 }
786 }
787}
788
789
791{
792 /*
793 <structure_out_descriptor >::=
794 (structure_out
795 {<layer_descriptor> }
796 [<rule_descriptor> ]
797 )
798 */
799
800 T tok = NextTok();
801
802 while( tok != T_RIGHT )
803 {
804 if( tok != T_LEFT )
805 Expecting( T_LEFT );
806
807 tok = NextTok();
808
809 switch( tok )
810 {
811 case T_layer:
812 LAYER* layer;
813 layer = new LAYER( growth );
814 growth->m_layers.push_back( layer );
815 doLAYER( layer );
816 break;
817
818 case T_rule:
819 if( growth->m_rules )
820 Unexpected( tok );
821
822 growth->m_rules = new RULE( growth, T_rule );
823 doRULE( growth->m_rules );
824 break;
825
826 default:
827 Unexpected( CurText() );
828 }
829
830 tok = NextTok();
831 }
832}
833
834
836{
837 T tok = NextTok();
838
839 if( IsSymbol(tok) )
840 {
841 growth->m_name = CurText();
842 tok = NextTok();
843 }
844
845 if( tok!=T_LEFT )
846 Expecting( T_LEFT );
847
848 while( tok != T_RIGHT )
849 {
850 if( tok!=T_LEFT )
851 Expecting( T_LEFT );
852
853 tok = NextTok();
854
855 switch( tok )
856 {
857 case T_sequence_number:
858 if( NextTok() != T_NUMBER )
859 Expecting( T_NUMBER );
860
861 growth->m_sequence_number = atoi( CurText() );
862 NeedRIGHT();
863 break;
864
865 case T_rule:
866 if( growth->m_rules )
867 Unexpected( tok );
868
869 growth->m_rules = new RULE( growth, T_rule );
870 doRULE( growth->m_rules );
871 break;
872
873 case T_place_rule:
874 if( growth->m_place_rules )
875 Unexpected( tok );
876
877 growth->m_place_rules = new RULE( growth, T_place_rule );
878 doRULE( growth->m_place_rules );
879 break;
880
881 case T_rect:
882 if( growth->m_shape )
883 Unexpected( tok );
884
885 growth->m_shape = new RECTANGLE( growth );
886 doRECTANGLE( (RECTANGLE*) growth->m_shape );
887 break;
888
889 case T_circle:
890 if( growth->m_shape )
891 Unexpected( tok );
892
893 growth->m_shape = new CIRCLE( growth );
894 doCIRCLE( (CIRCLE*) growth->m_shape );
895 break;
896
897 case T_polyline_path:
898 tok = T_path;
900
901 case T_path:
902 case T_polygon:
903 if( growth->m_shape )
904 Unexpected( tok );
905
906 growth->m_shape = new PATH( growth, tok );
907 doPATH( (PATH*) growth->m_shape );
908 break;
909
910 case T_qarc:
911 if( growth->m_shape )
912 Unexpected( tok );
913
914 growth->m_shape = new QARC( growth );
915 doQARC( (QARC*) growth->m_shape );
916 break;
917
918 case T_window:
919 WINDOW* window;
920 window = new WINDOW( growth );
921 growth->m_windows.push_back( window );
922 doWINDOW( window );
923 break;
924
925 default:
926 Unexpected( CurText() );
927 }
928
929 tok = NextTok();
930 }
931}
932
933
935{
936 /* from page 143 of specctra spec:
937
938 (connect
939 {(terminal <object_type> [<pin_reference> ])}
940 )
941 */
942
943 T tok = NextTok();
944
945 while( tok != T_RIGHT )
946 {
947 if( tok!=T_LEFT )
948 Expecting( T_LEFT );
949
950 tok = NextTok();
951
952 switch( tok )
953 {
954 case T_terminal:
955 // since we do not use the terminal information, simply toss it.
956 while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
957 ;
958 break;
959
960 default:
961 Unexpected( CurText() );
962 }
963
964 tok = NextTok();
965 }
966}
967
968
970{
971 T tok = NextTok();
972
973 while( tok != T_RIGHT )
974 {
975 if( tok!=T_LEFT )
976 Expecting( T_LEFT );
977
978 tok = NextTok();
979
980 switch( tok )
981 {
982 case T_rect:
983 if( growth->shape )
984 Unexpected( tok );
985
986 growth->shape = new RECTANGLE( growth );
987 doRECTANGLE( (RECTANGLE*) growth->shape );
988 break;
989
990 case T_circle:
991 if( growth->shape )
992 Unexpected( tok );
993
994 growth->shape = new CIRCLE( growth );
995 doCIRCLE( (CIRCLE*) growth->shape );
996 break;
997
998 case T_polyline_path:
999 tok = T_path;
1001
1002 case T_path:
1003 case T_polygon:
1004 if( growth->shape )
1005 Unexpected( tok );
1006
1007 growth->shape = new PATH( growth, tok );
1008 doPATH( (PATH*) growth->shape );
1009 break;
1010
1011 case T_qarc:
1012 if( growth->shape )
1013 Unexpected( tok );
1014
1015 growth->shape = new QARC( growth );
1016 doQARC( (QARC*) growth->shape );
1017 break;
1018
1019 default:
1020 Unexpected( CurText() );
1021 }
1022
1023 tok = NextTok();
1024 }
1025}
1026
1027
1029{
1030 T tok = NextTok();
1031
1032 if( tok != T_LEFT )
1033 Expecting( T_LEFT );
1034
1035 tok = NextTok();
1036
1037 if( tok == T_rect )
1038 {
1039 if( growth->paths.size() )
1040 Unexpected( "rect when path already encountered" );
1041
1042 growth->rectangle = new RECTANGLE( growth );
1043 doRECTANGLE( growth->rectangle );
1044 NeedRIGHT();
1045 }
1046 else if( tok == T_path )
1047 {
1048 if( growth->rectangle )
1049 Unexpected( "path when rect already encountered" );
1050
1051 for(;;)
1052 {
1053 if( tok != T_path )
1054 Expecting( T_path );
1055
1056 PATH* path = new PATH( growth, T_path );
1057 growth->paths.push_back( path );
1058
1059 doPATH( path );
1060
1061 tok = NextTok();
1062 if( tok == T_RIGHT )
1063 break;
1064
1065 if( tok != T_LEFT )
1066 Expecting(T_LEFT);
1067
1068 tok = NextTok();
1069 }
1070 }
1071 else
1072 {
1073 Expecting( "rect|path" );
1074 }
1075}
1076
1077
1079{
1080 T tok = NextTok();
1081
1082 if( !IsSymbol( tok ) && tok != T_NUMBER ) // a layer name can be like a number like +12
1083 Expecting( "layer_id" );
1084
1085 growth->layer_id = CurText();
1086
1087 if( NextTok() != T_NUMBER )
1088 Expecting( "aperture_width" );
1089
1090 growth->aperture_width = strtod( CurText(), nullptr );
1091
1092 POINT ptTemp;
1093
1094 tok = NextTok();
1095
1096 do
1097 {
1098 if( tok != T_NUMBER )
1099 Expecting( T_NUMBER );
1100
1101 ptTemp.x = strtod( CurText(), nullptr );
1102
1103 if( NextTok() != T_NUMBER )
1104 Expecting( T_NUMBER );
1105
1106 ptTemp.y = strtod( CurText(), nullptr );
1107
1108 growth->points.push_back( ptTemp );
1109
1110 } while( ( tok = NextTok() ) != T_RIGHT && tok != T_LEFT );
1111
1112 if( tok == T_LEFT )
1113 {
1114 if( NextTok() != T_aperture_type )
1115 Expecting( T_aperture_type );
1116
1117 tok = NextTok();
1118
1119 if( tok!=T_round && tok!=T_square )
1120 Expecting( "round|square" );
1121
1122 growth->aperture_type = tok;
1123
1124 NeedRIGHT();
1125 }
1126}
1127
1128
1130{
1131 NeedSYMBOL();
1132 growth->layer_id = CurText();
1133
1134 if( NextTok() != T_NUMBER )
1135 Expecting( T_NUMBER );
1136
1137 growth->point0.x = strtod( CurText(), nullptr );
1138
1139 if( NextTok() != T_NUMBER )
1140 Expecting( T_NUMBER );
1141
1142 growth->point0.y = strtod( CurText(), nullptr );
1143
1144 if( NextTok() != T_NUMBER )
1145 Expecting( T_NUMBER );
1146
1147 growth->point1.x = strtod( CurText(), nullptr );
1148
1149 if( NextTok() != T_NUMBER )
1150 Expecting( T_NUMBER );
1151
1152 growth->point1.y = strtod( CurText(), nullptr );
1153
1154 NeedRIGHT();
1155}
1156
1157
1159{
1160 T tok;
1161
1162 NeedSYMBOLorNUMBER();
1163 growth->layer_id = CurText();
1164
1165 if( NextTok() != T_NUMBER )
1166 Expecting( T_NUMBER );
1167
1168 growth->diameter = strtod( CurText(), 0 );
1169
1170 tok = NextTok();
1171
1172 if( tok == T_NUMBER )
1173 {
1174 growth->vertex.x = strtod( CurText(), 0 );
1175
1176 if( NextTok() != T_NUMBER )
1177 Expecting( T_NUMBER );
1178
1179 growth->vertex.y = strtod( CurText(), 0 );
1180
1181 tok = NextTok();
1182 }
1183
1184 if( tok != T_RIGHT )
1185 Expecting( T_RIGHT );
1186}
1187
1188
1190{
1191 NeedSYMBOL();
1192 growth->layer_id = CurText();
1193
1194 if( NextTok() != T_NUMBER )
1195 Expecting( T_NUMBER );
1196
1197 growth->aperture_width = strtod( CurText(), 0 );
1198
1199 for( int i = 0; i < 3; ++i )
1200 {
1201 if( NextTok() != T_NUMBER )
1202 Expecting( T_NUMBER );
1203
1204 growth->vertex[i].x = strtod( CurText(), 0 );
1205
1206 if( NextTok() != T_NUMBER )
1207 Expecting( T_NUMBER );
1208
1209 growth->vertex[i].y = strtod( CurText(), 0 );
1210 }
1211
1212 NeedRIGHT();
1213}
1214
1215
1217{
1218 NeedSYMBOL();
1219 growth->value = CurText();
1220 NeedRIGHT();
1221}
1222
1223
1225{
1226 T tok = NextTok();
1227
1228 if( tok<0 )
1229 Unexpected( CurText() );
1230
1231 growth->value = tok;
1232
1233 NeedRIGHT();
1234}
1235
1236
1238{
1239 T tok;
1240
1241 while( ( tok = NextTok() ) != T_RIGHT )
1242 {
1243 if( tok == T_LEFT )
1244 {
1245 if( NextTok() != T_spare )
1246 Expecting( T_spare );
1247
1248 while( (tok = NextTok()) != T_RIGHT )
1249 {
1250 if( !IsSymbol( tok ) )
1251 Expecting( T_SYMBOL );
1252
1253 growth->m_spares.push_back( CurText() );
1254 }
1255 }
1256 else if( IsSymbol( tok ) )
1257 {
1258 growth->m_padstacks.push_back( CurText() );
1259 }
1260 else
1261 {
1262 Unexpected( CurText() );
1263 }
1264 }
1265}
1266
1267
1269{
1270 T tok;
1271
1272 while( (tok = NextTok()) != T_RIGHT )
1273 {
1274 if( tok != T_LEFT )
1275 Expecting( T_LEFT );
1276
1277 tok = NextTok();
1278
1279 switch( tok )
1280 {
1281 case T_via_at_smd:
1282 tok = NextTok();
1283
1284 if( tok!=T_on && tok!=T_off )
1285 Expecting( "on|off" );
1286
1287 growth->via_at_smd = (tok==T_on);
1288 NeedRIGHT();
1289 break;
1290
1291 case T_off_grid:
1292 case T_route_to_fanout_only:
1293 case T_force_to_terminal_point:
1294 case T_same_net_checking:
1295 case T_checking_trim_by_pin:
1296 case T_noise_calculation:
1297 case T_noise_accumulation:
1298 case T_include_pins_in_crosstalk:
1299 case T_bbv_ctr2ctr:
1300 case T_average_pair_length:
1301 case T_crosstalk_model:
1302 case T_roundoff_rotation:
1303 case T_microvia:
1304 case T_reroute_order_viols:
1305 TOKPROP* tokprop;
1306 tokprop = new TOKPROP( growth, tok );
1307 growth->Append( tokprop );
1308 doTOKPROP( tokprop );
1309 break;
1310
1311 default:
1312 Unexpected( CurText() );
1313 }
1314 }
1315}
1316
1317
1319{
1320 T tok;
1321 PROPERTY property; // construct it once here, append multiple times.
1322
1323 while( ( tok = NextTok() ) != T_RIGHT )
1324 {
1325 if( tok != T_LEFT )
1326 Expecting( T_LEFT );
1327
1328 NeedSYMBOLorNUMBER();
1329 property.name = CurText();
1330
1331 NeedSYMBOLorNUMBER();
1332 property.value = CurText();
1333
1334 growth->push_back( property );
1335
1336 NeedRIGHT();
1337 }
1338}
1339
1340
1342{
1343 T tok = NextTok();
1344
1345 if( !IsSymbol( tok ) )
1346 Expecting( T_SYMBOL );
1347
1348 growth->name = CurText();
1349
1350 while( ( tok = NextTok() ) != T_RIGHT )
1351 {
1352 if( tok != T_LEFT )
1353 Expecting( T_LEFT );
1354
1355 tok = NextTok();
1356
1357 switch( tok )
1358 {
1359 case T_type:
1360 tok = NextTok();
1361
1362 if( tok != T_signal && tok != T_power && tok != T_mixed && tok != T_jumper )
1363 Expecting( "signal|power|mixed|jumper" );
1364
1365 growth->layer_type = tok;
1366
1367 if( NextTok()!=T_RIGHT )
1368 Expecting(T_RIGHT);
1369
1370 break;
1371
1372 case T_rule:
1373 growth->rules = new RULE( growth, T_rule );
1374 doRULE( growth->rules );
1375 break;
1376
1377 case T_property:
1378 doPROPERTIES( &growth->properties );
1379 break;
1380
1381 case T_direction:
1382 tok = NextTok();
1383
1384 switch( tok )
1385 {
1386 case T_horizontal:
1387 case T_vertical:
1388 case T_orthogonal:
1389 case T_positive_diagonal:
1390 case T_negative_diagonal:
1391 case T_diagonal:
1392 case T_off:
1393 growth->direction = tok;
1394 break;
1395 default:
1396 // the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
1397 if( !strcmp( "hori", CurText() ) )
1398 {
1399 growth->direction = T_horizontal;
1400 break;
1401 }
1402 else if( !strcmp( "vert", CurText() ) )
1403 {
1404 growth->direction = T_vertical;
1405 break;
1406 }
1407
1408 Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|"
1409 "diagonal|off" );
1410 }
1411
1412 if( NextTok() != T_RIGHT )
1413 Expecting( T_RIGHT );
1414
1415 break;
1416
1417 case T_cost:
1418 tok = NextTok();
1419
1420 switch( tok )
1421 {
1422 case T_forbidden:
1423 case T_high:
1424 case T_medium:
1425 case T_low:
1426 case T_free:
1427 growth->cost = tok;
1428 break;
1429 case T_NUMBER:
1430 // store as negative so we can differentiate between
1431 // T (positive) and T_NUMBER (negative)
1432 growth->cost = -atoi( CurText() );
1433 break;
1434 default:
1435 Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
1436 }
1437
1438 tok = NextTok();
1439
1440 if( tok == T_LEFT )
1441 {
1442 if( NextTok() != T_type )
1443 Unexpected( CurText() );
1444
1445 tok = NextTok();
1446
1447 if( tok!=T_length && tok!=T_way )
1448 Expecting( "length|way" );
1449
1450 growth->cost_type = tok;
1451
1452 if( NextTok()!=T_RIGHT )
1453 Expecting( T_RIGHT );
1454
1455 tok = NextTok();
1456 }
1457
1458 if( tok != T_RIGHT )
1459 Expecting( T_RIGHT );
1460
1461 break;
1462
1463 case T_use_net:
1464 while( ( tok = NextTok() ) != T_RIGHT )
1465 {
1466 if( !IsSymbol( tok ) )
1467 Expecting( T_SYMBOL );
1468
1469 growth->use_net.push_back( CurText() );
1470 }
1471
1472 break;
1473
1474 default:
1475 Unexpected( CurText() );
1476 }
1477 }
1478}
1479
1480
1482{
1483 std::string builder;
1484 int bracketNesting = 1; // we already saw the opening T_LEFT
1485 T tok = T_NONE;
1486
1487 while( bracketNesting != 0 && tok != T_EOF )
1488 {
1489 tok = NextTok();
1490
1491 if( tok==T_LEFT)
1492 ++bracketNesting;
1493 else if( tok==T_RIGHT )
1494 --bracketNesting;
1495
1496 if( bracketNesting >= 1 )
1497 {
1498 if( PrevTok() != T_LEFT && tok != T_RIGHT && ( tok != T_LEFT || bracketNesting > 2 ) )
1499 builder += ' ';
1500
1501 if( tok == T_STRING )
1502 builder += m_quote_char;
1503
1504 builder += CurText();
1505
1506 if( tok == T_STRING )
1507 builder += m_quote_char;
1508 }
1509
1510 // When the nested rule is closed with a T_RIGHT and we are back down
1511 // to bracketNesting == 1, (inside the <rule_descriptor> but outside
1512 // the last rule). Then save the last rule and clear the string builder.
1513 if( bracketNesting == 1 )
1514 {
1515 growth->m_rules.push_back( builder );
1516 builder.clear();
1517 }
1518 }
1519
1520 if( tok==T_EOF )
1521 Unexpected( T_EOF );
1522}
1523
1524
1525#if 0
1526void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type )
1527{
1528 /* (place_rule [<structure_place_rule_object> ]
1529 {[<spacing_descriptor> |
1530 <permit_orient_descriptor> |
1531 <permit_side_descriptor> |
1532 <opposite_side_descriptor> ]}
1533 )
1534 */
1535
1536 T tok = NextTok();
1537
1538 if( tok != T_LEFT )
1539 Expecting( T_LEFT );
1540
1541 tok = NextTok();
1542
1543 if( tok == T_object_type )
1544 {
1545 if( !expect_object_type )
1546 Unexpected( tok );
1547
1548 /* [(object_type
1549 [pcb |
1550 image_set [large | small | discrete | capacitor | resistor]
1551 [(image_type [smd | pin])]]
1552 )]
1553 */
1554
1555 tok = NextTok();
1556
1557 switch( tok )
1558 {
1559 case T_pcb:
1560 growth->object_type = tok;
1561 break;
1562
1563 case T_image_set:
1564 tok = NextTok();
1565
1566 switch( tok )
1567 {
1568 case T_large:
1569 case T_small:
1570 case T_discrete:
1571 case T_capacitor:
1572 case T_resistor:
1573 growth->object_type = tok;
1574 break;
1575 default:
1576 Unexpected( CurText() );
1577 }
1578
1579 break;
1580
1581 default:
1582 Unexpected( CurText() );
1583 }
1584
1585 tok = NextTok();
1586
1587 if( tok == T_LEFT )
1588 {
1589 tok = NextTok();
1590
1591 if( tok != T_image_type )
1592 Expecting( T_image_type );
1593
1594 tok = NextTok();
1595
1596 if( tok!=T_smd && tok!=T_pin )
1597 Expecting( "smd|pin" );
1598
1599 NeedRIGHT();
1600
1601 tok = NextTok();
1602 }
1603
1604 if( tok != T_RIGHT )
1605 Expecting( T_RIGHT );
1606
1607 tok = NextTok();
1608 }
1609
1610 /* {[<spacing_descriptor> |
1611 <permit_orient_descriptor> |
1612 <permit_side_descriptor> | <opposite_side_descriptor> ]}
1613 */
1614 doRULE( growth );
1615}
1616#endif
1617
1618
1620{
1621 T tok = NextTok();
1622
1623 if( IsSymbol( tok ) )
1624 {
1625 growth->m_region_id = CurText();
1626 tok = NextTok();
1627 }
1628
1629 for(;;)
1630 {
1631 if( tok != T_LEFT )
1632 Expecting( T_LEFT );
1633
1634 tok = NextTok();
1635
1636 switch( tok )
1637 {
1638 case T_rect:
1639 if( growth->m_rectangle )
1640 Unexpected( tok );
1641
1642 growth->m_rectangle = new RECTANGLE( growth );
1643 doRECTANGLE( growth->m_rectangle );
1644 break;
1645
1646 case T_polygon:
1647 if( growth->m_polygon )
1648 Unexpected( tok );
1649
1650 growth->m_polygon = new PATH( growth, T_polygon );
1651 doPATH( growth->m_polygon );
1652 break;
1653
1654 case T_region_net:
1655 case T_region_class:
1656 STRINGPROP* stringprop;
1657 stringprop = new STRINGPROP( growth, tok );
1658 growth->Append( stringprop );
1659 doSTRINGPROP( stringprop );
1660 break;
1661
1662 case T_region_class_class:
1663 CLASS_CLASS* class_class;
1664 class_class = new CLASS_CLASS( growth, tok );
1665 growth->Append( class_class );
1666 doCLASS_CLASS( class_class );
1667 break;
1668
1669 case T_rule:
1670 if( growth->m_rules )
1671 Unexpected( tok );
1672
1673 growth->m_rules = new RULE( growth, T_rule );
1674 doRULE( growth->m_rules );
1675 break;
1676
1677 default:
1678 Unexpected( CurText() );
1679 }
1680
1681 tok = NextTok();
1682
1683 if( tok == T_RIGHT )
1684 {
1685 if( !growth->m_rules )
1686 Expecting( T_rule );
1687
1688 break;
1689 }
1690 }
1691}
1692
1693
1695{
1696 T tok = NextTok();
1697
1698 if( tok != T_LEFT )
1699 Expecting( T_LEFT );
1700
1701 while( ( tok = NextTok() ) != T_RIGHT )
1702 {
1703 switch( tok )
1704 {
1705 case T_classes:
1706 if( growth->classes )
1707 Unexpected( tok );
1708
1709 growth->classes = new CLASSES( growth );
1710 doCLASSES( growth->classes );
1711 break;
1712
1713 case T_rule:
1714 // only T_class_class takes a T_rule
1715 if( growth->Type() == T_region_class_class )
1716 Unexpected( tok );
1717
1718 RULE* rule;
1719 rule = new RULE( growth, T_rule );
1720 growth->Append( rule );
1721 doRULE( rule );
1722 break;
1723
1724 case T_layer_rule:
1725 // only T_class_class takes a T_layer_rule
1726 if( growth->Type() == T_region_class_class )
1727 Unexpected( tok );
1728
1729 LAYER_RULE* layer_rule;
1730 layer_rule = new LAYER_RULE( growth );
1731 growth->Append( layer_rule );
1732 doLAYER_RULE( layer_rule );
1733 break;
1734
1735 default:
1736 Unexpected( tok );
1737 }
1738 }
1739}
1740
1741
1743{
1744 T tok = NextTok();
1745
1746 // require at least 2 class_ids
1747
1748 if( !IsSymbol( tok ) )
1749 Expecting( "class_id" );
1750
1751 growth->class_ids.push_back( CurText() );
1752
1753 do
1754 {
1755 tok = NextTok();
1756
1757 if( !IsSymbol( tok ) )
1758 Expecting( "class_id" );
1759
1760 growth->class_ids.push_back( CurText() );
1761
1762 } while( ( tok = NextTok() ) != T_RIGHT );
1763}
1764
1765
1767{
1768 T tok = NextTok();
1769
1770 switch( tok )
1771 {
1772 case T_via:
1773 case T_wire:
1774 case T_via_keepout:
1775 case T_snap:
1776 case T_place:
1777 growth->m_grid_type = tok;
1778
1779 if( NextTok() != T_NUMBER )
1780 Expecting( T_NUMBER );
1781
1782 growth->m_dimension = strtod( CurText(), 0 );
1783 tok = NextTok();
1784
1785 if( tok == T_LEFT )
1786 {
1787 while( ( tok = NextTok() ) != T_RIGHT )
1788 {
1789 if( tok == T_direction )
1790 {
1791 if( growth->m_grid_type == T_place )
1792 Unexpected( tok );
1793
1794 tok = NextTok();
1795
1796 if( tok != T_x && tok != T_y )
1797 Unexpected( CurText() );
1798
1799 growth->m_direction = tok;
1800
1801 if( NextTok() != T_RIGHT )
1802 Expecting(T_RIGHT);
1803 }
1804 else if( tok == T_offset )
1805 {
1806 if( growth->m_grid_type == T_place )
1807 Unexpected( tok );
1808
1809 if( NextTok() != T_NUMBER )
1810 Expecting( T_NUMBER );
1811
1812 growth->m_offset = strtod( CurText(), 0 );
1813
1814 if( NextTok() != T_RIGHT )
1815 Expecting( T_RIGHT );
1816 }
1817 else if( tok == T_image_type )
1818 {
1819 if( growth->m_grid_type != T_place )
1820 Unexpected( tok );
1821
1822 tok = NextTok();
1823
1824 if( tok != T_smd && tok != T_pin )
1825 Unexpected( CurText() );
1826
1827 growth->m_image_type = tok;
1828
1829 if( NextTok() != T_RIGHT )
1830 Expecting( T_RIGHT );
1831 }
1832 }
1833 }
1834
1835 break;
1836
1837 default:
1838 Unexpected( tok );
1839 }
1840}
1841
1842
1844{
1845 T tok;
1846
1847 NeedSYMBOL();
1848
1849 do
1850 {
1851 growth->m_layer_ids.push_back( CurText() );
1852
1853 } while( IsSymbol( tok = NextTok() ) );
1854
1855 if( tok != T_LEFT )
1856 Expecting( T_LEFT );
1857
1858 if( NextTok() != T_rule )
1859 Expecting( T_rule );
1860
1861 growth->m_rule = new RULE( growth, T_rule );
1862 doRULE( growth->m_rule );
1863
1864 NeedRIGHT();
1865}
1866
1867
1869{
1870 T tok = NextTok();
1871
1872 if( !IsSymbol( tok ) )
1873 Expecting( "component_id" );
1874
1875 growth->m_component_id = CurText();
1876
1877 tok = NextTok();
1878
1879 if( tok == T_NUMBER )
1880 {
1881 POINT point;
1882
1883 point.x = strtod( CurText(), 0 );
1884
1885 if( NextTok() != T_NUMBER )
1886 Expecting( T_NUMBER );
1887
1888 point.y = strtod( CurText(), 0 );
1889
1890 growth->SetVertex( point );
1891
1892 tok = NextTok();
1893
1894 if( tok != T_front && tok != T_back )
1895 Expecting( "front|back" );
1896
1897 growth->m_side = tok;
1898
1899 if( NextTok() != T_NUMBER )
1900 Expecting( "rotation" );
1901
1902 growth->SetRotation( strtod( CurText(), 0 ) );
1903 }
1904
1905 while( ( tok = NextTok() ) != T_RIGHT )
1906 {
1907 if( tok != T_LEFT )
1908 Expecting( T_LEFT );
1909
1910 tok = NextTok();
1911
1912 switch( tok )
1913 {
1914 case T_mirror:
1915 tok = NextTok();
1916
1917 if( tok == T_x || tok == T_y || tok == T_xy || tok == T_off )
1918 growth->m_mirror = tok;
1919 else
1920 Expecting( "x|y|xy|off" );
1921
1922 break;
1923
1924 case T_status:
1925 tok = NextTok();
1926
1927 if( tok==T_added || tok==T_deleted || tok==T_substituted )
1928 growth->m_status = tok;
1929 else
1930 Expecting("added|deleted|substituted");
1931
1932 break;
1933
1934 case T_logical_part:
1935 if( growth->m_logical_part.size() )
1936 Unexpected( tok );
1937
1938 tok = NextTok();
1939
1940 if( !IsSymbol( tok ) )
1941 Expecting( "logical_part_id");
1942
1943 growth->m_logical_part = CurText();
1944 break;
1945
1946 case T_place_rule:
1947 if( growth->m_place_rules )
1948 Unexpected( tok );
1949
1950 growth->m_place_rules = new RULE( growth, T_place_rule );
1951 doRULE( growth->m_place_rules );
1952 break;
1953
1954 case T_property:
1955 if( growth->m_properties.size() )
1956 Unexpected( tok );
1957
1958 doPROPERTIES( &growth->m_properties );
1959 break;
1960
1961 case T_lock_type:
1962 tok = NextTok();
1963
1964 if( tok == T_position || tok == T_gate || tok == T_subgate || tok == T_pin )
1965 growth->m_lock_type = tok;
1966 else
1967 Expecting( "position|gate|subgate|pin" );
1968
1969 break;
1970
1971 case T_rule:
1972 if( growth->m_rules || growth->m_region )
1973 Unexpected( tok );
1974
1975 growth->m_rules = new RULE( growth, T_rule );
1976 doRULE( growth->m_rules );
1977 break;
1978
1979 case T_region:
1980 if( growth->m_rules || growth->m_region )
1981 Unexpected( tok );
1982
1983 growth->m_region = new REGION( growth );
1984 doREGION( growth->m_region );
1985 break;
1986
1987 case T_pn:
1988 if( growth->m_part_number.size() )
1989 Unexpected( tok );
1990
1991 NeedSYMBOLorNUMBER();
1992 growth->m_part_number = CurText();
1993 NeedRIGHT();
1994 break;
1995
1996 default:
1997 Unexpected( tok );
1998 }
1999 }
2000}
2001
2002
2004{
2005 T tok = NextTok();
2006
2007 if( !IsSymbol( tok ) && tok != T_NUMBER )
2008 Expecting( "image_id" );
2009
2010 growth->m_image_id = CurText();
2011
2012 while( ( tok = NextTok() ) != T_RIGHT )
2013 {
2014 if( tok != T_LEFT )
2015 Expecting( T_LEFT );
2016
2017 tok = NextTok();
2018
2019 switch( tok )
2020 {
2021 case T_place:
2022 PLACE* place;
2023 place = new PLACE( growth );
2024 growth->m_places.push_back( place );
2025 doPLACE( place );
2026 break;
2027
2028 default:
2029 Unexpected( tok );
2030 }
2031 }
2032}
2033
2034
2036{
2037 T tok;
2038
2039 while( ( tok = NextTok() ) != T_RIGHT )
2040 {
2041 if( tok == T_EOF )
2042 Unexpected( T_EOF );
2043
2044 if( tok != T_LEFT )
2045 Expecting( T_LEFT );
2046
2047 tok = NextTok();
2048
2049 switch( tok )
2050 {
2051 case T_unit:
2052 case T_resolution:
2053 growth->m_unit = new UNIT_RES( growth, tok );
2054
2055 if( tok == T_resolution )
2056 doRESOLUTION( growth->m_unit );
2057 else
2058 doUNIT( growth->m_unit );
2059 break;
2060
2061 case T_place_control:
2062 NeedRIGHT();
2063 tok = NextTok();
2064
2065 if( tok != T_flip_style )
2066 Expecting( T_flip_style );
2067
2068 tok = NextTok();
2069
2070 if( tok == T_mirror_first || tok == T_rotate_first )
2071 growth->m_flip_style = tok;
2072 else
2073 Expecting( "mirror_first|rotate_first" );
2074
2075 NeedRIGHT();
2076 NeedRIGHT();
2077 break;
2078
2079 case T_component:
2080 COMPONENT* component;
2081 component = new COMPONENT( growth );
2082 growth->m_components.push_back( component );
2083 doCOMPONENT( component );
2084 break;
2085
2086 default:
2087 Unexpected( tok );
2088 }
2089 }
2090}
2091
2092
2094{
2095 T tok = NextTok();
2096
2097 /* (padstack <m_padstack_id >
2098 [<unit_descriptor> ]
2099 {(shape <shape_descriptor>
2100 [<reduced_shape_descriptor> ]
2101 [(connect [on | off])]
2102 [{<window_descriptor> }]
2103 )}
2104 [<attach_descriptor> ]
2105 [{<pad_via_site_descriptor> }]
2106 [(rotate [on | off])]
2107 [(absolute [on | off])]
2108 [(rule <clearance_descriptor> )])
2109 */
2110
2111 // m_padstack_id may be a number
2112 if( !IsSymbol( tok ) && tok != T_NUMBER )
2113 Expecting( "m_padstack_id" );
2114
2115 growth->m_padstack_id = CurText();
2116
2117 while( ( tok = NextTok() ) != T_RIGHT )
2118 {
2119 if( tok != T_LEFT )
2120 Expecting( T_LEFT );
2121
2122 tok = NextTok();
2123
2124 switch( tok )
2125 {
2126 case T_unit:
2127 if( growth->m_unit )
2128 Unexpected( tok );
2129
2130 growth->m_unit = new UNIT_RES( growth, tok );
2131 doUNIT( growth->m_unit );
2132 break;
2133
2134 case T_rotate:
2135 tok = NextTok();
2136
2137 if( tok != T_on && tok != T_off )
2138 Expecting( "on|off" );
2139
2140 growth->m_rotate = tok;
2141 NeedRIGHT();
2142 break;
2143
2144 case T_absolute:
2145 tok = NextTok();
2146
2147 if( tok != T_on && tok != T_off )
2148 Expecting( "on|off" );
2149
2150 growth->m_absolute = tok;
2151 NeedRIGHT();
2152 break;
2153
2154 case T_shape:
2155 SHAPE* shape;
2156 shape = new SHAPE( growth );
2157 growth->Append( shape );
2158 doSHAPE( shape );
2159 break;
2160
2161 case T_attach:
2162 tok = NextTok();
2163
2164 if( tok != T_off && tok != T_on )
2165 Expecting( "off|on" );
2166
2167 growth->m_attach = tok;
2168 tok = NextTok();
2169
2170 if( tok == T_LEFT )
2171 {
2172 if( NextTok() != T_use_via )
2173 Expecting( T_use_via );
2174
2175 NeedSYMBOL();
2176 growth->m_via_id = CurText();
2177
2178 NeedRIGHT();
2179 NeedRIGHT();
2180 }
2181
2182 break;
2183
2184 /*
2185 case T_via_site: not supported
2186 break;
2187 */
2188
2189 case T_rule:
2190
2191 if( growth->m_rules )
2192 Unexpected( tok );
2193
2194 growth->m_rules = new RULE( growth, T_rule );
2195 doRULE( growth->m_rules );
2196 break;
2197
2198 default:
2199 Unexpected( CurText() );
2200 }
2201 }
2202}
2203
2204
2206{
2207 T tok;
2208
2209 /* (shape <shape_descriptor>
2210 [<reduced_shape_descriptor> ]
2211 [(connect [on | off])]
2212 [{<window_descriptor> }])
2213 */
2214
2215 while( ( tok = NextTok() ) != T_RIGHT )
2216 {
2217 if( tok != T_LEFT )
2218 Expecting( T_LEFT );
2219
2220 tok = NextTok();
2221
2222 switch( tok )
2223 {
2224 case T_polyline_path:
2225 tok = T_path;
2227
2228 case T_rect:
2229 case T_circle:
2230 case T_path:
2231 case T_polygon:
2232 case T_qarc:
2233L_done_that:
2234 if( growth->shape )
2235 Unexpected( tok );
2236
2237 break;
2238
2239 default:
2240 // the example in the spec uses "circ" instead of "circle". Bad!
2241 if( !strcmp( "circ", CurText() ) )
2242 {
2243 tok = T_circle;
2244 goto L_done_that;
2245 }
2246 }
2247
2248 switch( tok )
2249 {
2250 case T_rect:
2251 growth->shape = new RECTANGLE( growth );
2252 doRECTANGLE( (RECTANGLE*) growth->shape );
2253 break;
2254
2255 case T_circle:
2256 growth->shape = new CIRCLE( growth );
2257 doCIRCLE( (CIRCLE*)growth->shape );
2258 break;
2259
2260 case T_path:
2261 case T_polygon:
2262 growth->shape = new PATH( growth, tok );
2263 doPATH( (PATH*)growth->shape );
2264 break;
2265
2266 case T_qarc:
2267 growth->shape = new QARC( growth );
2268 doQARC( (QARC*)growth->shape );
2269 break;
2270
2271 case T_connect:
2272 tok = NextTok();
2273 if( tok!=T_on && tok!=T_off )
2274 Expecting( "on|off" );
2275 growth->m_connect = tok;
2276 NeedRIGHT();
2277 break;
2278
2279 case T_window:
2280 WINDOW* window;
2281 window = new WINDOW( growth );
2282 growth->m_windows.push_back( window );
2283 doWINDOW( window );
2284 break;
2285
2286 default:
2287 Unexpected( CurText() );
2288 }
2289 }
2290}
2291
2292
2294{
2295 T tok = NextTok();
2296
2297 /* <image_descriptor >::=
2298 (image <image_id >
2299 [(side [front | back | both])]
2300 [<unit_descriptor> ]
2301 [<outline_descriptor> ]
2302 {(pin <m_padstack_id > [(rotate <rotation> )]
2303 [<reference_descriptor> | <pin_array_descriptor> ]
2304 [<user_property_descriptor> ])}
2305 [{<conductor_shape_descriptor> }]
2306 [{<conductor_via_descriptor> }]
2307 [<rule_descriptor> ]
2308 [<place_rule_descriptor> ]
2309 [{<keepout_descriptor> }]
2310 [<image_property_descriptor> ]
2311 )
2312 */
2313
2314 if( !IsSymbol( tok ) && tok != T_NUMBER )
2315 Expecting( "image_id" );
2316
2317 growth->m_image_id = CurText();
2318
2319 while( ( tok = NextTok() ) != T_RIGHT )
2320 {
2321 if( tok != T_LEFT )
2322 Expecting( T_LEFT );
2323
2324 tok = NextTok();
2325
2326 switch( tok )
2327 {
2328 case T_unit:
2329 if( growth->m_unit )
2330 Unexpected( tok );
2331
2332 growth->m_unit = new UNIT_RES( growth, tok );
2333 doUNIT( growth->m_unit );
2334 break;
2335
2336 case T_side:
2337 tok = NextTok();
2338
2339 if( tok != T_front && tok != T_back && tok != T_both )
2340 Expecting( "front|back|both" );
2341
2342 growth->m_side = tok;
2343 NeedRIGHT();
2344 break;
2345
2346 case T_outline:
2347 SHAPE* outline;
2348 outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
2349 growth->Append( outline );
2350 doSHAPE( outline );
2351 break;
2352
2353 case T_pin:
2354 PIN* pin;
2355 pin = new PIN( growth );
2356 growth->m_pins.push_back( pin );
2357 doPIN( pin );
2358 break;
2359
2360 case T_rule:
2361 if( growth->m_rules )
2362 Unexpected( tok );
2363
2364 growth->m_rules = new RULE( growth, tok );
2365 doRULE( growth->m_rules );
2366 break;
2367
2368 case T_place_rule:
2369 if( growth->m_place_rules )
2370 Unexpected( tok );
2371
2372 growth->m_place_rules = new RULE( growth, tok );
2373 doRULE( growth->m_place_rules );
2374 break;
2375
2376 case T_keepout:
2377 case T_place_keepout:
2378 case T_via_keepout:
2379 case T_wire_keepout:
2380 case T_bend_keepout:
2381 case T_elongate_keepout:
2382 KEEPOUT* keepout;
2383 keepout = new KEEPOUT( growth, tok );
2384 growth->m_keepouts.push_back( keepout );
2385 doKEEPOUT( keepout );
2386 break;
2387
2388 default:
2389 Unexpected( CurText() );
2390 }
2391 }
2392}
2393
2394
2396{
2397 T tok = NextTok();
2398
2399 /* (pin <m_padstack_id > [(rotate <rotation> )]
2400 [<reference_descriptor> | <pin_array_descriptor> ]
2401 [<user_property_descriptor> ])
2402 */
2403
2404 // a m_padstack_id may be a number
2405 if( !IsSymbol( tok ) && tok!=T_NUMBER )
2406 Expecting( "m_padstack_id" );
2407
2408 growth->m_padstack_id = CurText();
2409
2410 while( ( tok = NextTok() ) != T_RIGHT )
2411 {
2412 if( tok == T_LEFT )
2413 {
2414 tok = NextTok();
2415
2416 if( tok != T_rotate )
2417 Expecting( T_rotate );
2418
2419 if( NextTok() != T_NUMBER )
2420 Expecting( T_NUMBER );
2421
2422 growth->SetRotation( strtod( CurText(), 0 ) );
2423 NeedRIGHT();
2424 }
2425 else
2426 {
2427 if( !IsSymbol( tok ) && tok != T_NUMBER )
2428 Expecting( "pin_id" );
2429
2430 growth->m_pin_id = CurText();
2431
2432 if( NextTok() != T_NUMBER )
2433 Expecting( T_NUMBER );
2434
2435 growth->m_vertex.x = strtod( CurText(), 0 );
2436
2437 if( NextTok() != T_NUMBER )
2438 Expecting( T_NUMBER );
2439
2440 growth->m_vertex.y = strtod( CurText(), 0 );
2441 }
2442 }
2443}
2444
2445
2447{
2448 T tok;
2449
2450 /* <library_descriptor >::=
2451 (library
2452 [<unit_descriptor> ]
2453 {<image_descriptor> }
2454 [{<jumper_descriptor> }]
2455 {<padstack_descriptor> }
2456 {<via_array_template_descriptor> }
2457 [<directory_descriptor> ]
2458 [<extra_image_directory_descriptor> ]
2459 [{<family_family_descriptor> }]
2460 [{<image_image_descriptor> }]
2461 )
2462 */
2463
2464 while( ( tok = NextTok() ) != T_RIGHT )
2465 {
2466 if( tok != T_LEFT )
2467 Expecting( T_LEFT );
2468
2469 tok = NextTok();
2470
2471 switch( tok )
2472 {
2473 case T_unit:
2474 if( growth->m_unit )
2475 Unexpected( tok );
2476
2477 growth->m_unit = new UNIT_RES( growth, tok );
2478 doUNIT( growth->m_unit );
2479 break;
2480
2481 case T_padstack:
2482 PADSTACK* padstack;
2483 padstack = new PADSTACK();
2484 growth->AddPadstack( padstack );
2485 doPADSTACK( padstack );
2486 break;
2487
2488 case T_image:
2489 IMAGE* image;
2490 image = new IMAGE( growth );
2491 growth->m_images.push_back( image );
2492 doIMAGE( image );
2493 break;
2494
2495 default:
2496 Unexpected( CurText() );
2497 }
2498 }
2499}
2500
2501
2503{
2504 T tok = NextTok();
2505 PIN_REFS* pin_refs;
2506
2507 /* <net_descriptor >::=
2508 (net <net_id >
2509 [(unassigned)]
2510 [(net_number <integer >)]
2511 [(pins {<pin_reference> }) | (order {<pin_reference> })]
2512 [<component_order_descriptor> ]
2513 [(type [fix | normal])]
2514 [<user_property_descriptor> ]
2515 [<circuit_descriptor> ]
2516 [<rule_descriptor> ]
2517 [{<layer_rule_descriptor> }]
2518 [<fromto_descriptor> ]
2519 [(expose {<pin_reference> })]
2520 [(noexpose {<pin_reference> })]
2521 [(source {<pin_reference> })]
2522 [(load {<pin_reference> })]
2523 [(terminator {<pin_reference> })]
2524 [(supply [power | ground])]
2525 )
2526 */
2527
2528 if( !IsSymbol( tok ) )
2529 Expecting( "net_id" );
2530
2531 growth->m_net_id = CurText();
2532
2533 while( ( tok = NextTok() ) != T_RIGHT )
2534 {
2535 if( tok != T_LEFT )
2536 Expecting( T_LEFT );
2537
2538 tok = NextTok();
2539
2540 switch( tok )
2541 {
2542 case T_unassigned:
2543 growth->m_unassigned = true;
2544 NeedRIGHT();
2545 break;
2546
2547 case T_net_number:
2548 if( NextTok() != T_NUMBER )
2549 Expecting( T_NUMBER );
2550
2551 growth->m_net_number = atoi( CurText() );
2552 NeedRIGHT();
2553 break;
2554
2555 case T_pins:
2556 case T_order:
2557 growth->m_pins_type = tok;
2558 pin_refs = &growth->m_pins;
2559 goto L_pins;
2560
2561 case T_expose:
2562 pin_refs = &growth->m_expose;
2563 goto L_pins;
2564
2565 case T_noexpose:
2566 pin_refs = &growth->m_noexpose;
2567 goto L_pins;
2568
2569 case T_source:
2570 pin_refs = &growth->m_source;
2571 goto L_pins;
2572
2573 case T_load:
2574 pin_refs = &growth->m_load;
2575 goto L_pins;
2576
2577 case T_terminator:
2578 pin_refs = &growth->m_terminator;
2579 //goto L_pins;
2580
2581L_pins:
2582 {
2583 PIN_REF empty( growth );
2584
2585 while( ( tok = NextTok() ) != T_RIGHT )
2586 {
2587 // copy the empty one, then fill its copy later thru pin_ref.
2588 pin_refs->push_back( empty );
2589
2590 PIN_REF* pin_ref = &pin_refs->back();
2591
2592 readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
2593 }
2594 }
2595
2596 break;
2597
2598 case T_comp_order:
2599 if( growth->m_comp_order )
2600 Unexpected( tok );
2601
2602 growth->m_comp_order = new COMP_ORDER( growth );
2603 doCOMP_ORDER( growth->m_comp_order );
2604 break;
2605
2606 case T_type:
2607 tok = NextTok();
2608
2609 if( tok!=T_fix && tok!=T_normal )
2610 Expecting( "fix|normal" );
2611
2612 growth->type = tok;
2613 NeedRIGHT();
2614 break;
2615
2616/* @todo
2617 case T_circuit:
2618 break;
2619*/
2620
2621 case T_rule:
2622 if( growth->m_rules )
2623 Unexpected( tok );
2624
2625 growth->m_rules = new RULE( growth, T_rule );
2626 doRULE( growth->m_rules );
2627 break;
2628
2629 case T_layer_rule:
2630 LAYER_RULE* layer_rule;
2631 layer_rule = new LAYER_RULE( growth );
2632 growth->m_layer_rules.push_back( layer_rule );
2633 doLAYER_RULE( layer_rule );
2634 break;
2635
2636 case T_fromto:
2637 FROMTO* fromto;
2638 fromto = new FROMTO( growth );
2639 growth->m_fromtos.push_back( fromto );
2640 doFROMTO( fromto );
2641 break;
2642
2643 default:
2644 Unexpected( CurText() );
2645 }
2646 }
2647}
2648
2649
2651{
2652 T tok;
2653
2654 /* <topology_descriptor >::=
2655 (topology {[<fromto_descriptor> |
2656 <component_order_descriptor> ]})
2657 */
2658
2659 while( ( tok = NextTok() ) != T_RIGHT )
2660 {
2661 if( tok != T_LEFT )
2662 Expecting( T_LEFT );
2663
2664 tok = NextTok();
2665
2666 switch( tok )
2667 {
2668 case T_fromto:
2669 FROMTO* fromto;
2670 fromto = new FROMTO( growth );
2671 growth->m_fromtos.push_back( fromto );
2672 doFROMTO( fromto );
2673 break;
2674
2675 case T_comp_order:
2676 COMP_ORDER* comp_order;
2677 comp_order = new COMP_ORDER( growth );
2678 growth->m_comp_orders.push_back( comp_order );
2679 doCOMP_ORDER( comp_order );
2680 break;
2681
2682 default:
2683 Unexpected( CurText() );
2684 }
2685 }
2686}
2687
2688
2690{
2691 T tok;
2692
2693 /* <class_descriptor >::=
2694 (class
2695 <class_id > {[{<net_id >} | {<composite_name_list> }]}
2696 [<circuit_descriptor> ]
2697 [<rule_descriptor> ]
2698 [{<layer_rule_descriptor> }]
2699 [<topology_descriptor> ]
2700 )
2701 */
2702
2703 NeedSYMBOL();
2704
2705 growth->m_class_id = CurText();
2706
2707 // do net_ids, do not support <composite_name_list>s at this time
2708 while( IsSymbol( tok = NextTok() ) )
2709 {
2710 growth->m_net_ids.push_back( CurText() );
2711 }
2712
2713
2714 while( tok != T_RIGHT )
2715 {
2716 if( tok != T_LEFT )
2717 Expecting( T_LEFT );
2718
2719 tok = NextTok();
2720
2721 switch( tok )
2722 {
2723 case T_rule:
2724 if( growth->m_rules )
2725 Unexpected( tok );
2726
2727 growth->m_rules = new RULE( growth, T_rule );
2728 doRULE( growth->m_rules );
2729 break;
2730
2731 case T_layer_rule:
2732 LAYER_RULE* layer_rule;
2733 layer_rule = new LAYER_RULE( growth );
2734 growth->m_layer_rules.push_back( layer_rule );
2735 doLAYER_RULE( layer_rule );
2736 break;
2737
2738 case T_topology:
2739 if( growth->m_topology )
2740 Unexpected( tok );
2741
2742 growth->m_topology = new TOPOLOGY( growth );
2743 doTOPOLOGY( growth->m_topology );
2744 break;
2745
2746 case T_circuit: // handle all the circuit_descriptor here as strings
2747 {
2748 std::string builder;
2749 int bracketNesting = 1; // we already saw the opening T_LEFT
2750 tok = T_NONE;
2751
2752 while( bracketNesting != 0 && tok != T_EOF )
2753 {
2754 tok = NextTok();
2755
2756 if( tok == T_LEFT )
2757 ++bracketNesting;
2758 else if( tok == T_RIGHT )
2759 --bracketNesting;
2760
2761 if( bracketNesting >= 1 )
2762 {
2763 T previousTok = (T) PrevTok();
2764
2765 if( previousTok != T_LEFT && previousTok != T_circuit && tok != T_RIGHT )
2766 builder += ' ';
2767
2768 if( tok == T_STRING )
2769 builder += m_quote_char;
2770
2771 builder += CurText();
2772
2773 if( tok == T_STRING )
2774 builder += m_quote_char;
2775 }
2776
2777 // When the nested rule is closed with a T_RIGHT and we are back down
2778 // to bracketNesting == 0, then save the builder and break;
2779 if( bracketNesting == 0 )
2780 {
2781 growth->m_circuit.push_back( builder );
2782 break;
2783 }
2784 }
2785
2786 if( tok == T_EOF )
2787 Unexpected( T_EOF );
2788
2789 break;
2790 } // scope bracket
2791
2792 default:
2793 Unexpected( CurText() );
2794 } // switch
2795
2796 tok = NextTok();
2797
2798 } // while
2799}
2800
2801
2803{
2804 T tok;
2805
2806 /* <network_descriptor >::=
2807 (network
2808 {<net_descriptor>}
2809 [{<class_descriptor> }]
2810 [{<class_class_descriptor> }]
2811 [{<group_descriptor> }]
2812 [{<group_set_descriptor> }]
2813 [{<pair_descriptor> }]
2814 [{<bundle_descriptor> }]
2815 )
2816 */
2817
2818 while( ( tok = NextTok() ) != T_RIGHT )
2819 {
2820 if( tok != T_LEFT )
2821 Expecting( T_LEFT );
2822
2823 tok = NextTok();
2824
2825 switch( tok )
2826 {
2827 case T_net:
2828 NET* net;
2829 net = new NET( growth );
2830 growth->m_nets.push_back( net );
2831 doNET( net );
2832 break;
2833
2834 case T_class:
2835 CLASS* myclass;
2836 myclass = new CLASS( growth );
2837 growth->m_classes.push_back( myclass );
2838 doCLASS( myclass );
2839 break;
2840
2841 default:
2842 Unexpected( CurText() );
2843 }
2844 }
2845}
2846
2847
2849{
2850 T tok;
2851
2852 /* <component_order_descriptor >::=
2853 (comp_order {<placement_id> })
2854 */
2855
2856 while( IsSymbol( tok = NextTok() ) )
2857 growth->m_placement_ids.push_back( CurText() );
2858
2859 if( tok != T_RIGHT )
2860 Expecting( T_RIGHT );
2861}
2862
2863
2865{
2866 T tok;
2867
2868 /* <fromto_descriptor >::=
2869 {(fromto
2870 [<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
2871 [<pin_reference> | <virtual_pin_descriptor> | <component_id >]
2872 [(type [fix | normal | soft])]
2873 [(net <net_id >)]
2874 [<rule_descriptor> ]
2875 [<circuit_descriptor> ]
2876 [{<layer_rule_descriptor> }]
2877 )}
2878 */
2879
2880
2881 // read the first two grammar items in as 2 single tokens, i.e. do not
2882 // split apart the <pin_reference>s into 3 separate tokens. Do this by
2883 // turning off the string delimiter in the lexer.
2884
2885 char old = SetStringDelimiter( 0 );
2886
2887 if( !IsSymbol(NextTok() ) )
2888 {
2889 SetStringDelimiter( old );
2890 Expecting( T_SYMBOL );
2891 }
2892
2893 growth->m_fromText = CurText();
2894
2895 if( !IsSymbol(NextTok() ) )
2896 {
2897 SetStringDelimiter( old );
2898 Expecting( T_SYMBOL );
2899 }
2900
2901 growth->m_toText = CurText();
2902
2903 SetStringDelimiter( old );
2904
2905 while( ( tok = NextTok() ) != T_RIGHT )
2906 {
2907 if( tok != T_LEFT )
2908 Expecting( T_LEFT );
2909
2910 tok = NextTok();
2911
2912 switch( tok )
2913 {
2914 case T_type:
2915 tok = NextTok();
2916
2917 if( tok != T_fix && tok != T_normal && tok != T_soft )
2918 Expecting( "fix|normal|soft" );
2919
2920 growth->m_fromto_type = tok;
2921 NeedRIGHT();
2922 break;
2923
2924 case T_rule:
2925 if( growth->m_rules )
2926 Unexpected( tok );
2927
2928 growth->m_rules = new RULE( growth, T_rule );
2929 doRULE( growth->m_rules );
2930 break;
2931
2932 case T_layer_rule:
2933 LAYER_RULE* layer_rule;
2934 layer_rule = new LAYER_RULE( growth );
2935 growth->m_layer_rules.push_back( layer_rule );
2936 doLAYER_RULE( layer_rule );
2937 break;
2938
2939 case T_net:
2940 if( growth->m_net_id.size() )
2941 Unexpected( tok );
2942
2943 NeedSYMBOL();
2944 growth->m_net_id = CurText();
2945 NeedRIGHT();
2946 break;
2947
2948 // circuit descriptor not supported at this time
2949
2950 default:
2951 Unexpected( CurText() );
2952 }
2953 }
2954}
2955
2956
2958{
2959 T tok;
2960
2961 /* <wire_shape_descriptor >::=
2962 (wire
2963 <shape_descriptor>
2964 [(net <net_id >)]
2965 [(turret <turret#> )]
2966 [(type [fix | route | normal | protect])]
2967 [(attr [test | fanout | bus | jumper])]
2968 [(shield <net_id >)]
2969 [{<window_descriptor> }]
2970 [(connect
2971 (terminal <object_type> [<pin_reference> ])
2972 (terminal <object_type> [<pin_reference> ])
2973 )]
2974 [(supply)]
2975 )
2976 */
2977
2978 while( ( tok = NextTok() ) != T_RIGHT )
2979 {
2980 if( tok != T_LEFT )
2981 Expecting( T_LEFT );
2982
2983 tok = NextTok();
2984
2985 switch( tok )
2986 {
2987 case T_rect:
2988 if( growth->m_shape )
2989 Unexpected( tok );
2990
2991 growth->m_shape = new RECTANGLE( growth );
2992 doRECTANGLE( (RECTANGLE*) growth->m_shape );
2993 break;
2994
2995 case T_circle:
2996 if( growth->m_shape )
2997 Unexpected( tok );
2998
2999 growth->m_shape = new CIRCLE( growth );
3000 doCIRCLE( (CIRCLE*) growth->m_shape );
3001 break;
3002
3003 case T_polyline_path:
3004 tok = T_path;
3006
3007 case T_path:
3008 case T_polygon:
3009 if( growth->m_shape )
3010 Unexpected( tok );
3011
3012 growth->m_shape = new PATH( growth, tok );
3013 doPATH( (PATH*) growth->m_shape );
3014 break;
3015
3016 case T_qarc:
3017 if( growth->m_shape )
3018 Unexpected( tok );
3019
3020 growth->m_shape = new QARC( growth );
3021 doQARC( (QARC*) growth->m_shape );
3022 break;
3023
3024 case T_net:
3025 NeedSYMBOLorNUMBER();
3026 growth->m_net_id = CurText();
3027 NeedRIGHT();
3028 break;
3029
3030 case T_turret:
3031 if( NextTok() != T_NUMBER )
3032 Expecting( T_NUMBER );
3033
3034 growth->m_turret = atoi( CurText() );
3035 NeedRIGHT();
3036 break;
3037
3038 case T_type:
3039 tok = NextTok();
3040
3041 if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3042 Expecting( "fix|route|normal|protect" );
3043
3044 growth->m_wire_type = tok;
3045 NeedRIGHT();
3046 break;
3047
3048 case T_attr:
3049 tok = NextTok();
3050
3051 if( tok != T_test && tok != T_fanout && tok != T_bus && tok != T_jumper )
3052 Expecting( "test|fanout|bus|jumper" );
3053
3054 growth->m_attr = tok;
3055 NeedRIGHT();
3056 break;
3057
3058 case T_shield:
3059 NeedSYMBOL();
3060 growth->m_shield = CurText();
3061 NeedRIGHT();
3062 break;
3063
3064 case T_window:
3065 WINDOW* window;
3066 window = new WINDOW( growth );
3067 growth->m_windows.push_back( window );
3068 doWINDOW( window );
3069 break;
3070
3071 case T_connect:
3072 if( growth->m_connect )
3073 Unexpected( tok );
3074
3075 growth->m_connect = new CONNECT( growth );
3076 doCONNECT( growth->m_connect );
3077 break;
3078
3079 case T_supply:
3080 growth->m_supply = true;
3081 NeedRIGHT();
3082 break;
3083
3084 default:
3085 Unexpected( CurText() );
3086 }
3087 }
3088}
3089
3090
3092{
3093 T tok;
3094 POINT point;
3095
3096 /* <wire_via_descriptor >::=
3097 (via
3098 <m_padstack_id > {<vertex> }
3099 [(net <net_id >)]
3100 [(via_number <via#> )]
3101 [(type [fix | route | normal | protect])]
3102 [(attr [test | fanout | jumper |
3103 virtual_pin <m_virtual_pin_name> ])]
3104 [(contact {<layer_id >})]
3105 [(supply)]
3106 )
3107 (virtual_pin
3108 <m_virtual_pin_name> <vertex> (net <net_id >)
3109 )
3110 */
3111
3112 NeedSYMBOL();
3113 growth->m_padstack_id = CurText();
3114
3115 while( ( tok = NextTok() ) == T_NUMBER )
3116 {
3117 point.x = strtod( CurText(), 0 );
3118
3119 if( NextTok() != T_NUMBER )
3120 Expecting( "vertex.y" );
3121
3122 point.y = strtod( CurText(), 0 );
3123
3124 growth->m_vertexes.push_back( point );
3125 }
3126
3127 while( tok != T_RIGHT )
3128 {
3129 if( tok != T_LEFT )
3130 Expecting( T_LEFT );
3131
3132 tok = NextTok();
3133
3134 switch( tok )
3135 {
3136 case T_net:
3137 NeedSYMBOL();
3138 growth->m_net_id = CurText();
3139 NeedRIGHT();
3140 break;
3141
3142 case T_via_number:
3143 if( NextTok() != T_NUMBER )
3144 Expecting( "<via#>" );
3145
3146 growth->m_via_number = atoi( CurText() );
3147 NeedRIGHT();
3148 break;
3149
3150 case T_type:
3151 tok = NextTok();
3152
3153 if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3154 Expecting( "fix|route|normal|protect" );
3155
3156 growth->m_via_type = tok;
3157 NeedRIGHT();
3158 break;
3159
3160 case T_attr:
3161 tok = NextTok();
3162
3163 if( tok != T_test && tok != T_fanout && tok != T_jumper && tok != T_virtual_pin )
3164 Expecting( "test|fanout|jumper|virtual_pin" );
3165
3166 growth->m_attr = tok;
3167
3168 if( tok == T_virtual_pin )
3169 {
3170 NeedSYMBOL();
3171 growth->m_virtual_pin_name = CurText();
3172 }
3173
3174 NeedRIGHT();
3175 break;
3176
3177 case T_contact:
3178 NeedSYMBOL();
3179 tok = T_SYMBOL;
3180
3181 while( IsSymbol( tok ) )
3182 {
3183 growth->m_contact_layers.push_back( CurText() );
3184 tok = NextTok();
3185 }
3186
3187 if( tok != T_RIGHT )
3188 Expecting( T_RIGHT );
3189
3190 break;
3191
3192 case T_supply:
3193 growth->m_supply = true;
3194 NeedRIGHT();
3195 break;
3196
3197 default:
3198 Unexpected( CurText() );
3199 }
3200
3201 tok = NextTok();
3202 }
3203}
3204
3205
3207{
3208 T tok;
3209
3210 /* <wiring_descriptor >::=
3211 (wiring
3212 [<unit_descriptor> | <resolution_descriptor> | null]
3213 {<wire_descriptor> }
3214 [<test_points_descriptor> ]
3215 {[<supply_pin_descriptor> ]}
3216 )
3217 */
3218
3219 while( ( tok = NextTok() ) != T_RIGHT )
3220 {
3221 if( tok != T_LEFT )
3222 Expecting( T_LEFT );
3223
3224 tok = NextTok();
3225
3226 switch( tok )
3227 {
3228 case T_unit:
3229 if( growth->unit )
3230 Unexpected( tok );
3231
3232 growth->unit = new UNIT_RES( growth, tok );
3233 doUNIT( growth->unit );
3234 break;
3235
3236 case T_resolution:
3237 if( growth->unit )
3238 Unexpected( tok );
3239
3240 growth->unit = new UNIT_RES( growth, tok );
3241 doRESOLUTION( growth->unit );
3242 break;
3243
3244 case T_wire:
3245 WIRE* wire;
3246 wire = new WIRE( growth );
3247 growth->wires.push_back( wire );
3248 doWIRE( wire );
3249 break;
3250
3251 case T_via:
3252 WIRE_VIA* wire_via;
3253 wire_via = new WIRE_VIA( growth );
3254 growth->wire_vias.push_back( wire_via );
3255 doWIRE_VIA( wire_via );
3256 break;
3257
3258 default:
3259 Unexpected( CurText() );
3260 }
3261 }
3262}
3263
3264
3266{
3267 T tok;
3268
3269 /* <ancestor_file_descriptor >::=
3270 (ancestor <file_path_name> (created_time <time_stamp> )
3271 [(comment <comment_string> )])
3272 */
3273
3274 NeedSYMBOL();
3275 growth->filename = CurText();
3276
3277 while( ( tok = NextTok() ) != T_RIGHT )
3278 {
3279 if( tok != T_LEFT )
3280 Expecting( T_LEFT );
3281
3282 tok = NextTok();
3283
3284 switch( tok )
3285 {
3286 case T_created_time:
3287 readTIME( &growth->time_stamp );
3288 NeedRIGHT();
3289 break;
3290
3291 case T_comment:
3292 NeedSYMBOL();
3293 growth->comment = CurText();
3294 NeedRIGHT();
3295 break;
3296
3297 default:
3298 Unexpected( CurText() );
3299 }
3300 }
3301}
3302
3303
3305{
3306 T tok;
3307
3308 /* <history_descriptor >::=
3309 (history [{<ancestor_file_descriptor> }] <self_descriptor> )
3310 */
3311
3312 while( ( tok = NextTok() ) != T_RIGHT )
3313 {
3314 if( tok != T_LEFT )
3315 Expecting( T_LEFT );
3316
3317 tok = NextTok();
3318
3319 switch( tok )
3320 {
3321 case T_ancestor:
3322 ANCESTOR* ancestor;
3323 ancestor = new ANCESTOR( growth );
3324 growth->ancestors.push_back( ancestor );
3325 doANCESTOR( ancestor );
3326 break;
3327
3328 case T_self:
3329 while( ( tok = NextTok() ) != T_RIGHT )
3330 {
3331 if( tok != T_LEFT )
3332 Expecting( T_LEFT );
3333
3334 tok = NextTok();
3335
3336 switch( tok )
3337 {
3338 case T_created_time:
3339 readTIME( &growth->time_stamp );
3340 NeedRIGHT();
3341 break;
3342
3343 case T_comment:
3344 NeedSYMBOL();
3345 growth->comments.push_back( CurText() );
3346 NeedRIGHT();
3347 break;
3348
3349 default:
3350 Unexpected( CurText() );
3351 }
3352 }
3353
3354 break;
3355
3356 default:
3357 Unexpected( CurText() );
3358 }
3359 }
3360}
3361
3362
3364{
3365 T tok;
3366
3367 /* <session_file_descriptor >::=
3368 (session <session_id >
3369 (base_design <path/filename >)
3370 [<history_descriptor> ]
3371 [<session_structure_descriptor> ]
3372 [<placement_descriptor> ]
3373 [<floor_plan_descriptor> ]
3374 [<net_pin_changes_descriptor> ]
3375 [<was_is_descriptor> ]
3376 <swap_history_descriptor> ]
3377 [<route_descriptor> ]
3378 )
3379 */
3380
3381 // The path can be defined by multiple tokens if there are spaces in it (e.g. by TopoR).
3382 NeedSYMBOL();
3383 std::stringstream fullPath;
3384 fullPath << CurText();
3385
3386 while( ( tok = NextTok() ) != T_LEFT )
3387 fullPath << " " << CurText();
3388
3389 growth->session_id = fullPath.str();
3390
3391 do
3392 {
3393 if( tok != T_LEFT )
3394 Expecting( T_LEFT );
3395
3396 tok = NextTok();
3397
3398 switch( tok )
3399 {
3400 case T_base_design:
3401 NeedSYMBOL();
3402 growth->base_design = CurText();
3403 NeedRIGHT();
3404 break;
3405
3406 case T_history:
3407 if( growth->history )
3408 Unexpected( tok );
3409
3410 growth->history = new HISTORY( growth );
3411 doHISTORY( growth->history );
3412 break;
3413
3414 case T_structure:
3415 if( growth->structure )
3416 Unexpected( tok );
3417
3418 growth->structure = new STRUCTURE( growth );
3419 doSTRUCTURE( growth->structure );
3420 break;
3421
3422 case T_placement:
3423 if( growth->placement )
3424 Unexpected( tok );
3425
3426 growth->placement = new PLACEMENT( growth );
3427 doPLACEMENT( growth->placement );
3428 break;
3429
3430 case T_was_is:
3431 if( growth->was_is )
3432 Unexpected( tok );
3433
3434 growth->was_is = new WAS_IS( growth );
3435 doWAS_IS( growth->was_is );
3436 break;
3437
3438 case T_routes:
3439 if( growth->route )
3440 Unexpected( tok );
3441
3442 growth->route = new ROUTE( growth );
3443 doROUTE( growth->route );
3444 break;
3445
3446 default:
3447 Unexpected( CurText() );
3448 }
3449 } while( ( tok = NextTok() ) != T_RIGHT );
3450}
3451
3452
3454{
3455 T tok;
3456 PIN_PAIR empty( growth );
3457 PIN_PAIR* pin_pair;
3458
3459 /* <was_is_descriptor >::=
3460 (was_is {(pins <pin_reference> <pin_reference> )})
3461 */
3462
3463 // none of the pins is ok too
3464 while( ( tok = NextTok() ) != T_RIGHT )
3465 {
3466 if( tok != T_LEFT )
3467 Expecting( T_LEFT );
3468
3469 tok = NextTok();
3470
3471 switch( tok )
3472 {
3473 case T_pins:
3474 // copy the empty one, then fill its copy later thru pin_pair.
3475 growth->pin_pairs.push_back( empty );
3476 pin_pair= &growth->pin_pairs.back();
3477
3478 NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3479 readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
3480
3481 NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3482 readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
3483
3484 NeedRIGHT();
3485 break;
3486
3487 default:
3488 Unexpected( CurText() );
3489 }
3490 }
3491}
3492
3493
3495{
3496 T tok;
3497
3498 /* <route_descriptor >::=
3499 (routes
3500 <resolution_descriptor>
3501 <parser_descriptor>
3502 <structure_out_descriptor>
3503 <library_out_descriptor>
3504 <network_out_descriptor>
3505 <test_points_descriptor>
3506 )
3507 */
3508
3509 while( ( tok = NextTok() ) != T_RIGHT )
3510 {
3511 if( tok != T_LEFT )
3512 Expecting( T_LEFT );
3513
3514 tok = NextTok();
3515
3516 switch( tok )
3517 {
3518 case T_resolution:
3519 if( growth->resolution )
3520 Unexpected( tok );
3521
3522 growth->resolution = new UNIT_RES( growth, tok );
3523 doRESOLUTION( growth->resolution );
3524 break;
3525
3526 case T_parser:
3527 if( growth->parser )
3528 {
3529#if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
3530 // Work around their bug for now.
3531 Unexpected( tok );
3532#else
3533 delete growth->parser;
3534#endif
3535 }
3536
3537 growth->parser = new PARSER( growth );
3538 doPARSER( growth->parser );
3539 break;
3540
3541 case T_structure_out:
3542 if( growth->structure_out )
3543 Unexpected( tok );
3544
3545 growth->structure_out = new STRUCTURE_OUT( growth );
3546 doSTRUCTURE_OUT( growth->structure_out );
3547 break;
3548
3549 case T_library_out:
3550 if( growth->library )
3551 Unexpected( tok );
3552
3553 growth->library = new LIBRARY( growth, tok );
3554 doLIBRARY( growth->library );
3555 break;
3556
3557 case T_network_out:
3558 while( ( tok = NextTok() ) != T_RIGHT )
3559 {
3560 if( tok != T_LEFT )
3561 Expecting( T_LEFT );
3562
3563 tok = NextTok();
3564
3565 // it is class NET_OUT, but token T_net in Freerouting
3566 // Allegro PCB Router (Specctra) uses capitalized "Net"
3567 if( tok != T_net && !( tok == T_SYMBOL && !strcmp( CurText(), "Net" ) ) )
3568 Unexpected( CurText() );
3569
3570 NET_OUT* net_out;
3571 net_out = new NET_OUT( growth );
3572
3573 growth->net_outs.push_back( net_out );
3574 doNET_OUT( net_out );
3575 }
3576
3577 break;
3578
3579 case T_test_points:
3580 while( ( tok = NextTok() ) != T_RIGHT )
3581 {
3582 // TODO: Not supported yet
3583 Unexpected( CurText() );
3584 }
3585 break;
3586
3587 default:
3588 Unexpected( CurText() );
3589 }
3590 }
3591}
3592
3593
3595{
3596 T tok;
3597
3598 /* <net_out_descriptor >::=
3599 (net <net_id >
3600 [(net_number <integer >)]
3601 [<rule_descriptor> ]
3602 {[<wire_shape_descriptor> | <wire_guide_descriptor> |
3603 <wire_via_descriptor> | <bond_shape_descriptor> ]}
3604 {[<supply_pin_descriptor> ]}
3605 )
3606 */
3607
3608 NeedSYMBOLorNUMBER();
3609 growth->net_id = CurText();
3610
3611 while( ( tok = NextTok() ) != T_RIGHT )
3612 {
3613 if( tok != T_LEFT )
3614 Expecting( T_LEFT );
3615
3616 tok = NextTok();
3617
3618 switch( tok )
3619 {
3620 case T_net_number:
3621 tok = NextTok();
3622
3623 if( tok!= T_NUMBER )
3624 Expecting( T_NUMBER );
3625
3626 growth->net_number = atoi( CurText() );
3627 NeedRIGHT();
3628 break;
3629
3630 case T_rule:
3631 if( growth->rules )
3632 Unexpected( tok );
3633
3634 growth->rules = new RULE( growth, tok );
3635 doRULE( growth->rules );
3636 break;
3637
3638 case T_wire:
3639 WIRE* wire;
3640 wire = new WIRE( growth );
3641 growth->wires.push_back( wire );
3642 doWIRE( wire );
3643 break;
3644
3645 case T_via:
3646 WIRE_VIA* wire_via;
3647 wire_via = new WIRE_VIA( growth );
3648 growth->wire_vias.push_back( wire_via );
3649 doWIRE_VIA( wire_via );
3650 break;
3651
3652 case T_supply_pin:
3653 SUPPLY_PIN* supply_pin;
3654 supply_pin = new SUPPLY_PIN( growth );
3655 growth->supply_pins.push_back( supply_pin );
3656 doSUPPLY_PIN( supply_pin );
3657 break;
3658
3659 default:
3660 Unexpected( CurText() );
3661 }
3662 }
3663}
3664
3665
3667{
3668 T tok;
3669 PIN_REF empty(growth);
3670
3671 /* <supply_pin_descriptor >::=
3672 (supply_pin {<pin_reference> } [(net <net_id >)])
3673 */
3674
3675 NeedSYMBOL();
3676 growth->net_id = CurText();
3677
3678 while( ( tok = NextTok() ) != T_RIGHT )
3679 {
3680 if( IsSymbol(tok) )
3681 {
3682 growth->pin_refs.push_back( empty );
3683
3684 PIN_REF* pin_ref = &growth->pin_refs.back();
3685
3686 readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
3687 }
3688 else if( tok == T_LEFT )
3689 {
3690 tok = NextTok();
3691
3692 if( tok != T_net )
3693 Expecting( T_net );
3694
3695 growth->net_id = CurText();
3696 NeedRIGHT();
3697 }
3698 else
3699 Unexpected( CurText() );
3700 }
3701}
3702
3703
3704void SPECCTRA_DB::ExportPCB( const wxString& aFilename, bool aNameChange )
3705{
3706 if( m_pcb )
3707 {
3708 FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3709
3710 if( aNameChange )
3711 m_pcb->m_pcbname = TO_UTF8( aFilename );
3712
3713 m_pcb->Format( &formatter, 0 );
3714 }
3715}
3716
3717
3718void SPECCTRA_DB::ExportSESSION( const wxString& aFilename )
3719{
3720 if( m_session )
3721 {
3722 FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3723
3724 m_session->Format( &formatter, 0 );
3725 }
3726}
3727
3728
3730{
3731 PCB* pcb = new PCB();
3732
3733 pcb->m_parser = new PARSER( pcb );
3734 pcb->m_resolution = new UNIT_RES( pcb, T_resolution );
3735 pcb->m_unit = new UNIT_RES( pcb, T_unit );
3736
3737 pcb->m_structure = new STRUCTURE( pcb );
3738 pcb->m_structure->m_boundary = new BOUNDARY( pcb->m_structure );
3739 pcb->m_structure->m_via = new VIA( pcb->m_structure );
3740 pcb->m_structure->m_rules = new RULE( pcb->m_structure, T_rule );
3741
3742 pcb->m_placement = new PLACEMENT( pcb );
3743
3744 pcb->m_library = new LIBRARY( pcb );
3745
3746 pcb->m_network = new NETWORK( pcb );
3747
3748 pcb->m_wiring = new WIRING( pcb );
3749
3750 return pcb;
3751}
3752
3753
3754//-----<ELEM>---------------------------------------------------------------
3755
3756ELEM::ELEM( T aType, ELEM* aParent ) :
3757 type( aType ),
3758 parent( aParent )
3759{
3760}
3761
3762
3764{
3765}
3766
3767const char* ELEM::Name() const
3768{
3769 return SPECCTRA_DB::TokenName( type );
3770}
3771
3773{
3774 if( parent )
3775 return parent->GetUnits();
3776
3777 return &UNIT_RES::Default;
3778}
3779
3780
3781void ELEM::Format( OUTPUTFORMATTER* out, int nestLevel )
3782{
3783 out->Print( nestLevel, "(%s\n", Name() );
3784
3785 FormatContents( out, nestLevel+1 );
3786
3787 out->Print( nestLevel, ")\n" );
3788}
3789
3790
3792{
3793 for( int i = 0; i < Length(); ++i )
3794 At(i)->Format( out, nestLevel );
3795}
3796
3797
3798int ELEM_HOLDER::FindElem( T aType, int instanceNum )
3799{
3800 int repeats=0;
3801
3802 for( unsigned i = 0; i < kids.size(); ++i )
3803 {
3804 if( kids[i].Type() == aType )
3805 {
3806 if( repeats == instanceNum )
3807 return i;
3808
3809 ++repeats;
3810 }
3811 }
3812
3813 return -1;
3814}
3815
3816
3817// a reasonably small memory price to pay for improved performance
3819
3820
3821UNIT_RES UNIT_RES::Default( nullptr, T_resolution );
3822
3823
3825{
3826 if( !lhs->m_hash.size() )
3827 lhs->m_hash = lhs->makeHash();
3828
3829 if( !rhs->m_hash.size() )
3830 rhs->m_hash = rhs->makeHash();
3831
3832 int result = lhs->m_hash.compare( rhs->m_hash );
3833
3834 if( result )
3835 return result;
3836
3837 // Via names hold the drill diameters, so we have to include those to discern
3838 // between two vias with same copper size but with different drill sizes.
3839 result = lhs->m_padstack_id.compare( rhs->m_padstack_id );
3840
3841 return result;
3842}
3843
3844
3845int IMAGE::Compare( IMAGE* lhs, IMAGE* rhs )
3846{
3847 if( !lhs->m_hash.size() )
3848 lhs->m_hash = lhs->makeHash();
3849
3850 if( !rhs->m_hash.size() )
3851 rhs->m_hash = rhs->makeHash();
3852
3853 int result = lhs->m_hash.compare( rhs->m_hash );
3854
3855 return result;
3856}
3857
3858
3859/*
3860int COMPONENT::Compare( COMPONENT* lhs, COMPONENT* rhs )
3861{
3862 if( !lhs->hash.size() )
3863 lhs->hash = lhs->makeHash();
3864
3865 if( !rhs->hash.size() )
3866 rhs->hash = rhs->makeHash();
3867
3868 int result = lhs->hash.compare( rhs->hash );
3869 return result;
3870}
3871*/
3872
3874 ELEM( T_parser, aParent )
3875{
3876 string_quote = '"';
3877 space_in_quoted_tokens = false;
3878
3879 case_sensitive = false;
3882 routes_include_guides = false;
3884 via_rotate_first = true;
3885 generated_by_freeroute = false;
3886
3887 host_cad = "KiCad's Pcbnew";
3888 wxString msg = GetBuildVersion();
3889 host_version = TO_UTF8(msg);
3890}
3891
3892
3893void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel )
3894{
3895 out->Print( nestLevel, "(string_quote %c)\n", string_quote );
3896 out->Print( nestLevel, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
3897 out->Print( nestLevel, "(host_cad \"%s\")\n", host_cad.c_str() );
3898 out->Print( nestLevel, "(host_version \"%s\")\n", host_version.c_str() );
3899
3900 for( STRINGS::iterator i = constants.begin(); i != constants.end(); )
3901 {
3902 const std::string& s1 = *i++;
3903 const std::string& s2 = *i++;
3904
3905 const char* q1 = out->GetQuoteChar( s1.c_str() );
3906 const char* q2 = out->GetQuoteChar( s2.c_str() );
3907 out->Print( nestLevel, "(constant %s%s%s %s%s%s)\n",
3908 q1, s1.c_str(), q1, q2, s2.c_str(), q2 );
3909 }
3910
3912 {
3913 out->Print( nestLevel, "(routes_include%s%s%s)\n",
3914 routes_include_testpoint ? " testpoint" : "",
3915 routes_include_guides ? " guides" : "",
3916 routes_include_image_conductor ? " image_conductor" : "" );
3917 }
3918
3920 out->Print( nestLevel, "(wires_include testpoint)\n" );
3921
3922 if( !via_rotate_first )
3923 out->Print( nestLevel, "(via_rotate_first off)\n" );
3924
3925 if( case_sensitive )
3926 out->Print( nestLevel, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
3927}
3928
3929
3930void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel )
3931{
3932 bool useMultiLine;
3933
3934 const char* quote = out->GetQuoteChar( m_component_id.c_str() );
3935
3936 if( m_place_rules || m_properties.size() || m_rules || m_region )
3937 {
3938 useMultiLine = true;
3939
3940 out->Print( nestLevel, "(%s %s%s%s\n", Name(), quote, m_component_id.c_str(), quote );
3941 out->Print( nestLevel+1, "%s", "" );
3942 }
3943 else
3944 {
3945 useMultiLine = false;
3946
3947 out->Print( nestLevel, "(%s %s%s%s", Name(), quote, m_component_id.c_str(), quote );
3948 }
3949
3950 if( m_hasVertex )
3951 {
3952 out->Print( 0, " %.6f %.6f", m_vertex.x, m_vertex.y );
3953 out->Print( 0, " %s", GetTokenText( m_side ) );
3954 out->Print( 0, " %.6f", m_rotation );
3955 }
3956
3957 const char* space = " "; // one space, as c string.
3958
3959 if( m_mirror != T_NONE )
3960 {
3961 out->Print( 0, "%s(mirror %s)", space, GetTokenText( m_mirror ) );
3962 space = "";
3963 }
3964
3965 if( m_status != T_NONE )
3966 {
3967 out->Print( 0, "%s(status %s)", space, GetTokenText( m_status ) );
3968 space = "";
3969 }
3970
3971 if( m_logical_part.size() )
3972 {
3973 quote = out->GetQuoteChar( m_logical_part.c_str() );
3974 out->Print( 0, "%s(logical_part %s%s%s)", space, quote, m_logical_part.c_str(), quote );
3975 space = "";
3976 }
3977
3978 if( useMultiLine )
3979 {
3980 out->Print( 0, "\n" );
3981
3982 if( m_place_rules )
3983 m_place_rules->Format( out, nestLevel+1 );
3984
3985 if( m_properties.size() )
3986 {
3987 out->Print( nestLevel + 1, "(property \n" );
3988
3989 for( PROPERTIES::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i )
3990 i->Format( out, nestLevel + 2 );
3991
3992 out->Print( nestLevel + 1, ")\n" );
3993 }
3994
3995 if( m_lock_type != T_NONE )
3996 out->Print( nestLevel + 1, "(lock_type %s)\n", GetTokenText( m_lock_type ) );
3997
3998 if( m_rules )
3999 m_rules->Format( out, nestLevel+1 );
4000
4001 if( m_region )
4002 m_region->Format( out, nestLevel+1 );
4003
4004 if( m_part_number.size() )
4005 {
4006 quote = out->GetQuoteChar( m_part_number.c_str() );
4007 out->Print( nestLevel + 1, "(PN %s%s%s)\n", quote, m_part_number.c_str(), quote );
4008 }
4009 }
4010 else
4011 {
4012 if( m_lock_type != T_NONE )
4013 {
4014 out->Print( 0, "%s(lock_type %s)", space, GetTokenText( m_lock_type ) );
4015 space = "";
4016 }
4017
4018 if( m_part_number.size() )
4019 {
4020 quote = out->GetQuoteChar( m_part_number.c_str() );
4021 out->Print( 0, "%s(PN %s%s%s)", space, quote, m_part_number.c_str(), quote );
4022 }
4023 }
4024
4025 out->Print( 0, ")\n" );
4026}
4027
4028} // namespace DSN
wxString GetBuildVersion()
Get the full KiCad version string.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:295
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:820
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:616
time_t time_stamp
Definition: specctra.h:3299
std::string filename
Definition: specctra.h:3297
std::string comment
Definition: specctra.h:3298
PATHS paths
Definition: specctra.h:729
RECTANGLE * rectangle
Definition: specctra.h:730
std::string layer_id
Definition: specctra.h:775
double diameter
Definition: specctra.h:777
POINT vertex
Definition: specctra.h:778
STRINGS class_ids
Definition: specctra.h:1121
CLASSES * classes
Definition: specctra.h:1156
The <class_descriptor> in the specctra spec.
Definition: specctra.h:2748
TOPOLOGY * m_topology
Definition: specctra.h:2834
std::string m_class_id
Definition: specctra.h:2823
RULE * m_rules
Definition: specctra.h:2830
STRINGS m_net_ids
Definition: specctra.h:2825
STRINGS m_circuit
circuit descriptor list
Definition: specctra.h:2828
LAYER_RULES m_layer_rules
Definition: specctra.h:2832
Implement a <component_descriptor> in the specctra dsn spec.
Definition: specctra.h:1768
std::string m_image_id
Definition: specctra.h:1808
PLACES m_places
Definition: specctra.h:1809
The <component_order_descriptor>.
Definition: specctra.h:2556
STRINGS m_placement_ids
Definition: specctra.h:2582
bool via_at_smd
Definition: specctra.h:1196
A <plane_descriptor> in the specctra dsn spec.
Definition: specctra.h:1353
void Append(ELEM *aElem)
Definition: specctra.h:322
int FindElem(DSN_T aType, int instanceNum=0)
Find a particular instance number of a given type of ELEM.
Definition: specctra.cpp:3798
virtual void FormatContents(OUTPUTFORMATTER *out, int nestLevel) override
Write the contents as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.cpp:3791
ELEM_ARRAY kids
ELEM pointers.
Definition: specctra.h:360
ELEM * At(int aIndex) const
Definition: specctra.h:341
int Length() const
Return the number of ELEMs in this holder.
Definition: specctra.h:317
A base class for any DSN element class.
Definition: specctra.h:203
ELEM * parent
Definition: specctra.h:276
std::string makeHash()
Return a string which uniquely represents this ELEM among other ELEMs of the same derived class as "t...
Definition: specctra.h:263
const char * Name() const
Definition: specctra.cpp:3767
virtual void Format(OUTPUTFORMATTER *out, int nestLevel)
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.cpp:3781
ELEM(DSN_T aType, ELEM *aParent=nullptr)
Definition: specctra.cpp:3756
DSN_T type
Definition: specctra.h:275
virtual UNIT_RES * GetUnits() const
Return the units for this section.
Definition: specctra.cpp:3772
virtual ~ELEM()
Definition: specctra.cpp:3763
virtual void FormatContents(OUTPUTFORMATTER *out, int nestLevel)
Write the contents as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:242
DSN_T Type() const
Definition: specctra.h:210
static STRING_FORMATTER sf
Definition: specctra.h:273
LAYER_RULES m_layer_rules
Definition: specctra.h:2546
std::string m_fromText
Definition: specctra.h:2539
std::string m_net_id
Definition: specctra.h:2543
std::string m_toText
Definition: specctra.h:2540
DSN_T m_fromto_type
Definition: specctra.h:2542
RULE * m_rules
Definition: specctra.h:2544
DSN_T m_grid_type
T_via | T_wire | T_via_keepout | T_place | T_snap.
Definition: specctra.h:1515
double m_offset
Definition: specctra.h:1518
DSN_T m_direction
T_x | T_y | -1 for both.
Definition: specctra.h:1517
double m_dimension
Definition: specctra.h:1516
DSN_T m_image_type
Definition: specctra.h:1519
STRINGS comments
Definition: specctra.h:3342
ANCESTORS ancestors
Definition: specctra.h:3340
time_t time_stamp
Definition: specctra.h:3341
DSN_T m_side
Definition: specctra.h:2096
std::string m_hash
a hash string used by Compare(), not Format()ed/exported.
Definition: specctra.h:2093
KEEPOUTS m_keepouts
Definition: specctra.h:2109
static int Compare(IMAGE *lhs, IMAGE *rhs)
Compare two objects of this type and returns <0, 0, or >0.
Definition: specctra.cpp:3845
RULE * m_rules
Definition: specctra.h:2106
UNIT_RES * m_unit
Definition: specctra.h:2097
std::string m_image_id
Definition: specctra.h:2095
PINS m_pins
Definition: specctra.h:2104
RULE * m_place_rules
Definition: specctra.h:2107
Used for <keepout_descriptor> and <plane_descriptor>.
Definition: specctra.h:906
RULE * m_place_rules
Definition: specctra.h:1015
std::string m_name
Definition: specctra.h:1012
WINDOWS m_windows
Definition: specctra.h:1017
ELEM * m_shape
Definition: specctra.h:1026
RULE * m_rules
Definition: specctra.h:1014
int m_sequence_number
Definition: specctra.h:1013
SPECCTRA_LAYER_PAIRS layer_pairs
Definition: specctra.h:1328
STRINGS m_layer_ids
Definition: specctra.h:570
RULE * m_rule
Definition: specctra.h:571
STRINGS use_net
Definition: specctra.h:1286
PROPERTIES properties
Definition: specctra.h:1288
DSN_T layer_type
one of: T_signal, T_power, T_mixed, T_jumper
Definition: specctra.h:1279
RULE * rules
Definition: specctra.h:1285
int cost_type
T_length | T_way.
Definition: specctra.h:1284
int direction
[forbidden | high | medium | low | free | <positive_integer> | -1]
Definition: specctra.h:1280
std::string name
Definition: specctra.h:1278
A <library_descriptor> in the specctra dsn specification.
Definition: specctra.h:2252
IMAGES m_images
Definition: specctra.h:2439
UNIT_RES * m_unit
Definition: specctra.h:2438
void AddPadstack(PADSTACK *aPadstack)
Definition: specctra.h:2266
CLASSLIST m_classes
Definition: specctra.h:2861
A <net_out_descriptor> of the specctra dsn spec.
Definition: specctra.h:3399
int net_number
Definition: specctra.h:3442
SUPPLY_PINS supply_pins
Definition: specctra.h:3446
std::string net_id
Definition: specctra.h:3441
RULE * rules
Definition: specctra.h:3443
WIRE_VIAS wire_vias
Definition: specctra.h:3445
WIRES wires
Definition: specctra.h:3444
A <net_descriptor> in the DSN spec.
Definition: specctra.h:2591
FROMTOS m_fromtos
Definition: specctra.h:2710
PIN_REFS m_source
Definition: specctra.h:2698
PIN_REFS m_expose
Definition: specctra.h:2696
PIN_REFS m_load
Definition: specctra.h:2699
RULE * m_rules
Definition: specctra.h:2706
PIN_REFS m_noexpose
Definition: specctra.h:2697
std::string m_net_id
Definition: specctra.h:2689
int m_net_number
Definition: specctra.h:2691
LAYER_RULES m_layer_rules
Definition: specctra.h:2708
PIN_REFS m_pins
Definition: specctra.h:2694
bool m_unassigned
Definition: specctra.h:2690
COMP_ORDER * m_comp_order
Definition: specctra.h:2712
PIN_REFS m_terminator
Definition: specctra.h:2700
DSN_T m_pins_type
T_pins | T_order, type of field 'pins' below.
Definition: specctra.h:2693
Hold either a via or a pad definition.
Definition: specctra.h:2121
std::string m_via_id
Definition: specctra.h:2228
std::string m_hash
a hash string used by Compare(), not Format()ed/exported.
Definition: specctra.h:2218
DSN_T m_attach
Definition: specctra.h:2227
DSN_T m_absolute
Definition: specctra.h:2226
std::string m_padstack_id
Definition: specctra.h:2220
RULE * m_rules
Definition: specctra.h:2230
DSN_T m_rotate
Definition: specctra.h:2225
static int Compare(PADSTACK *lhs, PADSTACK *rhs)
Compare two objects of this type and returns <0, 0, or >0.
Definition: specctra.cpp:3824
UNIT_RES * m_unit
Definition: specctra.h:2221
A configuration record per the SPECCTRA DSN file spec.
Definition: specctra.h:370
std::string host_version
Definition: specctra.h:394
void FormatContents(OUTPUTFORMATTER *out, int nestLevel) override
Write the contents as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.cpp:3893
bool routes_include_image_conductor
Definition: specctra.h:386
std::string host_cad
Definition: specctra.h:393
bool routes_include_guides
Definition: specctra.h:385
bool case_sensitive
Definition: specctra.h:382
bool wires_include_testpoint
Definition: specctra.h:383
STRINGS constants
This holds pairs of strings, one pair for each constant definition.
Definition: specctra.h:391
bool via_rotate_first
Definition: specctra.h:387
char string_quote
Definition: specctra.h:380
PARSER(ELEM *aParent)
Definition: specctra.cpp:3873
bool routes_include_testpoint
Definition: specctra.h:384
bool generated_by_freeroute
Definition: specctra.h:388
bool space_in_quoted_tokens
Definition: specctra.h:381
Support both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition: specctra.h:583
DSN_T aperture_type
Definition: specctra.h:654
POINTS points
Definition: specctra.h:653
double aperture_width
Definition: specctra.h:651
std::string layer_id
Definition: specctra.h:650
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:3205
UNIT_RES * m_unit
Definition: specctra.h:3255
UNIT_RES * m_resolution
Definition: specctra.h:3254
std::string m_pcbname
Definition: specctra.h:3252
NETWORK * m_network
Definition: specctra.h:3259
PLACEMENT * m_placement
Definition: specctra.h:3257
STRUCTURE * m_structure
Definition: specctra.h:3256
PARSER * m_parser
Definition: specctra.h:3253
WIRING * m_wiring
Definition: specctra.h:3260
LIBRARY * m_library
Definition: specctra.h:3258
POINT m_vertex
Definition: specctra.h:1996
void SetRotation(double aRotation)
Definition: specctra.h:1964
std::string m_pin_id
Definition: specctra.h:1995
std::string m_padstack_id
Definition: specctra.h:1992
DSN_T m_flip_style
Definition: specctra.h:1880
UNIT_RES * m_unit
Definition: specctra.h:1878
COMPONENTS m_components
Definition: specctra.h:1882
Implement a <placement_reference> in the specctra dsn spec.
Definition: specctra.h:1688
void SetVertex(const POINT &aVertex)
Definition: specctra.h:1716
DSN_T m_status
Definition: specctra.h:1743
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.cpp:3930
bool m_hasVertex
Definition: specctra.h:1739
POINT m_vertex
Definition: specctra.h:1740
DSN_T m_mirror
Definition: specctra.h:1742
void SetRotation(double aRotation)
Definition: specctra.h:1723
RULE * m_rules
Definition: specctra.h:1754
DSN_T m_lock_type
Definition: specctra.h:1751
DSN_T m_side
Definition: specctra.h:1735
double m_rotation
Definition: specctra.h:1737
std::string m_logical_part
Definition: specctra.h:1745
std::string m_part_number
Definition: specctra.h:1758
REGION * m_region
Definition: specctra.h:1755
std::string m_component_id
reference designator
Definition: specctra.h:1733
RULE * m_place_rules
Definition: specctra.h:1747
PROPERTIES m_properties
Definition: specctra.h:1749
std::string layer_id
Definition: specctra.h:837
double aperture_width
Definition: specctra.h:838
POINT vertex[3]
Definition: specctra.h:839
std::string layer_id
Definition: specctra.h:481
POINT point1
Definition: specctra.h:484
POINT point0
one of two opposite corners
Definition: specctra.h:483
RULE * m_rules
Definition: specctra.h:1474
RECTANGLE * m_rectangle
Definition: specctra.h:1466
PATH * m_polygon
Definition: specctra.h:1467
std::string m_region_id
Definition: specctra.h:1463
STRUCTURE_OUT * structure_out
Definition: specctra.h:3514
NET_OUTS net_outs
Definition: specctra.h:3516
UNIT_RES * resolution
Definition: specctra.h:3512
LIBRARY * library
Definition: specctra.h:3515
PARSER * parser
Definition: specctra.h:3513
A <rule_descriptor> in the specctra dsn spec.
Definition: specctra.h:492
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:500
STRINGS m_rules
rules are saved in std::string form.
Definition: specctra.h:530
A <session_file_descriptor> in the specctra dsn spec.
Definition: specctra.h:3574
void Format(OUTPUTFORMATTER *out, int nestLevel) override
Write this object as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
Definition: specctra.h:3595
std::string session_id
Definition: specctra.h:3623
PLACEMENT * placement
Definition: specctra.h:3628
HISTORY * history
Definition: specctra.h:3626
STRUCTURE * structure
Definition: specctra.h:3627
std::string base_design
Definition: specctra.h:3624
ROUTE * route
Definition: specctra.h:3630
WAS_IS * was_is
Definition: specctra.h:3629
A "(shape ..)" element in the specctra dsn spec.
Definition: specctra.h:1894
DSN_T m_connect
Definition: specctra.h:1938
WINDOWS m_windows
Definition: specctra.h:1949
void doUNIT(UNIT_RES *growth)
Definition: specctra.cpp:587
void doPCB(PCB *growth)
Definition: specctra.cpp:288
void doCOMPONENT(COMPONENT *growth)
Definition: specctra.cpp:2003
void doWAS_IS(WAS_IS *growth)
Definition: specctra.cpp:3453
void doPLACEMENT(PLACEMENT *growth)
Definition: specctra.cpp:2035
void doNET_OUT(NET_OUT *growth)
Definition: specctra.cpp:3594
void buildLayerMaps(BOARD *aBoard)
Create a few data translation structures for layer name and number mapping between the DSN::PCB struc...
Definition: specctra.cpp:76
void doCLASS(CLASS *growth)
Definition: specctra.cpp:2689
void SetSESSION(SESSION *aSession)
Delete any existing SESSION and replaces it with the given one.
Definition: specctra.h:3697
void doSTRUCTURE_OUT(STRUCTURE_OUT *growth)
Definition: specctra.cpp:790
std::map< int, PCB_LAYER_ID > m_pcbLayer2kicad
maps PCB layer number to BOARD layer numbers
Definition: specctra.h:3995
void doCIRCLE(CIRCLE *growth)
Definition: specctra.cpp:1158
void doANCESTOR(ANCESTOR *growth)
Definition: specctra.cpp:3265
void doLAYER_NOISE_WEIGHT(LAYER_NOISE_WEIGHT *growth)
Definition: specctra.cpp:625
void ExportPCB(const wxString &aFilename, bool aNameChange=false)
Write the internal PCB instance out as a SPECTRA DSN format file.
Definition: specctra.cpp:3704
void doCLASS_CLASS(CLASS_CLASS *growth)
Definition: specctra.cpp:1694
void doSESSION(SESSION *growth)
Definition: specctra.cpp:3363
void doWINDOW(WINDOW *growth)
Definition: specctra.cpp:969
void doSHAPE(SHAPE *growth)
Definition: specctra.cpp:2205
void doQARC(QARC *growth)
Definition: specctra.cpp:1189
void doRESOLUTION(UNIT_RES *growth)
Definition: specctra.cpp:558
void LoadPCB(const wxString &aFilename)
A recursive descent parser for a SPECCTRA DSN "design" file.
Definition: specctra.cpp:249
void doSTRINGPROP(STRINGPROP *growth)
Definition: specctra.cpp:1216
STRINGS m_layerIds
indexed by PCB layer number
Definition: specctra.h:3992
void doBOUNDARY(BOUNDARY *growth)
Definition: specctra.cpp:1028
void doSPECCTRA_LAYER_PAIR(SPECCTRA_LAYER_PAIR *growth)
Definition: specctra.cpp:608
SESSION * m_session
Definition: specctra.h:3984
void doRECTANGLE(RECTANGLE *growth)
Definition: specctra.cpp:1129
void doREGION(REGION *growth)
Definition: specctra.cpp:1619
void ExportSESSION(const wxString &aFilename)
Write the internal #SESSION instance out as a #SPECTRA DSN format file.
Definition: specctra.cpp:3718
void doWIRE(WIRE *growth)
Definition: specctra.cpp:2957
void SetPCB(PCB *aPcb)
Delete any existing PCB and replaces it with the given one.
Definition: specctra.h:3686
void doTOKPROP(TOKPROP *growth)
Definition: specctra.cpp:1224
void doIMAGE(IMAGE *growth)
Definition: specctra.cpp:2293
void doCONNECT(CONNECT *growth)
Definition: specctra.cpp:934
void doCOMP_ORDER(COMP_ORDER *growth)
Definition: specctra.cpp:2848
static PCB * MakePCB()
Make a PCB with all the default ELEMs and parts on the heap.
Definition: specctra.cpp:3729
void doTOPOLOGY(TOPOLOGY *growth)
Definition: specctra.cpp:2650
void doKEEPOUT(KEEPOUT *growth)
Definition: specctra.cpp:835
void doRULE(RULE *growth)
Definition: specctra.cpp:1481
void doPATH(PATH *growth)
Definition: specctra.cpp:1078
void doPIN(PIN *growth)
Definition: specctra.cpp:2395
void doSUPPLY_PIN(SUPPLY_PIN *growth)
Definition: specctra.cpp:3666
void doLAYER(LAYER *growth)
Definition: specctra.cpp:1341
void LoadSESSION(const wxString &aFilename)
A recursive descent parser for a SPECCTRA DSN "session" file.
Definition: specctra.cpp:268
void doLIBRARY(LIBRARY *growth)
Definition: specctra.cpp:2446
std::map< PCB_LAYER_ID, int > m_kicadLayer2pcb
maps BOARD layer number to PCB layer numbers
Definition: specctra.h:3994
void doVIA(VIA *growth)
Definition: specctra.cpp:1237
void doFROMTO(FROMTO *growth)
Definition: specctra.cpp:2864
void doPLACE(PLACE *growth)
Definition: specctra.cpp:1868
void doGRID(GRID *growth)
Definition: specctra.cpp:1766
void doLAYER_RULE(LAYER_RULE *growth)
Definition: specctra.cpp:1843
void doWIRE_VIA(WIRE_VIA *growth)
Definition: specctra.cpp:3091
void doCLASSES(CLASSES *growth)
Definition: specctra.cpp:1742
void readCOMPnPIN(std::string *component_id, std::string *pid_id)
Read a <pin_reference> and splits it into the two parts which are on either side of the hyphen.
Definition: specctra.cpp:111
std::string m_quote_char
Definition: specctra.h:3986
void doPARSER(PARSER *growth)
Definition: specctra.cpp:403
void doNETWORK(NETWORK *growth)
Definition: specctra.cpp:2802
void doNET(NET *growth)
Definition: specctra.cpp:2502
void doSTRUCTURE(STRUCTURE *growth)
Definition: specctra.cpp:645
int findLayerName(const std::string &aLayerName) const
Return the PCB layer index for a given layer name, within the specctra sessionfile.
Definition: specctra.cpp:99
void doROUTE(ROUTE *growth)
Definition: specctra.cpp:3494
void readTIME(time_t *time_stamp)
Read a <time_stamp> which consists of 8 lexer tokens: "month date hour : minute : second year".
Definition: specctra.cpp:153
void doPADSTACK(PADSTACK *growth)
Definition: specctra.cpp:2093
void doWIRING(WIRING *growth)
Definition: specctra.cpp:3206
void doHISTORY(HISTORY *growth)
Definition: specctra.cpp:3304
void doCONTROL(CONTROL *growth)
Definition: specctra.cpp:1268
void doPROPERTIES(PROPERTIES *growth)
Definition: specctra.cpp:1318
A container for a single property whose value is a string.
Definition: specctra.h:1399
std::string value
Definition: specctra.h:1418
RULE * m_place_rules
Definition: specctra.h:1677
UNIT_RES * m_unit
Definition: specctra.h:1658
KEEPOUTS m_keepouts
Definition: specctra.h:1670
BOUNDARY * m_boundary
Definition: specctra.h:1664
LAYER_NOISE_WEIGHT * m_layer_noise_weight
Definition: specctra.h:1662
COPPER_PLANES m_planes
Definition: specctra.h:1672
REGIONS m_regions
Definition: specctra.h:1675
BOUNDARY * m_place_boundary
Definition: specctra.h:1665
LAYERS m_layers
Definition: specctra.h:1660
CONTROL * m_control
Definition: specctra.h:1667
RULE * m_rules
Definition: specctra.h:1668
A <supply_pin_descriptor> in the specctra dsn spec.
Definition: specctra.h:3350
std::string net_id
Definition: specctra.h:3389
PIN_REFS pin_refs
Definition: specctra.h:3388
A container for a single property whose value is another DSN_T token.
Definition: specctra.h:1372
DSN_T value
Definition: specctra.h:1389
FROMTOS m_fromtos
Definition: specctra.h:2738
COMP_ORDERS m_comp_orders
Definition: specctra.h:2740
A holder for either a T_unit or T_resolution object which are usually mutually exclusive in the dsn g...
Definition: specctra.h:403
static UNIT_RES Default
A static instance which holds the default units of T_inch and 2540000.
Definition: specctra.h:410
DSN_T units
Definition: specctra.h:433
A <via_descriptor> in the specctra dsn spec.
Definition: specctra.h:1039
STRINGS m_spares
Definition: specctra.h:1097
STRINGS m_padstacks
Definition: specctra.h:1096
A <was_is_descriptor> in the specctra dsn spec.
Definition: specctra.h:3544
PIN_PAIRS pin_pairs
Definition: specctra.h:3566
ELEM * shape
Definition: specctra.h:893
A <wire_via_descriptor> in the specctra dsn spec.
Definition: specctra.h:2988
std::string m_net_id
Definition: specctra.h:3119
std::string m_padstack_id
Definition: specctra.h:3117
int m_via_number
Definition: specctra.h:3120
DSN_T m_via_type
Definition: specctra.h:3121
std::string m_virtual_pin_name
Definition: specctra.h:3123
STRINGS m_contact_layers
Definition: specctra.h:3124
DSN_T m_attr
Definition: specctra.h:3122
POINTS m_vertexes
Definition: specctra.h:3118
A <wire_shape_descriptor> in the specctra dsn spec.
Definition: specctra.h:2879
CONNECT * m_connect
Definition: specctra.h:2977
DSN_T m_wire_type
Definition: specctra.h:2973
ELEM * m_shape
Definition: specctra.h:2969
bool m_supply
Definition: specctra.h:2978
WINDOWS m_windows
Definition: specctra.h:2976
int m_turret
Definition: specctra.h:2972
std::string m_net_id
Definition: specctra.h:2971
std::string m_shield
Definition: specctra.h:2975
DSN_T m_attr
Definition: specctra.h:2974
A <wiring_descriptor> in the specctra dsn spec.
Definition: specctra.h:3135
UNIT_RES * unit
Definition: specctra.h:3171
WIRES wires
Definition: specctra.h:3172
WIRE_VIAS wire_vias
Definition: specctra.h:3173
A LINE_READER that reads from an open file.
Definition: richio.h:185
Used for text file output.
Definition: richio.h:491
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:247
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:564
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:322
int PRINTF_FUNC_N Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:460
static const char * GetQuoteChar(const char *wrapee, const char *quote_char)
Perform quote character need determination according to the Specctra DSN specification.
Definition: richio.cpp:382
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:449
static bool empty(const wxTextEntryBase *aCtrl)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
This source file implements export and import capabilities to the specctra dsn file format.
Definition: specctra.cpp:63
std::vector< PIN_REF > PIN_REFS
Definition: specctra.h:2479
const char * GetTokenText(T aTok)
The DSN namespace and returns the C string representing a SPECCTRA_DB::keyword.
Definition: specctra.cpp:70
std::vector< PROPERTY > PROPERTIES
Definition: specctra.h:192
@ VIA
Normal via.
Definition: router_tool.cpp:96
@ NET
This item represents a net.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:398
Used within the WAS_IS class below to hold a pair of PIN_REFs and corresponds to the (pins was is) co...
Definition: specctra.h:3526
PIN_REF is
Definition: specctra.h:3534
PIN_REF was
Definition: specctra.h:3533
A <pin_reference> definition in the specctra dsn spec.
Definition: specctra.h:2450
std::string pin_id
Definition: specctra.h:2476
std::string component_id
Definition: specctra.h:2475
A point in the SPECCTRA DSN coordinate system.
Definition: specctra.h:103
double y
Definition: specctra.h:105
double x
Definition: specctra.h:104