【问题标题】:Parsing a simple libconfuse file with Augeas使用 Augeas 解析一个简单的 libconfuse 文件
【发布时间】:2013-05-20 02:31:14
【问题描述】:

我将libconfuse 用于我程序的配置文件,效果很好。现在我有兴趣使用Augeas 解析配置文件。我发现了一个mailing list post,它说libconfuse 文件没有通用的Augeas 镜头,因为它是一种“无上下文的文件格式”(本质上,它允许无限嵌套)。

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

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

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

为这种简单的libconfuse 配置文件编写一个通用的Augeas 镜头会涉及什么?周围有例子吗?最直接的处理方法是什么?

【问题讨论】:

    标签: configuration-files augeas


    【解决方案1】:

    您所指的帖子来自 2008 年。此后,Augeas 能够使用 rec 关键字解析递归配置文件。例如,请参阅 lvm.aug,这与您想要实现的目标非常相似。

    【讨论】:

    • 我在this documentation page 上找不到详细信息,实际上它说“Augeas 不支持递归”。这是否意味着文档已过时?
    • 我找到了changes page,这表明该功能是在 2010 年 1 月添加的。很好——但我猜没有很好的记录。非常感谢您提供指向此功能的指针。
    • 确实,这个功能没有很好的文档记录。欢迎补丁:-)
    • JSON lens 看起来也可以作为libconfuse 镜头的一个很好的起点。
    • 如果它是有效的 JSON,当然可以。不过我不这么认为。
    【解决方案2】:

    感谢ℝaphink's answer,我从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 /\[[ \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))*
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 2014-09-15
      • 2021-06-02
      • 1970-01-01
      • 2013-12-30
      • 1970-01-01
      • 2014-07-09
      相关资源
      最近更新 更多