1 (* 'df' command for virtual domains.
2 (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 (* Scanner for LVM2 metadata.
22 * http://plus.kaist.ac.kr/~shoh/ocaml/ocamllex-ocamlyacc/ocamllex-tutorial/
29 open Diskimage_lvm2_parser
32 (* Temporary buffer used for parsing strings, etc. *)
33 let tmp = Buffer.create 80
35 exception Error of string
39 let alpha = ['a'-'z' 'A'-'Z']
40 let alphau = ['a'-'z' 'A'-'Z' '_']
41 let alnum = ['a'-'z' 'A'-'Z' '0'-'9']
42 let alnumu = ['a'-'z' 'A'-'Z' '0'-'9' '_']
43 let ident = alphau alnumu*
45 let whitespace = [' ' '\t' '\r' '\n']+
47 let escaped_char = '\\' _
50 (* ignore whitespace and comments *)
55 (* scan single character tokens *)
63 (* strings - see LVM2/lib/config/config.c *)
67 STRING (dq_string lexbuf)
72 STRING (dq_string lexbuf)
76 | ('-'? digit+ '.' digit*) as f
78 let f = float_of_string f in
85 let i = Int63.of_string i in
98 { raise (Error (sprintf "%c: invalid character in input" c)) }
100 and dq_string = parse
102 { Buffer.contents tmp }
103 | escaped_char as str
104 { Buffer.add_char tmp str.[1]; dq_string lexbuf }
106 { raise (Error "unterminated string in metadata") }
108 { Buffer.add_char tmp c; dq_string lexbuf }
112 { Buffer.contents tmp }
113 | escaped_char as str
114 { Buffer.add_char tmp str.[1]; q_string lexbuf }
116 { raise (Error "unterminated string in metadata") }
118 { Buffer.add_char tmp c; q_string lexbuf }
121 (* Demonstration of how to wrap the token function
122 with extra debugging statements:
125 let r = token lexbuf in
127 eprintf "Lexer: token returned is %s\n"
131 | LSQUARE -> "LSQUARE"
132 | RSQUARE -> "RSQUARE"
135 | STRING s -> sprintf "STRING(%S)" s
136 | INT i -> sprintf "INT(%Ld)" i
137 | FLOAT f -> sprintf "FLOAT(%g)" f
138 | IDENT s -> sprintf "IDENT(%s)" s
143 prerr_endline (Printexc.to_string exn);
147 (* Lex and parse input.
149 * Return the parsed metadata structure if everything went to plan.
150 * Raises [Error msg] if there was some parsing problem.
152 let rec parse_lvm2_metadata_from_string str =
153 let lexbuf = Lexing.from_string str in
154 parse_lvm2_metadata lexbuf
155 and parse_lvm2_metadata_from_channel chan =
156 let lexbuf = Lexing.from_channel chan in
157 parse_lvm2_metadata lexbuf
158 and parse_lvm2_metadata lexbuf =
162 | Error _ as exn -> raise exn
163 | Parsing.Parse_error -> raise (Error "Parse error")
164 | exn -> raise (Error ("Exception: " ^ Printexc.to_string exn))