1<?xml version="1.0" standalone="no"?> 2<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 3"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" 4[ 5<!ENTITY listing1 SYSTEM "listing1.xml"> 6<!ENTITY listing2 SYSTEM "listing2.xml"> 7<!ENTITY listing3 SYSTEM "listing3.xml"> 8<!ENTITY listing4 SYSTEM "listing4.xml"> 9<!ENTITY listing5 SYSTEM "listing5.xml"> 10<!ENTITY listing6 SYSTEM "listing6.xml"> 11<!ENTITY listing7 SYSTEM "listing7.xml"> 12<!ENTITY listing8 SYSTEM "listing8.xml"> 13]> 14<article> 15 <articleinfo> 16 <title>libConfuse tutorial</title> 17 <author><firstname>Martin</firstname> <surname>Hedenfalk</surname></author> 18 </articleinfo> 19 <sect1> 20 <title>Introducing libConfuse in an existing program</title> 21 <para>Consider this simple program:</para> 22 &listing1; 23 <para> 24 Simple enough, but we want to extend the program so we can greet 25 others. Maybe we don't want to greet the whole world, just our 26 neighbour. We use libConfuse to let the user decide whom to greet. 27 </para> 28 &listing2; 29 <para> 30 All programs using libConfuse must first include the 31 <filename>confuse.h</filename> header file. This is done on line 32 2. 33 </para> 34 <para> 35 On line 6 - 10, the options that should be recognized are defined in an 36 array of cfg_opt_t structs. This is passed to the 37 <function>cfg_init</function> function on line 13. The resulting 38 <structname>cfg_t</structname> context is used by 39 <function>cfg_parse()</function>, which reads the configuration file 40 "hello.conf". When reading the configuration file, only options defined in 41 the array of options passed to <function>cfg_init()</function> are 42 recognized. 43 </para> 44 <para> 45 The friendly greeting is now replaced with a parameter read from the 46 configuration file. The value of the <varname>target</varname> option is retrieved with 47 <function>cfg_getstr(cfg, "target")</function>. 48 </para> 49 <para> 50 Lets take a look at the configuration file hello.conf: 51 </para> 52 53 <programlisting> 54# this is the configuration file for the hello program 55 56target = "Neighbour" 57 </programlisting> 58 <para> 59 Here, the target option is set to the string value "Neighbour". 60 What if the configuration file was empty or didn't exist? Then the 61 default value for the <varname>target</varname> option would be 62 used. When we initialized our options, the second parameter to the 63 <function>CFG_STR()</function> macro specified the default value. 64 Thus, if no <varname>target</varname> option was specified in the 65 configuration file, the hello program would have printed the 66 standard greeting "Hello, World". 67 </para> 68 69 <sect2> 70 <title>Environment variables in values</title> 71 72 <para> 73 What else can we do in the configuration file? We can set the value to an 74 environment variable: 75 </para> 76 <programlisting> 77target = ${USER} 78 </programlisting> 79 <para> 80 This results in the hello program greeting the user who runs it. On some 81 systems, the USER variable might not be available, so we want to specify a 82 default value in those cases: 83 </para> 84 <programlisting> 85target = ${USER:-User} 86 </programlisting> 87 <para> 88 Now, if the USER environment variable is unset, the string "User" will be 89 used instead. 90 </para> 91 </sect2> 92 </sect1> 93 <sect1> 94 <title>Other types of options</title> 95 96 <para> 97 Of course, not only strings can be specified in the configuration file. 98 libConfuse can parse strings, integers, booleans and floating point values. 99 These are the fundamental values, and they are all also available as lists. 100 We'll talk more about lists in the next chapter. 101 </para> 102 <para> 103 The macros used to initialize a string, integer, boolean and a 104 float is, respectively, <function>CFG_STR()</function>, 105 <function>CFG_INT()</function>, <function>CFG_BOOL()</function>, 106 <function>CFG_FLOAT()</function> and 107 <function>CFG_PTR()</function>. All macros take three parameters: 108 the name of the option, a default value and flags. To retrieve the 109 values, use <function>cfg_getstr()</function>, 110 <function>cfg_getint()</function>, 111 <function>cfg_getbool()</function>, 112 <function>cfg_getfloat()</function> or 113 <function>cfg_getptr()</function>, respectively. 114 </para> 115 <para> 116 Let's introduce an integer option that tells us how many times to print the 117 greeting: 118 </para> 119 &listing3; 120 <para> 121 Here we have used the <function>CFG_INT()</function> macro to 122 initialize an integer option named "repeat". The default value is 1 123 as in the standard greeting. The value is retrieved with 124 <function>cfg_getint()</function>. 125 </para> 126 <para id="negative-repeat-problem"> 127 But, wait a moment, what if the user specified a negative value for 128 "repeat"? Or a too large positive value? libConfuse can handle 129 that with a so-called validating callback. We'll come back to this 130 problem later on, but we will first take a look at lists. 131 </para> 132 </sect1> 133 134 <sect1> 135 <title>Introducing lists</title> 136 137 <para> 138 That was easy. Now let's extend the program a bit so we can greet more than one 139 "target". We'd like to be able to specify a list of targets to greet. 140 </para> 141 <para> 142 The list versions of the initialization macros are named 143 <function>CFG_STR_LIST()</function>, 144 <function>CFG_INT_LIST()</function>, 145 <function>CFG_BOOL_LIST()</function> and 146 <function>CFG_FLOAT_LIST()</function>. They take the same 147 parameters as the non-list versions, except the default value must 148 be a string surrounded by curly braces. 149 </para> 150 <para> 151 The modified program is shown below: 152 </para> 153 &listing4; 154 <para> 155 Three things are a bit different here. First, the macro to 156 initialize the "targets" option is 157 <function>CFG_STR_LIST()</function>. This tells libConfuse that 158 "targets" is a list of strings. Second, the default value in the 159 second parameter is surrounded by curly braces. This is needed to 160 indicate to libConfuse where the list of values ends. 161 </para> 162 <para> 163 The third change is in the printing of the greeting. First we print 164 the "Hello" string. Then we loop through all values found for the 165 "targets" option. The number of values is retrieved with the 166 <function>cfg_size()</function> function. The string values are 167 then retrieved with <function>cfg_getnstr()</function>, which is an 168 indexed version of <function>cfg_getstr()</function>. In fact, 169 <function>cfg_getstr()</function> is equivalent to 170 <function>cfg_getnstr()</function> with an index of zero. 171 </para> 172 <para> 173 In the configuration file hello.conf, we can now specify a list of targets to 174 greet: 175 </para> 176 <programlisting> 177# this is the configuration file for the hello program 178 179targets = {"Life", "Universe", "Everything"} 180repeat = 1 181 </programlisting> 182 <para> 183 The output of the hello program, run with the above configuration file, is: 184 "Hello, Life, Universe, Everything!" 185 </para> 186 <para> 187 Again, if no targets were configured, the greeting would have been the standard 188 "Hello, World!". 189 </para> 190 191 </sect1> 192 <sect1> 193 <title>Using sections</title> 194 195 <para> 196 So far, we have only use a flat configuration file. libConfuse can also handle 197 sections to build a hierarchy of options. Sections can be used to group options 198 in logical blocks, and those blocks can (optionally) be specified multiple 199 times. 200 </para> 201 <para> 202 Sections are initialized with the <function>CFG_SEC()</function> macro. It also takes three 203 parameters: the name of the option, an array of options allowed in the section 204 and flags. 205 </para> 206 <para> 207 We'll extend the, now rather complex, hello program so we can do other kinds of 208 greetings, not just "Hello". Each greeting will have its own settings for 209 targets and repeat. 210 </para> 211 &listing5; 212 <para> 213 We have renamed the option array from "opts" to "greet_opts", and introduced a 214 new "opts" array that only has one option: a "greeting" section. 215 The second parameter of the <function>CFG_SEC()</function> macro 216 points to the old greeting options "targets" and "repeat". 217 </para> 218 <para> 219 We have also used a couple of flags to alter the behaviour of the 220 section: CFGF_TITLE means that a greeting section should have a 221 title and the CFGF_MULTI flag tells libConfuse that this section 222 may be specified multiple times in the configuration file. The 223 title of a section is retrieved with the 224 <function>cfg_title()</function> function. 225 </para> 226 <para> 227 The outmost loop (with index j) now loops through all given 228 sections in the configuration file. We retrieve a section with a 229 <function>cfg_getnsec()</function> call. The value returned is a 230 pointer to a cfg_t struct, the same type as returned by 231 <function>cfg_init()</function>. Thus we can use the ordinary value 232 retrieval functions <function>cfg_getstr()</function>, 233 <function>cfg_getint()</function> and so on to retrieve values of 234 options inside the section. 235 </para> 236 <para> 237 Ok, so how does the configuration file look like for this setup? 238 </para> 239 <programlisting> 240# this is the configuration file for the hello program 241 242greeting Hello 243{ 244 targets = {"Life", "Universe", "Everything"} 245 repeat = 1 246} 247 248greeting Bye 249{ 250 targets = {Adams} 251 repeat = 1 252} 253 </programlisting> 254 <para> 255 The program will loop through the sections in the order specified 256 in the configuration file. First it will find the "Hello" section. 257 It prints the title of the section, "Hello", retrieved with 258 <function>cfg_title()</function>. Then the targets are printed just 259 as in the previous exemples, but this time the values are retrieved 260 from the cfg_greet section. Next, the section titled "Bye" is 261 found, and the values are retrieved from that section. 262 </para> 263 <para> 264 When run, the program produces the following: 265 </para> 266 <programlisting> 267$ ./listing5 268Hello, Life, Universe, Everything! 269Bye, Adams! 270$ 271 </programlisting> 272 273 </sect1> 274 <sect1> 275 <title>Parsing from internal buffers</title> 276 <para> 277 So far, we have only parsed configuration data from files. 278 libConfuse can also parse buffers, or in-memory character 279 strings. We will use this to fix a problem in the previous code. 280 </para> 281 <para> 282 The problem is that without a configuration file, the hello program 283 will not print anything. We want it to at least print the standard 284 greeting "Hello, World!" if no configuration file is available. 285 </para> 286 <para> 287 We can't have a default value for a section that can be specified 288 multiple times (ie, a section with the CFGF_MULTI flag set). 289 Instead we will parse a default configuration string if no section 290 has been parsed: 291 </para> 292 &listing6; 293 <para> 294 Only the changes from the previous code is shown here. We check if 295 the size of the "greeting" section is zero (ie, no section has been 296 defined). In that case we call <function>cfg_parse_buf()</function> 297 to parse a default in-memory string "greeting Hello {}". This 298 string defines a greeting section with title Hello, but without any 299 sub-options. This way we rely on the default values of the 300 (sub-)options "targets" and "repeat". 301 </para> 302 <para> 303 When this program is run, it issues the well-known standard greeting 304 "Hello, World!" if no configuration file is present. 305 </para> 306 </sect1> 307 308 <sect1> 309 <title>Validating callback functions</title> 310 <para> 311 Remember the problem about a negative or too large "repeat" value 312 in <xref linkend="negative-repeat-problem"/>? The code that prints 313 the greeting has those lines: 314 </para> 315 <programlisting> 316... 317repeat = cfg_getint(cfg_greet, "repeat"); 318while(repeat--) 319... 320 </programlisting> 321 <para> 322 The repeat variable is defined as an int, a signed integer. If the user 323 specified a negative repeat value in the configuration file, this code 324 would continue to decrease the repeat variable until it eventually 325 underflowed. 326 </para> 327 <para> 328 We'll fix this by not allowing a negative value in the configuration 329 file. Of course we could first just check if the value is negative 330 and then abort, using <function>cfg_getint()</function> and a test. 331 But we will use a validating callback function instead. This way 332 <function>cfg_parse()</function> will return an error directly when 333 parsing the file, additionally indicating on which line the error 334 is. 335 </para> 336 <para> 337 A validating callback function is defined as: 338 </para> 339 <programlisting> 340typedef int (*cfg_validate_callback_t)(cfg_t *cfg, cfg_opt_t *opt); 341 </programlisting> 342 <para> 343 This function takes two arguments: the section and the option. It 344 should return 0 on success (ie, the value validated ok). All other 345 values indicates an error, and the parsing is aborted. The callback 346 function should notify the error itself, for example by calling 347 <function>cfg_error()</function>. 348 </para> 349 <para> 350 Here is the code for the callback function: 351 </para> 352 &listing7; 353 <para> 354 Only the last value is validated, because libConfuse will call this 355 function once for every value corresponding to the option. Since 356 the "repeat" option is not a list, we could instead have used 357 <function>cfg_opt_getint(opt)</function> to retrieve the only 358 value. However, if we later want to use this callback to validate 359 an integer list, it is already lists-aware. 360 </para> 361 362 <sect2> 363 <title>Installing the callback</title> 364 <para> 365 The validating callback is installed with 366 <function>cfg_set_validate_func()</function>. It is called with 367 a string specifying which option is affected, and a pointer to 368 the callback function. To specify an option in a subsection, 369 the section and the option must be separated with a vertical 370 bar ("|"). 371 </para> 372 <para> 373 We're now also looking at the return code from 374 <function>cfg_parse()</function> to verify that the parsing was 375 successful. The complete program is now: 376 </para> 377 &listing8; 378 </sect2> 379 </sect1> 380 381 <sect1> 382 <title>Value parsing callback</title> 383 <para> 384 A value parsing callback is another kind of callback function 385 available in libConfuse. This function is used to map a string into 386 some other other value. One example is to extend a boolean option 387 to accept the values "yes", "no" and "ask" (or perhaps "true", 388 "false" and "maybe"). Those values should be mapped to the integers 389 1, 2 and 3. 390 </para> 391 <programlisting> 392typedef int (*cfg_callback_t)(cfg_t *cfg, cfg_opt_t *opt, 393 const char *value, void *result); 394 </programlisting> 395 <para> 396 397 </para> 398 </sect1> 399 400 <sect1> 401 <title>Functions</title> 402 <para> 403 libConfuse supports functions to parse options that does not fit 404 well in the general syntax. Functions can be called with a variable 405 number of arguments. No data from the function or any arguments are 406 stored by libConfuse after the function has run. It is up to the caller 407 to process and/or save the data. 408 </para> 409 <para> 410 A function is defined with a <function>CFG_FUNC</function> macro. 411 It takes two arguments: the name of the function and a function 412 callback. The callback is defined as: 413 </para> 414 <programlisting> 415typedef int (*cfg_func_t)(cfg_t *cfg, cfg_opt_t *opt, 416 int argc, const char **argv); 417 </programlisting> 418 <para> 419 </para> 420 421 <sect2> 422 <title>Predefined functions</title> 423 <para> 424 Currently there is only one pre-defined function: 425 <function>cfg_include()</function>. This function includes 426 another configuration file. Configuration data is immediately 427 read from the included file, and is returned to the position 428 right after the include() statement upon end of file. 429 </para> 430 <para> 431 To use this function, include a <function>CFG_FUNC()</function> 432 entry in your options: 433 </para> 434 <programlisting> 435cfg_opt_t opts[] = { 436 CFG_FUNC("include", cfg_include), 437 CFG_END() 438}; 439 </programlisting> 440 <para> 441 In the configuration file, it is used in the following way: 442 </para> 443 <programlisting> 444include("included.conf") 445 </programlisting> 446 </sect2> 447 </sect1> 448 449 <sect1> 450 <title>Saving configuration files</title> 451 <para> 452 </para> 453 454 <sect2> 455 <title>Altering the printing of certain options</title> 456 <para> 457 </para> 458 </sect2> 459 </sect1> 460 461</article> 462 463