~ubuntu-transition-trackers/ubuntu-transition-tracker/ben

« back to all changes in this revision

Viewing changes to lib/lexer.mll

  • Committer: Stephane Glondu
  • Date: 2009-07-22 15:10:26 UTC
  • Revision ID: git-v1:b4790e0fb07eb5e5ed2378f246cb2a864ccba47d
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(**************************************************************************)
 
2
(*  Copyright © 2009 Stéphane Glondu <steph@glondu.net>                   *)
 
3
(*                                                                        *)
 
4
(*  This program is free software: you can redistribute it and/or modify  *)
 
5
(*  it under the terms of the GNU Affero General Public License as        *)
 
6
(*  published by the Free Software Foundation, either version 3 of the    *)
 
7
(*  License, or (at your option) any later version, with the additional   *)
 
8
(*  exemption that compiling, linking, and/or using OpenSSL is allowed.   *)
 
9
(*                                                                        *)
 
10
(*  This program is distributed in the hope that it will be useful, but   *)
 
11
(*  WITHOUT ANY WARRANTY; without even the implied warranty of            *)
 
12
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *)
 
13
(*  Affero General Public License for more details.                       *)
 
14
(*                                                                        *)
 
15
(*  You should have received a copy of the GNU Affero General Public      *)
 
16
(*  License along with this program.  If not, see                         *)
 
17
(*  <http://www.gnu.org/licenses/>.                                       *)
 
18
(**************************************************************************)
 
19
 
 
20
{
 
21
  open Utils
 
22
  open Parser
 
23
}
 
24
 
 
25
let space = [' ' '\t']
 
26
let field_name = ['a'-'z' 'A'-'Z' '-' '0'-'9']+
 
27
let field_value = ([^ '\n'] | '\n' space)*
 
28
 
 
29
rule stanza to_keep empty accu = parse
 
30
  | (field_name as name) space* ":" space* (field_value as value) '\n'?
 
31
      {
 
32
        let name = String.lowercase name in
 
33
        if Fields.mem name to_keep then
 
34
          stanza to_keep false ((name, value)::accu) lexbuf
 
35
        else
 
36
          stanza to_keep false accu lexbuf
 
37
      }
 
38
  | '\n'+ | eof
 
39
        {
 
40
          if empty then raise End_of_file else List.rev accu
 
41
        }
 
42
 
 
43
and token = parse
 
44
  | '?' (field_name as name) { FIELD name }
 
45
  | "source" { SOURCE }
 
46
  | "~" { MATCH }
 
47
  | "|" { OR }
 
48
  | "&" { AND }
 
49
  | "!" { NOT }
 
50
  | "(" { LPAREN }
 
51
  | ")" { RPAREN }
 
52
  | '@' (_ as c) | ('/' as c) { REGEXP (regexp c (Buffer.create 32) lexbuf) }
 
53
  | space | "\n" { token lexbuf }
 
54
  | eof { EOF }
 
55
 
 
56
and regexp separator buf = parse
 
57
  | _ as c
 
58
      {
 
59
        if c = separator then
 
60
          let res = Buffer.contents buf in
 
61
          let reg = Pcre.regexp res in
 
62
          (res, reg)
 
63
        else begin
 
64
          Buffer.add_char buf c;
 
65
          regexp separator buf lexbuf
 
66
        end
 
67
      }
 
68
 
 
69
{
 
70
  let stanza_fold headers_to_keep f accu lexbuf =
 
71
    let rec loop accu =
 
72
      let stanza =
 
73
        try Some (stanza headers_to_keep true [] lexbuf)
 
74
        with End_of_file -> None
 
75
      in
 
76
      match stanza with
 
77
        | None -> accu
 
78
        | Some x -> loop (f accu x)
 
79
    in loop accu
 
80
}