Blame lenses/inifile.aug

Packit Service a2ae7a
(*
Packit Service a2ae7a
Module: IniFile
Packit Service a2ae7a
  Generic module to create INI files lenses
Packit Service a2ae7a
Packit Service a2ae7a
Author: Raphael Pinson <raphink@gmail.com>
Packit Service a2ae7a
Packit Service a2ae7a
About: License
Packit Service a2ae7a
  This file is licensed under the LGPL v2+, like the rest of Augeas.
Packit Service a2ae7a
Packit Service a2ae7a
About: TODO
Packit Service a2ae7a
  Things to add in the future
Packit Service a2ae7a
  - Support double quotes in value
Packit Service a2ae7a
Packit Service a2ae7a
About: Lens usage
Packit Service a2ae7a
  This lens is made to provide generic primitives to construct INI File lenses.
Packit Service a2ae7a
  See <Puppet>, <PHP>, <MySQL> or <Dput> for examples of real life lenses using it.
Packit Service a2ae7a
Packit Service a2ae7a
About: Examples
Packit Service a2ae7a
  The <Test_IniFile> file contains various examples and tests.
Packit Service a2ae7a
*)
Packit Service a2ae7a
Packit Service a2ae7a
module IniFile  =
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(************************************************************************
Packit Service a2ae7a
 * Group:               USEFUL PRIMITIVES
Packit Service a2ae7a
 *************************************************************************)
Packit Service a2ae7a
Packit Service a2ae7a
(* Group: Internal primitives *)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: eol
Packit Service a2ae7a
  End of line, inherited from <Util.eol>
Packit Service a2ae7a
*)
Packit Service a2ae7a
let eol = Util.doseol
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(* Group: Separators *)
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sep
Packit Service a2ae7a
  Generic separator
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    pat:regexp - the pattern to delete
Packit Service a2ae7a
    default:string - the default string to use
Packit Service a2ae7a
*)
Packit Service a2ae7a
let sep (pat:regexp) (default:string)
Packit Service a2ae7a
                       = Sep.opt_space . del pat default
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sep_noindent
Packit Service a2ae7a
  Generic separator, no indentation
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    pat:regexp - the pattern to delete
Packit Service a2ae7a
    default:string - the default string to use
Packit Service a2ae7a
*)
Packit Service a2ae7a
let sep_noindent (pat:regexp) (default:string)
Packit Service a2ae7a
                       = del pat default
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sep_re
Packit Service a2ae7a
  The default regexp for a separator
Packit Service a2ae7a
*)
Packit Service a2ae7a
Packit Service a2ae7a
let sep_re             = /[=:]/
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sep_default
Packit Service a2ae7a
  The default separator value
Packit Service a2ae7a
*)
Packit Service a2ae7a
let sep_default        = "="
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(* Group: Stores *)
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sto_to_eol
Packit Service a2ae7a
  Store until end of line
Packit Service a2ae7a
*)
Packit Service a2ae7a
let sto_to_eol         = Sep.opt_space . store Rx.space_in
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: to_comment_re
Packit Service a2ae7a
  Regex until comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let to_comment_re = /[^";# \t\n][^";#\n]*[^";# \t\n]|[^";# \t\n]/
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sto_to_comment
Packit Service a2ae7a
  Store until comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let sto_to_comment = Sep.opt_space . store to_comment_re
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sto_multiline
Packit Service a2ae7a
  Store multiline values
Packit Service a2ae7a
*)
Packit Service a2ae7a
let sto_multiline = Sep.opt_space
Packit Service a2ae7a
         . store (to_comment_re
Packit Service a2ae7a
               . (/[ \t]*\n/ . Rx.space . to_comment_re)*)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: sto_multiline_nocomment
Packit Service a2ae7a
  Store multiline values without an end-of-line comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let sto_multiline_nocomment = Sep.opt_space
Packit Service a2ae7a
         . store (Rx.space_in . (/[ \t]*\n/ . Rx.space . Rx.space_in)*)
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(* Group: Define comment and defaults *)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: comment_noindent
Packit Service a2ae7a
  Map comments into "#comment" nodes,
Packit Service a2ae7a
  no indentation allowed
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    pat:regexp - pattern to delete before commented data
Packit Service a2ae7a
    default:string - default pattern before commented data
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
  (start code)
Packit Service a2ae7a
    let comment  = IniFile.comment_noindent "#" "#"
Packit Service a2ae7a
    let comment  = IniFile.comment_noindent IniFile.comment_re IniFile.comment_default
Packit Service a2ae7a
  (end code)
