<div dir="ltr">Yes Xavier, this is a good (and useful) explanation.<div><br></div><div>It would be great if that could end up on a wiki page actually.</div><div><br></div><div><br></div><div><br></div><div>Raphaël</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 8, 2016 at 2:24 PM, Mol, Xavier (SCC) <span dir="ltr"><<a href="mailto:xavier.mol@kit.edu" target="_blank">xavier.mol@kit.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Hi Yclept,<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">this is a late reply and you possibly don't need it anymore, but I think I have finally understood the issue regarding "overlapping lenses in union.put", so I want to share my experience with you.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">As you and David explained, Augeas has trouble when putting a tree into a file that (potentially) has nodes, which can be matched by more than one lens. This problem can be avoided in get direction, because parent nodes might be distinguishable in some way. We can make use of that key difference, by giving alternate node options to Augeas (as opposed to alternate expressions).<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Say we have a tree <u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">/a<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">/a/color = "blue"<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">/b<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">/b/color = "red"<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Depending on the lens definitions for nodes "a" and "b", the "color" subnode might have to be read/written differently. Yet just from looking at the tree, Augeas cannot distinguish between either "color" node definition. That is what David said in his mail: "when Augeas sees a lens construct like 'l1|l2' it only looks at the labels of the tree node it's currently at to decide whether to use l1 or l2". In this situation, the label is identical for both nodes, hence the conflict.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">How can we avoid this problem with actually applying ugly hacks? We change the construct such that Augeas has to consider the depth of the tree. Without concrete examples, this will be difficult to understand, so lets expand on the above example with these lens definitions:<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">let a = key "a" . [ label "color" . store /red|blue|green|yellow/ ]<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">let b = key "b" . [ label "color" . del /dark-/ "dark-" . store /red|blue|green|yellow/ ]<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">let lns = [ a | b ]<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">So for "b"-nodes color strings are prefixed with "dark-". When parsing a source file, Augeas can clearly distinguish between when to apply lenses "a" or "b". But because in either case the resulting "color"-node is identical, saving the tree to a file fails. We make Augeas aware of the difference on node-level, by alternating between nodes:<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">let lns = [ a ]|[ b ]<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I hope this was somewhat understandable and helpful to you (or others finding this mail with Google </span><span style="font-size:11.0pt;font-family:Wingdings;color:#1f497d">J</span><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> ).<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Ciao,<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Xavier.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p><p class="MsoNormal"><u></u> <u></u></p><div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt"><div><div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0cm 0cm 0cm"><p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> <a href="mailto:augeas-devel-bounces@redhat.com" target="_blank">augeas-devel-bounces@redhat.com</a> [mailto:<a href="mailto:augeas-devel-bounces@redhat.com" target="_blank">augeas-devel-bounces@redhat.com</a>] <b>On Behalf Of </b>Yclept Nemo<br><b>Sent:</b> Friday, Oct</span><span lang="DE" style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">ober 23, 2015 7:07 AM<br><b>To:</b> augeas-devel<br><b>Subject:</b> [augeas-devel] Lens Help: disambiguating 1] regex difference 2] overlapping lenses in union.put<u></u><u></u></span></p></div></div><div><div class="h5"><p class="MsoNormal"><u></u> <u></u></p><div><p class="MsoNormal">Hi,<br><br>I'm working on a lens that has two errors:<br><br> >>  1 (*<br> >>  2 # example configuration follows:<br> >>  3 # default = value<br> >>  4 key = value<br> >>  5<br> >>  6 # default = value # inline comment<br> >>  7 key = value # inline comment<br> >>  8 *)<br> >>  9<br> >> 10 (*<br> >> 11 # key/value formats:<br> >> 12<br> >> 13 keys<br> >> 14     [a-z_]<br> >> 15<br> >> 16 values<br> >> 17     boolean:            true/false<br> >> 18     int                 0, 100<br> >> 19     real                3.0<br> >> 20     hex int             ffeedd<br> >> 21     string              "..."<br> >> 22     unquoted string     sdl, f, f2<br> >> 23 *)<br> >> 24<br> >> 25 (*<br> >> 26 # quoted string regex scratchpad<br> >> 27 quoted string regex =<br> >> 28     good:<br> >> 29         "asdf\"qwer"<br> >> 30         "asdf\\qwer"<br> >> 31         "asdf\\\\\"qwer"<br> >> 32     bad:<br> >> 33         "asdf\\"qwer"<br> >> 34         "asdf\\\\\\"qwer"<br> >> 35<br> >> 36     /.*/ - /.*(<a>\\)*[^\]".*/</a><br> >> 37<br> >> 38     /([^"](\")?)*/<br> >> 39 *)<br> >> 40<br> >> 41 module ConfigObj =<br> >> 42     let _               = print_regexp /"/<br> >> 43     let _               = print_string "\n"<br> >> 44     let var0            = "\""<br> >> 45     let _               = print_string (var0 . "\n")<br> >> 46     let _               = print_string "\n"<br> >> 47<br> >> 48     let var1            = "\"asdf\\\\\\\\"qwer\""<br> >> 49     let _               = print_string (var1 . "\n")<br> >> 50     let _               = print_string ((regexp_match (/\".*\"/ - /\"(.*[^\])?([\]{2})*".*\"/) var1) . "\n")<br> >> 51<br> >> 52     let option          = key /[a-z]([a-z_]*[a-z])?/<br> >> 53     let value_bool      = store /(true|false)/ . [ label "type" . value "bool" ]<br> >> 54     let value_int       = store /(0|[1-9][0-9]*)/ . [ label "type" . value "int" ]<br> >> 55     let value_decimal   = store ((lens_ctype value_int) . /\.[0-9]+/) . [ label "type" . value "decimal" ]<br> >> 56     let value_string    = (del "\"" "\"") . (store (/.*/ - /(.*[^\]|)([\]{2})*".*/)) . (del "\"" "\"") . [ label "type" . value "string" ]<br> >> 57     let value_all       = value_bool | value_int | value_decimal<br> >> 58     let sep_assign      = del /[ \t]*=[ \t]*/ " = "<br> >> 59     let sep_comment     = del /[ \t]*#[ \t]*/ " # "<br> >> 60     let record_comment  = [ label "comment" . sep_comment . store /([^ \t\n].*)?/ ]<br> >> 61     let record          = option . sep_assign . value_all . record_comment?<br> >> 62     let record_not      = label "comment" . store (/([^ \t\n].*)?/ - lens_ctype record)<br> >> 63     let comment         = del /#[ \t]*/ "# " . ( [ record . [ label "commented" ] ] | [ record_not ] )<br> >> 64     let line            = del /[ \t]*/ "" . ( comment | [ record ] ) . del "\n" "\n"<br> >> 65     let lns             = line *<br><br>The first is a regex problem: I want to match double-quoted c-style strings, ie strings with escape sequences such as "\"", "\\\"" and so on. The regex I've crafted (line#50) evidently fits the bill - try modifying the input test values (line#48) to verify - so I don't understand why the derived lens (line#56) is failing, and thereby causing this "ambiguous concatenation" error:<br><br> >> Syntax error in lens definition<br> >> configobj.aug:61.4-.75:Failed to compile record<br> >> configobj.aug:61.26-.75:exception: ambiguous concatenation<br> >>       First regexp: /([a-z]([a-z_]*[a-z])?)([ \t]*=[ \t]*)((((true|false)))|(((0|[1-9][0-9]*)))|(((((0|[1-9][0-9]*)))(<a>\\.[0-9]+)))|((")(([^\n"\\][^\n"\\]*\\\\|\\\\)([^\n\\][^\n"\\]*\\\\)*\\\\(([^\n"\\][^\n"\\]*\\\\|\\\\)([^\n\\][^\n"\\]*\\\\)*\\\\)*(([^\n"\\][^\n"\\]*\\\\|\\\\)([^\n\\][^\n"\\]*\\\\)*([^\n\\][^\n"\\]*|)|[^\n"\\][^\n"\\]*|)|([^\n"\\][^\n"\\]*\\\\|\\\\)([^\n\\][^\n"\\]*\\\\)*([^\n\\][^\n"\\]*|)|[^\n"\\][^\n"\\]*|)(")))/</a><br> >>       Second regexp: /(([ \t]*#[ \t]*)(([^ \t\n].*)?))?/<br> >>       'a="\\"#"' can be split into<br> >>       'a="\\"|=|#"'<br> >><br> >>      and<br> >>       'a="\\"#"|=|'  <----- not possible per the regex<br> >><br> >>     First lens: configobj.aug:61.26-.57:<br> >>     Second lens: configobj.aug:61.60-.75:<br><br>The second problem - you'll see if the first is fixed - is a limitation of augeas' tree-text conversion, the inability to differentiate trees on depth. This generates the error "exception: overlapping lenses in tree union.put" and crops up in two locations:<br><br> '[ record . [ label "commented" ] ]' (line#63) ----vs---- '[ record_not ]' (line#63)<br>    ::: The "record_not" label of "comment" is also a possible valid label of the "record" lens [line#52]. Hacky workaround is to change the label to an invalid key, ie "comment2", etc.<br> '[ record . [ label "commented" ] ]' (line#63) ----vs---- '[ record ]' (line#64)<br>    ::: Unlike previous, no hacky workaround.<br><br>Obviously this can be fixed by scanning the *depth* of the tree. In both cases, one branch is guaranteed to have a subnode with the label "commented" unlike the other. While augeas doesn't implement this, there was a suggestion on the mailing list regarding a lens-based workaround[1] that I didn't understand. I'd appreciate if someone could provide a concrete example for my case.<br><br><br>Sincerely,<br><br><br>[1] <a href="https://www.redhat.com/archives/augeas-devel/2009-June/msg00088.html" target="_blank">https://www.redhat.com/archives/augeas-devel/2009-June/msg00088.html</a><u></u><u></u></p></div></div></div></div></div></div><br>_______________________________________________<br>
augeas-devel mailing list<br>
<a href="mailto:augeas-devel@redhat.com">augeas-devel@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/augeas-devel" rel="noreferrer" target="_blank">https://www.redhat.com/mailman/listinfo/augeas-devel</a><br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr">Raphaël Pinson<div>Infrastructure Developer & Training Leader</div><div>+33 458 482 013<div><br></div><div>Camptocamp France<br>
Savoie Technolac<br>
BP 352<br>
48, avenue du Lac du Bourget<br>
73372 Le Bourget du Lac, Cedex<br>
<a href="http://www.camptocamp.com" target="_blank">www.camptocamp.com</a><br>
</div></div></div></div></div></div>
</div>