<div dir="ltr">There, I'm a bit more happy with this...<br><br>I added a test file which (I believe) performs all the necessary tests. I will have a look at the hg mail command to send the diff to you.<br><br><br>inifile.aug :<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>    (* Define useful shortcuts *)<br><br>    let eol                = Util.del_str "\n"<br>    let del_to_eol         = del /[^\n]*/ ""<br>
    let value_sep          = del /[ \t]*=[ \t]*/ " = "<br>    let value_sepwithcolon = del /[ \t]*(=|:)[ \t]*/ " = "<br>    let value_to_eol       = store /([^ \t\n][^\n]*)?/<br><br><br>    (* Define entry function *)<br>
    (* Some implementations of INI file allow ";" as separator *)<br>    let entry (kw:regexp) = [ key kw . value_sepwithcolon . value_to_eol . eol ]<br>    let entry_nocolon (kw:regexp) = [ key kw . value_sep . value_to_eol . eol ]<br>
<br>    (* Define comment and empty strings *)<br>    (* Some implementations of INI file allow "#" as a comment sign *)<br>    let comment = [ label "comment" . del /(#|;)[ \t]*/ "; " .  store /([^ \t\n][^\n]*)?/ . eol ]<br>
    let comment_nosharp = [ label "comment" . del /;[ \t]*/ "; " .  store /([^ \t\n][^\n]*)?/ . eol ]<br><br>    let empty  = [ del /[ \t]*/ "" . eol ]<br><br><br>    (* Define record *)<br><br>
    let title = Util.del_str "[" . store /[^] ]+/ . Util.del_str "]". eol<br>    let record (label_name:string) (entry:lens) = [ label label_name . title . (entry | comment | empty)* ] <br>    let record_setcomment (label_name:string) (entry:lens) (comment:lens) = [ label label_name . title . (entry | comment | empty)* ] <br>
    (* Some implementations of INI File do not allow empty lines *)<br>    let record_noempty (label_name:string) (entry:lens) = [ label label_name . title . (entry | comment)* ] <br>    let record_noempty_setcomment (label_name:string) (entry:lens) (comment:lens) = [ label label_name . title . (entry | comment)* ] <br>
<br>    (* Generic INI file lens *)<br>    let lns (record:lens) = ( comment | empty )* . record*<br>    (* Let the user choose the type of comment they want *)<br>    let lns_setcomment (record:lens) (comment:lens) = ( comment | empty )* . record*<br>
<br>    (* Some implementations of INI File do not allow empty lines *)<br>    let lns_noempty (record:lens) = comment* . record*<br>    (* Let the user choose the type of comment they want *)<br>    let lns_noempty_setcomment (record:lens) (comment:lens) = comment* . record*<br>
<br>==================================================================<br><br><br>tests/test_inifile.aug<br>==================================================================<br>module Test_IniFile =<br><br>  (* ALL TESTS TO RUN *)<br>
<br>  (* entry   :  (a) entry;   (b) entry_nocolon       *)<br>  (* comment :  (c) comment; (d) comment_nosharp     *)<br>  (* lns     :  (e) lns;     (f) lns_noempty         *)<br><br><br>  (* TEST a/c/e *)<br>  let entry_ace  = IniFile.entry "test_ace"<br>
  let record_ace = IniFile.record "record_ace" entry_ace<br>  let lns_ace    = IniFile.lns record_ace<br>  let conf_ace   = "# comment with sharp<br><br>[section1]<br>test_ace = value<br>; comment with colon<br>
<br>"<br>  test lns_ace get conf_ace = <br>      { "comment" = "comment with sharp" }<br>      {}<br>      { "record_ace" = "section1"<br>          { "test_ace" = "value" }<br>
      { "comment"  = "comment with colon" }<br>      {} }<br><br><br>  (* TEST a/c/f *)<br>  let entry_acf  = IniFile.entry "test_acf"<br>  let record_acf = IniFile.record_noempty "record_acf" entry_acf<br>
  let lns_acf    = IniFile.lns_noempty record_acf<br>  let conf_acf   = "# comment with sharp<br>[section1]<br>test_acf = value<br>test_acf : value2<br>; comment with colon<br>"<br>  test lns_acf get conf_acf = <br>
      { "comment" = "comment with sharp" }<br>      { "record_acf" = "section1"<br>         { "test_acf" = "value" }<br>         { "test_acf" = "value2" }<br>
     { "comment"  = "comment with colon" } }<br><br><br>  (* TEST a/d/e *)<br>  let entry_ade  = IniFile.entry "test_ade"<br>  let record_ade = IniFile.record_setcomment "record_ade" entry_ade IniFile.comment_nosharp<br>
  let lns_ade    = IniFile.lns_setcomment record_ade IniFile.comment_nosharp<br>  let conf_ade   = "; a first comment with colon<br>[section1]<br>test_ade = value<br>test_ade : value2<br>; comment with colon<br><br>"<br>
   test lns_ade get conf_ade =<br>      { "comment" = "a first comment with colon" }<br>      { "record_ade" = "section1"<br>         { "test_ade" = "value" }<br>
         { "test_ade" = "value2" }<br>     { "comment"  = "comment with colon" }<br>     {} }<br><br><br>  (* TEST a/d/f *)<br>  let entry_adf  = IniFile.entry "test_adf"<br>
  let record_adf = IniFile.record_noempty_setcomment "record_adf" entry_adf IniFile.comment_nosharp<br>  let lns_adf    = IniFile.lns_noempty_setcomment record_adf IniFile.comment_nosharp<br>  let conf_adf   = "; a first comment with colon<br>
