[augeas-devel] ConfigObj: working lens seeking tips/improvements
Mol, Xavier (SCC)
xavier.mol at kit.edu
Mon Nov 2 09:22:43 UTC 2015
Hi Yclept,
I can only repeat a tip from the parallel mail thread: Use variables and constructs from the generic Augeas modules like Rx, Util, Sep
and Build. In doing so, you ease yourself the development of new lenses, since you don't have to reinvent the wheel every time, and
for other people the maintainance and understanding of your lenses. The tools provides in these modules are used for many years in
many modules. Hence they are very refined and allow people foreign to your code a quick start, since they might recognize statements
from those modules and will understand faster what you are trying to achieve.
I'm sorry to say that, but personally, I have too little time to learn your lens to the same level as you know it, just to give you
any worthwhile comment on it. Getting into your lens would be much easier for me, once not everything are explicit regular
expressions, which become quite difficult to read with a certain length (refer to my first paragraph).
Besides that, the generic Build module provides functions, that show you, how you could combine lenses with no strict ordering or
existence: http://augeas.net/docs/references/lenses/files/build-aug.html#Build.COMBINATORICS.
Ciao,
Xavier.
From: augeas-devel-bounces at redhat.com [mailto:augeas-devel-bounces at redhat.com] On Behalf Of Yclept Nemo
Sent: Saturday, October 31, 2015 6:45 PM
To: augeas-devel
Subject: Re: [augeas-devel] ConfigObj: working lens seeking tips/improvements
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/20151102/f17f3f1f/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 6401 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20151102/f17f3f1f/attachment.p7s>
More information about the augeas-devel
mailing list