let parse_cigar text =
match text with
| "*" -> Ok []
| "" ->
error "invalid cigar string" text sexp_of_string
| _ ->
let ch = Scanf.Scanning.from_string text in
let rec loop accum =
if Scanf.Scanning.end_of_input ch then Ok accum
else
try
let n = Scanf.bscanf ch "%d" ident in
let c = Scanf.bscanf ch "%c" ident in
let x =
match c with
| 'M' -> cigar_op_alignment_match n
| 'I' -> cigar_op_insertion n
| 'D' -> cigar_op_deletion n
| 'N' -> cigar_op_skipped n
| 'S' -> cigar_op_soft_clipping n
| 'H' -> cigar_op_hard_clipping n
| 'P' -> cigar_op_padding n
| '=' -> cigar_op_seq_match n
| 'X' -> cigar_op_seq_mismatch n
| other -> Or_error.error_string "invalid cigar operation type"
in
Or_error.tag x "Sam.parse_cigar: invalid cigar string" >>= fun x ->
loop (x::accum)
with
_ ->
error "invalid cigar string" text sexp_of_string
in
loop [] >>| List.rev