[section1]<br>test_adf = value<br>test_adf : value2<br>; comment with colon<br>"<br>   test lns_adf get conf_adf =<br>      { "comment" = "a first comment with colon" }<br>      { "record_adf" = "section1"<br>
         { "test_adf" = "value" }<br>         { "test_adf" = "value2" }<br>     { "comment"  = "comment with colon" } }<br><br><br>  (* TEST b/c/e *)<br>  let entry_bce  = IniFile.entry_nocolon "test_bce"<br>
  let record_bce = IniFile.record "record_bce" entry_bce<br>  let lns_bce    = IniFile.lns record_bce<br>  let conf_bce   = "# comment with sharp<br><br>[section1]<br>test_bce = value<br>; comment with colon<br>
<br>"<br>  test lns_bce get conf_bce = <br>      { "comment" = "comment with sharp" }<br>      {}<br>      { "record_bce" = "section1"<br>          { "test_bce" = "value" }<br>
      { "comment"  = "comment with colon" }<br>      {} }<br><br><br>  (* TEST b/c/f *)<br>  let entry_bcf  = IniFile.entry_nocolon "test_bcf"<br>  let record_bcf = IniFile.record_noempty "record_bcf" entry_bcf<br>
  let lns_bcf    = IniFile.lns_noempty record_bcf<br>  let conf_bcf   = "# comment with sharp<br>[section1]<br>test_bcf = value<br>; comment with colon<br>"<br>  test lns_bcf get conf_bcf = <br>      { "comment" = "comment with sharp" }<br>
      { "record_bcf" = "section1"<br>          { "test_bcf" = "value" }<br>      { "comment"  = "comment with colon" } }<br><br><br>  (* TEST b/d/e *)<br>  let entry_bde  = IniFile.entry_nocolon "test_bde"<br>
  let record_bde = IniFile.record_setcomment "record_bde" entry_bde IniFile.comment_nosharp<br>  let lns_bde    = IniFile.lns_setcomment record_bde IniFile.comment_nosharp<br>  let conf_bde   = "; first comment with colon<br>
<br>[section1]<br>test_bde = value<br>; comment with colon<br><br>"<br>  test lns_bde get conf_bde = <br>      { "comment" = "first comment with colon" }<br>      {}<br>      { "record_bde" = "section1"<br>
          { "test_bde" = "value" }<br>      { "comment"  = "comment with colon" }<br>      {} }<br><br><br>  (* TEST b/d/f *)<br>  let entry_bdf  = IniFile.entry_nocolon "test_bdf"<br>
  let record_bdf = IniFile.record_noempty_setcomment "record_bdf" entry_bdf IniFile.comment_nosharp<br>  let lns_bdf    = IniFile.lns_noempty_setcomment record_bdf IniFile.comment_nosharp<br>  let conf_bdf   = "; first comment with colon<br>
[section1]<br>test_bdf = value<br>; comment with colon<br>"<br>  test lns_bdf get conf_bdf = <br>      { "comment" = "first comment with colon" }<br>      { "record_bdf" = "section1"<br>
          { "test_bdf" = "value" }<br>      { "comment"  = "comment with colon" } }<br><br><br>==================================================================<br><br><br><div class="gmail_quote">
On Wed, Jul 23, 2008 at 10:49 AM, Raphaël Pinson <<a href="mailto:raphink@gmail.com">raphink@gmail.com</a>> 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 class="Ih2E3d">On Tue, Jul 22, 2008 at 8:53 PM, David Lutterkort <<a href="mailto:dlutter@redhat.com" target="_blank">dlutter@redhat.com</a>> 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>On Tue, 2008-07-22 at 10:58 +0200, Raphaël Pinson wrote:<br>
> Actually, here is an even more compact version :<br>
<br>
</div>Very nice. I like that a lot. Do you want me to commit that ?<br>
</blockquote></div><div><br>I'm happy you like it.<br><br>I don't think it's ready for production yet though. I made a wiki page for it where I'm posting the code and notes as it goes ( <a href="http://augeas.net/page/Generic_modules/IniFile" target="_blank">http://augeas.net/page/Generic_modules/IniFile</a> ). I understand that it's not as useful as a VCS, but it's a bit easier for me for now and it allows to put the documentation altogether.<br>

<br></div><div class="Ih2E3d"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
One small request: it would make my life easier if you could send these<br>
things as patches (if you commit your changes locally, you can send a<br>
patch with 'hg email')</blockquote></div><div><br><br>I will certainly email you the patch once I have implemented the full format (or at least a reasonable amount of it).<br><br><br><br>Raphaël<br></div></div><br>
</div>
</blockquote></div><br></div>