views:

51

answers:

3

For my C projects I'd like to use curly brackets based configuration files like:

account {
    name = "[email protected]";
    password = "test";
    autoconnect = true;
}

etc. or some variations.

I'm trying to find some nice C libraries to suit my needs. Can you please advise?

+4  A: 

I would suggest using a lexer and parser for doing this, either the lex/yacc combo or flex/bison.

You basically write code in a .l and .y file to describe the layout and the lexer/parser generator creates C code that will process the file for you, calling functions to deliver the data to you.

Lexical analysis and parsing are a pain to do unless you're well versed in the art. Tools like those I've mentioned make the job a lot easier.

In the lexer, you get it to recognise the lexical elements like

  • e_account (account)
  • e_openbrace ({)
  • e_name (name)
  • e_string ("[^"]*")
  • e_semicolon (;)

and so on.

The lexer is used by the parser to detect the lexical elements and the parser has the higher level rules for deciding what constructs are valid. Things like an account section being e_account, e_openbrace, zero or more of e_stanza then finally e_closebrace. And also detecting e_stanza as being (among others) e_name, e_equals, e_string then e_semicolon.

Most of the intelligence is under the covers (and pretty ugly looking code at least for lex/yacc) but it's better than trying to write it yourself :-)

paxdiablo
I'd like to recommend Ragel for this, it can generate scanners and has a fairly simple syntax. http://www.complang.org/ragel/
Hasturkun
+5  A: 

Your desired syntax is nearly identical to Lua, which would look like this:

account = {
    name = "[email protected]",
    password = "test",
    autoconnect = true,
}

If that suits you, I highly recommend Lua, as it's designed to be embeddable in C programs as a configuration or scripting facility. You can either use the raw Lua C API, or if you prefer C++ there are things like Luabind to make certain things prettier in that language.

Here is a trivial example using the pure C Lua API to retrieve values from a buffer which contains a Lua "chunk": http://lua-users.org/wiki/GettingValuesFromLua . You can basically read (or mmap) your configuration file in C, pass the pointer to the text to Lua, have Lua execute it, and then retrieve the bits and pieces iteratively. An alternative is to do "binding" (for which there is also an example on the Lua wiki). With binding the flow is more like that you set up C structures to represent your configuration data, bind them to Lua, and let the Lua configuration script actually populate (construct) a configuration object which is then accessible from C. Depending on your exact needs this may be better or worse, but in pure C (as opposed to C++), the learning curve may be steeper than the "get values" approach.

John Zwinck
+1: Actually, one of Lua's design goals was to be usable as a configuration language.
Luther Blissett
+3  A: 

A variant of what you described would be JSON:

account={
    name: "[email protected]",
    password: "test",
    autoconnect: true
}

lists ~100 libraries to read and write JSON for every conceivable platform and language. There are seven libraries alone for C. The nice thing for JSON is interoperability of course and having a data format which is widely accepted (it even has a RFC: rfc4627)

Luther Blissett