Bump to 1.14.1
[platform/upstream/augeas.git] / examples / cont.aug
1 module Cont =
2
3   (* An experiment in handling empty lines and comments in httpd.conf and
4    * similar. What makes this challenging is that httpd.conf allows
5    * continuation lines; the markers for continuation lines (backslash +
6    * newline) needs to be treated like any other whitespace.  *)
7
8   (* The continuation sequence that indicates that we should consider the
9    * next line part of the current line *)
10   let cont = /\\\\\r?\n/
11
12   (* Whitespace within a line: space, tab, and the continuation sequence *)
13   let ws = /[ \t]/ | cont
14
15   (* Any possible character - '.' does not match \n *)
16   let any = /(.|\n)/
17
18   (* Newline sequence - both for Unix and DOS newlines *)
19   let nl = /\r?\n/
20
21   (* Whitespace at the end of a line *)
22   let eol = del (ws* . nl) "\n"
23
24   (* A complete line that is either just whitespace or a comment that only
25    * contains whitespace *)
26   let empty = [ del (ws* . /#?/ . ws* . nl) "\n" ]
27
28   (* A comment that is not just whitespace. We define it in terms of the
29    * things that are not allowed as part of such a comment:
30    *   1) Starts with whitespace or newline
31    *   2) Ends with whitespace, a backslash or \r
32    *   3) Unescaped newlines
33    *)
34   let comment =
35     let comment_start = del (ws* . "#" . ws* ) "# " in
36     let unesc_eol = /[^\]/ . nl in
37     (* As a complement, the above criteria can be written as
38        let line = any* -  ((ws|nl) . any*
39                           | any* . (ws|/[\r\\]/)
40                           | any* . unesc_eol . any* )? in
41      * Printing this out with 'print_regexp line' and simplifying it while
42      * checking for equality with the ruby-fa bindings, we can write this
43      * as follows: *)
44     let w = /[^\t\n\r \\]/ in
45     let r = /[\r\\]/ in
46     let s = /[\t\r ]/ in
47     let b = "\\\\" in
48     let t = /[\t\n\r ]/ in
49     let line = ((r . s* . w|w|r) . (s|w)* . (b . (t? . (s|w)* ))*|(r.s* )?).w.(s*.w)* in
50     [ label "#comment" . comment_start . store line . eol ]
51
52   let lns = (comment|empty)*
53
54   test [eol] get " \n" = { }
55   test [eol] get " \t\n" = { }
56   test [eol] get "\\\n\n" = { }
57
58
59   test lns get "#  \\\r\n \t \\\n\n" = { }
60   test lns get "#  x\n" = { "#comment" = "x" }
61   test lns get "#  x\\\n\n" = { "#comment" = "x" }
62   test lns get "#  \\\r\n \tx \\\n\n" = { "#comment" = "x" }
63   test lns get "  \t\\\n# x\n" = { "#comment" = "x" }
64   test lns get "# word\\\n word  \n" = { "#comment" = "word\\\n word" }
65   (* Not valid as it is an incomplete 'line' *)
66   test lns get "# x\\\n" = *