summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/configuration.cc149
-rw-r--r--apt-pkg/contrib/configuration.h2
-rw-r--r--apt-pkg/contrib/strutl.cc57
3 files changed, 150 insertions, 58 deletions
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 36866a35a..4de17e3e1 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -171,48 +171,60 @@ string Configuration::Find(const char *Name,const char *Default) const
string Configuration::FindFile(const char *Name,const char *Default) const
{
const Item *RootItem = Lookup("RootDir");
- std::string rootDir = (RootItem == 0) ? "" : RootItem->Value;
- if(rootDir.size() > 0 && rootDir[rootDir.size() - 1] != '/')
- rootDir.push_back('/');
+ std::string result = (RootItem == 0) ? "" : RootItem->Value;
+ if(result.empty() == false && result[result.size() - 1] != '/')
+ result.push_back('/');
const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
{
- if (Default == 0)
- return rootDir;
- else
- return rootDir + Default;
+ if (Default != 0)
+ result.append(Default);
}
-
- string val = Itm->Value;
- while (Itm->Parent != 0)
+ else
{
- if (Itm->Parent->Value.empty() == true)
+ string val = Itm->Value;
+ while (Itm->Parent != 0)
{
- Itm = Itm->Parent;
- continue;
- }
+ if (Itm->Parent->Value.empty() == true)
+ {
+ Itm = Itm->Parent;
+ continue;
+ }
+
+ // Absolute
+ if (val.length() >= 1 && val[0] == '/')
+ {
+ if (val.compare(0, 9, "/dev/null") == 0)
+ val.erase(9);
+ break;
+ }
- // Absolute
- if (val.length() >= 1 && val[0] == '/')
- break;
+ // ~/foo or ./foo
+ if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
+ break;
- // ~/foo or ./foo
- if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
- break;
-
- // ../foo
- if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
- break;
-
- if (Itm->Parent->Value.end()[-1] != '/')
- val.insert(0, "/");
+ // ../foo
+ if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
+ break;
+
+ if (Itm->Parent->Value.end()[-1] != '/')
+ val.insert(0, "/");
- val.insert(0, Itm->Parent->Value);
- Itm = Itm->Parent;
+ val.insert(0, Itm->Parent->Value);
+ Itm = Itm->Parent;
+ }
+ result.append(val);
}
- return rootDir + val;
+ // do some normalisation by removing // and /./ from the path
+ size_t found = string::npos;
+ while ((found = result.find("/./")) != string::npos)
+ result.replace(found, 3, "/");
+ while ((found = result.find("//")) != string::npos)
+ result.replace(found, 2, "/");
+
+ return result;
}
/*}}}*/
// Configuration::FindDir - Find a directory name /*{{{*/
@@ -222,7 +234,12 @@ string Configuration::FindDir(const char *Name,const char *Default) const
{
string Res = FindFile(Name,Default);
if (Res.end()[-1] != '/')
+ {
+ size_t const found = Res.rfind("/dev/null");
+ if (found != string::npos && found == Res.size() - 9)
+ return Res; // /dev/null returning
return Res + '/';
+ }
return Res;
}
/*}}}*/
@@ -482,24 +499,80 @@ bool Configuration::ExistsAny(const char *Name) const
/* Dump the entire configuration space */
void Configuration::Dump(ostream& str)
{
- /* Write out all of the configuration directives by walking the
+ Dump(str, NULL, "%f \"%v\";\n", true);
+}
+void Configuration::Dump(ostream& str, char const * const root,
+ char const * const formatstr, bool const emptyValue)
+{
+ const Configuration::Item* Top = Tree(root);
+ if (Top == 0)
+ return;
+ const Configuration::Item* const Root = (root == NULL) ? NULL : Top;
+ std::vector<std::string> const format = VectorizeString(formatstr, '%');
+
+ /* Write out all of the configuration directives by walking the
configuration tree */
- const Configuration::Item *Top = Tree(0);
- for (; Top != 0;)
- {
- str << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
-
+ do {
+ if (emptyValue == true || Top->Value.empty() == emptyValue)
+ {
+ std::vector<std::string>::const_iterator f = format.begin();
+ str << *f;
+ for (++f; f != format.end(); ++f)
+ {
+ if (f->empty() == true)
+ {
+ ++f;
+ str << '%' << *f;
+ continue;
+ }
+ char const type = (*f)[0];
+ if (type == 'f')
+ str << Top->FullTag();
+ else if (type == 't')
+ str << Top->Tag;
+ else if (type == 'v')
+ str << Top->Value;
+ else if (type == 'F')
+ str << QuoteString(Top->FullTag(), "=\"\n");
+ else if (type == 'T')
+ str << QuoteString(Top->Tag, "=\"\n");
+ else if (type == 'V')
+ str << QuoteString(Top->Value, "=\"\n");
+ else if (type == 'n')
+ str << "\n";
+ else if (type == 'N')
+ str << "\t";
+ else
+ str << '%' << type;
+ str << f->c_str() + 1;
+ }
+ }
+
if (Top->Child != 0)
{
Top = Top->Child;
continue;
}
-
+
while (Top != 0 && Top->Next == 0)
Top = Top->Parent;
if (Top != 0)
Top = Top->Next;
- }
+
+ if (Root != NULL)
+ {
+ const Configuration::Item* I = Top;
+ while(I != 0)
+ {
+ if (I == Root)
+ break;
+ else
+ I = I->Parent;
+ }
+ if (I == 0)
+ break;
+ }
+ } while (Top != 0);
}
/*}}}*/
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index 4c2e75041..ea94c2fe6 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -103,6 +103,8 @@ class Configuration
inline void Dump() { Dump(std::clog); };
void Dump(std::ostream& str);
+ void Dump(std::ostream& str, char const * const root,
+ char const * const format, bool const emptyValue);
Configuration(const Item *Root);
Configuration();
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index 99efa8d98..ca096d736 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -23,6 +23,7 @@
#include <ctype.h>
#include <string.h>
+#include <sstream>
#include <stdio.h>
#include <algorithm>
#include <unistd.h>
@@ -1168,34 +1169,50 @@ unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin,
return Hits;
}
/*}}}*/
-// ioprintf - C format string outputter to C++ iostreams /*{{{*/
+// {str,io}printf - C format string outputter to C++ strings/iostreams /*{{{*/
// ---------------------------------------------------------------------
/* This is used to make the internationalization strings easier to translate
and to allow reordering of parameters */
-void ioprintf(ostream &out,const char *format,...)
+static bool iovprintf(ostream &out, const char *format,
+ va_list &args, ssize_t &size) {
+ char *S = (char*)malloc(size);
+ ssize_t const n = vsnprintf(S, size, format, args);
+ if (n > -1 && n < size) {
+ out << S;
+ free(S);
+ return true;
+ } else {
+ if (n > -1)
+ size = n + 1;
+ else
+ size *= 2;
+ }
+ free(S);
+ return false;
+}
+void ioprintf(ostream &out,const char *format,...)
{
va_list args;
- va_start(args,format);
-
- // sprintf the description
- char S[4096];
- vsnprintf(S,sizeof(S),format,args);
- out << S;
+ ssize_t size = 400;
+ while (true) {
+ va_start(args,format);
+ if (iovprintf(out, format, args, size) == true)
+ return;
+ va_end(args);
+ }
}
- /*}}}*/
-// strprintf - C format string outputter to C++ strings /*{{{*/
-// ---------------------------------------------------------------------
-/* This is used to make the internationalization strings easier to translate
- and to allow reordering of parameters */
-void strprintf(string &out,const char *format,...)
+void strprintf(string &out,const char *format,...)
{
va_list args;
- va_start(args,format);
-
- // sprintf the description
- char S[4096];
- vsnprintf(S,sizeof(S),format,args);
- out = string(S);
+ ssize_t size = 400;
+ std::ostringstream outstr;
+ while (true) {
+ va_start(args,format);
+ if (iovprintf(outstr, format, args, size) == true)
+ break;
+ va_end(args);
+ }
+ out = outstr.str();
}
/*}}}*/
// safe_snprintf - Safer snprintf /*{{{*/