# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kinkie@squid-cache.org-20080813154513-scid8h9og9nxbc84 # target_branch: http://www.squid-cache.org/bzr/squid3/trunk # testament_sha1: 5fe2ebc86a5040d49d862d3f50256c1547ce4b29 # timestamp: 2008-08-13 17:54:29 +0200 # source_branch: ../repo/squid-trunk # base_revision_id: squid3@treenet.co.nz-20080813102225-\ # 5eq6cy876h2qb39f # # Begin patch === modified file 'src/ACLARP.cc' --- src/ACLARP.cc 2008-04-06 12:37:53 +0000 +++ src/ACLARP.cc 2008-08-09 16:13:04 +0000 @@ -631,13 +631,13 @@ arp->eth[0] & 0xff, arp->eth[1] & 0xff, arp->eth[2] & 0xff, arp->eth[3] & 0xff, arp->eth[4] & 0xff, arp->eth[5] & 0xff); - wordlistAdd((wordlist **)state, buf); + (*static_cast (state))->add(buf); } wordlist * ACLARP::dump() const { - wordlist *w = NULL; + wordlist *w = new wordlist; data->walk(aclDumpArpListWalkee, &w); return w; } === modified file 'src/ACLCertificateData.cc' --- src/ACLCertificateData.cc 2006-04-23 20:28:06 +0000 +++ src/ACLCertificateData.cc 2008-08-07 16:03:51 +0000 @@ -86,14 +86,14 @@ aclDumpAttributeListWalkee(char * const & node_data, void *outlist) { /* outlist is really a wordlist ** */ - wordlistAdd((wordlist **)outlist, node_data); + (*static_cast(outlist))->add(node_data); } wordlist * ACLCertificateData::dump() { - wordlist *wl = NULL; - wordlistAdd(&wl, attribute); + wordlist *wl = new wordlist; + wl->add(attribute); /* damn this is VERY inefficient for long ACL lists... filling * a wordlist this way costs Sum(1,N) iterations. For instance * a 1000-elements list will be filled in 499500 iterations. === modified file 'src/ACLDomainData.cc' --- src/ACLDomainData.cc 2007-04-29 04:26:37 +0000 +++ src/ACLDomainData.cc 2008-08-09 16:13:04 +0000 @@ -127,13 +127,13 @@ aclDumpDomainListWalkee(char * const & node_data, void *outlist) { /* outlist is really a wordlist ** */ - wordlistAdd((wordlist **)outlist, (char const *)node_data); + (*static_cast(outlist))->add((char const *) node_data); } wordlist * ACLDomainData::dump() { - wordlist *wl = NULL; + wordlist *wl = new wordlist; /* damn this is VERY inefficient for long ACL lists... filling * a wordlist this way costs Sum(1,N) iterations. For instance * a 1000-elements list will be filled in 499500 iterations. === modified file 'src/ACLHTTPHeaderData.cc' --- src/ACLHTTPHeaderData.cc 2007-05-29 19:31:36 +0000 +++ src/ACLHTTPHeaderData.cc 2008-08-13 07:05:45 +0000 @@ -73,11 +73,8 @@ wordlist * ACLHTTPHeaderData::dump() { - wordlist *W = NULL; - wordlistAdd(&W, hdrName.buf()); - wordlist * regex_dump = regex_rule->dump(); - wordlistAddWl(&W, regex_dump); - wordlistDestroy(®ex_dump); + wordlist *W = new wordlist(hdrName.buf()); + W->append(regex_rule->dump()); return W; } === modified file 'src/ACLHTTPStatus.cc' --- src/ACLHTTPStatus.cc 2007-04-29 04:26:37 +0000 +++ src/ACLHTTPStatus.cc 2008-08-09 16:13:04 +0000 @@ -193,13 +193,13 @@ { static char buf[8]; node->toStr(buf, sizeof(buf)); - wordlistAdd((wordlist **)state, buf); + (*static_cast(state))->add(buf); } wordlist * ACLHTTPStatus::dump() const { - wordlist *w = NULL; + wordlist *w = new wordlist; data->walk(aclDumpHTTPStatusListWalkee, &w); return w; } === modified file 'src/ACLIP.cc' --- src/ACLIP.cc 2008-08-13 03:22:54 +0000 +++ src/ACLIP.cc 2008-08-13 06:16:53 +0000 @@ -73,7 +73,7 @@ assert(mb.max_capacity > 0 && 2==2 ); mb.append(tmpbuf, strlen(tmpbuf) ); assert(mb.max_capacity > 0 && 3==3); - wordlistAdd(W, mb.buf); + (*W)->add(mb.buf); mb.clean(); } @@ -433,7 +433,7 @@ wordlist * ACLIP::dump() const { - wordlist *w = NULL; + wordlist *w = new wordlist; data->walk (DumpIpListWalkee, &w); return w; } === modified file 'src/ACLIntRange.cc' --- src/ACLIntRange.cc 2008-07-09 11:55:41 +0000 +++ src/ACLIntRange.cc 2008-08-07 16:03:51 +0000 @@ -111,7 +111,7 @@ wordlist * ACLIntRange::dump () { - wordlist *W = NULL; + wordlist *W = new wordlist; char buf[32]; CbDataListIterator iter(ranges); @@ -123,7 +123,7 @@ else snprintf(buf, sizeof(buf), "%d-%d", element.start, element.end-1); - wordlistAdd(&W, buf); + W->add(buf); } return W; === modified file 'src/ACLMaxConnection.cc' --- src/ACLMaxConnection.cc 2007-04-29 04:26:37 +0000 +++ src/ACLMaxConnection.cc 2008-08-07 16:03:51 +0000 @@ -104,13 +104,13 @@ if (!limit) return NULL; - wordlist *W = NULL; + wordlist *W = new wordlist; char buf[32]; snprintf(buf, sizeof(buf), "%d", limit); - wordlistAdd(&W, buf); + W->add(buf); return W; } === modified file 'src/ACLMaxUserIP.cc' --- src/ACLMaxUserIP.cc 2008-06-13 13:36:53 +0000 +++ src/ACLMaxUserIP.cc 2008-08-07 16:03:51 +0000 @@ -174,16 +174,16 @@ if (!maximum) return NULL; - wordlist *W = NULL; + wordlist *W = new wordlist; if (flags.strict) - wordlistAdd(&W, "-s"); + W->add("-s"); char buf[128]; snprintf(buf, sizeof(buf), "%lu", (unsigned long int) maximum); - wordlistAdd(&W, buf); + W->add(buf); return W; } === modified file 'src/ACLMethodData.cc' --- src/ACLMethodData.cc 2008-07-09 11:55:41 +0000 +++ src/ACLMethodData.cc 2008-08-07 16:03:51 +0000 @@ -70,11 +70,11 @@ wordlist * ACLMethodData::dump() { - wordlist *W = NULL; + wordlist *W=new wordlist; CbDataList *data = values; while (data != NULL) { - wordlistAdd(&W, RequestMethodStr(data->element)); + W->add(RequestMethodStr(data->element)); data = data->next; } === modified file 'src/ACLProtocolData.cc' --- src/ACLProtocolData.cc 2008-07-09 11:55:41 +0000 +++ src/ACLProtocolData.cc 2008-08-07 16:03:51 +0000 @@ -69,11 +69,11 @@ wordlist * ACLProtocolData::dump() { - wordlist *W = NULL; + wordlist *W = new wordlist; CbDataList *data = values; while (data != NULL) { - wordlistAdd(&W, ProtocolStr[data->element]); + W->add(ProtocolStr[data->element]); data = data->next; } === modified file 'src/ACLRegexData.cc' --- src/ACLRegexData.cc 2008-03-16 21:48:45 +0000 +++ src/ACLRegexData.cc 2008-08-07 16:03:51 +0000 @@ -103,11 +103,11 @@ wordlist * ACLRegexData::dump() { - wordlist *W = NULL; + wordlist *W = new wordlist; relist *temp = data; while (temp != NULL) { - wordlistAdd(&W, temp->pattern); + W->add(temp->pattern); temp = temp->next; } === modified file 'src/ACLSslErrorData.cc' --- src/ACLSslErrorData.cc 2008-07-09 11:55:41 +0000 +++ src/ACLSslErrorData.cc 2008-08-07 16:03:51 +0000 @@ -34,11 +34,11 @@ wordlist * ACLSslErrorData::dump() { - wordlist *W = NULL; + wordlist *W = new wordlist; CbDataList *data = values; while (data != NULL) { - wordlistAdd(&W, sslFindErrorString(data->element)); + W->add(sslFindErrorString(data->element)); data = data->next; } === modified file 'src/ACLStringData.cc' --- src/ACLStringData.cc 2007-04-29 04:26:37 +0000 +++ src/ACLStringData.cc 2008-08-09 16:13:04 +0000 @@ -86,13 +86,13 @@ aclDumpStringWalkee(char * const & node_data, void *outlist) { /* outlist is really a wordlist ** */ - wordlistAdd((wordlist **)outlist, node_data); + (*static_cast(outlist))->add(node_data); } wordlist * ACLStringData::dump() { - wordlist *wl = NULL; + wordlist *wl = new wordlist; /* damn this is VERY inefficient for long ACL lists... filling * a wordlist this way costs Sum(1,N) iterations. For instance * a 1000-elements list will be filled in 499500 iterations. === modified file 'src/ACLTimeData.cc' --- src/ACLTimeData.cc 2008-03-16 21:48:45 +0000 +++ src/ACLTimeData.cc 2008-08-07 16:03:51 +0000 @@ -102,7 +102,7 @@ wordlist * ACLTimeData::dump() { - wordlist *W = NULL; + wordlist *W = new wordlist; char buf[128]; ACLTimeData *t = this; @@ -116,7 +116,7 @@ t->weekbits & ACL_FRIDAY ? 'F' : '-', t->weekbits & ACL_SATURDAY ? 'A' : '-', t->start / 60, t->start % 60, t->stop / 60, t->stop % 60); - wordlistAdd(&W, buf); + W->add(buf); t = t->next; } === modified file 'src/ACLUserData.cc' --- src/ACLUserData.cc 2007-04-29 04:26:37 +0000 +++ src/ACLUserData.cc 2008-08-07 16:03:51 +0000 @@ -100,23 +100,23 @@ aclDumpUserListWalkee(char * const & node_data, void *outlist) { /* outlist is really a wordlist ** */ - wordlistAdd((wordlist **)outlist, (char const *)node_data); + (*static_cast(outlist))->add(node_data); } wordlist * ACLUserData::dump() { - wordlist *wl = NULL; + wordlist *wl = new wordlist; if (flags.case_insensitive) - wordlistAdd(&wl, "-i"); + wl->add("-i"); /* damn this is VERY inefficient for long ACL lists... filling * a wordlist this way costs Sum(1,N) iterations. For instance * a 1000-elements list will be filled in 499500 iterations. */ if (flags.required) - wordlistAdd(&wl, "REQUIRED"); + wl->add("REQUIRED"); else if (names) names->walk(aclDumpUserListWalkee, &wl); === modified file 'src/ICAP/ICAPConfig.cc' --- src/ICAP/ICAPConfig.cc 2008-04-03 05:31:29 +0000 +++ src/ICAP/ICAPConfig.cc 2008-08-09 16:13:04 +0000 @@ -43,7 +43,6 @@ #include "HttpRequest.h" #include "HttpReply.h" #include "ACLChecklist.h" -#include "wordlist.h" ICAPConfig TheICAPConfig; === modified file 'src/ICAP/ICAPOptions.cc' --- src/ICAP/ICAPOptions.cc 2007-05-29 19:31:36 +0000 +++ src/ICAP/ICAPOptions.cc 2008-08-10 22:19:32 +0000 @@ -155,11 +155,11 @@ }; ICAPOptions::TransferList::~TransferList() { - wordlistDestroy(&extensions); + delete extensions; }; void ICAPOptions::TransferList::add(const char *extension) { - wordlistAdd(&extensions, extension); + extensions->add(extension); }; bool ICAPOptions::TransferList::matches(const String &urlPath) const { === modified file 'src/Makefile.am' --- src/Makefile.am 2008-08-09 05:59:55 +0000 +++ src/Makefile.am 2008-08-13 14:28:09 +0000 @@ -1188,6 +1188,7 @@ tests/testStore \ tests/testString \ tests/testURL \ + tests/testWordlist \ @STORE_TESTS@ ## Special Universal .h dependency test script @@ -2513,3 +2514,28 @@ @REPL_OBJS@ \ @SQUID_CPPUNIT_LA@ \ ${ADAPTATION_LIBS} + +tests_testWordlist_SOURCES = \ + tests/testWordlist.h tests/testWordlist.cc \ + wordlist.cc \ + tests/testMain.cc \ + time.cc \ + mem.cc \ + MemBuf.cc \ + tests/stub_cache_manager.cc \ + tests/stub_event.cc \ + tests/stub_tools.cc \ + $(TESTSOURCES) + + +tests_testWordlist_LDADD = \ + @SQUID_CPPUNIT_LIBS@ \ + @SQUID_CPPUNIT_LA@ \ + @XTRA_LIBS@ \ + libsquid.la \ + -L../lib -lmiscutil +tests_testWordlist_LDFLAGS = $(LIBADD_DL) +tests_testWordlist_DEPENDENCIES = \ + $(top_builddir)/lib/libmiscutil.a \ + @SQUID_CPPUNIT_LA@ \ + $(top_builddir)/lib/libmiscutil.a === modified file 'src/RemovalPolicy.h' --- src/RemovalPolicy.h 2006-08-21 06:50:40 +0000 +++ src/RemovalPolicy.h 2008-08-09 16:13:04 +0000 @@ -45,7 +45,8 @@ { public: - RemovalPolicySettings() : type(NULL), args(NULL) {}; + RemovalPolicySettings() : type(NULL), args(new wordlist) {}; + ~RemovalPolicySettings() { if (args) delete args; } char *type; wordlist *args; === modified file 'src/URLScheme.cc' --- src/URLScheme.cc 2006-05-09 05:38:33 +0000 +++ src/URLScheme.cc 2008-08-13 14:28:09 +0000 @@ -35,7 +35,6 @@ #include "squid.h" #include "URLScheme.h" -#include "wordlist.h" const char *ProtocolStr[] = { === modified file 'src/adaptation/ServiceGroups.cc' --- src/adaptation/ServiceGroups.cc 2008-04-03 23:11:40 +0000 +++ src/adaptation/ServiceGroups.cc 2008-08-12 19:57:38 +0000 @@ -21,11 +21,11 @@ { ConfigParser::ParseString(&id); - wordlist *names = NULL; + wordlist *names = new wordlist; ConfigParser::ParseWordList(&names); for (wordlist *i = names; i; i = i->next) services.push_back(i->key); - wordlistDestroy(&names); + delete names; } void === modified file 'src/asn.cc' --- src/asn.cc 2008-07-12 15:51:24 +0000 +++ src/asn.cc 2008-08-07 16:03:51 +0000 @@ -551,13 +551,13 @@ wordlist * ACLASN::dump() { - wordlist *W = NULL; + wordlist *W = new wordlist; char buf[32]; CbDataList *ldata = data; while (ldata != NULL) { snprintf(buf, sizeof(buf), "%d", ldata->element); - wordlistAdd(&W, buf); + W->add(buf); ldata = ldata->next; } === modified file 'src/auth/basic/auth_basic.cc' --- src/auth/basic/auth_basic.cc 2008-07-09 14:38:11 +0000 +++ src/auth/basic/auth_basic.cc 2008-08-12 19:57:38 +0000 @@ -223,8 +223,10 @@ void AuthBasicConfig::done() { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } if (basicAuthRealm) safe_free(basicAuthRealm); @@ -326,9 +328,12 @@ AuthBasicConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) { if (strcasecmp(param_str, "program") == 0) { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } + authenticate = new wordlist; parse_wordlist(&authenticate); requirePathnameExists("authparam basic program", authenticate->key); === modified file 'src/auth/digest/auth_digest.cc' --- src/auth/digest/auth_digest.cc 2008-07-09 14:38:11 +0000 +++ src/auth/digest/auth_digest.cc 2008-08-12 19:57:38 +0000 @@ -900,8 +900,10 @@ void AuthDigestConfig::done() { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } safe_free(digestAuthRealm); } @@ -927,9 +929,12 @@ AuthDigestConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) { if (strcasecmp(param_str, "program") == 0) { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } + authenticate = new wordlist; //wordlist MUST be a valid object parse_wordlist(&authenticate); requirePathnameExists("authparam digest program", authenticate->key); === modified file 'src/auth/negotiate/auth_negotiate.cc' --- src/auth/negotiate/auth_negotiate.cc 2008-08-06 12:51:15 +0000 +++ src/auth/negotiate/auth_negotiate.cc 2008-08-12 19:57:38 +0000 @@ -126,8 +126,10 @@ void AuthNegotiateConfig::done() { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } } void @@ -154,9 +156,12 @@ AuthNegotiateConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) { if (strcasecmp(param_str, "program") == 0) { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } + authenticate = new wordlist; parse_wordlist(&authenticate); requirePathnameExists("authparam negotiate program", authenticate->key); === modified file 'src/auth/ntlm/auth_ntlm.cc' --- src/auth/ntlm/auth_ntlm.cc 2008-07-09 14:28:16 +0000 +++ src/auth/ntlm/auth_ntlm.cc 2008-08-12 19:57:38 +0000 @@ -108,8 +108,10 @@ void AuthNTLMConfig::done() { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } } void @@ -136,9 +138,12 @@ AuthNTLMConfig::parse(AuthConfig * scheme, int n_configured, char *param_str) { if (strcasecmp(param_str, "program") == 0) { - if (authenticate) - wordlistDestroy(&authenticate); + if (authenticate) { + delete authenticate; + authenticate = NULL; + } + authenticate = new wordlist; parse_wordlist(&authenticate); requirePathnameExists("authparam ntlm program", authenticate->key); === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2008-08-10 05:05:45 +0000 +++ src/cache_cf.cc 2008-08-12 19:57:38 +0000 @@ -463,7 +463,8 @@ if (Config.Program.redirect) { if (Config.redirectChildren < 1) { Config.redirectChildren = 0; - wordlistDestroy(&Config.Program.redirect); + delete Config.Program.redirect; + Config.Program.redirect = NULL; } } @@ -928,7 +929,7 @@ } storeAppendPrintf(entry, "\n"); - wordlistDestroy(&w); + delete w; ae = ae->next; } } @@ -1951,7 +1952,7 @@ while ((p = *head) != NULL) { *head = p->next; xfree(p->passwd); - wordlistDestroy(&p->actions); + delete p->actions; xfree(p); } } @@ -2606,8 +2607,11 @@ char *token; char *t = strtok(NULL, ""); + if (*list == NULL) + *list = new wordlist; + while ((token = strwordtok(NULL, &t))) - wordlistAdd(list, token); + (*list)->add(token); } #if 0 /* now unused */ @@ -2624,7 +2628,6 @@ return a == NULL; } -#define free_wordlist wordlistDestroy #define free_uri_whitespace free_int @@ -2677,7 +2680,7 @@ free_string(&(*settings)->type); - free_wordlist(&(*settings)->args); + delete (*settings)->args; delete *settings; === modified file 'src/client_side_request.cc' --- src/client_side_request.cc 2008-08-13 03:24:57 +0000 +++ src/client_side_request.cc 2008-08-13 06:16:53 +0000 @@ -667,7 +667,7 @@ const char *url = http->uri; HttpRequest *request = http->request; HttpRequestMethod method = request->method; - const wordlist *p = NULL; + const wordlist *p; /* * IMS needs a private key, so we can use the hierarchy for IMS only if our === modified file 'src/dns.cc' --- src/dns.cc 2008-07-13 08:37:43 +0000 +++ src/dns.cc 2008-08-12 19:57:38 +0000 @@ -81,14 +81,14 @@ assert(dnsservers->cmdline == NULL); - wordlistAdd(&dnsservers->cmdline, Config.Program.dnsserver); + dnsservers->cmdline->add(Config.Program.dnsserver); if (Config.onoff.res_defnames) - wordlistAdd(&dnsservers->cmdline, "-D"); + dnsservers->cmdline->add("-D"); for (w = Config.dns_nameservers; w != NULL; w = w->next) { - wordlistAdd(&dnsservers->cmdline, "-s"); - wordlistAdd(&dnsservers->cmdline, w->key); + dnsservers->cmdline->add("-s"); + dnsservers->cmdline->add(w->key); } helperOpenServers(dnsservers); @@ -102,7 +102,8 @@ helperShutdown(dnsservers); - wordlistDestroy(&dnsservers->cmdline); + delete dnsservers->cmdline; + dnsservers->cmdline = NULL; if (!shutting_down) return; === modified file 'src/errorpage.cc' --- src/errorpage.cc 2008-08-09 05:59:55 +0000 +++ src/errorpage.cc 2008-08-12 19:57:38 +0000 @@ -482,7 +482,8 @@ safe_free(err->url); safe_free(err->dnsserver_msg); safe_free(err->request_hdrs); - wordlistDestroy(&err->ftp.server_msg); + delete err->ftp.server_msg; + err->ftp.server_msg = NULL; safe_free(err->ftp.request); safe_free(err->ftp.reply); AUTHUSERREQUESTUNLOCK(err->auth_user_request, "errstate"); @@ -556,7 +557,7 @@ str.Printf("FTP Request: %s\r\n", ftp.request); str.Printf("FTP Reply: %s\r\n", ftp.reply); str.Printf("FTP Msg: "); - wordlistCat(ftp.server_msg, &str); + ftp.server_msg->cat(&str); str.Printf("\r\n"); } @@ -635,7 +636,7 @@ case 'g': /* FTP SERVER MESSAGE */ - wordlistCat(ftp.server_msg, &mb); + ftp.server_msg->cat(&mb); break; === modified file 'src/external_acl.cc' --- src/external_acl.cc 2008-07-13 08:37:43 +0000 +++ src/external_acl.cc 2008-08-12 19:57:38 +0000 @@ -194,7 +194,8 @@ cbdataFree(f); } - wordlistDestroy(&p->cmdline); + delete p->cmdline; + p->cmdline = NULL; if (p->theHelper) { helperShutdown(p->theHelper); @@ -403,7 +404,7 @@ if (!token) self_destruct(); - wordlistAdd(&a->cmdline, token); + a->cmdline->add(token); /* arguments */ parse_wordlist(&a->cmdline); @@ -578,7 +579,8 @@ free_external_acl_data(void *data) { external_acl_data *p = static_cast(data); - wordlistDestroy(&p->arguments); + delete p->arguments; + p->arguments = NULL; cbdataReferenceDone(p->def); } @@ -605,7 +607,7 @@ self_destruct(); while ((token = strtokFile())) { - wordlistAdd(&data->arguments, token); + data->arguments->add(token); } } @@ -747,7 +749,7 @@ ACLExternal::dump() const { external_acl_data const *acl = data; - wordlist *result = NULL; + wordlist *result = new wordlist; wordlist *arg; MemBuf mb; mb.init(); @@ -757,7 +759,7 @@ mb.Printf(" %s", arg->key); } - wordlistAdd(&result, mb.buf); + result->add(mb.buf); mb.clean(); return result; } === modified file 'src/fqdncache.cc' --- src/fqdncache.cc 2008-07-12 15:40:56 +0000 +++ src/fqdncache.cc 2008-08-09 16:13:04 +0000 @@ -857,13 +857,15 @@ fce = fqdncacheCreateEntry(addr); - while (hostnames) { - fce->names[j] = xstrdup(hostnames->key); - j++; - hostnames = hostnames->next; + if (!hostnames->isEmpty()) { + while (hostnames) { + fce->names[j] = xstrdup(hostnames->key); + j++; + hostnames = hostnames->next; - if (j >= FQDN_MAX_NAMES) - break; + if (j >= FQDN_MAX_NAMES) + break; + } } fce->name_count = j; === modified file 'src/ftp.cc' --- src/ftp.cc 2008-07-22 12:33:41 +0000 +++ src/ftp.cc 2008-08-12 19:57:38 +0000 @@ -455,13 +455,13 @@ } if (pathcomps) - wordlistDestroy(&pathcomps); + delete pathcomps; if (ctrl.message) - wordlistDestroy(&ctrl.message); + delete ctrl.message; if (cwd_message) - wordlistDestroy(&cwd_message); + delete cwd_message; safe_free(ctrl.last_reply); @@ -570,7 +570,8 @@ printfReplyBody("
\n"); - wordlistDestroy(&cwd_message); + delete cwd_message; + cwd_message = NULL; } printfReplyBody("

