src/Makefile.am | 2 + src/action.c | 15 ---- src/netlist.c | 86 ++------------------- src/pcb_regex.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pcb_regex.h | 55 +++++++++++++ src/select.c | 81 +++----------------- src/select.h | 2 - src/vendor.c | 83 ++----------------- 8 files changed, 318 insertions(+), 241 deletions(-) create mode 100644 src/pcb_regex.c create mode 100644 src/pcb_regex.h diff --git a/src/Makefile.am b/src/Makefile.am index 34c672d..2ab9c59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -106,6 +106,8 @@ PCB_SRCS = \ parse_l.l \ parse_y.h \ parse_y.y \ + pcb_regex.c \ + pcb_regex.h \ polygon.c \ polygon.h \ polygon1.c \ diff --git a/src/action.c b/src/action.c index de2738e..975d906 100644 --- a/src/action.c +++ b/src/action.c @@ -5432,7 +5432,6 @@ ActionSelect (int argc, char **argv, int x, int y) HideCrosshair (true); switch (GetFunctionID (function)) { -#if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) int type; /* select objects by their names */ case F_ElementByName: @@ -5472,7 +5471,6 @@ ActionSelect (int argc, char **argv, int x, int y) } break; } -#endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */ /* select a single object */ case F_ToggleObject: @@ -5557,17 +5555,6 @@ ActionSelect (int argc, char **argv, int x, int y) return 0; } -/* FLAG(have_regex,FlagHaveRegex,0) */ -int -FlagHaveRegex (int parm) -{ -#if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) - return 1; -#else - return 0; -#endif -} - /* --------------------------------------------------------------------------- */ static const char unselect_syntax[] = @@ -5618,7 +5605,6 @@ ActionUnselect (int argc, char **argv, int x, int y) HideCrosshair (true); switch (GetFunctionID (function)) { -#if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) int type; /* select objects by their names */ case F_ElementByName: @@ -5658,7 +5644,6 @@ ActionUnselect (int argc, char **argv, int x, int y) } break; } -#endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */ /* all objects in block */ case F_Block: diff --git a/src/netlist.c b/src/netlist.c index 0c004f9..7a9bc19 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -39,9 +39,6 @@ #endif #include #include -#ifdef HAVE_REGEX_H -#include -#endif #include "global.h" #include "action.h" @@ -58,14 +55,7 @@ #include "set.h" #include "vendor.h" #include "create.h" - -#ifdef HAVE_REGCOMP -#undef HAVE_RE_COMP -#endif - -#if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) -#define USE_RE -#endif +#include "pcb_regex.h" #ifdef HAVE_LIBDMALLOC #include @@ -352,16 +342,6 @@ Netlist (int argc, char **argv, int x, int y) LibraryEntryType *pin; int net_found = 0; int pin_found = 0; -#if defined(USE_RE) - int use_re = 0; -#endif -#if defined(HAVE_REGCOMP) - regex_t elt_pattern; - regmatch_t match; -#endif -#if defined(HAVE_RE_COMP) - char *elt_pattern; -#endif if (!PCB) return 1; @@ -427,67 +407,18 @@ Netlist (int argc, char **argv, int x, int y) return 1; } -#if defined(USE_RE) if (argc > 1) - { - int result; - use_re = 1; - for (i = 0; i < PCB->NetlistLib.MenuN; i++) - { - net = PCB->NetlistLib.Menu + i; - if (strcasecmp (argv[1], net->Name + 2) == 0) - use_re = 0; - } - if (use_re) - { -#if defined(HAVE_REGCOMP) - result = - regcomp (&elt_pattern, argv[1], - REG_EXTENDED | REG_ICASE | REG_NOSUB); - if (result) - { - char errorstring[128]; - - regerror (result, &elt_pattern, errorstring, 128); - Message (_("regexp error: %s\n"), errorstring); - regfree (&elt_pattern); - return (1); - } -#endif -#if defined(HAVE_RE_COMP) - if ((elt_pattern = re_comp (argv[1])) != NULL) - { - Message (_("re_comp error: %s\n"), elt_pattern); - return (false); - } -#endif - } - } -#endif + if (!pcb_regex_compile (argv[1])) + return 1; for (i = PCB->NetlistLib.MenuN-1; i >= 0; i--) { net = PCB->NetlistLib.Menu + i; if (argc > 1) - { -#if defined(USE_RE) - if (use_re) - { -#if defined(HAVE_REGCOMP) - if (regexec (&elt_pattern, net->Name + 2, 1, &match, 0) != 0) - continue; -#endif -#if defined(HAVE_RE_COMP) - if (re_exec (net->Name + 2) != 1) - continue; -#endif - } - else -#endif - if (strcasecmp (net->Name + 2, argv[1])) - continue; - } + if (!pcb_regexec (net->Name + 2)) + continue; + net_found = 1; pin = 0; @@ -521,10 +452,7 @@ Netlist (int argc, char **argv, int x, int y) { gui->log ("No net named %s\n", argv[1]); } -#ifdef HAVE_REGCOMP - if (use_re) - regfree (&elt_pattern); -#endif + pcb_regex_cleanup (); return 0; } diff --git a/src/pcb_regex.c b/src/pcb_regex.c new file mode 100644 index 0000000..a2b9c9f --- /dev/null +++ b/src/pcb_regex.c @@ -0,0 +1,235 @@ +/* $Id$ */ + +/* + * COPYRIGHT + * + * PCB, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Contact addresses for paper mail and Email: + * Martin Kupec, Hradecka 14, 74601 Opava, Czech Republic + * martin.kupec@kupson.cz + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "global.h" +#include "error.h" + +#include + +#ifdef HAVE_REGEX_H +#include +#else +#ifdef HAVE_UNISTD_H +#include +#endif +#endif + +#ifdef HAVE_LIBDMALLOC +#include +#endif + +RCSID ("$Id$"); + +/* ---------------------------------------------------------------------- + * Takes a regular expression pattern and adds '\' before each characted + * mentioned in 'armored' list. If there was '\' before the character it + * strips it instead. This changes the syntax of regular expression to + * GNU one regadring 'armored' characters. + * + * Regular expression pattern is taken as an argument, new string is + * returned. This returned string needs to be freed. + */ +static char * +ArmorPattern (const char *Pattern) +{ + const char armored[] = {'+', '(', ')', '{', '}', '?', '|'}; + char *buffer, *tmp; + int counter, i; + + /* Get the length of the Pattern and add an extra space + * for potentional additional '\' characters */ + counter = 0; + tmp = (char *) Pattern; + for (; *tmp != '\0'; tmp++) + { + counter++; + for (i = 0; i < (sizeof(armored)/sizeof(armored[0])); i++) + if (*tmp == armored[i]) + counter++; + } + /* Allocate space for the new string plus terminating \0 */ + buffer = malloc(sizeof(char) * (counter + 1)); + + /* And change the '\'s */ + counter = 0; + tmp = buffer; + for (; *Pattern != '\0'; Pattern++) + { + /* check for armored characters */ + for (i = 0; i < (sizeof(armored)/sizeof(armored[0])); i++) + if (*Pattern == armored[i]) + { + if (!counter) + *tmp++ = '\\'; + else + counter = 0; + break; + } + if (*Pattern != '\\') + { + /* if even put them to ouput */ + if (counter == 2) + { + *tmp++ = '\\'; + *tmp++ = '\\'; + /* just a single '\' */ + } else if (counter) + *tmp++ = '\\'; + + *tmp++ = *Pattern; + /* last character was not '\' */ + counter = 0; + } else { + /* count the number of succesive '\' */ + counter++; + } + } + *tmp = '\0'; + return buffer; +} + +#if defined(HAVE_REGCOMP) + +/* Global vaiable for storing last compiled pattern */ +regex_t regex_compiled; + +bool +pcb_regexec (const char *string) +{ + regmatch_t match; + + if (regexec (®ex_compiled, string, 1, &match, 0) != 0) + return (false); + if (match.rm_so != 0) + return (false); + if (match.rm_eo != strlen(string)) + return (false); + return (true); +} + +bool +pcb_regex_compile (const char *Pattern) +{ + int result; + char *new_pattern; + + /* Change the meaning of +, \+ and similars */ + new_pattern = ArmorPattern (Pattern); + + /* compile the regular expression */ + result = regcomp (®ex_compiled, new_pattern, REG_EXTENDED | REG_ICASE); + + /* ArmorPattern returns string which have to be freed * + * and Pattern is not needed any more */ + free(new_pattern); + + if (result) + { + char errorstring[128]; + + regerror (result, ®ex_compiled, errorstring, 128); + Message (_("regex error: %s\n"), errorstring); + regfree (®ex_compiled); + return (false); + } + return (true); +} + +void +pcb_regex_cleanup (void) +{ + regfree (®ex_compiled); +} + +#elif defined(HAVE_RE_COMP) + +bool +pcb_regexec (const char *string) +{ + return (re_exec(string) == 1); +} + +bool +pcb_regex_compile (const char *Pattern) +{ + char *compiled; + char *new_pattern; + + new_pattern = ArmorPattern (Pattern); + + /* compile the regular expression */ + compiled = re_comp (new_pattern); + + /* ArmorPattern returns string which have to be freed * + * and Pattern is not needed any more */ + free(new_pattern); + + if (compiled != NULL) + { + Message (_("re_comp error: %s\n"), compiled); + return (false); + } + return (true); +} + +void +pcb_regex_cleanup (void) +{ + return; +} + +#else + +char *regex_pattern; + +bool +pcb_regexec (const char *string) +{ + return !strcmp(string, regex_pattern); +} + +bool +pcb_regex_compile (const char *Pattern) +{ + regex_pattern = strdup(Pattern); + return (true); +} + +void +pcb_regex_cleanup (void) +{ + free(regex_pattern); + regex_pattern = NULL; + return; +} + +#endif diff --git a/src/pcb_regex.h b/src/pcb_regex.h new file mode 100644 index 0000000..54dafcb --- /dev/null +++ b/src/pcb_regex.h @@ -0,0 +1,55 @@ +/* + * COPYRIGHT + * + * PCB, interactive printed circuit board design + * Copyright (C) 1994,1995,1996 Thomas Nau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Contact addresses for paper mail and Email: + * Martin Kupec, Hradecka 14, 74601 Opava, Czech Republic + * martin.kupec@kupson.cz + * + * RCS: $Id$ + */ + +/* prototypes for internal regex routines */ + +#ifndef __PCB_REGEX_INCLUDED__ +#define __PCB_REGEX_INCLUDED__ + +#include "global.h" + +/* + * Execute compiled regular expression. + * The only parametr is string to compare. + * Returns true on success. + */ +bool pcb_regexec (const char *string); + +/* + * Compile regular expression given + * by the only argument. + * Compiled expression is stored internaly. + * Return true on success. + */ +bool pcb_regex_compile (const char *Pattern); + +/* + * Frees memory used for compiled expression. + */ +void pcb_regex_cleanup (void); + +#endif diff --git a/src/select.c b/src/select.c index 3e978bb..a31f2d8 100644 --- a/src/select.c +++ b/src/select.c @@ -45,15 +45,9 @@ #include "rats.h" #include "misc.h" #include "find.h" +#include "pcb_regex.h" #include -#ifdef HAVE_REGEX_H -#include -#else -#ifdef HAVE_UNISTD_H -#include -#endif -#endif #ifdef HAVE_LIBDMALLOC #include @@ -857,63 +851,13 @@ SelectConnection (bool Flag) return (changed); } -#if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) -/* --------------------------------------------------------------------------- - * selects objects as defined by Type by name; - * it's a case insensitive match - * returns true if any object has been selected - */ - -#if defined (HAVE_REGCOMP) -static int -regexec_match_all (const regex_t *preg, const char *string) -{ - regmatch_t match; - - if (regexec (preg, string, 1, &match, 0) != 0) - return 0; - if (match.rm_so != 0) - return 0; - if (match.rm_eo != strlen(string)) - return 0; - return 1; -} -#endif - bool SelectObjectByName (int Type, char *Pattern, bool Flag) { bool changed = false; -#if defined(HAVE_REGCOMP) -#define REGEXEC(arg) (regexec_match_all(&compiled, (arg))) - - int result; - regex_t compiled; - - /* compile the regular expression */ - result = regcomp (&compiled, Pattern, REG_EXTENDED | REG_ICASE); - if (result) - { - char errorstring[128]; - - regerror (result, &compiled, errorstring, 128); - Message (_("regexp error: %s\n"), errorstring); - regfree (&compiled); - return (false); - } -#else -#define REGEXEC(arg) (re_exec((arg)) == 1) - - char *compiled; - - /* compile the regular expression */ - if ((compiled = re_comp (Pattern)) != NULL) - { - Message (_("re_comp error: %s\n"), compiled); - return (false); - } -#endif + if (!pcb_regex_compile (Pattern)) + return (false); /* loop over all visible objects with names */ if (Type & TEXT_TYPE) @@ -922,7 +866,7 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) if (!TEST_FLAG (LOCKFLAG, text) && TEXT_IS_VISIBLE (PCB, layer, text) && text->TextString - && REGEXEC (text->TextString) + && pcb_regexec (text->TextString) && TEST_FLAG (SELECTEDFLAG, text) != Flag) { AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text); @@ -942,7 +886,7 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) && TEST_FLAG (SELECTEDFLAG, element) != Flag) { String name = ELEMENT_NAME (PCB, element); - if (name && REGEXEC (name)) + if (name && pcb_regexec (name)) { AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element); ASSIGN_FLAG (SELECTEDFLAG, Flag, element); @@ -975,7 +919,7 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) ALLPIN_LOOP (PCB->Data); { if (!TEST_FLAG (LOCKFLAG, element) - && pin->Name && REGEXEC (pin->Name) + && pin->Name && pcb_regexec (pin->Name) && TEST_FLAG (SELECTEDFLAG, pin) != Flag) { AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin); @@ -992,7 +936,7 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) && ((TEST_FLAG (ONSOLDERFLAG, pad) != 0) == SWAP_IDENT || PCB->InvisibleObjectsOn) && TEST_FLAG (SELECTEDFLAG, pad) != Flag) - if (pad->Name && REGEXEC (pad->Name)) + if (pad->Name && pcb_regexec (pad->Name)) { AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad); ASSIGN_FLAG (SELECTEDFLAG, Flag, pad); @@ -1006,7 +950,7 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) { if (!TEST_FLAG (LOCKFLAG, via) && via->Name - && REGEXEC (via->Name) && TEST_FLAG (SELECTEDFLAG, via) != Flag) + && pcb_regexec (via->Name) && TEST_FLAG (SELECTEDFLAG, via) != Flag) { AddObjectToFlagUndoList (VIA_TYPE, via, via, via); ASSIGN_FLAG (SELECTEDFLAG, Flag, via); @@ -1028,7 +972,7 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) /* Name[0] and Name[1] are special purpose, not the actual name*/ if (menu->Name && menu->Name[0] != '\0' && menu->Name[1] != '\0' && - REGEXEC (menu->Name + 2)) + pcb_regexec (menu->Name + 2)) { for (i = menu->EntryN, entry = menu->Entry; i; i--, entry++) if (SeekPad (entry, &conn, false)) @@ -1043,11 +987,7 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) FreeConnectionLookupMemory (); } -#if defined(HAVE_REGCOMP) -#if !defined(sgi) - regfree (&compiled); -#endif -#endif + pcb_regex_cleanup (); if (changed) { @@ -1056,4 +996,3 @@ SelectObjectByName (int Type, char *Pattern, bool Flag) } return (changed); } -#endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */ diff --git a/src/select.h b/src/select.h index e24ab82..36273da 100644 --- a/src/select.h +++ b/src/select.h @@ -44,8 +44,6 @@ bool SelectedOperation (ObjectFunctionTypePtr, bool, int); void *ObjectOperation (ObjectFunctionTypePtr, int, void *, void *, void *); bool SelectConnection (bool); -#if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) bool SelectObjectByName (int, char *, bool); -#endif #endif diff --git a/src/vendor.c b/src/vendor.c index 5b7f5eb..2c65a19 100644 --- a/src/vendor.c +++ b/src/vendor.c @@ -42,14 +42,6 @@ #include #endif -#ifdef HAVE_REGEX_H -#include -#else -#ifdef HAVE_UNISTD_H -#include -#endif -#endif - #include "change.h" #include "data.h" #include "draw.h" @@ -59,6 +51,7 @@ #include "set.h" #include "undo.h" #include "vendor.h" +#include "pcb_regex.h" #ifdef HAVE_LIBDMALLOC #include @@ -830,9 +823,7 @@ vendorIsElementMappable (ElementTypePtr element) noskip = 1; for (i = 0; i < n_refdes; i++) { - if ((NSTRCMP (UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]) == - 0) - || rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element)))) + if (rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element)))) { Message (_ ("Vendor mapping skipped because refdes = %s matches %s\n"), @@ -843,8 +834,7 @@ vendorIsElementMappable (ElementTypePtr element) if (noskip) for (i = 0; i < n_value; i++) { - if ((NSTRCMP (UNKNOWN (VALUE_NAME (element)), ignore_value[i]) == 0) - || rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element)))) + if (rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element)))) { Message (_ ("Vendor mapping skipped because value = %s matches %s\n"), @@ -856,10 +846,7 @@ vendorIsElementMappable (ElementTypePtr element) if (noskip) for (i = 0; i < n_descr; i++) { - if ((NSTRCMP (UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]) - == 0) - || rematch (ignore_descr[i], - UNKNOWN (DESCRIPTION_NAME (element)))) + if (rematch (ignore_descr[i], UNKNOWN (DESCRIPTION_NAME (element)))) { Message (_ ("Vendor mapping skipped because descr = %s matches %s\n"), @@ -884,68 +871,16 @@ vendorIsElementMappable (ElementTypePtr element) static bool rematch (const char *re, const char *s) { - /* - * If this system has regular expression capability, then - * add support for regular expressions in the skip lists. - */ - -#if defined(HAVE_REGCOMP) - - int result; - regmatch_t match; - regex_t compiled; + bool result; - /* compile the regular expression */ - result = regcomp (&compiled, re, REG_EXTENDED | REG_ICASE | REG_NOSUB); - if (result) - { - char errorstring[128]; - - regerror (result, &compiled, errorstring, sizeof (errorstring)); - Message ("regexp error: %s\n", errorstring); - regfree (&compiled); + if(!pcb_regex_compile (re)) return (false); - } - result = regexec (&compiled, s, 1, &match, 0); - regfree (&compiled); + result = pcb_regexec (s); - if (result == 0) - return (true); - else - return (false); - -#elif defined(HAVE_RE_COMP) - int m; - char *rslt; + pcb_regex_cleanup (); - /* compile the regular expression */ - if ((rslt = re_comp (re)) != NULL) - { - Message ("re_comp error: %s\n", rslt); - return (false); - } - - m = re_exec (s); - - switch m - { - case 1: - return (true); - break; - - case 0: - return (false); - break; - - default: - Message ("re_exec error\n"); - break; - } - -#else - return (false); -#endif + return result; }