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