summaryrefslogtreecommitdiffstats
path: root/virt-df/virt_df_lvm2_lexer.mll
diff options
context:
space:
mode:
Diffstat (limited to 'virt-df/virt_df_lvm2_lexer.mll')
-rw-r--r--virt-df/virt_df_lvm2_lexer.mll165
1 files changed, 165 insertions, 0 deletions
diff --git a/virt-df/virt_df_lvm2_lexer.mll b/virt-df/virt_df_lvm2_lexer.mll
new file mode 100644
index 0000000..2dbe7e5
--- /dev/null
+++ b/virt-df/virt_df_lvm2_lexer.mll
@@ -0,0 +1,165 @@
+(* 'df' command for virtual domains.
+ (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
+ http://libvirt.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *)
+
+(* Scanner for LVM2 metadata.
+ * ocamllex tutorial:
+ * http://plus.kaist.ac.kr/~shoh/ocaml/ocamllex-ocamlyacc/ocamllex-tutorial/
+ *)
+
+{
+ open Printf
+ open Lexing
+
+ open Virt_df
+ open Virt_df_lvm2_parser
+
+ (* Temporary buffer used for parsing strings, etc. *)
+ let tmp = Buffer.create 80
+
+ exception Error of string
+}
+
+let digit = ['0'-'9']
+let alpha = ['a'-'z' 'A'-'Z']
+let alphau = ['a'-'z' 'A'-'Z' '_']
+let alnum = ['a'-'z' 'A'-'Z' '0'-'9']
+let alnumu = ['a'-'z' 'A'-'Z' '0'-'9' '_']
+let ident = alphau alnumu*
+
+let whitespace = [' ' '\t' '\r' '\n']+
+
+let escaped_char = '\\' _
+
+rule token = parse
+ (* ignore whitespace and comments *)
+ | whitespace
+ | '#' [^ '\n']*
+ { token lexbuf }
+
+ (* scan single character tokens *)
+ | '{' { LBRACE }
+ | '}' { RBRACE }
+ | '[' { LSQUARE }
+ | ']' { RSQUARE }
+ | '=' { EQ }
+ | ',' { COMMA }
+
+ (* strings - see LVM2/lib/config/config.c *)
+ | '"'
+ {
+ Buffer.reset tmp;
+ STRING (dq_string lexbuf)
+ }
+ | '\''
+ {
+ Buffer.reset tmp;
+ STRING (dq_string lexbuf)
+ }
+
+ (* floats *)
+ | ('-'? digit+ '.' digit*) as f
+ {
+ let f = float_of_string f in
+ FLOAT f
+ }
+
+ (* integers *)
+ | ('-'? digit+) as i
+ {
+ let i = Int64.of_string i in
+ INT i
+ }
+
+ (* identifiers *)
+ | ident as id
+ { IDENT id }
+
+ (* end of file *)
+ | eof
+ { EOF }
+
+ | _ as c
+ { raise (Error (sprintf "%c: invalid character in input" c)) }
+
+and dq_string = parse
+ | '"'
+ { Buffer.contents tmp }
+ | escaped_char as str
+ { Buffer.add_char tmp str.[1]; dq_string lexbuf }
+ | eof
+ { raise (Error "unterminated string in metadata") }
+ | _ as c
+ { Buffer.add_char tmp c; dq_string lexbuf }
+
+and q_string = parse
+ | '\''
+ { Buffer.contents tmp }
+ | escaped_char as str
+ { Buffer.add_char tmp str.[1]; q_string lexbuf }
+ | eof
+ { raise (Error "unterminated string in metadata") }
+ | _ as c
+ { Buffer.add_char tmp c; q_string lexbuf }
+
+{
+ (* Demonstration of how to wrap the token function
+ with extra debugging statements:
+ let token lexbuf =
+ try
+ let r = token lexbuf in
+ if debug then
+ eprintf "Lexer: token returned is %s\n"
+ (match r with
+ | LBRACE -> "LBRACE"
+ | RBRACE -> "RBRACE"
+ | LSQUARE -> "LSQUARE"
+ | RSQUARE -> "RSQUARE"
+ | EQ -> "EQ"
+ | COMMA -> "COMMA"
+ | STRING s -> sprintf "STRING(%S)" s
+ | INT i -> sprintf "INT(%Ld)" i
+ | FLOAT f -> sprintf "FLOAT(%g)" f
+ | IDENT s -> sprintf "IDENT(%s)" s
+ | EOF -> "EOF");
+ r
+ with
+ exn ->
+ prerr_endline (Printexc.to_string exn);
+ raise exn
+ *)
+
+ (* Lex and parse input.
+ *
+ * Return the parsed metadata structure if everything went to plan.
+ * Raises [Error msg] if there was some parsing problem.
+ *)
+ let rec parse_lvm2_metadata_from_string str =
+ let lexbuf = Lexing.from_string str in
+ parse_lvm2_metadata lexbuf
+ and parse_lvm2_metadata_from_channel chan =
+ let lexbuf = Lexing.from_channel chan in
+ parse_lvm2_metadata lexbuf
+ and parse_lvm2_metadata lexbuf =
+ try
+ input token lexbuf
+ with
+ | Error _ as exn -> raise exn
+ | Parsing.Parse_error -> raise (Error "Parse error")
+ | exn -> raise (Error ("Exception: " ^ Printexc.to_string exn))
+}