Fix lockup when a scroll event is received outside the drawing area
[geda-pcb/pcjc2.git] / src / parse_y.y
blobfdd639295e02424767f1cc36a6f4882a0e1db1c7
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
687 | element
688 | error { YYABORT; }
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 + 2)
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;
864 if (yyData->LayerN + 2 < $3)
865 yyData->LayerN = $3 - 2;
867 layerdata ')'
870 layerdata
871 : layerdefinitions
875 layerdefinitions
876 : layerdefinition
877 | layerdefinitions layerdefinition
880 layerdefinition
881 : line_hi_format
882 | line_1.7_format
883 | line_oldformat
884 | arc_hi_format
885 | arc_1.7_format
886 | arc_oldformat
887 /* x1, y1, x2, y2, flags */
888 | T_RECTANGLE '(' measure measure measure measure INTEGER ')'
890 CreateNewPolygonFromRectangle(Layer,
891 OU ($3), OU ($4), OU ($3) + OU ($5), OU ($4) + OU ($6), OldFlags($7));
893 | text_hi_format
894 | text_newformat
895 | text_oldformat
896 | { attr_list = & Layer->Attributes; } attribute
897 | polygon_format
899 /* %start-doc pcbfile Line
901 @syntax
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)
905 @end syntax
907 @table @var
908 @item X1 Y1 X2 Y2
909 The end points of the line
910 @item Thickness
911 The width of the line
912 @item Clearance
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.
917 @item SFlags
918 Symbolic or numeric flags
919 @item NFlags
920 Numeric flags.
921 @end table
923 %end-doc */
925 line_hi_format
926 /* x1, y1, x2, y2, thickness, clearance, flags */
927 : T_LINE '[' measure measure measure measure measure measure flags ']'
929 CreateNewLineOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6),
930 NU ($7), NU ($8), $9);
934 line_1.7_format
935 /* x1, y1, x2, y2, thickness, clearance, flags */
936 : T_LINE '(' measure measure measure measure measure measure INTEGER ')'
938 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6),
939 OU ($7), OU ($8), OldFlags($9));
943 line_oldformat
944 /* x1, y1, x2, y2, thickness, flags */
945 : T_LINE '(' measure measure measure measure measure measure ')'
947 /* eliminate old-style rat-lines */
948 if ((IV ($8) & RATFLAG) == 0)
949 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7),
950 200*GROUNDPLANEFRAME, OldFlags(IV ($8)));
954 /* %start-doc pcbfile Arc
956 @syntax
957 Arc [X Y Width Height Thickness Clearance StartAngle DeltaAngle SFlags]
958 Arc (X Y Width Height Thickness Clearance StartAngle DeltaAngle NFlags)
959 Arc (X Y Width Height Thickness StartAngle DeltaAngle NFlags)
960 @end syntax
962 @table @var
963 @item X Y
964 Coordinates of the center of the arc.
965 @item Width Height
966 The width and height, from the center to the edge. The bounds of the
967 circle of which this arc is a segment, is thus @math{2*Width} by
968 @math{2*Height}.
969 @item Thickness
970 The width of the copper trace which forms the arc.
971 @item Clearance
972 The amount of space cleared around the arc when the line passes
973 through a polygon. The clearance is added to the thickness to get the
974 thickness of the clear; thus the space between the arc and the polygon
975 is @math{Clearance/2} wide.
976 @item StartAngle
977 The angle of one end of the arc, in degrees. In PCB, an angle of zero
978 points left (negative X direction), and 90 degrees points down
979 (positive Y direction).
980 @item DeltaAngle
981 The sweep of the arc. This may be negative. Positive angles sweep
982 counterclockwise.
983 @item SFlags
984 Symbolic or numeric flags.
985 @item NFlags
986 Numeric flags.
987 @end table
989 %end-doc */
991 arc_hi_format
992 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
993 : T_ARC '[' measure measure measure measure measure measure number number flags ']'
995 CreateNewArcOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6), $9, $10,
996 NU ($7), NU ($8), $11);
1000 arc_1.7_format
1001 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
1002 : T_ARC '(' measure measure measure measure measure measure number number INTEGER ')'
1004 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), $9, $10,
1005 OU ($7), OU ($8), OldFlags($11));
1009 arc_oldformat
1010 /* x, y, width, height, thickness, startangle, delta, flags */
1011 : T_ARC '(' measure measure measure measure measure measure number INTEGER ')'
1013 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($5), IV ($8), $9,
1014 OU ($7), 200*GROUNDPLANEFRAME, OldFlags($10));
1018 /* %start-doc pcbfile Text
1020 @syntax
1021 Text [X Y Direction Scale "String" SFlags]
1022 Text (X Y Direction Scale "String" NFlags)
1023 Text (X Y Direction "String" NFlags)
1024 @end syntax
1026 @table @var
1027 @item X Y
1028 The location of the upper left corner of the text.
1029 @item Direction
1030 0 means text is drawn left to right, 1 means up, 2 means right to left
1031 (i.e. upside down), and 3 means down.
1032 @item Scale
1033 Size of the text, as a percentage of the ``default'' size of of the
1034 font (the default font is about 40 mils high). Default is 100 (40
1035 mils).
1036 @item String
1037 The string to draw.
1038 @item SFlags
1039 Symbolic or numeric flags.
1040 @item NFlags
1041 Numeric flags.
1042 @end table
1044 %end-doc */
1046 text_oldformat
1047 /* x, y, direction, text, flags */
1048 : T_TEXT '(' measure measure number STRING INTEGER ')'
1050 /* use a default scale of 100% */
1051 CreateNewText(Layer,yyFont,OU ($3), OU ($4), $5, 100, $6, OldFlags($7));
1052 free ($6);
1056 text_newformat
1057 /* x, y, direction, scale, text, flags */
1058 : T_TEXT '(' measure measure number number STRING INTEGER ')'
1060 if ($8 & ONSILKFLAG)
1062 LayerType *lay = &yyData->Layer[yyData->LayerN +
1063 (($8 & ONSOLDERFLAG) ? SOLDER_LAYER : COMPONENT_LAYER)];
1065 CreateNewText(lay ,yyFont, OU ($3), OU ($4), $5, $6, $7,
1066 OldFlags($8));
1068 else
1069 CreateNewText(Layer, yyFont, OU ($3), OU ($4), $5, $6, $7,
1070 OldFlags($8));
1071 free ($7);
1074 text_hi_format
1075 /* x, y, direction, scale, text, flags */
1076 : T_TEXT '[' measure measure number number STRING flags ']'
1078 /* FIXME: shouldn't know about .f */
1079 /* I don't think this matters because anything with hi_format
1080 * will have the silk on its own layer in the file rather
1081 * than using the ONSILKFLAG and having it in a copper layer.
1082 * Thus there is no need for anything besides the 'else'
1083 * part of this code.
1085 if ($8.f & ONSILKFLAG)
1087 LayerType *lay = &yyData->Layer[yyData->LayerN +
1088 (($8.f & ONSOLDERFLAG) ? SOLDER_LAYER : COMPONENT_LAYER)];
1090 CreateNewText(lay, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1092 else
1093 CreateNewText(Layer, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1094 free ($7);
1098 /* %start-doc pcbfile Polygon
1100 @syntax
1101 Polygon (SFlags) (
1102 @ @ @ @dots{} (X Y) @dots{}
1103 @ @ @ @dots{} [X Y] @dots{}
1104 @ @ @ Hole (
1105 @ @ @ @ @ @ @dots{} (X Y) @dots{}
1106 @ @ @ @ @ @ @dots{} [X Y] @dots{}
1107 @ @ @ )
1108 @ @ @ @dots{}
1110 @end syntax
1112 @table @var
1113 @item SFlags
1114 Symbolic or numeric flags.
1115 @item X Y
1116 Coordinates of each vertex. You must list at least three coordinates.
1117 @item Hole (...)
1118 Defines a hole within the polygon's outer contour. There may be zero or more such sections.
1119 @end table
1121 %end-doc */
1123 polygon_format
1124 : /* flags are passed in */
1125 T_POLYGON '(' flags ')' '('
1127 Polygon = CreateNewPolygon(Layer, $3);
1129 polygonpoints
1130 polygonholes ')'
1132 Cardinal contour, contour_start, contour_end;
1133 bool bad_contour_found = false;
1134 /* ignore junk */
1135 for (contour = 0; contour <= Polygon->HoleIndexN; contour++)
1137 contour_start = (contour == 0) ?
1138 0 : Polygon->HoleIndex[contour - 1];
1139 contour_end = (contour == Polygon->HoleIndexN) ?
1140 Polygon->PointN :
1141 Polygon->HoleIndex[contour];
1142 if (contour_end - contour_start < 3)
1143 bad_contour_found = true;
1146 if (bad_contour_found)
1148 Message("WARNING parsing file '%s'\n"
1149 " line: %i\n"
1150 " description: 'ignored polygon (< 3 points in a contour)'\n",
1151 yyfilename, yylineno);
1152 DestroyObject(yyData, POLYGON_TYPE, Layer, Polygon, Polygon);
1154 else
1156 SetPolygonBoundingBox (Polygon);
1157 if (!Layer->polygon_tree)
1158 Layer->polygon_tree = r_create_tree (NULL, 0, 0);
1159 r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
1164 polygonholes
1165 : /* empty */
1166 | polygonholes polygonhole
1169 polygonhole
1170 : T_POLYGON_HOLE '('
1172 CreateNewHoleInPolygon (Polygon);
1174 polygonpoints ')'
1177 polygonpoints
1178 : /* empty */
1179 | polygonpoint polygonpoints
1182 polygonpoint
1183 /* xcoord ycoord */
1184 : '(' measure measure ')'
1186 CreateNewPointInPolygon(Polygon, OU ($2), OU ($3));
1188 | '[' measure measure ']'
1190 CreateNewPointInPolygon(Polygon, NU ($2), NU ($3));
1194 /* %start-doc pcbfile Element
1196 @syntax
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{}
1204 @end syntax
1206 @table @var
1207 @item SFlags
1208 Symbolic or numeric flags, for the element as a whole.
1209 @item NFlags
1210 Numeric flags, for the element as a whole.
1211 @item Desc
1212 The description of the element. This is one of the three strings
1213 which can be displayed on the screen.
1214 @item Name
1215 The name of the element, usually the reference designator.
1216 @item Value
1217 The value of the element.
1218 @item MX MY
1219 The location of the element's mark. This is the reference point
1220 for placing the element and its pins and pads.
1221 @item TX TY
1222 The upper left corner of the text (one of the three strings).
1223 @item TDir
1224 The relative direction of the text. 0 means left to right for
1225 an unrotated element, 1 means up, 2 left, 3 down.
1226 @item TScale
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
1229 mils).
1230 @item TSFlags
1231 Symbolic or numeric flags, for the text.
1232 @item TNFlags
1233 Numeric flags, for the text.
1234 @end table
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.
1245 %end-doc */
1247 element
1248 : element_oldformat
1249 | element_1.3.4_format
1250 | element_newformat
1251 | element_1.7_format
1252 | element_hi_format
1255 element_oldformat
1256 /* element_flags, description, pcb-name,
1257 * text_x, text_y, text_direction, text_scale, text_flags
1259 : T_ELEMENT '(' STRING STRING measure measure INTEGER ')' '('
1261 yyElement = CreateNewElement(yyData, yyFont, NoFlags(),
1262 $3, $4, NULL, OU ($5), OU ($6), $7, 100, NoFlags(), false);
1263 free ($3);
1264 free ($4);
1265 pin_num = 1;
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 '(' INTEGER STRING STRING measure measure measure measure INTEGER ')' '('
1279 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1280 $4, $5, NULL, OU ($6), OU ($7), IV ($8), IV ($9), OldFlags($10), false);
1281 free ($4);
1282 free ($5);
1283 pin_num = 1;
1285 elementdefinitions ')'
1287 SetElementBoundingBox(yyData, yyElement, yyFont);
1291 element_newformat
1292 /* element_flags, description, pcb-name, value,
1293 * text_x, text_y, text_direction, text_scale, text_flags
1295 : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure measure measure INTEGER ')' '('
1297 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1298 $4, $5, $6, OU ($7), OU ($8), IV ($9), IV ($10), OldFlags($11), false);
1299 free ($4);
1300 free ($5);
1301 free ($6);
1302 pin_num = 1;
1304 elementdefinitions ')'
1306 SetElementBoundingBox(yyData, yyElement, yyFont);
1310 element_1.7_format
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 '(' INTEGER STRING STRING STRING measure measure
1315 measure measure number number INTEGER ')' '('
1317 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1318 $4, $5, $6, OU ($7) + OU ($9), OU ($8) + OU ($10),
1319 $11, $12, OldFlags($13), false);
1320 yyElement->MarkX = OU ($7);
1321 yyElement->MarkY = OU ($8);
1322 free ($4);
1323 free ($5);
1324 free ($6);
1326 relementdefs ')'
1328 SetElementBoundingBox(yyData, yyElement, yyFont);
1332 element_hi_format
1333 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1334 * text_x, text_y, text_direction, text_scale, text_flags
1336 : T_ELEMENT '[' flags STRING STRING STRING measure measure
1337 measure measure number number flags ']' '('
1339 yyElement = CreateNewElement(yyData, yyFont, $3,
1340 $4, $5, $6, NU ($7) + NU ($9), NU ($8) + NU ($10),
1341 $11, $12, $13, false);
1342 yyElement->MarkX = NU ($7);
1343 yyElement->MarkY = NU ($8);
1344 free ($4);
1345 free ($5);
1346 free ($6);
1348 relementdefs ')'
1350 SetElementBoundingBox(yyData, yyElement, yyFont);
1354 /* %start-doc pcbfile ElementLine
1356 @syntax
1357 ElementLine [X1 Y1 X2 Y2 Thickness]
1358 ElementLine (X1 Y1 X2 Y2 Thickness)
1359 @end syntax
1361 @table @var
1362 @item X1 Y1 X2 Y2
1363 Coordinates of the endpoints of the line. These are relative to the
1364 Element's mark point for new element formats, or absolute for older
1365 formats.
1366 @item Thickness
1367 The width of the silk for this line.
1368 @end table
1370 %end-doc */
1372 /* %start-doc pcbfile ElementArc
1374 @syntax
1375 ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
1376 ElementArc (X Y Width Height StartAngle DeltaAngle Thickness)
1377 @end syntax
1379 @table @var
1380 @item X Y
1381 Coordinates of the center of the arc. These are relative to the
1382 Element's mark point for new element formats, or absolute for older
1383 formats.
1384 @item Width Height
1385 The width and height, from the center to the edge. The bounds of the
1386 circle of which this arc is a segment, is thus @math{2*Width} by
1387 @math{2*Height}.
1388 @item StartAngle
1389 The angle of one end of the arc, in degrees. In PCB, an angle of zero
1390 points left (negative X direction), and 90 degrees points down
1391 (positive Y direction).
1392 @item DeltaAngle
1393 The sweep of the arc. This may be negative. Positive angles sweep
1394 counterclockwise.
1395 @item Thickness
1396 The width of the silk line which forms the arc.
1397 @end table
1399 %end-doc */
1401 /* %start-doc pcbfile Mark
1403 @syntax
1404 Mark [X Y]
1405 Mark (X Y)
1406 @end syntax
1408 @table @var
1409 @item X Y
1410 Coordinates of the Mark, for older element formats that don't have
1411 the mark as part of the Element line.
1412 @end table
1414 %end-doc */
1416 elementdefinitions
1417 : elementdefinition
1418 | elementdefinitions elementdefinition
1421 elementdefinition
1422 : pin_1.6.3_format
1423 | pin_newformat
1424 | pin_oldformat
1425 | pad_newformat
1426 | pad
1427 /* x1, y1, x2, y2, thickness */
1428 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1430 CreateNewLineInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1432 /* x1, y1, x2, y2, thickness */
1433 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1435 CreateNewLineInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1437 /* x, y, width, height, startangle, anglediff, thickness */
1438 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1440 CreateNewArcInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), $7, $8, NU ($9));
1442 /* x, y, width, height, startangle, anglediff, thickness */
1443 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1445 CreateNewArcInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), $7, $8, OU ($9));
1447 /* x, y position */
1448 | T_MARK '[' measure measure ']'
1450 yyElement->MarkX = NU ($3);
1451 yyElement->MarkY = NU ($4);
1453 | T_MARK '(' measure measure ')'
1455 yyElement->MarkX = OU ($3);
1456 yyElement->MarkY = OU ($4);
1458 | { attr_list = & yyElement->Attributes; } attribute
1461 relementdefs
1462 : relementdef
1463 | relementdefs relementdef
1466 relementdef
1467 : pin_1.7_format
1468 | pin_hi_format
1469 | pad_1.7_format
1470 | pad_hi_format
1471 /* x1, y1, x2, y2, thickness */
1472 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1474 CreateNewLineInElement(yyElement, NU ($3) + yyElement->MarkX,
1475 NU ($4) + yyElement->MarkY, NU ($5) + yyElement->MarkX,
1476 NU ($6) + yyElement->MarkY, NU ($7));
1478 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1480 CreateNewLineInElement(yyElement, OU ($3) + yyElement->MarkX,
1481 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1482 OU ($6) + yyElement->MarkY, OU ($7));
1484 /* x, y, width, height, startangle, anglediff, thickness */
1485 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1487 CreateNewArcInElement(yyElement, NU ($3) + yyElement->MarkX,
1488 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), $7, $8, NU ($9));
1490 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1492 CreateNewArcInElement(yyElement, OU ($3) + yyElement->MarkX,
1493 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), $7, $8, OU ($9));
1495 | { attr_list = & yyElement->Attributes; } attribute
1498 /* %start-doc pcbfile Pin
1500 @syntax
1501 Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags]
1502 Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags)
1503 Pin (aX aY Thickness Drill "Name" "Number" NFlags)
1504 Pin (aX aY Thickness Drill "Name" NFlags)
1505 Pin (aX aY Thickness "Name" NFlags)
1506 @end syntax
1508 @table @var
1509 @item rX rY
1510 coordinates of center, relative to the element's mark
1511 @item aX aY
1512 absolute coordinates of center.
1513 @item Thickness
1514 outer diameter of copper annulus
1515 @item Clearance
1516 add to thickness to get clearance diameter
1517 @item Mask
1518 diameter of solder mask opening
1519 @item Drill
1520 diameter of drill
1521 @item Name
1522 name of pin
1523 @item Number
1524 number of pin
1525 @item SFlags
1526 symbolic or numerical flags
1527 @item NFlags
1528 numerical flags only
1529 @end table
1531 %end-doc */
1533 pin_hi_format
1534 /* x, y, thickness, clearance, mask, drilling hole, name,
1535 number, flags */
1536 : T_PIN '[' measure measure measure measure measure measure STRING STRING flags ']'
1538 CreateNewPin(yyElement, NU ($3) + yyElement->MarkX,
1539 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), NU ($7), NU ($8), $9,
1540 $10, $11);
1541 free ($9);
1542 free ($10);
1545 pin_1.7_format
1546 /* x, y, thickness, clearance, mask, drilling hole, name,
1547 number, flags */
1548 : T_PIN '(' measure measure measure measure measure measure STRING STRING INTEGER ')'
1550 CreateNewPin(yyElement, OU ($3) + yyElement->MarkX,
1551 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), OU ($7), OU ($8), $9,
1552 $10, OldFlags($11));
1553 free ($9);
1554 free ($10);
1558 pin_1.6.3_format
1559 /* x, y, thickness, drilling hole, name, number, flags */
1560 : T_PIN '(' measure measure measure measure STRING STRING INTEGER ')'
1562 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1563 OU ($5) + 2*MASKFRAME, OU ($6), $7, $8, OldFlags($9));
1564 free ($7);
1565 free ($8);
1569 pin_newformat
1570 /* x, y, thickness, drilling hole, name, flags */
1571 : T_PIN '(' measure measure measure measure STRING INTEGER ')'
1573 char p_number[8];
1575 sprintf(p_number, "%d", pin_num++);
1576 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1577 OU ($5) + 2*MASKFRAME, OU ($6), $7, p_number, OldFlags($8));
1579 free ($7);
1583 pin_oldformat
1584 /* old format: x, y, thickness, name, flags
1585 * drilling hole is 40% of the diameter
1587 : T_PIN '(' measure measure measure STRING INTEGER ')'
1589 Coord hole = OU ($5) * DEFAULT_DRILLINGHOLE;
1590 char p_number[8];
1592 /* make sure that there's enough copper left */
1593 if (OU ($5) - hole < MIN_PINORVIACOPPER &&
1594 OU ($5) > MIN_PINORVIACOPPER)
1595 hole = OU ($5) - MIN_PINORVIACOPPER;
1597 sprintf(p_number, "%d", pin_num++);
1598 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1599 OU ($5) + 2*MASKFRAME, hole, $6, p_number, OldFlags($7));
1600 free ($6);
1604 /* %start-doc pcbfile Pad
1606 @syntax
1607 Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags]
1608 Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags)
1609 Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags)
1610 Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags)
1611 @end syntax
1613 @table @var
1614 @item rX1 rY1 rX2 rY2
1615 Coordinates of the endpoints of the pad, relative to the element's
1616 mark. Note that the copper extends beyond these coordinates by half
1617 the thickness. To make a square or round pad, specify the same
1618 coordinate twice.
1619 @item aX1 aY1 aX2 aY2
1620 Same, but absolute coordinates of the endpoints of the pad.
1621 @item Thickness
1622 width of the pad.
1623 @item Clearance
1624 add to thickness to get clearance width.
1625 @item Mask
1626 width of solder mask opening.
1627 @item Name
1628 name of pin
1629 @item Number
1630 number of pin
1631 @item SFlags
1632 symbolic or numerical flags
1633 @item NFlags
1634 numerical flags only
1635 @end table
1637 %end-doc */
1639 pad_hi_format
1640 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1641 : T_PAD '[' measure measure measure measure measure measure measure STRING STRING flags ']'
1643 CreateNewPad(yyElement, NU ($3) + yyElement->MarkX,
1644 NU ($4) + yyElement->MarkY,
1645 NU ($5) + yyElement->MarkX,
1646 NU ($6) + yyElement->MarkY, NU ($7), NU ($8), NU ($9),
1647 $10, $11, $12);
1648 free ($10);
1649 free ($11);
1653 pad_1.7_format
1654 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1655 : T_PAD '(' measure measure measure measure measure measure measure STRING STRING INTEGER ')'
1657 CreateNewPad(yyElement,OU ($3) + yyElement->MarkX,
1658 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1659 OU ($6) + yyElement->MarkY, OU ($7), OU ($8), OU ($9),
1660 $10, $11, OldFlags($12));
1661 free ($10);
1662 free ($11);
1666 pad_newformat
1667 /* x1, y1, x2, y2, thickness, name , pad number, flags */
1668 : T_PAD '(' measure measure measure measure measure STRING STRING INTEGER ')'
1670 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1671 OU ($7) + 2*MASKFRAME, $8, $9, OldFlags($10));
1672 free ($8);
1673 free ($9);
1678 /* x1, y1, x2, y2, thickness, name and flags */
1679 : T_PAD '(' measure measure measure measure measure STRING INTEGER ')'
1681 char p_number[8];
1683 sprintf(p_number, "%d", pin_num++);
1684 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1685 OU ($7) + 2*MASKFRAME, $8,p_number, OldFlags($9));
1686 free ($8);
1690 flags : INTEGER { $$ = OldFlags($1); }
1691 | STRING { $$ = string_to_flags ($1, yyerror); }
1694 symbols
1695 : symbol
1696 | symbols symbol
1699 /* %start-doc pcbfile Symbol
1701 @syntax
1702 Symbol [Char Delta] (
1703 Symbol (Char Delta) (
1704 @ @ @ @dots{} symbol lines @dots{}
1706 @end syntax
1708 @table @var
1709 @item Char
1710 The character or numerical character value this symbol represents.
1711 Characters must be in single quotes.
1712 @item Delta
1713 Additional space to allow after this character.
1714 @end table
1716 %end-doc */
1718 symbol : symbolhead symboldata ')'
1720 symbolhead : T_SYMBOL '[' symbolid measure ']' '('
1722 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1724 yyerror("fontposition out of range");
1725 YYABORT;
1727 Symbol = &yyFont->Symbol[$3];
1728 if (Symbol->Valid)
1730 yyerror("symbol ID used twice");
1731 YYABORT;
1733 Symbol->Valid = true;
1734 Symbol->Delta = NU ($4);
1736 | T_SYMBOL '(' symbolid measure ')' '('
1738 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1740 yyerror("fontposition out of range");
1741 YYABORT;
1743 Symbol = &yyFont->Symbol[$3];
1744 if (Symbol->Valid)
1746 yyerror("symbol ID used twice");
1747 YYABORT;
1749 Symbol->Valid = true;
1750 Symbol->Delta = OU ($4);
1754 symbolid
1755 : INTEGER
1756 | CHAR_CONST
1759 symboldata
1760 : /* empty */
1761 | symboldata symboldefinition
1762 | symboldata hiressymbol
1765 /* %start-doc pcbfile SymbolLine
1767 @syntax
1768 SymbolLine [X1 Y1 X2 Y2 Thickness]
1769 SymbolLine (X1 Y1 X2 Y2 Thickness)
1770 @end syntax
1772 @table @var
1773 @item X1 Y1 X2 Y2
1774 The endpoints of this line.
1775 @item Thickness
1776 The width of this line.
1777 @end table
1779 %end-doc */
1781 symboldefinition
1782 /* x1, y1, x2, y2, thickness */
1783 : T_SYMBOLLINE '(' measure measure measure measure measure ')'
1785 CreateNewLineInSymbol(Symbol, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1788 hiressymbol
1789 /* x1, y1, x2, y2, thickness */
1790 : T_SYMBOLLINE '[' measure measure measure measure measure ']'
1792 CreateNewLineInSymbol(Symbol, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1796 /* %start-doc pcbfile Netlist
1798 @syntax
1799 Netlist ( ) (
1800 @ @ @ @dots{} nets @dots{}
1802 @end syntax
1804 %end-doc */
1806 pcbnetlist : pcbnetdef
1809 pcbnetdef
1810 /* net(...) net(...) ... */
1811 : T_NETLIST '(' ')' '('
1812 nets ')'
1815 nets
1816 : netdefs
1820 netdefs
1821 : net
1822 | netdefs net
1825 /* %start-doc pcbfile Net
1827 @syntax
1828 Net ("Name" "Style") (
1829 @ @ @ @dots{} connects @dots{}
1831 @end syntax
1833 @table @var
1834 @item Name
1835 The name of this net.
1836 @item Style
1837 The routing style that should be used when autorouting this net.
1838 @end table
1840 %end-doc */
1843 /* name style pin pin ... */
1844 : T_NET '(' STRING STRING ')' '('
1846 Menu = CreateNewNet(&yyPCB->NetlistLib, $3, $4);
1847 free ($3);
1848 free ($4);
1850 connections ')'
1853 connections
1854 : conndefs
1858 conndefs
1859 : conn
1860 | conndefs conn
1863 /* %start-doc pcbfile Connect
1865 @syntax
1866 Connect ("PinPad")
1867 @end syntax
1869 @table @var
1870 @item PinPad
1871 The name of a pin or pad which is included in this net. Pin and Pad
1872 names are named by the refdes and pin name, like @code{"U14-7"} for
1873 pin 7 of U14, or @code{"T4-E"} for pin E of T4.
1874 @end table
1876 %end-doc */
1878 conn
1879 : T_CONN '(' STRING ')'
1881 CreateNewConnection(Menu, $3);
1882 free ($3);
1886 /* %start-doc pcbfile Attribute
1888 @syntax
1889 Attribute ("Name" "Value")
1890 @end syntax
1892 Attributes allow boards and elements to have arbitrary data attached
1893 to them, which is not directly used by PCB itself but may be of use by
1894 other programs or users.
1896 @table @var
1897 @item Name
1898 The name of the attribute
1900 @item Value
1901 The value of the attribute. Values are always stored as strings, even
1902 if the value is interpreted as, for example, a number.
1904 @end table
1906 %end-doc */
1908 attribute
1909 : T_ATTRIBUTE '(' STRING STRING ')'
1911 CreateNewAttribute (attr_list, $3, $4 ? $4 : (char *)"");
1912 free ($3);
1913 free ($4);
1917 opt_string : STRING { $$ = $1; }
1918 | /* empty */ { $$ = 0; }
1921 number
1922 : FLOATING { $$ = $1; }
1923 | INTEGER { $$ = $1; }
1926 measure
1927 /* Default unit (no suffix) is cmil */
1928 : number { do_measure(&$$, $1, MIL_TO_COORD ($1) / 100.0, 0); }
1929 | number T_UMIL { M ($$, $1, MIL_TO_COORD ($1) / 100000.0); }
1930 | number T_CMIL { M ($$, $1, MIL_TO_COORD ($1) / 100.0); }
1931 | number T_MIL { M ($$, $1, MIL_TO_COORD ($1)); }
1932 | number T_IN { M ($$, $1, INCH_TO_COORD ($1)); }
1933 | number T_NM { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1934 | number T_PX { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1935 | number T_UM { M ($$, $1, MM_TO_COORD ($1) / 1000.0); }
1936 | number T_MM { M ($$, $1, MM_TO_COORD ($1)); }
1937 | number T_M { M ($$, $1, MM_TO_COORD ($1) * 1000.0); }
1938 | number T_KM { M ($$, $1, MM_TO_COORD ($1) * 1000000.0); }
1943 /* ---------------------------------------------------------------------------
1944 * error routine called by parser library
1946 int yyerror(const char * s)
1948 Message("ERROR parsing file '%s'\n"
1949 " line: %i\n"
1950 " description: '%s'\n",
1951 yyfilename, yylineno, s);
1952 return(0);
1955 int yywrap()
1957 return 1;
1960 static int
1961 check_file_version (int ver)
1963 if ( ver > PCB_FILE_VERSION ) {
1964 Message ("ERROR: The file you are attempting to load is in a format\n"
1965 "which is too new for this version of pcb. To load this file\n"
1966 "you need a version of pcb which is >= %d. If you are\n"
1967 "using a version built from git source, the source date\n"
1968 "must be >= %d. This copy of pcb can only read files\n"
1969 "up to file version %d.\n", ver, ver, PCB_FILE_VERSION);
1970 return 1;
1973 return 0;
1976 static void
1977 do_measure (PLMeasure *m, Coord i, double d, int u)
1979 m->ival = i;
1980 m->bval = round (d);
1981 m->dval = d;
1982 m->has_units = u;
1985 static int
1986 integer_value (PLMeasure m)
1988 if (m.has_units)
1989 yyerror("units ignored here");
1990 return m.ival;
1993 static Coord
1994 old_units (PLMeasure m)
1996 if (m.has_units)
1997 return m.bval;
1998 return round (MIL_TO_COORD (m.ival));
2001 static Coord
2002 new_units (PLMeasure m)
2004 if (m.has_units)
2005 return m.bval;
2006 return round (MIL_TO_COORD (m.ival) / 100.0);