Package: apt Version: 0.6.38 Tags: patch Severity: wishlist Hi, I profiled aptitude a bit and found out that most of its slowness(*) is due to apt (which shouldn't be that much of a surprise, aptitude being mostly only a frontend for apt). Here's a patch that speeds up some things quite a bit, especially with some optimizations to aptitude too (which I will submit separately soon). Not all of the optimizations are that elegant, but in those cases they are really in some quite critical pieces of code, from aptitude's point of view. Unfortunately the patch breaks binary compatibility, but I have figured out that's quite normal for apt updates. Source compatibility I believe I did not break. I have only tested the patches enough (several days on one computer) to figure out they work for me; of course it's best to read them and think hard about if the code still does the same thing as before. Sami (*) Just moving the cursor in aptitude takes seconds on my old Pentium laptop.
--- apt-0.6.38.sli.0/apt-pkg/contrib/configuration.cc +++ apt-0.6.38.sli.0/apt-pkg/contrib/configuration.cc @@ -110,7 +110,7 @@ return 0; I = new Item; - I->Tag = string(S,Len); + I->Tag.assign(S,Len); I->Next = *Last; I->Parent = Head; *Last = I; @@ -161,7 +161,7 @@ if (Itm == 0 || Itm->Value.empty() == true) { if (Default == 0) - return string(); + return ""; else return Default; } @@ -180,7 +180,7 @@ if (Itm == 0 || Itm->Value.empty() == true) { if (Default == 0) - return string(); + return ""; else return Default; } @@ -294,7 +294,7 @@ // Configuration::CndSet - Conditinal Set a value /*{{{*/ // --------------------------------------------------------------------- /* This will not overwrite */ -void Configuration::CndSet(const char *Name,string Value) +void Configuration::CndSet(const char *Name,const string &Value) { Item *Itm = Lookup(Name,true); if (Itm == 0) @@ -306,7 +306,7 @@ // Configuration::Set - Set a value /*{{{*/ // --------------------------------------------------------------------- /* */ -void Configuration::Set(const char *Name,string Value) +void Configuration::Set(const char *Name,const string &Value) { Item *Itm = Lookup(Name,true); if (Itm == 0) @@ -330,13 +330,13 @@ // Configuration::Clear - Clear an entire tree /*{{{*/ // --------------------------------------------------------------------- /* */ -void Configuration::Clear(string Name) +void Configuration::Clear(const string &Name) { Item *Top = Lookup(Name.c_str(),false); if (Top == 0) return; - Top->Value = string(); + Top->Value.clear(); Item *Stop = Top; Top = Top->Child; Stop->Child = 0; @@ -444,7 +444,7 @@ sections like 'zone "foo.org" { .. };' This causes each section to be added in with a tag like "zone::foo.org" instead of being split tag/value. AsSectional enables Sectional parsing.*/ -bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional, +bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional, unsigned Depth) { // Open the stream for reading @@ -670,13 +670,13 @@ } // Empty the buffer - LineBuffer = string(); + LineBuffer.clear(); // Move up a tag, but only if there is no bit to parse if (TermChar == '}') { if (StackPos == 0) - ParentTag = string(); + ParentTag.clear(); else ParentTag = Stack[--StackPos]; } @@ -701,7 +701,7 @@ // ReadConfigDir - Read a directory of config files /*{{{*/ // --------------------------------------------------------------------- /* */ -bool ReadConfigDir(Configuration &Conf,string Dir,bool AsSectional, +bool ReadConfigDir(Configuration &Conf,const string &Dir,bool AsSectional, unsigned Depth) { DIR *D = opendir(Dir.c_str()); --- apt-0.6.38.sli.0/apt-pkg/contrib/configuration.h +++ apt-0.6.38.sli.0/apt-pkg/contrib/configuration.h @@ -69,25 +69,25 @@ public: string Find(const char *Name,const char *Default = 0) const; - string Find(string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);}; + string Find(const string &Name,const char *Default = 0) const {return Find(Name.c_str(),Default);}; string FindFile(const char *Name,const char *Default = 0) const; string FindDir(const char *Name,const char *Default = 0) const; int FindI(const char *Name,int Default = 0) const; - int FindI(string Name,int Default = 0) const {return FindI(Name.c_str(),Default);}; + int FindI(const string &Name,int Default = 0) const {return FindI(Name.c_str(),Default);}; bool FindB(const char *Name,bool Default = false) const; - bool FindB(string Name,bool Default = false) const {return FindB(Name.c_str(),Default);}; + bool FindB(const string &Name,bool Default = false) const {return FindB(Name.c_str(),Default);}; string FindAny(const char *Name,const char *Default = 0) const; - inline void Set(string Name,string Value) {Set(Name.c_str(),Value);}; - void CndSet(const char *Name,string Value); - void Set(const char *Name,string Value); + inline void Set(const string &Name,const string &Value) {Set(Name.c_str(),Value);}; + void CndSet(const char *Name,const string &Value); + void Set(const char *Name,const string &Value); void Set(const char *Name,int Value); - inline bool Exists(string Name) const {return Exists(Name.c_str());}; + inline bool Exists(const string &Name) const {return Exists(Name.c_str());}; bool Exists(const char *Name) const; bool ExistsAny(const char *Name) const; - void Clear(string Name); + void Clear(const string &Name); inline const Item *Tree(const char *Name) const {return Lookup(Name);}; @@ -101,10 +101,10 @@ extern Configuration *_config; -bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional = false, +bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional = false, unsigned Depth = 0); -bool ReadConfigDir(Configuration &Conf,string Dir,bool AsSectional = false, +bool ReadConfigDir(Configuration &Conf,const string &Dir,bool AsSectional = false, unsigned Depth = 0); #endif --- apt-0.6.38.sli.0/apt-pkg/contrib/mmap.h +++ apt-0.6.38.sli.0/apt-pkg/contrib/mmap.h @@ -94,7 +94,7 @@ unsigned long RawAllocate(unsigned long Size,unsigned long Aln = 0); unsigned long Allocate(unsigned long ItemSize); unsigned long WriteString(const char *String,unsigned long Len = (unsigned long)-1); - inline unsigned long WriteString(string S) {return WriteString(S.c_str(),S.length());}; + inline unsigned long WriteString(const string &S) {return WriteString(S.c_str(),S.length());}; void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;}; DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace = 2*1024*1024); --- apt-0.6.38.sli.0/apt-pkg/contrib/progress.cc +++ apt-0.6.38.sli.0/apt-pkg/contrib/progress.cc @@ -50,7 +50,7 @@ // --------------------------------------------------------------------- /* */ void OpProgress::OverallProgress(unsigned long Current, unsigned long Total, - unsigned long Size,string Op) + unsigned long Size,const string &Op) { this->Current = Current; this->Total = Total; @@ -67,7 +67,7 @@ // OpProgress::SubProgress - Set the sub progress state /*{{{*/ // --------------------------------------------------------------------- /* */ -void OpProgress::SubProgress(unsigned long SubTotal,string Op) +void OpProgress::SubProgress(unsigned long SubTotal,const string &Op) { this->SubTotal = SubTotal; SubOp = Op; --- apt-0.6.38.sli.0/apt-pkg/contrib/progress.h +++ apt-0.6.38.sli.0/apt-pkg/contrib/progress.h @@ -59,9 +59,9 @@ void Progress(unsigned long Current); void SubProgress(unsigned long SubTotal); - void SubProgress(unsigned long SubTotal,string Op); + void SubProgress(unsigned long SubTotal,const string &Op); void OverallProgress(unsigned long Current,unsigned long Total, - unsigned long Size,string Op); + unsigned long Size,const string &Op); virtual void Done() {}; OpProgress(); --- apt-0.6.38.sli.0/apt-pkg/contrib/strutl.cc +++ apt-0.6.38.sli.0/apt-pkg/contrib/strutl.cc @@ -32,12 +32,49 @@ #include <regex.h> #include <errno.h> #include <stdarg.h> +#include <algorithm> +#include <sstream> #include "config.h" using namespace std; /*}}}*/ +static bool URICharsToQuote[256]; +// "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF"; +static const char *URIBadChars = "\\|{}[]<>\"^~_=!@#$%^&*"; + +namespace strutl_private { + bool isspace_tbl[256]; + char tolower_tbl[256]; + bool init_done=0; +} + +// strutl_init - Initialize everything in the module that needs to be /*{{{*/ +// --------------------------------------------------------------------- +void __attribute__ ((constructor)) strutl_init(void) +{ + if (strutl_private::init_done) + return; + + strutl_private::init_done=1; + + for (int I=0; I<256; I++) + { + strutl_private::isspace_tbl[I] = isspace(I); + strutl_private::tolower_tbl[I] = tolower(I); + } + + for (int I=0; I<256; I++) + if (I <= 0x20 || I >= 0x7F || isprint(I) == 0 || + strchr(URIBadChars,I) != 0) + URICharsToQuote[I]=1; + else + URICharsToQuote[I]=0; +}; + /*}}}*/ + + // strstrip - Remove white space from the front and back of a string /*{{{*/ // --------------------------------------------------------------------- /* This is handy to use when parsing a file. It also removes \n's left @@ -199,28 +236,48 @@ // QuoteString - Convert a string into quoted from /*{{{*/ // --------------------------------------------------------------------- /* */ -string QuoteString(string Str,const char *Bad) +string QuoteString(const string &Str,const char *Bad) { - string Res; - for (string::iterator I = Str.begin(); I != Str.end(); I++) + vector<char> Res; + Res.reserve(Str.length()*3/2); + for (string::const_iterator I = Str.begin(); I != Str.end(); I++) { - if (strchr(Bad,*I) != 0 || isprint(*I) == 0 || - *I <= 0x20 || *I >= 0x7F) + if (strchr(Bad,*I) != 0 || isprint(*I) == 0 || + *I <= 0x20 || *I >= 0x7F) { char Buf[10]; sprintf(Buf,"%%%02x",(int)*I); - Res += Buf; + copy(Buf,Buf+3,back_insert_iterator<vector<char> >(Res)); } else - Res += *I; + Res.push_back(*I); } - return Res; + return string(Res.begin(),Res.end()); } /*}}}*/ +// QuoteURI - Quote characters that may not appear in URIs /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string QuoteURI(const string &Str) +{ + char Res[Str.length()*3+1]; + int Wpos=0; + for (string::const_iterator I = Str.begin(); I != Str.end(); I++) + { + if (URICharsToQuote[static_cast<unsigned char>(*I)]) + Wpos += sprintf(Res+Wpos,"%%%02x",(int)*I); + else + Res[Wpos++] = *I; + } + Res[Wpos]=0; + return Res; +} + +/*}}}*/ // DeQuoteString - Convert a string from quoted from /*{{{*/ // --------------------------------------------------------------------- /* This undoes QuoteString */ -string DeQuoteString(string Str) +string DeQuoteString(const string &Str) { string Res; for (string::const_iterator I = Str.begin(); I != Str.end(); I++) @@ -317,7 +374,7 @@ // SubstVar - Substitute a string for another string /*{{{*/ // --------------------------------------------------------------------- /* This replaces all occurances of Subst with Contents in Str. */ -string SubstVar(string Str,string Subst,string Contents) +string SubstVar(const string &Str,const string &Subst,const string &Contents) { string::size_type Pos = 0; string::size_type OldPos = 0; @@ -348,21 +405,17 @@ /* This converts a URI into a safe filename. It quotes all unsafe characters and converts / to _ and removes the scheme identifier. The resulting file name should be unique and never occur again for a different file */ -string URItoFileName(string URI) +string URItoFileName(const string &URI) { // Nuke 'sensitive' items ::URI U(URI); - U.User = string(); - U.Password = string(); - U.Access = ""; + U.User.clear(); + U.Password.clear(); + U.Access.clear(); - // "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF"; - URI = QuoteString(U,"\\|{}[]<>\"^~_=!@#$%^&*"); - string::iterator J = URI.begin(); - for (; J != URI.end(); J++) - if (*J == '/') - *J = '_'; - return URI; + string NewURI = QuoteURI(U); + replace(NewURI.begin(),NewURI.end(),'/','_'); + return NewURI; } /*}}}*/ // Base64Encode - Base64 Encoding routine for short strings /*{{{*/ @@ -371,7 +424,7 @@ from wget and then patched and bug fixed. This spec can be found in rfc2045 */ -string Base64Encode(string S) +string Base64Encode(const string &S) { // Conversion table. static char tbl[64] = {'A','B','C','D','E','F','G','H', @@ -486,7 +539,7 @@ int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd) { for (; A != AEnd && B != BEnd; A++, B++) - if (toupper(*A) != toupper(*B)) + if (fast_tolower(*A) != fast_tolower(*B)) break; if (A == AEnd && B == BEnd) @@ -495,7 +548,7 @@ return 1; if (B == BEnd) return -1; - if (toupper(*A) < toupper(*B)) + if (fast_tolower(*A) < fast_tolower(*B)) return -1; return 1; } @@ -504,7 +557,7 @@ const char *B,const char *BEnd) { for (; A != AEnd && B != BEnd; A++, B++) - if (toupper(*A) != toupper(*B)) + if (fast_tolower(*A) != fast_tolower(*B)) break; if (A == AEnd && B == BEnd) @@ -513,7 +566,7 @@ return 1; if (B == BEnd) return -1; - if (toupper(*A) < toupper(*B)) + if (fast_tolower(*A) < fast_tolower(*B)) return -1; return 1; } @@ -521,7 +574,7 @@ string::const_iterator B,string::const_iterator BEnd) { for (; A != AEnd && B != BEnd; A++, B++) - if (toupper(*A) != toupper(*B)) + if (fast_tolower(*A) != fast_tolower(*B)) break; if (A == AEnd && B == BEnd) @@ -530,7 +583,7 @@ return 1; if (B == BEnd) return -1; - if (toupper(*A) < toupper(*B)) + if (fast_tolower(*A) < fast_tolower(*B)) return -1; return 1; } @@ -540,21 +593,21 @@ // --------------------------------------------------------------------- /* The format is like those used in package files and the method communication system */ -string LookupTag(string Message,const char *Tag,const char *Default) +string LookupTag(const string &Message,const char *Tag,const char *Default) { // Look for a matching tag. int Length = strlen(Tag); - for (string::iterator I = Message.begin(); I + Length < Message.end(); I++) + for (string::const_iterator I = Message.begin(); I + Length < Message.end(); I++) { // Found the tag if (I[Length] == ':' && stringcasecmp(I,I+Length,Tag) == 0) { // Find the end of line and strip the leading/trailing spaces - string::iterator J; + string::const_iterator J; I += Length + 1; - for (; isspace(*I) != 0 && I < Message.end(); I++); + for (; fast_isspace(*I) != 0 && I < Message.end(); I++); for (J = I; *J != '\n' && J < Message.end(); J++); - for (; J > I && isspace(J[-1]) != 0; J--); + for (; J > I && fast_isspace(J[-1]) != 0; J--); return string(I,J); } @@ -572,7 +625,7 @@ // --------------------------------------------------------------------- /* This inspects the string to see if it is true or if it is false and then returns the result. Several varients on true/false are checked. */ -int StringToBool(string Text,int Default) +int StringToBool(const string &Text,int Default) { char *End; int Res = strtol(Text.c_str(),&End,0); @@ -738,7 +791,7 @@ 'timegm' to convert a struct tm in UTC to a time_t. For some bizzar reason the C library does not provide any such function :< This also handles the weird, but unambiguous FTP time format*/ -bool StrToTime(string Val,time_t &Result) +bool StrToTime(const string &Val,time_t &Result) { struct tm Tm; char Month[10]; @@ -825,7 +878,7 @@ // Hex2Num - Convert a long hex number into a buffer /*{{{*/ // --------------------------------------------------------------------- /* The length of the buffer must be exactly 1/2 the length of the string. */ -bool Hex2Num(string Str,unsigned char *Num,unsigned int Length) +bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length) { if (Str.length() != Length*2) return false; @@ -986,7 +1039,7 @@ // --------------------------------------------------------------------- /* The domain list is a comma seperate list of domains that are suffix matched against the argument */ -bool CheckDomainList(string Host,string List) +bool CheckDomainList(const string &Host,const string &List) { string::const_iterator Start = List.begin(); for (string::const_iterator Cur = List.begin(); Cur <= List.end(); Cur++) @@ -1009,7 +1062,7 @@ // URI::CopyFrom - Copy from an object /*{{{*/ // --------------------------------------------------------------------- /* This parses the URI into all of its components */ -void URI::CopyFrom(string U) +void URI::CopyFrom(const string &U) { string::const_iterator I = U.begin(); @@ -1038,9 +1091,9 @@ SingleSlash = U.end(); // We can now write the access and path specifiers - Access = string(U,0,FirstColon - U.begin()); + Access.assign(U.begin(),FirstColon); if (SingleSlash != U.end()) - Path = string(U,SingleSlash - U.begin()); + Path.assign(SingleSlash,U.end()); if (Path.empty() == true) Path = "/"; @@ -1070,14 +1123,14 @@ if (At == SingleSlash) { if (FirstColon < SingleSlash) - Host = string(U,FirstColon - U.begin(),SingleSlash - FirstColon); + Host.assign(FirstColon,SingleSlash); } else { - Host = string(U,At - U.begin() + 1,SingleSlash - At - 1); - User = string(U,FirstColon - U.begin(),SecondColon - FirstColon); + Host.assign(At+1,SingleSlash); + User.assign(FirstColon,SecondColon); if (SecondColon < At) - Password = string(U,SecondColon - U.begin() + 1,At - SecondColon - 1); + Password.assign(SecondColon+1,At); } // Now we parse the RFC 2732 [] hostnames. @@ -1105,7 +1158,7 @@ // Tsk, weird. if (InBracket == true) { - Host = string(); + Host.erase(); return; } @@ -1116,7 +1169,7 @@ return; Port = atoi(string(Host,Pos+1).c_str()); - Host = string(Host,0,Pos); + Host.assign(Host,0,Pos); } /*}}}*/ // URI::operator string - Convert the URI to a string /*{{{*/ @@ -1124,54 +1177,70 @@ /* */ URI::operator string() { - string Res; + vector<char> Res; if (Access.empty() == false) - Res = Access + ':'; + { + Res.insert(Res.end(),Access.begin(),Access.end()); + Res.push_back(':'); + } if (Host.empty() == false) { if (Access.empty() == false) - Res += "//"; + { + Res.push_back('/'); + Res.push_back('/'); + } if (User.empty() == false) { - Res += User; + Res.insert(Res.end(),User.begin(),User.end()); if (Password.empty() == false) - Res += ":" + Password; - Res += "@"; + { + Res.push_back(':'); + Res.insert(Res.end(),Password.begin(),Password.end()); + } + Res.push_back('@'); } // Add RFC 2732 escaping characters if (Access.empty() == false && (Host.find('/') != string::npos || Host.find(':') != string::npos)) - Res += '[' + Host + ']'; + { + Res.push_back('['); + Res.insert(Res.end(),Host.begin(),Host.end()); + Res.push_back(']'); + } else - Res += Host; + Res.insert(Res.end(),Host.begin(),Host.end()); if (Port != 0) { char S[30]; sprintf(S,":%u",Port); - Res += S; + Res.insert(Res.end(),S,S+strlen(S)); } } if (Path.empty() == false) { if (Path[0] != '/') - Res += "/" + Path; + { + Res.push_back('/'); + Res.insert(Res.end(),Path.begin(),Path.end()); + } else - Res += Path; + Res.insert(Res.end(),Path.begin(),Path.end()); } - return Res; + return string(Res.begin(),Res.end()); } /*}}}*/ // URI::SiteOnly - Return the schema and site for the URI /*{{{*/ // --------------------------------------------------------------------- /* */ -string URI::SiteOnly(string URI) +string URI::SiteOnly(const string &URI) { ::URI U(URI); U.User = string(); --- apt-0.6.38.sli.0/apt-pkg/contrib/strutl.h +++ apt-0.6.38.sli.0/apt-pkg/contrib/strutl.h @@ -38,41 +38,60 @@ #define APT_FORMAT2 #define APT_FORMAT3 #endif - + +namespace strutl_private { + extern bool isspace_tbl[256]; + extern char tolower_tbl[256]; +} + +static inline bool fast_isspace(char c) +{ + return strutl_private::isspace_tbl[(unsigned char)(c)]; +} + +static inline char fast_tolower(char c) +{ + return strutl_private::tolower_tbl[(unsigned char)(c)]; +} + +void strutl_init(void); char *_strstrip(char *String); char *_strtabexpand(char *String,size_t Len); bool ParseQuoteWord(const char *&String,string &Res); bool ParseCWord(const char *&String,string &Res); -string QuoteString(string Str,const char *Bad); -string DeQuoteString(string Str); +string QuoteString(const string &Str,const char *Bad); +string QuoteURI(const string &Str); +string DeQuoteString(const string &Str); string SizeToStr(double Bytes); string TimeToStr(unsigned long Sec); -string Base64Encode(string Str); -string URItoFileName(string URI); +string Base64Encode(const string &Str); +string URItoFileName(const string &URI); string TimeRFC1123(time_t Date); -bool StrToTime(string Val,time_t &Result); -string LookupTag(string Message,const char *Tag,const char *Default = 0); -int StringToBool(string Text,int Default = -1); +bool StrToTime(const string &Val,time_t &Result); +string LookupTag(const string &Message,const char *Tag,const char *Default = 0); +int StringToBool(const string &Text,int Default = -1); bool ReadMessages(int Fd, vector<string> &List); bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0); -bool Hex2Num(string Str,unsigned char *Num,unsigned int Length); +bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length); bool TokSplitString(char Tok,char *Input,char **List, unsigned long ListMax); void ioprintf(ostream &out,const char *format,...) APT_FORMAT2; char *safe_snprintf(char *Buffer,char *End,const char *Format,...) APT_FORMAT3; -bool CheckDomainList(string Host,string List); +bool CheckDomainList(const string &Host,const string &List); #define APT_MKSTRCMP(name,func) \ +inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \ inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \ -inline int name(string A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \ -inline int name(string A,string B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \ -inline int name(string A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);}; +inline int name(const string &A,const char *B) {return func(A.c_str(),A.c_str()+A.length(),B,B+strlen(B));}; \ +inline int name(const string &A,const string &B) {return func(A.c_str(),A.c_str()+A.length(),B.c_str(),B.c_str()+B.length());}; \ +inline int name(const string &A,const char *B,const char *BEnd) {return func(A.c_str(),A.c_str()+A.length(),B,BEnd);}; #define APT_MKSTRCMP2(name,func) \ +inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \ inline int name(const char *A,const char *AEnd,const char *B) {return func(A,AEnd,B,B+strlen(B));}; \ -inline int name(string A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \ -inline int name(string A,string B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \ -inline int name(string A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);}; +inline int name(const string &A,const char *B) {return func(A.begin(),A.end(),B,B+strlen(B));}; \ +inline int name(const string &A,const string &B) {return func(A.begin(),A.end(),B.begin(),B.end());}; \ +inline int name(const string &A,const char *B,const char *BEnd) {return func(A.begin(),A.end(),B,BEnd);}; int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd); int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd); @@ -101,7 +120,7 @@ class URI { - void CopyFrom(string From); + void CopyFrom(const string &From); public: @@ -113,11 +132,11 @@ unsigned int Port; operator string(); - inline void operator =(string From) {CopyFrom(From);}; + inline void operator =(const string &From) {CopyFrom(From);}; inline bool empty() {return Access.empty();}; - static string SiteOnly(string URI); + static string SiteOnly(const string &URI); - URI(string Path) {CopyFrom(Path);}; + URI(const string &Path) {CopyFrom(Path);}; URI() : Port(0) {}; }; @@ -127,7 +146,7 @@ const string *Contents; }; string SubstVar(string Str,const struct SubstVar *Vars); -string SubstVar(string Str,string Subst,string Contents); +string SubstVar(const string &Str,const string &Subst,const string &Contents); struct RxChoiceList { --- apt-0.6.38.sli.0/apt-pkg/deb/debindexfile.cc +++ apt-0.6.38.sli.0/apt-pkg/deb/debindexfile.cc @@ -221,20 +221,34 @@ } string debPackagesIndex::IndexURI(const char *Type) const { - string Res; - if (Dist[Dist.size() - 1] == '/') - { - if (Dist != "/") - Res = URI + Dist; - else - Res = URI; - } - else - Res = URI + "dists/" + Dist + '/' + Section + - "/binary-" + _config->Find("APT::Architecture") + '/'; + vector<char> Res; + Res.reserve(150); + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + { + Res.insert(Res.end(),URI.begin(),URI.end()); + Res.insert(Res.end(),Dist.begin(),Dist.end()); + } + else + Res.assign(URI.begin(),URI.end()); + } + else + { + static const char *Dists="dists/", *Binary="/binary-"; + const string Arch(_config->Find("APT::Architecture")); + Res.assign(URI.begin(),URI.end()); + Res.insert(Res.end(),Dists,Dists+6); + Res.insert(Res.end(),Dist.begin(),Dist.end()); + Res.push_back('/'); + Res.insert(Res.end(),Section.begin(),Section.end()); + Res.insert(Res.end(),Binary,Binary+8); + Res.insert(Res.end(),Arch.begin(),Arch.end()); + Res.push_back('/'); + } - Res += Type; - return Res; + Res.insert(Res.end(),Type,Type+strlen(Type)); + return string(Res.begin(),Res.end()); } /*}}}*/ // PackagesIndex::Exists - Check if the index is available /*{{{*/ --- apt-0.6.38.sli.0/apt-pkg/deb/deblistparser.cc +++ apt-0.6.38.sli.0/apt-pkg/deb/deblistparser.cc @@ -166,8 +166,8 @@ char *I = S; for (; Start != End; Start++) { - if (isspace(*Start) == 0) - *I++ = tolower(*Start); + if (fast_isspace(*Start) == 0) + *I++ = fast_tolower(*Start); if (*Start == '<' && Start[1] != '<' && Start[1] != '=') *I++ = '='; if (*Start == '>' && Start[1] != '>' && Start[1] != '=') @@ -337,11 +337,11 @@ unsigned int &Op, bool ParseArchFlags) { // Strip off leading space - for (;Start != Stop && isspace(*Start) != 0; Start++); + for (;Start != Stop && fast_isspace(*Start) != 0; Start++); // Parse off the package name const char *I = Start; - for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' && + for (;I != Stop && fast_isspace(*I) == 0 && *I != '(' && *I != ')' && *I != ',' && *I != '|'; I++); // Malformed, no '(' @@ -355,19 +355,19 @@ Package.assign(Start,I - Start); // Skip white space to the '(' - for (;I != Stop && isspace(*I) != 0 ; I++); + for (;I != Stop && fast_isspace(*I) != 0 ; I++); // Parse a version if (I != Stop && *I == '(') { // Skip the '(' - for (I++; I != Stop && isspace(*I) != 0 ; I++); + for (I++; I != Stop && fast_isspace(*I) != 0 ; I++); if (I + 3 >= Stop) return 0; I = ConvertRelation(I,Op); // Skip whitespace - for (;I != Stop && isspace(*I) != 0; I++); + for (;I != Stop && fast_isspace(*I) != 0; I++); Start = I; for (;I != Stop && *I != ')'; I++); if (I == Stop || Start == I) @@ -375,19 +375,19 @@ // Skip trailing whitespace const char *End = I; - for (; End > Start && isspace(End[-1]); End--); + for (; End > Start && fast_isspace(End[-1]); End--); - Ver = string(Start,End-Start); + Ver.assign(Start,End-Start); I++; } else { - Ver = string(); + Ver.clear(); Op = pkgCache::Dep::NoOp; } // Skip whitespace - for (;I != Stop && isspace(*I) != 0; I++); + for (;I != Stop && fast_isspace(*I) != 0; I++); if (ParseArchFlags == true) { @@ -407,7 +407,7 @@ while (I != Stop) { // look for whitespace or ending ']' - while (End != Stop && !isspace(*End) && *End != ']') + while (End != Stop && !fast_isspace(*End) && *End != ']') End++; if (End == Stop) @@ -428,7 +428,7 @@ } I = End; - for (;I != Stop && isspace(*I) != 0; I++); + for (;I != Stop && fast_isspace(*I) != 0; I++); } if (NegArch) @@ -439,7 +439,7 @@ } // Skip whitespace - for (;I != Stop && isspace(*I) != 0; I++); + for (;I != Stop && fast_isspace(*I) != 0; I++); } if (I != Stop && *I == '|') @@ -448,7 +448,7 @@ if (I == Stop || *I == ',' || *I == '|') { if (I != Stop) - for (I++; I != Stop && isspace(*I) != 0; I++); + for (I++; I != Stop && fast_isspace(*I) != 0; I++); return I; } --- apt-0.6.38.sli.0/apt-pkg/deb/debversion.cc +++ apt-0.6.38.sli.0/apt-pkg/deb/debversion.cc @@ -33,15 +33,29 @@ } /*}}}*/ +#define isdigit(x) ((x)>='0' && (x)<='9') +#define isalpha(x) (((x)>='a' && (x)<='z') || ((x)>='A' && (x)<='Z')) + // debVS::CmpFragment - Compare versions /*{{{*/ // --------------------------------------------------------------------- /* This compares a fragment of the version. This is a slightly adapted version of what dpkg uses. */ -#define order(x) ((x) == '~' ? -1 \ - : isdigit((x)) ? 0 \ - : !(x) ? 0 \ - : isalpha((x)) ? (x) \ - : (x) + 256) +#define order2(x) ((x) == '~' ? -1 \ + : isdigit((x)) ? 0 \ + : !(x) ? 0 \ + : isalpha((x)) ? (x) \ + : (x) + 256) + +static int ordertab[256]; + +#define order(x) ordertab[(unsigned int)(x)] + +static void __attribute__ ((constructor)) make_ordertab() +{ + for (int I=0; I<256; I++) + ordertab[I]=order2(I); +} + int debVersioningSystem::CmpFragment(const char *A,const char *AEnd, const char *B,const char *BEnd) { @@ -133,11 +147,11 @@ // Strip off the epoch and compare it const char *lhs = A; const char *rhs = B; - for (;lhs != AEnd && *lhs != ':'; lhs++); - for (;rhs != BEnd && *rhs != ':'; rhs++); - if (lhs == AEnd) + lhs=static_cast<const char *>(memchr(lhs,':',AEnd-lhs)); + rhs=static_cast<const char *>(memchr(rhs,':',BEnd-rhs)); + if (lhs == 0) lhs = A; - if (rhs == BEnd) + if (rhs == 0) rhs = B; // Compare the epoch @@ -154,12 +168,12 @@ // Find the last - const char *dlhs = AEnd-1; const char *drhs = BEnd-1; - for (;dlhs > lhs && *dlhs != '-'; dlhs--); - for (;drhs > rhs && *drhs != '-'; drhs--); + dlhs = static_cast<const char *>(memrchr(lhs, '-', dlhs-lhs)); + drhs = static_cast<const char *>(memrchr(rhs, '-', drhs-rhs)); - if (dlhs == lhs) + if (dlhs == 0) dlhs = AEnd; - if (drhs == rhs) + if (drhs == 0) drhs = BEnd; // Compare the main version --- apt-0.6.38.sli.0/apt-pkg/init.cc +++ apt-0.6.38.sli.0/apt-pkg/init.cc @@ -11,6 +11,7 @@ #include <apt-pkg/init.h> #include <apt-pkg/fileutl.h> #include <apt-pkg/error.h> +#include <apt-pkg/strutl.h> #include <apti18n.h> #include <config.h> @@ -33,7 +34,9 @@ is prepended, this allows a fair degree of flexability. */ bool pkgInitConfig(Configuration &Cnf) { + strutl_init(); + // General APT things if (strcmp(COMMON_OS,"linux") == 0 || strcmp(COMMON_OS,"unknown") == 0) --- apt-0.6.38.sli.0/apt-pkg/pkgcache.cc +++ apt-0.6.38.sli.0/apt-pkg/pkgcache.cc @@ -153,11 +153,11 @@ /* This is used to generate the hash entries for the HashTable. With my package list from bo this function gets 94% table usage on a 512 item table (480 used items) */ -unsigned long pkgCache::sHash(string Str) const +unsigned long pkgCache::sHash(const string &Str) const { unsigned long Hash = 0; for (string::const_iterator I = Str.begin(); I != Str.end(); I++) - Hash = 5*Hash + tolower(*I); + Hash = 5*Hash + fast_tolower(*I); return Hash % _count(HeaderP->HashTable); } @@ -165,7 +165,7 @@ { unsigned long Hash = 0; for (const char *I = Str; *I != 0; I++) - Hash = 5*Hash + tolower(*I); + Hash = 5*Hash + fast_tolower(*I); return Hash % _count(HeaderP->HashTable); } @@ -173,7 +173,7 @@ // Cache::FindPkg - Locate a package by name /*{{{*/ // --------------------------------------------------------------------- /* Returns 0 on error, pointer to the package otherwise */ -pkgCache::PkgIterator pkgCache::FindPkg(string Name) +pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { // Look at the hash bucket Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)]; --- apt-0.6.38.sli.0/apt-pkg/pkgcache.h +++ apt-0.6.38.sli.0/apt-pkg/pkgcache.h @@ -89,7 +89,7 @@ string CacheFile; MMap ⤅ - unsigned long sHash(string S) const; + unsigned long sHash(const string &S) const; unsigned long sHash(const char *S) const; public: @@ -111,14 +111,14 @@ inline void *DataEnd() {return ((unsigned char *)Map.Data()) + Map.Size();}; // String hashing function (512 range) - inline unsigned long Hash(string S) const {return sHash(S);}; + inline unsigned long Hash(const string &S) const {return sHash(S);}; inline unsigned long Hash(const char *S) const {return sHash(S);}; // Usefull transformation things const char *Priority(unsigned char Priority); // Accessors - PkgIterator FindPkg(string Name); + PkgIterator FindPkg(const string &Name); Header &Head() {return *HeaderP;}; inline PkgIterator PkgBegin(); inline PkgIterator PkgEnd(); --- apt-0.6.38.sli.0/apt-pkg/pkgcachegen.cc +++ apt-0.6.38.sli.0/apt-pkg/pkgcachegen.cc @@ -266,7 +266,7 @@ // CacheGenerator::NewPackage - Add a new package /*{{{*/ // --------------------------------------------------------------------- /* This creates a new package structure and adds it to the hash table */ -bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,string Name) +bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name) { Pkg = Cache.FindPkg(Name); if (Pkg.end() == false) @@ -330,7 +330,7 @@ // --------------------------------------------------------------------- /* This puts a version structure in the linked list */ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, - string VerStr, + const string &VerStr, unsigned long Next) { // Get a structure @@ -354,8 +354,8 @@ /* This creates a dependency element in the tree. It is linked to the version and to the package that it is pointing to. */ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, - string PackageName, - string Version, + const string &PackageName, + const string &Version, unsigned int Op, unsigned int Type) { @@ -419,8 +419,8 @@ // --------------------------------------------------------------------- /* */ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, - string PackageName, - string Version) + const string &PackageName, + const string &Version) { pkgCache &Cache = Owner->Cache; @@ -459,7 +459,7 @@ // --------------------------------------------------------------------- /* This is used to select which file is to be associated with all newly added versions. The caller is responsible for setting the IMS fields. */ -bool pkgCacheGenerator::SelectFile(string File,string Site, +bool pkgCacheGenerator::SelectFile(const string &File,const string &Site, const pkgIndexFile &Index, unsigned long Flags) { @@ -543,7 +543,7 @@ /* This just verifies that each file in the list of index files exists, has matching attributes with the cache and the cache does not have any extra files. */ -static bool CheckValidity(string CacheFile, FileIterator Start, +static bool CheckValidity(const string &CacheFile, FileIterator Start, FileIterator End,MMap **OutMap = 0) { // No file, certainly invalid --- apt-0.6.38.sli.0/apt-pkg/pkgcachegen.h +++ apt-0.6.38.sli.0/apt-pkg/pkgcachegen.h @@ -53,17 +53,17 @@ // Flag file dependencies bool FoundFileDeps; - bool NewPackage(pkgCache::PkgIterator &Pkg,string Pkg); + bool NewPackage(pkgCache::PkgIterator &Pkg,const string &Pkg); bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List); - unsigned long NewVersion(pkgCache::VerIterator &Ver,string VerStr,unsigned long Next); + unsigned long NewVersion(pkgCache::VerIterator &Ver,const string &VerStr,unsigned long Next); public: unsigned long WriteUniqString(const char *S,unsigned int Size); - inline unsigned long WriteUniqString(string S) {return WriteUniqString(S.c_str(),S.length());}; + inline unsigned long WriteUniqString(const string &S) {return WriteUniqString(S.c_str(),S.length());}; void DropProgress() {Progress = 0;}; - bool SelectFile(string File,string Site,pkgIndexFile const &Index, + bool SelectFile(const string &File,const string &Site,pkgIndexFile const &Index, unsigned long Flags = 0); bool MergeList(ListParser &List,pkgCache::VerIterator *Ver = 0); inline pkgCache &GetCache() {return Cache;}; @@ -92,14 +92,14 @@ protected: - inline unsigned long WriteUniqString(string S) {return Owner->WriteUniqString(S);}; + inline unsigned long WriteUniqString(const string &S) {return Owner->WriteUniqString(S);}; inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);}; - inline unsigned long WriteString(string S) {return Owner->Map.WriteString(S);}; + inline unsigned long WriteString(const string &S) {return Owner->Map.WriteString(S);}; inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);}; - bool NewDepends(pkgCache::VerIterator Ver,string Package, - string Version,unsigned int Op, + bool NewDepends(pkgCache::VerIterator Ver,const string &Package, + const string &Version,unsigned int Op, unsigned int Type); - bool NewProvides(pkgCache::VerIterator Ver,string Package,string Version); + bool NewProvides(pkgCache::VerIterator Ver,const string &Package,const string &Version); public: --- apt-0.6.38.sli.0/apt-pkg/tagfile.cc +++ apt-0.6.38.sli.0/apt-pkg/tagfile.cc @@ -188,7 +188,7 @@ while (TagCount+1 < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End) { // Start a new index and add it to the hash - if (isspace(Stop[0]) == 0) + if (Stop[0] != ' ') { Indexes[TagCount++] = Stop - Section; AlphaIndexes[AlphaHash(Stop,End)] = TagCount; @@ -199,7 +199,8 @@ if (Stop == 0) return false; - for (; Stop+1 < End && Stop[1] == '\r'; Stop++); + if (Stop+1 < End && Stop[1] == '\r') + Stop++; // Double newline marks the end of the record if (Stop+1 < End && Stop[1] == '\n') @@ -239,12 +240,12 @@ { const char *St; St = Section + Indexes[I]; - if (strncasecmp(Tag,St,Length) != 0) + if (strncmp(Tag,St,Length) != 0) continue; // Make sure the colon is in the right place const char *C = St + Length; - for (; isspace(*C) != 0; C++); + for (; fast_isspace(*C) != 0; C++); if (*C != ':') continue; Pos = I; @@ -272,12 +273,12 @@ { const char *St; St = Section + Indexes[I]; - if (strncasecmp(Tag,St,Length) != 0) + if (strncmp(Tag,St,Length) != 0) continue; // Make sure the colon is in the right place const char *C = St + Length; - for (; isspace(*C) != 0; C++); + for (; *C == ' '; C++); if (*C != ':') continue; @@ -287,8 +288,8 @@ if (Start >= End) return _error->Error("Internal parsing error"); - for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++); - for (; isspace(End[-1]) != 0 && End > Start; End--); + for (; Start < End && (fast_isspace(*Start) || *Start == ':'); Start++); + for (; End > Start && fast_isspace(End[-1]); End--); return true; } @@ -449,7 +450,7 @@ Visited[J] |= 2; if (Rewrite[J].Rewrite != 0 && Rewrite[J].Rewrite[0] != 0) { - if (isspace(Rewrite[J].Rewrite[0])) + if (fast_isspace(Rewrite[J].Rewrite[0])) fprintf(Output,"%s:%s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); else fprintf(Output,"%s: %s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); @@ -505,7 +506,7 @@ Visited[J] |= 2; if (Rewrite[J].Rewrite != 0 && Rewrite[J].Rewrite[0] != 0) { - if (isspace(Rewrite[J].Rewrite[0])) + if (fast_isspace(Rewrite[J].Rewrite[0])) fprintf(Output,"%s:%s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); else fprintf(Output,"%s: %s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); @@ -534,7 +535,7 @@ if (Rewrite[J].Rewrite != 0 && Rewrite[J].Rewrite[0] != 0) { - if (isspace(Rewrite[J].Rewrite[0])) + if (fast_isspace(Rewrite[J].Rewrite[0])) fprintf(Output,"%s:%s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); else fprintf(Output,"%s: %s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite);
Attachment:
signature.asc
Description: Digital signature