1 /*******************************************************************************
2 ********************************************************************************
4 Copyright (c) 2008 Ahmed S. Badran
6 Filename: configfile.cc
7 Description: Implementation.
8 Created: 08/12/2008 10:27:53 PM PDT
10 Author: Ahmed S. Badran (Ahmed B.), ahmed.badran@gmail.com
12 ********************************************************************************
13 *******************************************************************************/
14 #include "configfile.h"
17 configfile::configfile(const string
& fpath
):
21 char* buf
= new char[MAX
];
22 FILE* filp
= fopen(file_path
.c_str(), "r");
25 string secname
= "", key
= "", value
= "";
26 while (getline(&buf
, &MAX
, filp
) != -1) {
27 if (is_comment(buf
)) {
29 } else if (is_section_header(buf
, &secname
)) {
31 } else if (is_key_value(buf
, &key
, &value
)) {
33 add_key(secname
, key
, value
);
45 configfile::get_sections () const
47 vector
<string
> section_names
;
48 data_struct::const_iterator pos
;
49 data_struct::const_iterator end
= sections
.end();
50 for (pos
= sections
.begin(); pos
!= end
; ++pos
) {
51 section_names
.push_back(pos
->first
);
57 configfile::get_keys (const string
& secname
) const
61 if (!get_section_index(secname
, &index
)) {
64 const vector
<pair
<string
, string
> >& key_values
=
65 sections
[index
].second
;
66 vector
<pair
<string
, string
> >::const_iterator pos
;
67 vector
<pair
<string
, string
> >::const_iterator end
= key_values
.end();
68 for (pos
= key_values
.begin(); pos
!= end
; ++pos
) {
69 keys
.push_back(pos
->first
);
75 configfile::get_key_value (const string
& secname
, const string
& key
, string
*
79 if (!get_section_index(secname
, &index
)) {
82 const vector
<pair
<string
, string
> >& key_values
=
83 sections
[index
].second
;
84 vector
<pair
<string
, string
> >::const_iterator pos
;
85 vector
<pair
<string
, string
> >::const_iterator end
= key_values
.end();
86 for (pos
= key_values
.begin(); pos
!= end
; ++pos
) {
87 if (pos
->first
== key
) {
96 configfile::add_section (const string
& name
)
98 vector
<pair
<string
, string
> > empty
;
99 sections
.push_back(make_pair(name
, empty
));
103 configfile::add_key (const string
& secname
, const string
& key
, const string
&
107 if (!get_section_index(secname
, &index
)) {
110 vector
<pair
<string
, string
> >& key_values
= sections
[index
].second
;
111 key_values
.push_back(make_pair(key
, value
));
116 configfile::get_section_index (const string
& secname
, unsigned* index
) const
119 unsigned section_count
= sections
.size();
120 for (i
= 0; i
< section_count
; ++i
) {
121 if (sections
[i
].first
== secname
) {
130 configfile::is_comment (const char* buf
) const
134 regcomp(®ex
, "^[ ]*#.*$", REG_EXTENDED
);
135 if (regexec(®ex
, buf
, 0, 0, 0) == 0) {
144 configfile::is_section_header(const char* buf
, string
* secname
) const
146 const unsigned MAX
= 1024;
147 regmatch_t substr
[3];
148 char tmpbuf
[MAX
] = {0};
149 memset(substr
, 0, sizeof(substr
));
151 regcomp(®ex
, "^[ ]*\\[[ ]*([^ ]+)[ ]+\"([^ ]+)\""
152 "[ ]*\\][ ]*$", REG_EXTENDED
| REG_NEWLINE
);
153 if (regexec(®ex
, buf
, 3, substr
, 0) == 0) {
154 memset(tmpbuf
, 0, MAX
);
155 extract_field(1, substr
, buf
, tmpbuf
);
158 memset(tmpbuf
, 0, MAX
);
159 extract_field(2, substr
, buf
, tmpbuf
);
165 regcomp(®ex
, "^[ ]*\\[[ ]*([^ ]+)[ ]*\\][ ]*$",
166 REG_EXTENDED
| REG_NEWLINE
);
167 if (regexec(®ex
, buf
, 3, substr
, 0) == 0) {
168 memset(tmpbuf
, 0, MAX
);
169 extract_field(1, substr
, buf
, tmpbuf
);
178 configfile::is_key_value(const char* buf
, string
* key
, string
* value
) const
180 const unsigned MAX
= 1024;
181 regmatch_t substr
[3];
182 char tmpbuf
[MAX
] = {0};
183 memset(substr
, 0, sizeof(substr
));
185 regcomp(®ex
, "^[ ]*([^ ].*[^ ])[ ]*=[ ]*"
186 "([^ ].*[^ ])[ ]*$", REG_EXTENDED
| REG_NEWLINE
);
187 if (regexec(®ex
, buf
, 3, substr
, 0) == 0) {
188 memset(tmpbuf
, 0, MAX
);
189 extract_field(1, substr
, buf
, tmpbuf
);
191 memset(tmpbuf
, 0, MAX
);
192 extract_field(2, substr
, buf
, tmpbuf
);
200 configfile::extract_field (unsigned i
, regmatch_t
* regex_arr
, const char*
201 inbuf
, char* outbuf
) const
203 strncpy(outbuf
, &inbuf
[regex_arr
[i
].rm_so
], regex_arr
[i
].rm_eo
-
208 configfile::save_to (const string
& fpath
) const
210 FILE* filp
= fopen(fpath
.c_str(), "w");
214 data_struct::const_iterator pos
;
215 data_struct::const_iterator end
= sections
.end();
218 for (pos
= sections
.begin(); pos
!= end
; ++pos
) {
219 index
= pos
->first
.find('.', 0);
220 if (index
!= string::npos
) {
221 tmp1
= pos
->first
.substr(0, index
);
222 tmp2
= pos
->first
.substr(index
+ 1);
223 fprintf(filp
, "[%s \"%s\"]\n", tmp1
.c_str(),
226 fprintf(filp
, "[%s]\n", pos
->first
.c_str());
228 const vector
<pair
<string
, string
> >& key_values
= pos
->second
;
229 vector
<pair
<string
, string
> >::const_iterator kpos
;
230 vector
<pair
<string
, string
> >::const_iterator kend
=
232 for (kpos
= key_values
.begin(); kpos
!= kend
; ++kpos
) {
233 fprintf(filp
, "\t%s = %s\n", kpos
->first
.c_str(),
234 kpos
->second
.c_str());
244 return save_to(file_path
);
247 configfile::~configfile ()