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 case T_poly: // Allegro Specctra abbreviation of polygon
901 if( tok == T_poly )
902 tok = T_polygon;
903
904 if( growth->m_shape )
905 Unexpected( tok );
906
907 growth->m_shape = new PATH( growth, tok );
908 doPATH( (PATH*) growth->m_shape );
909 break;
910
911 case T_qarc:
912 if( growth->m_shape )
913 Unexpected( tok );
914
915 growth->m_shape = new QARC( growth );
916 doQARC( (QARC*) growth->m_shape );
917 break;
918
919 case T_window:
920 WINDOW* window;
921 window = new WINDOW( growth );
922 growth->m_windows.push_back( window );
923 doWINDOW( window );
924 break;
925
926 default:
927 Unexpected( CurText() );
928 }
929
930 tok = NextTok();
931 }
932}
933
934
936{
937 /* from page 143 of specctra spec:
938
939 (connect
940 {(terminal <object_type> [<pin_reference> ])}
941 )
942 */
943
944 T tok = NextTok();
945
946 while( tok != T_RIGHT )
947 {
948 if( tok!=T_LEFT )
949 Expecting( T_LEFT );
950
951 tok = NextTok();
952
953 switch( tok )
954 {
955 case T_terminal:
956 // since we do not use the terminal information, simply toss it.
957 while( ( tok = NextTok() ) != T_RIGHT && tok != T_EOF )
958 ;
959 break;
960
961 default:
962 Unexpected( CurText() );
963 }
964
965 tok = NextTok();
966 }
967}
968
969
971{
972 T tok = NextTok();
973
974 while( tok != T_RIGHT )
975 {
976 if( tok!=T_LEFT )
977 Expecting( T_LEFT );
978
979 tok = NextTok();
980
981 switch( tok )
982 {
983 case T_rect:
984 if( growth->shape )
985 Unexpected( tok );
986
987 growth->shape = new RECTANGLE( growth );
988 doRECTANGLE( (RECTANGLE*) growth->shape );
989 break;
990
991 case T_circle:
992 if( growth->shape )
993 Unexpected( tok );
994
995 growth->shape = new CIRCLE( growth );
996 doCIRCLE( (CIRCLE*) growth->shape );
997 break;
998
999 case T_polyline_path:
1000 tok = T_path;
1002
1003 case T_path:
1004 case T_polygon:
1005 case T_poly: // Allegro Specctra abbreviation of polygon
1006 if( tok == T_poly )
1007 tok = T_polygon;
1008
1009 if( growth->shape )
1010 Unexpected( tok );
1011
1012 growth->shape = new PATH( growth, tok );
1013 doPATH( (PATH*) growth->shape );
1014 break;
1015
1016 case T_qarc:
1017 if( growth->shape )
1018 Unexpected( tok );
1019
1020 growth->shape = new QARC( growth );
1021 doQARC( (QARC*) growth->shape );
1022 break;
1023
1024 default:
1025 Unexpected( CurText() );
1026 }
1027
1028 tok = NextTok();
1029 }
1030}
1031
1032
1034{
1035 T tok = NextTok();
1036
1037 if( tok != T_LEFT )
1038 Expecting( T_LEFT );
1039
1040 tok = NextTok();
1041
1042 if( tok == T_rect )
1043 {
1044 if( growth->paths.size() )
1045 Unexpected( "rect when path already encountered" );
1046
1047 growth->rectangle = new RECTANGLE( growth );
1048 doRECTANGLE( growth->rectangle );
1049 NeedRIGHT();
1050 }
1051 else if( tok == T_path )
1052 {
1053 if( growth->rectangle )
1054 Unexpected( "path when rect already encountered" );
1055
1056 for(;;)
1057 {
1058 if( tok != T_path )
1059 Expecting( T_path );
1060
1061 PATH* path = new PATH( growth, T_path );
1062 growth->paths.push_back( path );
1063
1064 doPATH( path );
1065
1066 tok = NextTok();
1067 if( tok == T_RIGHT )
1068 break;
1069
1070 if( tok != T_LEFT )
1071 Expecting(T_LEFT);
1072
1073 tok = NextTok();
1074 }
1075 }
1076 else
1077 {
1078 Expecting( "rect|path" );
1079 }
1080}
1081
1082
1084{
1085 T tok = NextTok();
1086
1087 if( !IsSymbol( tok ) && tok != T_NUMBER ) // a layer name can be like a number like +12
1088 Expecting( "layer_id" );
1089
1090 growth->layer_id = CurText();
1091
1092 if( NextTok() != T_NUMBER )
1093 Expecting( "aperture_width" );
1094
1095 growth->aperture_width = parseDouble();
1096
1097 POINT ptTemp;
1098
1099 tok = NextTok();
1100
1101 do
1102 {
1103 if( tok != T_NUMBER )
1104 Expecting( T_NUMBER );
1105
1106 ptTemp.x = parseDouble();
1107
1108 if( NextTok() != T_NUMBER )
1109 Expecting( T_NUMBER );
1110
1111 ptTemp.y = parseDouble();
1112
1113 growth->points.push_back( ptTemp );
1114
1115 } while( ( tok = NextTok() ) != T_RIGHT && tok != T_LEFT );
1116
1117 if( tok == T_LEFT )
1118 {
1119 if( NextTok() != T_aperture_type )
1120 Expecting( T_aperture_type );
1121
1122 tok = NextTok();
1123
1124 if( tok!=T_round && tok!=T_square )
1125 Expecting( "round|square" );
1126
1127 growth->aperture_type = tok;
1128
1129 NeedRIGHT();
1130 }
1131}
1132
1133
1135{
1136 NeedSYMBOL();
1137 growth->layer_id = CurText();
1138
1139 if( NextTok() != T_NUMBER )
1140 Expecting( T_NUMBER );
1141
1142 growth->point0.x = parseDouble();
1143
1144 if( NextTok() != T_NUMBER )
1145 Expecting( T_NUMBER );
1146
1147 growth->point0.y = parseDouble();
1148
1149 if( NextTok() != T_NUMBER )
1150 Expecting( T_NUMBER );
1151
1152 growth->point1.x = parseDouble();
1153
1154 if( NextTok() != T_NUMBER )
1155 Expecting( T_NUMBER );
1156
1157 growth->point1.y = parseDouble();
1158
1159 NeedRIGHT();
1160}
1161
1162
1164{
1165 T tok;
1166
1167 NeedSYMBOLorNUMBER();
1168 growth->layer_id = CurText();
1169
1170 if( NextTok() != T_NUMBER )
1171 Expecting( T_NUMBER );
1172
1173 growth->diameter = parseDouble();
1174
1175 tok = NextTok();
1176
1177 if( tok == T_NUMBER )
1178 {
1179 growth->vertex.x = parseDouble();
1180
1181 if( NextTok() != T_NUMBER )
1182 Expecting( T_NUMBER );
1183
1184 growth->vertex.y = parseDouble();
1185
1186 tok = NextTok();
1187 }
1188
1189 if( tok != T_RIGHT )
1190 Expecting( T_RIGHT );
1191}
1192
1193
1195{
1196 NeedSYMBOL();
1197 growth->layer_id = CurText();
1198
1199 if( NextTok() != T_NUMBER )
1200 Expecting( T_NUMBER );
1201
1202 growth->aperture_width = parseDouble();
1203
1204 for( int i = 0; i < 3; ++i )
1205 {
1206 if( NextTok() != T_NUMBER )
1207 Expecting( T_NUMBER );
1208
1209 growth->vertex[i].x = parseDouble();
1210
1211 if( NextTok() != T_NUMBER )
1212 Expecting( T_NUMBER );
1213
1214 growth->vertex[i].y = parseDouble();
1215 }
1216
1217 NeedRIGHT();
1218}
1219
1220
1222{
1223 NeedSYMBOL();
1224 growth->value = CurText();
1225 NeedRIGHT();
1226}
1227
1228
1230{
1231 T tok = NextTok();
1232
1233 if( tok<0 )
1234 Unexpected( CurText() );
1235
1236 growth->value = tok;
1237
1238 NeedRIGHT();
1239}
1240
1241
1243{
1244 T tok;
1245
1246 while( ( tok = NextTok() ) != T_RIGHT )
1247 {
1248 if( tok == T_LEFT )
1249 {
1250 if( NextTok() != T_spare )
1251 Expecting( T_spare );
1252
1253 while( (tok = NextTok()) != T_RIGHT )
1254 {
1255 if( !IsSymbol( tok ) )
1256 Expecting( T_SYMBOL );
1257
1258 growth->m_spares.push_back( CurText() );
1259 }
1260 }
1261 else if( IsSymbol( tok ) )
1262 {
1263 growth->m_padstacks.push_back( CurText() );
1264 }
1265 else
1266 {
1267 Unexpected( CurText() );
1268 }
1269 }
1270}
1271
1272
1274{
1275 T tok;
1276
1277 while( (tok = NextTok()) != T_RIGHT )
1278 {
1279 if( tok != T_LEFT )
1280 Expecting( T_LEFT );
1281
1282 tok = NextTok();
1283
1284 switch( tok )
1285 {
1286 case T_via_at_smd:
1287 tok = NextTok();
1288
1289 if( tok!=T_on && tok!=T_off )
1290 Expecting( "on|off" );
1291
1292 growth->via_at_smd = (tok==T_on);
1293 NeedRIGHT();
1294 break;
1295
1296 case T_off_grid:
1297 case T_route_to_fanout_only:
1298 case T_force_to_terminal_point:
1299 case T_same_net_checking:
1300 case T_checking_trim_by_pin:
1301 case T_noise_calculation:
1302 case T_noise_accumulation:
1303 case T_include_pins_in_crosstalk:
1304 case T_bbv_ctr2ctr:
1305 case T_average_pair_length:
1306 case T_crosstalk_model:
1307 case T_roundoff_rotation:
1308 case T_microvia:
1309 case T_reroute_order_viols:
1310 TOKPROP* tokprop;
1311 tokprop = new TOKPROP( growth, tok );
1312 growth->Append( tokprop );
1313 doTOKPROP( tokprop );
1314 break;
1315
1316 default:
1317 Unexpected( CurText() );
1318 }
1319 }
1320}
1321
1322
1324{
1325 T tok;
1326 PROPERTY property; // construct it once here, append multiple times.
1327
1328 while( ( tok = NextTok() ) != T_RIGHT )
1329 {
1330 if( tok != T_LEFT )
1331 Expecting( T_LEFT );
1332
1333 NeedSYMBOLorNUMBER();
1334 property.name = CurText();
1335
1336 NeedSYMBOLorNUMBER();
1337 property.value = CurText();
1338
1339 growth->push_back( property );
1340
1341 NeedRIGHT();
1342 }
1343}
1344
1345
1347{
1348 T tok = NextTok();
1349
1350 if( !IsSymbol( tok ) )
1351 Expecting( T_SYMBOL );
1352
1353 growth->name = CurText();
1354
1355 while( ( tok = NextTok() ) != T_RIGHT )
1356 {
1357 if( tok != T_LEFT )
1358 Expecting( T_LEFT );
1359
1360 tok = NextTok();
1361
1362 switch( tok )
1363 {
1364 case T_type:
1365 tok = NextTok();
1366
1367 if( tok != T_signal && tok != T_power && tok != T_mixed && tok != T_jumper )
1368 Expecting( "signal|power|mixed|jumper" );
1369
1370 growth->layer_type = tok;
1371
1372 if( NextTok()!=T_RIGHT )
1373 Expecting(T_RIGHT);
1374
1375 break;
1376
1377 case T_rule:
1378 growth->rules = new RULE( growth, T_rule );
1379 doRULE( growth->rules );
1380 break;
1381
1382 case T_property:
1383 doPROPERTIES( &growth->properties );
1384 break;
1385
1386 case T_direction:
1387 tok = NextTok();
1388
1389 switch( tok )
1390 {
1391 case T_horizontal:
1392 case T_vertical:
1393 case T_orthogonal:
1394 case T_positive_diagonal:
1395 case T_negative_diagonal:
1396 case T_diagonal:
1397 case T_off:
1398 growth->direction = tok;
1399 break;
1400 default:
1401 // the spec has an example show an abbreviation of the "horizontal" keyword. Ouch.
1402 if( !strcmp( "hori", CurText() ) )
1403 {
1404 growth->direction = T_horizontal;
1405 break;
1406 }
1407 else if( !strcmp( "vert", CurText() ) )
1408 {
1409 growth->direction = T_vertical;
1410 break;
1411 }
1412
1413 Expecting( "horizontal|vertical|orthogonal|positive_diagonal|negative_diagonal|"
1414 "diagonal|off" );
1415 }
1416
1417 if( NextTok() != T_RIGHT )
1418 Expecting( T_RIGHT );
1419
1420 break;
1421
1422 case T_cost:
1423 tok = NextTok();
1424
1425 switch( tok )
1426 {
1427 case T_forbidden:
1428 case T_high:
1429 case T_medium:
1430 case T_low:
1431 case T_free:
1432 growth->cost = tok;
1433 break;
1434 case T_NUMBER:
1435 // store as negative so we can differentiate between
1436 // T (positive) and T_NUMBER (negative)
1437 growth->cost = -atoi( CurText() );
1438 break;
1439 default:
1440 Expecting( "forbidden|high|medium|low|free|<positive_integer>|-1" );
1441 }
1442
1443 tok = NextTok();
1444
1445 if( tok == T_LEFT )
1446 {
1447 if( NextTok() != T_type )
1448 Unexpected( CurText() );
1449
1450 tok = NextTok();
1451
1452 if( tok!=T_length && tok!=T_way )
1453 Expecting( "length|way" );
1454
1455 growth->cost_type = tok;
1456
1457 if( NextTok()!=T_RIGHT )
1458 Expecting( T_RIGHT );
1459
1460 tok = NextTok();
1461 }
1462
1463 if( tok != T_RIGHT )
1464 Expecting( T_RIGHT );
1465
1466 break;
1467
1468 case T_use_net:
1469 while( ( tok = NextTok() ) != T_RIGHT )
1470 {
1471 if( !IsSymbol( tok ) )
1472 Expecting( T_SYMBOL );
1473
1474 growth->use_net.push_back( CurText() );
1475 }
1476
1477 break;
1478
1479 default:
1480 Unexpected( CurText() );
1481 }
1482 }
1483}
1484
1485
1487{
1488 std::string builder;
1489 int bracketNesting = 1; // we already saw the opening T_LEFT
1490 T tok = T_NONE;
1491
1492 while( bracketNesting != 0 && tok != T_EOF )
1493 {
1494 tok = NextTok();
1495
1496 if( tok==T_LEFT)
1497 ++bracketNesting;
1498 else if( tok==T_RIGHT )
1499 --bracketNesting;
1500
1501 if( bracketNesting >= 1 )
1502 {
1503 if( PrevTok() != T_LEFT && tok != T_RIGHT && ( tok != T_LEFT || bracketNesting > 2 ) )
1504 builder += ' ';
1505
1506 if( tok == T_STRING )
1507 builder += m_quote_char;
1508
1509 builder += CurText();
1510
1511 if( tok == T_STRING )
1512 builder += m_quote_char;
1513 }
1514
1515 // When the nested rule is closed with a T_RIGHT and we are back down
1516 // to bracketNesting == 1, (inside the <rule_descriptor> but outside
1517 // the last rule). Then save the last rule and clear the string builder.
1518 if( bracketNesting == 1 )
1519 {
1520 growth->m_rules.push_back( builder );
1521 builder.clear();
1522 }
1523 }
1524
1525 if( tok==T_EOF )
1526 Unexpected( T_EOF );
1527}
1528
1529
1530#if 0
1531void SPECCTRA_DB::doPLACE_RULE( PLACE_RULE* growth, bool expect_object_type )
1532{
1533 /* (place_rule [<structure_place_rule_object> ]
1534 {[<spacing_descriptor> |
1535 <permit_orient_descriptor> |
1536 <permit_side_descriptor> |
1537 <opposite_side_descriptor> ]}
1538 )
1539 */
1540
1541 T tok = NextTok();
1542
1543 if( tok != T_LEFT )
1544 Expecting( T_LEFT );
1545
1546 tok = NextTok();
1547
1548 if( tok == T_object_type )
1549 {
1550 if( !expect_object_type )
1551 Unexpected( tok );
1552
1553 /* [(object_type
1554 [pcb |
1555 image_set [large | small | discrete | capacitor | resistor]
1556 [(image_type [smd | pin])]]
1557 )]
1558 */
1559
1560 tok = NextTok();
1561
1562 switch( tok )
1563 {
1564 case T_pcb:
1565 growth->object_type = tok;
1566 break;
1567
1568 case T_image_set:
1569 tok = NextTok();
1570
1571 switch( tok )
1572 {
1573 case T_large:
1574 case T_small:
1575 case T_discrete:
1576 case T_capacitor:
1577 case T_resistor:
1578 growth->object_type = tok;
1579 break;
1580 default:
1581 Unexpected( CurText() );
1582 }
1583
1584 break;
1585
1586 default:
1587 Unexpected( CurText() );
1588 }
1589
1590 tok = NextTok();
1591
1592 if( tok == T_LEFT )
1593 {
1594 tok = NextTok();
1595
1596 if( tok != T_image_type )
1597 Expecting( T_image_type );
1598
1599 tok = NextTok();
1600
1601 if( tok!=T_smd && tok!=T_pin )
1602 Expecting( "smd|pin" );
1603
1604 NeedRIGHT();
1605
1606 tok = NextTok();
1607 }
1608
1609 if( tok != T_RIGHT )
1610 Expecting( T_RIGHT );
1611
1612 tok = NextTok();
1613 }
1614
1615 /* {[<spacing_descriptor> |
1616 <permit_orient_descriptor> |
1617 <permit_side_descriptor> | <opposite_side_descriptor> ]}
1618 */
1619 doRULE( growth );
1620}
1621#endif
1622
1623
1625{
1626 T tok = NextTok();
1627
1628 if( IsSymbol( tok ) )
1629 {
1630 growth->m_region_id = CurText();
1631 tok = NextTok();
1632 }
1633
1634 for(;;)
1635 {
1636 if( tok != T_LEFT )
1637 Expecting( T_LEFT );
1638
1639 tok = NextTok();
1640
1641 switch( tok )
1642 {
1643 case T_rect:
1644 if( growth->m_rectangle )
1645 Unexpected( tok );
1646
1647 growth->m_rectangle = new RECTANGLE( growth );
1648 doRECTANGLE( growth->m_rectangle );
1649 break;
1650
1651 case T_polygon:
1652 case T_poly: // Allegro Specctra abbreviation of polygon
1653 if( growth->m_polygon )
1654 Unexpected( tok );
1655
1656 growth->m_polygon = new PATH( growth, T_polygon );
1657 doPATH( growth->m_polygon );
1658 break;
1659
1660 case T_region_net:
1661 case T_region_class:
1662 STRINGPROP* stringprop;
1663 stringprop = new STRINGPROP( growth, tok );
1664 growth->Append( stringprop );
1665 doSTRINGPROP( stringprop );
1666 break;
1667
1668 case T_region_class_class:
1669 CLASS_CLASS* class_class;
1670 class_class = new CLASS_CLASS( growth, tok );
1671 growth->Append( class_class );
1672 doCLASS_CLASS( class_class );
1673 break;
1674
1675 case T_rule:
1676 if( growth->m_rules )
1677 Unexpected( tok );
1678
1679 growth->m_rules = new RULE( growth, T_rule );
1680 doRULE( growth->m_rules );
1681 break;
1682
1683 default:
1684 Unexpected( CurText() );
1685 }
1686
1687 tok = NextTok();
1688
1689 if( tok == T_RIGHT )
1690 {
1691 if( !growth->m_rules )
1692 Expecting( T_rule );
1693
1694 break;
1695 }
1696 }
1697}
1698
1699
1701{
1702 T tok = NextTok();
1703
1704 if( tok != T_LEFT )
1705 Expecting( T_LEFT );
1706
1707 while( ( tok = NextTok() ) != T_RIGHT )
1708 {
1709 switch( tok )
1710 {
1711 case T_classes:
1712 if( growth->classes )
1713 Unexpected( tok );
1714
1715 growth->classes = new CLASSES( growth );
1716 doCLASSES( growth->classes );
1717 break;
1718
1719 case T_rule:
1720 // only T_class_class takes a T_rule
1721 if( growth->Type() == T_region_class_class )
1722 Unexpected( tok );
1723
1724 RULE* rule;
1725 rule = new RULE( growth, T_rule );
1726 growth->Append( rule );
1727 doRULE( rule );
1728 break;
1729
1730 case T_layer_rule:
1731 // only T_class_class takes a T_layer_rule
1732 if( growth->Type() == T_region_class_class )
1733 Unexpected( tok );
1734
1735 LAYER_RULE* layer_rule;
1736 layer_rule = new LAYER_RULE( growth );
1737 growth->Append( layer_rule );
1738 doLAYER_RULE( layer_rule );
1739 break;
1740
1741 default:
1742 Unexpected( tok );
1743 }
1744 }
1745}
1746
1747
1749{
1750 T tok = NextTok();
1751
1752 // require at least 2 class_ids
1753
1754 if( !IsSymbol( tok ) )
1755 Expecting( "class_id" );
1756
1757 growth->class_ids.push_back( CurText() );
1758
1759 do
1760 {
1761 tok = NextTok();
1762
1763 if( !IsSymbol( tok ) )
1764 Expecting( "class_id" );
1765
1766 growth->class_ids.push_back( CurText() );
1767
1768 } while( ( tok = NextTok() ) != T_RIGHT );
1769}
1770
1771
1773{
1774 T tok = NextTok();
1775
1776 switch( tok )
1777 {
1778 case T_via:
1779 case T_wire:
1780 case T_via_keepout:
1781 case T_snap:
1782 case T_place:
1783 growth->m_grid_type = tok;
1784
1785 if( NextTok() != T_NUMBER )
1786 Expecting( T_NUMBER );
1787
1788 growth->m_dimension = parseDouble();
1789 tok = NextTok();
1790
1791 if( tok == T_LEFT )
1792 {
1793 while( ( tok = NextTok() ) != T_RIGHT )
1794 {
1795 if( tok == T_direction )
1796 {
1797 if( growth->m_grid_type == T_place )
1798 Unexpected( tok );
1799
1800 tok = NextTok();
1801
1802 if( tok != T_x && tok != T_y )
1803 Unexpected( CurText() );
1804
1805 growth->m_direction = tok;
1806
1807 if( NextTok() != T_RIGHT )
1808 Expecting(T_RIGHT);
1809 }
1810 else if( tok == T_offset )
1811 {
1812 if( growth->m_grid_type == T_place )
1813 Unexpected( tok );
1814
1815 if( NextTok() != T_NUMBER )
1816 Expecting( T_NUMBER );
1817
1818 growth->m_offset = parseDouble();
1819
1820 if( NextTok() != T_RIGHT )
1821 Expecting( T_RIGHT );
1822 }
1823 else if( tok == T_image_type )
1824 {
1825 if( growth->m_grid_type != T_place )
1826 Unexpected( tok );
1827
1828 tok = NextTok();
1829
1830 if( tok != T_smd && tok != T_pin )
1831 Unexpected( CurText() );
1832
1833 growth->m_image_type = tok;
1834
1835 if( NextTok() != T_RIGHT )
1836 Expecting( T_RIGHT );
1837 }
1838 }
1839 }
1840
1841 break;
1842
1843 default:
1844 Unexpected( tok );
1845 }
1846}
1847
1848
1850{
1851 T tok;
1852
1853 NeedSYMBOL();
1854
1855 do
1856 {
1857 growth->m_layer_ids.push_back( CurText() );
1858
1859 } while( IsSymbol( tok = NextTok() ) );
1860
1861 if( tok != T_LEFT )
1862 Expecting( T_LEFT );
1863
1864 if( NextTok() != T_rule )
1865 Expecting( T_rule );
1866
1867 growth->m_rule = new RULE( growth, T_rule );
1868 doRULE( growth->m_rule );
1869
1870 NeedRIGHT();
1871}
1872
1873
1875{
1876 T tok = NextTok();
1877
1878 if( !IsSymbol( tok ) )
1879 Expecting( "component_id" );
1880
1881 growth->m_component_id = CurText();
1882
1883 tok = NextTok();
1884
1885 if( tok == T_NUMBER )
1886 {
1887 POINT point;
1888
1889 point.x = parseDouble();
1890
1891 if( NextTok() != T_NUMBER )
1892 Expecting( T_NUMBER );
1893
1894 point.y = parseDouble();
1895
1896 growth->SetVertex( point );
1897
1898 tok = NextTok();
1899
1900 if( tok != T_front && tok != T_back )
1901 Expecting( "front|back" );
1902
1903 growth->m_side = tok;
1904
1905 if( NextTok() != T_NUMBER )
1906 Expecting( "rotation" );
1907
1908 growth->SetRotation( parseDouble() );
1909 }
1910
1911 while( ( tok = NextTok() ) != T_RIGHT )
1912 {
1913 if( tok != T_LEFT )
1914 Expecting( T_LEFT );
1915
1916 tok = NextTok();
1917
1918 switch( tok )
1919 {
1920 case T_mirror:
1921 tok = NextTok();
1922
1923 if( tok == T_x || tok == T_y || tok == T_xy || tok == T_off )
1924 growth->m_mirror = tok;
1925 else
1926 Expecting( "x|y|xy|off" );
1927
1928 break;
1929
1930 case T_status:
1931 tok = NextTok();
1932
1933 if( tok==T_added || tok==T_deleted || tok==T_substituted )
1934 growth->m_status = tok;
1935 else
1936 Expecting("added|deleted|substituted");
1937
1938 break;
1939
1940 case T_logical_part:
1941 if( growth->m_logical_part.size() )
1942 Unexpected( tok );
1943
1944 tok = NextTok();
1945
1946 if( !IsSymbol( tok ) )
1947 Expecting( "logical_part_id");
1948
1949 growth->m_logical_part = CurText();
1950 break;
1951
1952 case T_place_rule:
1953 if( growth->m_place_rules )
1954 Unexpected( tok );
1955
1956 growth->m_place_rules = new RULE( growth, T_place_rule );
1957 doRULE( growth->m_place_rules );
1958 break;
1959
1960 case T_property:
1961 if( growth->m_properties.size() )
1962 Unexpected( tok );
1963
1964 doPROPERTIES( &growth->m_properties );
1965 break;
1966
1967 case T_lock_type:
1968 tok = NextTok();
1969
1970 if( tok == T_position || tok == T_gate || tok == T_subgate || tok == T_pin )
1971 growth->m_lock_type = tok;
1972 else
1973 Expecting( "position|gate|subgate|pin" );
1974
1975 break;
1976
1977 case T_rule:
1978 if( growth->m_rules || growth->m_region )
1979 Unexpected( tok );
1980
1981 growth->m_rules = new RULE( growth, T_rule );
1982 doRULE( growth->m_rules );
1983 break;
1984
1985 case T_region:
1986 if( growth->m_rules || growth->m_region )
1987 Unexpected( tok );
1988
1989 growth->m_region = new REGION( growth );
1990 doREGION( growth->m_region );
1991 break;
1992
1993 case T_pn:
1994 if( growth->m_part_number.size() )
1995 Unexpected( tok );
1996
1997 NeedSYMBOLorNUMBER();
1998 growth->m_part_number = CurText();
1999 NeedRIGHT();
2000 break;
2001
2002 default:
2003 Unexpected( tok );
2004 }
2005 }
2006}
2007
2008
2010{
2011 T tok = NextTok();
2012
2013 if( !IsSymbol( tok ) && tok != T_NUMBER )
2014 Expecting( "image_id" );
2015
2016 growth->m_image_id = CurText();
2017
2018 while( ( tok = NextTok() ) != T_RIGHT )
2019 {
2020 if( tok != T_LEFT )
2021 Expecting( T_LEFT );
2022
2023 tok = NextTok();
2024
2025 switch( tok )
2026 {
2027 case T_place:
2028 PLACE* place;
2029 place = new PLACE( growth );
2030 growth->m_places.push_back( place );
2031 doPLACE( place );
2032 break;
2033
2034 default:
2035 Unexpected( tok );
2036 }
2037 }
2038}
2039
2040
2042{
2043 T tok;
2044
2045 while( ( tok = NextTok() ) != T_RIGHT )
2046 {
2047 if( tok == T_EOF )
2048 Unexpected( T_EOF );
2049
2050 if( tok != T_LEFT )
2051 Expecting( T_LEFT );
2052
2053 tok = NextTok();
2054
2055 switch( tok )
2056 {
2057 case T_unit:
2058 case T_resolution:
2059 growth->m_unit = new UNIT_RES( growth, tok );
2060
2061 if( tok == T_resolution )
2062 doRESOLUTION( growth->m_unit );
2063 else
2064 doUNIT( growth->m_unit );
2065 break;
2066
2067 case T_place_control:
2068 NeedRIGHT();
2069 tok = NextTok();
2070
2071 if( tok != T_flip_style )
2072 Expecting( T_flip_style );
2073
2074 tok = NextTok();
2075
2076 if( tok == T_mirror_first || tok == T_rotate_first )
2077 growth->m_flip_style = tok;
2078 else
2079 Expecting( "mirror_first|rotate_first" );
2080
2081 NeedRIGHT();
2082 NeedRIGHT();
2083 break;
2084
2085 case T_component:
2086 COMPONENT* component;
2087 component = new COMPONENT( growth );
2088 growth->m_components.push_back( component );
2089 doCOMPONENT( component );
2090 break;
2091
2092 default:
2093 Unexpected( tok );
2094 }
2095 }
2096}
2097
2098
2100{
2101 T tok = NextTok();
2102
2103 /* (padstack <m_padstack_id >
2104 [<unit_descriptor> ]
2105 {(shape <shape_descriptor>
2106 [<reduced_shape_descriptor> ]
2107 [(connect [on | off])]
2108 [{<window_descriptor> }]
2109 )}
2110 [<attach_descriptor> ]
2111 [{<pad_via_site_descriptor> }]
2112 [(rotate [on | off])]
2113 [(absolute [on | off])]
2114 [(rule <clearance_descriptor> )])
2115 */
2116
2117 // m_padstack_id may be a number
2118 if( !IsSymbol( tok ) && tok != T_NUMBER )
2119 Expecting( "m_padstack_id" );
2120
2121 growth->m_padstack_id = CurText();
2122
2123 while( ( tok = NextTok() ) != T_RIGHT )
2124 {
2125 if( tok != T_LEFT )
2126 Expecting( T_LEFT );
2127
2128 tok = NextTok();
2129
2130 switch( tok )
2131 {
2132 case T_unit:
2133 if( growth->m_unit )
2134 Unexpected( tok );
2135
2136 growth->m_unit = new UNIT_RES( growth, tok );
2137 doUNIT( growth->m_unit );
2138 break;
2139
2140 case T_rotate:
2141 tok = NextTok();
2142
2143 if( tok != T_on && tok != T_off )
2144 Expecting( "on|off" );
2145
2146 growth->m_rotate = tok;
2147 NeedRIGHT();
2148 break;
2149
2150 case T_absolute:
2151 tok = NextTok();
2152
2153 if( tok != T_on && tok != T_off )
2154 Expecting( "on|off" );
2155
2156 growth->m_absolute = tok;
2157 NeedRIGHT();
2158 break;
2159
2160 case T_shape:
2161 SHAPE* shape;
2162 shape = new SHAPE( growth );
2163 growth->Append( shape );
2164 doSHAPE( shape );
2165 break;
2166
2167 case T_attach:
2168 tok = NextTok();
2169
2170 if( tok != T_off && tok != T_on )
2171 Expecting( "off|on" );
2172
2173 growth->m_attach = tok;
2174 tok = NextTok();
2175
2176 if( tok == T_LEFT )
2177 {
2178 if( NextTok() != T_use_via )
2179 Expecting( T_use_via );
2180
2181 NeedSYMBOL();
2182 growth->m_via_id = CurText();
2183
2184 NeedRIGHT();
2185 NeedRIGHT();
2186 }
2187
2188 break;
2189
2190 /*
2191 case T_via_site: not supported
2192 break;
2193 */
2194
2195 case T_rule:
2196
2197 if( growth->m_rules )
2198 Unexpected( tok );
2199
2200 growth->m_rules = new RULE( growth, T_rule );
2201 doRULE( growth->m_rules );
2202 break;
2203
2204 default:
2205 Unexpected( CurText() );
2206 }
2207 }
2208}
2209
2210
2212{
2213 T tok;
2214
2215 /* (shape <shape_descriptor>
2216 [<reduced_shape_descriptor> ]
2217 [(connect [on | off])]
2218 [{<window_descriptor> }])
2219 */
2220
2221 while( ( tok = NextTok() ) != T_RIGHT )
2222 {
2223 if( tok != T_LEFT )
2224 Expecting( T_LEFT );
2225
2226 tok = NextTok();
2227
2228 switch( tok )
2229 {
2230 case T_polyline_path:
2231 tok = T_path;
2233
2234 case T_rect:
2235 case T_circle:
2236 case T_path:
2237 case T_polygon:
2238 case T_poly: // Allegro Specctra abbreviation of polygon
2239 case T_qarc:
2240L_done_that:
2241 if( growth->shape )
2242 Unexpected( tok );
2243
2244 break;
2245
2246 default:
2247 // the example in the spec uses "circ" instead of "circle". Bad!
2248 if( !strcmp( "circ", CurText() ) )
2249 {
2250 tok = T_circle;
2251 goto L_done_that;
2252 }
2253 }
2254
2255 switch( tok )
2256 {
2257 case T_rect:
2258 growth->shape = new RECTANGLE( growth );
2259 doRECTANGLE( (RECTANGLE*) growth->shape );
2260 break;
2261
2262 case T_circle:
2263 growth->shape = new CIRCLE( growth );
2264 doCIRCLE( (CIRCLE*)growth->shape );
2265 break;
2266
2267 case T_path:
2268 case T_polygon:
2269 case T_poly: // Allegro Specctra abbreviation of polygon
2270 if( tok == T_poly )
2271 tok = T_polygon;
2272
2273 growth->shape = new PATH( growth, tok );
2274 doPATH( (PATH*)growth->shape );
2275 break;
2276
2277 case T_qarc:
2278 growth->shape = new QARC( growth );
2279 doQARC( (QARC*)growth->shape );
2280 break;
2281
2282 case T_connect:
2283 tok = NextTok();
2284 if( tok!=T_on && tok!=T_off )
2285 Expecting( "on|off" );
2286 growth->m_connect = tok;
2287 NeedRIGHT();
2288 break;
2289
2290 case T_window:
2291 WINDOW* window;
2292 window = new WINDOW( growth );
2293 growth->m_windows.push_back( window );
2294 doWINDOW( window );
2295 break;
2296
2297 default:
2298 Unexpected( CurText() );
2299 }
2300 }
2301}
2302
2303
2305{
2306 T tok = NextTok();
2307
2308 /* <image_descriptor >::=
2309 (image <image_id >
2310 [(side [front | back | both])]
2311 [<unit_descriptor> ]
2312 [<outline_descriptor> ]
2313 {(pin <m_padstack_id > [(rotate <rotation> )]
2314 [<reference_descriptor> | <pin_array_descriptor> ]
2315 [<user_property_descriptor> ])}
2316 [{<conductor_shape_descriptor> }]
2317 [{<conductor_via_descriptor> }]
2318 [<rule_descriptor> ]
2319 [<place_rule_descriptor> ]
2320 [{<keepout_descriptor> }]
2321 [<image_property_descriptor> ]
2322 )
2323 */
2324
2325 if( !IsSymbol( tok ) && tok != T_NUMBER )
2326 Expecting( "image_id" );
2327
2328 growth->m_image_id = CurText();
2329
2330 while( ( tok = NextTok() ) != T_RIGHT )
2331 {
2332 if( tok != T_LEFT )
2333 Expecting( T_LEFT );
2334
2335 tok = NextTok();
2336
2337 switch( tok )
2338 {
2339 case T_unit:
2340 if( growth->m_unit )
2341 Unexpected( tok );
2342
2343 growth->m_unit = new UNIT_RES( growth, tok );
2344 doUNIT( growth->m_unit );
2345 break;
2346
2347 case T_side:
2348 tok = NextTok();
2349
2350 if( tok != T_front && tok != T_back && tok != T_both )
2351 Expecting( "front|back|both" );
2352
2353 growth->m_side = tok;
2354 NeedRIGHT();
2355 break;
2356
2357 case T_outline:
2358 SHAPE* outline;
2359 outline = new SHAPE( growth, T_outline ); // use SHAPE for T_outline
2360 growth->Append( outline );
2361 doSHAPE( outline );
2362 break;
2363
2364 case T_pin:
2365 PIN* pin;
2366 pin = new PIN( growth );
2367 growth->m_pins.push_back( pin );
2368 doPIN( pin );
2369 break;
2370
2371 case T_rule:
2372 if( growth->m_rules )
2373 Unexpected( tok );
2374
2375 growth->m_rules = new RULE( growth, tok );
2376 doRULE( growth->m_rules );
2377 break;
2378
2379 case T_place_rule:
2380 if( growth->m_place_rules )
2381 Unexpected( tok );
2382
2383 growth->m_place_rules = new RULE( growth, tok );
2384 doRULE( growth->m_place_rules );
2385 break;
2386
2387 case T_keepout:
2388 case T_place_keepout:
2389 case T_via_keepout:
2390 case T_wire_keepout:
2391 case T_bend_keepout:
2392 case T_elongate_keepout:
2393 KEEPOUT* keepout;
2394 keepout = new KEEPOUT( growth, tok );
2395 growth->m_keepouts.push_back( keepout );
2396 doKEEPOUT( keepout );
2397 break;
2398
2399 default:
2400 Unexpected( CurText() );
2401 }
2402 }
2403}
2404
2405
2407{
2408 T tok = NextTok();
2409
2410 /* (pin <m_padstack_id > [(rotate <rotation> )]
2411 [<reference_descriptor> | <pin_array_descriptor> ]
2412 [<user_property_descriptor> ])
2413 */
2414
2415 // a m_padstack_id may be a number
2416 if( !IsSymbol( tok ) && tok!=T_NUMBER )
2417 Expecting( "m_padstack_id" );
2418
2419 growth->m_padstack_id = CurText();
2420
2421 while( ( tok = NextTok() ) != T_RIGHT )
2422 {
2423 if( tok == T_LEFT )
2424 {
2425 tok = NextTok();
2426
2427 if( tok != T_rotate )
2428 Expecting( T_rotate );
2429
2430 if( NextTok() != T_NUMBER )
2431 Expecting( T_NUMBER );
2432
2433 growth->SetRotation( parseDouble() );
2434 NeedRIGHT();
2435 }
2436 else
2437 {
2438 if( !IsSymbol( tok ) && tok != T_NUMBER )
2439 Expecting( "pin_id" );
2440
2441 growth->m_pin_id = CurText();
2442
2443 if( NextTok() != T_NUMBER )
2444 Expecting( T_NUMBER );
2445
2446 growth->m_vertex.x = parseDouble();
2447
2448 if( NextTok() != T_NUMBER )
2449 Expecting( T_NUMBER );
2450
2451 growth->m_vertex.y = parseDouble();
2452 }
2453 }
2454}
2455
2456
2458{
2459 T tok;
2460
2461 /* <library_descriptor >::=
2462 (library
2463 [<unit_descriptor> ]
2464 {<image_descriptor> }
2465 [{<jumper_descriptor> }]
2466 {<padstack_descriptor> }
2467 {<via_array_template_descriptor> }
2468 [<directory_descriptor> ]
2469 [<extra_image_directory_descriptor> ]
2470 [{<family_family_descriptor> }]
2471 [{<image_image_descriptor> }]
2472 )
2473 */
2474
2475 while( ( tok = NextTok() ) != T_RIGHT )
2476 {
2477 if( tok != T_LEFT )
2478 Expecting( T_LEFT );
2479
2480 tok = NextTok();
2481
2482 switch( tok )
2483 {
2484 case T_unit:
2485 if( growth->m_unit )
2486 Unexpected( tok );
2487
2488 growth->m_unit = new UNIT_RES( growth, tok );
2489 doUNIT( growth->m_unit );
2490 break;
2491
2492 case T_padstack:
2493 PADSTACK* padstack;
2494 padstack = new PADSTACK();
2495 growth->AddPadstack( padstack );
2496 doPADSTACK( padstack );
2497 break;
2498
2499 case T_image:
2500 IMAGE* image;
2501 image = new IMAGE( growth );
2502 growth->m_images.push_back( image );
2503 doIMAGE( image );
2504 break;
2505
2506 default:
2507 Unexpected( CurText() );
2508 }
2509 }
2510}
2511
2512
2514{
2515 T tok = NextTok();
2516 std::vector<PIN_REF>* pin_refs;
2517
2518 /* <net_descriptor >::=
2519 (net <net_id >
2520 [(unassigned)]
2521 [(net_number <integer >)]
2522 [(pins {<pin_reference> }) | (order {<pin_reference> })]
2523 [<component_order_descriptor> ]
2524 [(type [fix | normal])]
2525 [<user_property_descriptor> ]
2526 [<circuit_descriptor> ]
2527 [<rule_descriptor> ]
2528 [{<layer_rule_descriptor> }]
2529 [<fromto_descriptor> ]
2530 [(expose {<pin_reference> })]
2531 [(noexpose {<pin_reference> })]
2532 [(source {<pin_reference> })]
2533 [(load {<pin_reference> })]
2534 [(terminator {<pin_reference> })]
2535 [(supply [power | ground])]
2536 )
2537 */
2538
2539 if( !IsSymbol( tok ) )
2540 Expecting( "net_id" );
2541
2542 growth->m_net_id = CurText();
2543
2544 while( ( tok = NextTok() ) != T_RIGHT )
2545 {
2546 if( tok != T_LEFT )
2547 Expecting( T_LEFT );
2548
2549 tok = NextTok();
2550
2551 switch( tok )
2552 {
2553 case T_unassigned:
2554 growth->m_unassigned = true;
2555 NeedRIGHT();
2556 break;
2557
2558 case T_net_number:
2559 if( NextTok() != T_NUMBER )
2560 Expecting( T_NUMBER );
2561
2562 growth->m_net_number = atoi( CurText() );
2563 NeedRIGHT();
2564 break;
2565
2566 case T_pins:
2567 case T_order:
2568 growth->m_pins_type = tok;
2569 pin_refs = &growth->m_pins;
2570 goto L_pins;
2571
2572 case T_expose:
2573 pin_refs = &growth->m_expose;
2574 goto L_pins;
2575
2576 case T_noexpose:
2577 pin_refs = &growth->m_noexpose;
2578 goto L_pins;
2579
2580 case T_source:
2581 pin_refs = &growth->m_source;
2582 goto L_pins;
2583
2584 case T_load:
2585 pin_refs = &growth->m_load;
2586 goto L_pins;
2587
2588 case T_terminator:
2589 pin_refs = &growth->m_terminator;
2590 //goto L_pins;
2591
2592L_pins:
2593 {
2594 PIN_REF empty( growth );
2595
2596 while( ( tok = NextTok() ) != T_RIGHT )
2597 {
2598 // copy the empty one, then fill its copy later thru pin_ref.
2599 pin_refs->push_back( empty );
2600
2601 PIN_REF* pin_ref = &pin_refs->back();
2602
2603 readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
2604 }
2605 }
2606
2607 break;
2608
2609 case T_comp_order:
2610 if( growth->m_comp_order )
2611 Unexpected( tok );
2612
2613 growth->m_comp_order = new COMP_ORDER( growth );
2614 doCOMP_ORDER( growth->m_comp_order );
2615 break;
2616
2617 case T_type:
2618 tok = NextTok();
2619
2620 if( tok!=T_fix && tok!=T_normal )
2621 Expecting( "fix|normal" );
2622
2623 growth->type = tok;
2624 NeedRIGHT();
2625 break;
2626
2627/* @todo
2628 case T_circuit:
2629 break;
2630*/
2631
2632 case T_rule:
2633 if( growth->m_rules )
2634 Unexpected( tok );
2635
2636 growth->m_rules = new RULE( growth, T_rule );
2637 doRULE( growth->m_rules );
2638 break;
2639
2640 case T_layer_rule:
2641 LAYER_RULE* layer_rule;
2642 layer_rule = new LAYER_RULE( growth );
2643 growth->m_layer_rules.push_back( layer_rule );
2644 doLAYER_RULE( layer_rule );
2645 break;
2646
2647 case T_fromto:
2648 FROMTO* fromto;
2649 fromto = new FROMTO( growth );
2650 growth->m_fromtos.push_back( fromto );
2651 doFROMTO( fromto );
2652 break;
2653
2654 default:
2655 Unexpected( CurText() );
2656 }
2657 }
2658}
2659
2660
2662{
2663 T tok;
2664
2665 /* <topology_descriptor >::=
2666 (topology {[<fromto_descriptor> |
2667 <component_order_descriptor> ]})
2668 */
2669
2670 while( ( tok = NextTok() ) != T_RIGHT )
2671 {
2672 if( tok != T_LEFT )
2673 Expecting( T_LEFT );
2674
2675 tok = NextTok();
2676
2677 switch( tok )
2678 {
2679 case T_fromto:
2680 FROMTO* fromto;
2681 fromto = new FROMTO( growth );
2682 growth->m_fromtos.push_back( fromto );
2683 doFROMTO( fromto );
2684 break;
2685
2686 case T_comp_order:
2687 COMP_ORDER* comp_order;
2688 comp_order = new COMP_ORDER( growth );
2689 growth->m_comp_orders.push_back( comp_order );
2690 doCOMP_ORDER( comp_order );
2691 break;
2692
2693 default:
2694 Unexpected( CurText() );
2695 }
2696 }
2697}
2698
2699
2701{
2702 T tok;
2703
2704 /* <class_descriptor >::=
2705 (class
2706 <class_id > {[{<net_id >} | {<composite_name_list> }]}
2707 [<circuit_descriptor> ]
2708 [<rule_descriptor> ]
2709 [{<layer_rule_descriptor> }]
2710 [<topology_descriptor> ]
2711 )
2712 */
2713
2714 NeedSYMBOL();
2715
2716 growth->m_class_id = CurText();
2717
2718 // do net_ids, do not support <composite_name_list>s at this time
2719 while( IsSymbol( tok = NextTok() ) )
2720 {
2721 growth->m_net_ids.push_back( CurText() );
2722 }
2723
2724
2725 while( tok != T_RIGHT )
2726 {
2727 if( tok != T_LEFT )
2728 Expecting( T_LEFT );
2729
2730 tok = NextTok();
2731
2732 switch( tok )
2733 {
2734 case T_rule:
2735 if( growth->m_rules )
2736 Unexpected( tok );
2737
2738 growth->m_rules = new RULE( growth, T_rule );
2739 doRULE( growth->m_rules );
2740 break;
2741
2742 case T_layer_rule:
2743 LAYER_RULE* layer_rule;
2744 layer_rule = new LAYER_RULE( growth );
2745 growth->m_layer_rules.push_back( layer_rule );
2746 doLAYER_RULE( layer_rule );
2747 break;
2748
2749 case T_topology:
2750 if( growth->m_topology )
2751 Unexpected( tok );
2752
2753 growth->m_topology = new TOPOLOGY( growth );
2754 doTOPOLOGY( growth->m_topology );
2755 break;
2756
2757 case T_circuit: // handle all the circuit_descriptor here as strings
2758 {
2759 std::string builder;
2760 int bracketNesting = 1; // we already saw the opening T_LEFT
2761 tok = T_NONE;
2762
2763 while( bracketNesting != 0 && tok != T_EOF )
2764 {
2765 tok = NextTok();
2766
2767 if( tok == T_LEFT )
2768 ++bracketNesting;
2769 else if( tok == T_RIGHT )
2770 --bracketNesting;
2771
2772 if( bracketNesting >= 1 )
2773 {
2774 T previousTok = (T) PrevTok();
2775
2776 if( previousTok != T_LEFT && previousTok != T_circuit && tok != T_RIGHT )
2777 builder += ' ';
2778
2779 if( tok == T_STRING )
2780 builder += m_quote_char;
2781
2782 builder += CurText();
2783
2784 if( tok == T_STRING )
2785 builder += m_quote_char;
2786 }
2787
2788 // When the nested rule is closed with a T_RIGHT and we are back down
2789 // to bracketNesting == 0, then save the builder and break;
2790 if( bracketNesting == 0 )
2791 {
2792 growth->m_circuit.push_back( builder );
2793 break;
2794 }
2795 }
2796
2797 if( tok == T_EOF )
2798 Unexpected( T_EOF );
2799
2800 break;
2801 } // scope bracket
2802
2803 default:
2804 Unexpected( CurText() );
2805 } // switch
2806
2807 tok = NextTok();
2808
2809 } // while
2810}
2811
2812
2814{
2815 T tok;
2816
2817 /* <network_descriptor >::=
2818 (network
2819 {<net_descriptor>}
2820 [{<class_descriptor> }]
2821 [{<class_class_descriptor> }]
2822 [{<group_descriptor> }]
2823 [{<group_set_descriptor> }]
2824 [{<pair_descriptor> }]
2825 [{<bundle_descriptor> }]
2826 )
2827 */
2828
2829 while( ( tok = NextTok() ) != T_RIGHT )
2830 {
2831 if( tok != T_LEFT )
2832 Expecting( T_LEFT );
2833
2834 tok = NextTok();
2835
2836 switch( tok )
2837 {
2838 case T_net:
2839 NET* net;
2840 net = new NET( growth );
2841 growth->m_nets.push_back( net );
2842 doNET( net );
2843 break;
2844
2845 case T_class:
2846 CLASS* myclass;
2847 myclass = new CLASS( growth );
2848 growth->m_classes.push_back( myclass );
2849 doCLASS( myclass );
2850 break;
2851
2852 default:
2853 Unexpected( CurText() );
2854 }
2855 }
2856}
2857
2858
2860{
2861 T tok;
2862
2863 /* <component_order_descriptor >::=
2864 (comp_order {<placement_id> })
2865 */
2866
2867 while( IsSymbol( tok = NextTok() ) )
2868 growth->m_placement_ids.push_back( CurText() );
2869
2870 if( tok != T_RIGHT )
2871 Expecting( T_RIGHT );
2872}
2873
2874
2876{
2877 T tok;
2878
2879 /* <fromto_descriptor >::=
2880 {(fromto
2881 [<pin_reference> | <virtual_pin_descriptor> ] | <component_id >]
2882 [<pin_reference> | <virtual_pin_descriptor> | <component_id >]
2883 [(type [fix | normal | soft])]
2884 [(net <net_id >)]
2885 [<rule_descriptor> ]
2886 [<circuit_descriptor> ]
2887 [{<layer_rule_descriptor> }]
2888 )}
2889 */
2890
2891
2892 // read the first two grammar items in as 2 single tokens, i.e. do not
2893 // split apart the <pin_reference>s into 3 separate tokens. Do this by
2894 // turning off the string delimiter in the lexer.
2895
2896 char old = SetStringDelimiter( 0 );
2897
2898 if( !IsSymbol(NextTok() ) )
2899 {
2900 SetStringDelimiter( old );
2901 Expecting( T_SYMBOL );
2902 }
2903
2904 growth->m_fromText = CurText();
2905
2906 if( !IsSymbol(NextTok() ) )
2907 {
2908 SetStringDelimiter( old );
2909 Expecting( T_SYMBOL );
2910 }
2911
2912 growth->m_toText = CurText();
2913
2914 SetStringDelimiter( old );
2915
2916 while( ( tok = NextTok() ) != T_RIGHT )
2917 {
2918 if( tok != T_LEFT )
2919 Expecting( T_LEFT );
2920
2921 tok = NextTok();
2922
2923 switch( tok )
2924 {
2925 case T_type:
2926 tok = NextTok();
2927
2928 if( tok != T_fix && tok != T_normal && tok != T_soft )
2929 Expecting( "fix|normal|soft" );
2930
2931 growth->m_fromto_type = tok;
2932 NeedRIGHT();
2933 break;
2934
2935 case T_rule:
2936 if( growth->m_rules )
2937 Unexpected( tok );
2938
2939 growth->m_rules = new RULE( growth, T_rule );
2940 doRULE( growth->m_rules );
2941 break;
2942
2943 case T_layer_rule:
2944 LAYER_RULE* layer_rule;
2945 layer_rule = new LAYER_RULE( growth );
2946 growth->m_layer_rules.push_back( layer_rule );
2947 doLAYER_RULE( layer_rule );
2948 break;
2949
2950 case T_net:
2951 if( growth->m_net_id.size() )
2952 Unexpected( tok );
2953
2954 NeedSYMBOL();
2955 growth->m_net_id = CurText();
2956 NeedRIGHT();
2957 break;
2958
2959 // circuit descriptor not supported at this time
2960
2961 default:
2962 Unexpected( CurText() );
2963 }
2964 }
2965}
2966
2967
2969{
2970 T tok;
2971
2972 /* <wire_shape_descriptor >::=
2973 (wire
2974 <shape_descriptor>
2975 [(net <net_id >)]
2976 [(turret <turret#> )]
2977 [(type [fix | route | normal | protect])]
2978 [(attr [test | fanout | bus | jumper])]
2979 [(shield <net_id >)]
2980 [{<window_descriptor> }]
2981 [(connect
2982 (terminal <object_type> [<pin_reference> ])
2983 (terminal <object_type> [<pin_reference> ])
2984 )]
2985 [(supply)]
2986 )
2987 */
2988
2989 while( ( tok = NextTok() ) != T_RIGHT )
2990 {
2991 if( tok != T_LEFT )
2992 Expecting( T_LEFT );
2993
2994 tok = NextTok();
2995
2996 switch( tok )
2997 {
2998 case T_rect:
2999 if( growth->m_shape )
3000 Unexpected( tok );
3001
3002 growth->m_shape = new RECTANGLE( growth );
3003 doRECTANGLE( (RECTANGLE*) growth->m_shape );
3004 break;
3005
3006 case T_circle:
3007 if( growth->m_shape )
3008 Unexpected( tok );
3009
3010 growth->m_shape = new CIRCLE( growth );
3011 doCIRCLE( (CIRCLE*) growth->m_shape );
3012 break;
3013
3014 case T_polyline_path:
3015 tok = T_path;
3017
3018 case T_path:
3019 case T_polygon:
3020 case T_poly: // Specctra abbreviation of polygon
3021 if( tok == T_poly )
3022 tok = T_polygon;
3023
3024 if( growth->m_shape )
3025 Unexpected( tok );
3026
3027 growth->m_shape = new PATH( growth, tok );
3028 doPATH( (PATH*) growth->m_shape );
3029 break;
3030
3031 case T_qarc:
3032 if( growth->m_shape )
3033 Unexpected( tok );
3034
3035 growth->m_shape = new QARC( growth );
3036 doQARC( (QARC*) growth->m_shape );
3037 break;
3038
3039 case T_net:
3040 NeedSYMBOLorNUMBER();
3041 growth->m_net_id = CurText();
3042 NeedRIGHT();
3043 break;
3044
3045 case T_turret:
3046 if( NextTok() != T_NUMBER )
3047 Expecting( T_NUMBER );
3048
3049 growth->m_turret = atoi( CurText() );
3050 NeedRIGHT();
3051 break;
3052
3053 case T_type:
3054 tok = NextTok();
3055
3056 if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3057 Expecting( "fix|route|normal|protect" );
3058
3059 growth->m_wire_type = tok;
3060 NeedRIGHT();
3061 break;
3062
3063 case T_attr:
3064 tok = NextTok();
3065
3066 if( tok != T_test && tok != T_fanout && tok != T_bus && tok != T_jumper )
3067 Expecting( "test|fanout|bus|jumper" );
3068
3069 growth->m_attr = tok;
3070 NeedRIGHT();
3071 break;
3072
3073 case T_shield:
3074 NeedSYMBOL();
3075 growth->m_shield = CurText();
3076 NeedRIGHT();
3077 break;
3078
3079 case T_window:
3080 WINDOW* window;
3081 window = new WINDOW( growth );
3082 growth->m_windows.push_back( window );
3083 doWINDOW( window );
3084 break;
3085
3086 case T_connect:
3087 if( growth->m_connect )
3088 Unexpected( tok );
3089
3090 growth->m_connect = new CONNECT( growth );
3091 doCONNECT( growth->m_connect );
3092 break;
3093
3094 case T_supply:
3095 growth->m_supply = true;
3096 NeedRIGHT();
3097 break;
3098
3099 default:
3100 Unexpected( CurText() );
3101 }
3102 }
3103}
3104
3105
3107{
3108 T tok;
3109 POINT point;
3110
3111 /* <wire_via_descriptor >::=
3112 (via
3113 <m_padstack_id > {<vertex> }
3114 [(net <net_id >)]
3115 [(via_number <via#> )]
3116 [(type [fix | route | normal | protect])]
3117 [(attr [test | fanout | jumper |
3118 virtual_pin <m_virtual_pin_name> ])]
3119 [(contact {<layer_id >})]
3120 [(supply)]
3121 )
3122 (virtual_pin
3123 <m_virtual_pin_name> <vertex> (net <net_id >)
3124 )
3125 */
3126
3127 NeedSYMBOL();
3128 growth->m_padstack_id = CurText();
3129
3130 while( ( tok = NextTok() ) == T_NUMBER )
3131 {
3132 point.x = parseDouble();
3133
3134 if( NextTok() != T_NUMBER )
3135 Expecting( "vertex.y" );
3136
3137 point.y = parseDouble();
3138
3139 growth->m_vertexes.push_back( point );
3140 }
3141
3142 while( tok != T_RIGHT )
3143 {
3144 if( tok != T_LEFT )
3145 Expecting( T_LEFT );
3146
3147 tok = NextTok();
3148
3149 switch( tok )
3150 {
3151 case T_net:
3152 NeedSYMBOL();
3153 growth->m_net_id = CurText();
3154 NeedRIGHT();
3155 break;
3156
3157 case T_via_number:
3158 if( NextTok() != T_NUMBER )
3159 Expecting( "<via#>" );
3160
3161 growth->m_via_number = atoi( CurText() );
3162 NeedRIGHT();
3163 break;
3164
3165 case T_type:
3166 tok = NextTok();
3167
3168 if( tok != T_fix && tok != T_route && tok != T_normal && tok != T_protect )
3169 Expecting( "fix|route|normal|protect" );
3170
3171 growth->m_via_type = tok;
3172 NeedRIGHT();
3173 break;
3174
3175 case T_attr:
3176 tok = NextTok();
3177
3178 if( tok != T_test && tok != T_fanout && tok != T_jumper && tok != T_virtual_pin )
3179 Expecting( "test|fanout|jumper|virtual_pin" );
3180
3181 growth->m_attr = tok;
3182
3183 if( tok == T_virtual_pin )
3184 {
3185 NeedSYMBOL();
3186 growth->m_virtual_pin_name = CurText();
3187 }
3188
3189 NeedRIGHT();
3190 break;
3191
3192 case T_contact:
3193 NeedSYMBOL();
3194 tok = T_SYMBOL;
3195
3196 while( IsSymbol( tok ) )
3197 {
3198 growth->m_contact_layers.push_back( CurText() );
3199 tok = NextTok();
3200 }
3201
3202 if( tok != T_RIGHT )
3203 Expecting( T_RIGHT );
3204
3205 break;
3206
3207 case T_supply:
3208 growth->m_supply = true;
3209 NeedRIGHT();
3210 break;
3211
3212 default:
3213 Unexpected( CurText() );
3214 }
3215
3216 tok = NextTok();
3217 }
3218}
3219
3220
3222{
3223 T tok;
3224
3225 /* <wiring_descriptor >::=
3226 (wiring
3227 [<unit_descriptor> | <resolution_descriptor> | null]
3228 {<wire_descriptor> }
3229 [<test_points_descriptor> ]
3230 {[<supply_pin_descriptor> ]}
3231 )
3232 */
3233
3234 while( ( tok = NextTok() ) != T_RIGHT )
3235 {
3236 if( tok != T_LEFT )
3237 Expecting( T_LEFT );
3238
3239 tok = NextTok();
3240
3241 switch( tok )
3242 {
3243 case T_unit:
3244 if( growth->unit )
3245 Unexpected( tok );
3246
3247 growth->unit = new UNIT_RES( growth, tok );
3248 doUNIT( growth->unit );
3249 break;
3250
3251 case T_resolution:
3252 if( growth->unit )
3253 Unexpected( tok );
3254
3255 growth->unit = new UNIT_RES( growth, tok );
3256 doRESOLUTION( growth->unit );
3257 break;
3258
3259 case T_wire:
3260 WIRE* wire;
3261 wire = new WIRE( growth );
3262 growth->wires.push_back( wire );
3263 doWIRE( wire );
3264 break;
3265
3266 case T_via:
3267 WIRE_VIA* wire_via;
3268 wire_via = new WIRE_VIA( growth );
3269 growth->wire_vias.push_back( wire_via );
3270 doWIRE_VIA( wire_via );
3271 break;
3272
3273 default:
3274 Unexpected( CurText() );
3275 }
3276 }
3277}
3278
3279
3281{
3282 T tok;
3283
3284 /* <ancestor_file_descriptor >::=
3285 (ancestor <file_path_name> (created_time <time_stamp> )
3286 [(comment <comment_string> )])
3287 */
3288
3289 NeedSYMBOL();
3290 growth->filename = CurText();
3291
3292 while( ( tok = NextTok() ) != T_RIGHT )
3293 {
3294 if( tok != T_LEFT )
3295 Expecting( T_LEFT );
3296
3297 tok = NextTok();
3298
3299 switch( tok )
3300 {
3301 case T_created_time:
3302 readTIME( &growth->time_stamp );
3303 NeedRIGHT();
3304 break;
3305
3306 case T_comment:
3307 NeedSYMBOL();
3308 growth->comment = CurText();
3309 NeedRIGHT();
3310 break;
3311
3312 default:
3313 Unexpected( CurText() );
3314 }
3315 }
3316}
3317
3318
3320{
3321 T tok;
3322
3323 /* <history_descriptor >::=
3324 (history [{<ancestor_file_descriptor> }] <self_descriptor> )
3325 */
3326
3327 while( ( tok = NextTok() ) != T_RIGHT )
3328 {
3329 if( tok != T_LEFT )
3330 Expecting( T_LEFT );
3331
3332 tok = NextTok();
3333
3334 switch( tok )
3335 {
3336 case T_ancestor:
3337 ANCESTOR* ancestor;
3338 ancestor = new ANCESTOR( growth );
3339 growth->ancestors.push_back( ancestor );
3340 doANCESTOR( ancestor );
3341 break;
3342
3343 case T_self:
3344 while( ( tok = NextTok() ) != T_RIGHT )
3345 {
3346 if( tok != T_LEFT )
3347 Expecting( T_LEFT );
3348
3349 tok = NextTok();
3350
3351 switch( tok )
3352 {
3353 case T_created_time:
3354 readTIME( &growth->time_stamp );
3355 NeedRIGHT();
3356 break;
3357
3358 case T_comment:
3359 NeedSYMBOL();
3360 growth->comments.push_back( CurText() );
3361 NeedRIGHT();
3362 break;
3363
3364 default:
3365 Unexpected( CurText() );
3366 }
3367 }
3368
3369 break;
3370
3371 default:
3372 Unexpected( CurText() );
3373 }
3374 }
3375}
3376
3377
3379{
3380 T tok;
3381
3382 /* <session_file_descriptor >::=
3383 (session <session_id >
3384 (base_design <path/filename >)
3385 [<history_descriptor> ]
3386 [<session_structure_descriptor> ]
3387 [<placement_descriptor> ]
3388 [<floor_plan_descriptor> ]
3389 [<net_pin_changes_descriptor> ]
3390 [<was_is_descriptor> ]
3391 <swap_history_descriptor> ]
3392 [<route_descriptor> ]
3393 )
3394 */
3395
3396 // The path can be defined by multiple tokens if there are spaces in it (e.g. by TopoR).
3397 NeedSYMBOL();
3398 std::stringstream fullPath;
3399 fullPath << CurText();
3400
3401 while( ( tok = NextTok() ) != T_LEFT )
3402 fullPath << " " << CurText();
3403
3404 growth->session_id = fullPath.str();
3405
3406 do
3407 {
3408 if( tok != T_LEFT )
3409 Expecting( T_LEFT );
3410
3411 tok = NextTok();
3412
3413 switch( tok )
3414 {
3415 case T_base_design:
3416 NeedSYMBOL();
3417 growth->base_design = CurText();
3418 NeedRIGHT();
3419 break;
3420
3421 case T_history:
3422 if( growth->history )
3423 Unexpected( tok );
3424
3425 growth->history = new HISTORY( growth );
3426 doHISTORY( growth->history );
3427 break;
3428
3429 case T_structure:
3430 if( growth->structure )
3431 Unexpected( tok );
3432
3433 growth->structure = new STRUCTURE( growth );
3434 doSTRUCTURE( growth->structure );
3435 break;
3436
3437 case T_placement:
3438 if( growth->placement )
3439 Unexpected( tok );
3440
3441 growth->placement = new PLACEMENT( growth );
3442 doPLACEMENT( growth->placement );
3443 break;
3444
3445 case T_was_is:
3446 if( growth->was_is )
3447 Unexpected( tok );
3448
3449 growth->was_is = new WAS_IS( growth );
3450 doWAS_IS( growth->was_is );
3451 break;
3452
3453 case T_routes:
3454 if( growth->route )
3455 Unexpected( tok );
3456
3457 growth->route = new ROUTE( growth );
3458 doROUTE( growth->route );
3459 break;
3460
3461 default:
3462 Unexpected( CurText() );
3463 }
3464 } while( ( tok = NextTok() ) != T_RIGHT );
3465}
3466
3467
3469{
3470 T tok;
3471 PIN_PAIR empty( growth );
3472 PIN_PAIR* pin_pair;
3473
3474 /* <was_is_descriptor >::=
3475 (was_is {(pins <pin_reference> <pin_reference> )})
3476 */
3477
3478 // none of the pins is ok too
3479 while( ( tok = NextTok() ) != T_RIGHT )
3480 {
3481 if( tok != T_LEFT )
3482 Expecting( T_LEFT );
3483
3484 tok = NextTok();
3485
3486 switch( tok )
3487 {
3488 case T_pins:
3489 // copy the empty one, then fill its copy later thru pin_pair.
3490 growth->pin_pairs.push_back( empty );
3491 pin_pair= &growth->pin_pairs.back();
3492
3493 NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3494 readCOMPnPIN( &pin_pair->was.component_id, &pin_pair->was.pin_id );
3495
3496 NeedSYMBOL(); // readCOMPnPIN() expects 1st token to have been read
3497 readCOMPnPIN( &pin_pair->is.component_id, &pin_pair->is.pin_id );
3498
3499 NeedRIGHT();
3500 break;
3501
3502 default:
3503 Unexpected( CurText() );
3504 }
3505 }
3506}
3507
3508
3510{
3511 T tok;
3512
3513 /* <route_descriptor >::=
3514 (routes
3515 <resolution_descriptor>
3516 <parser_descriptor>
3517 <structure_out_descriptor>
3518 <library_out_descriptor>
3519 <network_out_descriptor>
3520 <test_points_descriptor>
3521 )
3522 */
3523
3524 while( ( tok = NextTok() ) != T_RIGHT )
3525 {
3526 if( tok != T_LEFT )
3527 Expecting( T_LEFT );
3528
3529 tok = NextTok();
3530
3531 switch( tok )
3532 {
3533 case T_resolution:
3534 if( growth->resolution )
3535 Unexpected( tok );
3536
3537 growth->resolution = new UNIT_RES( growth, tok );
3538 doRESOLUTION( growth->resolution );
3539 break;
3540
3541 case T_parser:
3542 if( growth->parser )
3543 {
3544#if 0 // Electra 2.9.1 emits two (parser ) elements in a row.
3545 // Work around their bug for now.
3546 Unexpected( tok );
3547#else
3548 delete growth->parser;
3549#endif
3550 }
3551
3552 growth->parser = new PARSER( growth );
3553 doPARSER( growth->parser );
3554 break;
3555
3556 case T_structure_out:
3557 if( growth->structure_out )
3558 Unexpected( tok );
3559
3560 growth->structure_out = new STRUCTURE_OUT( growth );
3561 doSTRUCTURE_OUT( growth->structure_out );
3562 break;
3563
3564 case T_library_out:
3565 if( growth->library )
3566 Unexpected( tok );
3567
3568 growth->library = new LIBRARY( growth, tok );
3569 doLIBRARY( growth->library );
3570 break;
3571
3572 case T_network_out:
3573 while( ( tok = NextTok() ) != T_RIGHT )
3574 {
3575 if( tok != T_LEFT )
3576 Expecting( T_LEFT );
3577
3578 tok = NextTok();
3579
3580 // it is class NET_OUT, but token T_net in Freerouting
3581 // Allegro PCB Router (Specctra) uses capitalized "Net"
3582 if( tok != T_net && !( tok == T_SYMBOL && !strcmp( CurText(), "Net" ) ) )
3583 Unexpected( CurText() );
3584
3585 NET_OUT* net_out;
3586 net_out = new NET_OUT( growth );
3587
3588 growth->net_outs.push_back( net_out );
3589 doNET_OUT( net_out );
3590 }
3591
3592 break;
3593
3594 case T_test_points:
3595 while( ( tok = NextTok() ) != T_RIGHT )
3596 {
3597 // TODO: Not supported yet
3598 Unexpected( CurText() );
3599 }
3600 break;
3601
3602 default:
3603 Unexpected( CurText() );
3604 }
3605 }
3606}
3607
3608
3610{
3611 T tok;
3612
3613 /* <net_out_descriptor >::=
3614 (net <net_id >
3615 [(unassigned)]
3616 [(net_number <integer >)]
3617 [<rule_descriptor> ]
3618 {[<wire_shape_descriptor> | <wire_guide_descriptor> |
3619 <wire_via_descriptor> | <bond_shape_descriptor> ]}
3620 {[<supply_pin_descriptor> ]}
3621 )
3622 */
3623
3624 NeedSYMBOLorNUMBER();
3625 growth->net_id = CurText();
3626
3627 while( ( tok = NextTok() ) != T_RIGHT )
3628 {
3629 if( tok != T_LEFT )
3630 Expecting( T_LEFT );
3631
3632 tok = NextTok();
3633
3634 switch( tok )
3635 {
3636 case T_unassigned:
3637 growth->m_unassigned = true;
3638 NeedRIGHT();
3639 break;
3640
3641 case T_net_number:
3642 tok = NextTok();
3643
3644 if( tok!= T_NUMBER )
3645 Expecting( T_NUMBER );
3646
3647 growth->net_number = atoi( CurText() );
3648 NeedRIGHT();
3649 break;
3650
3651 case T_rule:
3652 if( growth->rules )
3653 Unexpected( tok );
3654
3655 growth->rules = new RULE( growth, tok );
3656 doRULE( growth->rules );
3657 break;
3658
3659 case T_wire:
3660 WIRE* wire;
3661 wire = new WIRE( growth );
3662 growth->wires.push_back( wire );
3663 doWIRE( wire );
3664 break;
3665
3666 case T_via:
3667 WIRE_VIA* wire_via;
3668 wire_via = new WIRE_VIA( growth );
3669 growth->wire_vias.push_back( wire_via );
3670 doWIRE_VIA( wire_via );
3671 break;
3672
3673 case T_supply_pin:
3674 SUPPLY_PIN* supply_pin;
3675 supply_pin = new SUPPLY_PIN( growth );
3676 growth->supply_pins.push_back( supply_pin );
3677 doSUPPLY_PIN( supply_pin );
3678 break;
3679
3680 default:
3681 Unexpected( CurText() );
3682 }
3683 }
3684}
3685
3686
3688{
3689 T tok;
3690 PIN_REF empty(growth);
3691
3692 /* <supply_pin_descriptor >::=
3693 (supply_pin {<pin_reference> } [(net <net_id >)])
3694 */
3695
3696 NeedSYMBOL();
3697 growth->net_id = CurText();
3698
3699 while( ( tok = NextTok() ) != T_RIGHT )
3700 {
3701 if( IsSymbol(tok) )
3702 {
3703 growth->pin_refs.push_back( empty );
3704
3705 PIN_REF* pin_ref = &growth->pin_refs.back();
3706
3707 readCOMPnPIN( &pin_ref->component_id, &pin_ref->pin_id );
3708 }
3709 else if( tok == T_LEFT )
3710 {
3711 tok = NextTok();
3712
3713 if( tok != T_net )
3714 Expecting( T_net );
3715
3716 growth->net_id = CurText();
3717 NeedRIGHT();
3718 }
3719 else
3720 Unexpected( CurText() );
3721 }
3722}
3723
3724
3725void SPECCTRA_DB::ExportPCB( const wxString& aFilename, bool aNameChange )
3726{
3727 if( m_pcb )
3728 {
3729 FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3730
3731 if( aNameChange )
3732 m_pcb->m_pcbname = TO_UTF8( aFilename );
3733
3734 m_pcb->Format( &formatter, 0 );
3735 formatter.Finish();
3736 }
3737}
3738
3739
3740void SPECCTRA_DB::ExportSESSION( const wxString& aFilename )
3741{
3742 if( m_session )
3743 {
3744 FILE_OUTPUTFORMATTER formatter( aFilename, wxT( "wt" ), m_quote_char[0] );
3745
3746 m_session->Format( &formatter, 0 );
3747 formatter.Finish();
3748 }
3749}
3750
3751
3753{
3754 PCB* pcb = new PCB();
3755
3756 pcb->m_parser = new PARSER( pcb );
3757 pcb->m_resolution = new UNIT_RES( pcb, T_resolution );
3758 pcb->m_unit = new UNIT_RES( pcb, T_unit );
3759
3760 pcb->m_structure = new STRUCTURE( pcb );
3761 pcb->m_structure->m_boundary = new BOUNDARY( pcb->m_structure );
3762 pcb->m_structure->m_via = new VIA( pcb->m_structure );
3763 pcb->m_structure->m_rules = new RULE( pcb->m_structure, T_rule );
3764
3765 pcb->m_placement = new PLACEMENT( pcb );
3766
3767 pcb->m_library = new LIBRARY( pcb );
3768
3769 pcb->m_network = new NETWORK( pcb );
3770
3771 pcb->m_wiring = new WIRING( pcb );
3772
3773 return pcb;
3774}
3775
3776
3777//-----<ELEM>---------------------------------------------------------------
3778
3779ELEM::ELEM( T aType, ELEM* aParent ) :
3780 type( aType ),
3781 parent( aParent )
3782{
3783}
3784
3785
3787{
3788}
3789
3790const char* ELEM::Name() const
3791{
3792 return SPECCTRA_DB::TokenName( type );
3793}
3794
3796{
3797 if( parent )
3798 return parent->GetUnits();
3799
3800 return &UNIT_RES::Default;
3801}
3802
3803
3804void ELEM::Format( OUTPUTFORMATTER* out, int nestLevel )
3805{
3806 out->Print( nestLevel, "(%s\n", Name() );
3807
3808 FormatContents( out, nestLevel+1 );
3809
3810 out->Print( nestLevel, ")\n" );
3811}
3812
3813
3815{
3816 for( int i = 0; i < Length(); ++i )
3817 At(i)->Format( out, nestLevel );
3818}
3819
3820
3821int ELEM_HOLDER::FindElem( T aType, int instanceNum )
3822{
3823 int repeats=0;
3824
3825 for( unsigned i = 0; i < kids.size(); ++i )
3826 {
3827 if( kids[i].Type() == aType )
3828 {
3829 if( repeats == instanceNum )
3830 return i;
3831
3832 ++repeats;
3833 }
3834 }
3835
3836 return -1;
3837}
3838
3839
3840// a reasonably small memory price to pay for improved performance
3842
3843
3844UNIT_RES UNIT_RES::Default( nullptr, T_resolution );
3845
3846
3848{
3849 if( !lhs->m_hash.size() )
3850 lhs->m_hash = lhs->makeHash();
3851
3852 if( !rhs->m_hash.size() )
3853 rhs->m_hash = rhs->makeHash();
3854
3855 int result = lhs->m_hash.compare( rhs->m_hash );
3856
3857 if( result )
3858 return result;
3859
3860 // Via names hold the drill diameters, so we have to include those to discern
3861 // between two vias with same copper size but with different drill sizes.
3862 result = lhs->m_padstack_id.compare( rhs->m_padstack_id );
3863
3864 return result;
3865}
3866
3867
3868int IMAGE::Compare( IMAGE* lhs, IMAGE* rhs )
3869{
3870 if( !lhs->m_hash.size() )
3871 lhs->m_hash = lhs->makeHash();
3872
3873 if( !rhs->m_hash.size() )
3874 rhs->m_hash = rhs->makeHash();
3875
3876 int result = lhs->m_hash.compare( rhs->m_hash );
3877
3878 return result;
3879}
3880
3881
3882/*
3883int COMPONENT::Compare( COMPONENT* lhs, COMPONENT* rhs )
3884{
3885 if( !lhs->hash.size() )
3886 lhs->hash = lhs->makeHash();
3887
3888 if( !rhs->hash.size() )
3889 rhs->hash = rhs->makeHash();
3890
3891 int result = lhs->hash.compare( rhs->hash );
3892 return result;
3893}
3894*/
3895
3897 ELEM( T_parser, aParent )
3898{
3899 string_quote = '"';
3900 space_in_quoted_tokens = false;
3901
3902 case_sensitive = false;
3905 routes_include_guides = false;
3907 via_rotate_first = true;
3908 generated_by_freeroute = false;
3909
3910 host_cad = "KiCad's Pcbnew";
3911 wxString msg = GetBuildVersion();
3912 host_version = TO_UTF8(msg);
3913}
3914
3915
3916void PARSER::FormatContents( OUTPUTFORMATTER* out, int nestLevel )
3917{
3918 out->Print( nestLevel, "(string_quote %c)\n", string_quote );
3919 out->Print( nestLevel, "(space_in_quoted_tokens %s)\n", space_in_quoted_tokens ? "on" : "off" );
3920 out->Print( nestLevel, "(host_cad \"%s\")\n", host_cad.c_str() );
3921 out->Print( nestLevel, "(host_version \"%s\")\n", host_version.c_str() );
3922
3923 for( auto i = constants.begin(); i != constants.end(); )
3924 {
3925 const std::string& s1 = *i++;
3926 const std::string& s2 = *i++;
3927
3928 const char* q1 = out->GetQuoteChar( s1.c_str() );
3929 const char* q2 = out->GetQuoteChar( s2.c_str() );
3930 out->Print( nestLevel, "(constant %s%s%s %s%s%s)\n",
3931 q1, s1.c_str(), q1, q2, s2.c_str(), q2 );
3932 }
3933
3935 {
3936 out->Print( nestLevel, "(routes_include%s%s%s)\n",
3937 routes_include_testpoint ? " testpoint" : "",
3938 routes_include_guides ? " guides" : "",
3939 routes_include_image_conductor ? " image_conductor" : "" );
3940 }
3941
3943 out->Print( nestLevel, "(wires_include testpoint)\n" );
3944
3945 if( !via_rotate_first )
3946 out->Print( nestLevel, "(via_rotate_first off)\n" );
3947
3948 if( case_sensitive )
3949 out->Print( nestLevel, "(case_sensitive %s)\n", case_sensitive ? "on" : "off" );
3950}
3951
3952
3953void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel )
3954{
3955 bool useMultiLine;
3956
3957 const char* quote = out->GetQuoteChar( m_component_id.c_str() );
3958
3959 if( m_place_rules || m_properties.size() || m_rules || m_region )
3960 {
3961 useMultiLine = true;
3962
3963 out->Print( nestLevel, "(%s %s%s%s\n", Name(), quote, m_component_id.c_str(), quote );
3964 out->Print( nestLevel+1, "%s", "" );
3965 }
3966 else
3967 {
3968 useMultiLine = false;
3969
3970 out->Print( nestLevel, "(%s %s%s%s", Name(), quote, m_component_id.c_str(), quote );
3971 }
3972
3973 if( m_hasVertex )
3974 {
3975 out->Print( 0, " %s %s", FormatDouble2Str( m_vertex.x ).c_str(), FormatDouble2Str( m_vertex.y ).c_str() );
3976 out->Print( 0, " %s", GetTokenText( m_side ) );
3977 out->Print( 0, " %s", FormatDouble2Str( m_rotation ).c_str() );
3978 }
3979
3980 const char* space = " "; // one space, as c string.
3981
3982 if( m_mirror != T_NONE )
3983 {
3984 out->Print( 0, "%s(mirror %s)", space, GetTokenText( m_mirror ) );
3985 space = "";
3986 }
3987
3988 if( m_status != T_NONE )
3989 {
3990 out->Print( 0, "%s(status %s)", space, GetTokenText( m_status ) );
3991 space = "";
3992 }
3993
3994 if( m_logical_part.size() )
3995 {
3996 quote = out->GetQuoteChar( m_logical_part.c_str() );
3997 out->Print( 0, "%s(logical_part %s%s%s)", space, quote, m_logical_part.c_str(), quote );
3998 space = "";
3999 }
4000
4001 if( useMultiLine )
4002 {
4003 out->Print( 0, "\n" );
4004
4005 if( m_place_rules )
4006 m_place_rules->Format( out, nestLevel+1 );
4007
4008 if( m_properties.size() )
4009 {
4010 out->Print( nestLevel + 1, "(property \n" );
4011
4012 for( PROPERTIES::const_iterator i = m_properties.begin(); i != m_properties.end(); ++i )
4013 i->Format( out, nestLevel + 2 );
4014
4015 out->Print( nestLevel + 1, ")\n" );
4016 }
4017
4018 if( m_lock_type != T_NONE )
4019 out->Print( nestLevel + 1, "(lock_type %s)\n", GetTokenText( m_lock_type ) );
4020
4021 if( m_rules )
4022 m_rules->Format( out, nestLevel+1 );
4023
4024 if( m_region )
4025 m_region->Format( out, nestLevel+1 );
4026
4027 if( m_part_number.size() )
4028 {
4029 quote = out->GetQuoteChar( m_part_number.c_str() );
4030 out->Print( nestLevel + 1, "(PN %s%s%s)\n", quote, m_part_number.c_str(), quote );
4031 }
4032 }
4033 else
4034 {
4035 if( m_lock_type != T_NONE )
4036 {
4037 out->Print( 0, "%s(lock_type %s)", space, GetTokenText( m_lock_type ) );
4038 space = "";
4039 }
4040
4041 if( m_part_number.size() )
4042 {
4043 quote = out->GetQuoteChar( m_part_number.c_str() );
4044 out->Print( 0, "%s(PN %s%s%s)", space, quote, m_part_number.c_str(), quote );
4045 }
4046 }
4047
4048 out->Print( 0, ")\n" );
4049}
4050
4051} // namespace DSN
wxString GetBuildVersion()
Get the full KiCad version string.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
int GetCopperLayerCount() const
Definition board.cpp:994
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:802
time_t time_stamp
Definition specctra.h:3257
std::string filename
Definition specctra.h:3255
std::string comment
Definition specctra.h:3256
RECTANGLE * rectangle
Definition specctra.h:725
std::string layer_id
Definition specctra.h:769
double diameter
Definition specctra.h:771
POINT vertex
Definition specctra.h:772
std::vector< std::string > class_ids
Definition specctra.h:1111
CLASSES * classes
Definition specctra.h:1146
The <class_descriptor> in the specctra spec.
Definition specctra.h:2707
TOPOLOGY * m_topology
Definition specctra.h:2790
std::vector< std::string > m_circuit
circuit descriptor list
Definition specctra.h:2786
boost::ptr_vector< LAYER_RULE > m_layer_rules
Definition specctra.h:2789
std::string m_class_id
Definition specctra.h:2782
RULE * m_rules
Definition specctra.h:2788
std::vector< std::string > m_net_ids
Definition specctra.h:2783
Implement a <component_descriptor> in the specctra dsn spec.
Definition specctra.h:1752
std::string m_image_id
Definition specctra.h:1792
boost::ptr_vector< PLACE > m_places
Definition specctra.h:1793
The <component_order_descriptor>.
Definition specctra.h:2522
std::vector< std::string > m_placement_ids
Definition specctra.h:2548
bool via_at_smd
Definition specctra.h:1186
A <plane_descriptor> in the specctra dsn spec.
Definition specctra.h:1343
void Append(ELEM *aElem)
Definition specctra.h:322
int FindElem(DSN_T aType, int instanceNum=0)
Find a particular instance number of a given type of ELEM.
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:360
ELEM * At(int aIndex) const
Definition specctra.h:341
int Length() const
Return the number of ELEMs in this holder.
Definition specctra.h:317
ELEM * parent
Definition specctra.h:276
std::string makeHash()
Return a string which uniquely represents this ELEM among other ELEMs of the same derived class as "t...
Definition specctra.h:263
const char * Name() const
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:275
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:242
DSN_T Type() const
Definition specctra.h:210
static STRING_FORMATTER sf
Definition specctra.h:273
std::string m_fromText
Definition specctra.h:2507
std::string m_net_id
Definition specctra.h:2511
std::string m_toText
Definition specctra.h:2508
DSN_T m_fromto_type
Definition specctra.h:2510
boost::ptr_vector< LAYER_RULE > m_layer_rules
Definition specctra.h:2514
RULE * m_rules
Definition specctra.h:2512
DSN_T m_grid_type
T_via | T_wire | T_via_keepout | T_place | T_snap.
Definition specctra.h:1505
double m_offset
Definition specctra.h:1508
DSN_T m_direction
T_x | T_y | -1 for both.
Definition specctra.h:1507
double m_dimension
Definition specctra.h:1506
DSN_T m_image_type
Definition specctra.h:1509
ANCESTORS ancestors
Definition specctra.h:3298
time_t time_stamp
Definition specctra.h:3299
std::vector< std::string > comments
Definition specctra.h:3300
DSN_T m_side
Definition specctra.h:2072
std::string m_hash
a hash string used by Compare(), not Format()ed/exported.
Definition specctra.h:2069
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:1985
RULE * m_rules
Definition specctra.h:2082
boost::ptr_vector< KEEPOUT > m_keepouts
Definition specctra.h:2085
UNIT_RES * m_unit
Definition specctra.h:2073
std::string m_image_id
Definition specctra.h:2071
boost::ptr_vector< PIN > m_pins
Definition specctra.h:2080
RULE * m_place_rules
Definition specctra.h:2083
Used for <keepout_descriptor> and <plane_descriptor>.
Definition specctra.h:898
RULE * m_place_rules
Definition specctra.h:1007
boost::ptr_vector< WINDOW > m_windows
Definition specctra.h:1009
std::string m_name
Definition specctra.h:1004
ELEM * m_shape
Definition specctra.h:1018
RULE * m_rules
Definition specctra.h:1006
int m_sequence_number
Definition specctra.h:1005
SPECCTRA_LAYER_PAIRS layer_pairs
Definition specctra.h:1318
std::vector< std::string > m_layer_ids
Definition specctra.h:570
PROPERTIES properties
Definition specctra.h:1277
DSN_T layer_type
one of: T_signal, T_power, T_mixed, T_jumper
Definition specctra.h:1268
std::vector< std::string > use_net
Definition specctra.h:1275
RULE * rules
Definition specctra.h:1274
int cost_type
T_length | T_way.
Definition specctra.h:1273
int direction
[forbidden | high | medium | low | free | <positive_integer> | -1]
Definition specctra.h:1269
std::string name
Definition specctra.h:1267
A <library_descriptor> in the specctra dsn specification.
Definition specctra.h:2224
UNIT_RES * m_unit
Definition specctra.h:2408
boost::ptr_vector< IMAGE > m_images
Definition specctra.h:2409
void AddPadstack(PADSTACK *aPadstack)
Definition specctra.h:2238
boost::ptr_vector< NET > m_nets
Definition specctra.h:2816
boost::ptr_vector< CLASS > m_classes
Definition specctra.h:2817
A <net_out_descriptor> of the specctra dsn spec.
Definition specctra.h:3355
bool m_unassigned
Definition specctra.h:3403
boost::ptr_vector< WIRE > wires
Definition specctra.h:3405
boost::ptr_vector< WIRE_VIA > wire_vias
Definition specctra.h:3406
std::string net_id
Definition specctra.h:3401
boost::ptr_vector< SUPPLY_PIN > supply_pins
Definition specctra.h:3407
RULE * rules
Definition specctra.h:3404
A <net_descriptor> in the DSN spec.
Definition specctra.h:2557
std::vector< PIN_REF > m_load
Definition specctra.h:2665
boost::ptr_vector< FROMTO > m_fromtos
Definition specctra.h:2673
std::vector< PIN_REF > m_pins
Definition specctra.h:2660
RULE * m_rules
Definition specctra.h:2670
std::vector< PIN_REF > m_noexpose
Definition specctra.h:2663
std::vector< PIN_REF > m_source
Definition specctra.h:2664
std::string m_net_id
Definition specctra.h:2655
std::vector< PIN_REF > m_expose
Definition specctra.h:2662
int m_net_number
Definition specctra.h:2657
std::vector< PIN_REF > m_terminator
Definition specctra.h:2666
boost::ptr_vector< LAYER_RULE > m_layer_rules
Definition specctra.h:2672
bool m_unassigned
Definition specctra.h:2656
COMP_ORDER * m_comp_order
Definition specctra.h:2674
DSN_T m_pins_type
T_pins | T_order, type of field 'pins' below.
Definition specctra.h:2659
Hold either a via or a pad definition.
Definition specctra.h:2095
std::string m_via_id
Definition specctra.h:2202
std::string m_hash
a hash string used by Compare(), not Format()ed/exported.
Definition specctra.h:2192
DSN_T m_absolute
Definition specctra.h:2200
PADSTACK()
Cannot take ELEM* aParent because PADSTACKSET confuses this with a copy constructor and causes havoc.
Definition specctra.h:2102
std::string m_padstack_id
Definition specctra.h:2194
RULE * m_rules
Definition specctra.h:2204
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:2195
A configuration record per the SPECCTRA DSN file spec.
Definition specctra.h:370
std::string host_version
Definition specctra.h:394
void FormatContents(OUTPUTFORMATTER *out, int nestLevel) override
Write the contents as ASCII out to an OUTPUTFORMATTER according to the SPECCTRA DSN format.
std::vector< std::string > constants
This holds pairs of strings, one pair for each constant definition.
Definition specctra.h:391
bool routes_include_image_conductor
Definition specctra.h:386
std::string host_cad
Definition specctra.h:393
bool routes_include_guides
Definition specctra.h:385
bool case_sensitive
Definition specctra.h:382
bool wires_include_testpoint
Definition specctra.h:383
bool via_rotate_first
Definition specctra.h:387
char string_quote
Definition specctra.h:380
PARSER(ELEM *aParent)
bool routes_include_testpoint
Definition specctra.h:384
bool generated_by_freeroute
Definition specctra.h:388
bool space_in_quoted_tokens
Definition specctra.h:381
Support both the <path_descriptor> and the <polygon_descriptor> per the specctra dsn spec.
Definition specctra.h:580
DSN_T aperture_type
Definition specctra.h:651
std::vector< POINT > points
Definition specctra.h:650
double aperture_width
Definition specctra.h:648
std::string layer_id
Definition specctra.h:647
UNIT_RES * m_unit
Definition specctra.h:3213
UNIT_RES * m_resolution
Definition specctra.h:3212
std::string m_pcbname
Definition specctra.h:3210
NETWORK * m_network
Definition specctra.h:3217
PLACEMENT * m_placement
Definition specctra.h:3215
STRUCTURE * m_structure
Definition specctra.h:3214
PARSER * m_parser
Definition specctra.h:3211
WIRING * m_wiring
Definition specctra.h:3218
LIBRARY * m_library
Definition specctra.h:3216
POINT m_vertex
Definition specctra.h:1974
void SetRotation(double aRotation)
Definition specctra.h:1943
std::string m_pin_id
Definition specctra.h:1973
std::string m_padstack_id
Definition specctra.h:1970
DSN_T m_flip_style
Definition specctra.h:1860
UNIT_RES * m_unit
Definition specctra.h:1859
boost::ptr_vector< COMPONENT > m_components
Definition specctra.h:1861
Implement a <placement_reference> in the specctra dsn spec.
Definition specctra.h:1674
void SetVertex(const POINT &aVertex)
Definition specctra.h:1702
DSN_T m_status
Definition specctra.h:1729
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:1725
POINT m_vertex
Definition specctra.h:1726
DSN_T m_mirror
Definition specctra.h:1728
void SetRotation(double aRotation)
Definition specctra.h:1709
RULE * m_rules
Definition specctra.h:1740
DSN_T m_lock_type
Definition specctra.h:1737
DSN_T m_side
Definition specctra.h:1721
double m_rotation
Definition specctra.h:1723
std::string m_logical_part
Definition specctra.h:1731
std::string m_part_number
Definition specctra.h:1744
REGION * m_region
Definition specctra.h:1741
std::string m_component_id
reference designator
Definition specctra.h:1719
RULE * m_place_rules
Definition specctra.h:1733
PROPERTIES m_properties
Definition specctra.h:1735
std::string layer_id
Definition specctra.h:831
double aperture_width
Definition specctra.h:832
POINT vertex[3]
Definition specctra.h:833
std::string layer_id
Definition specctra.h:481
POINT point0
one of two opposite corners
Definition specctra.h:483
RULE * m_rules
Definition specctra.h:1464
RECTANGLE * m_rectangle
Definition specctra.h:1456
PATH * m_polygon
Definition specctra.h:1457
std::string m_region_id
Definition specctra.h:1453
STRUCTURE_OUT * structure_out
Definition specctra.h:3473
UNIT_RES * resolution
Definition specctra.h:3471
LIBRARY * library
Definition specctra.h:3474
boost::ptr_vector< NET_OUT > net_outs
Definition specctra.h:3475
PARSER * parser
Definition specctra.h:3472
A <rule_descriptor> in the specctra dsn spec.
Definition specctra.h:492
std::vector< std::string > m_rules
rules are saved in std::string form.
Definition specctra.h:530
A <session_file_descriptor> in the specctra dsn spec.
Definition specctra.h:3531
std::string session_id
Definition specctra.h:3580
PLACEMENT * placement
Definition specctra.h:3585
HISTORY * history
Definition specctra.h:3583
STRUCTURE * structure
Definition specctra.h:3584
std::string base_design
Definition specctra.h:3581
ROUTE * route
Definition specctra.h:3587
WAS_IS * was_is
Definition specctra.h:3586
A "(shape ..)" element in the specctra dsn spec.
Definition specctra.h:1873
boost::ptr_vector< WINDOW > m_windows
Definition specctra.h:1928
DSN_T m_connect
Definition specctra.h:1917
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:3654
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:3953
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:970
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:3942
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:3643
void doTOKPROP(TOKPROP *growth)
std::vector< std::string > m_layerIds
indexed by PCB layer number
Definition specctra.h:3950
void doIMAGE(IMAGE *growth)
void doCONNECT(CONNECT *growth)
Definition specctra.cpp:935
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:3952
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:3944
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:1389
std::string value
Definition specctra.h:1408
boost::ptr_vector< LAYER > m_layers
Definition specctra.h:1539
boost::ptr_vector< REGION > m_regions
Definition specctra.h:1662
RULE * m_place_rules
Definition specctra.h:1664
UNIT_RES * m_unit
Definition specctra.h:1648
boost::ptr_vector< GRID > m_grids
Definition specctra.h:1666
boost::ptr_vector< KEEPOUT > m_keepouts
Definition specctra.h:1660
BOUNDARY * m_boundary
Definition specctra.h:1654
LAYER_NOISE_WEIGHT * m_layer_noise_weight
Definition specctra.h:1652
BOUNDARY * m_place_boundary
Definition specctra.h:1655
boost::ptr_vector< COPPER_PLANE > m_planes
Definition specctra.h:1661
CONTROL * m_control
Definition specctra.h:1657
boost::ptr_vector< LAYER > m_layers
Definition specctra.h:1650
A <supply_pin_descriptor> in the specctra dsn spec.
Definition specctra.h:3308
std::string net_id
Definition specctra.h:3347
std::vector< PIN_REF > pin_refs
Definition specctra.h:3346
A container for a single property whose value is another DSN_T token.
Definition specctra.h:1362
boost::ptr_vector< COMP_ORDER > m_comp_orders
Definition specctra.h:2699
boost::ptr_vector< FROMTO > m_fromtos
Definition specctra.h:2698
A holder for either a T_unit or T_resolution object which are usually mutually exclusive in the dsn g...
Definition specctra.h:403
static UNIT_RES Default
A static instance which holds the default units of T_inch and 2540000.
Definition specctra.h:410
A <via_descriptor> in the specctra dsn spec.
Definition specctra.h:1029
std::vector< std::string > m_spares
Definition specctra.h:1087
std::vector< std::string > m_padstacks
Definition specctra.h:1086
A <was_is_descriptor> in the specctra dsn spec.
Definition specctra.h:3501
std::vector< PIN_PAIR > pin_pairs
Definition specctra.h:3523
ELEM * shape
Definition specctra.h:887
A <wire_via_descriptor> in the specctra dsn spec.
Definition specctra.h:2950
std::string m_net_id
Definition specctra.h:3079
std::string m_padstack_id
Definition specctra.h:3077
DSN_T m_via_type
Definition specctra.h:3081
std::string m_virtual_pin_name
Definition specctra.h:3083
std::vector< std::string > m_contact_layers
Definition specctra.h:3084
std::vector< POINT > m_vertexes
Definition specctra.h:3078
A <wire_shape_descriptor> in the specctra dsn spec.
Definition specctra.h:2835
CONNECT * m_connect
Definition specctra.h:2941
DSN_T m_wire_type
Definition specctra.h:2937
ELEM * m_shape
Definition specctra.h:2933
bool m_supply
Definition specctra.h:2942
boost::ptr_vector< WINDOW > m_windows
Definition specctra.h:2940
int m_turret
Definition specctra.h:2936
std::string m_net_id
Definition specctra.h:2935
std::string m_shield
Definition specctra.h:2939
DSN_T m_attr
Definition specctra.h:2938
A <wiring_descriptor> in the specctra dsn spec.
Definition specctra.h:3093
UNIT_RES * unit
Definition specctra.h:3129
boost::ptr_vector< WIRE > wires
Definition specctra.h:3130
boost::ptr_vector< WIRE_VIA > wire_vias
Definition specctra.h:3131
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:636
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:418
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:340
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:192
@ 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:3485
PIN_REF was
Definition specctra.h:3492
A <pin_reference> definition in the specctra dsn spec.
Definition specctra.h:2420
std::string pin_id
Definition specctra.h:2446
std::string component_id
Definition specctra.h:2445
A point in the SPECCTRA DSN coordinate system.
Definition specctra.h:105
double y
Definition specctra.h:107
double x
Definition specctra.h:106
std::string path
KIBIS_PIN * pin
wxString result
Test unit parsing edge cases and error handling.