select.c: Set an explicit flag to search using when selecting nets by name
[geda-pcb/pcjc2.git] / src / select.c
blobca6a66043b03304fe351a1692599040fb4724bf9
1 /*
2 * COPYRIGHT
4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Contact addresses for paper mail and Email:
22 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 * Thomas.Nau@rz.uni-ulm.de
28 /* select routines
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
35 #include "global.h"
37 #include "data.h"
38 #include "draw.h"
39 #include "error.h"
40 #include "search.h"
41 #include "select.h"
42 #include "undo.h"
43 #include "rats.h"
44 #include "misc.h"
45 #include "find.h"
47 #include <sys/types.h>
48 #ifdef HAVE_REGEX_H
49 #include <regex.h>
50 #else
51 #ifdef HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 #endif
56 #ifdef HAVE_LIBDMALLOC
57 #include <dmalloc.h>
58 #endif
60 /* ---------------------------------------------------------------------------
61 * toggles the selection of any kind of object
62 * the different types are defined by search.h
64 bool
65 SelectObject (void)
67 void *ptr1, *ptr2, *ptr3;
68 LayerType *layer;
69 int type;
71 bool changed = true;
73 type = SearchScreen (Crosshair.X, Crosshair.Y, SELECT_TYPES,
74 &ptr1, &ptr2, &ptr3);
75 if (type == NO_TYPE || TEST_FLAG (LOCKFLAG, (PinType *) ptr2))
76 return (false);
77 switch (type)
79 case VIA_TYPE:
80 AddObjectToFlagUndoList (VIA_TYPE, ptr1, ptr1, ptr1);
81 TOGGLE_FLAG (SELECTEDFLAG, (PinType *) ptr1);
82 DrawVia ((PinType *) ptr1);
83 break;
85 case LINE_TYPE:
87 LineType *line = (LineType *) ptr2;
89 layer = (LayerType *) ptr1;
90 AddObjectToFlagUndoList (LINE_TYPE, ptr1, ptr2, ptr2);
91 TOGGLE_FLAG (SELECTEDFLAG, line);
92 DrawLine (layer, line);
93 break;
96 case RATLINE_TYPE:
98 RatType *rat = (RatType *) ptr2;
100 AddObjectToFlagUndoList (RATLINE_TYPE, ptr1, ptr1, ptr1);
101 TOGGLE_FLAG (SELECTEDFLAG, rat);
102 DrawRat (rat);
103 break;
106 case ARC_TYPE:
108 ArcType *arc = (ArcType *) ptr2;
110 layer = (LayerType *) ptr1;
111 AddObjectToFlagUndoList (ARC_TYPE, ptr1, ptr2, ptr2);
112 TOGGLE_FLAG (SELECTEDFLAG, arc);
113 DrawArc (layer, arc);
114 break;
117 case TEXT_TYPE:
119 TextType *text = (TextType *) ptr2;
121 layer = (LayerType *) ptr1;
122 AddObjectToFlagUndoList (TEXT_TYPE, ptr1, ptr2, ptr2);
123 TOGGLE_FLAG (SELECTEDFLAG, text);
124 DrawText (layer, text);
125 break;
128 case POLYGON_TYPE:
130 PolygonType *poly = (PolygonType *) ptr2;
132 layer = (LayerType *) ptr1;
133 AddObjectToFlagUndoList (POLYGON_TYPE, ptr1, ptr2, ptr2);
134 TOGGLE_FLAG (SELECTEDFLAG, poly);
135 DrawPolygon (layer, poly);
136 /* changing memory order no longer effects draw order */
137 break;
140 case PIN_TYPE:
141 AddObjectToFlagUndoList (PIN_TYPE, ptr1, ptr2, ptr2);
142 TOGGLE_FLAG (SELECTEDFLAG, (PinType *) ptr2);
143 DrawPin ((PinType *) ptr2);
144 break;
146 case PAD_TYPE:
147 AddObjectToFlagUndoList (PAD_TYPE, ptr1, ptr2, ptr2);
148 TOGGLE_FLAG (SELECTEDFLAG, (PadType *) ptr2);
149 DrawPad ((PadType *) ptr2);
150 break;
152 case ELEMENTNAME_TYPE:
154 ElementType *element = (ElementType *) ptr1;
156 /* select all names of the element */
157 ELEMENTTEXT_LOOP (element);
159 AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
160 TOGGLE_FLAG (SELECTEDFLAG, text);
162 END_LOOP;
163 DrawElementName (element);
164 break;
167 case ELEMENT_TYPE:
169 ElementType *element = (ElementType *) ptr1;
171 /* select all pins and names of the element */
172 PIN_LOOP (element);
174 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
175 TOGGLE_FLAG (SELECTEDFLAG, pin);
177 END_LOOP;
178 PAD_LOOP (element);
180 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
181 TOGGLE_FLAG (SELECTEDFLAG, pad);
183 END_LOOP;
184 ELEMENTTEXT_LOOP (element);
186 AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
187 TOGGLE_FLAG (SELECTEDFLAG, text);
189 END_LOOP;
190 AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
191 TOGGLE_FLAG (SELECTEDFLAG, element);
192 if (PCB->ElementOn &&
193 ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT ||
194 PCB->InvisibleObjectsOn))
195 if (PCB->ElementOn)
197 DrawElementName (element);
198 DrawElementPackage (element);
200 if (PCB->PinOn)
201 DrawElementPinsAndPads (element);
202 break;
205 Draw ();
206 IncrementUndoSerialNumber ();
207 return (changed);
210 /* ----------------------------------------------------------------------
211 * selects/unselects all visible objects within the passed box
212 * Flag determines if the block is to be selected or unselected
213 * returns true if the state of any object has changed
215 bool
216 SelectBlock (BoxType *Box, bool Flag)
218 bool changed = false;
220 if (PCB->RatOn || !Flag)
221 RAT_LOOP (PCB->Data);
223 if (LINE_IN_BOX ((LineType *) line, Box) &&
224 !TEST_FLAG (LOCKFLAG, line) && TEST_FLAG (SELECTEDFLAG, line) != Flag)
226 AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
227 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
228 if (PCB->RatOn)
229 DrawRat (line);
230 changed = true;
233 END_LOOP;
235 /* check layers */
236 LAYER_LOOP(PCB->Data, max_copper_layer + 2);
238 if (layer == & PCB->Data->SILKLAYER)
240 if (! (PCB->ElementOn || !Flag))
241 continue;
243 else if (layer == & PCB->Data->BACKSILKLAYER)
245 if (! (PCB->InvisibleObjectsOn || !Flag))
246 continue;
248 else
249 if (! (layer->On || !Flag))
250 continue;
252 LINE_LOOP (layer);
254 if (LINE_IN_BOX (line, Box)
255 && !TEST_FLAG (LOCKFLAG, line)
256 && TEST_FLAG (SELECTEDFLAG, line) != Flag)
258 AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
259 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
260 if (layer->On)
261 DrawLine (layer, line);
262 changed = true;
265 END_LOOP;
266 ARC_LOOP (layer);
268 if (ARC_IN_BOX (arc, Box)
269 && !TEST_FLAG (LOCKFLAG, arc)
270 && TEST_FLAG (SELECTEDFLAG, arc) != Flag)
272 AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
273 ASSIGN_FLAG (SELECTEDFLAG, Flag, arc);
274 if (layer->On)
275 DrawArc (layer, arc);
276 changed = true;
279 END_LOOP;
280 TEXT_LOOP (layer);
282 if (!Flag || TEXT_IS_VISIBLE(PCB, layer, text))
284 if (TEXT_IN_BOX (text, Box)
285 && !TEST_FLAG (LOCKFLAG, text)
286 && TEST_FLAG (SELECTEDFLAG, text) != Flag)
288 AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
289 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
290 if (TEXT_IS_VISIBLE(PCB, layer, text))
291 DrawText (layer, text);
292 changed = true;
296 END_LOOP;
297 POLYGON_LOOP (layer);
299 if (POLYGON_IN_BOX (polygon, Box)
300 && !TEST_FLAG (LOCKFLAG, polygon)
301 && TEST_FLAG (SELECTEDFLAG, polygon) != Flag)
303 AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
304 ASSIGN_FLAG (SELECTEDFLAG, Flag, polygon);
305 if (layer->On)
306 DrawPolygon (layer, polygon);
307 changed = true;
310 END_LOOP;
312 END_LOOP;
314 /* elements */
315 ELEMENT_LOOP (PCB->Data);
318 bool gotElement = false;
319 if ((PCB->ElementOn || !Flag)
320 && !TEST_FLAG (LOCKFLAG, element)
321 && ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
322 || PCB->InvisibleObjectsOn))
324 if (BOX_IN_BOX
325 (&ELEMENT_TEXT (PCB, element).BoundingBox, Box)
326 && !TEST_FLAG (LOCKFLAG, &ELEMENT_TEXT (PCB, element))
327 && TEST_FLAG (SELECTEDFLAG,
328 &ELEMENT_TEXT (PCB, element)) != Flag)
330 /* select all names of element */
331 ELEMENTTEXT_LOOP (element);
333 AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
334 element, text, text);
335 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
337 END_LOOP;
338 if (PCB->ElementOn)
339 DrawElementName (element);
340 changed = true;
342 if ((PCB->PinOn || !Flag) && ELEMENT_IN_BOX (element, Box))
343 if (TEST_FLAG (SELECTEDFLAG, element) != Flag)
345 AddObjectToFlagUndoList (ELEMENT_TYPE,
346 element, element, element);
347 ASSIGN_FLAG (SELECTEDFLAG, Flag, element);
348 PIN_LOOP (element);
350 if (TEST_FLAG (SELECTEDFLAG, pin) != Flag)
352 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
353 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
354 if (PCB->PinOn)
355 DrawPin (pin);
356 changed = true;
359 END_LOOP;
360 PAD_LOOP (element);
362 if (TEST_FLAG (SELECTEDFLAG, pad) != Flag)
364 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
365 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
366 if (PCB->PinOn)
367 DrawPad (pad);
368 changed = true;
371 END_LOOP;
372 if (PCB->PinOn)
373 DrawElement (element);
374 changed = true;
375 gotElement = true;
378 if ((PCB->PinOn || !Flag) && !TEST_FLAG (LOCKFLAG, element) && !gotElement)
380 PIN_LOOP (element);
382 if ((VIA_OR_PIN_IN_BOX (pin, Box)
383 && TEST_FLAG (SELECTEDFLAG, pin) != Flag))
385 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
386 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
387 if (PCB->PinOn)
388 DrawPin (pin);
389 changed = true;
392 END_LOOP;
393 PAD_LOOP (element);
395 if (PAD_IN_BOX (pad, Box)
396 && TEST_FLAG (SELECTEDFLAG, pad) != Flag
397 && (TEST_FLAG (ONSOLDERFLAG, pad) == SWAP_IDENT
398 || PCB->InvisibleObjectsOn
399 || !Flag))
401 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
402 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
403 if (PCB->PinOn)
404 DrawPad (pad);
405 changed = true;
408 END_LOOP;
412 END_LOOP;
413 /* end with vias */
414 if (PCB->ViaOn || !Flag)
415 VIA_LOOP (PCB->Data);
417 if (VIA_OR_PIN_IN_BOX (via, Box)
418 && !TEST_FLAG (LOCKFLAG, via)
419 && TEST_FLAG (SELECTEDFLAG, via) != Flag)
421 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
422 ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
423 if (PCB->ViaOn)
424 DrawVia (via);
425 changed = true;
428 END_LOOP;
429 if (changed)
431 Draw ();
432 IncrementUndoSerialNumber ();
434 return (changed);
437 /* ----------------------------------------------------------------------
438 * performs several operations on the passed object
440 void *
441 ObjectOperation (ObjectFunctionType *F,
442 int Type, void *Ptr1, void *Ptr2, void *Ptr3)
444 switch (Type)
446 case LINE_TYPE:
447 if (F->Line)
448 return (F->Line ((LayerType *) Ptr1, (LineType *) Ptr2));
449 break;
451 case ARC_TYPE:
452 if (F->Arc)
453 return (F->Arc ((LayerType *) Ptr1, (ArcType *) Ptr2));
454 break;
456 case LINEPOINT_TYPE:
457 if (F->LinePoint)
458 return (F->LinePoint ((LayerType *) Ptr1, (LineType *) Ptr2,
459 (PointType *) Ptr3));
460 break;
462 case TEXT_TYPE:
463 if (F->Text)
464 return (F->Text ((LayerType *) Ptr1, (TextType *) Ptr2));
465 break;
467 case POLYGON_TYPE:
468 if (F->Polygon)
469 return (F->Polygon ((LayerType *) Ptr1, (PolygonType *) Ptr2));
470 break;
472 case POLYGONPOINT_TYPE:
473 if (F->Point)
474 return (F->Point ((LayerType *) Ptr1, (PolygonType *) Ptr2,
475 (PointType *) Ptr3));
476 break;
478 case VIA_TYPE:
479 if (F->Via)
480 return (F->Via ((PinType *) Ptr1));
481 break;
483 case ELEMENT_TYPE:
484 if (F->Element)
485 return (F->Element ((ElementType *) Ptr1));
486 break;
488 case PIN_TYPE:
489 if (F->Pin)
490 return (F->Pin ((ElementType *) Ptr1, (PinType *) Ptr2));
491 break;
493 case PAD_TYPE:
494 if (F->Pad)
495 return (F->Pad ((ElementType *) Ptr1, (PadType *) Ptr2));
496 break;
498 case ELEMENTNAME_TYPE:
499 if (F->ElementName)
500 return (F->ElementName ((ElementType *) Ptr1));
501 break;
503 case RATLINE_TYPE:
504 if (F->Rat)
505 return (F->Rat ((RatType *) Ptr1));
506 break;
508 return (NULL);
511 /* ----------------------------------------------------------------------
512 * performs several operations on selected objects which are also visible
513 * The lowlevel procedures are passed together with additional information
514 * resets the selected flag if requested
515 * returns true if anything has changed
517 bool
518 SelectedOperation (ObjectFunctionType *F, bool Reset, int type)
520 bool changed = false;
522 /* check lines */
523 if (type & LINE_TYPE && F->Line)
524 VISIBLELINE_LOOP (PCB->Data);
526 if (TEST_FLAG (SELECTEDFLAG, line))
528 if (Reset)
530 AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
531 CLEAR_FLAG (SELECTEDFLAG, line);
533 F->Line (layer, line);
534 changed = true;
537 ENDALL_LOOP;
539 /* check arcs */
540 if (type & ARC_TYPE && F->Arc)
541 VISIBLEARC_LOOP (PCB->Data);
543 if (TEST_FLAG (SELECTEDFLAG, arc))
545 if (Reset)
547 AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
548 CLEAR_FLAG (SELECTEDFLAG, arc);
550 F->Arc (layer, arc);
551 changed = true;
554 ENDALL_LOOP;
556 /* check text */
557 if (type & TEXT_TYPE && F->Text)
558 ALLTEXT_LOOP (PCB->Data);
560 if (TEST_FLAG (SELECTEDFLAG, text) && TEXT_IS_VISIBLE (PCB, layer, text))
562 if (Reset)
564 AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
565 CLEAR_FLAG (SELECTEDFLAG, text);
567 F->Text (layer, text);
568 changed = true;
571 ENDALL_LOOP;
573 /* check polygons */
574 if (type & POLYGON_TYPE && F->Polygon)
575 VISIBLEPOLYGON_LOOP (PCB->Data);
577 if (TEST_FLAG (SELECTEDFLAG, polygon))
579 if (Reset)
581 AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
582 CLEAR_FLAG (SELECTEDFLAG, polygon);
584 F->Polygon (layer, polygon);
585 changed = true;
588 ENDALL_LOOP;
590 /* elements silkscreen */
591 if (type & ELEMENT_TYPE && PCB->ElementOn && F->Element)
592 ELEMENT_LOOP (PCB->Data);
594 if (TEST_FLAG (SELECTEDFLAG, element))
596 if (Reset)
598 AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
599 CLEAR_FLAG (SELECTEDFLAG, element);
601 F->Element (element);
602 changed = true;
605 END_LOOP;
606 if (type & ELEMENTNAME_TYPE && PCB->ElementOn && F->ElementName)
607 ELEMENT_LOOP (PCB->Data);
609 if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element)))
611 if (Reset)
613 AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
614 element,
615 &ELEMENT_TEXT (PCB, element),
616 &ELEMENT_TEXT (PCB, element));
617 CLEAR_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element));
619 F->ElementName (element);
620 changed = true;
623 END_LOOP;
625 if (type & PIN_TYPE && PCB->PinOn && F->Pin)
626 ELEMENT_LOOP (PCB->Data);
628 PIN_LOOP (element);
630 if (TEST_FLAG (SELECTEDFLAG, pin))
632 if (Reset)
634 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
635 CLEAR_FLAG (SELECTEDFLAG, pin);
637 F->Pin (element, pin);
638 changed = true;
641 END_LOOP;
643 END_LOOP;
645 if (type & PAD_TYPE && PCB->PinOn && F->Pad)
646 ELEMENT_LOOP (PCB->Data);
648 PAD_LOOP (element);
650 if (TEST_FLAG (SELECTEDFLAG, pad))
652 if (Reset)
654 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
655 CLEAR_FLAG (SELECTEDFLAG, pad);
657 F->Pad (element, pad);
658 changed = true;
661 END_LOOP;
663 END_LOOP;
665 /* process vias */
666 if (type & VIA_TYPE && PCB->ViaOn && F->Via)
667 VIA_LOOP (PCB->Data);
669 if (TEST_FLAG (SELECTEDFLAG, via))
671 if (Reset)
673 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
674 CLEAR_FLAG (SELECTEDFLAG, via);
676 F->Via (via);
677 changed = true;
680 END_LOOP;
681 /* and rat-lines */
682 if (type & RATLINE_TYPE && PCB->RatOn && F->Rat)
683 RAT_LOOP (PCB->Data);
685 if (TEST_FLAG (SELECTEDFLAG, line))
687 if (Reset)
689 AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
690 CLEAR_FLAG (SELECTEDFLAG, line);
692 F->Rat (line);
693 changed = true;
696 END_LOOP;
697 if (Reset && changed)
698 IncrementUndoSerialNumber ();
699 return (changed);
702 /* ----------------------------------------------------------------------
703 * selects/unselects all objects which were found during a connection scan
704 * Flag determines if they are to be selected or unselected
705 * returns true if the state of any object has changed
707 * text objects and elements cannot be selected by this routine
709 bool
710 SelectConnection (bool Flag)
712 bool changed = false;
714 if (PCB->RatOn)
715 RAT_LOOP (PCB->Data);
717 if (TEST_FLAG (FOUNDFLAG, line))
719 AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
720 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
721 DrawRat (line);
722 changed = true;
725 END_LOOP;
727 VISIBLELINE_LOOP (PCB->Data);
729 if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
731 AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
732 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
733 DrawLine (layer, line);
734 changed = true;
737 ENDALL_LOOP;
738 VISIBLEARC_LOOP (PCB->Data);
740 if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc))
742 AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
743 ASSIGN_FLAG (SELECTEDFLAG, Flag, arc);
744 DrawArc (layer, arc);
745 changed = true;
748 ENDALL_LOOP;
749 VISIBLEPOLYGON_LOOP (PCB->Data);
751 if (TEST_FLAG (FOUNDFLAG, polygon) && !TEST_FLAG (LOCKFLAG, polygon))
753 AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
754 ASSIGN_FLAG (SELECTEDFLAG, Flag, polygon);
755 DrawPolygon (layer, polygon);
756 changed = true;
759 ENDALL_LOOP;
761 if (PCB->PinOn && PCB->ElementOn)
763 ALLPIN_LOOP (PCB->Data);
765 if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (FOUNDFLAG, pin))
767 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
768 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
769 DrawPin (pin);
770 changed = true;
773 ENDALL_LOOP;
774 ALLPAD_LOOP (PCB->Data);
776 if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (FOUNDFLAG, pad))
778 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
779 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
780 DrawPad (pad);
781 changed = true;
784 ENDALL_LOOP;
787 if (PCB->ViaOn)
788 VIA_LOOP (PCB->Data);
790 if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
792 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
793 ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
794 DrawVia (via);
795 changed = true;
798 END_LOOP;
799 return (changed);
802 #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP)
803 /* ---------------------------------------------------------------------------
804 * selects objects as defined by Type by name;
805 * it's a case insensitive match
806 * returns true if any object has been selected
809 #if defined (HAVE_REGCOMP)
810 static int
811 regexec_match_all (const regex_t *preg, const char *string)
813 regmatch_t match;
815 if (regexec (preg, string, 1, &match, 0) != 0)
816 return 0;
817 if (match.rm_so != 0)
818 return 0;
819 if (match.rm_eo != strlen(string))
820 return 0;
821 return 1;
823 #endif
825 bool
826 SelectObjectByName (int Type, char *Pattern, bool Flag)
828 bool changed = false;
830 #if defined(HAVE_REGCOMP)
831 #define REGEXEC(arg) (regexec_match_all(&compiled, (arg)))
833 int result;
834 regex_t compiled;
836 /* compile the regular expression */
837 result = regcomp (&compiled, Pattern, REG_EXTENDED | REG_ICASE);
838 if (result)
840 char errorstring[128];
842 regerror (result, &compiled, errorstring, 128);
843 Message (_("regexp error: %s\n"), errorstring);
844 regfree (&compiled);
845 return (false);
847 #else
848 #define REGEXEC(arg) (re_exec((arg)) == 1)
850 char *compiled;
852 /* compile the regular expression */
853 if ((compiled = re_comp (Pattern)) != NULL)
855 Message (_("re_comp error: %s\n"), compiled);
856 return (false);
858 #endif
860 /* loop over all visible objects with names */
861 if (Type & TEXT_TYPE)
862 ALLTEXT_LOOP (PCB->Data);
864 if (!TEST_FLAG (LOCKFLAG, text)
865 && TEXT_IS_VISIBLE (PCB, layer, text)
866 && text->TextString
867 && REGEXEC (text->TextString)
868 && TEST_FLAG (SELECTEDFLAG, text) != Flag)
870 AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
871 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
872 DrawText (layer, text);
873 changed = true;
876 ENDALL_LOOP;
878 if (PCB->ElementOn && (Type & ELEMENT_TYPE))
879 ELEMENT_LOOP (PCB->Data);
881 if (!TEST_FLAG (LOCKFLAG, element)
882 && ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
883 || PCB->InvisibleObjectsOn)
884 && TEST_FLAG (SELECTEDFLAG, element) != Flag)
886 String name = ELEMENT_NAME (PCB, element);
887 if (name && REGEXEC (name))
889 AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
890 ASSIGN_FLAG (SELECTEDFLAG, Flag, element);
891 PIN_LOOP (element);
893 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
894 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
896 END_LOOP;
897 PAD_LOOP (element);
899 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
900 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
902 END_LOOP;
903 ELEMENTTEXT_LOOP (element);
905 AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
906 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
908 END_LOOP;
909 DrawElementName (element);
910 DrawElement (element);
911 changed = true;
915 END_LOOP;
916 if (PCB->PinOn && (Type & PIN_TYPE))
917 ALLPIN_LOOP (PCB->Data);
919 if (!TEST_FLAG (LOCKFLAG, element)
920 && pin->Name && REGEXEC (pin->Name)
921 && TEST_FLAG (SELECTEDFLAG, pin) != Flag)
923 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
924 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
925 DrawPin (pin);
926 changed = true;
929 ENDALL_LOOP;
930 if (PCB->PinOn && (Type & PAD_TYPE))
931 ALLPAD_LOOP (PCB->Data);
933 if (!TEST_FLAG (LOCKFLAG, element)
934 && ((TEST_FLAG (ONSOLDERFLAG, pad) != 0) == SWAP_IDENT
935 || PCB->InvisibleObjectsOn)
936 && TEST_FLAG (SELECTEDFLAG, pad) != Flag)
937 if (pad->Name && REGEXEC (pad->Name))
939 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
940 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
941 DrawPad (pad);
942 changed = true;
945 ENDALL_LOOP;
946 if (PCB->ViaOn && (Type & VIA_TYPE))
947 VIA_LOOP (PCB->Data);
949 if (!TEST_FLAG (LOCKFLAG, via)
950 && via->Name
951 && REGEXEC (via->Name) && TEST_FLAG (SELECTEDFLAG, via) != Flag)
953 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
954 ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
955 DrawVia (via);
956 changed = true;
959 END_LOOP;
960 if (Type & NET_TYPE)
962 SaveFindFlag (FOUNDFLAG);
963 InitConnectionLookup ();
964 changed = ResetConnections (true) || changed;
966 MENU_LOOP (&PCB->NetlistLib);
968 Cardinal i;
969 LibraryEntryType *entry;
970 ConnectionType conn;
972 /* Name[0] and Name[1] are special purpose, not the actual name*/
973 if (menu->Name && menu->Name[0] != '\0' && menu->Name[1] != '\0' &&
974 REGEXEC (menu->Name + 2))
976 for (i = menu->EntryN, entry = menu->Entry; i; i--, entry++)
977 if (SeekPad (entry, &conn, false))
978 RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2,
979 true, true);
982 END_LOOP;
984 changed = SelectConnection (Flag) || changed;
985 changed = ResetConnections (false) || changed;
986 FreeConnectionLookupMemory ();
987 RestoreFindFlag ();
990 #if defined(HAVE_REGCOMP)
991 #if !defined(sgi)
992 regfree (&compiled);
993 #endif
994 #endif
996 if (changed)
998 IncrementUndoSerialNumber ();
999 Draw ();
1001 return (changed);
1003 #endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */