GCC Code Coverage Report


Directory: ./
File: pdserv-1.1.0/src/Config.cpp
Date: 2026-10-18 04:09:42
Exec Total Coverage
Lines: 8 92 8.7%
Branches: 1 89 1.1%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright 2010 Richard Hacker (lerichi at gmx dot net)
6 *
7 * This file is part of the pdserv library.
8 *
9 * The pdserv library is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * The pdserv library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
21 *
22 *****************************************************************************/
23
24 #include <cstring>
25 #include <cstdio>
26 #include <cerrno>
27
28 #include "Config.h"
29
30 #include <yaml.h>
31 using namespace PdServ;
32
33 /////////////////////////////////////////////////////////////////////////////
34 /////////////////////////////////////////////////////////////////////////////
35 static char error[100];
36
37 /////////////////////////////////////////////////////////////////////////////
38 /////////////////////////////////////////////////////////////////////////////
39 10 Config::Config(): node(0)
40 {
41 10 }
42
43 /////////////////////////////////////////////////////////////////////////////
44 ✗ Config::Config(yaml_document_t *d, yaml_node_t *n): document(d), node(n)
45 {
46 }
47
48 /////////////////////////////////////////////////////////////////////////////
49 20 Config::~Config()
50 {
51 10 clear();
52 10 }
53
54 /////////////////////////////////////////////////////////////////////////////
55 10 void Config::clear()
56 {
57
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 if (!file.empty()) {
58 ✗ yaml_document_delete(document);
59 ✗ delete document;
60
61 ✗ file.clear();
62 }
63 10 }
64
65 /////////////////////////////////////////////////////////////////////////////
66 ✗ const char * Config::load(const char *file)
67 {
68 ✗ yaml_parser_t parser;
69 FILE *fh;
70
71 /* Initialize parser */
72 ✗ if(!yaml_parser_initialize(&parser)) {
73 ✗ ::snprintf(error, sizeof(error), "Could not initialize YAML parser");
74 ✗ return error;
75 }
76
77 ✗ fh = ::fopen(file, "r");
78 ✗ if (!fh) {
79 ✗ ::snprintf(error, sizeof(error), "Could not open config file %s: %s",
80 ✗ file, strerror(errno));
81 ✗ return error;
82 }
83
84 /* Set input file */
85 ✗ yaml_parser_set_input_file(&parser, fh);
86
87 ✗ clear();
88 ✗ document = new yaml_document_t;
89 ✗ this->file = file;
90
91 /* START new code */
92 ✗ if (!yaml_parser_load(&parser, document)) {
93 ✗ snprintf(error, sizeof(error), "YAML parser failure at line %zu: %s",
94 parser.problem_mark.line, parser.problem);
95 ✗ return error;
96 }
97
98 // Now finished with the file
99 ✗ ::fclose(fh);
100
101 ✗ node = yaml_document_get_root_node(document);
102
103 ✗ return 0;
104 }
105
106 /////////////////////////////////////////////////////////////////////////////
107 ✗ Config Config::operator[](const char *key) const
108 {
109 ✗ return this->operator[](std::string(key));
110 }
111
112 /////////////////////////////////////////////////////////////////////////////
113 ✗ Config::operator bool() const
114 {
115 ✗ return node != 0;
116 }
117
118 /////////////////////////////////////////////////////////////////////////////
119 ✗ Config Config::operator[](const std::string& key) const
120 {
121 ✗ if (!node or node->type != YAML_MAPPING_NODE)
122 ✗ return Config();
123
124 ✗ for (yaml_node_pair_t *pair = node->data.mapping.pairs.start;
125 ✗ pair != node->data.mapping.pairs.top; ++pair) {
126 ✗ yaml_node_t *n = yaml_document_get_node(document, pair->key);
127 ✗ if (n->type == YAML_SCALAR_NODE
128 ✗ and key.size() == n->data.scalar.length
129 ✗ and !strncmp((char*)n->data.scalar.value,
130 ✗ key.c_str(), n->data.scalar.length)) {
131 ✗ return Config(document,
132 ✗ yaml_document_get_node(document, pair->value));
133 }
134 }
135
136 ✗ return Config();
137 }
138
139 /////////////////////////////////////////////////////////////////////////////
140 ✗ Config Config::operator[](size_t index) const
141 {
142 ✗ if (!node)
143 ✗ return Config();
144
145 ✗ switch (node->type) {
146 ✗ case YAML_SEQUENCE_NODE:
147 {
148 ✗ yaml_node_item_t *n = node->data.sequence.items.start;
149 ✗ do {
150 ✗ if (!index--)
151 ✗ return Config(document,
152 ✗ yaml_document_get_node(document, *n));
153 ✗ } while (++n != node->data.sequence.items.top);
154 }
155 ✗ break;
156
157 ✗ case YAML_MAPPING_NODE:
158 {
159 ✗ yaml_node_pair_t *pair = node->data.mapping.pairs.start;
160 ✗ do {
161 ✗ if (!index--)
162 ✗ return Config(document,
163 ✗ yaml_document_get_node(document,
164 ✗ pair->key));
165 ✗ } while (++pair != node->data.mapping.pairs.top);
166 }
167 ✗ break;
168
169 ✗ default:
170 ✗ break;
171 }
172
173 ✗ return Config();
174 }
175
176 /////////////////////////////////////////////////////////////////////////////
177 ✗ std::string Config::toString(const std::string& defaultString) const
178 {
179 ✗ if (!node or node->type != YAML_SCALAR_NODE)
180 ✗ return defaultString;
181
182 ✗ return std::string((char*)node->data.scalar.value, node->data.scalar.length);
183 }
184
185 /////////////////////////////////////////////////////////////////////////////
186 namespace PdServ {
187 template <typename T>
188 ✗ bool Config::get(T &value) const
189 {
190 ✗ if (!*this)
191 ✗ return false;
192
193 ✗ value = *this;
194 ✗ return true;
195 }
196
197 template bool Config::get(int& value) const;
198 }
199
200 /////////////////////////////////////////////////////////////////////////////
201 ✗ int Config::toInt() const
202 {
203 ✗ std::string sval(toString());
204 ✗ if (sval.empty())
205 ✗ return 0;
206
207 ✗ return strtol(sval.c_str(), 0, 0);
208 }
209
210 /////////////////////////////////////////////////////////////////////////////
211 ✗ unsigned int Config::toUInt() const
212 {
213 ✗ std::string sval(toString());
214 ✗ if (sval.empty())
215 ✗ return 0;
216
217 ✗ return strtoul(sval.c_str(), 0, 0);
218 }
219