(no commit message)
[geda-pcb/pcjc2.git] / src / parse_y.y
blobba31cd64492a8599281b06105733ea993867105e
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 + 2];
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 | parsedata
135 | parsefont
136 | error { YYABORT; }
139 /* %start-doc pcbfile 00pcb
140 @nodetype subsection
141 @nodename %s syntax
143 A special note about units: Older versions of @code{pcb} used mils
144 (1/1000 inch) as the base unit; a value of 500 in the file meant
145 half an inch. Newer versions uses a "high resolution" syntax,
146 where the base unit is 1/100 of a mil (0.000010 inch); a value of 500 in
147 the file means 5 mils. As a general rule, the variants of each entry
148 listed below which use square brackets are the high resolution formats
149 and use the 1/100 mil units, and the ones with parentheses are the older
150 variants and use 1 mil units. Note that when multiple variants
151 are listed, the most recent (and most preferred) format is the first
152 listed.
154 Symbolic and numeric flags (SFlags and NFlags) are described in
155 @ref{Object Flags}.
157 %end-doc */
159 parsepcb
161 /* reset flags for 'used layers';
162 * init font and data pointers
164 int i;
166 if (!yyPCB)
168 Message(_("illegal fileformat\n"));
169 YYABORT;
171 for (i = 0; i < MAX_LAYER + 2; i++)
172 LayerFlag[i] = false;
173 yyFont = &yyPCB->Font;
174 yyData = yyPCB->Data;
175 yyData->pcb = yyPCB;
176 yyData->LayerN = 0;
177 /* Parse the default layer group string, just in case the file doesn't have one */
178 if (ParseGroupString (Settings.Groups, &yyPCB->LayerGroups, &yyData->LayerN))
180 Message(_("illegal default layer-group string\n"));
181 YYABORT;
184 pcbfileversion
185 pcbname
186 pcbgrid
187 pcbcursor
188 polyarea
189 pcbthermal
190 pcbdrc
191 pcbflags
192 pcbgroups
193 pcbstyles
194 pcbfont
195 pcbdata
196 pcbnetlist
198 PCBType *pcb_save = PCB;
200 CreateNewPCBPost (yyPCB, 0);
201 /* initialize the polygon clipping now since
202 * we didn't know the layer grouping before.
204 PCB = yyPCB;
205 ALLPOLYGON_LOOP (yyData);
207 InitClip (yyData, layer, polygon);
209 ENDALL_LOOP;
210 PCB = pcb_save;
214 if (yyPCB != NULL)
216 /* This case is when we load a footprint with file->open, or from the command line */
217 yyFont = &yyPCB->Font;
218 yyData = yyPCB->Data;
219 yyData->pcb = yyPCB;
220 yyData->LayerN = 0;
223 element
225 PCBType *pcb_save = PCB;
226 ElementType *e;
227 if (yyPCB != NULL)
229 /* This case is when we load a footprint with file->open, or from the command line */
230 CreateNewPCBPost (yyPCB, 0);
231 ParseGroupString("1,c:2,s", &yyPCB->LayerGroups, &yyData->LayerN);
232 e = yyPCB->Data->Element->data; /* we know there's only one */
233 PCB = yyPCB;
234 MoveElementLowLevel (yyPCB->Data, e, -e->BoundingBox.X1, -e->BoundingBox.Y1);
235 PCB = pcb_save;
236 yyPCB->MaxWidth = e->BoundingBox.X2;
237 yyPCB->MaxHeight = e->BoundingBox.Y2;
238 yyPCB->is_footprint = 1;
243 parsedata
245 /* reset flags for 'used layers';
246 * init font and data pointers
248 int i;
250 if (!yyData || !yyFont)
252 Message(_("illegal fileformat\n"));
253 YYABORT;
255 for (i = 0; i < MAX_LAYER + 2; i++)
256 LayerFlag[i] = false;
257 yyData->LayerN = 0;
259 pcbdata
262 pcbfont
263 : parsefont
267 parsefont
270 /* mark all symbols invalid */
271 int i;
273 if (!yyFont)
275 Message(_("illegal fileformat\n"));
276 YYABORT;
278 yyFont->Valid = false;
279 for (i = 0; i <= MAX_FONTPOSITION; i++)
280 free (yyFont->Symbol[i].Line);
281 bzero(yyFont->Symbol, sizeof(yyFont->Symbol));
283 symbols
285 yyFont->Valid = true;
286 SetFontInfo(yyFont);
290 /* %start-doc pcbfile FileVersion
292 @syntax
293 FileVersion[Version]
294 @end syntax
296 @table @var
297 @item Version
298 File format version. This version number represents the date when the pcb file
299 format was last changed.
300 @end table
302 Any version of pcb build from sources equal to or newer
303 than this number should be able to read the file. If this line is not present
304 in the input file then file format compatibility is not checked.
307 %end-doc */
309 pcbfileversion
311 T_FILEVERSION '[' INTEGER ']'
313 if (check_file_version ($3) != 0)
315 YYABORT;
320 /* %start-doc pcbfile PCB
322 @syntax
323 PCB ["Name" Width Height]
324 PCB ("Name" Width Height]
325 PCB ("Name")
326 @end syntax
328 @table @var
329 @item Name
330 Name of the PCB project
331 @item Width Height
332 Size of the board
333 @end table
335 If you don't specify the size of the board, a very large default is
336 chosen.
338 %end-doc */
340 pcbname
341 : T_PCB '(' STRING ')'
343 yyPCB->Name = $3;
344 yyPCB->MaxWidth = MAX_COORD;
345 yyPCB->MaxHeight = MAX_COORD;
347 | T_PCB '(' STRING measure measure ')'
349 yyPCB->Name = $3;
350 yyPCB->MaxWidth = OU ($4);
351 yyPCB->MaxHeight = OU ($5);
353 | T_PCB '[' STRING measure measure ']'
355 yyPCB->Name = $3;
356 yyPCB->MaxWidth = NU ($4);
357 yyPCB->MaxHeight = NU ($5);
361 /* %start-doc pcbfile Grid
363 @syntax
364 Grid [Step OffsetX OffsetY Visible]
365 Grid (Step OffsetX OffsetY Visible)
366 Grid (Step OffsetX OffsetY)
367 @end syntax
369 @table @var
370 @item Step
371 Distance from one grid point to adjacent points. This value may be a
372 floating point number for the first two variants.
373 @item OffsetX OffsetY
374 The "origin" of the grid. Normally zero.
375 @item Visible
376 If non-zero, the grid will be visible on the screen.
377 @end table
379 %end-doc */
381 pcbgrid
382 : pcbgridold
383 | pcbgridnew
384 | pcbhigrid
386 pcbgridold
387 : T_GRID '(' measure measure measure ')'
389 yyPCB->Grid = OU ($3);
390 yyPCB->GridOffsetX = OU ($4);
391 yyPCB->GridOffsetY = OU ($5);
394 pcbgridnew
395 : T_GRID '(' measure measure measure INTEGER ')'
397 yyPCB->Grid = OU ($3);
398 yyPCB->GridOffsetX = OU ($4);
399 yyPCB->GridOffsetY = OU ($5);
400 if ($6)
401 Settings.DrawGrid = true;
402 else
403 Settings.DrawGrid = false;
407 pcbhigrid
408 : T_GRID '[' measure measure measure INTEGER ']'
410 yyPCB->Grid = NU ($3);
411 yyPCB->GridOffsetX = NU ($4);
412 yyPCB->GridOffsetY = NU ($5);
413 if ($6)
414 Settings.DrawGrid = true;
415 else
416 Settings.DrawGrid = false;
420 /* %start-doc pcbfile Cursor
422 @syntax
423 Cursor [X Y Zoom]
424 Cursor (X Y Zoom)
425 @end syntax
427 @table @var
428 @item X Y
429 Location of the cursor when the board was saved.
430 As of November 2012 the cursor position is not written to file anymore.
431 Older versions of pcb ignore the absence of this line in the pcb file.
432 @item Zoom
433 The current zoom factor. Note that a zoom factor of "0" means 1 mil
434 per screen pixel, N means @math{2^N} mils per screen pixel, etc. The
435 first variant accepts floating point numbers. The special value
436 "1000" means "zoom to fit"
438 This field is ignored by PCB.
439 @end table
441 %end-doc */
443 pcbcursor
444 : T_CURSOR '(' measure measure number ')'
446 yyPCB->CursorX = OU ($3);
447 yyPCB->CursorY = OU ($4);
449 | T_CURSOR '[' measure measure number ']'
451 yyPCB->CursorX = NU ($3);
452 yyPCB->CursorY = NU ($4);
457 /* %start-doc pcbfile PolyArea
459 @syntax
460 PolyArea [Area]
461 @end syntax
463 @table @var
464 @item Area
465 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.
466 @end table
468 %end-doc */
470 polyarea
472 | T_AREA '[' number ']'
474 /* Read in cmil^2 for now; in future this should be a noop. */
475 yyPCB->IsleArea = MIL_TO_COORD (MIL_TO_COORD ($3) / 100.0) / 100.0;
480 /* %start-doc pcbfile Thermal
482 @syntax
483 Thermal [Scale]
484 @end syntax
486 @table @var
487 @item Scale
488 Relative size of thermal fingers. A value of 1.0 makes the finger
489 width twice the clearance gap width (measured across the gap, not
490 diameter). The normal value is 0.5, which results in a finger width
491 the same as the clearance gap width.
492 @end table
494 %end-doc */
497 pcbthermal
499 | T_THERMAL '[' number ']'
501 yyPCB->ThermScale = $3;
505 /* %start-doc pcbfile DRC
507 @syntax
508 DRC [Bloat Shrink Line Silk Drill Ring]
509 DRC [Bloat Shrink Line Silk]
510 DRC [Bloat Shrink Line]
511 @end syntax
513 @table @var
514 @item Bloat
515 Minimum spacing between copper.
516 @item Shrink
517 Minimum copper overlap to guarantee connectivity.
518 @item Line
519 Minimum line thickness.
520 @item Silk
521 Minimum silk thickness.
522 @item Drill
523 Minimum drill size.
524 @item Ring
525 Minimum width of the annular ring around pins and vias.
526 @end table
528 %end-doc */
530 pcbdrc
532 | pcbdrc1
533 | pcbdrc2
534 | pcbdrc3
537 pcbdrc1
538 : T_DRC '[' measure measure measure ']'
540 yyPCB->Bloat = NU ($3);
541 yyPCB->Shrink = NU ($4);
542 yyPCB->minWid = NU ($5);
543 yyPCB->minRing = NU ($5);
547 pcbdrc2
548 : T_DRC '[' measure measure measure measure ']'
550 yyPCB->Bloat = NU ($3);
551 yyPCB->Shrink = NU ($4);
552 yyPCB->minWid = NU ($5);
553 yyPCB->minSlk = NU ($6);
554 yyPCB->minRing = NU ($5);
558 pcbdrc3
559 : T_DRC '[' measure measure measure measure measure measure ']'
561 yyPCB->Bloat = NU ($3);
562 yyPCB->Shrink = NU ($4);
563 yyPCB->minWid = NU ($5);
564 yyPCB->minSlk = NU ($6);
565 yyPCB->minDrill = NU ($7);
566 yyPCB->minRing = NU ($8);
570 /* %start-doc pcbfile Flags
572 @syntax
573 Flags(Number)
574 @end syntax
576 @table @var
577 @item Number
578 A number, whose value is normally given in hex, individual bits of which
579 represent pcb-wide flags as defined in @ref{PCBFlags}.
581 @end table
583 %end-doc */
585 pcbflags
586 : T_FLAGS '(' INTEGER ')'
588 yyPCB->Flags = MakeFlags ($3 & PCB_FLAGS);
590 | T_FLAGS '(' STRING ')'
592 yyPCB->Flags = string_to_pcbflags ($3, yyerror);
597 /* %start-doc pcbfile Groups
599 @syntax
600 Groups("String")
601 @end syntax
603 @table @var
604 @item String
606 Encodes the layer grouping information. Each group is separated by a
607 colon, each member of each group is separated by a comma. Group
608 members are either numbers from @code{1}..@var{N} for each layer, and
609 the letters @code{c} or @code{s} representing the component side and
610 solder side of the board. Including @code{c} or @code{s} marks that
611 group as being the top or bottom side of the board.
613 @example
614 Groups("1,2,c:3:4:5,6,s:7,8")
615 @end example
617 @end table
619 %end-doc */
621 pcbgroups
622 : T_GROUPS '(' STRING ')'
624 if (ParseGroupString ($3, &yyPCB->LayerGroups, &yyData->LayerN))
626 Message(_("illegal layer-group string\n"));
627 YYABORT;
633 /* %start-doc pcbfile Styles
635 @syntax
636 Styles("String")
637 @end syntax
639 @table @var
640 @item String
642 Encodes the four routing styles @code{pcb} knows about. The four styles
643 are separated by colons. Each style consists of five parameters as follows:
645 @table @var
646 @item Name
647 The name of the style.
648 @item Thickness
649 Width of lines and arcs.
650 @item Diameter
651 Copper diameter of pins and vias.
652 @item Drill
653 Drill diameter of pins and vias.
654 @item Keepaway
655 Minimum spacing to other nets. If omitted, 10 mils is the default.
657 @end table
659 @end table
661 @example
662 Styles("Signal,10,40,20:Power,25,60,35:Fat,40,60,35:Skinny,8,36,20")
663 Styles["Logic,1000,3600,2000,1000:Power,2500,6000,3500,1000:
664 @ @ @ Line,4000,6000,3500,1000:Breakout,600,2402,1181,600"]
665 @end example
667 @noindent
668 Note that strings in actual files cannot span lines; the above example
669 is split across lines only to make it readable.
671 %end-doc */
673 pcbstyles
674 : T_STYLES '(' STRING ')'
676 if (ParseRouteString($3, &yyPCB->RouteStyle[0], "mil"))
678 Message(_("illegal route-style string\n"));
679 YYABORT;
682 | T_STYLES '[' STRING ']'
684 if (ParseRouteString($3, &yyPCB->RouteStyle[0], "cmil"))
686 Message(_("illegal route-style string\n"));
687 YYABORT;
693 pcbdata
694 : pcbdefinitions
698 pcbdefinitions
699 : pcbdefinition
700 | pcbdefinitions pcbdefinition
703 pcbdefinition
704 : via
705 | { attr_list = & yyPCB->Attributes; } attribute
706 | rats
707 | layer
708 | element
709 | error { YYABORT; }
713 : via_hi_format
714 | via_2.0_format
715 | via_1.7_format
716 | via_newformat
717 | via_oldformat
720 /* %start-doc pcbfile Via
722 @syntax
723 Via [X Y Thickness Clearance Mask Drill "Name" SFlags]
724 Via (X Y Thickness Clearance Mask Drill "Name" NFlags)
725 Via (X Y Thickness Clearance Drill "Name" NFlags)
726 Via (X Y Thickness Drill "Name" NFlags)
727 Via (X Y Thickness "Name" NFlags)
728 @end syntax
730 @table @var
731 @item X Y
732 coordinates of center
733 @item Thickness
734 outer diameter of copper annulus
735 @item Clearance
736 add to thickness to get clearance diameter
737 @item Mask
738 diameter of solder mask opening
739 @item Drill
740 diameter of drill
741 @item Name
742 string, name of via (vias have names?)
743 @item SFlags
744 symbolic or numerical flags
745 @item NFlags
746 numerical flags only
747 @end table
749 %end-doc */
751 via_hi_format
752 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
753 : T_VIA '[' measure measure measure measure measure measure STRING flags ']'
755 CreateNewVia(yyData, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7),
756 NU ($8), $9, $10);
757 free ($9);
761 via_2.0_format
762 /* x, y, thickness, clearance, mask, drilling-hole, name, flags */
763 : T_VIA '(' measure measure measure measure measure measure STRING INTEGER ')'
765 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7), OU ($8), $9,
766 OldFlags($10));
767 free ($9);
772 via_1.7_format
773 /* x, y, thickness, clearance, drilling-hole, name, flags */
774 : T_VIA '(' measure measure measure measure measure STRING INTEGER ')'
776 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), OU ($6),
777 OU ($5) + OU($6), OU ($7), $8, OldFlags($9));
778 free ($8);
782 via_newformat
783 /* x, y, thickness, drilling-hole, name, flags */
784 : T_VIA '(' measure measure measure measure STRING INTEGER ')'
786 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
787 OU($5) + 2*MASKFRAME, OU ($6), $7, OldFlags($8));
788 free ($7);
792 via_oldformat
793 /* old format: x, y, thickness, name, flags */
794 : T_VIA '(' measure measure measure STRING INTEGER ')'
796 Coord hole = (OU($5) * DEFAULT_DRILLINGHOLE);
798 /* make sure that there's enough copper left */
799 if (OU($5) - hole < MIN_PINORVIACOPPER &&
800 OU($5) > MIN_PINORVIACOPPER)
801 hole = OU($5) - MIN_PINORVIACOPPER;
803 CreateNewVia(yyData, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
804 OU($5) + 2*MASKFRAME, hole, $6, OldFlags($7));
805 free ($6);
809 /* %start-doc pcbfile Rat
811 @syntax
812 Rat [X1 Y1 Group1 X2 Y2 Group2 SFlags]
813 Rat (X1 Y1 Group1 X2 Y2 Group2 NFlags)
814 @end syntax
816 @table @var
817 @item X1 Y1 X2 Y2
818 The endpoints of the rat line.
819 @item Group1 Group2
820 The layer group each end is connected on.
821 @item SFlags
822 Symbolic or numeric flags.
823 @item NFlags
824 Numeric flags.
825 @end table
827 %end-doc */
829 rats
830 : T_RAT '[' measure measure INTEGER measure measure INTEGER flags ']'
832 CreateNewRat(yyData, NU ($3), NU ($4), NU ($6), NU ($7), $5, $8,
833 Settings.RatThickness, $9);
835 | T_RAT '(' measure measure INTEGER measure measure INTEGER INTEGER ')'
837 CreateNewRat(yyData, OU ($3), OU ($4), OU ($6), OU ($7), $5, $8,
838 Settings.RatThickness, OldFlags($9));
842 /* %start-doc pcbfile Layer
844 @syntax
845 Layer (LayerNum "Name") (
846 @ @ @ @dots{} contents @dots{}
848 @end syntax
850 @table @var
851 @item LayerNum
852 The layer number. Layers are numbered sequentially, starting with 1.
853 The last two layers (9 and 10 by default) are solder-side silk and
854 component-side silk, in that order.
855 @item Name
856 The layer name.
857 @item contents
858 The contents of the layer, which may include attributes, lines, arcs, rectangles,
859 text, and polygons.
860 @end table
862 %end-doc */
864 layer
865 /* name */
866 : T_LAYER '(' INTEGER STRING opt_string ')' '('
868 if ($3 <= 0 || $3 > MAX_LAYER + 2)
870 yyerror("Layernumber out of range");
871 YYABORT;
873 if (LayerFlag[$3-1])
875 yyerror("Layernumber used twice");
876 YYABORT;
878 Layer = &yyData->Layer[$3-1];
880 /* memory for name is already allocated */
881 Layer->Name = $4;
882 if (Layer->Name == NULL)
883 Layer->Name = strdup("");
884 LayerFlag[$3-1] = true;
886 layerdata ')'
889 layerdata
890 : layerdefinitions
894 layerdefinitions
895 : layerdefinition
896 | layerdefinitions layerdefinition
899 layerdefinition
900 : line_hi_format
901 | line_1.7_format
902 | line_oldformat
903 | arc_hi_format
904 | arc_1.7_format
905 | arc_oldformat
906 /* x1, y1, x2, y2, flags */
907 | T_RECTANGLE '(' measure measure measure measure INTEGER ')'
909 CreateNewPolygonFromRectangle(Layer,
910 OU ($3), OU ($4), OU ($3) + OU ($5), OU ($4) + OU ($6), OldFlags($7));
912 | text_hi_format
913 | text_newformat
914 | text_oldformat
915 | { attr_list = & Layer->Attributes; } attribute
916 | polygon_format
918 /* %start-doc pcbfile Line
920 @syntax
921 Line [X1 Y1 X2 Y2 Thickness Clearance SFlags]
922 Line (X1 Y1 X2 Y2 Thickness Clearance NFlags)
923 Line (X1 Y1 X2 Y2 Thickness NFlags)
924 @end syntax
926 @table @var
927 @item X1 Y1 X2 Y2
928 The end points of the line
929 @item Thickness
930 The width of the line
931 @item Clearance
932 The amount of space cleared around the line when the line passes
933 through a polygon. The clearance is added to the thickness to get the
934 thickness of the clear; thus the space between the line and the
935 polygon is @math{Clearance/2} wide.
936 @item SFlags
937 Symbolic or numeric flags
938 @item NFlags
939 Numeric flags.
940 @end table
942 %end-doc */
944 line_hi_format
945 /* x1, y1, x2, y2, thickness, clearance, flags */
946 : T_LINE '[' measure measure measure measure measure measure flags ']'
948 CreateNewLineOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6),
949 NU ($7), NU ($8), $9);
953 line_1.7_format
954 /* x1, y1, x2, y2, thickness, clearance, flags */
955 : T_LINE '(' measure measure measure measure measure measure INTEGER ')'
957 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6),
958 OU ($7), OU ($8), OldFlags($9));
962 line_oldformat
963 /* x1, y1, x2, y2, thickness, flags */
964 : T_LINE '(' measure measure measure measure measure measure ')'
966 /* eliminate old-style rat-lines */
967 if ((IV ($8) & RATFLAG) == 0)
968 CreateNewLineOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7),
969 200*GROUNDPLANEFRAME, OldFlags(IV ($8)));
973 /* %start-doc pcbfile Arc
975 @syntax
976 Arc [X Y Width Height Thickness Clearance StartAngle DeltaAngle SFlags]
977 Arc (X Y Width Height Thickness Clearance StartAngle DeltaAngle NFlags)
978 Arc (X Y Width Height Thickness StartAngle DeltaAngle NFlags)
979 @end syntax
981 @table @var
982 @item X Y
983 Coordinates of the center of the arc.
984 @item Width Height
985 The width and height, from the center to the edge. The bounds of the
986 circle of which this arc is a segment, is thus @math{2*Width} by
987 @math{2*Height}.
988 @item Thickness
989 The width of the copper trace which forms the arc.
990 @item Clearance
991 The amount of space cleared around the arc when the line passes
992 through a polygon. The clearance is added to the thickness to get the
993 thickness of the clear; thus the space between the arc and the polygon
994 is @math{Clearance/2} wide.
995 @item StartAngle
996 The angle of one end of the arc, in degrees. In PCB, an angle of zero
997 points left (negative X direction), and 90 degrees points down
998 (positive Y direction).
999 @item DeltaAngle
1000 The sweep of the arc. This may be negative. Positive angles sweep
1001 counterclockwise.
1002 @item SFlags
1003 Symbolic or numeric flags.
1004 @item NFlags
1005 Numeric flags.
1006 @end table
1008 %end-doc */
1010 arc_hi_format
1011 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
1012 : T_ARC '[' measure measure measure measure measure measure number number flags ']'
1014 CreateNewArcOnLayer(Layer, NU ($3), NU ($4), NU ($5), NU ($6), $9, $10,
1015 NU ($7), NU ($8), $11);
1019 arc_1.7_format
1020 /* x, y, width, height, thickness, clearance, startangle, delta, flags */
1021 : T_ARC '(' measure measure measure measure measure measure number number INTEGER ')'
1023 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($6), $9, $10,
1024 OU ($7), OU ($8), OldFlags($11));
1028 arc_oldformat
1029 /* x, y, width, height, thickness, startangle, delta, flags */
1030 : T_ARC '(' measure measure measure measure measure measure number INTEGER ')'
1032 CreateNewArcOnLayer(Layer, OU ($3), OU ($4), OU ($5), OU ($5), IV ($8), $9,
1033 OU ($7), 200*GROUNDPLANEFRAME, OldFlags($10));
1037 /* %start-doc pcbfile Text
1039 @syntax
1040 Text [X Y Direction Scale "String" SFlags]
1041 Text (X Y Direction Scale "String" NFlags)
1042 Text (X Y Direction "String" NFlags)
1043 @end syntax
1045 @table @var
1046 @item X Y
1047 The location of the upper left corner of the text.
1048 @item Direction
1049 0 means text is drawn left to right, 1 means up, 2 means right to left
1050 (i.e. upside down), and 3 means down.
1051 @item Scale
1052 Size of the text, as a percentage of the ``default'' size of of the
1053 font (the default font is about 40 mils high). Default is 100 (40
1054 mils).
1055 @item String
1056 The string to draw.
1057 @item SFlags
1058 Symbolic or numeric flags.
1059 @item NFlags
1060 Numeric flags.
1061 @end table
1063 %end-doc */
1065 text_oldformat
1066 /* x, y, direction, text, flags */
1067 : T_TEXT '(' measure measure number STRING INTEGER ')'
1069 /* use a default scale of 100% */
1070 CreateNewText(Layer,yyFont,OU ($3), OU ($4), $5, 100, $6, OldFlags($7));
1071 free ($6);
1075 text_newformat
1076 /* x, y, direction, scale, text, flags */
1077 : T_TEXT '(' measure measure number number STRING INTEGER ')'
1079 if ($8 & ONSILKFLAG)
1081 LayerType *lay = &yyData->Layer[yyData->LayerN +
1082 (($8 & ONSOLDERFLAG) ? BOTTOM_SILK_LAYER : TOP_SILK_LAYER)];
1084 CreateNewText(lay ,yyFont, OU ($3), OU ($4), $5, $6, $7,
1085 OldFlags($8));
1087 else
1088 CreateNewText(Layer, yyFont, OU ($3), OU ($4), $5, $6, $7,
1089 OldFlags($8));
1090 free ($7);
1093 text_hi_format
1094 /* x, y, direction, scale, text, flags */
1095 : T_TEXT '[' measure measure number number STRING flags ']'
1097 /* FIXME: shouldn't know about .f */
1098 /* I don't think this matters because anything with hi_format
1099 * will have the silk on its own layer in the file rather
1100 * than using the ONSILKFLAG and having it in a copper layer.
1101 * Thus there is no need for anything besides the 'else'
1102 * part of this code.
1104 if ($8.f & ONSILKFLAG)
1106 LayerType *lay = &yyData->Layer[yyData->LayerN +
1107 (($8.f & ONSOLDERFLAG) ? BOTTOM_SILK_LAYER : TOP_SILK_LAYER)];
1109 CreateNewText(lay, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1111 else
1112 CreateNewText(Layer, yyFont, NU ($3), NU ($4), $5, $6, $7, $8);
1113 free ($7);
1117 /* %start-doc pcbfile Polygon
1119 @syntax
1120 Polygon (SFlags) (
1121 @ @ @ @dots{} (X Y) @dots{}
1122 @ @ @ @dots{} [X Y] @dots{}
1123 @ @ @ Hole (
1124 @ @ @ @ @ @ @dots{} (X Y) @dots{}
1125 @ @ @ @ @ @ @dots{} [X Y] @dots{}
1126 @ @ @ )
1127 @ @ @ @dots{}
1129 @end syntax
1131 @table @var
1132 @item SFlags
1133 Symbolic or numeric flags.
1134 @item X Y
1135 Coordinates of each vertex. You must list at least three coordinates.
1136 @item Hole (...)
1137 Defines a hole within the polygon's outer contour. There may be zero or more such sections.
1138 @end table
1140 %end-doc */
1142 polygon_format
1143 : /* flags are passed in */
1144 T_POLYGON '(' flags ')' '('
1146 Polygon = CreateNewPolygon(Layer, $3);
1148 polygonpoints
1149 polygonholes ')'
1151 Cardinal contour, contour_start, contour_end;
1152 bool bad_contour_found = false;
1153 /* ignore junk */
1154 for (contour = 0; contour <= Polygon->HoleIndexN; contour++)
1156 contour_start = (contour == 0) ?
1157 0 : Polygon->HoleIndex[contour - 1];
1158 contour_end = (contour == Polygon->HoleIndexN) ?
1159 Polygon->PointN :
1160 Polygon->HoleIndex[contour];
1161 if (contour_end - contour_start < 3)
1162 bad_contour_found = true;
1165 if (bad_contour_found)
1167 Message(_("WARNING parsing file '%s'\n"
1168 " line: %i\n"
1169 " description: 'ignored polygon "
1170 "(< 3 points in a contour)'\n"),
1171 yyfilename, yylineno);
1172 DestroyObject(yyData, POLYGON_TYPE, Layer, Polygon, Polygon);
1174 else
1176 SetPolygonBoundingBox (Polygon);
1177 if (!Layer->polygon_tree)
1178 Layer->polygon_tree = r_create_tree (NULL, 0, 0);
1179 r_insert_entry (Layer->polygon_tree, (BoxType *) Polygon, 0);
1184 polygonholes
1185 : /* empty */
1186 | polygonholes polygonhole
1189 polygonhole
1190 : T_POLYGON_HOLE '('
1192 CreateNewHoleInPolygon (Polygon);
1194 polygonpoints ')'
1197 polygonpoints
1198 : /* empty */
1199 | polygonpoint polygonpoints
1202 polygonpoint
1203 /* xcoord ycoord */
1204 : '(' measure measure ')'
1206 CreateNewPointInPolygon(Polygon, OU ($2), OU ($3));
1208 | '[' measure measure ']'
1210 CreateNewPointInPolygon(Polygon, NU ($2), NU ($3));
1214 /* %start-doc pcbfile Element
1216 @syntax
1217 Element [SFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TSFlags] (
1218 Element (NFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TNFlags) (
1219 Element (NFlags "Desc" "Name" "Value" TX TY TDir TScale TNFlags) (
1220 Element (NFlags "Desc" "Name" TX TY TDir TScale TNFlags) (
1221 Element ("Desc" "Name" TX TY TDir TScale TNFlags) (
1222 @ @ @ @dots{} contents @dots{}
1224 @end syntax
1226 @table @var
1227 @item SFlags
1228 Symbolic or numeric flags, for the element as a whole.
1229 @item NFlags
1230 Numeric flags, for the element as a whole.
1231 @item Desc
1232 The description of the element. This is one of the three strings
1233 which can be displayed on the screen.
1234 @item Name
1235 The name of the element, usually the reference designator.
1236 @item Value
1237 The value of the element.
1238 @item MX MY
1239 The location of the element's mark. This is the reference point
1240 for placing the element and its pins and pads.
1241 @item TX TY
1242 The upper left corner of the text (one of the three strings).
1243 @item TDir
1244 The relative direction of the text. 0 means left to right for
1245 an unrotated element, 1 means up, 2 left, 3 down.
1246 @item TScale
1247 Size of the text, as a percentage of the ``default'' size of of the
1248 font (the default font is about 40 mils high). Default is 100 (40
1249 mils).
1250 @item TSFlags
1251 Symbolic or numeric flags, for the text.
1252 @item TNFlags
1253 Numeric flags, for the text.
1254 @end table
1256 Elements may contain pins, pads, element lines, element arcs,
1257 attributes, and (for older elements) an optional mark. Note that
1258 element definitions that have the mark coordinates in the element
1259 line, only support pins and pads which use relative coordinates. The
1260 pin and pad coordinates are relative to the mark. Element definitions
1261 which do not include the mark coordinates in the element line, may
1262 have a Mark definition in their contents, and only use pin and pad
1263 definitions which use absolute coordinates.
1265 %end-doc */
1267 element
1268 : element_oldformat
1269 | element_1.3.4_format
1270 | element_newformat
1271 | element_1.7_format
1272 | element_hi_format
1275 element_oldformat
1276 /* element_flags, description, pcb-name,
1277 * text_x, text_y, text_direction, text_scale, text_flags
1279 : T_ELEMENT '(' STRING STRING measure measure INTEGER ')' '('
1281 yyElement = CreateNewElement(yyData, yyFont, NoFlags(),
1282 $3, $4, NULL, OU ($5), OU ($6), $7, 100, NoFlags(), false);
1283 free ($3);
1284 free ($4);
1285 pin_num = 1;
1287 elementdefinitions ')'
1289 SetElementBoundingBox(yyData, yyElement, yyFont);
1293 element_1.3.4_format
1294 /* element_flags, description, pcb-name,
1295 * text_x, text_y, text_direction, text_scale, text_flags
1297 : T_ELEMENT '(' INTEGER STRING STRING measure measure measure measure INTEGER ')' '('
1299 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1300 $4, $5, NULL, OU ($6), OU ($7), IV ($8), IV ($9), OldFlags($10), false);
1301 free ($4);
1302 free ($5);
1303 pin_num = 1;
1305 elementdefinitions ')'
1307 SetElementBoundingBox(yyData, yyElement, yyFont);
1311 element_newformat
1312 /* element_flags, description, pcb-name, value,
1313 * text_x, text_y, text_direction, text_scale, text_flags
1315 : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure measure measure INTEGER ')' '('
1317 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1318 $4, $5, $6, OU ($7), OU ($8), IV ($9), IV ($10), OldFlags($11), false);
1319 free ($4);
1320 free ($5);
1321 free ($6);
1322 pin_num = 1;
1324 elementdefinitions ')'
1326 SetElementBoundingBox(yyData, yyElement, yyFont);
1330 element_1.7_format
1331 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1332 * text_x, text_y, text_direction, text_scale, text_flags
1334 : T_ELEMENT '(' INTEGER STRING STRING STRING measure measure
1335 measure measure number number INTEGER ')' '('
1337 yyElement = CreateNewElement(yyData, yyFont, OldFlags($3),
1338 $4, $5, $6, OU ($7) + OU ($9), OU ($8) + OU ($10),
1339 $11, $12, OldFlags($13), false);
1340 yyElement->MarkX = OU ($7);
1341 yyElement->MarkY = OU ($8);
1342 free ($4);
1343 free ($5);
1344 free ($6);
1346 relementdefs ')'
1348 SetElementBoundingBox(yyData, yyElement, yyFont);
1352 element_hi_format
1353 /* element_flags, description, pcb-name, value, mark_x, mark_y,
1354 * text_x, text_y, text_direction, text_scale, text_flags
1356 : T_ELEMENT '[' flags STRING STRING STRING measure measure
1357 measure measure number number flags ']' '('
1359 yyElement = CreateNewElement(yyData, yyFont, $3,
1360 $4, $5, $6, NU ($7) + NU ($9), NU ($8) + NU ($10),
1361 $11, $12, $13, false);
1362 yyElement->MarkX = NU ($7);
1363 yyElement->MarkY = NU ($8);
1364 free ($4);
1365 free ($5);
1366 free ($6);
1368 relementdefs ')'
1370 SetElementBoundingBox(yyData, yyElement, yyFont);
1374 /* %start-doc pcbfile ElementLine
1376 @syntax
1377 ElementLine [X1 Y1 X2 Y2 Thickness]
1378 ElementLine (X1 Y1 X2 Y2 Thickness)
1379 @end syntax
1381 @table @var
1382 @item X1 Y1 X2 Y2
1383 Coordinates of the endpoints of the line. These are relative to the
1384 Element's mark point for new element formats, or absolute for older
1385 formats.
1386 @item Thickness
1387 The width of the silk for this line.
1388 @end table
1390 %end-doc */
1392 /* %start-doc pcbfile ElementArc
1394 @syntax
1395 ElementArc [X Y Width Height StartAngle DeltaAngle Thickness]
1396 ElementArc (X Y Width Height StartAngle DeltaAngle Thickness)
1397 @end syntax
1399 @table @var
1400 @item X Y
1401 Coordinates of the center of the arc. These are relative to the
1402 Element's mark point for new element formats, or absolute for older
1403 formats.
1404 @item Width Height
1405 The width and height, from the center to the edge. The bounds of the
1406 circle of which this arc is a segment, is thus @math{2*Width} by
1407 @math{2*Height}.
1408 @item StartAngle
1409 The angle of one end of the arc, in degrees. In PCB, an angle of zero
1410 points left (negative X direction), and 90 degrees points down
1411 (positive Y direction).
1412 @item DeltaAngle
1413 The sweep of the arc. This may be negative. Positive angles sweep
1414 counterclockwise.
1415 @item Thickness
1416 The width of the silk line which forms the arc.
1417 @end table
1419 %end-doc */
1421 /* %start-doc pcbfile Mark
1423 @syntax
1424 Mark [X Y]
1425 Mark (X Y)
1426 @end syntax
1428 @table @var
1429 @item X Y
1430 Coordinates of the Mark, for older element formats that don't have
1431 the mark as part of the Element line.
1432 @end table
1434 %end-doc */
1436 elementdefinitions
1437 : elementdefinition
1438 | elementdefinitions elementdefinition
1441 elementdefinition
1442 : pin_1.6.3_format
1443 | pin_newformat
1444 | pin_oldformat
1445 | pad_newformat
1446 | pad
1447 /* x1, y1, x2, y2, thickness */
1448 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1450 CreateNewLineInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1452 /* x1, y1, x2, y2, thickness */
1453 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1455 CreateNewLineInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1457 /* x, y, width, height, startangle, anglediff, thickness */
1458 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1460 CreateNewArcInElement(yyElement, NU ($3), NU ($4), NU ($5), NU ($6), $7, $8, NU ($9));
1462 /* x, y, width, height, startangle, anglediff, thickness */
1463 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1465 CreateNewArcInElement(yyElement, OU ($3), OU ($4), OU ($5), OU ($6), $7, $8, OU ($9));
1467 /* x, y position */
1468 | T_MARK '[' measure measure ']'
1470 yyElement->MarkX = NU ($3);
1471 yyElement->MarkY = NU ($4);
1473 | T_MARK '(' measure measure ')'
1475 yyElement->MarkX = OU ($3);
1476 yyElement->MarkY = OU ($4);
1478 | { attr_list = & yyElement->Attributes; } attribute
1481 relementdefs
1482 : relementdef
1483 | relementdefs relementdef
1486 relementdef
1487 : pin_1.7_format
1488 | pin_hi_format
1489 | pad_1.7_format
1490 | pad_hi_format
1491 /* x1, y1, x2, y2, thickness */
1492 | T_ELEMENTLINE '[' measure measure measure measure measure ']'
1494 CreateNewLineInElement(yyElement, NU ($3) + yyElement->MarkX,
1495 NU ($4) + yyElement->MarkY, NU ($5) + yyElement->MarkX,
1496 NU ($6) + yyElement->MarkY, NU ($7));
1498 | T_ELEMENTLINE '(' measure measure measure measure measure ')'
1500 CreateNewLineInElement(yyElement, OU ($3) + yyElement->MarkX,
1501 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1502 OU ($6) + yyElement->MarkY, OU ($7));
1504 /* x, y, width, height, startangle, anglediff, thickness */
1505 | T_ELEMENTARC '[' measure measure measure measure number number measure ']'
1507 CreateNewArcInElement(yyElement, NU ($3) + yyElement->MarkX,
1508 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), $7, $8, NU ($9));
1510 | T_ELEMENTARC '(' measure measure measure measure number number measure ')'
1512 CreateNewArcInElement(yyElement, OU ($3) + yyElement->MarkX,
1513 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), $7, $8, OU ($9));
1515 | { attr_list = & yyElement->Attributes; } attribute
1518 /* %start-doc pcbfile Pin
1520 @syntax
1521 Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags]
1522 Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags)
1523 Pin (aX aY Thickness Drill "Name" "Number" NFlags)
1524 Pin (aX aY Thickness Drill "Name" NFlags)
1525 Pin (aX aY Thickness "Name" NFlags)
1526 @end syntax
1528 @table @var
1529 @item rX rY
1530 coordinates of center, relative to the element's mark
1531 @item aX aY
1532 absolute coordinates of center.
1533 @item Thickness
1534 outer diameter of copper annulus
1535 @item Clearance
1536 add to thickness to get clearance diameter
1537 @item Mask
1538 diameter of solder mask opening
1539 @item Drill
1540 diameter of drill
1541 @item Name
1542 name of pin
1543 @item Number
1544 number of pin
1545 @item SFlags
1546 symbolic or numerical flags
1547 @item NFlags
1548 numerical flags only
1549 @end table
1551 %end-doc */
1553 pin_hi_format
1554 /* x, y, thickness, clearance, mask, drilling hole, name,
1555 number, flags */
1556 : T_PIN '[' measure measure measure measure measure measure STRING STRING flags ']'
1558 CreateNewPin(yyElement, NU ($3) + yyElement->MarkX,
1559 NU ($4) + yyElement->MarkY, NU ($5), NU ($6), NU ($7), NU ($8), $9,
1560 $10, $11);
1561 free ($9);
1562 free ($10);
1565 pin_1.7_format
1566 /* x, y, thickness, clearance, mask, drilling hole, name,
1567 number, flags */
1568 : T_PIN '(' measure measure measure measure measure measure STRING STRING INTEGER ')'
1570 CreateNewPin(yyElement, OU ($3) + yyElement->MarkX,
1571 OU ($4) + yyElement->MarkY, OU ($5), OU ($6), OU ($7), OU ($8), $9,
1572 $10, OldFlags($11));
1573 free ($9);
1574 free ($10);
1578 pin_1.6.3_format
1579 /* x, y, thickness, drilling hole, name, number, flags */
1580 : T_PIN '(' measure measure measure measure STRING STRING INTEGER ')'
1582 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1583 OU ($5) + 2*MASKFRAME, OU ($6), $7, $8, OldFlags($9));
1584 free ($7);
1585 free ($8);
1589 pin_newformat
1590 /* x, y, thickness, drilling hole, name, flags */
1591 : T_PIN '(' measure measure measure measure STRING INTEGER ')'
1593 char p_number[8];
1595 sprintf(p_number, "%d", pin_num++);
1596 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1597 OU ($5) + 2*MASKFRAME, OU ($6), $7, p_number, OldFlags($8));
1599 free ($7);
1603 pin_oldformat
1604 /* old format: x, y, thickness, name, flags
1605 * drilling hole is 40% of the diameter
1607 : T_PIN '(' measure measure measure STRING INTEGER ')'
1609 Coord hole = OU ($5) * DEFAULT_DRILLINGHOLE;
1610 char p_number[8];
1612 /* make sure that there's enough copper left */
1613 if (OU ($5) - hole < MIN_PINORVIACOPPER &&
1614 OU ($5) > MIN_PINORVIACOPPER)
1615 hole = OU ($5) - MIN_PINORVIACOPPER;
1617 sprintf(p_number, "%d", pin_num++);
1618 CreateNewPin(yyElement, OU ($3), OU ($4), OU ($5), 2*GROUNDPLANEFRAME,
1619 OU ($5) + 2*MASKFRAME, hole, $6, p_number, OldFlags($7));
1620 free ($6);
1624 /* %start-doc pcbfile Pad
1626 @syntax
1627 Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags]
1628 Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags)
1629 Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags)
1630 Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags)
1631 @end syntax
1633 @table @var
1634 @item rX1 rY1 rX2 rY2
1635 Coordinates of the endpoints of the pad, relative to the element's
1636 mark. Note that the copper extends beyond these coordinates by half
1637 the thickness. To make a square or round pad, specify the same
1638 coordinate twice.
1639 @item aX1 aY1 aX2 aY2
1640 Same, but absolute coordinates of the endpoints of the pad.
1641 @item Thickness
1642 width of the pad.
1643 @item Clearance
1644 add to thickness to get clearance width.
1645 @item Mask
1646 width of solder mask opening.
1647 @item Name
1648 name of pin
1649 @item Number
1650 number of pin
1651 @item SFlags
1652 symbolic or numerical flags
1653 @item NFlags
1654 numerical flags only
1655 @end table
1657 %end-doc */
1659 pad_hi_format
1660 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1661 : T_PAD '[' measure measure measure measure measure measure measure STRING STRING flags ']'
1663 CreateNewPad(yyElement, NU ($3) + yyElement->MarkX,
1664 NU ($4) + yyElement->MarkY,
1665 NU ($5) + yyElement->MarkX,
1666 NU ($6) + yyElement->MarkY, NU ($7), NU ($8), NU ($9),
1667 $10, $11, $12);
1668 free ($10);
1669 free ($11);
1673 pad_1.7_format
1674 /* x1, y1, x2, y2, thickness, clearance, mask, name , pad number, flags */
1675 : T_PAD '(' measure measure measure measure measure measure measure STRING STRING INTEGER ')'
1677 CreateNewPad(yyElement,OU ($3) + yyElement->MarkX,
1678 OU ($4) + yyElement->MarkY, OU ($5) + yyElement->MarkX,
1679 OU ($6) + yyElement->MarkY, OU ($7), OU ($8), OU ($9),
1680 $10, $11, OldFlags($12));
1681 free ($10);
1682 free ($11);
1686 pad_newformat
1687 /* x1, y1, x2, y2, thickness, name , pad number, flags */
1688 : T_PAD '(' measure measure measure measure measure STRING STRING INTEGER ')'
1690 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1691 OU ($7) + 2*MASKFRAME, $8, $9, OldFlags($10));
1692 free ($8);
1693 free ($9);
1698 /* x1, y1, x2, y2, thickness, name and flags */
1699 : T_PAD '(' measure measure measure measure measure STRING INTEGER ')'
1701 char p_number[8];
1703 sprintf(p_number, "%d", pin_num++);
1704 CreateNewPad(yyElement,OU ($3),OU ($4),OU ($5),OU ($6),OU ($7), 2*GROUNDPLANEFRAME,
1705 OU ($7) + 2*MASKFRAME, $8,p_number, OldFlags($9));
1706 free ($8);
1710 flags : INTEGER { $$ = OldFlags($1); }
1711 | STRING { $$ = string_to_flags ($1, yyerror); }
1714 symbols
1715 : symbol
1716 | symbols symbol
1719 /* %start-doc pcbfile Symbol
1721 @syntax
1722 Symbol [Char Delta] (
1723 Symbol (Char Delta) (
1724 @ @ @ @dots{} symbol lines @dots{}
1726 @end syntax
1728 @table @var
1729 @item Char
1730 The character or numerical character value this symbol represents.
1731 Characters must be in single quotes.
1732 @item Delta
1733 Additional space to allow after this character.
1734 @end table
1736 %end-doc */
1738 symbol : symbolhead symboldata ')'
1740 symbolhead : T_SYMBOL '[' symbolid measure ']' '('
1742 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1744 yyerror("fontposition out of range");
1745 YYABORT;
1747 Symbol = &yyFont->Symbol[$3];
1748 if (Symbol->Valid)
1750 yyerror("symbol ID used twice");
1751 YYABORT;
1753 Symbol->Valid = true;
1754 Symbol->Delta = NU ($4);
1756 | T_SYMBOL '(' symbolid measure ')' '('
1758 if ($3 <= 0 || $3 > MAX_FONTPOSITION)
1760 yyerror("fontposition out of range");
1761 YYABORT;
1763 Symbol = &yyFont->Symbol[$3];
1764 if (Symbol->Valid)
1766 yyerror("symbol ID used twice");
1767 YYABORT;
1769 Symbol->Valid = true;
1770 Symbol->Delta = OU ($4);
1774 symbolid
1775 : INTEGER
1776 | CHAR_CONST
1779 symboldata
1780 : /* empty */
1781 | symboldata symboldefinition
1782 | symboldata hiressymbol
1785 /* %start-doc pcbfile SymbolLine
1787 @syntax
1788 SymbolLine [X1 Y1 X2 Y2 Thickness]
1789 SymbolLine (X1 Y1 X2 Y2 Thickness)
1790 @end syntax
1792 @table @var
1793 @item X1 Y1 X2 Y2
1794 The endpoints of this line.
1795 @item Thickness
1796 The width of this line.
1797 @end table
1799 %end-doc */
1801 symboldefinition
1802 /* x1, y1, x2, y2, thickness */
1803 : T_SYMBOLLINE '(' measure measure measure measure measure ')'
1805 CreateNewLineInSymbol(Symbol, OU ($3), OU ($4), OU ($5), OU ($6), OU ($7));
1808 hiressymbol
1809 /* x1, y1, x2, y2, thickness */
1810 : T_SYMBOLLINE '[' measure measure measure measure measure ']'
1812 CreateNewLineInSymbol(Symbol, NU ($3), NU ($4), NU ($5), NU ($6), NU ($7));
1816 /* %start-doc pcbfile Netlist
1818 @syntax
1819 Netlist ( ) (
1820 @ @ @ @dots{} nets @dots{}
1822 @end syntax
1824 %end-doc */
1826 pcbnetlist : pcbnetdef
1829 pcbnetdef
1830 /* net(...) net(...) ... */
1831 : T_NETLIST '(' ')' '('
1832 nets ')'
1835 nets
1836 : netdefs
1840 netdefs
1841 : net
1842 | netdefs net
1845 /* %start-doc pcbfile Net
1847 @syntax
1848 Net ("Name" "Style") (
1849 @ @ @ @dots{} connects @dots{}
1851 @end syntax
1853 @table @var
1854 @item Name
1855 The name of this net.
1856 @item Style
1857 The routing style that should be used when autorouting this net.
1858 @end table
1860 %end-doc */
1863 /* name style pin pin ... */
1864 : T_NET '(' STRING STRING ')' '('
1866 Menu = CreateNewNet(&yyPCB->NetlistLib, $3, $4);
1867 free ($3);
1868 free ($4);
1870 connections ')'
1873 connections
1874 : conndefs
1878 conndefs
1879 : conn
1880 | conndefs conn
1883 /* %start-doc pcbfile Connect
1885 @syntax
1886 Connect ("PinPad")
1887 @end syntax
1889 @table @var
1890 @item PinPad
1891 The name of a pin or pad which is included in this net. Pin and Pad
1892 names are named by the refdes and pin name, like @code{"U14-7"} for
1893 pin 7 of U14, or @code{"T4-E"} for pin E of T4.
1894 @end table
1896 %end-doc */
1898 conn
1899 : T_CONN '(' STRING ')'
1901 CreateNewConnection(Menu, $3);
1902 free ($3);
1906 /* %start-doc pcbfile Attribute
1908 @syntax
1909 Attribute ("Name" "Value")
1910 @end syntax
1912 Attributes allow boards and elements to have arbitrary data attached
1913 to them, which is not directly used by PCB itself but may be of use by
1914 other programs or users.
1916 @table @var
1917 @item Name
1918 The name of the attribute
1920 @item Value
1921 The value of the attribute. Values are always stored as strings, even
1922 if the value is interpreted as, for example, a number.
1924 @end table
1926 %end-doc */
1928 attribute
1929 : T_ATTRIBUTE '(' STRING STRING ')'
1931 CreateNewAttribute (attr_list, $3, $4 ? $4 : (char *)"");
1932 free ($3);
1933 free ($4);
1937 opt_string : STRING { $$ = $1; }
1938 | /* empty */ { $$ = 0; }
1941 number
1942 : FLOATING { $$ = $1; }
1943 | INTEGER { $$ = $1; }
1946 measure
1947 /* Default unit (no suffix) is cmil */
1948 : number { do_measure(&$$, $1, MIL_TO_COORD ($1) / 100.0, 0); }
1949 | number T_UMIL { M ($$, $1, MIL_TO_COORD ($1) / 100000.0); }
1950 | number T_CMIL { M ($$, $1, MIL_TO_COORD ($1) / 100.0); }
1951 | number T_MIL { M ($$, $1, MIL_TO_COORD ($1)); }
1952 | number T_IN { M ($$, $1, INCH_TO_COORD ($1)); }
1953 | number T_NM { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1954 | number T_PX { M ($$, $1, MM_TO_COORD ($1) / 1000000.0); }
1955 | number T_UM { M ($$, $1, MM_TO_COORD ($1) / 1000.0); }
1956 | number T_MM { M ($$, $1, MM_TO_COORD ($1)); }
1957 | number T_M { M ($$, $1, MM_TO_COORD ($1) * 1000.0); }
1958 | number T_KM { M ($$, $1, MM_TO_COORD ($1) * 1000000.0); }
1963 /* ---------------------------------------------------------------------------
1964 * error routine called by parser library
1966 int yyerror(const char * s)
1968 Message(_("ERROR parsing file '%s'\n"
1969 " line: %i\n"
1970 " description: '%s'\n"),
1971 yyfilename, yylineno, s);
1972 return(0);
1975 int yywrap()
1977 return 1;
1980 static int
1981 check_file_version (int ver)
1983 if ( ver > PCB_FILE_VERSION ) {
1984 Message (_("ERROR: The file you are attempting to load is in a format\n"
1985 "which is too new for this version of pcb. To load this file\n"
1986 "you need a version of pcb which is >= %d. If you are\n"
1987 "using a version built from git source, the source date\n"
1988 "must be >= %d. This copy of pcb can only read files\n"
1989 "up to file version %d.\n"), ver, ver, PCB_FILE_VERSION);
1990 return 1;
1993 return 0;
1996 static void
1997 do_measure (PLMeasure *m, Coord i, double d, int u)
1999 m->ival = i;
2000 m->bval = round (d);
2001 m->dval = d;
2002 m->has_units = u;
2005 static int
2006 integer_value (PLMeasure m)
2008 if (m.has_units)
2009 yyerror("units ignored here");
2010 return m.ival;
2013 static Coord
2014 old_units (PLMeasure m)
2016 if (m.has_units)
2017 return m.bval;
2018 return round (MIL_TO_COORD (m.ival));
2021 static Coord
2022 new_units (PLMeasure m)
2024 if (m.has_units)
2025 return m.bval;
2026 return round (MIL_TO_COORD (m.ival) / 100.0);