Packit Service a2ae7a
*)
Packit Service a2ae7a
let comment_noindent (pat:regexp) (default:string) =
Packit Service a2ae7a
  Util.comment_generic_seteol (pat . Rx.opt_space) default eol
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: comment
Packit Service a2ae7a
  Map comments into "#comment" nodes
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    pat:regexp - pattern to delete before commented data
Packit Service a2ae7a
    default:string - default pattern before commented data
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
  (start code)
Packit Service a2ae7a
    let comment  = IniFile.comment "#" "#"
Packit Service a2ae7a
    let comment  = IniFile.comment IniFile.comment_re IniFile.comment_default
Packit Service a2ae7a
  (end code)
Packit Service a2ae7a
*)
Packit Service a2ae7a
let comment (pat:regexp) (default:string) =
Packit Service a2ae7a
  Util.comment_generic_seteol (Rx.opt_space . pat . Rx.opt_space) default eol
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: comment_re
Packit Service a2ae7a
  Default regexp for <comment> pattern
Packit Service a2ae7a
*)
Packit Service a2ae7a
Packit Service a2ae7a
let comment_re         = /[;#]/
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: comment_default
Packit Service a2ae7a
  Default value for <comment> pattern
Packit Service a2ae7a
*)
Packit Service a2ae7a
let comment_default    = ";"
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: empty_generic
Packit Service a2ae7a
  Empty line, including empty comments
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    indent:regexp     - the indentation regexp
Packit Service a2ae7a
    comment_re:regexp - the comment separator regexp
Packit Service a2ae7a
*)
Packit Service a2ae7a
let empty_generic (indent:regexp) (comment_re:regexp) =
Packit Service a2ae7a
  Util.empty_generic_dos (indent . comment_re? . Rx.opt_space)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: empty
Packit Service a2ae7a
  Empty line
Packit Service a2ae7a
*)
Packit Service a2ae7a
let empty = empty_generic Rx.opt_space comment_re
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: empty_noindent
Packit Service a2ae7a
  Empty line, without indentation
Packit Service a2ae7a
*)
Packit Service a2ae7a
let empty_noindent = empty_generic "" comment_re
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(************************************************************************
Packit Service a2ae7a
 * Group:                     ENTRY
Packit Service a2ae7a
 *************************************************************************)
Packit Service a2ae7a
Packit Service a2ae7a
(* Group: entry includes comments *)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry_generic_nocomment
Packit Service a2ae7a
  A very generic INI File entry, not including comments
Packit Service a2ae7a
  It allows to set the key lens (to set indentation
Packit Service a2ae7a
  or subnodes linked to the key) as well as the comment
Packit Service a2ae7a
  separator regexp, used to tune the store regexps.
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:lens           - lens to match the key, including optional indentation
Packit Service a2ae7a
    sep:lens          - lens to use as key/value separator
Packit Service a2ae7a
    comment_re:regexp - comment separator regexp
Packit Service a2ae7a
    comment:lens      - lens to use as comment
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
     > let entry = IniFile.entry_generic (key "setting") sep IniFile.comment_re comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_generic_nocomment (kw:lens) (sep:lens)
Packit Service a2ae7a
                            (comment_re:regexp) (comment:lens) =
