<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>