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