Packit Service a2ae7a
     let bare_re_noquot = (/[^" \t\r\n]/ - comment_re)
Packit Service a2ae7a
  in let bare_re = (/[^\r\n]/ - comment_re)+
Packit Service a2ae7a
  in let no_quot = /[^"\r\n]*/
Packit Service a2ae7a
  in let bare = Quote.do_dquote_opt_nil (store (bare_re_noquot . (bare_re* . bare_re_noquot)?))
Packit Service a2ae7a
  in let quoted = Quote.do_dquote (store (no_quot . comment_re+ . no_quot))
Packit Service a2ae7a
  in [ kw . sep . (Sep.opt_space . bare)? . (comment|eol) ]
Packit Service a2ae7a
   | [ kw . sep . Sep.opt_space . quoted . (comment|eol) ]
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry_generic
Packit Service a2ae7a
  A very generic INI File entry
Packit Service a2ae7a
  It allows to set the key lens (to set indentation
Packit Service a2ae7a
  or subnodes linked to the key) as well as the comment
Packit Service a2ae7a
  separator regexp, used to tune the store regexps.
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:lens           - lens to match the key, including optional indentation
Packit Service a2ae7a
    sep:lens          - lens to use as key/value separator
Packit Service a2ae7a
    comment_re:regexp - comment separator regexp
Packit Service a2ae7a
    comment:lens      - lens to use as comment
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
     > let entry = IniFile.entry_generic (key "setting") sep IniFile.comment_re comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_generic (kw:lens) (sep:lens) (comment_re:regexp) (comment:lens) =
Packit Service a2ae7a
  entry_generic_nocomment kw sep comment_re comment | comment
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry
Packit Service a2ae7a
  Generic INI File entry
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp    - keyword regexp for the label
Packit Service a2ae7a
    sep:lens     - lens to use as key/value separator
Packit Service a2ae7a
    comment:lens - lens to use as comment
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
     > let entry = IniFile.entry setting sep comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry (kw:regexp) (sep:lens) (comment:lens) =
Packit Service a2ae7a
     entry_generic (key kw) sep comment_re comment
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: indented_entry
Packit Service a2ae7a
  Generic INI File entry that might be indented with an arbitrary
Packit Service a2ae7a
  amount of whitespace
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp    - keyword regexp for the label
Packit Service a2ae7a
    sep:lens     - lens to use as key/value separator
Packit Service a2ae7a
    comment:lens - lens to use as comment
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
     > let entry = IniFile.indented_entry setting sep comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let indented_entry (kw:regexp) (sep:lens) (comment:lens) =
Packit Service a2ae7a
     entry_generic (Util.indent . key kw) sep comment_re comment
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry_multiline_generic
Packit Service a2ae7a
  A very generic multiline INI File entry
Packit Service a2ae7a
  It allows to set the key lens (to set indentation
Packit Service a2ae7a
  or subnodes linked to the key) as well as the comment
Packit Service a2ae7a
  separator regexp, used to tune the store regexps.
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:lens           - lens to match the key, including optional indentation
Packit Service a2ae7a
    sep:lens          - lens to use as key/value separator
Packit Service a2ae7a
    comment_re:regexp - comment separator regexp
Packit Service a2ae7a
    comment:lens      - lens to use as comment
Packit Service a2ae7a
    eol:lens          - lens for end of line
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
     > let entry = IniFile.entry_generic (key "setting") sep IniFile.comment_re comment comment_or_eol
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_multiline_generic (kw:lens) (sep:lens) (comment_re:regexp)
Packit Service a2ae7a
                            (comment:lens) (eol:lens) =
Packit Service a2ae7a
     let newline = /\r?\n[ \t]+/
Packit Service a2ae7a
  in let bare =
Packit Service a2ae7a
          let word_re_noquot = (/[^" \t\r\n]/ - comment_re)+
Packit Service a2ae7a
       in let word_re = (/[^\r\n]/ - comment_re)+
Packit Service a2ae7a
       in let base_re = (word_re_noquot . (word_re* . word_re_noquot)?)
Packit Service a2ae7a
       in let sto_re = base_re . (newline . base_re)*
Packit Service a2ae7a
                     | (newline . base_re)+
Packit Service a2ae7a
       in Quote.do_dquote_opt_nil (store sto_re)
Packit Service a2ae7a
  in let quoted =
Packit Service a2ae7a
          let no_quot = /[^"\r\n]*/
Packit Service a2ae7a
       in let base_re = (no_quot . comment_re+ . no_quot)
Packit Service a2ae7a
       in let sto_re = base_re . (newline . base_re)*
Packit Service a2ae7a
                     | (newline . base_re)+
Packit Service a2ae7a
       in Quote.do_dquote (store sto_re)
Packit Service a2ae7a
  in [ kw . sep . (Sep.opt_space . bare)? . eol ]
Packit Service a2ae7a
   | [ kw . sep . Sep.opt_space . quoted . eol ]
Packit Service a2ae7a
   | comment
Packit Service a2ae7a
  
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry_multiline
Packit Service a2ae7a
  Generic multiline INI File entry
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp    - keyword regexp for the label
Packit Service a2ae7a
    sep:lens     - lens to use as key/value separator
Packit Service a2ae7a
    comment:lens - lens to use as comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_multiline (kw:regexp) (sep:lens) (comment:lens) =
Packit Service a2ae7a
  entry_multiline_generic (key kw) sep comment_re comment (comment|eol)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry_multiline_nocomment
Packit Service a2ae7a
  Generic multiline INI File entry without an end-of-line comment
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp    - keyword regexp for the label
Packit Service a2ae7a
    sep:lens     - lens to use as key/value separator
Packit Service a2ae7a
    comment:lens - lens to use as comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_multiline_nocomment (kw:regexp) (sep:lens) (comment:lens) =
Packit Service a2ae7a
  entry_multiline_generic (key kw) sep comment_re comment eol
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry_list
Packit Service a2ae7a
  Generic INI File list entry
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp     - keyword regexp for the label
Packit Service a2ae7a
    sep:lens      - lens to use as key/value separator
Packit Service a2ae7a
    sto:regexp    - store regexp for the values
Packit Service a2ae7a
    list_sep:lens - lens to use as list separator
Packit Service a2ae7a
    comment:lens  - lens to use as comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_list (kw:regexp) (sep:lens) (sto:regexp) (list_sep:lens) (comment:lens) =
Packit Service a2ae7a
  let list = counter "elem"
Packit Service a2ae7a
      . Build.opt_list [ seq "elem" . store sto ] list_sep
Packit Service a2ae7a
  in Build.key_value_line_comment kw sep (Sep.opt_space . list) comment
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: entry_list_nocomment
Packit Service a2ae7a
  Generic INI File list entry without an end-of-line comment
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp     - keyword regexp for the label
Packit Service a2ae7a
    sep:lens      - lens to use as key/value separator
Packit Service a2ae7a
    sto:regexp    - store regexp for the values
Packit Service a2ae7a
    list_sep:lens - lens to use as list separator
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_list_nocomment (kw:regexp) (sep:lens) (sto:regexp) (list_sep:lens) =
Packit Service a2ae7a
  let list = counter "elem"
Packit Service a2ae7a
      . Build.opt_list [ seq "elem" . store sto ] list_sep
Packit Service a2ae7a
  in Build.key_value_line kw sep (Sep.opt_space . list)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: entry_re
Packit Service a2ae7a
  Default regexp for <entry> keyword
Packit Service a2ae7a
*)
Packit Service a2ae7a
let entry_re           = ( /[A-Za-z][A-Za-z0-9._-]*/ )
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(************************************************************************
Packit Service a2ae7a
 * Group:                      RECORD
Packit Service a2ae7a
 *************************************************************************)
Packit Service a2ae7a
Packit Service a2ae7a
(* Group: Title definition *)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: title
Packit Service a2ae7a
  Title for <record>. This maps the title of a record as a node in the abstract tree.
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp - keyword regexp for the label
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
    > let title   = IniFile.title IniFile.record_re
Packit Service a2ae7a
*)
Packit Service a2ae7a
let title (kw:regexp)
Packit Service a2ae7a
                       = Util.del_str "[" . key kw
Packit Service a2ae7a
                         . Util.del_str "]". eol
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: indented_title
Packit Service a2ae7a
  Title for <record>. This maps the title of a record as a node in the abstract tree. The title may be indented with arbitrary amounts of whitespace
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    kw:regexp - keyword regexp for the label
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
    > let title   = IniFile.title IniFile.record_re
Packit Service a2ae7a
*)
Packit Service a2ae7a
let indented_title (kw:regexp)
Packit Service a2ae7a
                       = Util.indent . title kw
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: title_label
Packit Service a2ae7a
  Title for <record>. This maps the title of a record as a value in the abstract tree.
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    name:string - name for the title label
Packit Service a2ae7a
    kw:regexp   - keyword regexp for the label
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
    > let title   = IniFile.title_label "target" IniFile.record_label_re
Packit Service a2ae7a
*)
Packit Service a2ae7a
let title_label (name:string) (kw:regexp)
Packit Service a2ae7a
                       = label name
Packit Service a2ae7a
                         . Util.del_str "[" . store kw
Packit Service a2ae7a
                         . Util.del_str "]". eol
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: indented_title_label
Packit Service a2ae7a
  Title for <record>. This maps the title of a record as a value in the abstract tree. The title may be indented with arbitrary amounts of whitespace
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    name:string - name for the title label
Packit Service a2ae7a
    kw:regexp   - keyword regexp for the label
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
    > let title   = IniFile.title_label "target" IniFile.record_label_re
Packit Service a2ae7a
*)
Packit Service a2ae7a
let indented_title_label (name:string) (kw:regexp)
Packit Service a2ae7a
                       = Util.indent . title_label name kw
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: record_re
Packit Service a2ae7a
  Default regexp for <title> keyword pattern
Packit Service a2ae7a
*)
Packit Service a2ae7a
let record_re          = ( /[^]\r\n\/]+/ - /#comment/ )
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Variable: record_label_re
Packit Service a2ae7a
  Default regexp for <title_label> keyword pattern
