# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kinkie@squid-cache.org-20080812195738-d28oq2dr86vo0t9l # target_branch: file:///media/src/squid/repo/squid-trunk/ # testament_sha1: f96f2a37e1065776607bdc215ca3314fc4fe393e # timestamp: 2008-08-12 21:57:42 +0200 # base_revision_id: squid3@treenet.co.nz-20080812125950-\ # d69lme0f9b7ue81u # # 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-12 19:57:38 +0000 @@ -73,11 +73,10 @@ wordlist * ACLHTTPHeaderData::dump() { - wordlist *W = NULL; - wordlistAdd(&W, hdrName.buf()); + wordlist *W = new wordlist(hdrName.buf()); wordlist * regex_dump = regex_rule->dump(); - wordlistAddWl(&W, regex_dump); - wordlistDestroy(®ex_dump); + *W += *regex_dump; + delete regex_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-06-30 13:16:14 +0000 +++ src/ACLIP.cc 2008-08-09 16:13:04 +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-11 14:54:43 +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/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-06-09 01:58:19 +0000 +++ src/client_side_request.cc 2008-08-09 16:13:04 +0000 @@ -666,7 +666,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) +{ +} === modified file 'src/tests/stub_tools.cc' --- src/tests/stub_tools.cc 2006-09-15 02:13:23 +0000 +++ src/tests/stub_tools.cc 2008-08-11 14:54:43 +0000 @@ -45,3 +45,4 @@ { fatal ("Not implemented"); } + === added file 'src/tests/testWordlist.cc' --- src/tests/testWordlist.cc 1970-01-01 00:00:00 +0000 +++ src/tests/testWordlist.cc 2008-08-11 18:11:05 +0000 @@ -0,0 +1,166 @@ +#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: {" < + +/* + * 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( testCat ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + +protected: + void testWordlistCreation(); + void testEqualityTest(); + void testConstructors(); + void testConcatenation(); + void testCat(); +}; + +#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-12 18:05:42 +0000 @@ -35,78 +35,160 @@ #include "wordlist.h" #include "MemBuf.h" - -void -wordlistDestroy(wordlist ** list) +#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. + */ + +/** + \ingroup wordlist + * wordlist destructor. Frees all associated storage. + */ +wordlist::~wordlist() { - wordlist *w = NULL; + wordlist *w = this, *e; - while ((w = *list) != NULL) { - *list = w->next; - safe_free(w->key); - delete w; + while (w != NULL) { + e=w; + w = w->next; + safe_free(e->key); } - *list = NULL; -} - +} + +/** + \ingroup wordlist + * 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); +} + +/** + \ingroup wordlist + * 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 key; + } + + while (cur->next != NULL) + cur = cur->next; + + cur->next = new wordlist(word); + + return word; +} + +/** + \ingroup wordlist + \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; +} + +/** + \ingroup wordlist + \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; + } +} + +/** + \ingroup wordlist + \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; +} + +/** + \ingroup wordlist + * 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; +/** + \ingroup wordlist + * Convenience function, returns true if the wordlist is empty + */ +bool wordlist::isEmpty(void) { + return (key==NULL); +} + +/** + \ingroup wordlist + * 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; } === modified file 'src/wordlist.h' --- src/wordlist.h 2008-03-20 11:30:19 +0000 +++ src/wordlist.h 2008-08-12 19:57:38 +0000 @@ -35,6 +35,8 @@ #include "squid.h" #include "MemPool.h" +class MemBuf; //stub declaration + class wordlist { @@ -42,14 +44,23 @@ 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); + + 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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 4VSo2XWfx5dSZzszfLxsu7bJvbx3S6fVFJu7aRZm0aO3rprZLJBy3Uqk+cojt7SavcbpUbrd6Zzj viMfNm0Qwtlo7Va7pTdNFG7lm4ZppLsnbEd94aV4mpL+BJqzYcvhU1cK2Ye6uFnKiqP4RH5tOWkn CsOpLOFs+54TnSxdPLT0vu3ScMcvaT5+e2a7aKayifLudsbXj20Xxjhyw+Wb4ZZqO1NNHbRZhiOX D9F3TmLxKIgJ98JrKWVZJtGqT07cM1VV26ZRRVgjhm8ZuGGTZRRoyRsozeKrM2pVq3TXVbs2TlNR w5btkcKuVlllmicHDhykyctk2yrVmq3bLJv4ll2yJt2Tow/rR3T371UrIzaJnSyyizlRVhzFltdZ 7Ombxssmyyswu3Ubv4oNAdZN4cwq5HBdiV9SS7TOYLiZwAozKttBscRmg7tkO3DdRQqq9AeZVlRF wQmJjxgbUzSDYxIs3mVW2WE5NI84RcjsTgixGXA6Hl+0Sq1y3QYE9LySVk3h0m1cLEL0Xt+2vIeA Kv5Pj+TUWRqrnre1gVgTJVIUUTjJz94NPjI1qgaZPLTiPa66j7E26jLDZhotEVeQ5VUaqqoFpIrD ekmsapnVVJJE1hKwoLJETIQT1ApdKlMvOM+530atVXUNpJLIEZNlErxFYnq2asLl7poaN3TDRRdw kq7Ubn9nqnkq6KGenHnfW/5wh0su1TnllCOkkRG3jZ6eoZOk4Kt/z37zcttXbVyzXYZu0kPs666c UljZJVuv27707f1eNYxTDVkDlfZmu+VWikT4m7re2yU7E1Z1TpTlm2bNbmcI8SaKGbd6DoDECiHb NgWmgdmgZEXM8PBcozPWRZiBuJIiTpNpu0XTXSXcMNI9nPDbmcXk4k50Saq2SSevXTppk3dNHwTV YcPTh2s0cs8NL4pqn1SJ20ynulPZk1b+KsnDN7bummHLCSayj11C97UnKNZ9btl+s90uW5JkySdp LqONzrbZabnZ2skzaJNW6jZhu6dJqppOGHCTRoo/bOIRBu0VeOTNNRJJqq8WWdN27NV01YcHRkwy TcNW6rd03cqtW7Rk3ctm7J793MylOlUm7tk5frVoSZMlF1zts3cuUk1njnnW5WInomyeKumHLxos 4cqs2bDxZ0sk55owszbtUmaT8t3R07UXatUjN+H70K9Xbn5sRGQCRYcgknJbhJGQSQr6c9rEGg2T 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 tgcA