summaryrefslogtreecommitdiffstats
path: root/apt-pkg/contrib/configuration.h
blob: 2a3ae1aa4ff75d37e84bf2e6db5c1d11733b9bd0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// -*- mode: cpp; mode: fold -*-
// Description								/*{{{*/
/* ######################################################################

   Configuration Class
   
   This class provides a configuration file and command line parser
   for a tree-oriented configuration environment. All runtime configuration
   is stored in here.
   
   Each configuration name is given as a fully scoped string such as
     Foo::Bar
   And has associated with it a text string. The Configuration class only
   provides storage and lookup for this tree, other classes provide
   configuration file formats (and parsers/emitters if needed).

   Most things can get by quite happily with,
     cout << _config->Find("Foo::Bar") << endl;

   A special extension, support for ordered lists is provided by using the
   special syntax, "block::list::" the trailing :: designates the 
   item as a list. To access the list you must use the tree function on
   "block::list".
   
   ##################################################################### */
									/*}}}*/
#ifndef PKGLIB_CONFIGURATION_H
#define PKGLIB_CONFIGURATION_H

#include <regex.h>

#include <iostream>
#include <string>
#include <vector>

#include <apt-pkg/macros.h>

#ifndef APT_8_CLEANER_HEADERS
using std::string;
#endif

class Configuration
{
   public:
   
   struct Item
   {
      std::string Value;
      std::string Tag;
      Item *Parent;
      Item *Child;
      Item *Next;
      
      std::string FullTag(const Item *Stop = 0) const;
      
      Item() : Parent(0), Child(0), Next(0) {};
   };
   
   private:
   
   Item *Root;
   bool ToFree;

   Item *Lookup(Item *Head,const char *S,unsigned long const &Len,bool const &Create);
   Item *Lookup(const char *Name,const bool &Create);
   inline const Item *Lookup(const char *Name) const
   {
      return const_cast<Configuration *>(this)->Lookup(Name,false);
   }  
   
   public:

   std::string Find(const char *Name,const char *Default = 0) const;
   std::string Find(std::string const &Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
   std::string Find(std::string const &Name, std::string const &Default) const {return Find(Name.c_str(),Default.c_str());};
   std::string FindFile(const char *Name,const char *Default = 0) const;
   std::string FindDir(const char *Name,const char *Default = 0) const;
   /** return a list of child options
    *
    * Options like Acquire::Languages are handled as lists which
    * can be overridden and have a default. For the later two a comma
    * separated list of values is supported.
    *
    * \param Name of the parent node
    * \param Default list of values separated by commas */
   std::vector<std::string> FindVector(const char *Name, std::string const &Default = "", bool const Keys = false) const;
   std::vector<std::string> FindVector(std::string const &Name, std::string const &Default = "", bool const Keys = false) const { return FindVector(Name.c_str(), Default, Keys); };

   int FindI(const char *Name,int const &Default = 0) const;
   int FindI(std::string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);};
   bool FindB(const char *Name,bool const &Default = false) const;
   bool FindB(std::string const &Name,bool const &Default = false) const {return FindB(Name.c_str(),Default);};
   std::string FindAny(const char *Name,const char *Default = 0) const;
	      
   inline void Set(const std::string &Name,const std::string &Value) {Set(Name.c_str(),Value);};
   void CndSet(const char *Name,const std::string &Value);
   void CndSet(const char *Name,const int Value);
   void Set(const char *Name,const std::string &Value);
   void Set(const char *Name,const int &Value);
   
   inline bool Exists(const std::string &Name) const {return Exists(Name.c_str());};
   bool Exists(const char *Name) const;
   bool ExistsAny(const char *Name) const;

   void MoveSubTree(char const * const OldRoot, char const * const NewRoot);

   // clear a whole tree
   void Clear(const std::string &Name);
   void Clear();

   // remove a certain value from a list (e.g. the list of "APT::Keep-Fds")
   void Clear(std::string const &List, std::string const &Value);
   void Clear(std::string const &List, int const &Value);

   inline const Item *Tree(const char *Name) const {return Lookup(Name);};

   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();
   ~Configuration();

   /** \brief match a string against a configurable list of patterns */
   class MatchAgainstConfig
   {
     std::vector<regex_t *> patterns;
     APT_HIDDEN void clearPatterns();

   public:
     MatchAgainstConfig(char const * Config);
     virtual ~MatchAgainstConfig();

     /** \brief Returns \b true for a string matching one of the patterns */
     bool Match(char const * str) const;
     bool Match(std::string const &str) const { return Match(str.c_str()); };

     /** \brief returns if the matcher setup was successful */
     bool wasConstructedSuccessfully() const { return patterns.empty() == false; }
   };
};

extern Configuration *_config;

bool ReadConfigFile(Configuration &Conf,const std::string &FName,
		    bool const &AsSectional = false,
		    unsigned const &Depth = 0);

bool ReadConfigDir(Configuration &Conf,const std::string &Dir,
		   bool const &AsSectional = false,
		   unsigned const &Depth = 0);

#endif