Hi Yclept,
do I understand your lens correctly in that you try to find commented records,
which are the same as regular records, just that they happen to be preceeded by
a comment sign ('#')? Of course, that is your choice, but do you gain much out
of that? Once you have found a comment sign, you may simply store all of the
following up to the end of the line as value. In fact, that's what Util.comment
does. And in case a record is suffixed by a comment, Util.comment_eol exists
and creates a different node in the tree to represent that.
Here is a draft for possible simplifications:
module ConfigObj_Simple =
let sp = Sep.space
let empty = Util.empty
let comment = Util.comment
let record =
let option = key /[a-z_]+/ in
let value_all = Quote.dquote_spaces in
[ Util.indent . option . del /[ \t]*=/ " =" . (sp . value_all)? .
Util.comment_or_eol ]
let lns = ( empty | comment | record )*
I'm sorry, this example module doesn't even pass the tests from augparse
(ambiguity with Quote.dquote_spaces and trailing comments and after that still
the very same issue as discussed in the parallel mail thread), so it is more or
less again a demonstration on how one can reuse what is already present in
Augeas' shipped modules. Also, I made some compromises. For example, I allow
"[a-z_]+" as a valid string for option, whereas you forbid '_' as first and
last character. Yes, this might allow for wrong configuration files to be
created with Augeas, but in my personal opinion, Augeas makes it too difficult
to enforce all the details that might go into creating a syntactically correct
configuration file for every theoretically possible situation. So what I
normally do is allow for a different syntax, that achieves the same result. In
the case of trailing comments that means, that they are not supported by my
modules – comments always have to be on their own line by themselves, which
effectively doesn't alter the meaning of the configuration and saves me a lot
of headache. I also require all lines to have an end-of-line character, since I
have not found a way of matching the end of a file otherwise.
So in short, if it seems to be impossible to match all you want, try cut it
down to things you need at its core and make compromises. ;-) Augeas is not as
powerful as any scripting or programming language and therefore some
configuration files might be actually impossible to be parsed with it (though I
haven't found an example for that yet).
Ciao,
Xavier.
From: Yclept Nemo [mailto:[email protected]]
Sent: Monday, November 02, 2015 5:57 PM
To: Mol, Xavier (SCC)
Cc: augeas-devel
Subject: Re: [augeas-devel] ConfigObj: working lens seeking tips/improvements
Hi,
> 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
That's no-problem/understandable, for others I've substituted the
ConfigObj_Simple module with generic constructs.
> 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.
> Hence they are very refined and allow people foreign to your code a quick
> start
Here is the ConfigObj_Simple module with as much as possible substituted with
generic module constructs. There really isn't much simplification possible due
to the differing definitions of both comments (module Util) and quotes (module
Quote):
(* 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 = Util.del_opt_ws " "
let newline = Util.del_str "\n"
let option = key /[a-z]([a-z_]*[a-z])?/
let value_all = store (/"([^\n\"]*([\].)*)*"/ | /[^ \t\n"#][^
\t\n#]*/)
let sep_comment = Util.del_str "#"
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.equal . (spaces .
value_all)? . (Sep.opt_space | (spaces . record_comment))
let record = [ record_commented? . record_simple ]
let comment = [ comment_label . sep_comment . store (/.*/ - (/[
\t]*/ . lens_ctype record_simple)) ]
let entry = Util.indent . ( record | comment ) . newline
let empty = [ Util.eol ]
let line = empty | entry
let lns = line *
> 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.
That is a good idea but doesn't help in situtations such as ConfigObj_Simple or
(simplified):
module AmbiguousCombinatorics =
let a = store /a/ . [ label ".comment" ]
let b = [ label "commented" ]
let c = [ Build.combine_two a b ]
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ augeas-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/augeas-devel