\n"); @@ -1727,8 +1728,10 @@ *used = (size_t) (s - sbuf); safe_free(sbuf); - if (!complete) - wordlistDestroy(&head); + if (!complete) { + delete head; + head = NULL; + } if (codep) *codep = code; @@ -1834,7 +1837,7 @@ { wordlist **W; size_t bytes_used = 0; - wordlistDestroy(&ctrl.message); + delete ctrl.message; ctrl.message = ftpParseControlReply(ctrl.buf, ctrl.offset, &ctrl.replycode, &bytes_used); @@ -1864,12 +1867,12 @@ ctrl.last_reply = xstrdup((*W)->key); - wordlistDestroy(W); + delete *W; /* Copy the rest of the message to cwd_message to be printed in * error messages */ - wordlistAddWl(&cwd_message, ctrl.message); + *cwd_message += *ctrl.message; debugs(9, 3, HERE << "state=" << state << ", code=" << ctrl.replycode); @@ -2049,7 +2052,7 @@ rfc1738_unescape(d); if (*d) - wordlistAdd(&ftpState->pathcomps, d); + ftpState->pathcomps->add(d); } xfree(path); @@ -2140,8 +2143,10 @@ ftpState->unhack(); /* Reset cwd_message to only include the last message */ - if (ftpState->cwd_message) - wordlistDestroy(&ftpState->cwd_message); + if (ftpState->cwd_message) { + delete ftpState->cwd_message; + ftpState->cwd_message = NULL; + } ftpState->cwd_message = ftpState->ctrl.message; @@ -3396,8 +3401,10 @@ debugs(9, 3, HERE); - if (ftpState->pathcomps) - wordlistDestroy(&ftpState->pathcomps); + if (ftpState->pathcomps) { + delete ftpState->pathcomps; + ftpState->pathcomps = NULL; + } safe_free(ftpState->filepath); === modified file 'src/net_db.cc' --- src/net_db.cc 2008-07-19 10:16:48 +0000 +++ src/net_db.cc 2008-08-12 19:57:38 +0000 @@ -656,7 +656,7 @@ return w->key; } - return wordlistAdd(&peer_names, name); + return peer_names->add(name); } static void @@ -902,6 +902,8 @@ #if USE_ICMP int n; + peer_names = new wordlist; + netdbRegisterWithCacheManager(); if (addr_table) @@ -919,6 +921,7 @@ netdbReloadState(); + #endif } @@ -978,7 +981,7 @@ hashFreeItems(host_table, netdbFreeNameEntry); hashFreeMemory(host_table); host_table = NULL; - wordlistDestroy(&peer_names); + delete peer_names; peer_names = NULL; #endif } === modified file 'src/protos.h' --- src/protos.h 2008-07-17 12:38:06 +0000 +++ src/protos.h 2008-08-08 12:23:50 +0000 @@ -61,7 +61,6 @@ */ SQUIDCEXTERN void configFreeMemory(void); class MemBuf; -SQUIDCEXTERN void wordlistCat(const wordlist *, MemBuf * mb); SQUIDCEXTERN void self_destruct(void); SQUIDCEXTERN void add_http_port(char *portspec); extern int xatoi(const char *token); === modified file 'src/repl/lru/store_repl_lru.cc' --- src/repl/lru/store_repl_lru.cc 2007-04-25 17:30:14 +0000 +++ src/repl/lru/store_repl_lru.cc 2008-08-09 16:13:04 +0000 @@ -329,7 +329,7 @@ RemovalPolicy *policy; LruPolicyData *lru_data; /* no arguments expected or understood */ - assert(!args); + assert(args==NULL || args->isEmpty()); /* Initialize */ if (!lru_node_pool) { === modified file 'src/tests/stub_cache_cf.cc' --- src/tests/stub_cache_cf.cc 2007-04-06 18:15:45 +0000 +++ src/tests/stub_cache_cf.cc 2008-08-07 16:03:51 +0000 @@ -80,8 +80,10 @@ char *token; char *t = strtok(NULL, ""); + assert(*list != NULL); //wordlist myst be defined here + while ((token = strwordtok(NULL, &t))) - wordlistAdd(list, token); + (*list)->add(token); } void === added file 'src/tests/stub_debug.cc' --- src/tests/stub_debug.cc 1970-01-01 00:00:00 +0000 +++ src/tests/stub_debug.cc 2008-08-11 14:54:43 +0000 @@ -0,0 +1,40 @@ +/* + * stub_debug.cc + * + * AUTHOR: Francesco Chemolli + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "config.h" +#include "Debug.h" +#include + +void +Debug::parseOptions(char const *options) { } + === added file 'src/tests/stub_event.cc' --- src/tests/stub_event.cc 1970-01-01 00:00:00 +0000 +++ src/tests/stub_event.cc 2008-08-10 22:19:32 +0000 @@ -0,0 +1,41 @@ +/* + * stub_event.cc + * + * AUTHOR: Francesco Chemolli + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "config.h" +#include "event.h" + +void +eventAdd(const char *name, EVH * func, void *arg, double when, int weight, bool +cbdata) +{ +} === added file 'src/tests/testWordlist.cc' --- src/tests/testWordlist.cc 1970-01-01 00:00:00 +0000 +++ src/tests/testWordlist.cc 2008-08-13 07:05:45 +0000 @@ -0,0 +1,195 @@ +#define SQUID_UNIT_TEST 1 + +#include "squid.h" +#include + +#include "Mem.h" +#include "MemBuf.h" +#include "wordlist.h" +#include "testWordlist.h" +#include + +CPPUNIT_TEST_SUITE_REGISTRATION( testWordlist ); + +const char *words[] = { + "foo", "bar", "gazonk", "baz", "squid", "cache", "test", NULL + }; + +std::ostream& +operator << (std::ostream & str, wordlist & wl) +{ + wordlist *w= &wl; + while (w != NULL) { + if (w->key!=NULL) + str << w->key << ", "; + w = w->next; + } + return str; +} + +void +testWordlist::setUp() +{ + Mem::Init(); + /* std::cerr << "testWordlist::setUp()" << std::endl; */ +} + +void +testWordlist::testWordlistCreation() +{ + wordlist w1; + wordlist *w2 = new wordlist; + wordlist *w3 = new wordlist("foo"); + + CPPUNIT_ASSERT(w2 != NULL); + CPPUNIT_ASSERT(w3 != NULL); + + /* + std::cerr << "testWordlistCreation: w1 = {" << w1 << "}, w2 = {" << *w2 << + "}, w3 = {" << *w3 << "}" << std::endl; + */ + + delete w2; + delete w3; +} + +void +testWordlist::testEqualityTest() +{ + wordlist *w1=new wordlist; + wordlist *w2=new wordlist; + int j=0; + + while (words[j] != NULL) { + //std::cerr << "adding: " << words[j] << std::endl; + w1->add(words[j]); + w2->add(words[j]); + ++j; + } + /* + std::cerr << "testWordlist::testEqualityTest: w1 = {" << *w1 << + "}, w2 = {" << *w2 << "}" << std::endl; + */ + + CPPUNIT_ASSERT(*w1 == *w2); //test equality + delete w2; + + w2 = new wordlist(words[0]); + CPPUNIT_ASSERT(! (*w1 == *w2)); //inequality due to different lengths + delete w2; + + w2 = new wordlist("differentstring");; + j=1; + while (words[j] != NULL) { + w2->add(words[j]); + ++j; + } + CPPUNIT_ASSERT(! (*w1 == *w2)); //inequality due to different contents + + delete w1; + delete w2; +} + +void +testWordlist::testConstructors() +{ + wordlist *w1 = new wordlist(words[0]); + wordlist *w2 = new wordlist; + w2->add(words[0]); + + CPPUNIT_ASSERT(*w1 == *w2); + delete w1; + delete w2; +} + +void +testWordlist::testConcatenation() +{ + wordlist w1, w2; + + int j=0; + + while (words[j] != NULL) { + w1.add(words[j]); + w2.add(words[j]); + ++j; + } + + j=0; + w2 += w1; + while (words[j] != NULL) { + w1.add(words[j]); + ++j; + } + + /* + std::cerr << "testWordlist::testConcatenation: w1 = {" << w1 << + "}, w2 = {" << w2 << "}" << std::endl; + */ + + CPPUNIT_ASSERT(w1 == w2); +} + +void +testWordlist::testCat() +{ + MemBuf mb; + wordlist wl; + int j=0; + char *benchmark = new char[4096]; + + mb.init(1024,4096); + + while (words[j] != NULL) { + wl.add(words[j]); + ++j; + } + j=0; + while (words[j] != NULL) { + strcat(benchmark,words[j]); + strcat(benchmark,"\n"); + j++; + } + wl.cat(&mb); + //std::cerr << "mb: {" <add(words[j]); + w2->add(words[j]); + ++j; + } + + w1->append(w2); + w2 = new wordlist(); //not a leak, will be managed by w1 now + j=0; + while (words[j] != NULL) { + w2->add(words[j]); + ++j; + } + j=0; + while (words[j] != NULL) { + w2->add(words[j]); + ++j; + } + + w3->append(w2); + + std::cerr << "testWordlist::testAppend: w1 = {" << *w1 <<"}, w2 = {" + << *w2 << "}, w3 = {" << *w3 << "}" < + +/* + * test the wordlist functionality + */ + +class testWordlist : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testWordlist ); + CPPUNIT_TEST( testWordlistCreation ); + CPPUNIT_TEST( testEqualityTest ); + CPPUNIT_TEST( testConstructors ); + CPPUNIT_TEST( testConcatenation ); + CPPUNIT_TEST( testAppend ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + +protected: + void testWordlistCreation(); + void testEqualityTest(); + void testConstructors(); + void testConcatenation(); + void testCat(); + void testAppend(); +}; + +#endif + === modified file 'src/tools.cc' --- src/tools.cc 2008-07-17 12:27:10 +0000 +++ src/tools.cc 2008-08-12 19:57:38 +0000 @@ -1105,7 +1105,7 @@ #endif while (fgets(buf, 1024, fp)) { /* for each line */ - wordlist *hosts = NULL; + wordlist *hosts = new wordlist; char *addr; if (buf[0] == '#') /* MS-windows likes to add comments */ @@ -1154,7 +1154,7 @@ if (ipcacheAddEntryFromHosts(host, addr) != 0) goto skip; /* invalid address, continuing is useless */ - wordlistAdd(&hosts, host); + hosts->add(host); lt = nt + 1; } @@ -1162,7 +1162,8 @@ fqdncacheAddEntryFromHosts(addr, hosts); skip: - wordlistDestroy(&hosts); + delete hosts; + hosts = NULL; } fclose (fp); === modified file 'src/wordlist.cc' --- src/wordlist.cc 2006-04-23 17:10:29 +0000 +++ src/wordlist.cc 2008-08-13 15:45:13 +0000 @@ -35,78 +35,178 @@ #include "wordlist.h" #include "MemBuf.h" - -void -wordlistDestroy(wordlist ** list) -{ - wordlist *w = NULL; - - while ((w = *list) != NULL) { - *list = w->next; - safe_free(w->key); - delete w; - } - - *list = NULL; -} - +#include "Store.h" + +/** + \defgroup wordlist Word List + \par + * A wordlist is an ordered list of copied C-style strings, copied + * upon adding to the list. + */ + +/** + * wordlist destructor. Frees all associated storage. + */ +wordlist::~wordlist() +{ + empty(); +} + +/** + * creates a wordlist already containing the first element. + \param word a NULL-terminated string to add + */ +wordlist::wordlist(const char * word): next(NULL) +{ + key = xstrdup(word); +} + +/** + * add a word to the wordlist. + \param word a NULL-terminated string to add + \retval the original added string + */ const char * -wordlistAdd(wordlist ** list, const char *key) -{ - while (*list) - list = &(*list)->next; - - *list = new wordlist; - - (*list)->key = xstrdup(key); - - (*list)->next = NULL; - - return (*list)->key; -} - -void -wordlistJoin(wordlist ** list, wordlist ** wl) -{ - while (*list) - list = &(*list)->next; - - *list = *wl; - +wordlist::add(const char *word) +{ + wordlist *cur=this; + + if (key==NULL) { //special case empty wordlist + key = xstrdup(word); + return word; + } + + while (cur->next != NULL) + cur = cur->next; + + cur->next = new wordlist(word); + + return word; +} + +/** + \param word a NULL-terminated string to add + * syntactically-sugar-coated version of wordlist::add(word) + */ +wordlist & +wordlist::operator += (const char * word ) { + add(word); + return *this; +} + +/** + \param otherwl wordlist to concatenate to this + * appends (copies) all elements of the supplied list to this. + */ +void +wordlist::add_wordlist(wordlist & otherwl) +{ + wordlist *list=this, *wl=&otherwl; + + if (key == NULL) { //special-case: empty list. Consume one word + list->key=xstrdup(wl->key); + wl=wl->next; + } else { //walk till the last element of the list + while (list->next != NULL) + list = list->next; + } + + while (wl!=NULL) { + list->next = new wordlist(wl->key); + list = list->next; + wl = wl->next; + } +} + +/** + \param otherwl wordlist to concatenate to this + * syntactically-sugar-coated version of wordlist::add_wordlist. + */ +wordlist & +wordlist::operator += (wordlist & otherwl) +{ + add_wordlist(otherwl); + return *this; +} + +/** + * Appends all words in the wordlist to the supplied membuf, newline-separated. + */ +void +wordlist::cat(MemBuf * mb) +{ + wordlist *w=this; + if (key!=NULL) //special case: empty list + while (NULL != w) { + mb->Printf("%s\n", w->key); + w = w->next; + } +} + +// this is needed for the config parser +void free_wordlist (wordlist ** wl) { + delete *wl; *wl = NULL; } -void -wordlistAddWl(wordlist ** list, wordlist * wl) -{ - while (*list) - list = &(*list)->next; - - for (; wl; wl = wl->next, list = &(*list)->next) { - *list = new wordlist(); - (*list)->key = xstrdup(wl->key); - (*list)->next = NULL; - } -} - -void -wordlistCat(const wordlist * w, MemBuf * mb) -{ - while (NULL != w) { - mb->Printf("%s\n", w->key); - w = w->next; - } -} - -wordlist * -wordlistDup(const wordlist * w) -{ - wordlist *D = NULL; - - while (NULL != w) { - wordlistAdd(&D, w->key); - w = w->next; - } - - return D; +/** + * Convenience function, returns true if the wordlist is empty + */ +bool wordlist::isEmpty(void) { + return (key==NULL); +} + +/** + * Tests equality of two wordlists by checking their contents. + * It's only needed for the unit-tests really... + */ +bool +wordlist::operator == (const wordlist &wl) const +{ + const wordlist *k2 = &wl; + const wordlist *k1 = this; + + while (k1 != NULL && k2 != NULL) { + if (0!=strcmp(k1->key,k2->key)) + return false; + k1=k1->next; + k2=k2->next; + } + if (k1==NULL && k2==NULL) //all keys were equal and length is equal + return true; + return false; +} + +/** + * appends the supplied wordlist to the current one. DOES NOT copy the values, + * thus the caller should forget about the argument supplied as it will + * be freed when the current object gets deleted + */ +void +wordlist::append (wordlist *wl) { + wordlist *W=this; + if (key == NULL) { //empty wordlist + key = wl->key; + wl=wl->next; + } + while (W->next != NULL) //reach the end of the wordlist + W=W->next; + W->next=wl; //append the other wordlist +} + +/** + * empties a wordlist's contents, resetting it. + */ +void wordlist::empty(void) +{ + wordlist *w = this->next, *e; + + while (w != NULL) { + e=w; + w = w->next; + safe_free(e->key); + } + safe_free(key); //already set to NULL by safe_free + next=NULL; + } === modified file 'src/wordlist.h' --- src/wordlist.h 2008-03-20 11:30:19 +0000 +++ src/wordlist.h 2008-08-13 14:28:09 +0000 @@ -35,6 +35,8 @@ #include "squid.h" #include "MemPool.h" +class MemBuf; //stub declaration + class wordlist { @@ -42,14 +44,26 @@ MEMPROXY_CLASS(wordlist); char *key; wordlist *next; + + wordlist(const char * initial_key); + wordlist() : key(NULL), next(NULL) { } + ~wordlist(); + const char * add(const char * word); + wordlist & operator += (const char * word ); + void add_wordlist(wordlist & otherwl); + wordlist & operator += (wordlist & otherwl); + bool isEmpty(void); + + void cat (MemBuf *mb); + void append (wordlist *W); + + void empty(void); + + bool operator == (const wordlist &wl) const; }; MEMPROXY_CLASS_INLINE(wordlist); -SQUIDCEXTERN const char *wordlistAdd(wordlist **, const char *); -SQUIDCEXTERN void wordlistAddWl(wordlist **, wordlist *); -SQUIDCEXTERN void wordlistJoin(wordlist **, wordlist **); -SQUIDCEXTERN wordlist *wordlistDup(const wordlist *); -SQUIDCEXTERN void wordlistDestroy(wordlist **); +SQUIDCEXTERN void free_wordlist(wordlist **); //for cf_parser.h #endif /* SQUID_WORDLIST_H */ # Begin bundle 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