Разбор простого файла libconfuse с помощью Augeas

Я использую libconfuse для файлов конфигурации моей программы, и это прекрасно работает. Теперь мне интересно проанализировать файлы конфигурации с помощью Augeas. Я нашел сообщение в списка рассылки, в котором говорится, что универсальная линза Augeas для libconfuse файлов, потому что это «контекстно-свободный формат файла» (по сути, он допускает бесконечную вложенность).

Файлы конфигурации моей программы довольно просты, всего один уровень секций, содержащих параметры конфигурации. Например.:

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

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

Что потребуется для написания общей линзы Augeas для этого простого варианта libconfuse конфигурационного файла? Вокруг есть примеры? Каков был бы самый простой способ справиться с этим?


person Craig McQueen    schedule 20.05.2013    source источник


Ответы (2)


Сообщение, на которое вы ссылаетесь, относится к 2008 году. С тех пор Augeas может анализировать рекурсивные файлы конфигурации, используя ключевое слово rec. См., например, lvm.aug, что очень похоже на то, что вы пытаетесь достичь.

person raphink    schedule 20.05.2013
comment
Я не могу найти это подробно на этой странице документации, и на самом деле там написано, что Augeas не поддерживать рекурсию. Означает ли это, что документация устарела? - person Craig McQueen; 20.05.2013
comment
Я нашел страницу изменений, на которой указано, что эта функция была добавлена ​​в январе 2010 года. Хорошо, но не очень задокументировано, я думаю. Большое спасибо за указание на эту функцию. - person Craig McQueen; 20.05.2013
comment
Действительно, эта функция плохо документирована. Патчи приветствуются :-) - person raphink; 20.05.2013
comment
линза JSON выглядит так, как будто она тоже может быть хорошая отправная точка для объектива libconfuse. - person Craig McQueen; 21.05.2013
comment
Если это действительный JSON, конечно. Я не думаю, что это все же. - person raphink; 21.05.2013

Благодаря ℝaphink answer, я начал с < линза href="https://github.com/hercules-team/augeas/blob/master/lenses/lvm.aug" rel="nofollow noreferrer">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))*
person Craig McQueen    schedule 28.05.2013