用Augeas解析简单的libconfusion文件



我使用libconfuse作为我的程序的配置文件,这工作得很好。现在我有兴趣使用Augeas解析配置文件。我发现了一个邮件列表帖子,上面说libconfuse文件没有通用的Augeas镜头,因为它是一种"上下文无关的文件格式"(本质上,它允许无限嵌套)。

我的程序的配置文件非常简单,只有一层包含配置参数的节。例如:

serial {
    serial-device = "/dev/ttyUSB0"
    baudrate = 115200
}
server-socket {
    host = "localhost"
    port = 12345
}

为这个简单的libconfuse配置文件写一个通用的Augeas镜头会涉及什么?有什么例子吗?解决这个问题最直接的方法是什么?

你指的是2008年的帖子。Augeas已经能够使用rec关键字解析递归配置文件。例如,lvm.aug,它与您想要实现的非常相似。

多亏了一个很好的答案,我从lvm.aug镜头开始,这是一个很好的起点,并对其进行了一些改进。

这是我目前得到的,它只支持libconfuse语法的一个子集—如果您用libconfuse示例test.conf测试它,它将在几个地方失败。但它适用于我目前使用的配置文件中的语法子集,因此对于我当前的目的来说,它"足够好"。虽然我想弄清楚如何得到嵌套块看起来不错的缩进(如json.aug镜头);我还没有弄清楚它是如何做到的)。

(*
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 /[[ tn]*/ "["
        .([seq "list". flat_literal . del /,[ tn]*/ ", "]*
        . [seq "list". flat_literal . del /[ tn]*/ ""])?
        . 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))*

相关内容

  • 没有找到相关文章

最新更新