ocaml-lib / dcg / msg.ml

 * Msg: parsing message module.
 * Copyright (C) 2006
 * Dmitri Boulytchev, St.Petersburg State University
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License version 2, as published by the Free Software Foundation.
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * See the GNU Library General Public License version 2 for more details
 * (enclosed in the file COPYING).

open Printf

module Coord =

    type t = int * int

    let toString (x, y) = sprintf "(%d:%d)" x y 

module Locator =

    type t = No | Point of Coord.t | Interval of Coord.t * Coord.t | Set of t list
    and  l = t

    let rec toString = function
        | No              -> ""
        | Point x         -> Coord.toString x
        | Interval (x, y) -> sprintf "%s-%s" (Coord.toString x) (Coord.toString y)
        | Set      x      -> String.concat ", " (List.map toString x)

    let rec start = function
      | No -> (1,1)
      | Point coord -> coord
      | Interval (c1,c2) -> c1
      | Set [] -> (1,1)
      | Set (x::_) -> start x


type t = {phrase: string; args: string array; loc: Locator.t} 

let make      phrase args loc = {phrase=phrase; args=args; loc=loc}
let phrase    phrase          = make phrase [||] Locator.No
let orphan    phrase args     = make phrase args Locator.No

let string t = 
  let parmExpr = Str.regexp "%\\([0-9]+\\)" in
    (fun s -> 
        t.args.(int_of_string (Str.replace_matched "\\1" s))
      | Failure "int_of_string" -> 
          raise (Failure 
                   (sprintf "invalid integer parameter specification in message phrase \"%s\"" s)
      | Invalid_argument "index out of bounds" ->
          raise (Failure 
                   (sprintf "index out of bound while accessing message parameter in \"%s\"" s)
let toString t =
  let message = string t in
    match Locator.toString t.loc with
    | ""  -> message
    | loc -> message ^ " at " ^ loc
let augment msg loc = match msg.loc with Locator.No -> {msg with loc = loc} | _ -> msg
let augmentList msgs loc = List.map (fun x -> augment x loc) msgs
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.