Add support for filling / thindrawing raw polygons to the HID interface
[geda-pcb/gde.git] / src / report.c
blobaf9e0b37f20518e32082d6b1ccd4657f6840369d
1 /* $Id$ */
3 /*
4 * COPYRIGHT
6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996,1997,1998,1999 Thomas Nau
9 * This module, report.c, was written and is Copyright (C) 1997 harry eaton
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Contact addresses for paper mail and Email:
26 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
27 * Thomas.Nau@rz.uni-ulm.de
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
36 #include <math.h>
38 #include "report.h"
39 #include "crosshair.h"
40 #include "data.h"
41 #include "drill.h"
42 #include "error.h"
43 #include "search.h"
44 #include "misc.h"
45 #include "mymem.h"
46 #include "rtree.h"
47 #include "strflags.h"
48 #include "macro.h"
49 #include "undo.h"
50 #include "find.h"
52 #ifdef HAVE_LIBDMALLOC
53 #include <dmalloc.h>
54 #endif
56 RCSID ("$Id$");
59 #define UNIT1(value) (Settings.grid_units_mm ? ((value) / 100000.0 * 25.4) : ((value) / 100.0))
60 #define UNIT(value) UNIT1(value) , (Settings.grid_units_mm ? "mm" : "mils")
62 static int
63 ReportDrills (int argc, char **argv, int x, int y)
65 DrillInfoTypePtr AllDrills;
66 Cardinal n;
67 char *stringlist, *thestring;
68 int total_drills = 0;
70 AllDrills = GetDrillInfo (PCB->Data);
71 RoundDrillInfo (AllDrills, 100);
73 for (n = 0; n < AllDrills->DrillN; n++)
75 total_drills += AllDrills->Drill[n].PinCount;
76 total_drills += AllDrills->Drill[n].ViaCount;
77 total_drills += AllDrills->Drill[n].UnplatedCount;
80 stringlist = malloc (512L + AllDrills->DrillN * 64L);
82 /* Use tabs for formatting since can't count on a fixed font anymore.
83 | And even that probably isn't going to work in all cases.
85 sprintf (stringlist,
86 "There are %d different drill sizes used in this layout, %d holes total\n\n"
87 "Drill Diam. (mils)\t# of Pins\t# of Vias\t# of Elements\t# Unplated\n",
88 AllDrills->DrillN, total_drills);
89 thestring = stringlist;
90 while (*thestring != '\0')
91 thestring++;
92 for (n = 0; n < AllDrills->DrillN; n++)
94 sprintf (thestring,
95 "\t%d\t\t\t%d\t\t%d\t\t%d\t\t%d\n",
96 (AllDrills->Drill[n].DrillSize+50) / 100,
97 AllDrills->Drill[n].PinCount, AllDrills->Drill[n].ViaCount,
98 AllDrills->Drill[n].ElementN,
99 AllDrills->Drill[n].UnplatedCount);
100 while (*thestring != '\0')
101 thestring++;
103 FreeDrillInfo (AllDrills);
104 /* create dialog box */
105 gui->report_dialog ("Drill Report", stringlist);
107 SaveFree (stringlist);
108 return 0;
112 static const char reportdialog_syntax[] = "ReportDialog()";
114 static const char reportdialog_help[] =
115 "Report on the object under the crosshair";
117 /* %start-doc actions ReportDialog
119 This is a shortcut for @code{Report(Object)}.
121 %end-doc */
123 static int
124 ReportDialog (int argc, char **argv, int x, int y)
126 void *ptr1, *ptr2, *ptr3;
127 int type;
128 char report[2048];
130 type = SearchScreen (x, y, REPORT_TYPES, &ptr1, &ptr2, &ptr3);
131 if (type == NO_TYPE)
132 type =
133 SearchScreen (x, y, REPORT_TYPES | LOCKED_TYPE, &ptr1, &ptr2, &ptr3);
135 switch (type)
137 case VIA_TYPE:
139 PinTypePtr via;
140 #ifndef NDEBUG
141 if (gui->shift_is_pressed ())
143 __r_dump_tree (PCB->Data->via_tree->root, 0);
144 return 0;
146 #endif
147 via = (PinTypePtr) ptr2;
148 if (TEST_FLAG (HOLEFLAG, via))
149 sprintf (&report[0], "VIA ID# %ld Flags:%s\n"
150 "(X,Y) = (%d, %d)\n"
151 "It is a pure hole of diameter %0.2f %s\n"
152 "Name = \"%s\""
153 "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE),
154 via->X, via->Y, UNIT (via->DrillingHole),
155 EMPTY (via->Name), TEST_FLAG (LOCKFLAG,
156 via) ? "It is LOCKED\n" :
157 "");
158 else
159 sprintf (&report[0], "VIA ID# %ld Flags:%s\n"
160 "(X,Y) = (%d, %d)\n"
161 "Copper width = %0.2f %s Drill width = %0.2f %s\n"
162 "Clearance width in polygons = %0.2f %s\n"
163 "Annulus = %0.2f %s\n"
164 "Solder mask hole = %0.2f %s (gap = %0.2f %s)\n"
165 "Name = \"%s\""
166 "%s", via->ID, flags_to_string (via->Flags, VIA_TYPE),
167 via->X, via->Y, UNIT (via->Thickness),
168 UNIT (via->DrillingHole), UNIT (via->Clearance / 2.),
169 UNIT ((via->Thickness - via->DrillingHole)/2),
170 UNIT (via->Mask), UNIT ((via->Mask - via->Thickness)/2),
171 EMPTY (via->Name), TEST_FLAG (LOCKFLAG, via) ?
172 "It is LOCKED\n" : "");
173 break;
175 case PIN_TYPE:
177 PinTypePtr Pin;
178 ElementTypePtr element;
179 #ifndef NDEBUG
180 if (gui->shift_is_pressed ())
182 __r_dump_tree (PCB->Data->pin_tree->root, 0);
183 return 0;
185 #endif
186 Pin = (PinTypePtr) ptr2;
187 element = (ElementTypePtr) ptr1;
189 PIN_LOOP (element);
191 if (pin == Pin)
192 break;
194 END_LOOP;
195 if (TEST_FLAG (HOLEFLAG, Pin))
196 sprintf (&report[0], "PIN ID# %ld Flags:%s\n"
197 "(X,Y) = (%d, %d)\n"
198 "It is a mounting hole, Drill width = %0.2f %s\n"
199 "It is owned by element %s\n"
200 "%s", Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE),
201 Pin->X, Pin->Y, UNIT (Pin->DrillingHole),
202 EMPTY (element->Name[1].TextString),
203 TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED\n" : "");
204 else
205 sprintf (&report[0],
206 "PIN ID# %ld Flags:%s\n" "(X,Y) = (%d, %d)\n"
207 "Copper width = %0.2f %s Drill width = %0.2f %s\n"
208 "Clearance width to Polygon = %0.2f %s\n"
209 "Annulus = %0.2f %s\n"
210 "Solder mask hole = %0.2f %s (gap = %0.2f %s)\n"
211 "Name = \"%s\"\n"
212 "It is owned by element %s\n" "As pin number %s\n"
213 "%s",
214 Pin->ID, flags_to_string (Pin->Flags, PIN_TYPE),
215 Pin->X, Pin->Y, UNIT (Pin->Thickness),
216 UNIT (Pin->DrillingHole), UNIT (Pin->Clearance / 2.),
217 UNIT ((Pin->Thickness - Pin->DrillingHole)/2),
218 UNIT (Pin->Mask), UNIT ((Pin->Mask - Pin->Thickness)/2),
219 EMPTY (Pin->Name),
220 EMPTY (element->Name[1].TextString), EMPTY (Pin->Number),
221 TEST_FLAG (LOCKFLAG, Pin) ? "It is LOCKED\n" : "");
222 break;
224 case LINE_TYPE:
226 LineTypePtr line;
227 #ifndef NDEBUG
228 if (gui->shift_is_pressed ())
230 LayerTypePtr layer = (LayerTypePtr) ptr1;
231 __r_dump_tree (layer->line_tree->root, 0);
232 return 0;
234 #endif
235 line = (LineTypePtr) ptr2;
236 sprintf (&report[0], "LINE ID# %ld Flags:%s\n"
237 "FirstPoint(X,Y) = (%d, %d) ID = %ld\n"
238 "SecondPoint(X,Y) = (%d, %d) ID = %ld\n"
239 "Width = %0.2f %s.\nClearance width in polygons = %0.2f %s.\n"
240 "It is on layer %d\n"
241 "and has name %s\n"
242 "%s",
243 line->ID, flags_to_string (line->Flags, LINE_TYPE),
244 line->Point1.X, line->Point1.Y,
245 line->Point1.ID, line->Point2.X, line->Point2.Y,
246 line->Point2.ID, UNIT (line->Thickness),
247 UNIT (line->Clearance / 2.), GetLayerNumber (PCB->Data,
248 (LayerTypePtr) ptr1),
249 UNKNOWN (line->Number), TEST_FLAG (LOCKFLAG,
250 line) ? "It is LOCKED\n" :
251 "");
252 break;
254 case RATLINE_TYPE:
256 RatTypePtr line;
257 #ifndef NDEBUG
258 if (gui->shift_is_pressed ())
260 __r_dump_tree (PCB->Data->rat_tree->root, 0);
261 return 0;
263 #endif
264 line = (RatTypePtr) ptr2;
265 sprintf (&report[0], "RAT-LINE ID# %ld Flags:%s\n"
266 "FirstPoint(X,Y) = (%d, %d) ID = %ld "
267 "connects to layer group %d\n"
268 "SecondPoint(X,Y) = (%d, %d) ID = %ld "
269 "connects to layer group %d\n",
270 line->ID, flags_to_string (line->Flags, LINE_TYPE),
271 line->Point1.X, line->Point1.Y,
272 line->Point1.ID, line->group1,
273 line->Point2.X, line->Point2.Y,
274 line->Point2.ID, line->group2);
275 break;
277 case ARC_TYPE:
279 ArcTypePtr Arc;
280 BoxTypePtr box;
281 #ifndef NDEBUG
282 if (gui->shift_is_pressed ())
284 LayerTypePtr layer = (LayerTypePtr) ptr1;
285 __r_dump_tree (layer->arc_tree->root, 0);
286 return 0;
288 #endif
289 Arc = (ArcTypePtr) ptr2;
290 box = GetArcEnds (Arc);
292 sprintf (&report[0], "ARC ID# %ld Flags:%s\n"
293 "CenterPoint(X,Y) = (%d, %d)\n"
294 "Radius = %0.2f %s, Thickness = %0.2f %s\n"
295 "Clearance width in polygons = %0.2f %s\n"
296 "StartAngle = %ld degrees, DeltaAngle = %ld degrees\n"
297 "Bounding Box is (%d,%d), (%d,%d)\n"
298 "That makes the end points at (%d,%d) and (%d,%d)\n"
299 "It is on layer %d\n"
300 "%s", Arc->ID, flags_to_string (Arc->Flags, ARC_TYPE),
301 Arc->X, Arc->Y, UNIT (Arc->Width), UNIT (Arc->Thickness),
302 UNIT (Arc->Clearance / 2.), Arc->StartAngle, Arc->Delta,
303 Arc->BoundingBox.X1, Arc->BoundingBox.Y1,
304 Arc->BoundingBox.X2, Arc->BoundingBox.Y2, box->X1,
305 box->Y1, box->X2, box->Y2, GetLayerNumber (PCB->Data,
306 (LayerTypePtr)
307 ptr1),
308 TEST_FLAG (LOCKFLAG, Arc) ? "It is LOCKED\n" : "");
309 break;
311 case POLYGON_TYPE:
313 PolygonTypePtr Polygon;
314 #ifndef NDEBUG
315 if (gui->shift_is_pressed ())
317 LayerTypePtr layer = (LayerTypePtr) ptr1;
318 __r_dump_tree (layer->polygon_tree->root, 0);
319 return;
321 #endif
322 Polygon = (PolygonTypePtr) ptr2;
324 sprintf (&report[0], "POLYGON ID# %ld Flags:%s\n"
325 "Its bounding box is (%d,%d) (%d,%d)\n"
326 "It has %d points and could store %d more\n"
327 "without using more memory.\n"
328 "It resides on layer %d\n"
329 "%s", Polygon->ID,
330 flags_to_string (Polygon->Flags, POLYGON_TYPE),
331 Polygon->BoundingBox.X1, Polygon->BoundingBox.Y1,
332 Polygon->BoundingBox.X2, Polygon->BoundingBox.Y2,
333 Polygon->PointN, Polygon->PointMax - Polygon->PointN,
334 GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1),
335 TEST_FLAG (LOCKFLAG, Polygon) ? "It is LOCKED\n" : "");
336 break;
338 case PAD_TYPE:
340 int len, dx, dy, mgap;
341 PadTypePtr Pad;
342 ElementTypePtr element;
343 #ifndef NDEBUG
344 if (gui->shift_is_pressed ())
346 __r_dump_tree (PCB->Data->pad_tree->root, 0);
347 return 0;
349 #endif
350 Pad = (PadTypePtr) ptr2;
351 element = (ElementTypePtr) ptr1;
353 PAD_LOOP (element);
356 if (pad == Pad)
357 break;
360 END_LOOP;
361 dx = Pad->Point1.X - Pad->Point2.X;
362 dy = Pad->Point1.Y - Pad->Point2.Y;
363 len = sqrt (dx*dx+dy*dy);
364 mgap = (Pad->Mask - Pad->Thickness)/2;
365 sprintf (&report[0], "PAD ID# %ld Flags:%s\n"
366 "FirstPoint(X,Y) = (%d, %d) ID = %ld\n"
367 "SecondPoint(X,Y) = (%d, %d) ID = %ld\n"
368 "Width = %0.2f %s. Length = %0.2f %s.\n"
369 "Clearance width in polygons = %0.2f %s.\n"
370 "Solder mask = %0.2f x %0.2f %s (gap = %0.2f %s).\n"
371 "Name = \"%s\"\n"
372 "It is owned by SMD element %s\n"
373 "As pin number %s and is on the %s\n"
374 "side of the board.\n"
375 "%s", Pad->ID,
376 flags_to_string (Pad->Flags, PAD_TYPE),
377 Pad->Point1.X, Pad->Point1.Y, Pad->Point1.ID,
378 Pad->Point2.X, Pad->Point2.Y, Pad->Point2.ID,
379 UNIT (Pad->Thickness), UNIT (len + Pad->Thickness),
380 UNIT (Pad->Clearance / 2.),
381 UNIT1 (Pad->Mask), UNIT (Pad->Mask + len), UNIT (mgap),
382 EMPTY (Pad->Name),
383 EMPTY (element->Name[1].TextString),
384 EMPTY (Pad->Number),
385 TEST_FLAG (ONSOLDERFLAG,
386 Pad) ? "solder (bottom)" : "component",
387 TEST_FLAG (LOCKFLAG, Pad) ? "It is LOCKED\n" : "");
388 break;
390 case ELEMENT_TYPE:
392 ElementTypePtr element;
393 #ifndef NDEBUG
394 if (gui->shift_is_pressed ())
396 __r_dump_tree (PCB->Data->element_tree->root, 0);
397 return 0;
399 #endif
400 element = (ElementTypePtr) ptr2;
401 sprintf (&report[0], "ELEMENT ID# %ld Flags:%s\n"
402 "BoundingBox (%d,%d) (%d,%d)\n"
403 "Descriptive Name \"%s\"\n"
404 "Name on board \"%s\"\n"
405 "Part number name \"%s\"\n"
406 "It is %0.2f %s tall and is located at (X,Y) = (%d,%d)\n"
407 "%s"
408 "Mark located at point (X,Y) = (%d,%d)\n"
409 "It is on the %s side of the board.\n"
410 "%s",
411 element->ID, flags_to_string (element->Flags, ELEMENT_TYPE),
412 element->BoundingBox.X1, element->BoundingBox.Y1,
413 element->BoundingBox.X2, element->BoundingBox.Y2,
414 EMPTY (element->Name[0].TextString),
415 EMPTY (element->Name[1].TextString),
416 EMPTY (element->Name[2].TextString),
417 UNIT (0.45 * element->Name[1].Scale * 100.), element->Name[1].X,
418 element->Name[1].Y, TEST_FLAG (HIDENAMEFLAG, element) ?
419 "But it's hidden\n" : "", element->MarkX,
420 element->MarkY, TEST_FLAG (ONSOLDERFLAG,
421 element) ? "solder (bottom)" :
422 "component", TEST_FLAG (LOCKFLAG, element) ?
423 "It is LOCKED\n" : "");
424 break;
426 case TEXT_TYPE:
427 #ifndef NDEBUG
428 if (gui->shift_is_pressed ())
430 LayerTypePtr layer = (LayerTypePtr) ptr1;
431 __r_dump_tree (layer->text_tree->root, 0);
432 return 0;
434 #endif
435 case ELEMENTNAME_TYPE:
437 char laynum[32];
438 TextTypePtr text;
439 #ifndef NDEBUG
440 if (gui->shift_is_pressed ())
442 __r_dump_tree (PCB->Data->name_tree[NAME_INDEX (PCB)]->root, 0);
443 return 0;
445 #endif
446 text = (TextTypePtr) ptr2;
448 if (type == TEXT_TYPE)
449 sprintf (laynum, "is on layer %d",
450 GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1));
451 sprintf (&report[0], "TEXT ID# %ld Flags:%s\n"
452 "Located at (X,Y) = (%d,%d)\n"
453 "Characters are %0.2f %s tall\n"
454 "Value is \"%s\"\n"
455 "Direction is %d\n"
456 "The bounding box is (%d,%d) (%d, %d)\n"
457 "It %s\n"
458 "%s", text->ID, flags_to_string (text->Flags, TEXT_TYPE),
459 text->X, text->Y, UNIT (0.45 * text->Scale * 100.),
460 text->TextString, text->Direction,
461 text->BoundingBox.X1, text->BoundingBox.Y1,
462 text->BoundingBox.X2, text->BoundingBox.Y2,
463 (type == TEXT_TYPE) ? laynum : "is an element name.",
464 TEST_FLAG (LOCKFLAG, text) ? "It is LOCKED\n" : "");
465 break;
467 case LINEPOINT_TYPE:
468 case POLYGONPOINT_TYPE:
470 PointTypePtr point = (PointTypePtr) ptr2;
471 sprintf (&report[0], "POINT ID# %ld. Points don't have flags.\n"
472 "Located at (X,Y) = (%d,%d)\n"
473 "It belongs to a %s on layer %d\n", point->ID,
474 point->X, point->Y,
475 (type == LINEPOINT_TYPE) ? "line" : "polygon",
476 GetLayerNumber (PCB->Data, (LayerTypePtr) ptr1));
477 break;
479 case NO_TYPE:
480 report[0] = '\0';
481 break;
483 default:
484 sprintf (&report[0], "Unknown\n");
485 break;
488 if (report[0] == '\0')
490 Message (_("Nothing found to report on\n"));
491 return 1;
493 HideCrosshair (False);
494 /* create dialog box */
495 gui->report_dialog ("Report", &report[0]);
497 RestoreCrosshair (False);
498 return 0;
501 static int
502 ReportFoundPins (int argc, char **argv, int x, int y)
504 static DynamicStringType list;
505 char temp[64];
506 int col = 0;
508 DSClearString (&list);
509 DSAddString (&list, "The following pins/pads are FOUND:\n");
510 ELEMENT_LOOP (PCB->Data);
512 PIN_LOOP (element);
514 if (TEST_FLAG (FOUNDFLAG, pin))
516 sprintf (temp, "%s-%s,%c",
517 NAMEONPCB_NAME (element),
518 pin->Number,
519 ((col++ % (COLUMNS + 1)) == COLUMNS) ? '\n' : ' ');
520 DSAddString (&list, temp);
523 END_LOOP;
524 PAD_LOOP (element);
526 if (TEST_FLAG (FOUNDFLAG, pad))
528 sprintf (temp, "%s-%s,%c",
529 NAMEONPCB_NAME (element), pad->Number,
530 ((col++ % (COLUMNS + 1)) == COLUMNS) ? '\n' : ' ');
531 DSAddString (&list, temp);
534 END_LOOP;
536 END_LOOP;
538 HideCrosshair (False);
539 gui->report_dialog ("Report", list.Data);
540 RestoreCrosshair (False);
541 return 0;
544 static int
545 ReportNetLength (int argc, char **argv, int x, int y)
547 double length = 0;
548 char *netname = 0;
549 int found = 0;
551 SaveUndoSerialNumber ();
552 ResetFoundPinsViasAndPads (True);
553 RestoreUndoSerialNumber ();
554 ResetFoundLinesAndPolygons (True);
555 RestoreUndoSerialNumber ();
556 gui->get_coords ("Click on a connection", &x, &y);
557 LookupConnection (x, y, True, PCB->Grid, FOUNDFLAG);
559 ALLLINE_LOOP (PCB->Data);
561 if (TEST_FLAG (FOUNDFLAG, line))
563 double l;
564 int dx, dy;
565 dx = line->Point1.X - line->Point2.X;
566 dy = line->Point1.Y - line->Point2.Y;
567 l = sqrt ((double)dx*dx + (double)dy*dy);
568 length += l;
569 found = 1;
572 ENDALL_LOOP;
574 ALLARC_LOOP (PCB->Data);
576 if (TEST_FLAG (FOUNDFLAG, arc))
578 double l;
579 /* FIXME: we assume width==height here */
580 l = M_PI * 2*arc->Width * abs(arc->Delta)/360.0;
581 length += l;
582 found = 1;
585 ENDALL_LOOP;
587 if (!found)
589 gui->log ("No net under cursor.\n");
590 return 1;
593 ELEMENT_LOOP (PCB->Data);
595 PIN_LOOP (element);
597 if (TEST_FLAG (FOUNDFLAG, pin))
599 int ni, nei;
600 char *ename = element->Name[NAMEONPCB_INDEX].TextString;
601 char *pname = pin->Number;
602 char *n = Concat (ename, "-", pname, NULL);
603 for (ni = 0; ni < PCB->NetlistLib.MenuN; ni++)
604 for (nei = 0; nei < PCB->NetlistLib.Menu[ni].EntryN; nei++)
606 if (strcmp (PCB->NetlistLib.Menu[ni].Entry[nei].ListEntry, n) == 0)
608 netname = PCB->NetlistLib.Menu[ni].Name + 2;
609 goto got_net_name; /* four for loops deep */
614 END_LOOP;
615 PAD_LOOP (element);
617 if (TEST_FLAG (FOUNDFLAG, pad))
619 int ni, nei;
620 char *ename = element->Name[NAMEONPCB_INDEX].TextString;
621 char *pname = pad->Number;
622 char *n = Concat (ename, "-", pname, NULL);
623 for (ni = 0; ni < PCB->NetlistLib.MenuN; ni++)
624 for (nei = 0; nei < PCB->NetlistLib.Menu[ni].EntryN; nei++)
626 if (strcmp (PCB->NetlistLib.Menu[ni].Entry[nei].ListEntry, n) == 0)
628 netname = PCB->NetlistLib.Menu[ni].Name + 2;
629 goto got_net_name; /* four for loops deep */
634 END_LOOP;
636 END_LOOP;
637 got_net_name:
639 HideCrosshair (False);
640 if (netname)
641 gui->log ("Net %s length: %0.2f %s\n", netname, UNIT (length));
642 else
643 gui->log ("Net length: %0.2f %s\n", UNIT (length));
644 RestoreCrosshair (False);
645 return 0;
647 /* ---------------------------------------------------------------------------
648 * reports on an object
649 * syntax:
652 static const char report_syntax[] = "Report(Object|DrillReport|FoundPins|NetLength)";
654 static const char report_help[] = "Produce various report.";
656 /* %start-doc actions Report
658 @table @code
660 @item Object
661 The object under the crosshair will be reported, describing various
662 aspects of the object.
664 @item DrillReport
665 A report summarizing the number of drill sizes used, and how many of
666 each, will be produced.
668 @item FoundPins
669 A report listing all pins and pads which are marked as ``found'' will
670 be produced.
672 @item NetLength
673 The name and length of the net under the crosshair will be reported to
674 the message log.
676 @end table
678 %end-doc */
680 static int
681 Report (int argc, char **argv, int x, int y)
683 if (argc != 1)
684 AUSAGE (report);
685 else if (strcasecmp (argv[0], "Object") == 0)
687 gui->get_coords ("Click on an object", &x, &y);
688 return ReportDialog (argc - 1, argv + 1, x, y);
690 else if (strcasecmp (argv[0], "DrillReport") == 0)
691 return ReportDrills (argc - 1, argv + 1, x, y);
692 else if (strcasecmp (argv[0], "FoundPins") == 0)
693 return ReportFoundPins (argc - 1, argv + 1, x, y);
694 else if (strcasecmp (argv[0], "NetLength") == 0)
695 return ReportNetLength (argc - 1, argv + 1, x, y);
696 else
697 AFAIL (report);
698 return 1;
701 HID_Action report_action_list[] = {
702 {"ReportObject", "Click on an object", ReportDialog,
703 reportdialog_help, reportdialog_syntax}
705 {"Report", 0, Report,
706 report_help, report_syntax}
709 REGISTER_ACTIONS (report_action_list)