[augeas-devel] Unions matching empty strings?

David Lutterkort lutter at redhat.com
Fri Jul 31 09:52:55 UTC 2009


On Thu, 2009-07-30 at 08:45 +1000, Matthew Palmer wrote:
> [Sorry about the bollocks subject; not sure even what the right keywords
> here are]
> 
> I'm trying to write a lens (for syslinux boot config files, if it matters)
> and I want to take option keys which could be case-insensitive and turning
> them into consistent keys in the tree.  I'm trying to do this:
> 
> module Testparse =                                                                                                                                                                                              
>         autoload xfm                                                                                                                                                                                            
> 
>         let option = [ (del /[Ff][Oo][Oo]/ "foo" . label "foo")
>                       |(del /[Bb][Aa][Rr]/ "bar" . label "bar")
>                       . del /[ \t]+/ " "
>                       . store /[^ \t].*/
>                       . del /\n/ "\n"
>                      ]
> 
>         let lns = option+
> 
>         let filter = incl "/tmp/minparse"
> 
>         let xfm = transform lns filter
> 
> But I'm getting a rather arse error message:
> 
> ../testparse.aug:4.1-9.15:Failed to compile option
> ../testparse.aug:4.16-8.30:exception: overlapping lenses in tree union.put
>     Example matched by both: ''
>     First lens: ../testparse.aug:4.16-.55
>     Second lens: ../testparse.aug:5.15-8.30
> 
> To me, this seems totally wrong -- how could either of those match an empty
> string, let alone both?  None of the results found by Google seem to match
> up with what I'm doing.  Any pointers on what I'm doing wrong?

It's a limitation of how trees are matched against lenses; fixing it
would require a thorough overhaul of the tree -> file machinery. Can you
file a bug along the lines of 'gets confused by valid lens'

You can work around it by using two separate '[]' constructs for the two
branches of the union. Replacing option in the above with

        let option =
          let value =
            del /[ \t]+/ " " . store /[^ \t].*/ . del /\n/ "\n" in
          [ del /[Ff][Oo][Oo]/ "foo" . label "foo" . value ]
          | [ del /[Bb][Aa][Rr]/ "bar" . label "bar" . value ]
        
typechecks and should do what you want. As a sidenote, case-insensitive
regexps are something that's in dire need of being added to let you
write 'del /foo/i "foo" ...'

David







More information about the augeas-devel mailing list