I have an executable that run time should take configuration parameters from a script file. This way I dont need to re-compile the code for every configuration change. Right now I have all the configuration values in a .h file. Everytime I change it i need to re-compile.
The platform is C, gcc under Linux.
What is the best solution for this problem? I looked up on google and so XML, phthon and Lua bindings for C. Is using a separate scripting language the best approach? If so, which one would you recommend for my need?
Addendum: What if I would like to mirror data structures in script files?开发者_运维知识库 If I have an array of structures for example, if there an easy way to store and load it?
Thanks
I recommend Lua. It was designed for configuration.
The simplest way would be to have a text file containing something like:
key = value
key2 = anothervalue
....
keyn = etc
And then you simply open this file and parse it, putting everything in something like a hashmap/dictionary.
A quick search on google comes up with a library (libConfuse) that can do this for you.
Check out CCAN ciniparser. Its a fork of the original iniparser (which is no longer maintained) and makes parsing INI style configuration files easy.
Code from the example (almost mirrored by the unit tests):
#include <stdio.h>
#include <stdbool.h>
#include <ccan/ciniparser/ciniparser.h>
#define CONFIG_FILE "/etc/config.ini"
int main(int argc, char *argv[])
{
dictionary *d;
char *val1;
bool val2;
double val3;
int val4;
d = ciniparser_load(CONFIG_FILE);
if (d == NULL)
return 1;
val1 = ciniparser_getstring(d, "daemon:pidfile", NULL);
val2 = ciniparser_getboolean(d, "daemon:debug", false);
val3 = ciniparser_getdouble(d, "daemon:maxload", 3.5);
val4 = ciniparser_getint(d, "daemon:maxchild", 5);
ciniparser_freedict(d);
return 0;
}
Of course, you can just drop the few files needed in your tree and #include "iniparser.h"
, there are no dependencies on other CCAN modules unless you want to run the unit tests.
A sample configuration might look like this:
[stooges]
larry=larry_stooge
curly=curly_stooge
moe=moe_stooge
shemp=questionable
[cartoons]
tom_hates=jerry
Getting the value of stooges:shemp
would yield a statically allocated questionable
that you would use as-is (without modifying) or allocate and duplicate (i.e. strdup()
). It doesn't get much easier than that. Wrap access to the dictionary with a simple mutex and its thread safe.
CCAN is the Comprehensive C Archive network. Think CPAN
, just C
. Its a project Rusty Russell began a while ago which is finally gaining some traction.
Disclaimer: I maintain the module.
What's wrong with a plain text file? Are these configuration settings read once when the app starts, or continuously throughout the life of the app? When do they get written? It sounds like they only get read once at the begining of the app, because you need to recompile every time they change.
If there's only a handful of values, then I'd say keep it simple and stick with a text file formatted as key/value pairs:
Config1 = 1
ConfigValue2 = 33.4
ConfigValue3 = ABC
If you have more complex settings, maybe some hierarchy of values, XML might make more sense.
How much configuration do you need that it needs to be a "script file"?
I just keep a little chunk of code handy that's a ini format parser.
You could reread the configuration file when a signal such as SIGUSR1
is received.
you can just store all configurations values externally and read it with the old plain C
you can do something like:
param=value param2=value2
and read it normally with fgets and then do a strtok looking for '=' and then you have both params and values.
if you want to use XML i recommend you libxml2.
精彩评论