Config class and source list
[ntk/apt.git] / apt-pkg / contrib / configuration.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: configuration.cc,v 1.2 1998/07/09 05:12:33 jgg Exp $
4 /* ######################################################################
5
6 Configuration Class
7
8 This class provides a configuration file and command line parser
9 for a tree-oriented configuration environment. All runtime configuration
10 is stored in here.
11
12 ##################################################################### */
13 /*}}}*/
14 // Include files /*{{{*/
15 #ifdef __GNUG__
16 #pragma implementation "pkglib/configuration.h"
17 #endif
18 #include <pkglib/configuration.h>
19 #include <strutl.h>
20
21 #include <stdio.h>
22 /*}}}*/
23
24 Configuration *_config = new Configuration;
25
26 // Configuration::Configuration - Constructor /*{{{*/
27 // ---------------------------------------------------------------------
28 /* */
29 Configuration::Configuration()
30 {
31 Root = new Item;
32 }
33 /*}}}*/
34 // Configuration::Lookup - Lookup a single item /*{{{*/
35 // ---------------------------------------------------------------------
36 /* This will lookup a single item by name below another item. It is a
37 helper function for the main lookup function */
38 Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
39 unsigned long Len,bool Create)
40 {
41 int Res = 1;
42 Item *I = Head->Child;
43 Item **Last = &Head->Child;
44 for (; I != 0; Last = &I->Next, I = I->Next)
45 if ((Res = stringcasecmp(I->Tag.begin(),I->Tag.end(),S,S + Len)) == 0)
46 break;
47
48 if (Res == 0)
49 return I;
50 if (Create == false)
51 return 0;
52
53 I = new Item;
54 I->Tag = string(S,Len);
55 I->Next = *Last;
56 I->Parent = Head;
57 *Last = I;
58 return I;
59 }
60 /*}}}*/
61 // Configuration::Lookup - Lookup a fully scoped item /*{{{*/
62 // ---------------------------------------------------------------------
63 /* This performs a fully scoped lookup of a given name, possibly creating
64 new items */
65 Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
66 {
67 const char *Start = Name;
68 const char *End = Start + strlen(Name);
69 const char *TagEnd = Name;
70 Item *Itm = Root;
71 for (; End - TagEnd > 2; TagEnd++)
72 {
73 if (TagEnd[0] == ':' && TagEnd[1] == ':')
74 {
75 Itm = Lookup(Itm,Start,TagEnd - Start,Create);
76 if (Itm == 0)
77 return 0;
78 TagEnd = Start = TagEnd + 2;
79 }
80 }
81
82 Itm = Lookup(Itm,Start,End - Start,Create);
83 return Itm;
84 }
85 /*}}}*/
86 // Configuration::Find - Find a value /*{{{*/
87 // ---------------------------------------------------------------------
88 /* */
89 string Configuration::Find(const char *Name,const char *Default)
90 {
91 Item *Itm = Lookup(Name,false);
92 if (Itm == 0 || Itm->Value.empty() == true)
93 {
94 if (Default == 0)
95 return string();
96 else
97 return Default;
98 }
99
100 return Itm->Value;
101 }
102 /*}}}*/
103 // Configuration::FindDir - Find a directory /*{{{*/
104 // ---------------------------------------------------------------------
105 /* Directories are stored as the base dir in the Parent node and the
106 */
107 string Configuration::FindDir(const char *Name,const char *Default = 0)
108 {
109 Item *Itm = Lookup(Name,false);
110 if (Itm == 0 || Itm->Value.empty() == true)
111 {
112 if (Default == 0)
113 return string();
114 else
115 return Default;
116 }
117
118 if (Itm->Value[0] == '/' || Itm->Parent == 0)
119 return Itm->Value;
120 if (Itm->Parent->Value.end()[-1] == '/')
121 return Itm->Parent->Value + Itm->Value;
122 else
123 return Itm->Parent->Value + '/' + Itm->Value;
124 }
125 /*}}}*/
126 // Configuration::FindI - Find an integer value /*{{{*/
127 // ---------------------------------------------------------------------
128 /* */
129 int Configuration::FindI(const char *Name,int Default)
130 {
131 Item *Itm = Lookup(Name,false);
132 if (Itm == 0 || Itm->Value.empty() == true)
133 return Default;
134
135 char *End;
136 int Res = strtol(Itm->Value.c_str(),&End,0);
137 if (End == Itm->Value.c_str())
138 return Default;
139
140 return Res;
141 }
142 /*}}}*/
143 // Configuration::Set - Set a value /*{{{*/
144 // ---------------------------------------------------------------------
145 /* */
146 void Configuration::Set(const char *Name,string Value)
147 {
148 Item *Itm = Lookup(Name,true);
149 if (Itm == 0)
150 return;
151 Itm->Value = Value;
152 }
153 /*}}}*/
154 // Configuration::Set - Set an integer value /*{{{*/
155 // ---------------------------------------------------------------------
156 /* */
157 void Configuration::Set(const char *Name,int Value)
158 {
159 Item *Itm = Lookup(Name,true);
160 if (Itm == 0)
161 return;
162 char S[300];
163 snprintf(S,sizeof(S),"%i",Value);
164 Itm->Value = S;
165 }
166 /*}}}*/