1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
open Conex_utils open Conex_resource let np = ("", 0, 0) let rec encode_s = function | Wire.Map s -> if s = M.empty then OpamParserTypes.Ident (np, "emptymap") else let data = M.fold (fun k v acc -> OpamParserTypes.(List (np, [ String (np, k) ; encode_s v ])) :: acc) s [] in OpamParserTypes.List (np, data) | Wire.List l -> OpamParserTypes.List (np, List.map encode_s l) | Wire.String s -> OpamParserTypes.String (np, s) | Wire.Int i -> OpamParserTypes.Ident (np, "0x" ^ Uint.to_string i) let encode t = let file_contents = M.fold (fun k v acc -> OpamParserTypes.Variable (np, k, encode_s v) :: acc) t [] in let file = { OpamParserTypes.file_contents ; file_name = "" } in OpamPrinter.format_opamfile Format.str_formatter file ; Format.flush_str_formatter () (* OpamPrinter.Normalise.opamfile file *) let rec decode_s = function | OpamParserTypes.Ident (_, data) -> if String.is_prefix ~prefix:"0x" data then match Uint.of_string (String.slice ~start:2 data) with | None -> Error "cannot parse unsigned integer" | Some x -> Ok (Wire.Int x) else if data = "emptymap" then Ok (Wire.Map M.empty) else Error "unexpected ident" | OpamParserTypes.String (_, s) -> Ok (Wire.String (String.trim s)) | OpamParserTypes.List (_, []) -> Ok (Wire.List []) | OpamParserTypes.List (_, l) -> let is_pair = function OpamParserTypes.List (_, [OpamParserTypes.String _ ; _]) -> true | _ -> false in if List.for_all is_pair l then begin List.fold_left (fun m xs -> m >>= fun m -> match xs with OpamParserTypes.List (_, [ OpamParserTypes.String (_, k) ; v ]) -> (decode_s v >>= fun v -> Ok (M.add (String.trim k) v m)) | _ -> Error "can not happen") (Ok M.empty) l >>= fun map -> Ok (Wire.Map map) end else List.fold_left (fun xs s -> xs >>= fun xs -> decode_s s >>= fun x -> Ok (x :: xs)) (Ok []) l >>= fun xs -> Ok (Wire.List (List.rev xs)) | _ -> Error "unexpected thing while decoding" let decode data = (try Ok (OpamParser.string data "noname") with Parsing.Parse_error -> Error "parse error") >>= fun file -> let items = file.OpamParserTypes.file_contents in List.fold_left (fun acc v -> acc >>= fun acc -> match v with | OpamParserTypes.Section _ -> Error "unexpected section" | OpamParserTypes.Variable (_, k, v) -> decode_s v >>= fun v -> Ok (M.add k v acc)) (Ok M.empty) items