pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00029 #ifdef HAVE_CONFIG_H 00030 #include "config.h" 00031 #endif 00032 00033 #include <ctype.h> 00034 #include <math.h> 00035 #include <stdio.h> 00036 00037 #ifdef HAVE_STDLIB_H 00038 #include <stdlib.h> 00039 #endif 00040 00041 #ifdef HAVE_STRING_H 00042 #include <string.h> 00043 #endif 00044 00045 #ifdef HAVE_SYS_TYPES_H 00046 #include <sys/types.h> 00047 #endif 00048 00049 #ifdef HAVE_REGEX_H 00050 #include <regex.h> 00051 #else 00052 #ifdef HAVE_UNISTD_H 00053 #include <unistd.h> 00054 #endif 00055 #endif 00056 00057 #include "change.h" 00058 #include "data.h" 00059 #include "draw.h" 00060 #include "error.h" 00061 #include "global.h" 00062 #include "resource.h" 00063 #include "set.h" 00064 #include "undo.h" 00065 #include "vendor.h" 00066 00067 #ifdef HAVE_LIBDMALLOC 00068 #include <dmalloc.h> 00069 #endif 00070 00071 static void add_to_drills (char *); 00072 static void apply_vendor_map (void); 00073 static void process_skips (Resource *); 00074 static bool rematch (const char *, const char *); 00075 00076 /* list of vendor drills and a count of them */ 00077 static int *vendor_drills = NULL; 00078 static int n_vendor_drills = 0; 00079 00080 static int cached_drill = -1; 00081 static int cached_map = -1; 00082 00083 /* lists of elements to ignore */ 00084 static char **ignore_refdes = NULL; 00085 static int n_refdes = 0; 00086 static char **ignore_value = NULL; 00087 static int n_value = 0; 00088 static char **ignore_descr = NULL; 00089 static int n_descr = 0; 00090 00094 static char *vendor_name = NULL; 00095 00099 static double sf; 00100 00101 00105 static bool vendorMapEnable = false; 00106 00107 /* type of drill mapping */ 00108 #define CLOSEST 1 00109 #define ROUND_UP 0 00110 static int rounding_method = ROUND_UP; 00111 00112 #define FREE(x) if((x) != NULL) { free (x) ; (x) = NULL; } 00113 00114 /* ************************************************************ */ 00115 00116 static const char apply_vendor_syntax[] = N_("ApplyVendor()"); 00117 00118 static const char apply_vendor_help[] = 00119 N_("Applies the currently loaded vendor drill table to the current design."); 00120 00121 /* %start-doc actions ApplyVendor 00122 @cindex vendor map 00123 @cindex vendor drill table 00124 @findex ApplyVendor() 00125 00126 This will modify all of your drill holes to match the list of allowed 00127 sizes for your vendor. 00128 %end-doc */ 00129 00130 int 00131 ActionApplyVendor (int argc, char **argv, Coord x, Coord y) 00132 { 00133 hid_action ("Busy"); 00134 apply_vendor_map (); 00135 return 0; 00136 } 00137 00138 /* ************************************************************ */ 00139 00140 static const char toggle_vendor_syntax[] = N_("ToggleVendor()"); 00141 00142 static const char toggle_vendor_help[] = 00143 N_("Toggles the state of automatic drill size mapping."); 00144 00145 /* %start-doc actions ToggleVendor 00146 00147 @cindex vendor map 00148 @cindex vendor drill table 00149 @findex ToggleVendor() 00150 00151 When drill mapping is enabled, new instances of pins and vias will 00152 have their drill holes mapped to one of the allowed drill sizes 00153 specified in the currently loaded vendor drill table. To enable drill 00154 mapping, a vendor resource file containing a drill table must be 00155 loaded first. 00156 00157 %end-doc */ 00158 00159 int 00160 ActionToggleVendor (int argc, char **argv, Coord x, Coord y) 00161 { 00162 if (vendorMapEnable) 00163 vendorMapEnable = false; 00164 else 00165 vendorMapEnable = true; 00166 return 0; 00167 } 00168 00169 /* ************************************************************ */ 00170 00171 static const char enable_vendor_syntax[] = N_("EnableVendor()"); 00172 00173 static const char enable_vendor_help[] = 00174 N_("Enables automatic drill size mapping."); 00175 00176 /* %start-doc actions EnableVendor 00177 00178 @cindex vendor map 00179 @cindex vendor drill table 00180 @findex EnableVendor() 00181 00182 When drill mapping is enabled, new instances of pins and vias will 00183 have their drill holes mapped to one of the allowed drill sizes 00184 specified in the currently loaded vendor drill table. To enable drill 00185 mapping, a vendor resource file containing a drill table must be 00186 loaded first. 00187 00188 %end-doc */ 00189 00190 int 00191 ActionEnableVendor (int argc, char **argv, Coord x, Coord y) 00192 { 00193 vendorMapEnable = true; 00194 return 0; 00195 } 00196 00197 /* ************************************************************ */ 00198 00199 static const char disable_vendor_syntax[] = N_("DisableVendor()"); 00200 00201 static const char disable_vendor_help[] = 00202 N_("Disables automatic drill size mapping."); 00203 00204 /* %start-doc actions DisableVendor 00205 00206 @cindex vendor map 00207 @cindex vendor drill table 00208 @findex DisableVendor() 00209 00210 When drill mapping is enabled, new instances of pins and vias will 00211 have their drill holes mapped to one of the allowed drill sizes 00212 specified in the currently loaded vendor drill table. 00213 00214 %end-doc */ 00215 00216 int 00217 ActionDisableVendor (int argc, char **argv, Coord x, Coord y) 00218 { 00219 vendorMapEnable = false; 00220 return 0; 00221 } 00222 00223 /* ************************************************************ */ 00224 00225 static const char unload_vendor_syntax[] = N_("UnloadVendor()"); 00226 00227 static const char unload_vendor_help[] = 00228 N_("Unloads the current vendor drill mapping table."); 00229 00230 /* %start-doc actions UnloadVendor 00231 00232 @cindex vendor map 00233 @cindex vendor drill table 00234 @findex UnloadVendor() 00235 00236 %end-doc */ 00237 00238 int 00239 ActionUnloadVendor (int argc, char **argv, Coord x, Coord y) 00240 { 00241 cached_drill = -1; 00242 00243 /* Unload any vendor table we may have had */ 00244 n_vendor_drills = 0; 00245 n_refdes = 0; 00246 n_value = 0; 00247 n_descr = 0; 00248 FREE (vendor_drills); 00249 FREE (ignore_refdes); 00250 FREE (ignore_value); 00251 FREE (ignore_descr); 00252 return 0; 00253 } 00254 00255 /* ************************************************************ */ 00256 00257 static const char load_vendor_syntax[] = N_("LoadVendorFrom(filename)"); 00258 00259 static const char load_vendor_help[] = 00260 N_("Loads the specified vendor resource file."); 00261 00262 /* %start-doc actions LoadVendorFrom 00263 00264 @cindex vendor map 00265 @cindex vendor drill table 00266 @findex LoadVendorFrom() 00267 00268 @table @var 00269 @item filename 00270 Name of the vendor resource file. If not specified, the user will 00271 be prompted to enter one. 00272 @end table 00273 00274 %end-doc */ 00275 00276 int 00277 ActionLoadVendorFrom (int argc, char **argv, Coord x, Coord y) 00278 { 00279 int i; 00280 char *fname = NULL; 00281 static char *default_file = NULL; 00282 char *sval; 00283 Resource *res, *drcres, *drlres; 00284 int type; 00285 bool free_fname = false; 00286 00287 cached_drill = -1; 00288 00289 fname = argc ? argv[0] : 0; 00290 00291 if (!fname || !*fname) 00292 { 00293 fname = gui->fileselect (_("Load Vendor Resource File..."), 00294 _("Picks a vendor resource file to load.\n" 00295 "This file can contain drc settings for a\n" 00296 "particular vendor as well as a list of\n" 00297 "predefined drills which are allowed."), 00298 default_file, ".res", "vendor", 00299 HID_FILESELECT_READ); 00300 if (fname == NULL) 00301 AFAIL (load_vendor); 00302 00303 free_fname = true; 00304 00305 free (default_file); 00306 default_file = NULL; 00307 00308 if (fname && *fname) 00309 default_file = strdup (fname); 00310 } 00311 00312 /* Unload any vendor table we may have had */ 00313 n_vendor_drills = 0; 00314 n_refdes = 0; 00315 n_value = 0; 00316 n_descr = 0; 00317 FREE (vendor_drills); 00318 FREE (ignore_refdes); 00319 FREE (ignore_value); 00320 FREE (ignore_descr); 00321 00322 00323 /* load the resource file */ 00324 res = resource_parse (fname, NULL); 00325 if (res == NULL) 00326 { 00327 Message (_("Could not load vendor resource file \"%s\"\n"), fname); 00328 return 1; 00329 } 00330 00331 /* figure out the vendor name, if specified */ 00332 vendor_name = (char *)UNKNOWN (resource_value (res, "vendor")); 00333 00334 /* figure out the units, if specified */ 00335 sval = resource_value (res, "units"); 00336 if (sval == NULL) 00337 { 00338 sf = MIL_TO_COORD(1); 00339 } 00340 else if ((NSTRCMP (sval, "mil") == 0) || (NSTRCMP (sval, "mils") == 0)) 00341 { 00342 sf = MIL_TO_COORD(1); 00343 } 00344 else if ((NSTRCMP (sval, "inch") == 0) || (NSTRCMP (sval, "inches") == 0)) 00345 { 00346 sf = INCH_TO_COORD(1); 00347 } 00348 else if (NSTRCMP (sval, "mm") == 0) 00349 { 00350 sf = MM_TO_COORD(1); 00351 } 00352 else 00353 { 00354 Message (_("\"%s\" is not a supported units. Defaulting to inch\n"), 00355 sval); 00356 sf = INCH_TO_COORD(1); 00357 } 00358 00359 00360 /* default to ROUND_UP */ 00361 rounding_method = ROUND_UP; 00362 00363 /* extract the drillmap resource */ 00364 drlres = resource_subres (res, "drillmap"); 00365 if (drlres == NULL) 00366 { 00367 Message (_("No drillmap resource found\n")); 00368 } 00369 else 00370 { 00371 sval = resource_value (drlres, "round"); 00372 if (sval != NULL) 00373 { 00374 if (NSTRCMP (sval, "up") == 0) 00375 { 00376 rounding_method = ROUND_UP; 00377 } 00378 else if (NSTRCMP (sval, "nearest") == 0) 00379 { 00380 rounding_method = CLOSEST; 00381 } 00382 else 00383 { 00384 Message (_("\"%s\" is not a valid rounding type. " 00385 "Defaulting to up\n"), 00386 sval); 00387 rounding_method = ROUND_UP; 00388 } 00389 } 00390 00391 process_skips (resource_subres (drlres, "skips")); 00392 00393 for (i = 0; i < drlres->c; i++) 00394 { 00395 type = resource_type (drlres->v[i]); 00396 switch (type) 00397 { 00398 case 10: 00399 /* just a number */ 00400 add_to_drills (drlres->v[i].value); 00401 break; 00402 00403 default: 00404 break; 00405 } 00406 } 00407 } 00408 00409 /* Extract the DRC resource */ 00410 drcres = resource_subres (res, "drc"); 00411 00412 sval = resource_value (drcres, "copper_space"); 00413 if (sval != NULL) 00414 { 00415 PCB->Bloat = floor (sf * atof (sval) + 0.5); 00416 Message (_("Set DRC minimum copper spacing to %.2f mils\n"), 00417 0.01 * PCB->Bloat); 00418 } 00419 00420 sval = resource_value (drcres, "copper_overlap"); 00421 if (sval != NULL) 00422 { 00423 PCB->Shrink = floor (sf * atof (sval) + 0.5); 00424 Message (_("Set DRC minimum copper overlap to %.2f mils\n"), 00425 0.01 * PCB->Shrink); 00426 } 00427 00428 sval = resource_value (drcres, "copper_width"); 00429 if (sval != NULL) 00430 { 00431 PCB->minWid = floor (sf * atof (sval) + 0.5); 00432 Message (_("Set DRC minimum copper spacing to %.2f mils\n"), 00433 0.01 * PCB->minWid); 00434 } 00435 00436 sval = resource_value (drcres, "silk_width"); 00437 if (sval != NULL) 00438 { 00439 PCB->minSlk = floor (sf * atof (sval) + 0.5); 00440 Message (_("Set DRC minimum silk width to %.2f mils\n"), 00441 0.01 * PCB->minSlk); 00442 } 00443 00444 sval = resource_value (drcres, "min_drill"); 00445 if (sval != NULL) 00446 { 00447 PCB->minDrill = floor (sf * atof (sval) + 0.5); 00448 Message (_("Set DRC minimum drill diameter to %.2f mils\n"), 00449 0.01 * PCB->minDrill); 00450 } 00451 00452 sval = resource_value (drcres, "min_ring"); 00453 if (sval != NULL) 00454 { 00455 PCB->minRing = floor (sf * atof (sval) + 0.5); 00456 Message (_("Set DRC minimum annular ring to %.2f mils\n"), 00457 0.01 * PCB->minRing); 00458 } 00459 00460 Message (_("Loaded %d vendor drills from %s\n"), n_vendor_drills, fname); 00461 Message (_("Loaded %d RefDes skips, %d Value skips, %d Descr skips\n"), 00462 n_refdes, n_value, n_descr); 00463 00464 vendorMapEnable = true; 00465 apply_vendor_map (); 00466 if (free_fname) 00467 free (fname); 00468 return 0; 00469 } 00470 00471 static void 00472 apply_vendor_map (void) 00473 { 00474 int i; 00475 int changed, tot; 00476 bool state; 00477 00478 state = vendorMapEnable; 00479 00480 /* enable mapping */ 00481 vendorMapEnable = true; 00482 00483 /* reset our counts */ 00484 changed = 0; 00485 tot = 0; 00486 00487 /* If we have loaded vendor drills, then apply them to the design */ 00488 if (n_vendor_drills > 0) 00489 { 00490 00491 /* first all the vias */ 00492 VIA_LOOP (PCB->Data); 00493 { 00494 tot++; 00495 if (via->DrillingHole != vendorDrillMap (via->DrillingHole)) 00496 { 00497 /* only change unlocked vias */ 00498 if (!TEST_FLAG (LOCKFLAG, via)) 00499 { 00500 if (ChangeObject2ndSize (VIA_TYPE, via, NULL, NULL, 00501 vendorDrillMap (via->DrillingHole), 00502 true, false)) 00503 changed++; 00504 else 00505 { 00506 Message (_("Via at %.2f, %.2f not changed. " 00507 "Possible reasons:\n" 00508 "\t- pad size too small\n" 00509 "\t- new size would be too large or too small\n"), 00510 0.01 * via->X, 0.01 * via->Y); 00511 } 00512 } 00513 else 00514 { 00515 Message (_("Locked via at %.2f, %.2f not changed.\n"), 00516 0.01 * via->X, 0.01 * via->Y); 00517 } 00518 } 00519 } 00520 END_LOOP; 00521 00522 /* and now the pins */ 00523 ELEMENT_LOOP (PCB->Data); 00524 { 00525 /* 00526 * first figure out if this element should be skipped for some 00527 * reason 00528 */ 00529 if (vendorIsElementMappable (element)) 00530 { 00531 /* the element is ok to modify, so iterate over its pins */ 00532 PIN_LOOP (element); 00533 { 00534 tot++; 00535 if (pin->DrillingHole != vendorDrillMap (pin->DrillingHole)) 00536 { 00537 if (!TEST_FLAG (LOCKFLAG, pin)) 00538 { 00539 if (ChangeObject2ndSize (PIN_TYPE, element, pin, NULL, 00540 vendorDrillMap (pin-> 00541 DrillingHole), 00542 true, false)) 00543 changed++; 00544 else 00545 { 00546 Message (_("Pin %s (%s) at %.2f, %.2f " 00547 "(element %s, %s, %s) not changed.\n" 00548 "\tPossible reasons:\n" 00549 "\t- pad size too small\n" 00550 "\t- new size would be too large or too small\n"), 00551 UNKNOWN (pin->Number), UNKNOWN (pin->Name), 00552 0.01 * pin->X, 0.01 * pin->Y, 00553 UNKNOWN (NAMEONPCB_NAME (element)), 00554 UNKNOWN (VALUE_NAME (element)), 00555 UNKNOWN (DESCRIPTION_NAME (element))); 00556 } 00557 } 00558 else 00559 { 00560 Message (_("Locked pin at %-6.2f, %-6.2f not changed.\n"), 00561 0.01 * pin->X, 0.01 * pin->Y); 00562 } 00563 } 00564 } 00565 END_LOOP; 00566 } 00567 } 00568 END_LOOP; 00569 00570 Message (_("Updated %d drill sizes out of %d total\n"), changed, tot); 00571 00572 /* Update the current Via */ 00573 if (Settings.ViaDrillingHole != 00574 vendorDrillMap (Settings.ViaDrillingHole)) 00575 { 00576 changed++; 00577 Settings.ViaDrillingHole = 00578 vendorDrillMap (Settings.ViaDrillingHole); 00579 Message (_("Adjusted active via hole size to be %6.2f mils\n"), 00580 0.01 * Settings.ViaDrillingHole); 00581 } 00582 00583 /* and update the vias for the various routing styles */ 00584 for (i = 0; i < NUM_STYLES; i++) 00585 { 00586 if (PCB->RouteStyle[i].Hole != 00587 vendorDrillMap (PCB->RouteStyle[i].Hole)) 00588 { 00589 changed++; 00590 PCB->RouteStyle[i].Hole = 00591 vendorDrillMap (PCB->RouteStyle[i].Hole); 00592 Message (_("Adjusted %s routing style via hole size to be " 00593 "%6.2f mils\n"), 00594 PCB->RouteStyle[i].Name, 00595 0.01 * PCB->RouteStyle[i].Hole); 00596 if (PCB->RouteStyle[i].Diameter < 00597 PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER) 00598 { 00599 PCB->RouteStyle[i].Diameter = 00600 PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER; 00601 Message (_("Increased %s routing style via diameter to " 00602 "%6.2f mils\n"), 00603 PCB->RouteStyle[i].Name, 00604 0.01 * PCB->RouteStyle[i].Diameter); 00605 } 00606 } 00607 } 00608 00609 /* 00610 * if we've changed anything, indicate that we need to save the 00611 * file, redraw things, and make sure we can undo. 00612 */ 00613 if (changed) 00614 { 00615 SetChangedFlag (true); 00616 Redraw (); 00617 IncrementUndoSerialNumber (); 00618 } 00619 } 00620 00621 /* restore mapping on/off */ 00622 vendorMapEnable = state; 00623 } 00624 00628 int 00629 vendorDrillMap (int in) 00630 { 00631 int i, min, max; 00632 00633 if (in == cached_drill) 00634 return cached_map; 00635 cached_drill = in; 00636 00637 /* skip the mapping if we don't have a vendor drill table */ 00638 if ((n_vendor_drills == 0) || (vendor_drills == NULL) 00639 || (vendorMapEnable == false)) 00640 { 00641 cached_map = in; 00642 return in; 00643 } 00644 00645 /* are we smaller than the smallest drill? */ 00646 if (in <= vendor_drills[0]) 00647 { 00648 cached_map = vendor_drills[0]; 00649 return vendor_drills[0]; 00650 } 00651 00652 /* are we larger than the largest drill? */ 00653 if (in > vendor_drills[n_vendor_drills - 1]) 00654 { 00655 Message (_("Vendor drill list does not contain a drill >= %6.2f mil\n" 00656 "Using %6.2f mil instead.\n"), 00657 0.01 * in, 0.01 * vendor_drills[n_vendor_drills - 1]); 00658 cached_map = vendor_drills[n_vendor_drills - 1]; 00659 return vendor_drills[n_vendor_drills - 1]; 00660 } 00661 00662 /* figure out which 2 drills are closest in size */ 00663 min = 0; 00664 max = n_vendor_drills - 1; 00665 while (max - min > 1) 00666 { 00667 i = (max+min) / 2; 00668 if (in > vendor_drills[i]) 00669 min = i; 00670 else 00671 max = i; 00672 } 00673 i = max; 00674 00675 /* now round per the rounding mode */ 00676 if (rounding_method == CLOSEST) 00677 { 00678 /* find the closest drill size */ 00679 if ((in - vendor_drills[i - 1]) > (vendor_drills[i] - in)) 00680 { 00681 cached_map = vendor_drills[i]; 00682 return vendor_drills[i]; 00683 } 00684 else 00685 { 00686 cached_map = vendor_drills[i - 1]; 00687 return vendor_drills[i - 1]; 00688 } 00689 } 00690 else 00691 { 00692 /* always round up */ 00693 cached_map = vendor_drills[i]; 00694 return vendor_drills[i]; 00695 } 00696 00697 } 00698 00702 static void 00703 add_to_drills (char *sval) 00704 { 00705 double tmpd; 00706 int val; 00707 int k, j; 00708 00709 /* increment the count and make sure we have memory */ 00710 n_vendor_drills++; 00711 if ((vendor_drills = (int *)realloc (vendor_drills, 00712 n_vendor_drills * sizeof (int))) == NULL) 00713 { 00714 fprintf (stderr, _("realloc() failed to allocate %ld bytes\n"), 00715 (unsigned long) n_vendor_drills * sizeof (int)); 00716 return; 00717 } 00718 00719 /* string to a value with the units scale factor in place */ 00720 tmpd = atof (sval); 00721 val = floor (sf * tmpd + 0.5); 00722 00723 /* 00724 * We keep the array of vendor drills sorted to make it easier to 00725 * do the rounding later. The algorithm used here is not so efficient, 00726 * but we're not dealing with much in the way of data. 00727 */ 00728 00729 /* figure out where to insert the value to keep the array sorted. */ 00730 k = 0; 00731 while ((k < n_vendor_drills - 1) && (vendor_drills[k] < val)) 00732 k++; 00733 00734 if (k == n_vendor_drills - 1) 00735 { 00736 vendor_drills[n_vendor_drills - 1] = val; 00737 } 00738 else 00739 { 00740 /* move up the existing drills to make room */ 00741 for (j = n_vendor_drills - 1; j > k; j--) 00742 { 00743 vendor_drills[j] = vendor_drills[j - 1]; 00744 } 00745 00746 vendor_drills[k] = val; 00747 } 00748 } 00749 00753 static void 00754 process_skips (Resource * res) 00755 { 00756 int type; 00757 int i, k; 00758 char *sval; 00759 int *cnt; 00760 char ***lst = NULL; 00761 00762 if (res == NULL) 00763 return; 00764 00765 for (i = 0; i < res->c; i++) 00766 { 00767 type = resource_type (res->v[i]); 00768 switch (type) 00769 { 00770 case 1: 00771 /* 00772 * an unnamed sub resource. This is something like 00773 * {refdes "J3"} 00774 */ 00775 sval = res->v[i].subres->v[0].value; 00776 if (sval == NULL) 00777 { 00778 Message (_("Error: null skip value\n")); 00779 } 00780 else 00781 { 00782 if (NSTRCMP (sval, "refdes") == 0) 00783 { 00784 cnt = &n_refdes; 00785 lst = &ignore_refdes; 00786 } 00787 else if (NSTRCMP (sval, "value") == 0) 00788 { 00789 cnt = &n_value; 00790 lst = &ignore_value; 00791 } 00792 else if (NSTRCMP (sval, "descr") == 0) 00793 { 00794 cnt = &n_descr; 00795 lst = &ignore_descr; 00796 } 00797 else 00798 { 00799 cnt = NULL; 00800 } 00801 00802 /* add the entry to the appropriate list */ 00803 if (cnt != NULL) 00804 { 00805 for (k = 1; k < res->v[i].subres->c; k++) 00806 { 00807 sval = res->v[i].subres->v[k].value; 00808 (*cnt)++; 00809 if ((*lst = 00810 (char **) realloc (*lst, 00811 (*cnt) * sizeof (char *))) == 00812 NULL) 00813 { 00814 fprintf (stderr, _("realloc() failed\n")); 00815 exit (-1); 00816 } 00817 (*lst)[*cnt - 1] = strdup (sval); 00818 } 00819 } 00820 } 00821 break; 00822 00823 default: 00824 Message (_("Ignored resource type = %d in skips= section\n"), type); 00825 } 00826 } 00827 00828 } 00829 00830 bool 00831 vendorIsElementMappable (ElementType *element) 00832 { 00833 int i; 00834 int noskip; 00835 00836 if (vendorMapEnable == false) 00837 return false; 00838 00839 noskip = 1; 00840 for (i = 0; i < n_refdes; i++) 00841 { 00842 if ((NSTRCMP (UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]) == 00843 0) 00844 || rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element)))) 00845 { 00846 Message (_("Vendor mapping skipped because " 00847 "refdes = %s matches %s\n"), 00848 UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]); 00849 noskip = 0; 00850 } 00851 } 00852 if (noskip) 00853 for (i = 0; i < n_value; i++) 00854 { 00855 if ((NSTRCMP (UNKNOWN (VALUE_NAME (element)), ignore_value[i]) == 0) 00856 || rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element)))) 00857 { 00858 Message (_("Vendor mapping skipped because " 00859 "value = %s matches %s\n"), 00860 UNKNOWN (VALUE_NAME (element)), ignore_value[i]); 00861 noskip = 0; 00862 } 00863 } 00864 00865 if (noskip) 00866 for (i = 0; i < n_descr; i++) 00867 { 00868 if ((NSTRCMP (UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]) 00869 == 0) 00870 || rematch (ignore_descr[i], 00871 UNKNOWN (DESCRIPTION_NAME (element)))) 00872 { 00873 Message (_("Vendor mapping skipped because " 00874 "descr = %s matches %s\n"), 00875 UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]); 00876 noskip = 0; 00877 } 00878 } 00879 00880 if (noskip && TEST_FLAG (LOCKFLAG, element)) 00881 { 00882 Message (_("Vendor mapping skipped because element %s is locked\n"), 00883 UNKNOWN (NAMEONPCB_NAME (element))); 00884 noskip = 0; 00885 } 00886 00887 if (noskip) 00888 return true; 00889 else 00890 return false; 00891 } 00892 00893 static bool 00894 rematch (const char *re, const char *s) 00895 { 00896 /* 00897 * If this system has regular expression capability, then 00898 * add support for regular expressions in the skip lists. 00899 */ 00900 00901 #if defined(HAVE_REGCOMP) 00902 00903 int result; 00904 regmatch_t match; 00905 regex_t compiled; 00906 00907 /* compile the regular expression */ 00908 result = regcomp (&compiled, re, REG_EXTENDED | REG_ICASE | REG_NOSUB); 00909 if (result) 00910 { 00911 char errorstring[128]; 00912 00913 regerror (result, &compiled, errorstring, sizeof (errorstring)); 00914 Message (_("regexp error: %s\n"), errorstring); 00915 regfree (&compiled); 00916 return (false); 00917 } 00918 00919 result = regexec (&compiled, s, 1, &match, 0); 00920 regfree (&compiled); 00921 00922 if (result == 0) 00923 return (true); 00924 else 00925 return (false); 00926 00927 #elif defined(HAVE_RE_COMP) 00928 int m; 00929 char *rslt; 00930 00931 /* compile the regular expression */ 00932 if ((rslt = re_comp (re)) != NULL) 00933 { 00934 Message (_("re_comp error: %s\n"), rslt); 00935 return (false); 00936 } 00937 00938 m = re_exec (s); 00939 00940 switch m 00941 { 00942 case 1: 00943 return (true); 00944 break; 00945 00946 case 0: 00947 return (false); 00948 break; 00949 00950 default: 00951 Message (_("re_exec error\n")); 00952 break; 00953 } 00954 00955 #else 00956 return (false); 00957 #endif 00958 00959 } 00960 00961 HID_Action vendor_action_list[] = { 00962 {"ApplyVendor", 0, ActionApplyVendor, 00963 apply_vendor_help, apply_vendor_syntax} 00964 , 00965 {"ToggleVendor", 0, ActionToggleVendor, 00966 toggle_vendor_help, toggle_vendor_syntax} 00967 , 00968 {"EnableVendor", 0, ActionEnableVendor, 00969 enable_vendor_help, enable_vendor_syntax} 00970 , 00971 {"DisableVendor", 0, ActionDisableVendor, 00972 disable_vendor_help, disable_vendor_syntax} 00973 , 00974 {"UnloadVendor", 0, ActionUnloadVendor, 00975 unload_vendor_help, unload_vendor_syntax} 00976 , 00977 {"LoadVendorFrom", 0, ActionLoadVendorFrom, 00978 load_vendor_help, load_vendor_syntax} 00979 }; 00980 00981 REGISTER_ACTIONS (vendor_action_list) 00982 00983 static int vendor_get_enabled (void *data) 00984 { 00985 return vendorMapEnable; 00986 } 00987 00988 HID_Flag vendor_flag_list[] = { 00989 {"VendorMapOn", vendor_get_enabled, NULL} 00990 }; 00991 00992 REGISTER_FLAGS (vendor_flag_list)