Question

I'm using libconfuse for my program's configuration files, and that's working nicely. Now I'm interested to parse the configuration files using Augeas. I found a mailing list post which says that there's no generic Augeas lens for libconfuse files, because it's a "context-free file format" (in essence, it allows infinite nesting).

My program's configuration files are quite simple, with just one level of sections containing configuration parameters. E.g.:

serial {
    serial-device = "/dev/ttyUSB0"
    baudrate = 115200
}

server-socket {
    host = "localhost"
    port = 12345
}

What would be involved in writing a generic Augeas lens for this simple variety of libconfuse configuration file? Are there any examples around? What would be the most straight-forward way to handle this?

Was it helpful?

Solution

The post you're referring to is from 2008. Augeas has since been able to parse recursive configuration files, using the rec keyword. See for example lvm.aug, which is quite similar to what you're trying to achieve.

OTHER TIPS

Thanks to ℝaphink's answer, I started with the lvm.aug lens, which was a good starting point, and improved it a little.

Here's what I've got at the moment, which supports only a subset of libconfuse syntax—if you test it with the libconfuse example test.conf, it will fail in several places. But it works for the sub-set of the syntax in the config files I'm currently using, so it's "good enough" for my current purposes. Although I'd like to figure out how to get indentation of nested blocks looking nice (like the json.aug lens does; I haven't figured out how it does it yet).

(*
Module: LibconfuseSimple
  Based on Module LVM
*)

module LibconfuseSimple =
    (* See lvm2/libdm/libdm-config.c for tokenisation;
     * libdm uses a blacklist but I prefer the safer whitelist approach. *)
    (* View: identifier
     * The left hand side of a definition *)
    let identifier = /[a-zA-Z0-9_-]+/

    (* strings can contain backslash-escaped dquotes, but I don't know
     * how to get the message across to augeas *)
    let str = [label "str". Quote.do_quote (store /[^"]*/)]
    let int = [label "int". store Rx.integer]
    let env = [label "env". del "${" "${" . store /[^}]*/ . del "}" "}"]
    let const (r:regexp) = [ label "const" . store r ]
    let rawstr = [label "rawstr". store Rx.space_in]
    (* View: flat_literal
     * A literal without structure *)
    let flat_literal = int|str|env|const /true|false|null/|rawstr

    (* allow multiline and mixed int/str, used for raids and stripes *)
    (* View: list
     * A list containing flat literals *)
    let list = [
        label "list" . counter "list"
        . del /\[[ \t\n]*/ "["
        .([seq "list". flat_literal . del /,[ \t\n]*/ ", "]*
        . [seq "list". flat_literal . del /[ \t\n]*/ ""])?
        . Util.del_str "]"]

    (* View: val
     * Any value that appears on the right hand side of an assignment *)
    let val = flat_literal | list

    (* View: comments
     * Comments of various sorts *)
    let comments =
        Util.comment
        | Util.comment_c_style
        | Util.comment_multiline

    (* View: nondef
     * A line that doesn't contain a statement *)
    let nondef =
        Util.empty
        | comments

    (* View: indent
     * Remove any input indentation; output 4 spaces indentation. *)
    let indent = del /[ \t]*/ "    "

    (* Build.block couldn't be reused, because of recursion and
     * a different philosophy of whitespace handling. *)
    (* View: def
     * An assignment, or a block containing definitions *)
    let rec def = [
        key identifier . (
            (del /[ \t]*/ " " . [label "title" . store identifier])? . del /[ \t]*\{\n?/ " {\n"
            .[label "dict" . (Util.empty | indent . comments | indent . def)*]
            . Util.indent . Util.del_str "}\n"
            |Sep.space_equal . val . Util.comment_or_eol)]

    (* View: lns
     * The main lens *)
    let lns = (nondef | (Util.indent . def))*
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top