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