[augeas-devel] ConfigObj: working lens seeking tips/improvements
Yclept Nemo
orbisvicis at gmail.com
Sat Oct 31 17:45:02 UTC 2015
Updated lenses, now with test lens:
(* ConfigObj_Typed lens:
Pro:
* validates value types and provides child node "type" of record
* strips surrounding quotes from value_qstring
Con:
* child nodes of record are order-dependent: "commented" -> "type" ->
".comment"
* child nodes of record are not automatically derived. Nodes "type" and
"commented" must be provided
*)
module ConfigObj_Typed =
let spaces = del /[ \t]*/ " "
let spaces_none = del /[ \t]*/ ""
let newline = del /\n/ "\n"
let option = key /[a-z]([a-z_]*[a-z])?/
let option_pad = option . spaces
let value_none = [ label "type" . value "none" ]
let value_boolean = store /(true|false)/ . [ label "type" . value
"boolean" ]
let value_10_integer = store /(0|[+-]?[1-9][0-9]*)/ . [ label "type"
. value "integer base 10" ]
let value_10_decimal = store (/(0|[+-]?[0-9]*)\.[0-9]+/ -
/[+-]0\.0+/) . [ label "type" . value "decimal base 10" ]
let value_16_integer = store /[+-]?0x[0-9a-fA-F]+/ . [ label "type"
. value "integer base 16" ]
let value_any_simple = value_boolean | value_10_integer |
value_10_decimal | value_16_integer
let value_qstring = (del "\"" "\"") . (store
/([^\n\"]*([\].)*)*/) . (del "\"" "\"") . [ label "type" . value "string
quoted" ]
let value_ustring = store (/[^ \t\n"#][^ \t\n#]*/ - lens_ctype
value_any_simple) . [ label "type" . value "string unquoted" ]
let value_any = value_any_simple | value_qstring |
value_ustring
let value_any_pad = value_none | ( spaces . value_any )
let sep_assign = del /=/ "="
let sep_comment = del /#/ "#"
let comment_label = label ".comment"
let record_commented = [ sep_comment . spaces . label "commented" .
value "true" ] | [ label "commented" . value "false" ]
let record_comment = [ comment_label . sep_comment . store /.*/ ]
let record_comment_pad = spaces . record_comment
let record_simple = option_pad . sep_assign . value_any_pad .
(spaces_none | record_comment_pad)
let record = [ record_commented . record_simple ]
let comment = [ comment_label . sep_comment . store (/.*/ -
(/[ \t]*/ . lens_ctype record_simple)) ]
let entry = spaces_none . ( record | comment ) . newline
let empty = [ spaces_none . newline ]
let line = empty | entry
let lns = line *
(* ConfigObj_Simple lens:
Pro:
* removes extraneous nodes "type" and "commented = false"
* fast
Con:
* returns raw values - stripping surrounding quotes from value_qstring
creates overlapping lenses in union.put
* does not validate value types internally
* child nodes of record are still order-dependent: "commented" before
".comment"
*)
module ConfigObj_Simple =
let spaces = del /[ \t]*/ " "
let spaces_none = del /[ \t]*/ ""
let newline = del /\n/ "\n"
let option = key /[a-z]([a-z_]*[a-z])?/
let value_all = store (/"([^\n\"]*([\].)*)*"/ | /[^ \t\n"#][^
\t\n#]*/)
let sep_assign = del /=/ "="
let sep_comment = del /#/ "#"
let comment_label = label ".comment"
let record_commented = [ sep_comment . spaces . label "commented" ]
let record_comment = [ comment_label . sep_comment . store /.*/ ]
let record_simple = option . spaces . sep_assign . (spaces .
value_all)? . (spaces_none | (spaces . record_comment))
let record = [ record_commented? . record_simple ]
let comment = [ comment_label . sep_comment . store (/.*/ -
(/[ \t]*/ . lens_ctype record_simple)) ]
let entry = spaces_none . ( record | comment ) . newline
let empty = [ spaces_none . newline ]
let line = empty | entry
let lns = line *
module Test_ConfigObj =
let lstrip (s1:string) =
let l1 = [ label "a" . del /\n*/ "" ]? . [ label "b" .
store(/(.|\n)*/) ] in
let t1 = get l1 s1 in
let t2 = rm "/a" t1 in
put l1 t2 s1
let conf =
"
# comment
# key_a = \"123\"
key_b = \"value 123\"
# key_c = \"0.3\" # 1st inline comment #
key_d = \"true\" # inline comment with \"quoted\" word
# this is a comment, with indented example
# $ command
# result1
# result2
# # key_e = \"Nested comment. Looks like a record, but still a comment.\"
key_f =
key_f_a = # spaces
# key_g =
# key_g_a =#no-spaces
#
#
#
key_h=\"12\" #
key_i= \"12\" #
key_h= \"12\" #
key_j = \"-0x01\"
# key_k = \"word \\"in\\" quotes\"
## key_l = \"a comment\" # still a comment
key_m = true
key_n = 10#no-spaces
key_o =-0.001
key_p =+0xfe0#no-spaces
key_q =unquoted\"string
"
let conf_put = lstrip
"
####################
# \"put\" test follows
####################
# key_q = false ##### inline comment #####
key_r = #null value with comment
key_s = -100
key_t = +1.1119
key_u = 0x22
# key_v = <>
key_w = unquoted\"word
key_w = |
key_x = \"John \\"Doc\\" Cavendish\"
key_y =
"
let tree_simple =
{ }
{ ".comment" = " comment" }
{ "key_a" = "\"123\""
{ "commented" }
}
{ "key_b" = "\"value 123\"" }
{ }
{ }
{ }
{ "key_c" = "\"0.3\""
{ "commented" }
{ ".comment" = " 1st inline comment #" }
}
{ "key_d" = "\"true\""
{ ".comment" = " inline comment with \"quoted\" word" }
}
{ }
{ ".comment" = " this is a comment, with indented example" }
{ ".comment" = " $ command" }
{ ".comment" = " result1" }
{ ".comment" = " result2" }
{ ".comment" = " # key_e = \"Nested comment. Looks like a record,
but still a comment.\"" }
{ }
{ "key_f" }
{ "key_f_a"
{ ".comment" = " spaces" }
}
{ "key_g"
{ "commented" }
}
{ "key_g_a"
{ "commented" }
{ ".comment" = "no-spaces" }
}
{ }
{ ".comment" = "" }
{ ".comment" = "" }
{ ".comment" = " " }
{ }
{ "key_h" = "\"12\""
{ ".comment" = "" }
}
{ "key_i" = "\"12\""
{ ".comment" = "" }
}
{ "key_h" = "\"12\""
{ ".comment" = " " }
}
{ }
{ "key_j" = "\"-0x01\"" }
{ }
{ "key_k" = "\"word \\"in\\" quotes\""
{ "commented" }
}
{ ".comment" = "# key_l = \"a comment\" #
still a comment" }
{ }
{ "key_m" = "true" }
{ "key_n" = "10"
{ ".comment" = "no-spaces" }
}
{ "key_o" = "-0.001" }
{ "key_p" = "+0xfe0"
{ ".comment" = "no-spaces" }
}
{ "key_q" = "unquoted\"string" }
let tree_typed =
{ }
{ ".comment" = " comment" }
{ "key_a" = "123"
{ "commented" = "true" }
{ "type" = "string quoted" }
}
{ "key_b" = "value 123"
{ "commented" = "false" }
{ "type" = "string quoted" }
}
{ }
{ }
{ }
{ "key_c" = "0.3"
{ "commented" = "true" }
{ "type" = "string quoted" }
{ ".comment" = " 1st inline comment #" }
}
{ "key_d" = "true"
{ "commented" = "false" }
{ "type" = "string quoted" }
{ ".comment" = " inline comment with \"quoted\" word" }
}
{ }
{ ".comment" = " this is a comment, with indented example" }
{ ".comment" = " $ command" }
{ ".comment" = " result1" }
{ ".comment" = " result2" }
{ ".comment" = " # key_e = \"Nested comment. Looks like a record,
but still a comment.\"" }
{ }
{ "key_f"
{ "commented" = "false" }
{ "type" = "none" }
}
{ "key_f_a"
{ "commented" = "false" }
{ "type" = "none" }
{ ".comment" = " spaces" }
}
{ "key_g"
{ "commented" = "true" }
{ "type" = "none" }
}
{ "key_g_a"
{ "commented" = "true" }
{ "type" = "none" }
{ ".comment" = "no-spaces" }
}
{ }
{ ".comment" = "" }
{ ".comment" = "" }
{ ".comment" = " " }
{ }
{ "key_h" = "12"
{ "commented" = "false" }
{ "type" = "string quoted" }
{ ".comment" = "" }
}
{ "key_i" = "12"
{ "commented" = "false" }
{ "type" = "string quoted" }
{ ".comment" = "" }
}
{ "key_h" = "12"
{ "commented" = "false" }
{ "type" = "string quoted" }
{ ".comment" = " " }
}
{ }
{ "key_j" = "-0x01"
{ "commented" = "false" }
{ "type" = "string quoted" }
}
{ }
{ "key_k" = "word \\"in\\" quotes"
{ "commented" = "true" }
{ "type" = "string quoted" }
}
{ ".comment" = "# key_l = \"a comment\" #
still a comment" }
{ }
{ "key_m" = "true"
{ "commented" = "false" }
{ "type" = "boolean" }
}
{ "key_n" = "10"
{ "commented" = "false" }
{ "type" = "integer base 10" }
{ ".comment" = "no-spaces" }
}
{ "key_o" = "-0.001"
{ "commented" = "false" }
{ "type" = "decimal base 10" }
}
{ "key_p" = "+0xfe0"
{ "commented" = "false" }
{ "type" = "integer base 16" }
{ ".comment" = "no-spaces" }
}
{ "key_q" = "unquoted\"string"
{ "commented" = "false" }
{ "type" = "string unquoted" }
}
test ConfigObj_Simple.lns get conf = tree_simple
test ConfigObj_Typed.lns get conf = tree_typed
test ConfigObj_Simple.lns put conf after
set ".comment[last()+1]" "###################";
set ".comment[last()+1]" " \"put\" test follows";
set ".comment[last()+1]" "###################";
set "/key_q[last()+1]" "false";
set "/key_q[last()+0]/commented" "";
set "/key_q[last()+0]/.comment" "#### inline comment #####";
set "/key_r/.comment" "null value with comment";
set "/key_s" "-100";
set "/key_t" "+1.1119";
set "/key_u" "0x22";
set "/key_v" "<>";
set "/key_v/commented" "";
set "/key_w" "unquoted\"word";
set "/key_w[last()+1]" "|";
set "/key_x" "\"John \\"Doc\\" Cavendish\"";
clear "/key_y"
= (conf . conf_put)
test ConfigObj_Typed.lns put conf after
set ".comment[last()+1]" "###################";
set ".comment[last()+1]" " \"put\" test follows";
set ".comment[last()+1]" "###################";
set "/key_q[last()+1]" "false";
set "/key_q[last()+0]/commented" "true";
set "/key_q[last()+0]/type" "boolean";
set "/key_q[last()+0]/.comment" "#### inline comment #####";
set "/key_r/commented" "false";
set "/key_r/type" "none";
set "/key_r/.comment" "null value with comment";
set "/key_s" "-100";
set "/key_s/commented" "false";
set "/key_s/type" "integer base 10";
set "/key_t" "+1.1119";
set "/key_t/commented" "false";
set "/key_t/type" "decimal base 10";
set "/key_u" "0x22";
set "/key_u/commented" "false";
set "/key_u/type" "integer base 16";
set "/key_v" "<>";
set "/key_v/commented" "true";
set "/key_v/type" "string unquoted";
set "/key_w" "unquoted\"word";
set "/key_w/commented" "false";
set "/key_w/type" "string unquoted";
set "/key_w[last()+1]" "|";
set "/key_w[last()+0]/commented" "false";
set "/key_w[last()+0]/type" "string unquoted";
set "/key_x" "John \\"Doc\\" Cavendish";
set "/key_x/commented" "false";
set "/key_x/type" "string quoted";
clear "/key_y";
set "/key_y/commented" "false";
set "/key_y/type" "none"
= (conf . conf_put)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20151031/b9afede0/attachment.htm>
More information about the augeas-devel
mailing list