Skip to content

Named blocks standardization

raphink edited this page Jan 4, 2013 · 1 revision

Table of Contents

Rationale

Several lenses (logrotate.aug, xinetd.aug, keepalived.aug, aptconf.aug, dhclient.aug, shellvars.aug) use named blocks with the following syntax:

   block_name {
      entry+
   }

but each lens implements it differently. It would be good to add a (or several types of) block entry to build.aug to make it easier to build such blocks in a standard way.

Existing implementations

The following are existing implementations of such blocks. They are not working examples, but they show the general pattern of each implementation.

xinetd.aug

Code

  let service =
     let sto_re = /[^# \t\n\/]+/ in
     [ key "service" . Sep.space . store sto_re . body service_attr ]

Notes

  • This implementation forces a newline after the opening bracket;

logrotate.aug

Code

   let rule =
     [ label "rule" . Util.indent .
         [ label "file" . store filename ] .
         [ del /[ \t\n]+/ " " . label "file" . store filename ]* .
         del /[ \t\n]*/ " " . body ]

Notes

  • This lens was inspired by xinetd.aug and uses a similar "body" construct, only more complex;
  • This example shows that a standard block pattern should take a lens as the block name rather than a regexp, since the construction in logrotate.aug accepts several files (we could use Build.opt_list here) before the body;
  • This implementation forces a newline after the opening bracket, just like xinetd.aug;

keepalived.aug

Code

   let rbracket = Util.del_str "}"
   
   let lens_block (title:lens) (sto:lens) = [ indent . title . opt_eol . lbracket
                                         . (sto | empty | comment)+
                                         . indent . rbracket . eol ]

Notes

  • This lens doesn't force a newline after the opening bracket;
  • As a result, new blocks have no newlines;
  • This lens allows for eol before the opening bracket. This might not be the case of all formats (but it doesn't hurt in general to support it);
  • This lens doesn't allow the closing bracket to be on the same line as an entry (since entries have eol);

aptconf.aug

Code

  let entry = indent . entry_noeol . eol

Notes

  • This is a recursive lens, allowing two different formats. It might not be easy to fit it into a standard block pattern.

Comparison of existing implementations

eol before lbracket eol after lbracket eol before rbracket block name
xinetd mandatory mandatory mandatory
logrotate optional mandatory mandatory
keepalived optional optional mandatory
aptconf optional optional optional

Problems

The main issue has to do with newlines:

  • We want newlines to be allowed, optionally, in most places;
  • We would like newlines to be placed by default in most places;
  • We don't want newlines to conflict with empty lines;
  • When a comment is put right after the lbracket, where should it be mapped?