gtk/gl: Play with layer translucency
[geda-pcb/pcjc2.git] / src / parse_y.y
blobc0350f82cceb1ecf7a7849237d6245a7958a6288
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"
57 #include "move.h"
59 #ifdef HAVE_LIBDMALLOC
60 # include <dmalloc.h> /* see http://dmalloc.com */
61 #endif
63 static LayerType *Layer;
64 static PolygonType *Polygon;
65 static SymbolType *Symbol;
66 static int pin_num;
67 static LibraryMenuType *Menu;
68 static bool LayerFlag[MAX_LAYER + EXTRA_LAYERS];
70 extern char *yytext; /* defined by LEX */
71 extern PCBType *yyPCB;
72 extern DataType *yyData;
73 extern ElementType *yyElement;
74 extern FontType *yyFont;
75 extern int yylineno; /* linenumber */
76 extern char *yyfilename; /* in this file */
78 static AttributeListType *attr_list;
80 int yyerror(const char *s);
81 int yylex();
82 static int check_file_version (int);
84 static void do_measure (PLMeasure *m, Coord i, double d, int u);
85 #define M(r,f,d) do_measure (&(r), f, d, 1)
87 /* Macros for interpreting what "measure" means - integer value only,
88 old units (mil), or new units (cmil). */
89 #define IV(m) integer_value (m)
90 #define OU(m) old_units (m)
91 #define NU(m) new_units (m)
93 static int integer_value (PLMeasure m);
94 static Coord old_units (PLMeasure m);
95 static Coord new_units (PLMeasure m);
97 #define YYDEBUG 1
98 #define YYERROR_VERBOSE 1
100 #include "parse_y.h"
104 %verbose
106 %union /* define YYSTACK type */
108 int integer;
109 double number;
110 char *string;
111 FlagType flagtype;
112 PLMeasure measure;
115 %token <number> FLOATING /* line thickness, coordinates ... */
116 %token <integer> INTEGER CHAR_CONST /* flags ... */
117 %token <string> STRING /* element names ... */
119 %token T_FILEVERSION T_PCB T_LAYER T_VIA T_RAT T_LINE T_ARC T_RECTANGLE T_TEXT T_ELEMENTLINE
120 %token T_ELEMENT T_PIN T_PAD T_GRID T_FLAGS T_SYMBOL T_SYMBOLLINE T_CURSOR
121 %token T_ELEMENTARC T_MARK T_GROUPS T_STYLES T_POLYGON T_POLYGON_HOLE T_NETLIST T_NET T_CONN
122 %token T_AREA T_THERMAL T_DRC T_ATTRIBUTE
123 %token T_UMIL T_CMIL T_MIL T_IN T_NM T_UM T_MM T_M T_KM T_PX
124 %type <integer> symbolid
125 %type <string> opt_string
126 %type <flagtype> flags
127 %type <number> number
128 %type <measure> measure
132 parse
133 : parsepcb
134 | parsefont
135 | error { YYABORT; }
138 /* %start-doc pcbfile 00pcb
139 @nodetype subsection
140 @nodename %s syntax
142 A special note about units: Older versions of @code{pcb} used mils
143 (1/1000 inch) as the base unit; a value of 500 in the file meant
144 half an inch. Newer versions uses a "high resolution" syntax,
145 where the base unit is 1/100 of a mil (0.000010 inch); a value of 500 in
146 the file means 5 mils. As a general rule, the variants of each entry
147 listed below which use square brackets are the high resolution formats
148 and use the 1/100 mil units, and the ones with parentheses are the older
149 variants and use 1 mil units. Note that when multiple variants
150 are listed, the most recent (and most preferred) format is the first
151 listed.
153 Symbolic and numeric flags (SFlags and NFlags) are described in
154 @ref{Object Flags}.
156 %end-doc */
158 parsepcb
160 /* reset flags for 'used layers';
161 * init font and data pointers
163 int i;
165 if (!yyPCB)
167 Message(_("illegal fileformat\n"));
168 YYABORT;
170 for (i = 0; i < MAX_LAYER + EXTRA_LAYERS; i++)
171 LayerFlag[i] = false;
172 yyFont = &yyPCB->Font;
173 yyData = yyPCB->Data;
174 yyData->pcb = yyPCB;
175 yyData->LayerN = 0;
176 /* Parse the default layer group string, just in case the file doesn't have one */
177 if (ParseGroupString (Settings.Groups, &yyPCB->LayerGroups, &yyData->LayerN))
179 Message(_("illegal default layer-group string\n"));
180 YYABORT;
183 pcbfileversion
184 pcbname
185 pcbgrid
186 pcbcursor
187 polyarea
188 pcbthermal
189 pcbdrc
190 pcbflags
191 pcbgroups
192 pcbstyles
193 pcbfont
194 pcbdata
195 pcbnetlist
197 PCBType *pcb_save = PCB;
199 CreateNewPCBPost (yyPCB, 0);
200 /* initialize the polygon clipping now since
201 * we didn't know the layer grouping before.
203 PCB = yyPCB;
204 ALLPOLYGON_LOOP (yyData);
206 InitClip (yyData, layer, polygon);
208 ENDALL_LOOP;
209 PCB = pcb_save;
213 if (yyPCB != NULL)
215 /* This case is when we load a footprint with file->open, or from the command line */
216 yyFont = &yyPCB->Font;
217 yyData = yyPCB->Data;
218 yyData->pcb = yyPCB;
219 yyData->LayerN = 0;
222 element
224 PCBType *pcb_save = PCB;
225 ElementType *e;
226 if (yyPCB != NULL)
228 /* This case is when we load a footprint with file->open, or from the command line */
229 CreateNewPCBPost (yyPCB, 0);
230 ParseGroupString("1,c:2,s", &yyPCB->LayerGroups, &yyData->LayerN);
231 e = yyPCB->Data->Element->data; /* we know there's only one */
232 PCB = yyPCB;
233 MoveElementLowLevel (yyPCB->Data, e, -e->BoundingBox.X1, -e->BoundingBox.Y1);
234 PCB = pcb_save;
235 yyPCB->MaxWidth = e->BoundingBox.X2;
236 yyPCB->MaxHeight = e->BoundingBox.Y2;
237 yyPCB->is_footprint = 1;
242 pcbfont
243 : parsefont
247 parsefont
250 /* mark all symbols invalid */
251 int i;
253 if (!yyFont)
255 Message(_("illegal fileformat\n"));
256 YYABORT;
258 yyFont->Valid = false;
259 for (i = 0; i <= MAX_FONTPOSITION; i++)
260 free (yyFont->Symbol[i].Line);
261 bzero(yyFont->Symbol, sizeof(yyFont->Symbol));
263 symbols
265 yyFont->Valid = true;
266 SetFontInfo(yyFont);
270 /* %start-doc pcbfile FileVersion
272 @syntax
273 FileVersion[Version]
274 @end syntax
276 @table @var
277 @item Version
278 File format version. This version number represents the date when the pcb file
279 format was last changed.
280 @end table
282 Any version of pcb build from sources equal to or newer
283 than this number should be able to read the file. If this line is not present
284 in the input file then file format compatibility is not checked.
287 %end-doc */
289 pcbfileversion
291 T_FILEVERSION '[' INTEGER ']'
293 if (check_file_version ($3) != 0)
295 YYABORT;
300 /* %start-doc pcbfile PCB
302 @syntax
303 PCB ["Name" Width Height]
304 PCB ("Name" Width Height]
305 PCB ("Name")
306 @end syntax
308 @table @var
309 @item Name
310 Name of the PCB project
311 @item Width Height
312 Size of the board
313 @end table
315 If you don't specify the size of the board, a very large default is
316 chosen.
318 %end-doc */
320 pcbname
321 : T_PCB '(' STRING ')'
323 yyPCB->Name = $3;
324 yyPCB->MaxWidth = MAX_COORD;
325 yyPCB->MaxHeight = MAX_COORD;
327 | T_PCB '(' STRING measure measure ')'
329 yyPCB->Name = $3;
330 yyPCB->MaxWidth = OU ($4);
331 yyPCB->MaxHeight = OU ($5);
333 | T_PCB '[' STRING measure measure ']'
335 yyPCB->Name = $3;
336 yyPCB->MaxWidth = NU ($4);
337 yyPCB->MaxHeight = NU ($5);
341 /* %start-doc pcbfile Grid
343 @syntax
344 Grid [Step OffsetX OffsetY Visible]
345 Grid (Step OffsetX OffsetY Visible)
346 Grid (Step OffsetX OffsetY)
347 @end syntax
349 @table @var
350 @item Step
351 Distance from one grid point to adjacent points. This value may be a
352 floating point number for the first two variants.
353 @item OffsetX OffsetY
354 The "origin" of the grid. Normally zero.
355 @item Visible
356 If non-zero, the grid will be visible on the screen.
357 @end table
359 %end-doc */
361 pcbgrid
362 : pcbgridold
363 | pcbgridnew
364 | pcbhigrid
366 pcbgridold
367 : T_GRID '(' measure measure measure ')'
369 yyPCB->Grid = OU ($3);
370 yyPCB->GridOffsetX = OU ($4);
371 yyPCB->GridOffsetY = OU ($5);
374 pcbgridnew
375 : T_GRID '(' measure measure measure INTEGER ')'
377 yyPCB->Grid = OU ($3);
378 yyPCB->GridOffsetX = OU ($4);
379 yyPCB->GridOffsetY = OU ($5);
380 if ($6)
381 Settings.DrawGrid = true;
382 else
383 Settings.DrawGrid = false;
387 pcbhigrid
388 : T_GRID '[' measure measure measure INTEGER ']'
390 yyPCB->Grid = NU ($3);
391 yyPCB->GridOffsetX = NU ($4);
392 yyPCB->GridOffsetY = NU ($5);
393 if ($6)
394 Settings.DrawGrid = true;
395 else
396 Settings.DrawGrid = false;
400 /* %start-doc pcbfile Cursor
402 @syntax
403 Cursor [X Y Zoom]
404 Cursor (X Y Zoom)
405 @end syntax
407 @table @var
408 @item X Y
409 Location of the cursor when the board was saved.
410 As of November 2012 the cursor position is not written to file anymore.
411 Older versions of pcb ignore the absence of this line in the pcb file.
412 @item Zoom
413 The current zoom factor. Note that a zoom factor of "0" means 1 mil
414 per screen pixel, N means @math{2^N} mils per screen pixel, etc. The
415 first variant accepts floating point numbers. The special value
416 "1000" means "zoom to fit"
418 This field is ignored by PCB.
419 @end table
421 %end-doc */
423 pcbcursor
424 : T_CURSOR '(' measure measure number ')'
426 yyPCB->CursorX = OU ($3);
427 yyPCB->CursorY = OU ($4);
429 | T_CURSOR '[' measure measure number ']'
431 yyPCB->CursorX = NU ($3);
432 yyPCB->CursorY = NU ($4);
437 /* %start-doc pcbfile PolyArea
439 @syntax
440 PolyArea [Area]
441 @end syntax
443 @table @var
444 @item Area
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.
446 @end table
448 %end-doc */
450 polyarea
452 | T_AREA '[' number ']'
454 /* Read in cmil^2 for now; in future this should be a noop. */
455 yyPCB->IsleArea = MIL_TO_COORD (MIL_TO_COORD ($3) / 100.0) / 100.0;
460 /* %start-doc pcbfile Thermal
462 @syntax
463 Thermal [Scale]
464 @end syntax
466 @table @var
467 @item Scale
468 Relative size of thermal fingers. A value of 1.0 makes the finger
469 width twice the clearance gap width (measured across the gap, not
470 diameter). The normal value is 0.5, which results in a finger width
471 the same as the clearance gap width.
472 @end table
474 %end-doc */
477 pcbthermal
479 | T_THERMAL '[' number ']'
481 yyPCB->ThermScale = $3;
485 /* %start-doc pcbfile DRC
487 @syntax
488 DRC [Bloat Shrink Line Silk Drill Ring]
489 DRC [Bloat Shrink Line Silk]
490 DRC [Bloat Shrink Line]
491 @end syntax
493 @table @var
494 @item Bloat
495 Minimum spacing between copper.
496 @item Shrink
497 Minimum copper overlap to guarantee connectivity.
498 @item Line
499 Minimum line thickness.
500 @item Silk
501 Minimum silk thickness.
502 @item Drill
503 Minimum drill size.
504 @item Ring
505 Minimum width of the annular ring around pins and vias.
506 @end table
508 %end-doc */
510 pcbdrc
512 | pcbdrc1
513 | pcbdrc2
514 | pcbdrc3
517 pcbdrc1
518 : T_DRC '[' measure measure measure ']'
520 yyPCB->Bloat = NU ($3);
521 yyPCB->Shrink = NU ($4);
522 yyPCB->minWid = NU ($5);
523 yyPCB->minRing = NU ($5);
527 pcbdrc2
528 : T_DRC '[' measure measure measure measure ']'
530 yyPCB->Bloat = NU ($3);
531 yyPCB->Shrink = NU ($4);
532 yyPCB->minWid = NU ($5);
533 yyPCB->minSlk = NU ($6);
534 yyPCB->minRing = NU ($5);
538 pcbdrc3
539 : T_DRC '[' measure measure measure measure measure measure ']'
541 yyPCB->Bloat = NU ($3);
542 yyPCB->Shrink = NU ($4);
543 yyPCB->minWid = NU ($5);
544 yyPCB->minSlk = NU ($6);
545 yyPCB->minDrill = NU ($7);
546 yyPCB->minRing = NU ($8);
550 /* %start-doc pcbfile Flags
552 @syntax
553 Flags(Number)
554 @end syntax
556 @table @var
557 @item Number
558 A number, whose value is normally given in hex, individual bits of which
559 represent pcb-wide flags as defined in @ref{PCBFlags}.
561 @end table
563 %end-doc */
565 pcbflags
566 : T_FLAGS '(' INTEGER ')'
568 yyPCB->Flags = MakeFlags ($3 & PCB_FLAGS);
570 | T_FLAGS '(' STRING ')'
572 yyPCB->Flags = string_to_pcbflags ($3, yyerror);
577 /* %start-doc pcbfile Groups
579 @syntax
580 Groups("String")
581 @end syntax
583 @table @var
584 @item String
586 Encodes the layer grouping information. Each group is separated by a
587 colon, each member of each group is separated by a comma. Group
588 members are either numbers from @code{1}..@var{N} for each layer, and
589 the letters @code{c} or @code{s} representing the component side and
590 solder side of the board. Including @code{c} or @code{s} marks that
591 group as being the top or bottom side of the board.
593 @example
594 Groups("1,2,c:3:4:5,6,s:7,8")
595 @end example
597 @end table
599 %end-doc */
601 pcbgroups
602 : T_GROUPS '(' STRING ')'
604 if (ParseGroupString ($3, &yyPCB->LayerGroups, &yyData->LayerN))
606 Message(_("illegal layer-group string\n"));
607 YYABORT;
613 /* %start-doc pcbfile Styles
615 @syntax
616 Styles("String")
617 @end syntax
619 @table @var
620 @item String
622 Encodes the four routing styles @code{pcb} knows about. The four styles
623 are separated by colons. Each style consists of five parameters as follows:
625 @table @var
626 @item Name
627 The name of the style.
628 @item Thickness
629 Width of lines and arcs.
630 @item Diameter
631 Copper diameter of pins and vias.
632 @item Drill
633 Drill diameter of pins and vias.
634 @item Keepaway
635 Minimum spacing to other nets. If omitted, 10 mils is the default.
637 @end table
639 @end table
641 @example
642 Styles("Signal,10,40,20:Power,25,60,35:Fat,40,60,35:Skinny,8,36,20")
643 Styles["Logic,1000,3600,2000,1000:Power,2500,6000,3500,1000:
644 @ @ @ Line,4000,6000,3500,1000:Breakout,600,2402,1181,600"]
645 @end example
647 @noindent
648 Note that strings in actual files cannot span lines; the above example
649 is split across lines only to make it readable.
651 %end-doc */
653 pcbstyles
654 : T_STYLES '(' STRING ')'
656 if (ParseRouteString($3, &yyPCB->RouteStyle[0], "mil"))
658 Message(_("illegal route-style string\n"));
659 YYABORT;
662 | T_STYLES '[' STRING ']'
664 if (ParseRouteString($3, &yyPCB->RouteStyle[0], "cmil"))
666 Message(_("illegal route-style string\n"));
667 YYABORT;
673 pcbdata
674 : pcbdefinitions
678 pcbdefinitions
679 : pcbdefinition
680 | pcbdefinitions pcbdefinition
683 pcbdefinition
684 : via
685 | { attr_list = & yyPCB->Attributes; } attribute
686 | rats
687 | layer
688 | element
692 : via_hi_format
693 | via_2.0_format
694 | via_1.7_format
695 | via_newformat
696 | via_oldformat
699 /* %start-doc pcbfile Via
701 @syntax
702 Via [X Y Thickness Clearance Mask Drill "Name" SFlags]
703 Via (X Y Thickness Clearance Mask Drill "Name" NFlags)
704 Via (X Y Thickness Clearance Drill "Name" NFlags)
705 Via (X Y Thickness Drill "Name" NFlags)
706 Via (X Y Thickness "Name" NFlags)
707 @end syntax
709 @table @var
710 @item X Y
711 coordinates of center
712 @item Thickness
713 outer diameter of copper annulus
714 @item Clearance
715 add to thickness to get clearance diameter
716 @item Mask
717 diameter of solder mask opening
718 @item Drill
719 diameter of drill
720 @item Name
721 string, name of via (vias have names?)
722 @item SFlags
723 symbolic or numerical flags
724 @item NFlags
725 numerical flags only
726 @end table
728 %end-doc */
730 via_hi_format
731 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
732 : T_VIA '[' measure measure measure measure measure measure STRING flags ']'
734 CreateNewVia(yyData, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7),
735 NU ($8), $9, $10);
736 free ($9);
740 via_2.0_format
741 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
742 : T_VIA '(' measure measure measure measure measure measure STRING INTEGER ')'
744 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7), OU ($8), $9,
745 OldFlags($10));
746 free ($9);
751 via_1.7_format
752 /* x, y, thickness, clearance, drilling-hole, name, flags */
753 : T_VIA '(' measure measure measure measure measure STRING INTEGER ')'
755 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), OU ($6),
756 OU ($5) + OU($6), OU ($7), $8, OldFlags($9));
757 free ($8);
761 via_newformat
762 /* x, y, thickness, drilling-hole, name, flags */
763 : T_VIA '(' measure measure measure measure STRING INTEGER ')'
765 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
766 OU($5) + 2*MASKFRAME, OU ($6), $7, OldFlags($8));
767 free ($7);
771 via_oldformat
772 /* old format: x, y, thickness, name, flags */
773 : T_VIA '(' measure measure measure STRING INTEGER ')'
775 Coord hole = (OU($5) * DEFAULT_DRILLINGHOLE);
777 /* make sure that there's enough copper left */
778 if (OU($5) - hole < MIN_PINORVIACOPPER &&
779 OU($5) > MIN_PINORVIACOPPER)
780 hole = OU($5) - MIN_PINORVIACOPPER;
782 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
783 OU($5) + 2*MASKFRAME, hole, $6, OldFlags($7));
784 free ($6);
788 /* %start-doc pcbfile Rat
790 @syntax
791 Rat [X1 Y1 Group1 X2 Y2 Group2 SFlags]
792 Rat (X1 Y1 Group1 X2 Y2 Group2 NFlags)
793 @end syntax
795 @table @var
796 @item X1 Y1 X2 Y2
797 The endpoints of the rat line.
798 @item Group1 Group2
799 The layer group each end is connected on.
800 @item SFlags
801 Symbolic or numeric flags.
802 @item NFlags
803 Numeric flags.
804 @end table
806 %end-doc */
808 rats
809 : T_RAT '[' measure measure INTEGER measure measure INTEGER flags ']'
811 CreateNewRat(yyData, NU ($3), NU ($4), NU ($6), NU ($7), $5, $8,
812 Settings.RatThickness, $9);
814 | T_RAT '(' measure measure INTEGER measure measure INTEGER INTEGER ')'
816 CreateNewRat(yyData, OU ($3), OU ($4), OU ($6), OU ($7), $5, $8,
817 Settings.RatThickness, OldFlags($9));
821 /* %start-doc pcbfile Layer
823 @syntax
824 Layer (LayerNum "Name") (
825 @ @ @ @dots{} contents @dots{}
827 @end syntax
829 @table @var
830 @item LayerNum
831 The layer number. Layers are numbered sequentially, starting with 1.
832 The last two layers (9 and 10 by default) are solder-side silk and
833 component-side silk, in that order.
834 @item Name
835 The layer name.
836 @item contents
837 The contents of the layer, which may include attributes, lines, arcs, rectangles,
838 text, and polygons.
839 @end table
841 %end-doc */
843 layer
844 /* name */
845 : T_LAYER '(' INTEGER STRING opt_string ')' '('
847 if ($3 <= 0 || $3 > MAX_LAYER + EXTRA_LAYERS)
849 yyerror("Layernumber out of range");
850 YYABORT;
852 if (LayerFlag[$3-1])
854 yyerror("Layernumber used twice");
855 YYABORT;
857 Layer = &yyData->Layer[$3-1];
859 /* memory for name is already allocated */
860 Layer->Name = $4;
861 if (Layer->Name == NULL)
862 Layer->Name = strdup("");
863 LayerFlag[$3-1] = true;
865 layerdata ')'
868 layerdata
869 : layerdefinitions
873 layerdefinitions
874 : layerdefinition
875 | layerdefinitions layerdefinition
878 layerdefinition
879 : line_hi_format
880 | line_1.7_format
881 | line_oldformat
882 | arc_hi_format
883 | arc_1.7_format
884 | arc_oldformat
885 /* x1, y1, x2, y2, flags */
886 | T_RECTANGLE '(' measure measure measure measure INTEGER ')'
888 CreateNewPolygonFromRectangle(Layer,
889 OU ($3), OU ($4), OU ($3) + OU ($5), OU ($4) + OU ($6), OldFlags($7));
891 | text_hi_format
892 | text_newformat
893 | text_oldformat
894 | { attr_list = & Layer->Attributes; } attribute
895 | polygon_format
897 /* %start-doc pcbfile Line
899 @syntax
900 Line [X1 Y1 X2 Y2 Thickness Clearance SFlags]
901 Line (X1 Y1 X2 Y2 Thickness Clearance NFlags)
902 Line (X1 Y1 X2 Y2 Thickness NFlags)
903 @end syntax
905 @table @var
906 @item X1 Y1 X2 Y2
907 The end points of the line
908 @item Thickness
909 The width of the line
910 @item Clearance
911 The amount of space cleared around the line when the line passes
912 through a polygon. The clearance is added to the thickness to get the
913 thickness of the clear; thus the space between the line and the
914 polygon is @math{Clearance/2} wide.
915 @item SFlags
916 Symbolic or numeric flags
917 @item NFlags
918 Numeric flags.
919 @end table
921 %end-doc */
923 line_hi_format
924 /* x1, y1, x2, y2, thickness, clearance, flags */
925 : T_LINE '[' measure measure measure measure measure measure flags ']'
927 CreateNewLineOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6),
928 NU ($7), NU ($8), $9);
932 line_1.7_format
933 /* x1, y1, x2, y2, thickness, clearance, flags */
934 : T_LINE '(' measure measure measure measure measure measure INTEGER ')'
936 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6),
937 OU ($7), OU ($8), OldFlags($9));
941 line_oldformat
942 /* x1, y1, x2, y2, thickness, flags */
943 : T_LINE '(' measure measure measure measure measure measure ')'
945 /* eliminate old-style rat-lines */
946 if ((IV ($8) & RATFLAG) == 0)
947 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7),
948 200*GROUNDPLANEFRAME, OldFlags(IV ($8)));
952 /* %start-doc pcbfile Arc
954 @syntax
955 Arc [X Y Width Height Thickness Clearance StartAngle DeltaAngle SFlags]
956 Arc (X Y Width Height Thickness Clearance StartAngle DeltaAngle NFlags)
957 Arc (X Y Width Height Thickness StartAngle DeltaAngle NFlags)
958 @end syntax
960 @table @var
961 @item X Y
962 Coordinates of the center of the arc.
963 @item Width Height
964 The width and height, from the center to the edge. The bounds of the
965 circle of which this arc is a segment, is thus @math{2*Width} by
966 @math{2*Height}.
967 @item Thickness
968 The width of the copper trace which forms the arc.
969 @item Clearance
970 The amount of space cleared around the arc when the line passes
971 through a polygon. The clearance is added to the thickness to get the
972 thickness of the clear; thus the space between the arc and the polygon
973 is @math{Clearance/2} wide.
974 @item StartAngle
975 The angle of one end of the arc, in degrees. In PCB, an angle of zero
976 points left (negative X direction), and 90 degrees points down
977 (positive Y direction).
978 @item DeltaAngle
979 The sweep of the arc. This may be negative. Positive angles sweep
980 counterclockwise.
981 @item SFlags
982 Symbolic or numeric flags.
983 @item NFlags
984 Numeric flags.
985 @end table
987 %end-doc */
989 arc_hi_format
990 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
991 : T_ARC '[' measure measure measure measure measure measure number number flags ']'
993 CreateNewArcOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6), $9, $10,
994 NU ($7), NU ($8), $11);
998 arc_1.7_format
999 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
1000 : T_ARC '(' measure measure measure measure measure measure number number INTEGER ')'
1002 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), $9, $10,
1003 OU ($7), OU ($8), OldFlags($11));
1007 arc_oldformat
1008 /* x, y, width, height, thickness, startangle, delta, flags */
1009 : T_ARC '(' measure measure measure measure measure measure number INTEGER ')'
1011 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($5), IV ($8), $9,
1012 OU ($7), 200*GROUNDPLANEFRAME, OldFlags($10));
1016 /* %start-doc pcbfile Text
1018 @syntax
1019 Text [X Y Direction Scale "String" SFlags]
1020 Text (X Y Direction Scale "String" NFlags)
1021 Text (X Y Direction "String" NFlags)
1022 @end syntax
1024 @table @var
1025 @item X Y
1026 The location of the upper left corner of the text.
1027 @item Direction
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.
1030 @item Scale
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
1033 mils).
1034 @item String
1035 The string to draw.
1036 @item SFlags
1037 Symbolic or numeric flags.
1038 @item NFlags
1039 Numeric flags.
1040 @end table
1042 %end-doc */
1044 text_oldformat
1045 /* x, y, direction, text, flags */
1046 : T_TEXT '(' measure measure number STRING INTEGER ')'
1048 /* use a default scale of 100% */
1049 CreateNewText(Layer,yyFont,OU ($3), OU ($4), $5, 100, $6, OldFlags($7));
1050 free ($6);
1054 text_newformat
1055 /* x, y, direction, scale, text, flags */
1056 : T_TEXT '(' measure measure number number STRING INTEGER ')'
1058 if ($8 & ONSILKFLAG)
1060 LayerType *lay = &yyData->Layer[yyData->LayerN +
1061 (($8 & ONSOLDERFLAG) ? BOTTOM_SILK_LAYER : TOP_SILK_LAYER)];
1063 CreateNewText(lay ,yyFont, OU ($3), OU ($4), $5, $6, $7,
1064 OldFlags($8));
1066 else
1067 CreateNewText(Layer, yyFont, OU ($3), OU ($4), $5, $6, $7,
1068 OldFlags($8));
1069 free ($7);
1072 text_hi_format
1073 /* x, y, direction, scale, text, flags */
1074 : T_TEXT '[' measure measure 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 LayerType *lay = &yyData->Layer[yyData->LayerN +
1086 (($8.f & ONSOLDERFLAG) ? BOTTOM_SILK_LAYER : TOP_SILK_LAYER)];
1088 CreateNewText(lay, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1090 else
1091 CreateNewText(Layer, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1092 free ($7);
1096 /* %start-doc pcbfile Polygon
1098 @syntax
1099 Polygon (SFlags) (
1100 @ @ @ @dots{} (X Y) @dots{}
1101 @ @ @ @dots{} [X Y] @dots{}
1102 @ @ @ Hole (
1103 @ @ @ @ @ @ @dots{} (X Y) @dots{}
1104 @ @ @ @ @ @ @dots{} [X Y] @dots{}
1105 @ @ @ )
1106 @ @ @ @dots{}
1108 @end syntax
1110 @table @var
1111 @item SFlags
1112 Symbolic or numeric flags.
1113 @item X Y
1114 Coordinates of each vertex. You must list at least three coordinates.
1115 @item Hole (...)
1116 Defines a hole within the polygon's outer contour. There may be zero or more such sections.
1117 @end table
1119 %end-doc */
1121 polygon_format
1122 : /* flags are passed in */
1123 T_POLYGON '(' flags ')' '('
1125 Polygon = CreateNewPolygon(Layer, $3);
1127 polygonpoints
1128 polygonholes ')'
1130 Cardinal contour, contour_start, contour_end;
1131 bool bad_contour_found = false;
1132 /* ignore junk */
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) ?
1138 Polygon->PointN :
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"
1147 " line: %i\n"
1148 " description: 'ignored polygon "
1149 "(< 3 points in a contour)'\n"),
1150 yyfilename, yylineno);
1151 DestroyObject(yyData, POLYGON_TYPE, Layer, Polygon, Polygon);
1153 else
1155 SetPolygonBoundingBox (Polygon);
1156 if (!Layer->polygon_tree)
1157 Layer->polygon_tree = r_create_tree (NULL, 0, 0);
1158 r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
1163 polygonholes
1164 : /* empty */
1165 | polygonholes polygonhole
1168 polygonhole
1169 : T_POLYGON_HOLE '('
1171 CreateNewHoleInPolygon (Polygon);
1173 polygonpoints ')'
1176 polygonpoints
1177 : /* empty */
1178 | polygonpoint polygonpoints
1181 polygonpoint
1182 /* xcoord ycoord */
1183 : '(' measure measure ')'
1185 CreateNewPointInPolygon(Polygon, OU ($2), OU ($3));
1187 | '[' measure measure ']'
1189 CreateNewPointInPolygon(Polygon, NU ($2), NU ($3));
1193 /* %start-doc pcbfile Element
1195 @syntax
1196 Element [SFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TSFlags] (
1197 Element (NFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TNFlags) (
1198 Element (NFlags "Desc" "Name" "Value" TX TY TDir TScale TNFlags) (
1199 Element (NFlags "Desc" "Name" TX TY TDir TScale TNFlags) (
1200 Element ("Desc" "Name" TX TY TDir TScale TNFlags) (
1201 @ @ @ @dots{} contents @dots{}
1203 @end syntax
1205 @table @var
1206 @item SFlags
1207 Symbolic or numeric flags, for the element as a whole.
1208 @item NFlags
1209 Numeric flags, for the element as a whole.
1210 @item Desc
1211 The description of the element. This is one of the three strings
1212 which can be displayed on the screen.
1213 @item Name
1214 The name of the element, usually the reference designator.
1215 @item Value
1216 The value of the element.
1217 @item MX MY
1218 The location of the element's mark. This is the reference point
1219 for placing the element and its pins and pads.
1220 @item TX TY
1221 The upper left corner of the text (one of the three strings).
1222 @item TDir
1223 The relative direction of the text. 0 means left to right for
1224 an unrotated element, 1 means up, 2 left, 3 down.
1225 @item TScale
1226 Size of the text, as a percentage of the ``default'' size of of the
1227 font (the default font is about 40 mils high). Default is 100 (40
1228 mils).
1229 @item TSFlags
1230 Symbolic or numeric flags, for the text.
1231 @item TNFlags
1232 Numeric flags, for the text.
1233 @end table
1235 Elements may contain pins, pads, element lines, element arcs,
1236 attributes, and (for older elements) an optional mark. Note that
1237 element definitions that have the mark coordinates in the element
1238 line, only support pins and pads which use relative coordinates. The
1239 pin and pad coordinates are relative to the mark. Element definitions
1240 which do not include the mark coordinates in the element line, may
1241 have a Mark definition in their contents, and only use pin and pad
1242 definitions which use absolute coordinates.
1244 %end-doc */
1246 element
1247 : element_oldformat
1248 | element_1.3.4_format
1249 | element_newformat
1250 | element_1.7_format
1251 | element_hi_format
1254 element_oldformat
1255 /* element_flags, description, pcb-name,
1256 * text_x, text_y, text_direction, text_scale, text_flags
1258 : T_ELEMENT '(' STRING STRING measure measure INTEGER ')' '('
1260 yyElement = CreateNewElement(yyData, yyFont, NoFlags(),
1261 $3, $4, NULL, OU ($5), OU ($6), $7, 100, NoFlags(), false);
1262 free ($3);
1263 free ($4);
1264 pin_num = 1;
1266 elementdefinitions ')'
1268 SetElementBoundingBox(yyData, yyElement, yyFont);
1272 element_1.3.4_format
1273 /* element_flags, description, pcb-name,
1274 * text_x, text_y, text_direction, text_scale, text_flags
1276 : T_ELEMENT '(' INTEGER STRING STRING measure measure measure measure INTEGER ')' '('
1278 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1279 $4, $5, NULL, OU ($6), OU ($7), IV ($8), IV ($9), OldFlags($10), false);
1280 free ($4);
1281 free ($5);
1282 pin_num = 1;
1284 elementdefinitions ')'
1286 SetElementBoundingBox(yyData, yyElement, yyFont);
1290 element_newformat
1291 /* element_flags, description, pcb-name, value,
1292 * text_x, text_y, text_direction, text_scale, text_flags
1294 : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure measure measure INTEGER ')' '('
1296 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1297 $4, $5, $6, OU ($7), OU ($8), IV ($9), IV ($10), OldFlags($11), false);
1298 free ($4);
1299 free ($5);
1300 free ($6);
1301 pin_num = 1;
1303 elementdefinitions ')'
1305 SetElementBoundingBox(yyData, yyElement, yyFont);
1309 element_1.7_format
1310 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1311 * text_x, text_y, text_direction, text_scale, text_flags
1313 : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure
1314 measure measure number number INTEGER ')' '('
1316 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1317 $4, $5, $6, OU ($7) + OU ($9), OU ($8) + OU ($10),
1318 $11, $12, OldFlags($13), false);
1319 yyElement->MarkX = OU ($7);
1320 yyElement->MarkY = OU ($8);
1321 free ($4);
1322 free ($5);
1323 free ($6);
1325 relementdefs ')'
1327 SetElementBoundingBox(yyData, yyElement, yyFont);
1331 element_hi_format
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 measure measure
1336 measure measure number number flags ']' '('
1338 yyElement = CreateNewElement(yyData, yyFont, $3,
1339 $4, $5, $6, NU ($7) + NU ($9), NU ($8) + NU ($10),
1340 $11, $12, $13, false);
1341 yyElement->MarkX = NU ($7);
1342 yyElement->MarkY = NU ($8);
1343 free ($4);
1344 free ($5);
1345 free ($6);
1347 relementdefs ')'
1349 SetElementBoundingBox(yyData, yyElement, yyFont);
1353 /* %start-doc pcbfile ElementLine
1355 @syntax
1356 ElementLine [X1 Y1 X2 Y2 Thickness]
1357 ElementLine (X1 Y1 X2 Y2 Thickness)
1358 @end syntax
1360 @table @var
1361 @item X1 Y1 X2 Y2
1362 Coordinates of the endpoints of the line. These are relative to the
1363 Element's mark point for new element formats, or absolute for older
1364 formats.
1365 @item Thickness
1366 The width of the silk for this line.
1367 @end table
1369 %end-doc */
1371 /* %start-doc pcbfile ElementArc
1373 @syntax
1374 ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
1375 ElementArc (X Y Width Height StartAngle DeltaAngle Thickness)
1376 @end syntax
1378 @table @var
1379 @item X Y
1380 Coordinates of the center of the arc. These are relative to the
1381 Element's mark point for new element formats, or absolute for older
1382 formats.
1383 @item Width Height
1384 The width and height, from the center to the edge. The bounds of the
1385 circle of which this arc is a segment, is thus @math{2*Width} by
1386 @math{2*Height}.
1387 @item StartAngle
1388 The angle of one end of the arc, in degrees. In PCB, an angle of zero
1389 points left (negative X direction), and 90 degrees points down
1390 (positive Y direction).
1391 @item DeltaAngle
1392 The sweep of the arc. This may be negative. Positive angles sweep
1393 counterclockwise.
1394 @item Thickness
1395 The width of the silk line which forms the arc.
1396 @end table
1398 %end-doc */
1400 /* %start-doc pcbfile Mark
1402 @syntax
1403 Mark [X Y]
1404 Mark (X Y)
1405 @end syntax
1407 @table @var
1408 @item X Y
1409 Coordinates of the Mark, for older element formats that don't have
1410 the mark as part of the Element line.
1411 @end table
1413 %end-doc */
1415 elementdefinitions
1416 : elementdefinition
1417 | elementdefinitions elementdefinition
1420 elementdefinition
1421 : pin_1.6.3_format
1422 | pin_newformat
1423 | pin_oldformat
1424 | pad_newformat
1425 | pad
1426 /* x1, y1, x2, y2, thickness */
1427 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1429 CreateNewLineInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1431 /* x1, y1, x2, y2, thickness */
1432 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1434 CreateNewLineInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1436 /* x, y, width, height, startangle, anglediff, thickness */
1437 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1439 CreateNewArcInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), $7, $8, NU ($9));
1441 /* x, y, width, height, startangle, anglediff, thickness */
1442 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1444 CreateNewArcInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), $7, $8, OU ($9));
1446 /* x, y position */
1447 | T_MARK '[' measure measure ']'
1449 yyElement->MarkX = NU ($3);
1450 yyElement->MarkY = NU ($4);
1452 | T_MARK '(' measure measure ')'
1454 yyElement->MarkX = OU ($3);
1455 yyElement->MarkY = OU ($4);
1457 | { attr_list = & yyElement->Attributes; } attribute
1460 relementdefs
1461 : relementdef
1462 | relementdefs relementdef
1465 relementdef
1466 : pin_1.7_format
1467 | pin_hi_format
1468 | pad_1.7_format
1469 | pad_hi_format
1470 /* x1, y1, x2, y2, thickness */
1471 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1473 CreateNewLineInElement(yyElement, NU ($3) + yyElement->MarkX,
1474 NU ($4) + yyElement->MarkY, NU ($5) + yyElement->MarkX,
1475 NU ($6) + yyElement->MarkY, NU ($7));
1477 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1479 CreateNewLineInElement(yyElement, OU ($3) + yyElement->MarkX,
1480 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1481 OU ($6) + yyElement->MarkY, OU ($7));
1483 /* x, y, width, height, startangle, anglediff, thickness */
1484 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1486 CreateNewArcInElement(yyElement, NU ($3) + yyElement->MarkX,
1487 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), $7, $8, NU ($9));
1489 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1491 CreateNewArcInElement(yyElement, OU ($3) + yyElement->MarkX,
1492 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), $7, $8, OU ($9));
1494 | { attr_list = & yyElement->Attributes; } attribute
1497 /* %start-doc pcbfile Pin
1499 @syntax
1500 Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags]
1501 Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags)
1502 Pin (aX aY Thickness Drill "Name" "Number" NFlags)
1503 Pin (aX aY Thickness Drill "Name" NFlags)
1504 Pin (aX aY Thickness "Name" NFlags)
1505 @end syntax
1507 @table @var
1508 @item rX rY
1509 coordinates of center, relative to the element's mark
1510 @item aX aY
1511 absolute coordinates of center.
1512 @item Thickness
1513 outer diameter of copper annulus
1514 @item Clearance
1515 add to thickness to get clearance diameter
1516 @item Mask
1517 diameter of solder mask opening
1518 @item Drill
1519 diameter of drill
1520 @item Name
1521 name of pin
1522 @item Number
1523 number of pin
1524 @item SFlags
1525 symbolic or numerical flags
1526 @item NFlags
1527 numerical flags only
1528 @end table
1530 %end-doc */
1532 pin_hi_format
1533 /* x, y, thickness, clearance, mask, drilling hole, name,
1534 number, flags */
1535 : T_PIN '[' measure measure measure measure measure measure STRING STRING flags ']'
1537 CreateNewPin(yyElement, NU ($3) + yyElement->MarkX,
1538 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), NU ($7), NU ($8), $9,
1539 $10, $11);
1540 free ($9);
1541 free ($10);
1544 pin_1.7_format
1545 /* x, y, thickness, clearance, mask, drilling hole, name,
1546 number, flags */
1547 : T_PIN '(' measure measure measure measure measure measure STRING STRING INTEGER ')'
1549 CreateNewPin(yyElement, OU ($3) + yyElement->MarkX,
1550 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), OU ($7), OU ($8), $9,
1551 $10, OldFlags($11));
1552 free ($9);
1553 free ($10);
1557 pin_1.6.3_format
1558 /* x, y, thickness, drilling hole, name, number, flags */
1559 : T_PIN '(' measure measure measure measure STRING STRING INTEGER ')'
1561 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1562 OU ($5) + 2*MASKFRAME, OU ($6), $7, $8, OldFlags($9));
1563 free ($7);
1564 free ($8);
1568 pin_newformat
1569 /* x, y, thickness, drilling hole, name, flags */
1570 : T_PIN '(' measure measure measure measure STRING INTEGER ')'
1572 char p_number[8];
1574 sprintf(p_number, "%d", pin_num++);
1575 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1576 OU ($5) + 2*MASKFRAME, OU ($6), $7, p_number, OldFlags($8));
1578 free ($7);
1582 pin_oldformat
1583 /* old format: x, y, thickness, name, flags
1584 * drilling hole is 40% of the diameter
1586 : T_PIN '(' measure measure measure STRING INTEGER ')'
1588 Coord hole = OU ($5) * DEFAULT_DRILLINGHOLE;
1589 char p_number[8];
1591 /* make sure that there's enough copper left */
1592 if (OU ($5) - hole < MIN_PINORVIACOPPER &&
1593 OU ($5) > MIN_PINORVIACOPPER)
1594 hole = OU ($5) - MIN_PINORVIACOPPER;
1596 sprintf(p_number, "%d", pin_num++);
1597 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1598 OU ($5) + 2*MASKFRAME, hole, $6, p_number, OldFlags($7));
1599 free ($6);
1603 /* %start-doc pcbfile Pad
1605 @syntax
1606 Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags]
1607 Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags)
1608 Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags)
1609 Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags)
1610 @end syntax
1612 @table @var
1613 @item rX1 rY1 rX2 rY2
1614 Coordinates of the endpoints of the pad, relative to the element's
1615 mark. Note that the copper extends beyond these coordinates by half
1616 the thickness. To make a square or round pad, specify the same
1617 coordinate twice.
1618 @item aX1 aY1 aX2 aY2
1619 Same, but absolute coordinates of the endpoints of the pad.
1620 @item Thickness
1621 width of the pad.
1622 @item Clearance
1623 add to thickness to get clearance width.
1624 @item Mask
1625 width of solder mask opening.
1626 @item Name
1627 name of pin
1628 @item Number
1629 number of pin
1630 @item SFlags
1631 symbolic or numerical flags
1632 @item NFlags
1633 numerical flags only
1634 @end table
1636 %end-doc */
1638 pad_hi_format
1639 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1640 : T_PAD '[' measure measure measure measure measure measure measure STRING STRING flags ']'
1642 CreateNewPad(yyElement, NU ($3) + yyElement->MarkX,
1643 NU ($4) + yyElement->MarkY,
1644 NU ($5) + yyElement->MarkX,
1645 NU ($6) + yyElement->MarkY, NU ($7), NU ($8), NU ($9),
1646 $10, $11, $12);
1647 free ($10);
1648 free ($11);
1652 pad_1.7_format
1653 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1654 : T_PAD '(' measure measure measure measure measure measure measure STRING STRING INTEGER ')'
1656 CreateNewPad(yyElement,OU ($3) + yyElement->MarkX,
1657 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1658 OU ($6) + yyElement->MarkY, OU ($7), OU ($8), OU ($9),
1659 $10, $11, OldFlags($12));
1660 free ($10);
1661 free ($11);
1665 pad_newformat
1666 /* x1, y1, x2, y2, thickness, name , pad number, flags */
1667 : T_PAD '(' measure measure measure measure measure STRING STRING INTEGER ')'
1669 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1670 OU ($7) + 2*MASKFRAME, $8, $9, OldFlags($10));
1671 free ($8);
1672 free ($9);
1677 /* x1, y1, x2, y2, thickness, name and flags */
1678 : T_PAD '(' measure measure measure measure measure STRING INTEGER ')'
1680 char p_number[8];
1682 sprintf(p_number, "%d", pin_num++);
1683 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1684 OU ($7) + 2*MASKFRAME, $8,p_number, OldFlags($9));
1685 free ($8);
1689 flags : INTEGER { $$ = OldFlags($1); }
1690 | STRING { $$ = string_to_flags ($1, yyerror); }
1693 symbols
1694 : symbol
1695 | symbols symbol
1698 /* %start-doc pcbfile Symbol
1700 @syntax
1701 Symbol [Char Delta] (
1702 Symbol (Char Delta) (
1703 @ @ @ @dots{} symbol lines @dots{}
1705 @end syntax
1707 @table @var
1708 @item Char
1709 The character or numerical character value this symbol represents.
1710 Characters must be in single quotes.
1711 @item Delta
1712 Additional space to allow after this character.
1713 @end table
1715 %end-doc */
1717 symbol : symbolhead symboldata ')'
1719 symbolhead : T_SYMBOL '[' symbolid measure ']' '('
1721 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1723 yyerror("fontposition out of range");
1724 YYABORT;
1726 Symbol = &yyFont->Symbol[$3];
1727 if (Symbol->Valid)
1729 yyerror("symbol ID used twice");
1730 YYABORT;
1732 Symbol->Valid = true;
1733 Symbol->Delta = NU ($4);
1735 | T_SYMBOL '(' symbolid measure ')' '('
1737 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1739 yyerror("fontposition out of range");
1740 YYABORT;
1742 Symbol = &yyFont->Symbol[$3];
1743 if (Symbol->Valid)
1745 yyerror("symbol ID used twice");
1746 YYABORT;
1748 Symbol->Valid = true;
1749 Symbol->Delta = OU ($4);
1753 symbolid
1754 : INTEGER
1755 | CHAR_CONST
1758 symboldata
1759 : /* empty */
1760 | symboldata symboldefinition
1761 | symboldata hiressymbol
1764 /* %start-doc pcbfile SymbolLine
1766 @syntax
1767 SymbolLine [X1 Y1 X2 Y2 Thickness]
1768 SymbolLine (X1 Y1 X2 Y2 Thickness)
1769 @end syntax
1771 @table @var
1772 @item X1 Y1 X2 Y2
1773 The endpoints of this line.
1774 @item Thickness
1775 The width of this line.
1776 @end table
1778 %end-doc */
1780 symboldefinition
1781 /* x1, y1, x2, y2, thickness */
1782 : T_SYMBOLLINE '(' measure measure measure measure measure ')'
1784 CreateNewLineInSymbol(Symbol, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1787 hiressymbol
1788 /* x1, y1, x2, y2, thickness */
1789 : T_SYMBOLLINE '[' measure measure measure measure measure ']'
1791 CreateNewLineInSymbol(Symbol, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1795 /* %start-doc pcbfile Netlist
1797 @syntax
1798 Netlist ( ) (
1799 @ @ @ @dots{} nets @dots{}
1801 @end syntax
1803 %end-doc */
1805 pcbnetlist : pcbnetdef
1808 pcbnetdef
1809 /* net(...) net(...) ... */
1810 : T_NETLIST '(' ')' '('
1811 nets ')'
1814 nets
1815 : netdefs
1819 netdefs
1820 : net
1821 | netdefs net
1824 /* %start-doc pcbfile Net
1826 @syntax
1827 Net ("Name" "Style") (
1828 @ @ @ @dots{} connects @dots{}
1830 @end syntax
1832 @table @var
1833 @item Name
1834 The name of this net.
1835 @item Style
1836 The routing style that should be used when autorouting this net.
1837 @end table
1839 %end-doc */
1842 /* name style pin pin ... */
1843 : T_NET '(' STRING STRING ')' '('
1845 Menu = CreateNewNet(&yyPCB->NetlistLib, $3, $4);
1846 free ($3);
1847 free ($4);
1849 connections ')'
1852 connections
1853 : conndefs
1857 conndefs
1858 : conn
1859 | conndefs conn
1862 /* %start-doc pcbfile Connect
1864 @syntax
1865 Connect ("PinPad")
1866 @end syntax
1868 @table @var
1869 @item PinPad
1870 The name of a pin or pad which is included in this net. Pin and Pad
1871 names are named by the refdes and pin name, like @code{"U14-7"} for
1872 pin 7 of U14, or @code{"T4-E"} for pin E of T4.
1873 @end table
1875 %end-doc */
1877 conn
1878 : T_CONN '(' STRING ')'
1880 CreateNewConnection(Menu, $3);
1881 free ($3);
1885 /* %start-doc pcbfile Attribute
1887 @syntax
1888 Attribute ("Name" "Value")
1889 @end syntax
1891 Attributes allow boards and elements to have arbitrary data attached
1892 to them, which is not directly used by PCB itself but may be of use by
1893 other programs or users.
1895 @table @var
1896 @item Name
1897 The name of the attribute
1899 @item Value
1900 The value of the attribute. Values are always stored as strings, even
1901 if the value is interpreted as, for example, a number.
1903 @end table
1905 %end-doc */
1907 attribute
1908 : T_ATTRIBUTE '(' STRING STRING ')'
1910 CreateNewAttribute (attr_list, $3, $4 ? $4 : (char *)"");
1911 free ($3);
1912 free ($4);
1916 opt_string : STRING { $$ = $1; }
1917 | /* empty */ { $$ = 0; }
1920 number
1921 : FLOATING { $$ = $1; }
1922 | INTEGER { $$ = $1; }
1925 measure
1926 /* Default unit (no suffix) is cmil */
1927 : number { do_measure(&$$, $1, MIL_TO_COORD ($1) / 100.0, 0); }
1928 | number T_UMIL { M ($$, $1, MIL_TO_COORD ($1) / 1000000.0); }
1929 | number T_CMIL { M ($$, $1, MIL_TO_COORD ($1) / 100.0); }
1930 | number T_MIL { M ($$, $1, MIL_TO_COORD ($1)); }
1931 | number T_IN { M ($$, $1, INCH_TO_COORD ($1)); }
1932 | number T_NM { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1933 | number T_PX { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1934 | number T_UM { M ($$, $1, MM_TO_COORD ($1) / 1000.0); }
1935 | number T_MM { M ($$, $1, MM_TO_COORD ($1)); }
1936 | number T_M { M ($$, $1, MM_TO_COORD ($1) * 1000.0); }
1937 | number T_KM { M ($$, $1, MM_TO_COORD ($1) * 1000000.0); }
1942 /* ---------------------------------------------------------------------------
1943 * error routine called by parser library
1945 int yyerror(const char * s)
1947 Message(_("ERROR parsing file '%s'\n"
1948 " line: %i\n"
1949 " description: '%s'\n"),
1950 yyfilename, yylineno, s);
1951 return(0);
1954 int yywrap()
1956 return 1;
1959 static int
1960 check_file_version (int ver)
1962 if ( ver > PCB_FILE_VERSION ) {
1963 Message (_("ERROR: The file you are attempting to load is in a format\n"
1964 "which is too new for this version of pcb. To load this file\n"
1965 "you need a version of pcb which is >= %d. If you are\n"
1966 "using a version built from git source, the source date\n"
1967 "must be >= %d. This copy of pcb can only read files\n"
1968 "up to file version %d.\n"), ver, ver, PCB_FILE_VERSION);
1969 return 1;
1972 return 0;
1975 static void
1976 do_measure (PLMeasure *m, Coord i, double d, int u)
1978 m->ival = i;
1979 m->bval = round (d);
1980 m->dval = d;
1981 m->has_units = u;
1984 static int
1985 integer_value (PLMeasure m)
1987 if (m.has_units)
1988 yyerror("units ignored here");
1989 return m.ival;
1992 static Coord
1993 old_units (PLMeasure m)
1995 if (m.has_units)
1996 return m.bval;
1997 return round (MIL_TO_COORD (m.ival));
2000 static Coord
2001 new_units (PLMeasure m)
2003 if (m.has_units)
2004 return m.bval;
2005 return round (MIL_TO_COORD (m.ival) / 100.0);