[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