3 * ************************** README *******************
5 * If the file format is modified in any way, update
6 * PCB_FILE_VERSION in file.h
8 * ************************** README *******************
15 * PCB, interactive printed circuit board design
16 * Copyright (C) 1994,1995,1996 Thomas Nau
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 * Contact addresses for paper mail and Email:
33 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
34 * Thomas.Nau@rz.uni-ulm.de
38 /* grammar to parse ASCII input of PCB description
45 #define GRIDFIT(x,g) (int)(0.5 + (int)(((x)+(g)/2.)/(g))*(g))
60 #ifdef HAVE_LIBDMALLOC
61 # include <dmalloc.h> /* see http://dmalloc.com */
66 static LayerTypePtr Layer
;
67 static PolygonTypePtr Polygon
;
68 static SymbolTypePtr Symbol
;
70 static LibraryMenuTypePtr Menu
;
71 static bool LayerFlag
[MAX_LAYER
+ 2];
73 extern
char *yytext
; /* defined by LEX */
74 extern PCBTypePtr yyPCB
;
75 extern DataTypePtr yyData
;
76 extern ElementTypePtr yyElement
;
77 extern FontTypePtr yyFont
;
78 extern
int yylineno
; /* linenumber */
79 extern
char *yyfilename
; /* in this file */
81 static char *layer_group_string
;
83 static AttributeListTypePtr attr_list
;
85 int yyerror(const char *s
);
87 static int check_file_version
(int);
91 %
union /* define YYSTACK type */
99 %token
<number
> NUMBER CHAR_CONST
/* line thickness, coordinates ... */
100 %token
<floating
> FLOAT
101 %token
<string> STRING
/* element names ... */
103 %token T_FILEVERSION T_PCB T_LAYER T_VIA T_RAT T_LINE T_ARC T_RECTANGLE T_TEXT T_ELEMENTLINE
104 %token T_ELEMENT T_PIN T_PAD T_GRID T_FLAGS T_SYMBOL T_SYMBOLLINE T_CURSOR
105 %token T_ELEMENTARC T_MARK T_GROUPS T_STYLES T_POLYGON T_POLYGON_HOLE T_NETLIST T_NET T_CONN
106 %token T_AREA T_THERMAL T_DRC T_ATTRIBUTE
107 %type
<number
> symbolid
108 %type
<string> opt_string
109 %type
<flagtype
> flags
120 /* %start-doc pcbfile 00pcb
124 A special note about units: Older versions of @code{pcb} used mils
125 (1/1000 inch) as the base unit; a value of 500 in the file meant
126 half an inch. Newer versions uses a "high resolution" syntax,
127 where the base unit is 1/100 of a mil (0.000010 inch); a value of 500 in
128 the file means 5 mils. As a general rule, the variants of each entry
129 listed below which use square brackets are the high resolution formats
130 and use the 1/100 mil units, and the ones with parentheses are the older
131 variants and use 1 mil units. Note that when multiple variants
132 are listed, the most recent (and most preferred) format is the first
135 Symbolic and numeric flags (SFlags and NFlags) are described in
142 /* reset flags for 'used layers';
143 * init font and data pointers
149 Message
("illegal fileformat\n");
152 for
(i
= 0; i
< MAX_LAYER
+ 2; i
++)
153 LayerFlag
[i
] = false
;
154 yyFont
= &yyPCB
->Font
;
155 yyData
= yyPCB
->Data
;
156 yyData
->pcb
= (void *)yyPCB
;
158 layer_group_string
= NULL
;
175 PCBTypePtr pcb_save
= PCB
;
177 if
(layer_group_string
== NULL
)
178 layer_group_string
= Settings.Groups
;
179 CreateNewPCBPost
(yyPCB
, 0);
180 if
(ParseGroupString
(layer_group_string
, &yyPCB
->LayerGroups
, yyData
->LayerN
))
182 Message
("illegal layer-group string\n");
185 /* initialize the polygon clipping now since
186 * we didn't know the layer grouping before.
189 for
(i
= 0; i
< yyData
->LayerN
+2; i
++)
190 for
(j
= 0; j
< yyData
->Layer
[i
].PolygonN
; j
++)
191 InitClip
(yyData
, &yyData
->Layer
[i
], &yyData
->Layer
[i
].Polygon
[j
]);
195 |
{ PreLoadElementPCB
();
196 layer_group_string
= NULL
; }
198 { LayerFlag
[0] = true
;
201 PostLoadElementPCB
();
207 /* reset flags for 'used layers';
208 * init font and data pointers
212 if
(!yyData ||
!yyFont
)
214 Message
("illegal fileformat\n");
217 for
(i
= 0; i
< MAX_LAYER
+ 2; i
++)
218 LayerFlag
[i
] = false
;
232 /* mark all symbols invalid */
237 Message
("illegal fileformat\n");
240 yyFont
->Valid
= false
;
241 for
(i
= 0; i
<= MAX_FONTPOSITION
; i
++)
242 yyFont
->Symbol
[i
].Valid
= false
;
246 yyFont
->Valid
= true
;
251 /* %start-doc pcbfile FileVersion
259 File format version. This version number represents the date when the pcb file
260 format was last changed.
263 Any version of pcb build from sources equal to or newer
264 than this number should be able to read the file. If this line is not present
265 in the input file then file format compatibility is not checked.
272 T_FILEVERSION
'[' NUMBER
']'
274 if
(check_file_version
($3) != 0)
281 /* %start-doc pcbfile Grid
283 /* %start-doc pcbfile PCB
286 PCB ["Name" Width Height]
287 PCB ("Name" Width Height]
293 Name of the PCB project
298 If you don't specify the size of the board, a very large default is
304 : T_PCB
'(' STRING
')'
307 yyPCB
->MaxWidth
= MAX_COORD
;
308 yyPCB
->MaxHeight
= MAX_COORD
;
310 | T_PCB
'(' STRING NUMBER NUMBER
')'
313 yyPCB
->MaxWidth
= $4*100;
314 yyPCB
->MaxHeight
= $5*100;
316 | T_PCB
'[' STRING NUMBER NUMBER
']'
319 yyPCB
->MaxWidth
= $4;
320 yyPCB
->MaxHeight
= $5;
324 /* %start-doc pcbfile Grid
327 Grid [Step OffsetX OffsetY Visible]
328 Grid (Step OffsetX OffsetY Visible)
329 Grid (Step OffsetX OffsetY)
334 Distance from one grid point to adjacent points. This value may be a
335 floating point number for the first two variants.
336 @item OffsetX OffsetY
337 The "origin" of the grid. Normally zero.
339 If non-zero, the grid will be visible on the screen.
351 : T_GRID
'(' NUMBER NUMBER NUMBER
')'
353 yyPCB
->Grid
= $3*100;
354 yyPCB
->GridOffsetX
= $4*100;
355 yyPCB
->GridOffsetY
= $5*100;
359 : T_GRID
'(' NUMBER NUMBER NUMBER NUMBER
')'
361 yyPCB
->Grid
= $3*100;
362 yyPCB
->GridOffsetX
= $4*100;
363 yyPCB
->GridOffsetY
= $5*100;
365 Settings.DrawGrid
= true
;
367 Settings.DrawGrid
= false
;
372 : T_GRID
'(' FLOAT NUMBER NUMBER NUMBER
')'
374 yyPCB
->Grid
= $3*100;
375 yyPCB
->GridOffsetX
= $4*100;
376 yyPCB
->GridOffsetY
= $5*100;
378 Settings.DrawGrid
= true
;
380 Settings.DrawGrid
= false
;
384 : T_GRID
'[' FLOAT NUMBER NUMBER NUMBER
']'
387 yyPCB
->GridOffsetX
= $4;
388 yyPCB
->GridOffsetY
= $5;
390 Settings.DrawGrid
= true
;
392 Settings.DrawGrid
= false
;
396 /* %start-doc pcbfile Cursor
405 Location of the cursor when the board was saved.
407 The current zoom factor. Note that a zoom factor of "0" means 1 mil
408 per screen pixel, N means @math{2^N} mils per screen pixel, etc. The
409 first variant accepts floating point numbers. The special value
410 "1000" means "zoom to fit"
416 : T_CURSOR
'(' NUMBER NUMBER NUMBER
')'
418 yyPCB
->CursorX
= $3*100;
419 yyPCB
->CursorY
= $4*100;
422 | T_CURSOR
'[' NUMBER NUMBER NUMBER
']'
428 | T_CURSOR
'[' NUMBER NUMBER FLOAT
']'
437 /* %start-doc pcbfile PolyArea
445 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.
452 | T_AREA
'[' FLOAT
']'
454 yyPCB
->IsleArea
= $3;
459 /* %start-doc pcbfile Thermal
467 Relative size of thermal fingers. A value of 1.0 makes the finger
468 width twice the clearance gap width (measured across the gap, not
469 diameter). The normal value is 0.5, which results in a finger width
470 the same as the clearance gap width.
478 | T_THERMAL
'[' FLOAT
']'
480 yyPCB
->ThermScale
= $3;
484 /* %start-doc pcbfile DRC
487 DRC [Bloat Shrink Line Silk Drill Ring]
488 DRC [Bloat Shrink Line Silk]
489 DRC [Bloat Shrink Line]
494 Minimum spacing between copper.
496 Minimum copper overlap to guarantee connectivity.
498 Minimum line thickness.
500 Minimum silk thickness.
504 Minimum width of the annular ring around pins and vias.
517 : T_DRC
'[' NUMBER NUMBER NUMBER
']'
527 : T_DRC
'[' NUMBER NUMBER NUMBER NUMBER
']'
538 : T_DRC
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
']'
544 yyPCB
->minDrill
= $7;
549 /* %start-doc pcbfile Flags
557 A number, whose value is normally given in hex, individual bits of which
558 represent pcb-wide flags as defined in @ref{PCBFlags}.
565 : T_FLAGS
'(' NUMBER
')'
567 yyPCB
->Flags
= MakeFlags
($3 & PCB_FLAGS
);
569 | T_FLAGS
'(' STRING
')'
571 yyPCB
->Flags
= string_to_pcbflags
($3, yyerror);
576 /* %start-doc pcbfile Groups
585 Encodes the layer grouping information. Each group is separated by a
586 colon, each member of each group is separated by a comma. Group
587 members are either numbers from @code{1}..@var{N} for each layer, and
588 the letters @code{c} or @code{s} representing the component side and
589 solder side of the board. Including @code{c} or @code{s} marks that
590 group as being the top or bottom side of the board.
593 Groups("1,2,c:3:4:5,6,s:7,8")
601 : T_GROUPS
'(' STRING
')'
603 layer_group_string
= $3;
608 /* %start-doc pcbfile Styles
617 Encodes the four routing styles @code{pcb} knows about. The four styles
618 are separated by colons. Each style consists of five parameters as follows:
622 The name of the style.
624 Width of lines and arcs.
626 Copper diameter of pins and vias.
628 Drill diameter of pins and vias.
630 Minimum spacing to other nets. If omitted, 10 mils is the default.
637 Styles("Signal,10,40,20:Power,25,60,35:Fat,40,60,35:Skinny,8,36,20")
638 Styles["Logic,1000,3600,2000,1000:Power,2500,6000,3500,1000:
639 @ @ @ Line,4000,6000,3500,1000:Breakout,600,2402,1181,600"]
643 Note that strings in actual files cannot span lines; the above example
644 is split across lines only to make it readable.
649 : T_STYLES
'(' STRING
')'
651 if
(ParseRouteString
($3, &yyPCB
->RouteStyle
[0], 100))
653 Message
("illegal route-style string\n");
657 | T_STYLES
'[' STRING
']'
659 if
(ParseRouteString
($3, &yyPCB
->RouteStyle
[0], 1))
661 Message
("illegal route-style string\n");
675 | pcbdefinitions pcbdefinition
680 |
{ attr_list
= & yyPCB
->Attributes
; } attributes
685 /* clear pointer to force memory allocation by
686 * the appropriate subroutine
702 /* %start-doc pcbfile Via
705 Via [X Y Thickness Clearance Mask Drill "Name" SFlags]
706 Via (X Y Thickness Clearance Mask Drill "Name" NFlags)
707 Via (X Y Thickness Clearance Drill "Name" NFlags)
708 Via (X Y Thickness Drill "Name" NFlags)
709 Via (X Y Thickness "Name" NFlags)
714 coordinates of center
716 outer diameter of copper annulus
718 add to thickness to get clearance diameter
720 diameter of solder mask opening
724 string, name of via (vias have names?)
726 symbolic or numerical flags
734 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
735 : T_VIA
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER STRING flags
']'
737 CreateNewVia
(yyData
, $3, $4, $5, $6, $7, $8, $9, $10);
743 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
744 : T_VIA
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER STRING NUMBER
')'
746 CreateNewVia
(yyData
, $3*100, $4*100, $5*100, $6*100, $7*100, $8*100, $9,
754 /* x, y, thickness, clearance, drilling-hole, name, flags */
755 : T_VIA
'(' NUMBER NUMBER NUMBER NUMBER NUMBER STRING NUMBER
')'
757 CreateNewVia
(yyData
, $3*100, $4*100, $5*100, $6*100,
758 ($5 + $6)*100, $7*100, $8, OldFlags
($9));
764 /* x, y, thickness, drilling-hole, name, flags */
765 : T_VIA
'(' NUMBER NUMBER NUMBER NUMBER STRING NUMBER
')'
767 CreateNewVia
(yyData
, $3*100, $4*100, $5*100, 200*GROUNDPLANEFRAME
,
768 ($5 + 2*MASKFRAME
)*100, $6*100, $7, OldFlags
($8));
774 /* old format: x, y, thickness, name, flags */
775 : T_VIA
'(' NUMBER NUMBER NUMBER STRING NUMBER
')'
777 BDimension hole
= ($5 *DEFAULT_DRILLINGHOLE
);
779 /* make sure that there's enough copper left */
780 if
($5 -hole
< MIN_PINORVIACOPPER
&&
781 $5 > MIN_PINORVIACOPPER
)
782 hole
= $5 -MIN_PINORVIACOPPER
;
784 CreateNewVia
(yyData
, $3*100, $4*100, $5*100, 200*GROUNDPLANEFRAME
,
785 ($5 + 2*MASKFRAME
)*100, hole
, $6, OldFlags
($7));
790 /* %start-doc pcbfile Rat
793 Rat [X1 Y1 Group1 X2 Y2 Group2 SFlags]
794 Rat (X1 Y1 Group1 X2 Y2 Group2 NFlags)
799 The endpoints of the rat line.
801 The layer group each end is connected on.
803 Symbolic or numeric flags.
811 : T_RAT
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER flags
']'
813 CreateNewRat
(yyData
, $3, $4, $6, $7, $5, $8,
814 Settings.RatThickness
, $9);
816 | T_RAT
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
')'
818 CreateNewRat
(yyData
, $3*100, $4*100, $6*100, $7*100, $5, $8,
819 Settings.RatThickness
, OldFlags
($9));
823 /* %start-doc pcbfile Layer
826 Layer (LayerNum "Name") (
827 @ @ @ @dots{} contents @dots{}
833 The layer number. Layers are numbered sequentially, starting with 1.
834 The last two layers (9 and 10 by default) are solder-side silk and
835 component-side silk, in that order.
839 The contents of the layer, which may include attributes, lines, arcs, rectangles,
847 : T_LAYER
'(' NUMBER STRING opt_string
')' '('
849 if
($3 <= 0 ||
$3 > MAX_LAYER
+ 2)
851 yyerror("Layernumber out of range");
856 yyerror("Layernumber used twice");
859 Layer
= &yyData
->Layer
[$3-1];
861 /* memory for name is already allocated */
863 LayerFlag
[$3-1] = true
;
864 if
(yyData
->LayerN
+ 2 < $3)
865 yyData
->LayerN
= $3 - 2;
877 | layerdefinitions layerdefinition
887 /* x1, y1, x2, y2, flags */
888 | T_RECTANGLE
'(' NUMBER NUMBER NUMBER NUMBER NUMBER
')'
890 CreateNewPolygonFromRectangle
(Layer
,
891 $3*100, $4*100, ($3+$5)*100, ($4+$6)*100, OldFlags
($7));
896 |
{ attr_list
= & Layer
->Attributes
; } attributes
899 /* %start-doc pcbfile Line
902 Line [X1 Y1 X2 Y2 Thickness Clearance SFlags]
903 Line (X1 Y1 X2 Y2 Thickness Clearance NFlags)
904 Line (X1 Y1 X2 Y2 Thickness NFlags)
909 The end points of the line
911 The width of the line
913 The amount of space cleared around the line when the line passes
914 through a polygon. The clearance is added to the thickness to get the
915 thickness of the clear; thus the space between the line and the
916 polygon is @math{Clearance/2} wide.
918 Symbolic or numeric flags
926 /* x1, y1, x2, y2, thickness, clearance, flags */
927 : T_LINE
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER flags
']'
929 CreateNewLineOnLayer
(Layer
, $3, $4, $5, $6, $7, $8, $9);
934 /* x1, y1, x2, y2, thickness, clearance, flags */
935 : T_LINE
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
')'
937 CreateNewLineOnLayer
(Layer
, $3*100, $4*100, $5*100, $6*100,
938 $7*100, $8*100, OldFlags
($9));
943 /* x1, y1, x2, y2, thickness, flags */
944 : T_LINE
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
')'
946 /* eliminate old-style rat-lines */
947 if
(($8 & RATFLAG
) == 0)
948 CreateNewLineOnLayer
(Layer
, $3*100, $4*100, $5*100, $6*100, $7*100,
949 200*GROUNDPLANEFRAME
, OldFlags
($8));
953 /* %start-doc pcbfile Arc
956 Arc [X Y Width Height Thickness Clearance StartAngle DeltaAngle SFlags]
957 Arc (X Y Width Height Thickness Clearance StartAngle DeltaAngle NFlags)
958 Arc (X Y Width Height Thickness StartAngle DeltaAngle NFlags)
963 Coordinates of the center of the arc.
965 The width and height, from the center to the edge. The bounds of the
966 circle of which this arc is a segment, is thus @math{2*Width} by
969 The width of the copper trace which forms the arc.
971 The amount of space cleared around the arc when the line passes
972 through a polygon. The clearance is added to the thickness to get the
973 thickness of the clear; thus the space between the arc and the polygon
974 is @math{Clearance/2} wide.
976 The angle of one end of the arc, in degrees. In PCB, an angle of zero
977 points left (negative X direction), and 90 degrees points down
978 (positive Y direction).
980 The sweep of the arc. This may be negative. Positive angles sweep
983 Symbolic or numeric flags.
991 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
992 : T_ARC
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER flags
']'
994 CreateNewArcOnLayer
(Layer
, $3, $4, $5, $6, $9, $10, $7, $8, $11);
999 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
1000 : T_ARC
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
')'
1002 CreateNewArcOnLayer
(Layer
, $3*100, $4*100, $5*100, $6*100, $9, $10,
1003 $7*100, $8*100, OldFlags
($11));
1008 /* x, y, width, height, thickness, startangle, delta, flags */
1009 : T_ARC
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
')'
1011 CreateNewArcOnLayer
(Layer
, $3*100, $4*100, $5*100, $5*100, $8, $9,
1012 $7*100, 200*GROUNDPLANEFRAME
, OldFlags
($10));
1016 /* %start-doc pcbfile Text
1019 Text [X Y Direction Scale "String" SFlags]
1020 Text (X Y Direction Scale "String" NFlags)
1021 Text (X Y Direction "String" NFlags)
1026 The location of the upper left corner of the text.
1028 0 means text is drawn left to right, 1 means up, 2 means right to left
1029 (i.e. upside down), and 3 means down.
1031 Size of the text, as a percentage of the ``default'' size of of the
1032 font (the default font is about 40 mils high). Default is 100 (40
1037 Symbolic or numeric flags.
1045 /* x, y, direction, text, flags */
1046 : T_TEXT
'(' NUMBER NUMBER NUMBER STRING NUMBER
')'
1048 /* use a default scale of 100% */
1049 CreateNewText
(Layer
,yyFont
,$3*100, $4*100, $5, 100, $6, OldFlags
($7));
1055 /* x, y, direction, scale, text, flags */
1056 : T_TEXT
'(' NUMBER NUMBER NUMBER NUMBER STRING NUMBER
')'
1058 if
($8 & ONSILKFLAG
)
1060 LayerTypePtr lay
= &yyData
->Layer
[yyData
->LayerN
+
1061 (($8 & ONSOLDERFLAG
) ? SOLDER_LAYER
: COMPONENT_LAYER
)];
1063 CreateNewText
(lay
,yyFont
, $3*100, $4*100, $5, $6, $7,
1067 CreateNewText
(Layer
, yyFont
, $3*100, $4*100, $5, $6, $7,
1073 /* x, y, direction, scale, text, flags */
1074 : T_TEXT
'[' NUMBER NUMBER NUMBER NUMBER STRING flags
']'
1076 /* FIXME: shouldn't know about .f */
1077 /* I don't think this matters because anything with hi_format
1078 * will have the silk on its own layer in the file rather
1079 * than using the ONSILKFLAG and having it in a copper layer.
1080 * Thus there is no need for anything besides the 'else'
1081 * part of this code.
1083 if
($8.f
& ONSILKFLAG
)
1085 LayerTypePtr lay
= &yyData
->Layer
[yyData
->LayerN
+
1086 (($8.f
& ONSOLDERFLAG
) ? SOLDER_LAYER
: COMPONENT_LAYER
)];
1088 CreateNewText
(lay
, yyFont
, $3, $4, $5, $6, $7, $8);
1091 CreateNewText
(Layer
, yyFont
, $3, $4, $5, $6, $7, $8);
1096 /* %start-doc pcbfile Polygon
1100 @ @ @ @dots{} (X Y) @dots{}
1101 @ @ @ @dots{} [X Y] @dots{}
1103 @ @ @ @ @ @ @dots{} (X Y) @dots{}
1104 @ @ @ @ @ @ @dots{} [X Y] @dots{}
1112 Symbolic or numeric flags.
1114 Coordinates of each vertex. You must list at least three coordinates.
1116 Defines a hole within the polygon's outer contour. There may be zero or more such sections.
1122 : /* flags are passed in */
1123 T_POLYGON
'(' flags
')' '('
1125 Polygon
= CreateNewPolygon
(Layer
, $3);
1130 Cardinal contour
, contour_start
, contour_end
;
1131 bool bad_contour_found
= false
;
1133 for
(contour
= 0; contour
<= Polygon
->HoleIndexN
; contour
++)
1135 contour_start
= (contour
== 0) ?
1136 0 : Polygon
->HoleIndex
[contour
- 1];
1137 contour_end
= (contour
== Polygon
->HoleIndexN
) ?
1139 Polygon
->HoleIndex
[contour
];
1140 if
(contour_end
- contour_start
< 3)
1141 bad_contour_found
= true
;
1144 if
(bad_contour_found
)
1146 Message
("WARNING parsing file '%s'\n"
1148 " description: 'ignored polygon (< 3 points in a contour)'\n",
1149 yyfilename
, yylineno
);
1150 DestroyObject
(yyData
, POLYGON_TYPE
, Layer
, Polygon
, Polygon
);
1154 SetPolygonBoundingBox
(Polygon
);
1155 if
(!Layer
->polygon_tree
)
1156 Layer
->polygon_tree
= r_create_tree
(NULL
, 0, 0);
1157 r_insert_entry
(Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
1165 | polygonholes polygonhole
1169 : T_POLYGON_HOLE
'('
1171 CreateNewHoleInPolygon
(Polygon
);
1178 | polygonpoints polygonpoint
1183 : '(' NUMBER NUMBER
')'
1185 CreateNewPointInPolygon
(Polygon
, $2*100, $3*100);
1187 |
'[' NUMBER NUMBER
']'
1189 CreateNewPointInPolygon
(Polygon
, $2, $3);
1194 /* %start-doc pcbfile Element
1197 Element [SFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TSFlags] (
1198 Element (NFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TNFlags) (
1199 Element (NFlags "Desc" "Name" "Value" TX TY TDir TScale TNFlags) (
1200 Element (NFlags "Desc" "Name" TX TY TDir TScale TNFlags) (
1201 Element ("Desc" "Name" TX TY TDir TScale TNFlags) (
1202 @ @ @ @dots{} contents @dots{}
1208 Symbolic or numeric flags, for the element as a whole.
1210 Numeric flags, for the element as a whole.
1212 The description of the element. This is one of the three strings
1213 which can be displayed on the screen.
1215 The name of the element, usually the reference designator.
1217 The value of the element.
1219 The location of the element's mark. This is the reference point
1220 for placing the element and its pins and pads.
1222 The upper left corner of the text (one of the three strings).
1224 The relative direction of the text. 0 means left to right for
1225 an unrotated element, 1 means up, 2 left, 3 down.
1227 Size of the text, as a percentage of the ``default'' size of of the
1228 font (the default font is about 40 mils high). Default is 100 (40
1231 Symbolic or numeric flags, for the text.
1233 Numeric flags, for the text.
1236 Elements may contain pins, pads, element lines, element arcs,
1237 attributes, and (for older elements) an optional mark. Note that
1238 element definitions that have the mark coordinates in the element
1239 line, only support pins and pads which use relative coordinates. The
1240 pin and pad coordinates are relative to the mark. Element definitions
1241 which do not include the mark coordinates in the element line, may
1242 have a Mark definition in their contents, and only use pin and pad
1243 definitions which use absolute coordinates.
1249 | element_1.3
.4_format
1251 | element_1.7_format
1256 /* element_flags, description, pcb-name,
1257 * text_x, text_y, text_direction, text_scale, text_flags
1259 : T_ELEMENT
'(' STRING STRING NUMBER NUMBER NUMBER
')' '('
1261 yyElement
= CreateNewElement
(yyData
, yyElement
, yyFont
, NoFlags
(),
1262 $3, $4, NULL
, $5*100, $6*100, $7, 100, NoFlags
(), false
);
1267 elementdefinitions
')'
1269 SetElementBoundingBox
(yyData
, yyElement
, yyFont
);
1273 element_1.3
.4_format
1274 /* element_flags, description, pcb-name,
1275 * text_x, text_y, text_direction, text_scale, text_flags
1277 : T_ELEMENT
'(' NUMBER STRING STRING NUMBER NUMBER NUMBER NUMBER NUMBER
')' '('
1279 yyElement
= CreateNewElement
(yyData
, yyElement
, yyFont
, OldFlags
($3),
1280 $4, $5, NULL
, $6*100, $7*100, $8, $9, OldFlags
($10), false
);
1285 elementdefinitions
')'
1287 SetElementBoundingBox
(yyData
, yyElement
, yyFont
);
1292 /* element_flags, description, pcb-name, value,
1293 * text_x, text_y, text_direction, text_scale, text_flags
1295 : T_ELEMENT
'(' NUMBER STRING STRING STRING NUMBER NUMBER NUMBER NUMBER NUMBER
')' '('
1297 yyElement
= CreateNewElement
(yyData
, yyElement
, yyFont
, OldFlags
($3),
1298 $4, $5, $6, $7*100, $8*100, $9, $10, OldFlags
($11), false
);
1304 elementdefinitions
')'
1306 SetElementBoundingBox
(yyData
, yyElement
, yyFont
);
1311 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1312 * text_x, text_y, text_direction, text_scale, text_flags
1314 : T_ELEMENT
'(' NUMBER STRING STRING STRING NUMBER NUMBER
1315 NUMBER NUMBER NUMBER NUMBER NUMBER
')' '('
1317 yyElement
= CreateNewElement
(yyData
, yyElement
, yyFont
, OldFlags
($3),
1318 $4, $5, $6, ($7+$9)*100, ($8+$10)*100, $11, $12, OldFlags
($13), false
);
1319 yyElement
->MarkX
= $7*100;
1320 yyElement
->MarkY
= $8*100;
1327 SetElementBoundingBox
(yyData
, yyElement
, yyFont
);
1332 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1333 * text_x, text_y, text_direction, text_scale, text_flags
1335 : T_ELEMENT
'[' flags STRING STRING STRING NUMBER NUMBER
1336 NUMBER NUMBER NUMBER NUMBER flags
']' '('
1338 yyElement
= CreateNewElement
(yyData
, yyElement
, yyFont
, $3,
1339 $4, $5, $6, ($7+$9), ($8+$10), $11, $12, $13, false
);
1340 yyElement
->MarkX
= $7;
1341 yyElement
->MarkY
= $8;
1348 SetElementBoundingBox
(yyData
, yyElement
, yyFont
);
1352 /* %start-doc pcbfile ElementLine
1355 ElementLine [X1 Y1 X2 Y2 Thickness]
1356 ElementLine (X1 Y1 X2 Y2 Thickness)
1361 Coordinates of the endpoints of the line. These are relative to the
1362 Element's mark point for new element formats, or absolute for older
1365 The width of the silk for this line.
1370 /* %start-doc pcbfile ElementArc
1373 ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
1374 ElementArc (X Y Width Height StartAngle DeltaAngle Thickness)
1379 Coordinates of the center of the arc. These are relative to the
1380 Element's mark point for new element formats, or absolute for older
1383 The width and height, from the center to the edge. The bounds of the
1384 circle of which this arc is a segment, is thus @math{2*Width} by
1387 The angle of one end of the arc, in degrees. In PCB, an angle of zero
1388 points left (negative X direction), and 90 degrees points down
1389 (positive Y direction).
1391 The sweep of the arc. This may be negative. Positive angles sweep
1394 The width of the silk line which forms the arc.
1399 /* %start-doc pcbfile Mark
1408 Coordinates of the Mark, for older element formats that don't have
1409 the mark as part of the Element line.
1416 | elementdefinitions elementdefinition
1425 /* x1, y1, x2, y2, thickness */
1426 | T_ELEMENTLINE
'[' NUMBER NUMBER NUMBER NUMBER NUMBER
']'
1428 CreateNewLineInElement
(yyElement
, $3, $4, $5, $6, $7);
1430 /* x1, y1, x2, y2, thickness */
1431 | T_ELEMENTLINE
'(' NUMBER NUMBER NUMBER NUMBER NUMBER
')'
1433 CreateNewLineInElement
(yyElement
, $3*100, $4*100, $5*100, $6*100, $7*100);
1435 /* x, y, width, height, startangle, anglediff, thickness */
1436 | T_ELEMENTARC
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
']'
1438 CreateNewArcInElement
(yyElement
, $3, $4, $5, $6, $7, $8, $9);
1440 /* x, y, width, height, startangle, anglediff, thickness */
1441 | T_ELEMENTARC
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
')'
1443 CreateNewArcInElement
(yyElement
, $3*100, $4*100, $5*100, $6*100, $7, $8, $9*100);
1446 | T_MARK
'[' NUMBER NUMBER
']'
1448 yyElement
->MarkX
= $3;
1449 yyElement
->MarkY
= $4;
1451 | T_MARK
'(' NUMBER NUMBER
')'
1453 yyElement
->MarkX
= $3*100;
1454 yyElement
->MarkY
= $4*100;
1456 |
{ attr_list
= & yyElement
->Attributes
; } attributes
1461 | relementdefs relementdef
1469 /* x1, y1, x2, y2, thickness */
1470 | T_ELEMENTLINE
'[' NUMBER NUMBER NUMBER NUMBER NUMBER
']'
1472 CreateNewLineInElement
(yyElement
, $3 + yyElement
->MarkX
,
1473 $4 + yyElement
->MarkY
, $5 + yyElement
->MarkX
,
1474 $6 + yyElement
->MarkY
, $7);
1476 | T_ELEMENTLINE
'(' NUMBER NUMBER NUMBER NUMBER NUMBER
')'
1478 CreateNewLineInElement
(yyElement
, $3*100 + yyElement
->MarkX
,
1479 $4*100 + yyElement
->MarkY
, $5*100 + yyElement
->MarkX
,
1480 $6*100 + yyElement
->MarkY
, $7*100);
1482 /* x, y, width, height, startangle, anglediff, thickness */
1483 | T_ELEMENTARC
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
']'
1485 CreateNewArcInElement
(yyElement
, $3 + yyElement
->MarkX
,
1486 $4 + yyElement
->MarkY
, $5, $6, $7, $8, $9);
1488 | T_ELEMENTARC
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER
')'
1490 CreateNewArcInElement
(yyElement
, $3*100 + yyElement
->MarkX
,
1491 $4*100 + yyElement
->MarkY
, $5*100, $6*100, $7, $8, $9*100);
1493 |
{ attr_list
= & yyElement
->Attributes
; } attributes
1496 /* %start-doc pcbfile Pin
1499 Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags]
1500 Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags)
1501 Pin (aX aY Thickness Drill "Name" "Number" NFlags)
1502 Pin (aX aY Thickness Drill "Name" NFlags)
1503 Pin (aX aY Thickness "Name" NFlags)
1508 coordinates of center, relative to the element's mark
1510 absolute coordinates of center.
1512 outer diameter of copper annulus
1514 add to thickness to get clearance diameter
1516 diameter of solder mask opening
1524 symbolic or numerical flags
1526 numerical flags only
1532 /* x, y, thickness, clearance, mask, drilling hole, name,
1534 : T_PIN
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER STRING STRING flags
']'
1536 CreateNewPin
(yyElement
, $3 + yyElement
->MarkX
,
1537 $4 + yyElement
->MarkY
, $5, $6, $7, $8, $9,
1544 /* x, y, thickness, clearance, mask, drilling hole, name,
1546 : T_PIN
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER STRING STRING NUMBER
')'
1548 CreateNewPin
(yyElement
, $3*100 + yyElement
->MarkX
,
1549 $4*100 + yyElement
->MarkY
, $5*100, $6*100, $7*100, $8*100, $9,
1550 $10, OldFlags
($11));
1557 /* x, y, thickness, drilling hole, name, number, flags */
1558 : T_PIN
'(' NUMBER NUMBER NUMBER NUMBER STRING STRING NUMBER
')'
1560 CreateNewPin
(yyElement
, $3*100, $4*100, $5*100, 200*GROUNDPLANEFRAME
,
1561 ($5 + 2*MASKFRAME
)*100, $6*100, $7, $8, OldFlags
($9));
1568 /* x, y, thickness, drilling hole, name, flags */
1569 : T_PIN
'(' NUMBER NUMBER NUMBER NUMBER STRING NUMBER
')'
1573 sprintf
(p_number
, "%d", pin_num
++);
1574 CreateNewPin
(yyElement
, $3*100, $4*100, $5*100, 200*GROUNDPLANEFRAME
,
1575 ($5 + 2*MASKFRAME
)*100, $6*100, $7, p_number
, OldFlags
($8));
1582 /* old format: x, y, thickness, name, flags
1583 * drilling hole is 40% of the diameter
1585 : T_PIN
'(' NUMBER NUMBER NUMBER STRING NUMBER
')'
1587 BDimension hole
= ($5 *DEFAULT_DRILLINGHOLE
);
1590 /* make sure that there's enough copper left */
1591 if
($5 -hole
< MIN_PINORVIACOPPER
&&
1592 $5 > MIN_PINORVIACOPPER
)
1593 hole
= $5 -MIN_PINORVIACOPPER
;
1595 sprintf
(p_number
, "%d", pin_num
++);
1596 CreateNewPin
(yyElement
, $3*100, $4*100, $5*100, 200*GROUNDPLANEFRAME
,
1597 ($5 + 2*MASKFRAME
)*100, hole
, $6, p_number
, OldFlags
($7));
1602 /* %start-doc pcbfile Pad
1605 Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags]
1606 Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags)
1607 Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags)
1608 Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags)
1612 @item rX1 rY1 rX2 rY2
1613 Coordinates of the endpoints of the pad, relative to the element's
1614 mark. Note that the copper extends beyond these coordinates by half
1615 the thickness. To make a square or round pad, specify the same
1617 @item aX1 aY1 aX2 aY2
1618 Same, but absolute coordinates of the endpoints of the pad.
1622 add to thickness to get clearance width.
1624 width of solder mask opening.
1630 symbolic or numerical flags
1632 numerical flags only
1638 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1639 : T_PAD
'[' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER STRING STRING flags
']'
1641 CreateNewPad
(yyElement
, $3 + yyElement
->MarkX
,
1642 $4 + yyElement
->MarkY
,
1643 $5 + yyElement
->MarkX
,
1644 $6 + yyElement
->MarkY
, $7, $8, $9,
1652 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1653 : T_PAD
'(' NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER STRING STRING NUMBER
')'
1655 CreateNewPad
(yyElement
,$3*100 + yyElement
->MarkX
,
1656 $4*100 + yyElement
->MarkY
, $5*100 + yyElement
->MarkX
,
1657 $6*100 + yyElement
->MarkY
, $7*100, $8*100, $9*100,
1658 $10, $11, OldFlags
($12));
1665 /* x1, y1, x2, y2, thickness, name , pad number, flags */
1666 : T_PAD
'(' NUMBER NUMBER NUMBER NUMBER NUMBER STRING STRING NUMBER
')'
1668 CreateNewPad
(yyElement
,$3*100,$4*100,$5*100,$6*100,$7*100, 200*GROUNDPLANEFRAME
,
1669 ($7 + 2*MASKFRAME
)*100, $8,$9, OldFlags
($10));
1676 /* x1, y1, x2, y2, thickness, name and flags */
1677 : T_PAD
'(' NUMBER NUMBER NUMBER NUMBER NUMBER STRING NUMBER
')'
1681 sprintf
(p_number
, "%d", pin_num
++);
1682 CreateNewPad
(yyElement
,$3*100,$4*100,$5*100,$6*100,$7*100, 200*GROUNDPLANEFRAME
,
1683 ($7 + 2*MASKFRAME
)*100, $8,p_number
, OldFlags
($9));
1688 flags
: NUMBER
{ $$
= OldFlags
($1); }
1689 | STRING
{ $$
= string_to_flags
($1, yyerror); }
1697 /* %start-doc pcbfile Symbol
1700 Symbol [Char Delta] (
1701 Symbol (Char Delta) (
1702 @ @ @ @dots{} symbol lines @dots{}
1708 The character or numerical character value this symbol represents.
1709 Characters must be in single quotes.
1711 Additional space to allow after this character.
1717 : T_SYMBOL
'[' symbolid NUMBER
']' '('
1719 if
($3 <= 0 ||
$3 > MAX_FONTPOSITION
)
1721 yyerror("fontposition out of range");
1724 Symbol
= &yyFont
->Symbol
[$3];
1727 yyerror("symbol ID used twice");
1730 Symbol
->Valid
= true
;
1734 | T_SYMBOL
'(' symbolid NUMBER
')' '('
1736 if
($3 <= 0 ||
$3 > MAX_FONTPOSITION
)
1738 yyerror("fontposition out of range");
1741 Symbol
= &yyFont
->Symbol
[$3];
1744 yyerror("symbol ID used twice");
1747 Symbol
->Valid
= true
;
1748 Symbol
->Delta
= $4*100;
1760 | symboldata symboldefinitions
1769 /* %start-doc pcbfile SymbolLine
1772 SymbolLine [X1 Y1 X2 Y1 Thickness]
1773 SymbolLine (X1 Y1 X2 Y1 Thickness)
1778 The endpoints of this line.
1780 The width of this line.
1786 /* x1, y1, x2, y2, thickness */
1787 : T_SYMBOLLINE
'(' NUMBER NUMBER NUMBER NUMBER NUMBER
')'
1789 CreateNewLineInSymbol
(Symbol
, $3*100, $4*100, $5*100, $6*100, $7*100);
1793 /* x1, y1, x2, y2, thickness */
1794 : T_SYMBOLLINE
'[' NUMBER NUMBER NUMBER NUMBER NUMBER
']'
1796 CreateNewLineInSymbol
(Symbol
, $3, $4, $5, $6, $7);
1800 /* %start-doc pcbfile Netlist
1804 @ @ @ @dots{} nets @dots{}
1810 pcbnetlist
: pcbnetdef
1814 /* net(...) net(...) ... */
1815 : T_NETLIST
'(' ')' '('
1829 /* %start-doc pcbfile Net
1832 Net ("Name" "Style") (
1833 @ @ @ @dots{} connects @dots{}
1839 The name of this net.
1841 The routing style that should be used when autorouting this net.
1847 /* name style pin pin ... */
1848 : T_NET
'(' STRING STRING
')' '('
1850 Menu
= CreateNewNet
(&yyPCB
->NetlistLib
, $3, $4);
1867 /* %start-doc pcbfile Connect
1875 The name of a pin or pad which is included in this net. Pin and Pad
1876 names are named by the refdes and pin name, like @code{"U14-7"} for
1877 pin 7 of U14, or @code{"T4-E"} for pin E of T4.
1883 : T_CONN
'(' STRING
')'
1885 CreateNewConnection
(Menu
, $3);
1890 /* %start-doc pcbfile Attribute
1893 Attribute ("Name" "Value")
1896 Attributes allow boards and elements to have arbitrary data attached
1897 to them, which is not directly used by PCB itself but may be of use by
1898 other programs or users.
1902 The name of the attribute
1905 The value of the attribute. Values are always stored as strings, even
1906 if the value is interpreted as, for example, a number.
1912 attributes
: attribute
1913 | attributes attribute
1916 : T_ATTRIBUTE
'(' STRING STRING
')'
1918 CreateNewAttribute
(attr_list
, $3, $4 ?
$4 : "");
1924 opt_string
: STRING
{ $$
= $1; }
1925 |
/* empty */ { $$
= 0; }
1930 /* ---------------------------------------------------------------------------
1931 * error routine called by parser library
1936 Message
("ERROR parsing file '%s'\n"
1938 " description: '%s'\n",
1939 yyfilename
, yylineno
, s
);
1950 check_file_version
(int ver
)
1952 if
( ver
> PCB_FILE_VERSION
) {
1953 Message
("ERROR: The file you are attempting to load is in a format\n"
1954 "which is too new for this version of pcb. To load this file\n"
1955 "you need a version of pcb which is >= %d. If you are\n"
1956 "using a version built from git source, the source date\n"
1957 "must be >= %d. This copy of pcb can only read files\n"
1958 "up to file version %d.\n", ver
, ver
, PCB_FILE_VERSION
);