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