<div dir="ltr">I've been trying to implement my proposal already. <br><br>Here is the new inifile.aug:<br><br>=========================================================<br>(* IniFile generic module for Augeas          *)<br>
(* Author: Raphael Pinson <<a href="mailto:raphink@gmail.com">raphink@gmail.com</a>> *)<br>(*                                            *)<br>(* TODO: Support double quotes in value       *)<br><br>module IniFile  =<br>
<br><br>(************************************************************************<br> *                           USEFUL PRIMITIVES<br> *************************************************************************)<br><br>(* Internal primitives *)<br>
let eol                = Util.eol<br>let empty              = [ eol ]<br><br><br>(* Define sep and defaults *)<br>let sep (pat:regexp) (default:string) <br>                       = Util.del_opt_ws "" . del pat default<br>
let sep_re             = /[=:]/<br>let sep_default        = "="<br><br><br>(* Define sto_*  *)<br>let sto_to_eol         = Util.del_opt_ws ""<br>                         . store /([^ \t\n].*[^ \t\n]|[^ \t\n])/<br>
let sto_to_comment     = Util.del_opt_ws ""<br>                         . store /[^;# \t\n][^;#\n]*[^;# \t\n]|[^;# \t\n]/<br><br><br>(* Define comment and defaults *)<br>let comment (pat:regexp) (default:string)<br>
                       = [ label "#comment" . sep pat default<br>                 . sto_to_eol . eol ]<br>let comment_re         = /[;#]/<br>let comment_default    = ";"<br><br><br>(************************************************************************<br>
 *                             ENTRY<br> *************************************************************************)<br><br>(* entry includes comments *)<br><br>let entry (kw:regexp) (sep:lens) (comment:lens)<br>                       = [ key kw . sep . sto_to_comment? . (comment|eol) ] | comment<br>
let entry_re           = ( /[A-Za-z][A-Za-z0-9\._-]+/ - /#comment/ )<br><br><br>(************************************************************************<br> *                             RECORD <br> *************************************************************************)<br>
<br>let title (kw:regexp)<br>                       = Util.del_str "[" . key kw<br>                         . Util.del_str "]". eol<br>let title_label (name:string) (kw:regexp)<br>                       = label name<br>
                         . Util.del_str "[" . store kw<br>                         . Util.del_str "]". eol<br><br>let record_noempty (title:lens) (entry:lens)<br>                       = [ title<br>               . entry* ]<br>
let record (title:lens) (entry:lens)<br>                       = record_noempty title ( entry | empty )<br>let record_re          = ( /[^]\n\/]+/ - /#comment/ ) <br>let record_label_re    = /[^]\n]+/<br><br><br>(************************************************************************<br>
 *                              LENS<br> *************************************************************************)<br><br>let lns_noempty (record:lens) (comment:lens)<br>                       = comment* . record*<br>let lns (record:lens) (comment:lens)<br>
                       = lns_noempty record (comment|empty)<br><br>=========================================================<br><br><br>dput became <br><br><br>=========================================================<br>
(* Dput module for Augeas <br>   Author: Raphael Pinson <<a href="mailto:raphink@gmail.com">raphink@gmail.com</a>> <br><br><br>   Reference: dput uses Python's ConfigParser:<br>     <a href="http://docs.python.org/lib/module-ConfigParser.html">http://docs.python.org/lib/module-ConfigParser.html</a><br>
*)<br><br><br>module Dput =<br>  autoload xfm<br><br><br>(************************************************************************<br> * INI File settings<br> *************************************************************************)<br>
let comment  = IniFile.comment IniFile.comment_re IniFile.comment_default<br><br>let sep      = IniFile.sep IniFile.sep_re IniFile.sep_default<br><br><br>let setting = "allow_non-us_software"<br>            | "allow_unsigned_uploads"<br>
            | "check_version"<br>            | "default_host_main"<br>            | "default_host_non-us"<br>            | "fqdn"<br>            | "hash"<br>            | "incoming"<br>
            | "login"<br>            | "method"<br>            | "passive_ftp"<br>            | "post_upload_command"<br>            | "pre_upload_command"<br>            | "progress_indicator"<br>
            | "run_dinstall"<br>            | "run_lintian"<br>            | "scp_compress"<br>            | "ssh_config_options"<br><br>(************************************************************************<br>
 * "name: value" entries, with continuations in the style of RFC 822;<br> * "name=value" is also accepted<br> * leading whitespace is removed from values<br> *************************************************************************)<br>
let entry = IniFile.entry setting sep comment <br><br><br>(************************************************************************<br> * sections, led by a "[section]" header<br> * We can't use titles as node names here since they could contain "/"<br>
 * We remove #comment from possible keys<br> * since it is used as label for comments<br> * We also remove / as first character<br> * because augeas doesn't like '/' keys (although it is legal in INI Files)<br>
 *************************************************************************)<br>let title   = IniFile.title_label "target" IniFile.record_label_re<br>let record  = IniFile.record title entry <br><br>let lns    = IniFile.lns record comment<br>
<br>let filter = (incl "/etc/<a href="http://dput.cf">dput.cf</a>")<br>           . (incl "~/.<a href="http://dput.cf">dput.cf</a>")<br>           . Util.stdexcl<br><br>let xfm = transform lns filter<br>
=========================================================<br><br><br>php.aug:<br><br>=========================================================<br>(* PHP module for Augeas                      *)<br>(* Author: Raphael Pinson <<a href="mailto:raphink@gmail.com">raphink@gmail.com</a>> *)<br>
(*                                            *)<br><br>module PHP =<br>  autoload xfm<br><br>(************************************************************************<br> * INI File settings<br> *************************************************************************)<br>
<br>let comment  = IniFile.comment IniFile.comment_re IniFile.comment_default<br>let sep      = IniFile.sep IniFile.sep_re IniFile.sep_default<br><br><br>(************************************************************************<br>
 *                        ENTRY<br> *<br> * We have to remove the keyword "section" from possible entry keywords<br> * otherwise it would lead to an ambiguity with the "section" label<br> * since PHP allows entries outside of sections.<br>
 *************************************************************************)<br>let entry_re = ( /[A-Za-z][A-Za-z0-9\._-]+/ - /#comment/ - /section/ )<br>let entry    = IniFile.entry entry_re sep comment<br><br><br>(************************************************************************<br>
 *                         TITLE<br> *<br> * We use IniFile.title_label because there can be entries<br> * outside of sections whose labels would conflict with section names<br> *************************************************************************)<br>
let title   = IniFile.title_label "section" IniFile.record_label_re<br>let record  = IniFile.record title entry<br><br><br>(************************************************************************<br> *                         LENS & FILTER<br>
 * There can be entries before any section<br> * IniFile.entry includes comment management, so we just pass entry to lns<br> *************************************************************************)<br>let lns    = IniFile.lns record entry<br>
<br>let filter = (incl "/etc/php*/*/php.ini")<br>             . Util.stdexcl<br><br>let xfm = transform lns filter<br>=========================================================<br><br>and puppet.aug <br><br>=========================================================<br>
(* Puppet module for Augeas<br> Author: Raphael Pinson <<a href="mailto:raphink@gmail.com">raphink@gmail.com</a>><br><br> puppet.conf is a standard INI File.<br>*)<br><br><br>module Puppet =<br>  autoload xfm<br><br>
(************************************************************************<br> * INI File settings<br> *<br> * puppet.conf only supports "# as commentary and "=" as separator<br> *************************************************************************)<br>
let comment    = IniFile.comment "#" "#"<br>let sep        = IniFile.sep "=" "="<br><br><br>(************************************************************************<br> *                        ENTRY<br>
 * puppet.conf uses standard INI File entries<br> *************************************************************************)<br>let entry   = IniFile.entry IniFile.entry_re sep comment<br><br><br>(************************************************************************<br>
 *                        RECORD<br> * puppet.conf uses standard INI File records<br> *************************************************************************)<br>let title   = IniFile.title IniFile.record_re<br>let record  = IniFile.record title entry<br>
<br><br>(************************************************************************<br> *                        LENS & FILTER<br> * puppet.conf uses standard INI File records<br> *************************************************************************)<br>
let lns     = IniFile.lns record comment<br><br>let filter = (incl "/etc/puppet/puppet.conf")<br><br>let xfm = transform lns filter<br>=========================================================<br><br><br>Raphaël<br>
<br><br><br><div class="gmail_quote">On Thu, Aug 14, 2008 at 12:07 PM, Raphaël Pinson <span dir="ltr"><<a href="mailto:raphink@gmail.com">raphink@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div dir="ltr"><br><br><div class="gmail_quote"><div><div></div><div class="Wj3C7c">On Thu, Aug 14, 2008 at 11:56 AM, Raphaël Pinson <span dir="ltr"><<a href="mailto:raphink@gmail.com" target="_blank">raphink@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div>Hi there,<br><br><br>As I'm playing with inifile.aug and applying it to php.aug, mysql.aug and dput.aug, I find so many different configurations that inifile.aug gets very complicated to my taste. Since functions in lenses cannot take defaults, I end up defining lots of them to set more or less variables. I would like to really simplify inifile.aug. This might mean making the lenses that use it a bit more complicated, but also clearer.<br>


<br>Here is my proposal. Comments are very welcome:<br><br>Writing a generic INI file using inifile.aug would look like this :<br><br>=========================================================<br>let comment_re      = /[;#]/<br>


let comment_default = ";"<br>let comment         = IniFile.comment comment_re comment_default<br><br>let empty           = IniFile.empty comment_re<br><br>let sep_re          = /[:=]/<br>let sep_default     = "="<br>


let sep             = IniFile.sep sep_re sep_default<br><br>(* IniFile.entry_re  = ( /[A-Za-z][A-Za-z0-9\._-]+/ - /#comment/ ) *)<br>let entry_re        = IniFile.entry_re<br>let entry            = IniFile.entry entry_re sep comment<br>


<br>(* IniFile.record_re = ( /[^]\n\/]+/ - /#comment/ ) *)<br>let record_re      = IniFile.record_re<br>let record          = IniFile.record record_re entry comment empty<br><br><br>let lns             = IniFile.lns record comment<br>


=========================================================<br><br><br>This would be a bit longer than it is currently, but much clearer, too.<br><br>The values taken by the setting fields would be:<br><br>comment_re        := ";"| "#" | /[;#]/<br>


comment_default := ";" | "#"<br><br>sep_re                 := ":" | "=" | /[:=]/<br>sep_default          := ";" | "="<br><br>entry_re               := IniFile.entry_re | your_own_re<br>


<br>record_re             := IniFile.record_re | your_own_re<br><br>Other values for these fields could not be certified to work properly.<br><br><br>Default values provided:<br><br>IniFile.comment_re        = /[;#]/<br>

IniFile.comment_default = ";"<br>
IniFile.sep_re                = /[:=]/<br>IniFile.sep_default         = "="<br>IniFile.entry_re              = ( /[A-Za-z][A-Za-z0-9\._-]+/ - /#comment/ )<br>IniFile.record_re            =  ( /[^]\n\/]+/ - /#comment/ ) <br>


<br><br>
Additionally, IniFile.record_noempty and IniFile.lns_noempty would be provided, since I don't know how to deal with these.<br>
<br><br>Another example, with dput.aug :<br><br>=========================================================<br><br>
let comment  = IniFile.comment IniFile.comment_re IniFile.comment_default<br>
let empty      = IniFile.empty IniFile.comment_re<br>
<br>
let sep          = IniFile.sep IniFile.sep_re IniFile.set_default<br>
<br>let setting = "allow_non-us_software"<br>               | "allow_unsigned_uploads"<br>               | "check_version"<br>               | "default_host_main"<br>               | "default_host_non-us"<br>


               | "fqdn"<br>               | "hash"<br>               | "incoming"<br>               | "login"<br>               | "method"<br>               | "passive_ftp"<br>


               | "post_upload_command"<br>               | "pre_upload_command"<br>               | "progress_indicator"<br>               | "run_dinstall"<br>               | "run_lintian"<br>


               | "scp_compress"<br>               | "ssh_config_options"<br>
let entry = IniFile.entry setting sep comment<br>
<br>
let record  = IniFile.record IniFile.record_re entry comment empty<br>
<br>
let lns    = IniFile.lns record comment<br>
=========================================================<br><br><br>It is obviously longer than the current format, but also much clearer on what is accepted and what is not. Alternatively, this is php.aug:<br><br>
=========================================================<br><br>let comment  = IniFile.comment IniFile.comment_re IniFile.comment_default<br>

let empty      = IniFile.empty IniFile.comment_re<br>let eol          = IniFile.eol<br><br>let sep          = IniFile.sep IniFile.sep_re IniFile.set_default<br><br>(*<br>  We have to remove the keyword "section" from possible entry keywords<br>


  otherwise it would lead to an ambiguity with the "section" label<br>  since PHP allows entries outside of sections.<br>*)<br>let entry_re  = (  /[A-Za-z][A-Za-z0-9\._-]+/ - /#comment/ - /section/ )<br>let entry = IniFile.entry entry_re sep comment<br>


<br>let title<br>           = label "section"<br>             .Util.del_str "[" . store /[^]]+/<br>             . Util.del_str "]". eol<br><br>let record = [ title_label<br>             . (entry | comment | empty)* ]<br>


<br>let lns    = ( comment | empty | entry )* . record*<br>
=========================================================<br><br></div></blockquote></div></div><div><br><br>Alternatively, PHP.lns could be<br><br>let lns = IniFile.lns record (comment|entry) <br><br>This trick would send (comment|entry) as the comment lens for IniFile.lns, so lns would be equivalent to:<br>

<br>let lns =  ( (comment|entry) | empty )* . record*<br><br><br><br>Raphaël<br></div></div><br><br></div>
</blockquote></div><br></div>