我正在使用libconfuse
作为我的程序的配置文件,这很好用。现在我有兴趣使用Augeas解析配置文件。我发现mailing list post表示libconfuse
文件没有通用的Augeas镜头,因为它是“无上下文文件格式”(实质上,它允许无限嵌套)。
我的程序配置文件非常简单,只有一个级别的部分包含配置参数。 E.g:
serial {
serial-device = "/dev/ttyUSB0"
baudrate = 115200
}
server-socket {
host = "localhost"
port = 12345
}
为这种简单的libconfuse
配置文件编写通用Augeas镜头会涉及什么?周围有什么例子吗?处理这个问题最直接的方法是什么?
答案 0 :(得分:2)
您所指的帖子来自2008年。此后,Augeas能够使用rec
关键字解析递归配置文件。例如,请参阅lvm.aug
,这与您要实现的目标非常相似。
答案 1 :(得分:0)
感谢ℝ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))*