Packit Service a2ae7a
*)
Packit Service a2ae7a
let record_label_re    = /[^]\r\n]+/
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(* Group: Record definition *)
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: record_noempty
Packit Service a2ae7a
  INI File Record with no empty lines allowed.
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    title:lens - lens to use for title. Use either <title> or <title_label>.
Packit Service a2ae7a
    entry:lens - lens to use for entries in the record. See <entry>.
Packit Service a2ae7a
*)
Packit Service a2ae7a
let record_noempty (title:lens) (entry:lens)
Packit Service a2ae7a
                       = [ title
Packit Service a2ae7a
		       . entry* ]
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: record
Packit Service a2ae7a
  Generic INI File record
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    title:lens - lens to use for title. Use either <title> or <title_label>.
Packit Service a2ae7a
    entry:lens - lens to use for entries in the record. See <entry>.
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
    > let record  = IniFile.record title entry
Packit Service a2ae7a
*)
Packit Service a2ae7a
let record (title:lens) (entry:lens)
Packit Service a2ae7a
                       = record_noempty title ( entry | empty )
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(************************************************************************
Packit Service a2ae7a
 * Group:                      GENERIC LENSES
Packit Service a2ae7a
 *************************************************************************)
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
Packit Service a2ae7a
Group: Lens definition
Packit Service a2ae7a
Packit Service a2ae7a
View: lns_noempty
Packit Service a2ae7a
  Generic INI File lens with no empty lines
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    record:lens  - record lens to use. See <record_noempty>.
Packit Service a2ae7a
    comment:lens - comment lens to use. See <comment>.
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
    > let lns     = IniFile.lns_noempty record comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let lns_noempty (record:lens) (comment:lens)
