[augeas-devel] How to write lens so that it can parse empty file.

Raphaël Pinson raphael.pinson at camptocamp.com
Thu May 31 16:36:58 UTC 2012


On Thu, May 31, 2012 at 6:27 PM, Nathaniel Cook <nvcook42 at gmail.com> wrote:

> Raphaël,
>
> Thanks that helps a lot. I am very new at this so I appreciate the
> suggestions. Makes sense now that you explain that an empty file is
> "\n". As for the file you can only have one gridname entry, so to keep
> it simple I was going to force it to be first in the file or not at
> all. I tried this but
>
> let len = (gridname | Util.empty)? . (data_source | Util.empty)*
>
> but I get an ambiguos concatenation error,  which makes sense but I
> don' t know how to get around it. How can I enforce only one gridname
> entry?
>


How about:

let lns  = (Util.empty* . gridname)? . (data_source | Util.empty)*



Once you have a lens working as you wish, check the existing lenses for
NaturalDocs comments so your lens can be documented automatically.


Raphaël




>
> Nathaniel Cook
>
> On Thu, May 31, 2012 at 9:13 AM, Raphaël Pinson
> <raphael.pinson at camptocamp.com> wrote:
> > You could also make a larger use of common modules (Util, Rx, Sep,
> Build) to
> > simply the lens. Here is my take for the lens:
> >
> >
> >
> > module Gmetad =
> >
> > autoload xfm
> >
> > let quoted =
> >      let quote = Util.del_str "\""
> >   in quote . store Rx.word. quote
> >
> > let data_source =
> >      let host = [ label "host" . store Rx.word ]
> >   in Build.key_value_line "data_source" Sep.space
> >       (quoted . Sep.space
> >       . Build.opt_list host Sep.space)
> >
> >
> > let gridname = Build.key_value_line "gridname" Sep.space quoted
> >
> > let lns  = (gridname | data_source | Util.empty)*
> >
> > let filter = incl "/etc/gmetad.conf"
> > let xfm = transform lns filter
> >
> >
> >
> >
> > and for the test file:
> >
> >
> > module Test_gmetad =
> >    let conf = "gridname \"grid\"
> > data_source \"group_name\" ds1 ds2 ds3.example.com
> > data_source \"group_other\" www1 www2 www3.example.com
> > "
> >    test Gmetad.lns get  conf =
> >    { "gridname" = "grid" }
> >    { "data_source" = "group_name"
> >      { "host" = "ds1" }
> >      { "host" = "ds2" }
> >      { "host" = "ds3.example.com" } }
> >    { "data_source" = "group_other"
> >      { "host" = "www1" }
> >      { "host" = "www2" }
> >      { "host" = "www3.example.com" } }
> >
> >
> >
> > Raphaël
> >
> >
> >
> >
> > On Thu, May 31, 2012 at 4:57 PM, Raphaël Pinson
> > <raphael.pinson at camptocamp.com> wrote:
> >>
> >>
> >> On Thu, May 31, 2012 at 4:38 PM, Nathaniel Cook <nvcook42 at gmail.com>
> >> wrote:
> >>>
> >>> I have been working on writing a simplified lens for the ganglia
> >>> gmetad.conf file. I have the lens working as I like but when I try to
> >>> use augeas to add entries to the file I get errors on save if the file
> >>> doesn't exist or is empty. It says it cannot parse the entire input:
> >>>
> >>> /augeas/files/etc/gmetad.conf/error = "parse_failed"
> >>> /augeas/files/etc/gmetad.conf/error/pos = "0"
> >>> /augeas/files/etc/gmetad.conf/error/line = "1"
> >>> /augeas/files/etc/gmetad.conf/error/char = "0"
> >>> /augeas/files/etc/gmetad.conf/error/lens =
> >>> "/usr/share/augeas/lenses/gmetad.aug:22.12-.56:"
> >>> /augeas/files/etc/gmetad.conf/error/message = "Get did not match entire
> >>> input"
> >>>
> >>>
> >>> Here is the lens:
> >>>
> >>>
> >>> module Gmetad =
> >>>    autoload xfm
> >>>
> >>>    let quote = Util.del_str "\""
> >>>    let space = del /[ \t]+/ " "
> >>>    let eol = Util.del_str "\n"
> >>>    let empty =  del /[ \t]*/ "" . eol
> >>>
> >>>    let host = store /[a-zA-Z0-9._]+/
> >>>    let hosts = ( space . [ seq "hosts" . host ] )+
> >>>    let group = [ label "group" . quote . store /[a-zA-Z0-9._ ]+/ .
> quote
> >>> ]
> >>>    let data_source = [ counter "hosts" .  label "data_source" .
> >>> Util.del_str "data_source" . space . group . [ label "hosts" . hosts ]
> >>> ]
> >>>
> >>>    let gridname = [ label "gridname" . Util.del_str "gridname" .
> >>> space . quote . store /[a-zA-Z0-9._]+/ . quote ]
> >>>
> >>>    let lns  = (gridname . empty)* . (data_source . empty)*
> >>>
> >>>    let filter = incl "/etc/gmetad.conf"
> >>>    let xfm = transform lns filter
> >>>
> >>>
> >>> Here is the test module:
> >>>
> >>> module Test_gmetad =
> >>>    let conf = "gridname \"grid\"
> >>> data_source \"group_name\" ds1 ds2 ds3.example.com
> >>> data_source \"group_other\" www1 www2 www3.example.com
> >>> "
> >>>    test Gmetad.lns get  conf =
> >>>    { "gridname" = "grid" }
> >>>    { "data_source"
> >>>            { "group" = "group_name" }
> >>>            { "hosts"
> >>>                { "1" = "ds1" }
> >>>                { "2" = "ds2" }
> >>>                { "3" = "ds3.example.com" }
> >>>            }
> >>>    }
> >>>    { "data_source"
> >>>        { "group" = "group_other" }
> >>>        { "hosts"
> >>>            { "1" = "www1" }
> >>>            { "2" = "www2" }
> >>>            { "3" = "www3.example.com" }
> >>>        }
> >>>    }
> >>>
> >>>    let empty = ""
> >>>
> >>>    test Gmetad.lns get empty = ?
> >>>
> >>
> >>
> >> An empty (or non existent) file is not an empty string, but a single
> >> carriage return. The test should thus be:
> >>
> >> test Gmetad.lns get "\n" = ?
> >>
> >> which fails since the lens cannot parse a single carriage return. This
> is
> >> the reason why it fails in augtool.
> >>
> >>
> >> Doesn't this format not support empty lines? If it does, I'd advise to
> use
> >> Util.eol in gridname and data_source, and write lns as:
> >>
> >> let lns = (gridname | data_source | Util.empty)*
> >>
> >> or does the order strictly matter?
> >>
> >>
> >> Raphaël
> >>
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20120531/e5c0c225/attachment.htm>


More information about the augeas-devel mailing list