From: Amos Jeffries Date: Mon, 27 Jul 2015 12:51:43 +0000 (-0700) Subject: Replace RegexList wth std::list X-Git-Tag: merge-candidate-3-v1~24^2~2^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e2b74520b559882f0a754b1ee295d98dce25bcb5;p=thirdparty%2Fsquid.git Replace RegexList wth std::list --- diff --git a/src/AclRegs.cc b/src/AclRegs.cc index 9be5e3e052..068ac6d27e 100644 --- a/src/AclRegs.cc +++ b/src/AclRegs.cc @@ -96,6 +96,7 @@ #include "auth/AclMaxUserIp.h" #include "auth/AclProxyAuth.h" #endif +#include "base/RegexPattern.h" #if USE_IDENT #include "ident/AclIdent.h" #endif diff --git a/src/acl/HttpHeaderData.cc b/src/acl/HttpHeaderData.cc index 68cae3ec94..7b27e3f6fa 100644 --- a/src/acl/HttpHeaderData.cc +++ b/src/acl/HttpHeaderData.cc @@ -13,6 +13,7 @@ #include "acl/Checklist.h" #include "acl/HttpHeaderData.h" #include "acl/RegexData.h" +#include "base/RegexPattern.h" #include "ConfigParser.h" #include "Debug.h" #include "HttpHeaderTools.h" diff --git a/src/acl/RegexData.cc b/src/acl/RegexData.cc index 52c83811d1..951da42b01 100644 --- a/src/acl/RegexData.cc +++ b/src/acl/RegexData.cc @@ -25,43 +25,24 @@ ACLRegexData::~ACLRegexData() { - delete data; } bool ACLRegexData::match(char const *word) { - if (word == NULL) + if (!word) return 0; - debugs(28, 3, "aclRegexData::match: checking '" << word << "'"); + debugs(28, 3, "checking '" << word << "'"); - RegexList *first, *prev; - - first = data; - - prev = NULL; - - RegexList *current = first; - - while (current) { - debugs(28, 3, "aclRegexData::match: looking for '" << current->pattern << "'"); - - if (regexec(¤t->regex, word, 0, 0, 0) == 0) { - if (prev != NULL) { - /* shift the element just found to the second position - * in the list */ - prev->next = current->next; - current->next = first->next; - first->next = current; - } - - debugs(28, 2, "aclRegexData::match: match '" << current->pattern << "' found in '" << word << "'"); + // walk the list of patterns to see if one matches + for (auto &i : data) { + if (regexec(&i.regex, word, 0, 0, 0) == 0) { + debugs(28, 2, "'" << i.pattern << "' found in '" << word << "'"); + // TODO: old code also popped the pattern to second place of the list + // in order to reduce patterns search times. return 1; } - - prev = current; - current = current->next; } return 0; @@ -71,21 +52,21 @@ SBufList ACLRegexData::dump() const { SBufList sl; - RegexList *temp = data; int flags = REG_EXTENDED | REG_NOSUB; - while (temp != NULL) { - if (temp->flags != flags) { - if ((temp->flags®_ICASE) != 0) { + // walk and dump the list + // keeping the flags values consistent + for (auto &i : data) { + if (i.flags != flags) { + if ((i.flags®_ICASE) != 0) { sl.push_back(SBuf("-i")); } else { sl.push_back(SBuf("+i")); } - flags = temp->flags; + flags = i.flags; } - sl.push_back(SBuf(temp->pattern)); - temp = temp->next; + sl.push_back(SBuf(i.pattern)); } return sl; @@ -119,31 +100,26 @@ removeUnnecessaryWildcards(char * t) return t; } -static RegexList ** -compileRE(RegexList **Tail, char * RE, int flags) +static bool +compileRE(std::list &curlist, char * RE, int flags) { - int errcode; - RegexList *q; - regex_t comp; + if (RE == NULL || *RE == '\0') + return curlist.empty(); // XXX: old code did this. It looks wrong. - if (RE == NULL || *RE == '\0') - return Tail; - - if ((errcode = regcomp(&comp, RE, flags)) != 0) { + regex_t comp; + if (int errcode = regcomp(&comp, RE, flags)) { char errbuf[256]; regerror(errcode, &comp, errbuf, sizeof errbuf); debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line); debugs(28, DBG_CRITICAL, "ERROR: invalid regular expression: '" << RE << "': " << errbuf); - return NULL; + return false; } - debugs(28, 2, "compileRE: compiled '" << RE << "' with flags " << flags ); + debugs(28, 2, "compiled '" << RE << "' with flags " << flags); - q = new RegexList(flags, RE); - q->regex = comp; - *(Tail) = q; - Tail = &q->next; + curlist.emplace_back(flags, RE); + curlist.back().regex = comp; - return Tail; + return true; } /** Compose and compile one large RE from a set of (small) REs. @@ -151,20 +127,14 @@ compileRE(RegexList **Tail, char * RE, int flags) * called only once per ACL. */ static int -compileOptimisedREs(RegexList **curlist, wordlist * wl) +compileOptimisedREs(std::list &curlist, wordlist * wl) { - RegexList **Tail; - RegexList *newlist; - RegexList **newlistp; + std::list newlist; int numREs = 0; int flags = REG_EXTENDED | REG_NOSUB; int largeREindex = 0; char largeRE[BUFSIZ]; - - newlist = NULL; - newlistp = &newlist; - - largeRE[0] = '\0'; + *largeRE = 0; while (wl != NULL) { int RElen; @@ -176,11 +146,8 @@ compileOptimisedREs(RegexList **curlist, wordlist * wl) debugs(28, 2, "compileOptimisedREs: optimisation of -i ... -i" ); } else { debugs(28, 2, "compileOptimisedREs: -i" ); - newlistp = compileRE( newlistp, largeRE, flags ); - if (newlistp == NULL) { - delete newlist; + if (!compileRE(newlist, largeRE, flags)) return 0; - } flags |= REG_ICASE; largeRE[largeREindex=0] = '\0'; } @@ -190,11 +157,8 @@ compileOptimisedREs(RegexList **curlist, wordlist * wl) debugs(28, 2, "compileOptimisedREs: optimisation of +i ... +i"); } else { debugs(28, 2, "compileOptimisedREs: +i"); - newlistp = compileRE( newlistp, largeRE, flags ); - if (newlistp == NULL) { - delete newlist; + if (!compileRE(newlist, largeRE, flags)) return 0; - } flags &= ~REG_ICASE; largeRE[largeREindex=0] = '\0'; } @@ -216,31 +180,19 @@ compileOptimisedREs(RegexList **curlist, wordlist * wl) ++numREs; } else { debugs(28, 2, "compileOptimisedREs: buffer full, generating new optimised RE..." ); - newlistp = compileRE( newlistp, largeRE, flags ); - if (newlistp == NULL) { - delete newlist; + if (!compileRE(newlist, largeRE, flags)) return 0; - } largeRE[largeREindex=0] = '\0'; continue; /* do the loop again to add the RE to largeRE */ } wl = wl->next; } - newlistp = compileRE( newlistp, largeRE, flags ); - if (newlistp == NULL) { - delete newlist; + if (!compileRE(newlist, largeRE, flags)) return 0; - } /* all was successful, so put the new list at the tail */ - if (*curlist == NULL) { - *curlist = newlist; - } else { - for (Tail = curlist; *Tail != NULL; Tail = &((*Tail)->next)) - ; - (*Tail) = newlist; - } + curlist.splice(curlist.end(), newlist); debugs(28, 2, "compileOptimisedREs: " << numREs << " REs are optimised into one RE."); if (numREs > 100) { @@ -253,75 +205,59 @@ compileOptimisedREs(RegexList **curlist, wordlist * wl) } static void -compileUnoptimisedREs(RegexList **curlist, wordlist * wl) +compileUnoptimisedREs(std::list &curlist, wordlist * wl) { - RegexList **Tail; - RegexList **newTail; int flags = REG_EXTENDED | REG_NOSUB; - for (Tail = curlist; *Tail != NULL; Tail = &((*Tail)->next)) - ; - while (wl != NULL) { if (strcmp(wl->key, "-i") == 0) { flags |= REG_ICASE; } else if (strcmp(wl->key, "+i") == 0) { flags &= ~REG_ICASE; } else { - newTail = compileRE( Tail, wl->key , flags ); - if (newTail == NULL) + if (!compileRE(curlist, wl->key , flags)) debugs(28, DBG_CRITICAL, "ERROR: Skipping regular expression. Compile failed: '" << wl->key << "'"); - else - Tail = newTail; } wl = wl->next; } } -static void -aclParseRegexList(RegexList **curlist) +void +ACLRegexData::parse() { - char *t; - wordlist *wl = NULL; + debugs(28, 2, "new Regex line or file"); - debugs(28, 2, HERE << "aclParseRegexList: new Regex line or file"); - - while ((t = ConfigParser::RegexStrtokFile()) != NULL) { + wordlist *wl = NULL; + while (char *t = ConfigParser::RegexStrtokFile()) { const char *clean = removeUnnecessaryWildcards(t); if (strlen(clean) > BUFSIZ-1) { debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line); debugs(28, DBG_CRITICAL, "ERROR: Skipping regular expression. Larger than " << BUFSIZ-1 << " characters: '" << clean << "'"); } else { - debugs(28, 3, "aclParseRegexList: buffering RE '" << clean << "'"); + debugs(28, 3, "buffering RE '" << clean << "'"); wordlistAdd(&wl, clean); } } - if (!compileOptimisedREs(curlist, wl)) { + if (!compileOptimisedREs(data, wl)) { debugs(28, DBG_IMPORTANT, "WARNING: optimisation of regular expressions failed; using fallback method without optimisation"); - compileUnoptimisedREs(curlist, wl); + compileUnoptimisedREs(data, wl); } wordlistDestroy(&wl); } -void -ACLRegexData::parse() -{ - aclParseRegexList(&data); -} - bool ACLRegexData::empty() const { - return data == NULL; + return data.empty(); } ACLData * ACLRegexData::clone() const { /* Regex's don't clone yet. */ - assert (!data); + assert(data.empty()); return new ACLRegexData; } diff --git a/src/acl/RegexData.h b/src/acl/RegexData.h index 19c5a1ae85..7b4b15ba2d 100644 --- a/src/acl/RegexData.h +++ b/src/acl/RegexData.h @@ -11,7 +11,9 @@ #include "acl/Data.h" -class RegexList; +#include + +class RegexPattern; class ACLRegexData : public ACLData { @@ -26,7 +28,7 @@ public: virtual ACLData *clone() const; private: - RegexList *data; + std::list data; }; #endif /* SQUID_ACLREGEXDATA_H */ diff --git a/src/base/RegexPattern.cc b/src/base/RegexPattern.cc index 37018d4804..e70879ac4d 100644 --- a/src/base/RegexPattern.cc +++ b/src/base/RegexPattern.cc @@ -14,15 +14,3 @@ RegexPattern::~RegexPattern() xfree(pattern); regfree(®ex); } - -RegexList::~RegexList() -{ - // lists could be very long - // iterate instead of recursing - for (auto p = next; p; p = next) { - next = p->next; - p->next = nullptr; - delete p; - } -} - diff --git a/src/base/RegexPattern.h b/src/base/RegexPattern.h index eb2fdd5d45..180488b147 100644 --- a/src/base/RegexPattern.h +++ b/src/base/RegexPattern.h @@ -23,7 +23,7 @@ public: RegexPattern() = delete; RegexPattern(int aFlags, const char *aPattern) : flags(aFlags), pattern(xstrdup(aPattern)) {} RegexPattern(const RegexPattern &) = delete; - RegexPattern(const RegexPattern && o) = delete; + RegexPattern(RegexPattern &&) = default; ~RegexPattern(); int flags; @@ -31,21 +31,5 @@ public: regex_t regex; }; -/// list of regular expressions. -/// \deprecated use a std::list instead -class RegexList : public RegexPattern -{ - MEMPROXY_CLASS(RegexList); - -public: - RegexList() = delete; - RegexList(int aFlags, const char *aPattern) : RegexPattern(aFlags, aPattern), next(nullptr) {} - RegexList(const RegexList &) = delete; - RegexList(const RegexList && o) = delete; - ~RegexList(); - - RegexList *next; -}; - #endif /* SQUID_SRC_BASE_REGEXPATTERN_H */