Don't merge lines with different clearances
[geda-pcb/pcjc2.git] / src / parse_y.y
blob0942230dbd577631d836b90d97c859c761fea1ba
1 /*
2 * ************************** README *******************
4 * If the file format is modified in any way, update
5 * PCB_FILE_VERSION in file.h
6 *
7 * ************************** README *******************
8 */
12 * COPYRIGHT
14 * PCB, interactive printed circuit board design
15 * Copyright (C) 1994,1995,1996 Thomas Nau
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 * Contact addresses for paper mail and Email:
32 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
33 * Thomas.Nau@rz.uni-ulm.de
37 /* grammar to parse ASCII input of PCB description
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
44 #include "global.h"
45 #include "create.h"
46 #include "data.h"
47 #include "error.h"
48 #include "file.h"
49 #include "mymem.h"
50 #include "misc.h"
51 #include "parse_l.h"
52 #include "polygon.h"
53 #include "remove.h"
54 #include "rtree.h"
55 #include "strflags.h"
56 #include "thermal.h"
58 #ifdef HAVE_LIBDMALLOC
59 # include <dmalloc.h> /* see http://dmalloc.com */
60 #endif
62 static LayerType *Layer;
63 static PolygonType *Polygon;
64 static SymbolType *Symbol;
65 static int pin_num;
66 static LibraryMenuType *Menu;
67 static bool LayerFlag[MAX_LAYER + 2];
69 extern char *yytext; /* defined by LEX */
70 extern PCBType *yyPCB;
71 extern DataType *yyData;
72 extern ElementType *yyElement;
73 extern FontType *yyFont;
74 extern int yylineno; /* linenumber */
75 extern char *yyfilename; /* in this file */
77 static char *layer_group_string;
79 static AttributeListType *attr_list;
81 int yyerror(const char *s);
82 int yylex();
83 static int check_file_version (int);
85 static void do_measure (PLMeasure *m, Coord i, double d, int u);
86 #define M(r,f,d) do_measure (&(r), f, d, 1)
88 /* Macros for interpreting what "measure" means - integer value only,
89 old units (mil), or new units (cmil). */
90 #define IV(m) integer_value (m)
91 #define OU(m) old_units (m)
92 #define NU(m) new_units (m)
94 static int integer_value (PLMeasure m);
95 static Coord old_units (PLMeasure m);
96 static Coord new_units (PLMeasure m);
98 #define YYDEBUG 1
99 #define YYERROR_VERBOSE 1
101 #include "parse_y.h"
105 %verbose
107 %union /* define YYSTACK type */
109 int integer;
110 double number;
111 char *string;
112 FlagType flagtype;
113 PLMeasure measure;
116 %token <number> FLOATING /* line thickness, coordinates ... */
117 %token <integer> INTEGER CHAR_CONST /* flags ... */
118 %token <string> STRING /* element names ... */
120 %token T_FILEVERSION T_PCB T_LAYER T_VIA T_RAT T_LINE T_ARC T_RECTANGLE T_TEXT T_ELEMENTLINE
121 %token T_ELEMENT T_PIN T_PAD T_GRID T_FLAGS T_SYMBOL T_SYMBOLLINE T_CURSOR
122 %token T_ELEMENTARC T_MARK T_GROUPS T_STYLES T_POLYGON T_POLYGON_HOLE T_NETLIST T_NET T_CONN
123 %token T_AREA T_THERMAL T_DRC T_ATTRIBUTE
124 %token T_UMIL T_CMIL T_MIL T_IN T_NM T_UM T_MM T_M T_KM T_PX
125 %type <integer> symbolid
126 %type <string> opt_string
127 %type <flagtype> flags
128 %type <number> number
129 %type <measure> measure
133 parse
134 : parsepcb
135 | parsedata
136 | parsefont
137 | error { YYABORT; }
140 /* %start-doc pcbfile 00pcb
141 @nodetype subsection
142 @nodename %s syntax
144 A special note about units: Older versions of @code{pcb} used mils
145 (1/1000 inch) as the base unit; a value of 500 in the file meant
146 half an inch. Newer versions uses a "high resolution" syntax,
147 where the base unit is 1/100 of a mil (0.000010 inch); a value of 500 in
148 the file means 5 mils. As a general rule, the variants of each entry
149 listed below which use square brackets are the high resolution formats
150 and use the 1/100 mil units, and the ones with parentheses are the older
151 variants and use 1 mil units. Note that when multiple variants
152 are listed, the most recent (and most preferred) format is the first
153 listed.
155 Symbolic and numeric flags (SFlags and NFlags) are described in
156 @ref{Object Flags}.
158 %end-doc */
160 parsepcb
162 /* reset flags for 'used layers';
163 * init font and data pointers
165 int i;
167 if (!yyPCB)
169 Message("illegal fileformat\n");
170 YYABORT;
172 for (i = 0; i < MAX_LAYER + 2; i++)
173 LayerFlag[i] = false;
174 yyFont = &yyPCB->Font;
175 yyData = yyPCB->Data;
176 yyData->pcb = yyPCB;
177 yyData->LayerN = 0;
178 layer_group_string = NULL;
180 pcbfileversion
181 pcbname
182 pcbgrid
183 pcbcursor
184 polyarea
185 pcbthermal
186 pcbdrc
187 pcbflags
188 pcbgroups
189 pcbstyles
190 pcbfont
191 pcbdata
192 pcbnetlist
194 PCBType *pcb_save = PCB;
196 if (layer_group_string == NULL)
197 layer_group_string = Settings.Groups;
198 CreateNewPCBPost (yyPCB, 0);
199 if (ParseGroupString(layer_group_string, &yyPCB->LayerGroups, yyData->LayerN))
201 Message("illegal layer-group string\n");
202 YYABORT;
204 /* initialize the polygon clipping now since
205 * we didn't know the layer grouping before.
207 PCB = yyPCB;
208 ALLPOLYGON_LOOP (yyData);
210 InitClip (yyData, layer, polygon);
212 ENDALL_LOOP;
213 PCB = pcb_save;
216 | { PreLoadElementPCB ();
217 layer_group_string = NULL; }
218 element
219 { LayerFlag[0] = true;
220 LayerFlag[1] = true;
221 yyData->LayerN = 2;
222 PostLoadElementPCB ();
226 parsedata
228 /* reset flags for 'used layers';
229 * init font and data pointers
231 int i;
233 if (!yyData || !yyFont)
235 Message("illegal fileformat\n");
236 YYABORT;
238 for (i = 0; i < MAX_LAYER + 2; i++)
239 LayerFlag[i] = false;
240 yyData->LayerN = 0;
242 pcbdata
245 pcbfont
246 : parsefont
250 parsefont
253 /* mark all symbols invalid */
254 int i;
256 if (!yyFont)
258 Message("illegal fileformat\n");
259 YYABORT;
261 yyFont->Valid = false;
262 for (i = 0; i <= MAX_FONTPOSITION; i++)
263 free (yyFont->Symbol[i].Line);
264 bzero(yyFont->Symbol, sizeof(yyFont->Symbol));
266 symbols
268 yyFont->Valid = true;
269 SetFontInfo(yyFont);
273 /* %start-doc pcbfile FileVersion
275 @syntax
276 FileVersion[Version]
277 @end syntax
279 @table @var
280 @item Version
281 File format version. This version number represents the date when the pcb file
282 format was last changed.
283 @end table
285 Any version of pcb build from sources equal to or newer
286 than this number should be able to read the file. If this line is not present
287 in the input file then file format compatibility is not checked.
290 %end-doc */
292 pcbfileversion
294 T_FILEVERSION '[' INTEGER ']'
296 if (check_file_version ($3) != 0)
298 YYABORT;
303 /* %start-doc pcbfile PCB
305 @syntax
306 PCB ["Name" Width Height]
307 PCB ("Name" Width Height]
308 PCB ("Name")
309 @end syntax
311 @table @var
312 @item Name
313 Name of the PCB project
314 @item Width Height
315 Size of the board
316 @end table
318 If you don't specify the size of the board, a very large default is
319 chosen.
321 %end-doc */
323 pcbname
324 : T_PCB '(' STRING ')'
326 yyPCB->Name = $3;
327 yyPCB->MaxWidth = MAX_COORD;
328 yyPCB->MaxHeight = MAX_COORD;
330 | T_PCB '(' STRING measure measure ')'
332 yyPCB->Name = $3;
333 yyPCB->MaxWidth = OU ($4);
334 yyPCB->MaxHeight = OU ($5);
336 | T_PCB '[' STRING measure measure ']'
338 yyPCB->Name = $3;
339 yyPCB->MaxWidth = NU ($4);
340 yyPCB->MaxHeight = NU ($5);
344 /* %start-doc pcbfile Grid
346 @syntax
347 Grid [Step OffsetX OffsetY Visible]
348 Grid (Step OffsetX OffsetY Visible)
349 Grid (Step OffsetX OffsetY)
350 @end syntax
352 @table @var
353 @item Step
354 Distance from one grid point to adjacent points. This value may be a
355 floating point number for the first two variants.
356 @item OffsetX OffsetY
357 The "origin" of the grid. Normally zero.
358 @item Visible
359 If non-zero, the grid will be visible on the screen.
360 @end table
362 %end-doc */
364 pcbgrid
365 : pcbgridold
366 | pcbgridnew
367 | pcbhigrid
369 pcbgridold
370 : T_GRID '(' measure measure measure ')'
372 yyPCB->Grid = OU ($3);
373 yyPCB->GridOffsetX = OU ($4);
374 yyPCB->GridOffsetY = OU ($5);
377 pcbgridnew
378 : T_GRID '(' measure measure measure INTEGER ')'
380 yyPCB->Grid = OU ($3);
381 yyPCB->GridOffsetX = OU ($4);
382 yyPCB->GridOffsetY = OU ($5);
383 if ($6)
384 Settings.DrawGrid = true;
385 else
386 Settings.DrawGrid = false;
390 pcbhigrid
391 : T_GRID '[' measure measure measure INTEGER ']'
393 yyPCB->Grid = NU ($3);
394 yyPCB->GridOffsetX = NU ($4);
395 yyPCB->GridOffsetY = NU ($5);
396 if ($6)
397 Settings.DrawGrid = true;
398 else
399 Settings.DrawGrid = false;
403 /* %start-doc pcbfile Cursor
405 @syntax
406 Cursor [X Y Zoom]
407 Cursor (X Y Zoom)
408 @end syntax
410 @table @var
411 @item X Y
412 Location of the cursor when the board was saved.
413 As of November 2012 the cursor position is not written to file anymore.
414 Older versions of pcb ignore the absence of this line in the pcb file.
415 @item Zoom
416 The current zoom factor. Note that a zoom factor of "0" means 1 mil
417 per screen pixel, N means @math{2^N} mils per screen pixel, etc. The
418 first variant accepts floating point numbers. The special value
419 "1000" means "zoom to fit"
421 This field is ignored by PCB.
422 @end table
424 %end-doc */
426 pcbcursor
427 : T_CURSOR '(' measure measure number ')'
429 yyPCB->CursorX = OU ($3);
430 yyPCB->CursorY = OU ($4);
432 | T_CURSOR '[' measure measure number ']'
434 yyPCB->CursorX = NU ($3);
435 yyPCB->CursorY = NU ($4);
440 /* %start-doc pcbfile PolyArea
442 @syntax
443 PolyArea [Area]
444 @end syntax
446 @table @var
447 @item Area
448 Minimum area of polygon island to retain. If a polygon has clearances that cause an isolated island to be created, then will only be retained if the area exceeds this minimum area.
449 @end table
451 %end-doc */
453 polyarea
455 | T_AREA '[' number ']'
457 /* Read in cmil^2 for now; in future this should be a noop. */
458 yyPCB->IsleArea = MIL_TO_COORD (MIL_TO_COORD ($3) / 100.0) / 100.0;
463 /* %start-doc pcbfile Thermal
465 @syntax
466 Thermal [Scale]
467 @end syntax
469 @table @var
470 @item Scale
471 Relative size of thermal fingers. A value of 1.0 makes the finger
472 width twice the clearance gap width (measured across the gap, not
473 diameter). The normal value is 0.5, which results in a finger width
474 the same as the clearance gap width.
475 @end table
477 %end-doc */
480 pcbthermal
482 | T_THERMAL '[' number ']'
484 yyPCB->ThermScale = $3;
488 /* %start-doc pcbfile DRC
490 @syntax
491 DRC [Bloat Shrink Line Silk Drill Ring]
492 DRC [Bloat Shrink Line Silk]
493 DRC [Bloat Shrink Line]
494 @end syntax
496 @table @var
497 @item Bloat
498 Minimum spacing between copper.
499 @item Shrink
500 Minimum copper overlap to guarantee connectivity.
501 @item Line
502 Minimum line thickness.
503 @item Silk
504 Minimum silk thickness.
505 @item Drill
506 Minimum drill size.
507 @item Ring
508 Minimum width of the annular ring around pins and vias.
509 @end table
511 %end-doc */
513 pcbdrc
515 | pcbdrc1
516 | pcbdrc2
517 | pcbdrc3
520 pcbdrc1
521 : T_DRC '[' measure measure measure ']'
523 yyPCB->Bloat = NU ($3);
524 yyPCB->Shrink = NU ($4);
525 yyPCB->minWid = NU ($5);
526 yyPCB->minRing = NU ($5);
530 pcbdrc2
531 : T_DRC '[' measure measure measure measure ']'
533 yyPCB->Bloat = NU ($3);
534 yyPCB->Shrink = NU ($4);
535 yyPCB->minWid = NU ($5);
536 yyPCB->minSlk = NU ($6);
537 yyPCB->minRing = NU ($5);
541 pcbdrc3
542 : T_DRC '[' measure measure measure measure measure measure ']'
544 yyPCB->Bloat = NU ($3);
545 yyPCB->Shrink = NU ($4);
546 yyPCB->minWid = NU ($5);
547 yyPCB->minSlk = NU ($6);
548 yyPCB->minDrill = NU ($7);
549 yyPCB->minRing = NU ($8);
553 /* %start-doc pcbfile Flags
555 @syntax
556 Flags(Number)
557 @end syntax
559 @table @var
560 @item Number
561 A number, whose value is normally given in hex, individual bits of which
562 represent pcb-wide flags as defined in @ref{PCBFlags}.
564 @end table
566 %end-doc */
568 pcbflags
569 : T_FLAGS '(' INTEGER ')'
571 yyPCB->Flags = MakeFlags ($3 & PCB_FLAGS);
573 | T_FLAGS '(' STRING ')'
575 yyPCB->Flags = string_to_pcbflags ($3, yyerror);
580 /* %start-doc pcbfile Groups
582 @syntax
583 Groups("String")
584 @end syntax
586 @table @var
587 @item String
589 Encodes the layer grouping information. Each group is separated by a
590 colon, each member of each group is separated by a comma. Group
591 members are either numbers from @code{1}..@var{N} for each layer, and
592 the letters @code{c} or @code{s} representing the component side and
593 solder side of the board. Including @code{c} or @code{s} marks that
594 group as being the top or bottom side of the board.
596 @example
597 Groups("1,2,c:3:4:5,6,s:7,8")
598 @end example
600 @end table
602 %end-doc */
604 pcbgroups
605 : T_GROUPS '(' STRING ')'
607 layer_group_string = $3;
612 /* %start-doc pcbfile Styles
614 @syntax
615 Styles("String")
616 @end syntax
618 @table @var
619 @item String
621 Encodes the four routing styles @code{pcb} knows about. The four styles
622 are separated by colons. Each style consists of five parameters as follows:
624 @table @var
625 @item Name
626 The name of the style.
627 @item Thickness
628 Width of lines and arcs.
629 @item Diameter
630 Copper diameter of pins and vias.
631 @item Drill
632 Drill diameter of pins and vias.
633 @item Keepaway
634 Minimum spacing to other nets. If omitted, 10 mils is the default.
636 @end table
638 @end table
640 @example
641 Styles("Signal,10,40,20:Power,25,60,35:Fat,40,60,35:Skinny,8,36,20")
642 Styles["Logic,1000,3600,2000,1000:Power,2500,6000,3500,1000:
643 @ @ @ Line,4000,6000,3500,1000:Breakout,600,2402,1181,600"]
644 @end example
646 @noindent
647 Note that strings in actual files cannot span lines; the above example
648 is split across lines only to make it readable.
650 %end-doc */
652 pcbstyles
653 : T_STYLES '(' STRING ')'
655 if (ParseRouteString($3, &yyPCB->RouteStyle[0], "mil"))
657 Message("illegal route-style string\n");
658 YYABORT;
661 | T_STYLES '[' STRING ']'
663 if (ParseRouteString($3, &yyPCB->RouteStyle[0], "cmil"))
665 Message("illegal route-style string\n");
666 YYABORT;
672 pcbdata
673 : pcbdefinitions
677 pcbdefinitions
678 : pcbdefinition
679 | pcbdefinitions pcbdefinition
682 pcbdefinition
683 : via
684 | { attr_list = & yyPCB->Attributes; } attribute
685 | rats
686 | layer
689 /* clear pointer to force memory allocation by
690 * the appropriate subroutine
692 yyElement = NULL;
694 element
695 | error { YYABORT; }
699 : via_hi_format
700 | via_2.0_format
701 | via_1.7_format
702 | via_newformat
703 | via_oldformat
706 /* %start-doc pcbfile Via
708 @syntax
709 Via [X Y Thickness Clearance Mask Drill "Name" SFlags]
710 Via (X Y Thickness Clearance Mask Drill "Name" NFlags)
711 Via (X Y Thickness Clearance Drill "Name" NFlags)
712 Via (X Y Thickness Drill "Name" NFlags)
713 Via (X Y Thickness "Name" NFlags)
714 @end syntax
716 @table @var
717 @item X Y
718 coordinates of center
719 @item Thickness
720 outer diameter of copper annulus
721 @item Clearance
722 add to thickness to get clearance diameter
723 @item Mask
724 diameter of solder mask opening
725 @item Drill
726 diameter of drill
727 @item Name
728 string, name of via (vias have names?)
729 @item SFlags
730 symbolic or numerical flags
731 @item NFlags
732 numerical flags only
733 @end table
735 %end-doc */
737 via_hi_format
738 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
739 : T_VIA '[' measure measure measure measure measure measure STRING flags ']'
741 CreateNewVia(yyData, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7),
742 NU ($8), $9, $10);
743 free ($9);
747 via_2.0_format
748 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
749 : T_VIA '(' measure measure measure measure measure measure STRING INTEGER ')'
751 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7), OU ($8), $9,
752 OldFlags($10));
753 free ($9);
758 via_1.7_format
759 /* x, y, thickness, clearance, drilling-hole, name, flags */
760 : T_VIA '(' measure measure measure measure measure STRING INTEGER ')'
762 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), OU ($6),
763 OU ($5) + OU($6), OU ($7), $8, OldFlags($9));
764 free ($8);
768 via_newformat
769 /* x, y, thickness, drilling-hole, name, flags */
770 : T_VIA '(' measure measure measure measure STRING INTEGER ')'
772 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
773 OU($5) + 2*MASKFRAME, OU ($6), $7, OldFlags($8));
774 free ($7);
778 via_oldformat
779 /* old format: x, y, thickness, name, flags */
780 : T_VIA '(' measure measure measure STRING INTEGER ')'
782 Coord hole = (OU($5) * DEFAULT_DRILLINGHOLE);
784 /* make sure that there's enough copper left */
785 if (OU($5) - hole < MIN_PINORVIACOPPER &&
786 OU($5) > MIN_PINORVIACOPPER)
787 hole = OU($5) - MIN_PINORVIACOPPER;
789 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
790 OU($5) + 2*MASKFRAME, hole, $6, OldFlags($7));
791 free ($6);
795 /* %start-doc pcbfile Rat
797 @syntax
798 Rat [X1 Y1 Group1 X2 Y2 Group2 SFlags]
799 Rat (X1 Y1 Group1 X2 Y2 Group2 NFlags)
800 @end syntax
802 @table @var
803 @item X1 Y1 X2 Y2
804 The endpoints of the rat line.
805 @item Group1 Group2
806 The layer group each end is connected on.
807 @item SFlags
808 Symbolic or numeric flags.
809 @item NFlags
810 Numeric flags.
811 @end table
813 %end-doc */
815 rats
816 : T_RAT '[' measure measure INTEGER measure measure INTEGER flags ']'
818 CreateNewRat(yyData, NU ($3), NU ($4), NU ($6), NU ($7), $5, $8,
819 Settings.RatThickness, $9);
821 | T_RAT '(' measure measure INTEGER measure measure INTEGER INTEGER ')'
823 CreateNewRat(yyData, OU ($3), OU ($4), OU ($6), OU ($7), $5, $8,
824 Settings.RatThickness, OldFlags($9));
828 /* %start-doc pcbfile Layer
830 @syntax
831 Layer (LayerNum "Name") (
832 @ @ @ @dots{} contents @dots{}
834 @end syntax
836 @table @var
837 @item LayerNum
838 The layer number. Layers are numbered sequentially, starting with 1.
839 The last two layers (9 and 10 by default) are solder-side silk and
840 component-side silk, in that order.
841 @item Name
842 The layer name.
843 @item contents
844 The contents of the layer, which may include attributes, lines, arcs, rectangles,
845 text, and polygons.
846 @end table
848 %end-doc */
850 layer
851 /* name */
852 : T_LAYER '(' INTEGER STRING opt_string ')' '('
854 if ($3 <= 0 || $3 > MAX_LAYER + 2)
856 yyerror("Layernumber out of range");
857 YYABORT;
859 if (LayerFlag[$3-1])
861 yyerror("Layernumber used twice");
862 YYABORT;
864 Layer = &yyData->Layer[$3-1];
866 /* memory for name is already allocated */
867 Layer->Name = $4;
868 if (Layer->Name == NULL)
869 Layer->Name = strdup("");
870 LayerFlag[$3-1] = true;
871 if (yyData->LayerN + 2 < $3)
872 yyData->LayerN = $3 - 2;
874 layerdata ')'
877 layerdata
878 : layerdefinitions
882 layerdefinitions
883 : layerdefinition
884 | layerdefinitions layerdefinition
887 layerdefinition
888 : line_hi_format
889 | line_1.7_format
890 | line_oldformat
891 | arc_hi_format
892 | arc_1.7_format
893 | arc_oldformat
894 /* x1, y1, x2, y2, flags */
895 | T_RECTANGLE '(' measure measure measure measure INTEGER ')'
897 CreateNewPolygonFromRectangle(Layer,
898 OU ($3), OU ($4), OU ($3) + OU ($5), OU ($4) + OU ($6), OldFlags($7));
900 | text_hi_format
901 | text_newformat
902 | text_oldformat
903 | { attr_list = & Layer->Attributes; } attribute
904 | polygon_format
906 /* %start-doc pcbfile Line
908 @syntax
909 Line [X1 Y1 X2 Y2 Thickness Clearance SFlags]
910 Line (X1 Y1 X2 Y2 Thickness Clearance NFlags)
911 Line (X1 Y1 X2 Y2 Thickness NFlags)
912 @end syntax
914 @table @var
915 @item X1 Y1 X2 Y2
916 The end points of the line
917 @item Thickness
918 The width of the line
919 @item Clearance
920 The amount of space cleared around the line when the line passes
921 through a polygon. The clearance is added to the thickness to get the
922 thickness of the clear; thus the space between the line and the
923 polygon is @math{Clearance/2} wide.
924 @item SFlags
925 Symbolic or numeric flags
926 @item NFlags
927 Numeric flags.
928 @end table
930 %end-doc */
932 line_hi_format
933 /* x1, y1, x2, y2, thickness, clearance, flags */
934 : T_LINE '[' measure measure measure measure measure measure flags ']'
936 CreateNewLineOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6),
937 NU ($7), NU ($8), $9);
941 line_1.7_format
942 /* x1, y1, x2, y2, thickness, clearance, flags */
943 : T_LINE '(' measure measure measure measure measure measure INTEGER ')'
945 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6),
946 OU ($7), OU ($8), OldFlags($9));
950 line_oldformat
951 /* x1, y1, x2, y2, thickness, flags */
952 : T_LINE '(' measure measure measure measure measure measure ')'
954 /* eliminate old-style rat-lines */
955 if ((IV ($8) & RATFLAG) == 0)
956 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7),
957 200*GROUNDPLANEFRAME, OldFlags(IV ($8)));
961 /* %start-doc pcbfile Arc
963 @syntax
964 Arc [X Y Width Height Thickness Clearance StartAngle DeltaAngle SFlags]
965 Arc (X Y Width Height Thickness Clearance StartAngle DeltaAngle NFlags)
966 Arc (X Y Width Height Thickness StartAngle DeltaAngle NFlags)
967 @end syntax
969 @table @var
970 @item X Y
971 Coordinates of the center of the arc.
972 @item Width Height
973 The width and height, from the center to the edge. The bounds of the
974 circle of which this arc is a segment, is thus @math{2*Width} by
975 @math{2*Height}.
976 @item Thickness
977 The width of the copper trace which forms the arc.
978 @item Clearance
979 The amount of space cleared around the arc when the line passes
980 through a polygon. The clearance is added to the thickness to get the
981 thickness of the clear; thus the space between the arc and the polygon
982 is @math{Clearance/2} wide.
983 @item StartAngle
984 The angle of one end of the arc, in degrees. In PCB, an angle of zero
985 points left (negative X direction), and 90 degrees points down
986 (positive Y direction).
987 @item DeltaAngle
988 The sweep of the arc. This may be negative. Positive angles sweep
989 counterclockwise.
990 @item SFlags
991 Symbolic or numeric flags.
992 @item NFlags
993 Numeric flags.
994 @end table
996 %end-doc */
998 arc_hi_format
999 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
1000 : T_ARC '[' measure measure measure measure measure measure number number flags ']'
1002 CreateNewArcOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6), $9, $10,
1003 NU ($7), NU ($8), $11);
1007 arc_1.7_format
1008 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
1009 : T_ARC '(' measure measure measure measure measure measure number number INTEGER ')'
1011 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), $9, $10,
1012 OU ($7), OU ($8), OldFlags($11));
1016 arc_oldformat
1017 /* x, y, width, height, thickness, startangle, delta, flags */
1018 : T_ARC '(' measure measure measure measure measure measure number INTEGER ')'
1020 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($5), IV ($8), $9,
1021 OU ($7), 200*GROUNDPLANEFRAME, OldFlags($10));
1025 /* %start-doc pcbfile Text
1027 @syntax
1028 Text [X Y Direction Scale "String" SFlags]
1029 Text (X Y Direction Scale "String" NFlags)
1030 Text (X Y Direction "String" NFlags)
1031 @end syntax
1033 @table @var
1034 @item X Y
1035 The location of the upper left corner of the text.
1036 @item Direction
1037 0 means text is drawn left to right, 1 means up, 2 means right to left
1038 (i.e. upside down), and 3 means down.
1039 @item Scale
1040 Size of the text, as a percentage of the ``default'' size of of the
1041 font (the default font is about 40 mils high). Default is 100 (40
1042 mils).
1043 @item String
1044 The string to draw.
1045 @item SFlags
1046 Symbolic or numeric flags.
1047 @item NFlags
1048 Numeric flags.
1049 @end table
1051 %end-doc */
1053 text_oldformat
1054 /* x, y, direction, text, flags */
1055 : T_TEXT '(' measure measure number STRING INTEGER ')'
1057 /* use a default scale of 100% */
1058 CreateNewText(Layer,yyFont,OU ($3), OU ($4), $5, 100, $6, OldFlags($7));
1059 free ($6);
1063 text_newformat
1064 /* x, y, direction, scale, text, flags */
1065 : T_TEXT '(' measure measure number number STRING INTEGER ')'
1067 if ($8 & ONSILKFLAG)
1069 LayerType *lay = &yyData->Layer[yyData->LayerN +
1070 (($8 & ONSOLDERFLAG) ? SOLDER_LAYER : COMPONENT_LAYER)];
1072 CreateNewText(lay ,yyFont, OU ($3), OU ($4), $5, $6, $7,
1073 OldFlags($8));
1075 else
1076 CreateNewText(Layer, yyFont, OU ($3), OU ($4), $5, $6, $7,
1077 OldFlags($8));
1078 free ($7);
1081 text_hi_format
1082 /* x, y, direction, scale, text, flags */
1083 : T_TEXT '[' measure measure number number STRING flags ']'
1085 /* FIXME: shouldn't know about .f */
1086 /* I don't think this matters because anything with hi_format
1087 * will have the silk on its own layer in the file rather
1088 * than using the ONSILKFLAG and having it in a copper layer.
1089 * Thus there is no need for anything besides the 'else'
1090 * part of this code.
1092 if ($8.f & ONSILKFLAG)
1094 LayerType *lay = &yyData->Layer[yyData->LayerN +
1095 (($8.f & ONSOLDERFLAG) ? SOLDER_LAYER : COMPONENT_LAYER)];
1097 CreateNewText(lay, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1099 else
1100 CreateNewText(Layer, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1101 free ($7);
1105 /* %start-doc pcbfile Polygon
1107 @syntax
1108 Polygon (SFlags) (
1109 @ @ @ @dots{} (X Y) @dots{}
1110 @ @ @ @dots{} [X Y] @dots{}
1111 @ @ @ Hole (
1112 @ @ @ @ @ @ @dots{} (X Y) @dots{}
1113 @ @ @ @ @ @ @dots{} [X Y] @dots{}
1114 @ @ @ )
1115 @ @ @ @dots{}
1117 @end syntax
1119 @table @var
1120 @item SFlags
1121 Symbolic or numeric flags.
1122 @item X Y
1123 Coordinates of each vertex. You must list at least three coordinates.
1124 @item Hole (...)
1125 Defines a hole within the polygon's outer contour. There may be zero or more such sections.
1126 @end table
1128 %end-doc */
1130 polygon_format
1131 : /* flags are passed in */
1132 T_POLYGON '(' flags ')' '('
1134 Polygon = CreateNewPolygon(Layer, $3);
1136 polygonpoints
1137 polygonholes ')'
1139 Cardinal contour, contour_start, contour_end;
1140 bool bad_contour_found = false;
1141 /* ignore junk */
1142 for (contour = 0; contour <= Polygon->HoleIndexN; contour++)
1144 contour_start = (contour == 0) ?
1145 0 : Polygon->HoleIndex[contour - 1];
1146 contour_end = (contour == Polygon->HoleIndexN) ?
1147 Polygon->PointN :
1148 Polygon->HoleIndex[contour];
1149 if (contour_end - contour_start < 3)
1150 bad_contour_found = true;
1153 if (bad_contour_found)
1155 Message("WARNING parsing file '%s'\n"
1156 " line: %i\n"
1157 " description: 'ignored polygon (< 3 points in a contour)'\n",
1158 yyfilename, yylineno);
1159 DestroyObject(yyData, POLYGON_TYPE, Layer, Polygon, Polygon);
1161 else
1163 SetPolygonBoundingBox (Polygon);
1164 if (!Layer->polygon_tree)
1165 Layer->polygon_tree = r_create_tree (NULL, 0, 0);
1166 r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
1171 polygonholes
1172 : /* empty */
1173 | polygonholes polygonhole
1176 polygonhole
1177 : T_POLYGON_HOLE '('
1179 CreateNewHoleInPolygon (Polygon);
1181 polygonpoints ')'
1184 polygonpoints
1185 : /* empty */
1186 | polygonpoint polygonpoints
1189 polygonpoint
1190 /* xcoord ycoord */
1191 : '(' measure measure ')'
1193 CreateNewPointInPolygon(Polygon, OU ($2), OU ($3));
1195 | '[' measure measure ']'
1197 CreateNewPointInPolygon(Polygon, NU ($2), NU ($3));
1201 /* %start-doc pcbfile Element
1203 @syntax
1204 Element [SFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TSFlags] (
1205 Element (NFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TNFlags) (
1206 Element (NFlags "Desc" "Name" "Value" TX TY TDir TScale TNFlags) (
1207 Element (NFlags "Desc" "Name" TX TY TDir TScale TNFlags) (
1208 Element ("Desc" "Name" TX TY TDir TScale TNFlags) (
1209 @ @ @ @dots{} contents @dots{}
1211 @end syntax
1213 @table @var
1214 @item SFlags
1215 Symbolic or numeric flags, for the element as a whole.
1216 @item NFlags
1217 Numeric flags, for the element as a whole.
1218 @item Desc
1219 The description of the element. This is one of the three strings
1220 which can be displayed on the screen.
1221 @item Name
1222 The name of the element, usually the reference designator.
1223 @item Value
1224 The value of the element.
1225 @item MX MY
1226 The location of the element's mark. This is the reference point
1227 for placing the element and its pins and pads.
1228 @item TX TY
1229 The upper left corner of the text (one of the three strings).
1230 @item TDir
1231 The relative direction of the text. 0 means left to right for
1232 an unrotated element, 1 means up, 2 left, 3 down.
1233 @item TScale
1234 Size of the text, as a percentage of the ``default'' size of of the
1235 font (the default font is about 40 mils high). Default is 100 (40
1236 mils).
1237 @item TSFlags
1238 Symbolic or numeric flags, for the text.
1239 @item TNFlags
1240 Numeric flags, for the text.
1241 @end table
1243 Elements may contain pins, pads, element lines, element arcs,
1244 attributes, and (for older elements) an optional mark. Note that
1245 element definitions that have the mark coordinates in the element
1246 line, only support pins and pads which use relative coordinates. The
1247 pin and pad coordinates are relative to the mark. Element definitions
1248 which do not include the mark coordinates in the element line, may
1249 have a Mark definition in their contents, and only use pin and pad
1250 definitions which use absolute coordinates.
1252 %end-doc */
1254 element
1255 : element_oldformat
1256 | element_1.3.4_format
1257 | element_newformat
1258 | element_1.7_format
1259 | element_hi_format
1262 element_oldformat
1263 /* element_flags, description, pcb-name,
1264 * text_x, text_y, text_direction, text_scale, text_flags
1266 : T_ELEMENT '(' STRING STRING measure measure INTEGER ')' '('
1268 yyElement = CreateNewElement(yyData, yyElement, yyFont, NoFlags(),
1269 $3, $4, NULL, OU ($5), OU ($6), $7, 100, NoFlags(), false);
1270 free ($3);
1271 free ($4);
1272 pin_num = 1;
1274 elementdefinitions ')'
1276 SetElementBoundingBox(yyData, yyElement, yyFont);
1280 element_1.3.4_format
1281 /* element_flags, description, pcb-name,
1282 * text_x, text_y, text_direction, text_scale, text_flags
1284 : T_ELEMENT '(' INTEGER STRING STRING measure measure measure measure INTEGER ')' '('
1286 yyElement = CreateNewElement(yyData, yyElement, yyFont, OldFlags($3),
1287 $4, $5, NULL, OU ($6), OU ($7), IV ($8), IV ($9), OldFlags($10), false);
1288 free ($4);
1289 free ($5);
1290 pin_num = 1;
1292 elementdefinitions ')'
1294 SetElementBoundingBox(yyData, yyElement, yyFont);
1298 element_newformat
1299 /* element_flags, description, pcb-name, value,
1300 * text_x, text_y, text_direction, text_scale, text_flags
1302 : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure measure measure INTEGER ')' '('
1304 yyElement = CreateNewElement(yyData, yyElement, yyFont, OldFlags($3),
1305 $4, $5, $6, OU ($7), OU ($8), IV ($9), IV ($10), OldFlags($11), false);
1306 free ($4);
1307 free ($5);
1308 free ($6);
1309 pin_num = 1;
1311 elementdefinitions ')'
1313 SetElementBoundingBox(yyData, yyElement, yyFont);
1317 element_1.7_format
1318 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1319 * text_x, text_y, text_direction, text_scale, text_flags
1321 : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure
1322 measure measure number number INTEGER ')' '('
1324 yyElement = CreateNewElement(yyData, yyElement, yyFont, OldFlags($3),
1325 $4, $5, $6, OU ($7) + OU ($9), OU ($8) + OU ($10),
1326 $11, $12, OldFlags($13), false);
1327 yyElement->MarkX = OU ($7);
1328 yyElement->MarkY = OU ($8);
1329 free ($4);
1330 free ($5);
1331 free ($6);
1333 relementdefs ')'
1335 SetElementBoundingBox(yyData, yyElement, yyFont);
1339 element_hi_format
1340 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1341 * text_x, text_y, text_direction, text_scale, text_flags
1343 : T_ELEMENT '[' flags STRING STRING STRING measure measure
1344 measure measure number number flags ']' '('
1346 yyElement = CreateNewElement(yyData, yyElement, yyFont, $3,
1347 $4, $5, $6, NU ($7) + NU ($9), NU ($8) + NU ($10),
1348 $11, $12, $13, false);
1349 yyElement->MarkX = NU ($7);
1350 yyElement->MarkY = NU ($8);
1351 free ($4);
1352 free ($5);
1353 free ($6);
1355 relementdefs ')'
1357 SetElementBoundingBox(yyData, yyElement, yyFont);
1361 /* %start-doc pcbfile ElementLine
1363 @syntax
1364 ElementLine [X1 Y1 X2 Y2 Thickness]
1365 ElementLine (X1 Y1 X2 Y2 Thickness)
1366 @end syntax
1368 @table @var
1369 @item X1 Y1 X2 Y2
1370 Coordinates of the endpoints of the line. These are relative to the
1371 Element's mark point for new element formats, or absolute for older
1372 formats.
1373 @item Thickness
1374 The width of the silk for this line.
1375 @end table
1377 %end-doc */
1379 /* %start-doc pcbfile ElementArc
1381 @syntax
1382 ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
1383 ElementArc (X Y Width Height StartAngle DeltaAngle Thickness)
1384 @end syntax
1386 @table @var
1387 @item X Y
1388 Coordinates of the center of the arc. These are relative to the
1389 Element's mark point for new element formats, or absolute for older
1390 formats.
1391 @item Width Height
1392 The width and height, from the center to the edge. The bounds of the
1393 circle of which this arc is a segment, is thus @math{2*Width} by
1394 @math{2*Height}.
1395 @item StartAngle
1396 The angle of one end of the arc, in degrees. In PCB, an angle of zero
1397 points left (negative X direction), and 90 degrees points down
1398 (positive Y direction).
1399 @item DeltaAngle
1400 The sweep of the arc. This may be negative. Positive angles sweep
1401 counterclockwise.
1402 @item Thickness
1403 The width of the silk line which forms the arc.
1404 @end table
1406 %end-doc */
1408 /* %start-doc pcbfile Mark
1410 @syntax
1411 Mark [X Y]
1412 Mark (X Y)
1413 @end syntax
1415 @table @var
1416 @item X Y
1417 Coordinates of the Mark, for older element formats that don't have
1418 the mark as part of the Element line.
1419 @end table
1421 %end-doc */
1423 elementdefinitions
1424 : elementdefinition
1425 | elementdefinitions elementdefinition
1428 elementdefinition
1429 : pin_1.6.3_format
1430 | pin_newformat
1431 | pin_oldformat
1432 | pad_newformat
1433 | pad
1434 /* x1, y1, x2, y2, thickness */
1435 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1437 CreateNewLineInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1439 /* x1, y1, x2, y2, thickness */
1440 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1442 CreateNewLineInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1444 /* x, y, width, height, startangle, anglediff, thickness */
1445 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1447 CreateNewArcInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), $7, $8, NU ($9));
1449 /* x, y, width, height, startangle, anglediff, thickness */
1450 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1452 CreateNewArcInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), $7, $8, OU ($9));
1454 /* x, y position */
1455 | T_MARK '[' measure measure ']'
1457 yyElement->MarkX = NU ($3);
1458 yyElement->MarkY = NU ($4);
1460 | T_MARK '(' measure measure ')'
1462 yyElement->MarkX = OU ($3);
1463 yyElement->MarkY = OU ($4);
1465 | { attr_list = & yyElement->Attributes; } attribute
1468 relementdefs
1469 : relementdef
1470 | relementdefs relementdef
1473 relementdef
1474 : pin_1.7_format
1475 | pin_hi_format
1476 | pad_1.7_format
1477 | pad_hi_format
1478 /* x1, y1, x2, y2, thickness */
1479 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1481 CreateNewLineInElement(yyElement, NU ($3) + yyElement->MarkX,
1482 NU ($4) + yyElement->MarkY, NU ($5) + yyElement->MarkX,
1483 NU ($6) + yyElement->MarkY, NU ($7));
1485 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1487 CreateNewLineInElement(yyElement, OU ($3) + yyElement->MarkX,
1488 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1489 OU ($6) + yyElement->MarkY, OU ($7));
1491 /* x, y, width, height, startangle, anglediff, thickness */
1492 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1494 CreateNewArcInElement(yyElement, NU ($3) + yyElement->MarkX,
1495 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), $7, $8, NU ($9));
1497 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1499 CreateNewArcInElement(yyElement, OU ($3) + yyElement->MarkX,
1500 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), $7, $8, OU ($9));
1502 | { attr_list = & yyElement->Attributes; } attribute
1505 /* %start-doc pcbfile Pin
1507 @syntax
1508 Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags]
1509 Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags)
1510 Pin (aX aY Thickness Drill "Name" "Number" NFlags)
1511 Pin (aX aY Thickness Drill "Name" NFlags)
1512 Pin (aX aY Thickness "Name" NFlags)
1513 @end syntax
1515 @table @var
1516 @item rX rY
1517 coordinates of center, relative to the element's mark
1518 @item aX aY
1519 absolute coordinates of center.
1520 @item Thickness
1521 outer diameter of copper annulus
1522 @item Clearance
1523 add to thickness to get clearance diameter
1524 @item Mask
1525 diameter of solder mask opening
1526 @item Drill
1527 diameter of drill
1528 @item Name
1529 name of pin
1530 @item Number
1531 number of pin
1532 @item SFlags
1533 symbolic or numerical flags
1534 @item NFlags
1535 numerical flags only
1536 @end table
1538 %end-doc */
1540 pin_hi_format
1541 /* x, y, thickness, clearance, mask, drilling hole, name,
1542 number, flags */
1543 : T_PIN '[' measure measure measure measure measure measure STRING STRING flags ']'
1545 CreateNewPin(yyElement, NU ($3) + yyElement->MarkX,
1546 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), NU ($7), NU ($8), $9,
1547 $10, $11);
1548 free ($9);
1549 free ($10);
1552 pin_1.7_format
1553 /* x, y, thickness, clearance, mask, drilling hole, name,
1554 number, flags */
1555 : T_PIN '(' measure measure measure measure measure measure STRING STRING INTEGER ')'
1557 CreateNewPin(yyElement, OU ($3) + yyElement->MarkX,
1558 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), OU ($7), OU ($8), $9,
1559 $10, OldFlags($11));
1560 free ($9);
1561 free ($10);
1565 pin_1.6.3_format
1566 /* x, y, thickness, drilling hole, name, number, flags */
1567 : T_PIN '(' measure measure measure measure STRING STRING INTEGER ')'
1569 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1570 OU ($5) + 2*MASKFRAME, OU ($6), $7, $8, OldFlags($9));
1571 free ($7);
1572 free ($8);
1576 pin_newformat
1577 /* x, y, thickness, drilling hole, name, flags */
1578 : T_PIN '(' measure measure measure measure STRING INTEGER ')'
1580 char p_number[8];
1582 sprintf(p_number, "%d", pin_num++);
1583 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1584 OU ($5) + 2*MASKFRAME, OU ($6), $7, p_number, OldFlags($8));
1586 free ($7);
1590 pin_oldformat
1591 /* old format: x, y, thickness, name, flags
1592 * drilling hole is 40% of the diameter
1594 : T_PIN '(' measure measure measure STRING INTEGER ')'
1596 Coord hole = OU ($5) * DEFAULT_DRILLINGHOLE;
1597 char p_number[8];
1599 /* make sure that there's enough copper left */
1600 if (OU ($5) - hole < MIN_PINORVIACOPPER &&
1601 OU ($5) > MIN_PINORVIACOPPER)
1602 hole = OU ($5) - MIN_PINORVIACOPPER;
1604 sprintf(p_number, "%d", pin_num++);
1605 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1606 OU ($5) + 2*MASKFRAME, hole, $6, p_number, OldFlags($7));
1607 free ($6);
1611 /* %start-doc pcbfile Pad
1613 @syntax
1614 Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags]
1615 Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags)
1616 Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags)
1617 Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags)
1618 @end syntax
1620 @table @var
1621 @item rX1 rY1 rX2 rY2
1622 Coordinates of the endpoints of the pad, relative to the element's
1623 mark. Note that the copper extends beyond these coordinates by half
1624 the thickness. To make a square or round pad, specify the same
1625 coordinate twice.
1626 @item aX1 aY1 aX2 aY2
1627 Same, but absolute coordinates of the endpoints of the pad.
1628 @item Thickness
1629 width of the pad.
1630 @item Clearance
1631 add to thickness to get clearance width.
1632 @item Mask
1633 width of solder mask opening.
1634 @item Name
1635 name of pin
1636 @item Number
1637 number of pin
1638 @item SFlags
1639 symbolic or numerical flags
1640 @item NFlags
1641 numerical flags only
1642 @end table
1644 %end-doc */
1646 pad_hi_format
1647 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1648 : T_PAD '[' measure measure measure measure measure measure measure STRING STRING flags ']'
1650 CreateNewPad(yyElement, NU ($3) + yyElement->MarkX,
1651 NU ($4) + yyElement->MarkY,
1652 NU ($5) + yyElement->MarkX,
1653 NU ($6) + yyElement->MarkY, NU ($7), NU ($8), NU ($9),
1654 $10, $11, $12);
1655 free ($10);
1656 free ($11);
1660 pad_1.7_format
1661 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1662 : T_PAD '(' measure measure measure measure measure measure measure STRING STRING INTEGER ')'
1664 CreateNewPad(yyElement,OU ($3) + yyElement->MarkX,
1665 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1666 OU ($6) + yyElement->MarkY, OU ($7), OU ($8), OU ($9),
1667 $10, $11, OldFlags($12));
1668 free ($10);
1669 free ($11);
1673 pad_newformat
1674 /* x1, y1, x2, y2, thickness, name , pad number, flags */
1675 : T_PAD '(' measure measure measure measure measure STRING STRING INTEGER ')'
1677 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1678 OU ($7) + 2*MASKFRAME, $8, $9, OldFlags($10));
1679 free ($8);
1680 free ($9);
1685 /* x1, y1, x2, y2, thickness, name and flags */
1686 : T_PAD '(' measure measure measure measure measure STRING INTEGER ')'
1688 char p_number[8];
1690 sprintf(p_number, "%d", pin_num++);
1691 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1692 OU ($7) + 2*MASKFRAME, $8,p_number, OldFlags($9));
1693 free ($8);
1697 flags : INTEGER { $$ = OldFlags($1); }
1698 | STRING { $$ = string_to_flags ($1, yyerror); }
1701 symbols
1702 : symbol
1703 | symbols symbol
1706 /* %start-doc pcbfile Symbol
1708 @syntax
1709 Symbol [Char Delta] (
1710 Symbol (Char Delta) (
1711 @ @ @ @dots{} symbol lines @dots{}
1713 @end syntax
1715 @table @var
1716 @item Char
1717 The character or numerical character value this symbol represents.
1718 Characters must be in single quotes.
1719 @item Delta
1720 Additional space to allow after this character.
1721 @end table
1723 %end-doc */
1725 symbol : symbolhead symboldata ')'
1727 symbolhead : T_SYMBOL '[' symbolid measure ']' '('
1729 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1731 yyerror("fontposition out of range");
1732 YYABORT;
1734 Symbol = &yyFont->Symbol[$3];
1735 if (Symbol->Valid)
1737 yyerror("symbol ID used twice");
1738 YYABORT;
1740 Symbol->Valid = true;
1741 Symbol->Delta = NU ($4);
1743 | T_SYMBOL '(' symbolid measure ')' '('
1745 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1747 yyerror("fontposition out of range");
1748 YYABORT;
1750 Symbol = &yyFont->Symbol[$3];
1751 if (Symbol->Valid)
1753 yyerror("symbol ID used twice");
1754 YYABORT;
1756 Symbol->Valid = true;
1757 Symbol->Delta = OU ($4);
1761 symbolid
1762 : INTEGER
1763 | CHAR_CONST
1766 symboldata
1767 : /* empty */
1768 | symboldata symboldefinition
1769 | symboldata hiressymbol
1772 /* %start-doc pcbfile SymbolLine
1774 @syntax
1775 SymbolLine [X1 Y1 X2 Y2 Thickness]
1776 SymbolLine (X1 Y1 X2 Y2 Thickness)
1777 @end syntax
1779 @table @var
1780 @item X1 Y1 X2 Y2
1781 The endpoints of this line.
1782 @item Thickness
1783 The width of this line.
1784 @end table
1786 %end-doc */
1788 symboldefinition
1789 /* x1, y1, x2, y2, thickness */
1790 : T_SYMBOLLINE '(' measure measure measure measure measure ')'
1792 CreateNewLineInSymbol(Symbol, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1795 hiressymbol
1796 /* x1, y1, x2, y2, thickness */
1797 : T_SYMBOLLINE '[' measure measure measure measure measure ']'
1799 CreateNewLineInSymbol(Symbol, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1803 /* %start-doc pcbfile Netlist
1805 @syntax
1806 Netlist ( ) (
1807 @ @ @ @dots{} nets @dots{}
1809 @end syntax
1811 %end-doc */
1813 pcbnetlist : pcbnetdef
1816 pcbnetdef
1817 /* net(...) net(...) ... */
1818 : T_NETLIST '(' ')' '('
1819 nets ')'
1822 nets
1823 : netdefs
1827 netdefs
1828 : net
1829 | netdefs net
1832 /* %start-doc pcbfile Net
1834 @syntax
1835 Net ("Name" "Style") (
1836 @ @ @ @dots{} connects @dots{}
1838 @end syntax
1840 @table @var
1841 @item Name
1842 The name of this net.
1843 @item Style
1844 The routing style that should be used when autorouting this net.
1845 @end table
1847 %end-doc */
1850 /* name style pin pin ... */
1851 : T_NET '(' STRING STRING ')' '('
1853 Menu = CreateNewNet(&yyPCB->NetlistLib, $3, $4);
1854 free ($3);
1855 free ($4);
1857 connections ')'
1860 connections
1861 : conndefs
1865 conndefs
1866 : conn
1867 | conndefs conn
1870 /* %start-doc pcbfile Connect
1872 @syntax
1873 Connect ("PinPad")
1874 @end syntax
1876 @table @var
1877 @item PinPad
1878 The name of a pin or pad which is included in this net. Pin and Pad
1879 names are named by the refdes and pin name, like @code{"U14-7"} for
1880 pin 7 of U14, or @code{"T4-E"} for pin E of T4.
1881 @end table
1883 %end-doc */
1885 conn
1886 : T_CONN '(' STRING ')'
1888 CreateNewConnection(Menu, $3);
1889 free ($3);
1893 /* %start-doc pcbfile Attribute
1895 @syntax
1896 Attribute ("Name" "Value")
1897 @end syntax
1899 Attributes allow boards and elements to have arbitrary data attached
1900 to them, which is not directly used by PCB itself but may be of use by
1901 other programs or users.
1903 @table @var
1904 @item Name
1905 The name of the attribute
1907 @item Value
1908 The value of the attribute. Values are always stored as strings, even
1909 if the value is interpreted as, for example, a number.
1911 @end table
1913 %end-doc */
1915 attribute
1916 : T_ATTRIBUTE '(' STRING STRING ')'
1918 CreateNewAttribute (attr_list, $3, $4 ? $4 : (char *)"");
1919 free ($3);
1920 free ($4);
1924 opt_string : STRING { $$ = $1; }
1925 | /* empty */ { $$ = 0; }
1928 number
1929 : FLOATING { $$ = $1; }
1930 | INTEGER { $$ = $1; }
1933 measure
1934 /* Default unit (no suffix) is cmil */
1935 : number { do_measure(&$$, $1, MIL_TO_COORD ($1) / 100.0, 0); }
1936 | number T_UMIL { M ($$, $1, MIL_TO_COORD ($1) / 100000.0); }
1937 | number T_CMIL { M ($$, $1, MIL_TO_COORD ($1) / 100.0); }
1938 | number T_MIL { M ($$, $1, MIL_TO_COORD ($1)); }
1939 | number T_IN { M ($$, $1, INCH_TO_COORD ($1)); }
1940 | number T_NM { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1941 | number T_PX { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1942 | number T_UM { M ($$, $1, MM_TO_COORD ($1) / 1000.0); }
1943 | number T_MM { M ($$, $1, MM_TO_COORD ($1)); }
1944 | number T_M { M ($$, $1, MM_TO_COORD ($1) * 1000.0); }
1945 | number T_KM { M ($$, $1, MM_TO_COORD ($1) * 1000000.0); }
1950 /* ---------------------------------------------------------------------------
1951 * error routine called by parser library
1953 int yyerror(const char * s)
1955 Message("ERROR parsing file '%s'\n"
1956 " line: %i\n"
1957 " description: '%s'\n",
1958 yyfilename, yylineno, s);
1959 return(0);
1962 int yywrap()
1964 return 1;
1967 static int
1968 check_file_version (int ver)
1970 if ( ver > PCB_FILE_VERSION ) {
1971 Message ("ERROR: The file you are attempting to load is in a format\n"
1972 "which is too new for this version of pcb. To load this file\n"
1973 "you need a version of pcb which is >= %d. If you are\n"
1974 "using a version built from git source, the source date\n"
1975 "must be >= %d. This copy of pcb can only read files\n"
1976 "up to file version %d.\n", ver, ver, PCB_FILE_VERSION);
1977 return 1;
1980 return 0;
1983 static void
1984 do_measure (PLMeasure *m, Coord i, double d, int u)
1986 m->ival = i;
1987 m->bval = round (d);
1988 m->dval = d;
1989 m->has_units = u;
1992 static int
1993 integer_value (PLMeasure m)
1995 if (m.has_units)
1996 yyerror("units ignored here");
1997 return m.ival;
2000 static Coord
2001 old_units (PLMeasure m)
2003 if (m.has_units)
2004 return m.bval;
2005 return round (MIL_TO_COORD (m.ival));
2008 static Coord
2009 new_units (PLMeasure m)
2011 if (m.has_units)
2012 return m.bval;
2013 return round (MIL_TO_COORD (m.ival) / 100.0);