[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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)

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]