pcb 4.1.1
An interactive printed circuit board layout editor.

select.c

Go to the documentation of this file.
00001 
00036 #ifdef HAVE_CONFIG_H
00037 #include "config.h"
00038 #endif
00039 
00040 #include "global.h"
00041 
00042 #include "data.h"
00043 #include "draw.h"
00044 #include "error.h"
00045 #include "search.h"
00046 #include "select.h"
00047 #include "undo.h"
00048 #include "rats.h"
00049 #include "misc.h"
00050 #include "find.h"
00051 
00052 #include <sys/types.h>
00053 #ifdef HAVE_REGEX_H
00054 #include <regex.h>
00055 #else
00056 #ifdef HAVE_UNISTD_H
00057 #include <unistd.h>
00058 #endif
00059 #endif
00060 
00061 #ifdef HAVE_LIBDMALLOC
00062 #include <dmalloc.h>
00063 #endif
00064 
00070 bool
00071 SelectObject (void)
00072 {
00073   void *ptr1, *ptr2, *ptr3;
00074   LayerType *layer;
00075   int type;
00076 
00077   bool changed = true;
00078 
00079   type = SearchScreen (Crosshair.X, Crosshair.Y, SELECT_TYPES,
00080                        &ptr1, &ptr2, &ptr3);
00081   if (type == NO_TYPE || TEST_FLAG (LOCKFLAG, (PinType *) ptr2))
00082     return (false);
00083   switch (type)
00084     {
00085     case VIA_TYPE:
00086       AddObjectToFlagUndoList (VIA_TYPE, ptr1, ptr1, ptr1);
00087       TOGGLE_FLAG (SELECTEDFLAG, (PinType *) ptr1);
00088       DrawVia ((PinType *) ptr1);
00089       break;
00090 
00091     case LINE_TYPE:
00092       {
00093         LineType *line = (LineType *) ptr2;
00094 
00095         layer = (LayerType *) ptr1;
00096         AddObjectToFlagUndoList (LINE_TYPE, ptr1, ptr2, ptr2);
00097         TOGGLE_FLAG (SELECTEDFLAG, line);
00098         DrawLine (layer, line);
00099         break;
00100       }
00101 
00102     case RATLINE_TYPE:
00103       {
00104         RatType *rat = (RatType *) ptr2;
00105 
00106         AddObjectToFlagUndoList (RATLINE_TYPE, ptr1, ptr1, ptr1);
00107         TOGGLE_FLAG (SELECTEDFLAG, rat);
00108         DrawRat (rat);
00109         break;
00110       }
00111 
00112     case ARC_TYPE:
00113       {
00114         ArcType *arc = (ArcType *) ptr2;
00115 
00116         layer = (LayerType *) ptr1;
00117         AddObjectToFlagUndoList (ARC_TYPE, ptr1, ptr2, ptr2);
00118         TOGGLE_FLAG (SELECTEDFLAG, arc);
00119         DrawArc (layer, arc);
00120         break;
00121       }
00122 
00123     case TEXT_TYPE:
00124       {
00125         TextType *text = (TextType *) ptr2;
00126 
00127         layer = (LayerType *) ptr1;
00128         AddObjectToFlagUndoList (TEXT_TYPE, ptr1, ptr2, ptr2);
00129         TOGGLE_FLAG (SELECTEDFLAG, text);
00130         DrawText (layer, text);
00131         break;
00132       }
00133 
00134     case POLYGON_TYPE:
00135       {
00136         PolygonType *poly = (PolygonType *) ptr2;
00137 
00138         layer = (LayerType *) ptr1;
00139         AddObjectToFlagUndoList (POLYGON_TYPE, ptr1, ptr2, ptr2);
00140         TOGGLE_FLAG (SELECTEDFLAG, poly);
00141         DrawPolygon (layer, poly);
00142         /* changing memory order no longer effects draw order */
00143         break;
00144       }
00145 
00146     case PIN_TYPE:
00147       AddObjectToFlagUndoList (PIN_TYPE, ptr1, ptr2, ptr2);
00148       TOGGLE_FLAG (SELECTEDFLAG, (PinType *) ptr2);
00149       DrawPin ((PinType *) ptr2);
00150       break;
00151 
00152     case PAD_TYPE:
00153       AddObjectToFlagUndoList (PAD_TYPE, ptr1, ptr2, ptr2);
00154       TOGGLE_FLAG (SELECTEDFLAG, (PadType *) ptr2);
00155       DrawPad ((PadType *) ptr2);
00156       break;
00157 
00158     case ELEMENTNAME_TYPE:
00159       {
00160         ElementType *element = (ElementType *) ptr1;
00161 
00162         /* select all names of the element */
00163         ELEMENTTEXT_LOOP (element);
00164         {
00165           AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
00166           TOGGLE_FLAG (SELECTEDFLAG, text);
00167         }
00168         END_LOOP;
00169         DrawElementName (element);
00170         break;
00171       }
00172 
00173     case ELEMENT_TYPE:
00174       {
00175         ElementType *element = (ElementType *) ptr1;
00176 
00177         /* select all pins and names of the element */
00178         PIN_LOOP (element);
00179         {
00180           AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
00181           TOGGLE_FLAG (SELECTEDFLAG, pin);
00182         }
00183         END_LOOP;
00184         PAD_LOOP (element);
00185         {
00186           AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
00187           TOGGLE_FLAG (SELECTEDFLAG, pad);
00188         }
00189         END_LOOP;
00190         ELEMENTTEXT_LOOP (element);
00191         {
00192           AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
00193           TOGGLE_FLAG (SELECTEDFLAG, text);
00194         }
00195         END_LOOP;
00196         AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
00197         TOGGLE_FLAG (SELECTEDFLAG, element);
00198         if (PCB->ElementOn &&
00199             ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT ||
00200              PCB->InvisibleObjectsOn))
00201           if (PCB->ElementOn)
00202             {
00203               DrawElementName (element);
00204               DrawElementPackage (element);
00205             }
00206         if (PCB->PinOn)
00207           DrawElementPinsAndPads (element);
00208         break;
00209       }
00210     }
00211   Draw ();
00212   IncrementUndoSerialNumber ();
00213   return (changed);
00214 }
00215 
00223 bool
00224 SelectBlock (BoxType *Box, bool select)
00225 {
00226   bool changed = false;
00227 
00228   if (PCB->RatOn || !select)
00229     RAT_LOOP (PCB->Data);
00230   {
00231     if (LINE_IN_BOX ((LineType *) line, Box) &&
00232         !TEST_FLAG (LOCKFLAG, line) && TEST_FLAG (SELECTEDFLAG, line) != select)
00233       {
00234         AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
00235         ASSIGN_FLAG (SELECTEDFLAG, select, line);
00236         if (PCB->RatOn)
00237           DrawRat (line);
00238         changed = true;
00239       }
00240   }
00241   END_LOOP;
00242 
00243   /* check layers */
00244   LAYER_LOOP(PCB->Data, max_copper_layer + SILK_LAYER);
00245   {
00246     if (layer == & PCB->Data->SILKLAYER)
00247       {
00248         if (! (PCB->ElementOn || !select))
00249           continue;
00250       }
00251     else if (layer == & PCB->Data->BACKSILKLAYER)
00252       {
00253         if (! (PCB->InvisibleObjectsOn || !select))
00254           continue;
00255       }
00256     else
00257       if (! (layer->On || !select))
00258         continue;
00259 
00260     LINE_LOOP (layer);
00261     {
00262       if (LINE_IN_BOX (line, Box)
00263           && !TEST_FLAG (LOCKFLAG, line)
00264           && TEST_FLAG (SELECTEDFLAG, line) != select)
00265         {
00266           AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
00267           ASSIGN_FLAG (SELECTEDFLAG, select, line);
00268           if (layer->On)
00269             DrawLine (layer, line);
00270           changed = true;
00271         }
00272     }
00273     END_LOOP;
00274     ARC_LOOP (layer);
00275     {
00276       if (ARC_IN_BOX (arc, Box)
00277           && !TEST_FLAG (LOCKFLAG, arc)
00278           && TEST_FLAG (SELECTEDFLAG, arc) != select)
00279         {
00280           AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
00281           ASSIGN_FLAG (SELECTEDFLAG, select, arc);
00282           if (layer->On)
00283             DrawArc (layer, arc);
00284           changed = true;
00285         }
00286     }
00287     END_LOOP;
00288     TEXT_LOOP (layer);
00289     {
00290       if (!select || TEXT_IS_VISIBLE(PCB, layer, text))
00291         {
00292           if (TEXT_IN_BOX (text, Box)
00293               && !TEST_FLAG (LOCKFLAG, text)
00294               && TEST_FLAG (SELECTEDFLAG, text) != select)
00295             {
00296               AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
00297               ASSIGN_FLAG (SELECTEDFLAG, select, text);
00298               if (TEXT_IS_VISIBLE(PCB, layer, text))
00299                 DrawText (layer, text);
00300               changed = true;
00301             }
00302         }
00303     }
00304     END_LOOP;
00305     POLYGON_LOOP (layer);
00306     {
00307       if (POLYGON_IN_BOX (polygon, Box)
00308           && !TEST_FLAG (LOCKFLAG, polygon)
00309           && TEST_FLAG (SELECTEDFLAG, polygon) != select)
00310         {
00311           AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
00312           ASSIGN_FLAG (SELECTEDFLAG, select, polygon);
00313           if (layer->On)
00314             DrawPolygon (layer, polygon);
00315           changed = true;
00316         }
00317     }
00318     END_LOOP;
00319   }
00320   END_LOOP;
00321 
00322   /* elements */
00323   ELEMENT_LOOP (PCB->Data);
00324   {
00325     {
00326       bool gotElement = false;
00327       if ((PCB->ElementOn || !select)
00328           && !TEST_FLAG (LOCKFLAG, element)
00329           && ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
00330               || PCB->InvisibleObjectsOn))
00331         {
00332           if (BOX_IN_BOX
00333               (&ELEMENT_TEXT (PCB, element).BoundingBox, Box)
00334               && !TEST_FLAG (LOCKFLAG, &ELEMENT_TEXT (PCB, element))
00335               && TEST_FLAG (SELECTEDFLAG,
00336                             &ELEMENT_TEXT (PCB, element)) != select)
00337             {
00338               /* select all names of element */
00339               ELEMENTTEXT_LOOP (element);
00340               {
00341                 AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
00342                                          element, text, text);
00343                 ASSIGN_FLAG (SELECTEDFLAG, select, text);
00344               }
00345               END_LOOP;
00346               if (PCB->ElementOn)
00347                 DrawElementName (element);
00348               changed = true;
00349             }
00350           if ((PCB->PinOn || !select) && ELEMENT_IN_BOX (element, Box))
00351             if (TEST_FLAG (SELECTEDFLAG, element) != select)
00352               {
00353                 AddObjectToFlagUndoList (ELEMENT_TYPE,
00354                                          element, element, element);
00355                 ASSIGN_FLAG (SELECTEDFLAG, select, element);
00356                 PIN_LOOP (element);
00357                 {
00358                   if (TEST_FLAG (SELECTEDFLAG, pin) != select)
00359                     {
00360                       AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
00361                       ASSIGN_FLAG (SELECTEDFLAG, select, pin);
00362                       if (PCB->PinOn)
00363                         DrawPin (pin);
00364                       changed = true;
00365                     }
00366                 }
00367                 END_LOOP;
00368                 PAD_LOOP (element);
00369                 {
00370                   if (TEST_FLAG (SELECTEDFLAG, pad) != select)
00371                     {
00372                       AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
00373                       ASSIGN_FLAG (SELECTEDFLAG, select, pad);
00374                       if (PCB->PinOn)
00375                         DrawPad (pad);
00376                       changed = true;
00377                     }
00378                 }
00379                 END_LOOP;
00380                 if (PCB->PinOn)
00381                   DrawElement (element);
00382                 changed = true;
00383                 gotElement = true;
00384               }
00385         }
00386       if ((PCB->PinOn || !select) && !TEST_FLAG (LOCKFLAG, element) && !gotElement)
00387         {
00388           PIN_LOOP (element);
00389           {
00390             if ((VIA_OR_PIN_IN_BOX (pin, Box)
00391                  && TEST_FLAG (SELECTEDFLAG, pin) != select))
00392               {
00393                 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
00394                 ASSIGN_FLAG (SELECTEDFLAG, select, pin);
00395                 if (PCB->PinOn)
00396                   DrawPin (pin);
00397                 changed = true;
00398               }
00399           }
00400           END_LOOP;
00401           PAD_LOOP (element);
00402           {
00403             if (PAD_IN_BOX (pad, Box)
00404                 && TEST_FLAG (SELECTEDFLAG, pad) != select
00405                 && (TEST_FLAG (ONSOLDERFLAG, pad) == SWAP_IDENT
00406                     || PCB->InvisibleObjectsOn
00407                     || !select))
00408               {
00409                 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
00410                 ASSIGN_FLAG (SELECTEDFLAG, select, pad);
00411                 if (PCB->PinOn)
00412                   DrawPad (pad);
00413                 changed = true;
00414               }
00415           }
00416           END_LOOP;
00417         }
00418     }
00419   }
00420   END_LOOP;
00421   /* end with vias */
00422   if (PCB->ViaOn || !select)
00423     VIA_LOOP (PCB->Data);
00424   {
00425     if (VIA_OR_PIN_IN_BOX (via, Box)
00426         && !TEST_FLAG (LOCKFLAG, via)
00427         && TEST_FLAG (SELECTEDFLAG, via) != select)
00428       {
00429         AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
00430         ASSIGN_FLAG (SELECTEDFLAG, select, via);
00431         if (PCB->ViaOn)
00432           DrawVia (via);
00433         changed = true;
00434       }
00435   }
00436   END_LOOP;
00437   if (changed)
00438     {
00439       Draw ();
00440       IncrementUndoSerialNumber ();
00441     }
00442   return (changed);
00443 }
00444 
00448 void *
00449 ObjectOperation (ObjectFunctionType *F,
00450                  int Type, void *Ptr1, void *Ptr2, void *Ptr3)
00451 {
00452   switch (Type)
00453     {
00454     case LINE_TYPE:
00455       if (F->Line)
00456         return (F->Line ((LayerType *) Ptr1, (LineType *) Ptr2));
00457       break;
00458 
00459     case ARC_TYPE:
00460       if (F->Arc)
00461         return (F->Arc ((LayerType *) Ptr1, (ArcType *) Ptr2));
00462       break;
00463 
00464     case LINEPOINT_TYPE:
00465       if (F->LinePoint)
00466         return (F->LinePoint ((LayerType *) Ptr1, (LineType *) Ptr2,
00467                               (PointType *) Ptr3));
00468       break;
00469 
00470     case TEXT_TYPE:
00471       if (F->Text)
00472         return (F->Text ((LayerType *) Ptr1, (TextType *) Ptr2));
00473       break;
00474 
00475     case POLYGON_TYPE:
00476       if (F->Polygon)
00477         return (F->Polygon ((LayerType *) Ptr1, (PolygonType *) Ptr2));
00478       break;
00479 
00480     case POLYGONPOINT_TYPE:
00481       if (F->Point)
00482         return (F->Point ((LayerType *) Ptr1, (PolygonType *) Ptr2,
00483                           (PointType *) Ptr3));
00484       break;
00485 
00486     case VIA_TYPE:
00487       if (F->Via)
00488         return (F->Via ((PinType *) Ptr1));
00489       break;
00490 
00491     case ELEMENT_TYPE:
00492       if (F->Element)
00493         return (F->Element ((ElementType *) Ptr1));
00494       break;
00495 
00496     case PIN_TYPE:
00497       if (F->Pin)
00498         return (F->Pin ((ElementType *) Ptr1, (PinType *) Ptr2));
00499       break;
00500 
00501     case PAD_TYPE:
00502       if (F->Pad)
00503         return (F->Pad ((ElementType *) Ptr1, (PadType *) Ptr2));
00504       break;
00505 
00506     case ELEMENTNAME_TYPE:
00507       if (F->ElementName)
00508         return (F->ElementName ((ElementType *) Ptr1));
00509       break;
00510 
00511     case RATLINE_TYPE:
00512       if (F->Rat)
00513         return (F->Rat ((RatType *) Ptr1));
00514       break;
00515     }
00516   return (NULL);
00517 }
00518 
00530 bool
00531 SelectedOperation (ObjectFunctionType *F, bool Reset, int type)
00532 {
00533   bool changed = false;
00534 
00535   /* check lines */
00536   if (type & LINE_TYPE && F->Line)
00537     VISIBLELINE_LOOP (PCB->Data);
00538   {
00539     if (TEST_FLAG (SELECTEDFLAG, line))
00540       {
00541         if (Reset)
00542           {
00543             AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
00544             CLEAR_FLAG (SELECTEDFLAG, line);
00545           }
00546         F->Line (layer, line);
00547         changed = true;
00548       }
00549   }
00550   ENDALL_LOOP;
00551 
00552   /* check arcs */
00553   if (type & ARC_TYPE && F->Arc)
00554     VISIBLEARC_LOOP (PCB->Data);
00555   {
00556     if (TEST_FLAG (SELECTEDFLAG, arc))
00557       {
00558         if (Reset)
00559           {
00560             AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
00561             CLEAR_FLAG (SELECTEDFLAG, arc);
00562           }
00563         F->Arc (layer, arc);
00564         changed = true;
00565       }
00566   }
00567   ENDALL_LOOP;
00568 
00569   /* check text */
00570   if (type & TEXT_TYPE && F->Text)
00571     ALLTEXT_LOOP (PCB->Data);
00572   {
00573     if (TEST_FLAG (SELECTEDFLAG, text) && TEXT_IS_VISIBLE (PCB, layer, text))
00574       {
00575         if (Reset)
00576           {
00577             AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
00578             CLEAR_FLAG (SELECTEDFLAG, text);
00579           }
00580         F->Text (layer, text);
00581         changed = true;
00582       }
00583   }
00584   ENDALL_LOOP;
00585 
00586   /* check polygons */
00587   if (type & POLYGON_TYPE && F->Polygon)
00588     VISIBLEPOLYGON_LOOP (PCB->Data);
00589   {
00590     if (TEST_FLAG (SELECTEDFLAG, polygon))
00591       {
00592         if (Reset)
00593           {
00594             AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
00595             CLEAR_FLAG (SELECTEDFLAG, polygon);
00596           }
00597         F->Polygon (layer, polygon);
00598         changed = true;
00599       }
00600   }
00601   ENDALL_LOOP;
00602 
00603   /* elements silkscreen */
00604   if (type & ELEMENT_TYPE && PCB->ElementOn && F->Element)
00605     ELEMENT_LOOP (PCB->Data);
00606   {
00607     if (TEST_FLAG (SELECTEDFLAG, element))
00608       {
00609         if (Reset)
00610           {
00611             AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
00612             CLEAR_FLAG (SELECTEDFLAG, element);
00613           }
00614         F->Element (element);
00615         changed = true;
00616       }
00617   }
00618   END_LOOP;
00619   if (type & ELEMENTNAME_TYPE && PCB->ElementOn && F->ElementName)
00620     ELEMENT_LOOP (PCB->Data);
00621   {
00622     if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element)))
00623       {
00624         if (Reset)
00625           {
00626             AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
00627                                      element,
00628                                      &ELEMENT_TEXT (PCB, element),
00629                                      &ELEMENT_TEXT (PCB, element));
00630             CLEAR_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element));
00631           }
00632         F->ElementName (element);
00633         changed = true;
00634       }
00635   }
00636   END_LOOP;
00637 
00638   if (type & PIN_TYPE && PCB->PinOn && F->Pin)
00639     ELEMENT_LOOP (PCB->Data);
00640   {
00641     PIN_LOOP (element);
00642     {
00643       if (TEST_FLAG (SELECTEDFLAG, pin))
00644         {
00645           if (Reset)
00646             {
00647               AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
00648               CLEAR_FLAG (SELECTEDFLAG, pin);
00649             }
00650           F->Pin (element, pin);
00651           changed = true;
00652         }
00653     }
00654     END_LOOP;
00655   }
00656   END_LOOP;
00657 
00658   if (type & PAD_TYPE && PCB->PinOn && F->Pad)
00659     ELEMENT_LOOP (PCB->Data);
00660   {
00661     PAD_LOOP (element);
00662     {
00663       if (TEST_FLAG (SELECTEDFLAG, pad))
00664         {
00665           if (Reset)
00666             {
00667               AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
00668               CLEAR_FLAG (SELECTEDFLAG, pad);
00669             }
00670           F->Pad (element, pad);
00671           changed = true;
00672         }
00673     }
00674     END_LOOP;
00675   }
00676   END_LOOP;
00677 
00678   /* process vias */
00679   if (type & VIA_TYPE && PCB->ViaOn && F->Via)
00680     VIA_LOOP (PCB->Data);
00681   {
00682     if (TEST_FLAG (SELECTEDFLAG, via))
00683       {
00684         if (Reset)
00685           {
00686             AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
00687             CLEAR_FLAG (SELECTEDFLAG, via);
00688           }
00689         F->Via (via);
00690         changed = true;
00691       }
00692   }
00693   END_LOOP;
00694   /* and rat-lines */
00695   if (type & RATLINE_TYPE && PCB->RatOn && F->Rat)
00696     RAT_LOOP (PCB->Data);
00697   {
00698     if (TEST_FLAG (SELECTEDFLAG, line))
00699       {
00700         if (Reset)
00701           {
00702             AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
00703             CLEAR_FLAG (SELECTEDFLAG, line);
00704           }
00705         F->Rat (line);
00706         changed = true;
00707       }
00708   }
00709   END_LOOP;
00710   if (Reset && changed)
00711     IncrementUndoSerialNumber ();
00712   return (changed);
00713 }
00714 
00727 bool
00728 SelectByFlag (int flag, bool select)
00729 {
00730   bool changed = false;
00731 
00732   if (PCB->RatOn)
00733     RAT_LOOP (PCB->Data);
00734   {
00735     if (TEST_FLAG (flag, line))
00736       {
00737         AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
00738         ASSIGN_FLAG (SELECTEDFLAG, select, line);
00739         DrawRat (line);
00740         changed = true;
00741       }
00742   }
00743   END_LOOP;
00744 
00745   VISIBLELINE_LOOP (PCB->Data);
00746   {
00747     if (TEST_FLAG (flag, line) && !TEST_FLAG (LOCKFLAG, line))
00748       {
00749         AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
00750         ASSIGN_FLAG (SELECTEDFLAG, select, line);
00751         DrawLine (layer, line);
00752         changed = true;
00753       }
00754   }
00755   ENDALL_LOOP;
00756   VISIBLEARC_LOOP (PCB->Data);
00757   {
00758     if (TEST_FLAG (flag, arc) && !TEST_FLAG (LOCKFLAG, arc))
00759       {
00760         AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
00761         ASSIGN_FLAG (SELECTEDFLAG, select, arc);
00762         DrawArc (layer, arc);
00763         changed = true;
00764       }
00765   }
00766   ENDALL_LOOP;
00767   VISIBLEPOLYGON_LOOP (PCB->Data);
00768   {
00769     if (TEST_FLAG (flag, polygon) && !TEST_FLAG (LOCKFLAG, polygon))
00770       {
00771         AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
00772         ASSIGN_FLAG (SELECTEDFLAG, select, polygon);
00773         DrawPolygon (layer, polygon);
00774         changed = true;
00775       }
00776   }
00777   ENDALL_LOOP;
00778 
00779   if (PCB->PinOn && PCB->ElementOn)
00780     {
00781       ALLPIN_LOOP (PCB->Data);
00782       {
00783         if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (flag, pin))
00784           {
00785             AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
00786             ASSIGN_FLAG (SELECTEDFLAG, select, pin);
00787             DrawPin (pin);
00788             changed = true;
00789           }
00790       }
00791       ENDALL_LOOP;
00792       ALLPAD_LOOP (PCB->Data);
00793       {
00794         if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (flag, pad))
00795           {
00796             AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
00797             ASSIGN_FLAG (SELECTEDFLAG, select, pad);
00798             DrawPad (pad);
00799             changed = true;
00800           }
00801       }
00802       ENDALL_LOOP;
00803     }
00804 
00805   if (PCB->ViaOn)
00806     VIA_LOOP (PCB->Data);
00807   {
00808     if (TEST_FLAG (flag, via) && !TEST_FLAG (LOCKFLAG, via))
00809       {
00810         AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
00811         ASSIGN_FLAG (SELECTEDFLAG, select, via);
00812         DrawVia (via);
00813         changed = true;
00814       }
00815   }
00816   END_LOOP;
00817   return (changed);
00818 }
00819 
00820 #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP)
00821 
00827 #if defined (HAVE_REGCOMP)
00828 static int
00829 regexec_match_all (const  regex_t  *preg,  const  char  *string)
00830 {
00831   regmatch_t match;
00832 
00833   if (regexec (preg, string, 1, &match, 0) != 0)
00834     return 0;
00835   if (match.rm_so != 0)
00836     return 0;
00837   if (match.rm_eo != strlen(string))
00838     return 0;
00839   return 1;
00840 }
00841 #endif
00842 
00843 bool
00844 SelectObjectByName (int Type, char *Pattern, bool select)
00845 {
00846   bool changed = false;
00847 
00848 #if defined(HAVE_REGCOMP)
00849 #define REGEXEC(arg)    (regexec_match_all(&compiled, (arg)))
00850 
00851   int result;
00852   regex_t compiled;
00853 
00854   /* compile the regular expression */
00855   result = regcomp (&compiled, Pattern, REG_EXTENDED | REG_ICASE);
00856   if (result)
00857     {
00858       char errorstring[128];
00859 
00860       regerror (result, &compiled, errorstring, 128);
00861       Message (_("regexp error: %s\n"), errorstring);
00862       regfree (&compiled);
00863       return (false);
00864     }
00865 #else
00866 #define REGEXEC(arg)    (re_exec((arg)) == 1)
00867 
00868   char *compiled;
00869 
00870   /* compile the regular expression */
00871   if ((compiled = re_comp (Pattern)) != NULL)
00872     {
00873       Message (_("re_comp error: %s\n"), compiled);
00874       return (false);
00875     }
00876 #endif
00877 
00878   /* loop over all visible objects with names */
00879   if (Type & TEXT_TYPE)
00880     ALLTEXT_LOOP (PCB->Data);
00881   {
00882     if (!TEST_FLAG (LOCKFLAG, text)
00883         && TEXT_IS_VISIBLE (PCB, layer, text)
00884         && text->TextString
00885         && REGEXEC (text->TextString)
00886         && TEST_FLAG (SELECTEDFLAG, text) != select)
00887       {
00888         AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
00889         ASSIGN_FLAG (SELECTEDFLAG, select, text);
00890         DrawText (layer, text);
00891         changed = true;
00892       }
00893   }
00894   ENDALL_LOOP;
00895 
00896   if (PCB->ElementOn && (Type & ELEMENT_TYPE))
00897     ELEMENT_LOOP (PCB->Data);
00898   {
00899     if (!TEST_FLAG (LOCKFLAG, element)
00900         && ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
00901             || PCB->InvisibleObjectsOn)
00902         && TEST_FLAG (SELECTEDFLAG, element) != select)
00903       {
00904         String name = ELEMENT_NAME (PCB, element);
00905         if (name && REGEXEC (name))
00906           {
00907             AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
00908             ASSIGN_FLAG (SELECTEDFLAG, select, element);
00909             PIN_LOOP (element);
00910             {
00911               AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
00912               ASSIGN_FLAG (SELECTEDFLAG, select, pin);
00913             }
00914             END_LOOP;
00915             PAD_LOOP (element);
00916             {
00917               AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
00918               ASSIGN_FLAG (SELECTEDFLAG, select, pad);
00919             }
00920             END_LOOP;
00921             ELEMENTTEXT_LOOP (element);
00922             {
00923               AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
00924               ASSIGN_FLAG (SELECTEDFLAG, select, text);
00925             }
00926             END_LOOP;
00927             DrawElementName (element);
00928             DrawElement (element);
00929             changed = true;
00930           }
00931       }
00932   }
00933   END_LOOP;
00934   if (PCB->PinOn && (Type & PIN_TYPE))
00935     ALLPIN_LOOP (PCB->Data);
00936   {
00937     if (!TEST_FLAG (LOCKFLAG, element)
00938         && pin->Name && REGEXEC (pin->Name)
00939         && TEST_FLAG (SELECTEDFLAG, pin) != select)
00940       {
00941         AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
00942         ASSIGN_FLAG (SELECTEDFLAG, select, pin);
00943         DrawPin (pin);
00944         changed = true;
00945       }
00946   }
00947   ENDALL_LOOP;
00948   if (PCB->PinOn && (Type & PAD_TYPE))
00949     ALLPAD_LOOP (PCB->Data);
00950   {
00951     if (!TEST_FLAG (LOCKFLAG, element)
00952         && ((TEST_FLAG (ONSOLDERFLAG, pad) != 0) == SWAP_IDENT
00953             || PCB->InvisibleObjectsOn)
00954         && TEST_FLAG (SELECTEDFLAG, pad) != select)
00955       if (pad->Name && REGEXEC (pad->Name))
00956         {
00957           AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
00958           ASSIGN_FLAG (SELECTEDFLAG, select, pad);
00959           DrawPad (pad);
00960           changed = true;
00961         }
00962   }
00963   ENDALL_LOOP;
00964   if (PCB->ViaOn && (Type & VIA_TYPE))
00965     VIA_LOOP (PCB->Data);
00966   {
00967     if (!TEST_FLAG (LOCKFLAG, via)
00968         && via->Name
00969         && REGEXEC (via->Name) && TEST_FLAG (SELECTEDFLAG, via) != select)
00970       {
00971         AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
00972         ASSIGN_FLAG (SELECTEDFLAG, select, via);
00973         DrawVia (via);
00974         changed = true;
00975       }
00976   }
00977   END_LOOP;
00978   if (Type & NET_TYPE)
00979     {
00980       InitConnectionLookup ();
00981       changed = ClearFlagOnAllObjects (true, FOUNDFLAG) || changed;
00982 
00983       MENU_LOOP (&PCB->NetlistLib);
00984       {
00985         Cardinal i;
00986         LibraryEntryType *entry;
00987         ConnectionType conn;
00988 
00989         /* Name[0] and Name[1] are special purpose, not the actual name*/
00990         if (menu->Name && menu->Name[0] != '\0' && menu->Name[1] != '\0' &&
00991             REGEXEC (menu->Name + 2))
00992           {
00993             for (i = menu->EntryN, entry = menu->Entry; i; i--, entry++)
00994               if (SeekPad (entry, &conn, false))
00995                 RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2,
00996                              true, FOUNDFLAG, true);
00997           }
00998       }
00999       END_LOOP;
01000 
01001       changed = SelectByFlag (FOUNDFLAG, select) || changed;
01002       changed = ClearFlagOnAllObjects (false, FOUNDFLAG) || changed;
01003       FreeConnectionLookupMemory ();
01004     }
01005 
01006 #if defined(HAVE_REGCOMP)
01007 #if !defined(sgi)
01008   regfree (&compiled);
01009 #endif
01010 #endif
01011 
01012   if (changed)
01013     {
01014       IncrementUndoSerialNumber ();
01015       Draw ();
01016     }
01017   return (changed);
01018 }
01019 #endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */
01020 
01026 bool
01027 SelectBuriedVias (bool select)
01028 {
01029   bool changed = false;
01030 
01031   VIA_LOOP (PCB->Data)
01032    if (TEST_FLAG (LOCKFLAG, via))
01033      continue;
01034    if (VIA_IS_BURIED (via))
01035       {
01036         AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
01037         ASSIGN_FLAG (SELECTEDFLAG, select, via);
01038         changed = true;
01039       }
01040   END_LOOP;
01041 
01042   return changed;
01043 }