Packit Service a2ae7a
                       = comment* . record*
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: lns
Packit Service a2ae7a
  Generic INI File lens
Packit Service a2ae7a
Packit Service a2ae7a
  Parameters:
Packit Service a2ae7a
    record:lens  - record lens to use. See <record>.
Packit Service a2ae7a
    comment:lens - comment lens to use. See <comment>.
Packit Service a2ae7a
Packit Service a2ae7a
  Sample Usage:
Packit Service a2ae7a
    > let lns     = IniFile.lns record comment
Packit Service a2ae7a
*)
Packit Service a2ae7a
let lns (record:lens) (comment:lens)
Packit Service a2ae7a
                       = lns_noempty record (comment|empty)
Packit Service a2ae7a
Packit Service a2ae7a
Packit Service a2ae7a
(************************************************************************
Packit Service a2ae7a
 * Group:                   READY-TO-USE LENSES
Packit Service a2ae7a
 *************************************************************************)
Packit Service a2ae7a
Packit Service a2ae7a
let record_anon (entry:lens) = [ label "section" . value ".anon" . ( entry | empty )+ ]
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: lns_loose
Packit Service a2ae7a
  A loose, ready-to-use lens, featuring:
Packit Service a2ae7a
    - sections as values (to allow '/' in names)
Packit Service a2ae7a
    - support empty lines and comments
Packit Service a2ae7a
    - support for [#;] as comment, defaulting to ";"
Packit Service a2ae7a
    - .anon sections
Packit Service a2ae7a
    - don't allow multiline values
Packit Service a2ae7a
    - allow indented titles
Packit Service a2ae7a
    - allow indented entries
Packit Service a2ae7a
*)
Packit Service a2ae7a
let lns_loose = 
Packit Service a2ae7a
     let l_comment = comment comment_re comment_default
Packit Service a2ae7a
  in let l_sep = sep sep_re sep_default
Packit Service a2ae7a
  in let l_entry = indented_entry entry_re l_sep l_comment
Packit Service a2ae7a
  in let l_title = indented_title_label "section" (record_label_re - ".anon")
Packit Service a2ae7a
  in let l_record = record l_title l_entry
Packit Service a2ae7a
  in (record_anon l_entry)? . l_record*
Packit Service a2ae7a
Packit Service a2ae7a
(*
Packit Service a2ae7a
View: lns_loose_multiline
Packit Service a2ae7a
  A loose, ready-to-use lens, featuring:
Packit Service a2ae7a
    - sections as values (to allow '/' in names)
Packit Service a2ae7a
    - support empty lines and comments
Packit Service a2ae7a
    - support for [#;] as comment, defaulting to ";"
Packit Service a2ae7a
    - .anon sections
Packit Service a2ae7a
    - allow multiline values
Packit Service a2ae7a
*)
Packit Service a2ae7a
let lns_loose_multiline = 
Packit Service a2ae7a
     let l_comment = comment comment_re comment_default
Packit Service a2ae7a
  in let l_sep = sep sep_re sep_default
Packit Service a2ae7a
  in let l_entry = entry_multiline entry_re l_sep l_comment
Packit Service a2ae7a
  in let l_title = title_label "section" (record_label_re - ".anon")
Packit Service a2ae7a
  in let l_record = record l_title l_entry
Packit Service a2ae7a
  in (record_anon l_entry)? . l_record*
Packit Service a2ae7a