Clarify licensing for Debian.
[virt-df.git] / lib / diskimage_lvm2_lexer.mll
1 (* 'df' command for virtual domains.
2    (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
3    http://libvirt.org/
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2 of the License, or (at your option) any later version,
9    with the OCaml linking exception described in ../COPYING.LIB.
10
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19  *)
20
21 (* Scanner for LVM2 metadata.
22  * ocamllex tutorial:
23  * http://plus.kaist.ac.kr/~shoh/ocaml/ocamllex-ocamlyacc/ocamllex-tutorial/
24  *)
25
26 {
27   open Printf
28   open Lexing
29
30   open Diskimage_impl
31   open Diskimage_lvm2_parser
32
33   (* Temporary buffer used for parsing strings, etc. *)
34   let tmp = Buffer.create 80
35
36   exception Error of string
37 }
38
39 let digit = ['0'-'9']
40 let alpha = ['a'-'z' 'A'-'Z']
41 let alphau = ['a'-'z' 'A'-'Z' '_']
42 let alnum = ['a'-'z' 'A'-'Z' '0'-'9']
43 let alnumu = ['a'-'z' 'A'-'Z' '0'-'9' '_']
44 let ident = alphau alnumu*
45
46 let whitespace = [' ' '\t' '\r' '\n']+
47
48 let escaped_char = '\\' _
49
50 rule token = parse
51   (* ignore whitespace and comments *)
52   | whitespace
53   | '#' [^ '\n']*
54       { token lexbuf }
55
56   (* scan single character tokens *)
57   | '{'  { LBRACE }
58   | '}'  { RBRACE }
59   | '['  { LSQUARE }
60   | ']'  { RSQUARE }
61   | '='  { EQ }
62   | ','  { COMMA }
63
64   (* strings - see LVM2/lib/config/config.c *)
65   | '"'
66       {
67         Buffer.reset tmp;
68         STRING (dq_string lexbuf)
69       }
70   | '\''
71       {
72         Buffer.reset tmp;
73         STRING (dq_string lexbuf)
74       }
75
76   (* floats *)
77   | ('-'? digit+ '.' digit*) as f
78       {
79         let f = float_of_string f in
80         FLOAT f
81       }
82
83   (* integers *)
84   | ('-'? digit+) as i
85       {
86         let i = Int63.of_string i in
87         INT i
88       }
89
90   (* identifiers *)
91   | ident as id
92       { IDENT id }
93
94   (* end of file *)
95   | eof
96       { EOF }
97
98   | _ as c
99       { raise (Error (sprintf "%c: invalid character in input" c)) }
100
101 and dq_string = parse
102   | '"'
103       { Buffer.contents tmp }
104   | escaped_char as str
105       { Buffer.add_char tmp str.[1]; dq_string lexbuf }
106   | eof
107       { raise (Error "unterminated string in metadata") }
108   | _ as c
109       { Buffer.add_char tmp c; dq_string lexbuf }
110
111 and q_string = parse
112   | '\''
113       { Buffer.contents tmp }
114   | escaped_char as str
115       { Buffer.add_char tmp str.[1]; q_string lexbuf }
116   | eof
117       { raise (Error "unterminated string in metadata") }
118   | _ as c
119       { Buffer.add_char tmp c; q_string lexbuf }
120
121 {
122   (* Demonstration of how to wrap the token function
123      with extra debugging statements:
124   let token lexbuf =
125     try
126       let r = token lexbuf in
127       if debug then
128         eprintf "Lexer: token returned is %s\n"
129           (match r with
130            | LBRACE -> "LBRACE"
131            | RBRACE -> "RBRACE"
132            | LSQUARE -> "LSQUARE"
133            | RSQUARE -> "RSQUARE"
134            | EQ -> "EQ"
135            | COMMA -> "COMMA"
136            | STRING s -> sprintf "STRING(%S)" s
137            | INT i -> sprintf "INT(%Ld)" i
138            | FLOAT f -> sprintf "FLOAT(%g)" f
139            | IDENT s -> sprintf "IDENT(%s)" s
140            | EOF -> "EOF");
141       r
142     with
143       exn ->
144         prerr_endline (Printexc.to_string exn);
145         raise exn
146   *)
147
148   (* Lex and parse input.
149    *
150    * Return the parsed metadata structure if everything went to plan.
151    * Raises [Error msg] if there was some parsing problem.
152    *)
153   let rec parse_lvm2_metadata_from_string str =
154     let lexbuf = Lexing.from_string str in
155     parse_lvm2_metadata lexbuf
156   and parse_lvm2_metadata_from_channel chan =
157     let lexbuf = Lexing.from_channel chan in
158     parse_lvm2_metadata lexbuf
159   and parse_lvm2_metadata lexbuf =
160     try
161       input token lexbuf
162     with
163     | Error _ as exn -> raise exn
164     | Parsing.Parse_error -> raise (Error "Parse error")
165     | exn -> raise (Error ("Exception: " ^ Printexc.to_string exn))
166 }