Commits

Peter Szilagyi committed 8e3803e

ocp-indent update from OCamlPro

  • Participants
  • Parent commits 6de9577

Comments (0)

Files changed (35)

File ocaml/contrib/ocp-indent/.gitignore

 config.status
 ocp-indent
 src/globals.ml
+*~
+version.ocp
+autom4te.cache
+aclocal.m4

File ocaml/contrib/ocp-indent/Makefile

 $(native) native asm: ocp-build.root ALWAYS
 	ocp-build
 
+
+sanitize:
+	ocp-build -sanitize
+
 .PHONY: clean
 clean:
 	ocp-build -clean
 
 .PHONY: test
 test: ocp-indent
-	tests/test.sh
+	./tests/test.sh
 
 configure: configure.ac
 	aclocal -I m4
 	autoconf
 
 ocp-build.root:
+	@if (ocp-build -version 2>/dev/null |\
+	     awk -F'.' '{ exit $$1 > 1 || ($$1 = 1 && $$2 >= 99) }'); then \
+	  echo "Error: you need ocp-build >= 1.99." >&2;\
+	  exit 1;\
+	fi
 	ocp-build -init -scan

File ocaml/contrib/ocp-indent/configure

 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ocp-indent 0.6.0.
+# Generated by GNU Autoconf 2.69 for ocp-indent 0.6.1.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
 # Identity of this package.
 PACKAGE_NAME='ocp-indent'
 PACKAGE_TARNAME='ocp-indent'
-PACKAGE_VERSION='0.6.0'
-PACKAGE_STRING='ocp-indent 0.6.0'
+PACKAGE_VERSION='0.6.1'
+PACKAGE_STRING='ocp-indent 0.6.1'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures ocp-indent 0.6.0 to adapt to many kinds of systems.
+\`configure' configures ocp-indent 0.6.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of ocp-indent 0.6.0:";;
+     short | recursive ) echo "Configuration of ocp-indent 0.6.1:";;
    esac
   cat <<\_ACEOF
 
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-ocp-indent configure 0.6.0
+ocp-indent configure 0.6.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by ocp-indent $as_me 0.6.0, which was
+It was created by ocp-indent $as_me 0.6.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
    as_fn_error $? "You must install the OCaml compiler" "$LINENO" 5
 fi
 
-ac_config_files="$ac_config_files Makefile.config src/globals.ml"
+ac_config_files="$ac_config_files Makefile.config version.ocp"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by ocp-indent $as_me 0.6.0, which was
+This file was extended by ocp-indent $as_me 0.6.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-ocp-indent config.status 0.6.0
+ocp-indent config.status 0.6.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
 do
   case $ac_config_target in
     "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
-    "src/globals.ml") CONFIG_FILES="$CONFIG_FILES src/globals.ml" ;;
+    "version.ocp") CONFIG_FILES="$CONFIG_FILES version.ocp" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac

File ocaml/contrib/ocp-indent/configure.ac

-AC_INIT(ocp-indent,0.6.0)
+AC_INIT(ocp-indent,0.6.1)
 AC_COPYRIGHT(Copyright 2012 OcamlPro SAS)
 
 AC_CONFIG_MACRO_DIR([m4])
 
 AC_CONFIG_FILES(
   Makefile.config
-  src/globals.ml
+  version.ocp
 )
 AC_OUTPUT
 

File ocaml/contrib/ocp-indent/src/block.ml

-(**************************************************************************)
-(*                                                                        *)
-(*  Copyright 2011 Jun Furuse                                             *)
-(*  Copyright 2012,2013 OCamlPro                                          *)
-(*                                                                        *)
-(*  All rights reserved.  This file is distributed under the terms of     *)
-(*  the GNU Public License version 3.0.                                   *)
-(*                                                                        *)
-(*  TypeRex 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.                          *)
-(*                                                                        *)
-(**************************************************************************)
-
-open Pos
-open Nstream
-open Approx_lexer
-open Util
-
-module Node = struct
-
-  (* Node kind *)
-  type kind =
-    | KParen
-    | KBrace
-    | KBracket
-    | KBracketBar
-    | KLet
-    | KAnd of kind
-    | KLetIn
-    | KIn
-
-    | KExpr of int
-    (* actually handles also patterns / types / ... *)
-    (* Parameter:Priority - next expression is deindented if the op has
-       lower priority *)
-
-    | KBody of kind
-    | KArrow of kind
-    | KColon
-    | KType
-    | KException
-    | KOpen
-    | KInclude
-    | KVal
-    | KBar of kind
-    | KNone
-    | KStruct
-    | KSig
-    | KModule
-    | KBegin
-    | KObject
-    | KMatch
-    | KTry
-    | KWith of kind
-    | KLoop
-    | KIf
-    | KThen
-    | KElse
-    | KDo
-    | KFun
-    | KWhen
-    | KExternal
-
-  (* Priority of open expression constructs (see below for operators) *)
-  let prio = function
-    | KIn | KArrow _ -> 0
-    | KThen | KElse -> 10
-    | KExpr i -> i
-    | _ -> -10
-
-  let prio_max = 200
-  let prio_apply = 140
-  let expr_atom = KExpr prio_max
-  let expr_apply = KExpr 140
-  (* Special operators that should break arrow indentation have this prio
-     (eg monad operators, >>=) *)
-  let prio_flatop = 59
-
-  let rec follow = function
-    | KAnd k
-    | KBody k
-    | KBar k
-    | KWith k -> follow k
-    | k -> k
-
-  let rec string_of_kind = function
-    | KExpr i -> Printf.sprintf "KExpr(%d)" i
-    | KParen -> "KParen"
-    | KBrace -> "KBrace"
-    | KBracket -> "KBracket"
-    | KBracketBar -> "KBracketBar"
-    (* | KField -> "KField" *)
-    | KLet -> "KLet"
-    | KIn -> "KIn"
-    | KAnd k -> aux "KAnd" k
-    | KLetIn -> "KLetIn"
-    | KBody k -> aux "KBody" k
-    | KArrow k -> aux "KArrow" k
-    | KColon -> "KColon"
-    | KVal -> "KVal"
-    | KBar k -> aux "KBar" k
-    | KOpen -> "KOpen"
-    | KInclude -> "KInclude"
-    | KNone -> "KNone"
-    | KType -> "Ktype"
-    | KException -> "KException"
-    | KStruct -> "KStruct"
-    | KSig -> "KSig"
-    | KModule -> "KModule"
-    | KBegin -> "KBegin"
-    | KObject -> "KObject"
-    | KMatch -> "KMatch"
-    | KTry -> "KTry"
-    | KWith k -> aux "KWith" k
-    | KLoop -> "KLoop"
-    | KIf -> "KIf"
-    | KThen -> "Kthen"
-    | KElse -> "KElse"
-    | KDo -> "KDo"
-    | KFun -> "KFun"
-    | KWhen -> "KWhen"
-    | KExternal -> "KExternal"
-
-  and aux str k =
-    Printf.sprintf "%s(%s)" str (string_of_kind k)
-
-  (* A node:
-     - has a kind
-     - has the current line offset [l]
-     - has the current token offset [t]
-     - has a inner padding [pad]
-     - has a line count [count]
-
-         XXX XXX XXX [
-                            XXX
-                     ]
-
-         XXX XXX XXX [
-               XXX
-         ]
-
-<---l--->
-<----------x-------->
-                     <-pad->
-        <-pad->
-*)
-
-  type t = {
-    k:   kind;
-    l:   int;
-    t:   int;
-    pad : int;
-    line: int;
-  }
-
-  let to_string i t =
-    Printf.sprintf "%s%s %d|%d-%d(%d)"
-      (String.make i ' ') (string_of_kind t.k) t.line t.l t.t t.pad
-
-  let create k l t pad line =
-    { k; l; t; pad; line }
-
-  let shift node n =
-    let n = max n (- node.l) in
-    { node with l = node.l + n; t = node.t + n }
-
-end
-
-module Path = struct
-
-  open Node
-  type t = Node.t list
-
-  let to_string t =
-    String.concat " \027[35m/\027[m "
-      (List.map (fun n -> Node.to_string 0 n) (List.rev t))
-
-  let l = function
-    | [] -> 0
-    | t :: _ -> t.l
-
-  let t = function
-    | [] -> 0
-    | t :: _ -> t.t
-
-  let pad = function
-    | [] -> 0
-    | t :: _ -> t.pad
-
-  let maptop f = function
-    | []   -> []
-    | t::l -> f t :: l
-
-  let shift path n =
-    maptop (fun t -> Node.shift t n) path
-end
-
-open Node
-
-(* A block is:
-   - a node path to go to this block
-   - the last token of this block
-   - the last token offset
-   - the original indentation for this block *)
-type t = {
-  path: Path.t;
-  last: Nstream.token option;
-  toff: int;
-  orig: int;
-}
-
-let shift t n =
-  { t with path = Path.shift t.path n }
-
-let to_string t =
-  Path.to_string t.path
-    (* Printf.sprintf "%s\n%d %b" (Path.to_string t.path) t.toff *)
-
-let empty = {
-  path = [];
-  last = None;
-  toff = 0;
-  orig = 0;
-}
-
-(*
-(* Does the token close a top LET construct ? *)
-(* NB: we do this with another way below, but this one might be more robust *)
-let rec close_top_let = function
-  | None -> true
-  | Some t ->
-      match t.token with
-      | COMMENT _ -> assert false (* COMMENT must be skipped *)
-
-      (* Tokens that allow a let-in after them *)
-      | AMPERSAND | AMPERAMPER | BARBAR | BEGIN | COLONCOLON | COLONEQUAL
-      | COMMA | DO | DOWNTO | ELSE | EQUAL | GREATER | IF | IN
-      | INFIXOP0 _ | INFIXOP1 _ | INFIXOP2 _ | INFIXOP3 _ | INFIXOP4 _
-      | LBRACE | LBRACELESS
-      | LBRACKET | LBRACKETBAR | LBRACKETLESS | LBRACKETGREATER
-      | LESS | LESSMINUS | LPAREN | MATCH | MINUS | MINUSDOT | MINUSGREATER | OR
-      | PLUS | PLUSDOT | QUESTION | QUESTIONQUESTION | SEMI | STAR | THEN
-      | TO | TRY | WHEN | WHILE
-      | TILDE -> false
-
-      | _ -> true
-*)
-
-(* Go back to the node path path until [f] holds *)
-let rec unwind f path = match path with
-  | { k } :: _ when f k -> path
-  | _ :: path -> unwind f path
-  | [] -> []
-
-(* Unwinds the path while [f] holds, returning the last step for which it does *)
-let unwind_while f path =
-  let rec aux acc = function
-    | { k } as h :: p when f k -> aux h p
-    | p -> acc :: p
-  in
-  match path with
-  | { k } as h :: p when f k -> Some (aux h p)
-  | _ -> None
-
-(* Unwind the struct/sig top *)
-let unwind_top =
-  unwind (function KStruct|KSig|KParen|KBegin -> true | _ -> false)
-
-(* Get the parent node *)
-let parent = function
-  | []     -> []
-  | _ :: t -> t
-
-(* Get the next token *)
-let rec next_token_full stream =
-  match Nstream.next stream with
-  | None
-  | Some ({token=EOF},_)       -> None
-  | Some ({token=COMMENT _},s) -> next_token_full s
-  | Some (t,_)                 -> Some t
-
-let next_token stream =
-  match next_token_full stream with
-  | None -> None
-  | Some t -> Some t.token
-
-let last_token t =
-  match t.last with
-  | None   -> None
-  | Some t -> Some t.token
-
-let stacktrace =
-  if Config.debug then fun t ->
-    Printf.eprintf "\027[32m%8s\027[m %s\n%!"
-      (match t.last with Some tok -> tok.substr | _ -> "")
-      (to_string t)
-  else fun _ -> ()
-
-(* different kinds of position:
-   [T]: token aligned: the child is aligned with the token position
-   [L]: line aligned: the child is aligned with the begining of line
-   [A]: absolute position *)
-type pos = L | T | A of int (* position *)
-
-(* Take a block, a token stream and a token.
-   Return the new block stack. *)
-let rec update_path t stream tok =
-  let open Config.Indent in
-  let config = Config.indent in
-  let node replace k pos pad path =
-    let line = Region.start_line tok.region in
-    if tok.newlines > 0 then
-      let l = match pos with
-        | A p -> p
-        | L   -> Path.l path + if replace then 0 else Path.pad path
-        | T   -> Path.t path + if replace then 0 else Path.pad path in
-      Node.create k l l pad line
-    else
-      let l = Path.l path in
-      let t = t.toff + tok.offset in
-      Node.create k l t pad line
-  in
-  (* Add a new child block *)
-  let append k pos ?(pad=config.i_base) path =
-    node false k pos pad path :: path
-  in
-  (* replace the current block with a new one *)
-  let replace k pos ?(pad=config.i_base) path = match path with
-    | []   -> [node true k pos pad path]
-    | _::t -> node true k pos pad path :: t
-  in
-  (* Used when expressions are merged together (for example in "3 +" the "+"
-     extends the lower-priority expression "3") *)
-  let extend k pos ?(pad=config.i_base) = function
-    | [] -> [node true k pos pad []]
-    | h::p ->
-        let negative_indent () =
-          (* Special negative indent: relative, only at beginning of line,
-             and when prio is changed or there is a paren to back-align to *)
-          if pad >= 0 || tok.newlines = 0 then None else
-            match p with
-            | {k=KParen|KBracket|KBracketBar|KBrace|KBar _} as paren :: _
-              when paren.line = h.line
-              ->
-                let l = paren.t in
-                Some ({ h with k; l; t=l; pad = h.t - l } :: p)
-            | _ ->
-                match k,h.k with
-                | KExpr pk, KExpr ph when ph = pk -> None
-                | _ ->
-                    let l = max 0 (h.t + pad) in
-                    Some ({ h with k; l; t=l; pad = -pad } :: p)
-        in
-        match negative_indent () with
-        | Some p -> p
-        | None -> (* normal case *)
-            (* change l to set the starting column of the expression *)
-            let pad = max 0 pad in
-            let l,pad =
-              if pos = T then h.t + pad, 0
-              else
-                (* set indent of the whole expr accoring to its parent *)
-                Path.l p + Path.pad p, pad
-            in
-            { h with k; l; pad } :: p
-  in
-  (* use before appending a new expr_atom: checks if that may cause an
-     apply and folds parent exprs accordingly *)
-  let fold_expr path =
-    match path with
-    | {k=KExpr i}::_ when i = prio_max ->
-        (* we are appending two expr_atom next to each other:
-           this is an apply. *)
-        (* this "folds" the left-side of the apply *)
-        let p = match unwind_while (fun k -> prio k >= prio_apply) path with
-          | Some({k=KExpr i}::_ as p) when i = prio_apply -> p
-          | Some({k=KExpr _}::{k=KArrow (KMatch|KTry)}::_ as p) ->
-              (* Special case: switch to token-aligned (see test js-args) *)
-              extend (KExpr prio_apply) T p
-          | Some p -> extend (KExpr prio_apply) L p
-          | None -> assert false
-        in
-        p
-    | _ -> path
-  in
-  let before_append_atom = function
-    | {k=KWith(KTry|KMatch as m)}::_ as path ->
-        (* Special case: 'match with' and no bar for the 1st case:
-           we append a virtual bar for alignment *)
-        let p =
-          append (KBar m) L ~pad:(config.i_with + 2) path
-        in
-        if tok.newlines = 0 then
-          let t = max 0 (t.toff + tok.offset - 2) in
-          Path.maptop (fun h -> {h with t}) p
-        else p
-    | path -> fold_expr path
-  in
-  let atom path =
-    let path = before_append_atom path in
-    append expr_atom L ~pad:(max config.i_base (Path.pad path)) path
-  in
-  let open_paren k path =
-    let path = before_append_atom path in
-    let p = append k L (fold_expr path) in
-    match p,next_token_full stream with
-    | {k=KParen|KBegin} :: {k=KArrow _} :: _, _
-      when tok.newlines = 0 ->
-        (* Special case: paren/begin after arrow has extra indent
-           (see test js-begin) *)
-        Path.shift p config.i_base
-    | h::p, Some ({newlines=0} as next) ->
-        if tok.newlines = 0 then
-          if k <> KParen && k <> KBegin then
-            let l = t.toff + tok.offset in
-            (* set alignment for next lines relative to [ *)
-            { h with l; t=l; pad = next.offset } :: p
-          else
-            h::p
-        else
-          (* set padding for next lines *)
-          { h with pad = next.offset } :: p
-    | _ -> p
-  in
-  let close f path =
-    (* Remove the padding for the closing brace/bracket/paren/etc. *)
-    Path.maptop (fun h -> {h with k=expr_atom; pad=0}) (unwind f path)
-  in
-  let op_prio_align_indent = function
-    (* anything else : -10 *)
-    (* in -> : 0 *)
-    | SEMI -> 5,L,-2
-    | AS -> 8,L,config.i_base
-    (* special negative indent is only honored at beginning of line *)
-    (* then else : 10 *)
-    | BAR -> 10,T,-2
-    | OF -> 20,L,0
-    | LESSMINUS | COLONEQUAL -> 20,L,config.i_base
-    | COMMA -> 30,L,0
-    | MINUSGREATER -> 32,L,0 (* is an operator only in types *)
-    | COLON | COLONGREATER -> 35,L,config.i_base
-    | OR | BARBAR -> 40,T,0
-    | AMPERSAND | AMPERAMPER -> 50,T,0
-    | INFIXOP0 s ->
-        (match String.sub s 0 (min 2 (String.length s)) with
-        (* these should deindent fun -> *)
-        | ">>" -> prio_flatop,L,0
-        | "|!" -> prio_flatop,T,0
-        | _ -> 60,L,config.i_base)
-    | EQUAL | LESS | GREATER -> 60,L,config.i_base
-    | INFIXOP1 _ -> 70,L,config.i_base
-    | COLONCOLON -> 80,L,config.i_base
-    | INFIXOP2 _ | PLUSDOT | PLUS | MINUSDOT | MINUS -> 90,L,config.i_base
-    | INFIXOP3 _ | STAR -> 100,L,config.i_base
-    | INFIXOP4 _ -> 110,L,config.i_base
-    (* apply: 140 *)
-    | TILDE | QUESTION -> 140,L,config.i_base
-    | LABEL _ | OPTLABEL _ -> 145,L,0
-    | SHARP -> 150,L,config.i_base
-    | DOT -> 160,L,config.i_base
-    | _ -> assert false
-  in
-  let make_infix token path =
-    let op_prio, align, indent = op_prio_align_indent token in
-    match unwind_while (fun k -> prio k >= op_prio) path with
-    | Some p ->
-        extend (KExpr op_prio) align ~pad:indent p
-    | None -> (* used as prefix ? Don't apply T indent *)
-        append (KExpr op_prio) L ~pad:(max 0 indent) path
-  in
-  (* KNone nodes correspond to comments or top-level stuff, they shouldn't be
-     taken into account when indenting the next token *)
-  let t = match t.path with {k=KNone}::path -> {t with path}
-    | _ -> t
-  in
-  match tok.token with
-  | SEMISEMI    -> append KNone L ~pad:0 (unwind_top t.path)
-  | INCLUDE     -> append KInclude L (unwind_top t.path)
-  | EXCEPTION   -> append KException L (unwind_top t.path)
-  | BEGIN       -> open_paren KBegin t.path
-  | OBJECT      -> append KObject L t.path
-  | VAL         -> append KVal L (unwind_top t.path)
-  | MATCH       -> append KMatch L (fold_expr t.path)
-  | TRY         -> append KTry L (fold_expr t.path)
-  | LPAREN      -> open_paren KParen t.path
-  | LBRACKET | LBRACKETGREATER | LBRACKETLESS ->
-      open_paren KBracket t.path
-  | LBRACKETBAR -> open_paren KBracketBar t.path
-  | LBRACE | LBRACELESS ->
-      open_paren KBrace t.path
-  | FUNCTION ->
-      (match fold_expr t.path with
-      | {k = KBody (KLet|KLetIn) | KArrow(KMatch|KTry)} as l :: _ as p
-        when tok.newlines = 0 ->
-          append (KWith KMatch) L ~pad:(max l.pad config.i_with) p
-      | p ->
-          append (KWith KMatch) L ~pad:config.i_with p)
-  | FUN         -> append KFun L (fold_expr t.path)
-  | STRUCT      -> append KStruct L t.path
-  | WHEN ->
-      append KWhen L ~pad:(config.i_base + 2)
-        (unwind (function
-        | KWith(KTry|KMatch) | KBar(KTry|KMatch) -> true
-        | _ -> false)
-           t.path)
-  | SIG         -> append KSig L t.path
-
-  | OPEN ->
-      if last_token t = Some LET then
-        append KOpen L t.path
-      else
-        append KOpen L (unwind_top t.path)
-
-  | LET ->
-      (* Two ways to detect let vs letin ;
-         both seem to work, but need to check which one
-         is the most robust (for example w.r.t. unfinished expressions) *)
-      (* - it's a top Let if it is after a closed expression *)
-      (match t.path with
-      | {k=KExpr i}::p when i = prio_max ->
-          append KLet L (unwind_top p)
-      | {k=KNone}::_ | [] ->
-          append KLet L []
-      | _ ->
-          append KLetIn L (fold_expr t.path))
-      (* - or if after a specific token *)
-      (* if close_top_let t.last then *)
-      (*   append KLet L config.i_base (unwind_top t.path) *)
-      (* else *)
-      (*   append KLetIn L config.i_base (fold_expr t.path) *)
-
-  | CLASS ->
-      append KLet L (unwind_top t.path)
-
-  | METHOD ->
-      append KLet L (unwind_top t.path)
-
-  | AND ->
-      let unwind_to = function
-        | KLet | KLetIn | KType | KModule -> true
-        | _ -> false
-      in let path = unwind (unwind_to @* follow) t.path in
-      (match path with
-      | {k=KType|KModule|KBody (KType|KModule)}
-        :: ({k=KWith _} as m) :: p ->
-          (* hack to align "and" with the 'i' of "with": consider "with" was
-             1 column further to the right *)
-          let m = if tok.newlines > 0 then {m with t = m.t+1} else m in
-          replace (KAnd m.k) T ~pad:0 (m :: p)
-      | {k=KType|KModule|KBody (KType|KModule)}
-        :: ({k=KAnd (KWith _)} as m) :: p ->
-          replace m.k T ~pad:0 (m :: p)
-      | h::_ -> replace (KAnd (follow h.k)) L path
-      | []   -> append (KAnd KNone) L path)
-
-  | IN ->
-      let path = unwind ((=) KLetIn @* follow) t.path in
-      let pad = match next_token stream with
-        | Some LET -> 0
-        | _ -> config.i_in
-      in
-      (match unwind_while ((=) KIn) (parent path) with
-      | Some p -> replace KIn L ~pad p
-      | None -> replace KIn L ~pad path)
-
-  | TYPE ->
-      (match last_token t with
-      | Some MODULE -> t.path (* module type *)
-      | Some (WITH|AND) -> append KType L t.path
-      | _ -> append KType L (unwind_top t.path))
-
-  | MODULE ->
-      (match last_token t with
-      | Some LET -> t.path (* let module *)
-      | Some (WITH|AND) -> append KType L t.path
-      | _ -> append KModule L (unwind_top t.path))
-
-  | END ->
-      close (function KStruct|KSig|KBegin|KObject -> true | _ -> false) t.path
-
-  | WITH ->
-      (match next_token stream with
-      | Some (TYPE|MODULE as tm) ->
-          let path =
-            unwind (function
-            | KModule | KOpen | KInclude | KParen | KBegin | KColon -> true
-            | _ -> false)
-              t.path
-          in
-          let k =
-            match tm with TYPE -> KType | MODULE -> KModule | _ -> assert false
-          in
-          append (KWith k) L path
-      | _ ->
-          let path = unwind (function
-            |KTry|KMatch
-            |KVal|KType|KBody KType|KException (* type-conv *)
-            |KBrace -> true
-            | _ -> false
-          ) t.path in
-          match path with
-          | {k=KBrace} :: _ -> append (KWith KBrace) L path
-          | {k=KVal|KType|KException as k}::_ -> replace (KWith k) L path
-          | {k=KTry|KMatch} as m
-              :: ({k = KBody (KLet|KLetIn) | KArrow(KMatch|KTry)} as l)
-              :: _
-            when m.line = l.line ->
-              replace (KWith KMatch) L ~pad:(max l.pad config.i_with) path
-          | {k=(KTry|KMatch as k)}::_ ->
-              replace (KWith k) L ~pad:config.i_with path
-          | _ -> path)
-
-  | IF ->
-      (match last_token t with
-      | Some ELSE  -> replace KIf L t.path
-      | _ -> append  KIf L (fold_expr t.path))
-
-  | THEN ->
-      extend KThen L (unwind ((=) KIf) t.path)
-
-  | ELSE ->
-      extend KElse L (unwind ((=) KThen) t.path)
-
-  | WHILE | FOR ->
-      append KLoop L (fold_expr t.path)
-
-  | DO ->
-      extend KDo L (unwind ((=) KLoop) t.path)
-
-  | DONE ->
-      close ((=) KDo) t.path
-
-  | BARRBRACKET -> close ((=) KBracketBar) t.path
-
-  | RPAREN -> close ((=) KParen) t.path
-
-  | RBRACE | GREATERRBRACE -> close ((=) KBrace) t.path
-
-  | RBRACKET | GREATERRBRACKET -> close ((=) KBracket) t.path
-
-  | BAR ->
-      let path = unwind (function
-          | KParen | KBegin | KBracket | KBrace | KBracketBar
-          | KWith(KMatch|KTry) | KBar(KMatch|KTry) | KArrow(KMatch|KTry)
-          | KFun | KLet | KLetIn
-          | KBody(KType) -> true
-          | _ -> false)
-          t.path
-      in
-      (match path with
-      | {k=KWith m} :: _ -> append (KBar m) L path
-      | {k=KArrow m} :: ({k=KBar _} as h:: _ as p) ->
-          Path.maptop (fun x -> {x with t = h.t})
-            (replace (KBar m) (A h.t) p)
-      | {k=KArrow m} :: p ->
-          append (KBar m) L p
-      | _ ->
-          match t.path with
-          | {k = KExpr _}::_ -> make_infix tok.token t.path
-          | _ -> append (KBar KType) L t.path)
-
-  | MINUSGREATER ->
-      let rec find_parent path =
-        let path = unwind (function
-            | KParen | KBegin | KBracket | KBrace | KBracketBar
-            | KWith(KMatch|KTry) | KBar(KMatch|KTry) | KArrow(KMatch|KTry)
-            | KFun
-            | KBody(KType|KExternal) | KColon -> true
-            | _ -> false)
-            path
-        in
-        match path with
-        | {k=KFun} :: {k=KExpr i} :: path when i = prio_flatop ->
-            (* eg '>>= fun x ->': indent like the top of the expression *)
-            path
-        | {k=KFun} :: _ -> append (KArrow KFun) L path
-        | {k=KWith m | KBar m} :: _ ->
-            let pad =
-              config.i_match_clause
-              - if tok.newlines > 0 then config.i_base else 0
-            in
-            append (KArrow m) L ~pad path
-        | {k=KArrow(KMatch|KTry)} :: p ->
-            (* might happen if doing 'when match' for example *)
-            (match
-              unwind (function
-                | KParen | KBegin | KBracket | KBrace | KBracketBar
-                | KWith(KMatch|KTry)
-                | KFun
-                | KBody(KType|KExternal) | KColon -> true
-                | _ -> false)
-                p
-            with
-            | {k=KWith(_)}::p -> find_parent p
-            | _ -> make_infix tok.token t.path)
-        | _ -> make_infix tok.token t.path
-      in
-      find_parent t.path
-
-  | EQUAL ->
-      let unwind_to = function
-        | KParen | KBegin | KBrace | KBracket | KBracketBar | KBody _
-        | KExternal | KModule | KType | KLet | KLetIn | KException
-        | KAnd(KModule|KType|KLet|KLetIn) -> true
-        | _ -> false
-      in let path = unwind unwind_to t.path in
-      (match path with
-      | {k=KBody KType}::_ -> (* type t = t' = ... *)
-          replace (KBody KType) L ~pad:config.i_type path
-      | {k=KParen|KBegin|KBrace|KBracket|KBracketBar|KBody _}::_ ->
-          make_infix tok.token t.path
-      | h::p ->
-          let indent = match next_token stream, h.k with
-            | Some (STRUCT|SIG|OBJECT), _ -> 0
-            | _, (KType | KBody KType) -> config.i_type
-            | _ -> config.i_base
-          in
-          if tok.newlines > 0 then
-            let h = {h with l = h.l + indent; pad = 0} in
-            replace (KBody h.k) L ~pad:0 (h :: p)
-          else
-            replace (KBody h.k) L ~pad:indent (h :: p)
-      | [] ->
-          append (KBody KNone) L [])
-
-  | COLONEQUAL ->
-      (match
-         unwind_while (function KExpr _ | KType -> true | _ -> false) t.path
-       with
-       | Some ({k=KType}::_ as p) -> (* type t := t' *)
-           replace (KBody KType) L p
-       | _ ->
-           make_infix tok.token t.path)
-
-  | COLON ->
-      let path = unwind (function
-        | KParen | KBegin | KBrace | KBracket | KBracketBar | KBody _
-        | KModule | KLet | KLetIn | KExternal | KVal
-        | KAnd(KModule|KLet|KLetIn) -> true
-        | _ -> false)
-        t.path
-      in
-      (match path with
-      | {k=KModule|KLet|KLetIn|KExternal} :: _ ->
-          append KColon L path
-      | {k=KVal} as h :: p ->
-          let indent = config.i_base in
-          if tok.newlines > 0 then
-            let h = {h with l = h.l + indent; pad = 0} in
-            replace (KBody h.k) L ~pad:0 (h :: p)
-          else
-            replace (KBody h.k) L ~pad:indent (h :: p)
-      | {k=KBrace}::_ -> (* record type *)
-          (match t.path with
-          | {k=KExpr i}::{k=KBrace}::_ as p
-            when i = prio_max ->
-              extend KColon L p
-          | {k=KExpr i}::({k=KExpr j}::{k=KBrace}::_ as p)
-            when i = prio_max && j = prio_apply -> (* "mutable" *)
-              extend KColon L p
-          | _ -> make_infix tok.token t.path)
-      | _ -> make_infix tok.token t.path)
-
-  | SEMI ->
-      (match unwind (function KExpr _ -> false | _ -> true) t.path with
-      | {k=KColon}::({k=KBrace}::_ as p) -> p
-      | _ -> make_infix tok.token t.path)
-
-  (* Some commom preprocessor directives *)
-  | UIDENT ("INCLUDE"|"IFDEF"|"THEN"|"ELSE"|"ENDIF"
-           |"TEST"|"TEST_UNIT"|"TEST_MODULE" as s)
-    when tok.newlines > 0 ->
-      if String.sub s 0 4 = "TEST" then
-        append KLet L ~pad:(2 * config.i_base) (unwind_top t.path)
-      else
-        replace KNone L (unwind_top t.path)
-
-  | EXTERNAL ->
-      append KExternal L (unwind_top t.path)
-
-  | DOT ->
-      (match t.path with
-      | {k=KExpr i} :: ({k=KBrace} as h :: p)
-        when i = prio_max ->
-          (* special case: distributive { Module. field; field } *)
-          { h with pad = config.i_base } :: p
-      | _ -> make_infix tok.token t.path)
-
-  | LESSMINUS | COMMA | OR | BARBAR
-  | AMPERSAND | AMPERAMPER | INFIXOP0 _ | INFIXOP1 _
-  | COLONCOLON | INFIXOP2 _ | PLUSDOT | PLUS | MINUSDOT | MINUS
-  | INFIXOP3 _ | STAR | INFIXOP4 _
-  | SHARP | AS | COLONGREATER
-  | LESS | GREATER | OF ->
-      make_infix tok.token t.path
-
-  | LABEL _ | OPTLABEL _ ->
-      (match
-        unwind_while (function
-            | KExpr _ | KLet | KLetIn | KFun | KAnd(KLet|KLetIn) -> true
-            | _ -> false)
-          t.path
-      with
-      | Some ({k=KExpr _}::_) | None ->
-          (* considered as infix, but forcing function application *)
-          make_infix tok.token (fold_expr t.path)
-      | _ -> (* in function definition *)
-          atom t.path)
-
-  | UIDENT _ ->
-      (match t.path with
-      | {k=KBody KType}::_ when tok.newlines > 0 ->
-          (* type =\nA\n| B : append a virtual bar before A for alignment *)
-          let path = append (KBar KType) L ~pad:config.i_type t.path
-          in atom path
-      | _ -> atom t.path)
-
-  | INT64 _ | INT32 _ | INT _ | LIDENT _
-  | FLOAT _ | CHAR _ | STRING _ | EOF_IN_STRING _
-  | TRUE | FALSE | NATIVEINT _
-  | UNDERSCORE | TILDE | QUESTION
-  | QUOTE | QUOTATION | EOF_IN_QUOTATION _ ->
-      atom t.path
-
-  | PREFIXOP _ | BANG | QUESTIONQUESTION ->
-      (* FIXME: should be highest priority, > atom
-         ( append is not right for atoms ) *)
-      atom t.path
-
-  | ASSERT | LAZY | NEW | MUTABLE ->
-      append expr_apply L (fold_expr t.path)
-
-  | COMMENT _ | EOF_IN_COMMENT _ ->
-      if tok.newlines = 0 then t.path
-      else
-        (match Nstream.next stream with
-        | None | Some ({token=EOF},_) ->
-            if tok.newlines <= 1 then
-              (* comment is associated with the last token *)
-              append KNone (A (Path.l t.path)) ~pad:0 t.path
-            else
-              (* closing comments *)
-              append KNone (A 0) ~pad:0 []
-        | Some (ntok, nstream) ->
-            if ntok.newlines <= 1 || tok.newlines > 1 then
-            (* comment is associated to the next token: look-ahead *)
-              let npath = update_path t nstream ntok in
-              append KNone (A (Path.l npath)) ~pad:0 t.path
-            else
-            (* comment is associated to the previous token *)
-              append KNone (A (Path.l t.path)) ~pad:0 t.path)
-
-  |VIRTUAL|TO
-  |REC
-  |PRIVATE
-  |INITIALIZER|INHERIT
-  |FUNCTOR|EOF
-  |DOWNTO|DOTDOT|CONSTRAINT
-  |BACKQUOTE|ILLEGAL_CHAR _ ->
-      t.path
-
-let update block stream t =
-  let path = update_path block stream t in
-  let last = match t.token with
-    | COMMENT _ -> block.last
-    | _         -> Some t in
-  let toff =
-    if t.newlines > 0 then
-      Path.l path
-    else
-      block.toff + t.offset in
-  let orig =
-    if t.newlines > 0 then
-      Region.start_column t.region
-    else
-      block.orig in
-  { path; last; toff; orig }
-
-let indent t = Path.l t.path
-
-let original_indent t =
-  t.orig
-
-let offset t = t.toff
-
-let set_column t col =
-  { t with
-    path = Path.maptop (fun n -> {n with l = col}) t.path;
-    toff = col }
-
-let guess_indent line t =
-  match t with
-  | { path = {k=KExpr i}::p; last = Some tok }
-    when i = prio_max &&
-         line > Region.end_line tok.region + 1
-    ->
-      (* closed expr and newline: we probably want a toplevel block *)
-      Path.l (unwind_top p)
-  | { path } ->
-      (* we probably want to write a child of the current node *)
-      match unwind_while (fun k -> prio k >= prio_apply) path with
-      | Some ({l;pad}::_) -> l + pad
-      | _ -> match path with
-          | {l;pad}::_ -> l + pad
-          | [] -> 0

File ocaml/contrib/ocp-indent/src/block.mli

-(**************************************************************************)
-(*                                                                        *)
-(*  Copyright 2011 Jun Furuse                                             *)
-(*  Copyright 2012,2013 OCamlPro                                          *)
-(*                                                                        *)
-(*  All rights reserved.  This file is distributed under the terms of     *)
-(*  the GNU Public License version 3.0.                                   *)
-(*                                                                        *)
-(*  TypeRex 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.                          *)
-(*                                                                        *)
-(**************************************************************************)
-
-(** Indenter block *)
-type t
-
-(** Shift a block by a given offset *)
-val shift: t -> int -> t
-
-(** Set the start column of the given block to [column], to adapt to existing
-    code for partial indentation *)
-val set_column: t -> int -> t
-
-(** Return the current line offset *)
-val offset: t -> int
-
-(** Return the block indentation *)
-val indent: t -> int
-
-(** Return the block original indentation *)
-val original_indent: t -> int
-
-(** The empty block *)
-val empty: t
-
-(** [update t str tok] computes the new block state after processing
-    the token [tok] in block [t]. The next tokens can be observed in
-    the stream [str]. *)
-val update: t -> Nstream.t -> Nstream.token -> t
-
-(** Display stacktrace (if Config.debug is true) *)
-val stacktrace: t -> unit
-
-(** [guess_indent line block]
-    For indenting empty lines: attempt to guess what the most probable
-    indent at this point would be *)
-val guess_indent: int -> t -> int

File ocaml/contrib/ocp-indent/src/config.ml

-(**************************************************************************)
-(*                                                                        *)
-(*  Copyright 2011 Jun Furuse                                             *)
-(*  Copyright 2013 OCamlPro                                               *)
-(*                                                                        *)
-(*  All rights reserved.  This file is distributed under the terms of     *)
-(*  the GNU Public License version 3.0.                                   *)
-(*                                                                        *)
-(*  TypeRex 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.                          *)
-(*                                                                        *)
-(**************************************************************************)
-
-module Indent = struct
-  type t = {
-    i_base: int;
-    i_type: int;
-    i_in: int;
-    i_with: int;
-    i_match_clause: int;
-  }
-
-  let default = {
-    i_base = 2;
-    i_type = 2;
-    i_in = 0;
-    i_with = 0;
-    i_match_clause = 2;
-  }
-
-  let presets = [
-    "apprentice",
-    { i_base = 4; i_with = 2; i_in = 2; i_match_clause = 4; i_type = 4 };
-    "normal",
-    default;
-    "JaneStreet",
-    { i_base = 2; i_with = 0; i_in = 0; i_match_clause = 2; i_type = 0 };
-  ]
-
-  let set t var_name value =
-    try
-      match var_name with
-      | "base" -> {t with i_base = int_of_string value}
-      | "type" -> {t with i_type = int_of_string value}
-      | "in" -> {t with i_in = int_of_string value}
-      | "with" -> {t with i_with = int_of_string value}
-      | "match_clause" -> {t with i_match_clause = int_of_string value}
-      | _ -> raise (Invalid_argument var_name)
-    with
-    | Failure "int_of_string" ->
-        let e = Printf.sprintf "%S should be an integer" value in
-        raise (Invalid_argument e)
-
-  let update_from_string indent s =
-    List.fold_left
-      (fun indent s -> match Util.string_split '=' (String.trim s) with
-      | [var;value] -> set indent var value
-      | [preset] ->
-          (try List.assoc preset presets with
-            Not_found -> raise (Invalid_argument preset))
-      | _ -> raise (Invalid_argument s))
-      indent
-      (Util.string_split ',' s)
-
-  let help =
-    Printf.sprintf
-      "Config syntax: <var>=<value>[,<var>=<value>...] or <preset>[,...]\n\
-       \n\
-       Indent configuration variables:\n\
-      \  [variable]   [default] [help]\n\
-      \  base           %3d     base indent\n\
-      \  type           %3d     indent of type definitions\n\
-      \  in             %3d     indent after 'let in'\n\
-      \  with           %3d     indent of match cases (before '|')\n\
-      \  match_clause   %3d     indent inside match cases (after '->')\n\
-       \n\
-       Available configuration presets:%s\n\
-       \n\
-       The config can also be set in variable OCP_INDENT_CONFIG"
-      default.i_base
-      default.i_type
-      default.i_in
-      default.i_with
-      default.i_match_clause
-      (List.fold_left (fun s (name,_) -> s ^ " " ^ name) "" presets)
-
-  let default =
-    try
-      update_from_string default (Sys.getenv ("OCP_INDENT_CONFIG"))
-    with
-    | Not_found -> default
-    | Invalid_argument _ ->
-        prerr_endline "Warning: invalid $OCP_INDENT_CONFIG";
-        default
-end
-
-let version () =
-  Printf.printf "\
-%s version %s\n\
-\n\
-Copyright (C) 2013 OCamlPro\n\
-\n\
-This is free software; see the source for copying conditions.  There is NO\n\
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
-    Sys.argv.(0) Globals.version;
-  exit 0
-
-let init_config () =
-  let debug = ref false
-  and file  = ref None
-  and lines = ref (None, None)
-  and numeric_only = ref false
-  and indent = ref Indent.default
-  in
-  let usage =
-    Printf.sprintf "%s [options] [filename]" Sys.argv.(0)
-  in
-  let error fmt =
-    Printf.ksprintf (fun s -> raise (Arg.Bad s)) fmt
-  in
-  let set_lines str =
-    try
-      lines := match Util.string_split '-' str with
-      | [s] ->
-          let li = int_of_string s in Some li, Some li
-      | [s1;""] ->
-          Some (int_of_string s1), None
-      | ["";s2] ->
-          None, Some (int_of_string s2)
-      | [s1;s2] ->
-          Some (int_of_string s1), Some (int_of_string s2)
-      | _ -> error "Bad --lines parameter: %S" str
-    with
-    | Failure "int_of_string" ->
-        error "Bad --lines parameter: %S" str
-  in
-  let add_file s = match !file with
-    | None   -> file := Some s
-    | Some _ -> error "Unknown parameter %S" s
-  in
-  let set_indent s =
-    if s = "help" then (print_endline Indent.help; exit 0) else
-      try
-        indent := Indent.update_from_string !indent s
-      with
-      | Invalid_argument s ->
-          error "Bad --config parameter %S.\n%s" s Indent.help
-      | Failure _ ->
-          error "Bad --config value %S.\n%s" s Indent.help
-  in
-  let options = Arg.align [
-      "--config" , Arg.String set_indent, " ";
-      "-c"       , Arg.String set_indent, "var=value[,var=value...] \
-                                           Configure the indentation \
-                                           parameters. Try \"--config help\"";
-      "--debug"  , Arg.Set debug        , " ";
-      "-d"       , Arg.Set debug        , " Output debug info to stderr";
-      "--lines"  , Arg.String set_lines , " ";
-      "-l"       , Arg.String set_lines , "n1-n2 Only indent the lines in the \
-                                           given interval (eg. 10-12)";
-      "--numeric", Arg.Set numeric_only , " Only print the indentation values, \
-                                           not the contents. Useful in editors";
-      "--version", Arg.Unit version     , " ";
-      "-v"       , Arg.Unit version     , " Display version information and \
-                                           exit";
-  ]
-  in
-  Arg.parse (Arg.align options) add_file usage;
-  Util.default "/dev/stdin" !file, !lines, !numeric_only, !indent, !debug
-
-let file, lines, numeric_only, indent, debug = init_config ()
-
-(* indent_empty is set if and only if reindenting a single line *)
-let indent_empty = match lines with
-  | Some fst, Some lst when fst = lst -> true
-  | _ -> false
-
-let start_line =
-  match lines with None,_ -> 1 | Some n,_ -> n
-
-let in_lines l =
-  let first,last = lines in
-  (match first with None -> true | Some n -> n <= l) &&
-  (match last  with None -> true | Some n -> l <= n)

File ocaml/contrib/ocp-indent/src/config.mli

-(**************************************************************************)
-(*                                                                        *)
-(*  Copyright 2011 Jun Furuse                                             *)
-(*  Copyright 2013 OCamlPro                                               *)
-(*                                                                        *)
-(*  All rights reserved.  This file is distributed under the terms of     *)
-(*  the GNU Public License version 3.0.                                   *)
-(*                                                                        *)
-(*  TypeRex 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.                          *)
-(*                                                                        *)
-(**************************************************************************)
-
-module Indent : sig
-  type t = {
-    (* number of spaces used in all base cases, for example:
-       let foo =
-       ^^bar
-       default 2 *)
-    i_base: int;
-    (* indent for type definitions:
-       type t =
-       ^^int *)
-    i_type: int;
-    (* indent after [let in], unless followed by another [let]:
-       let foo = () in
-       ^^bar
-       default 0; beginners may prefer 2. *)
-    i_in: int;
-    (* indent after [match/try with] or [function]:
-       match foo with
-       ^^| _ -> bar
-       default 0
-       note that this is superseded if just after [let _ =] on the same line *)
-    i_with: int;
-    (* indent for clauses inside a pattern-match:
-       match foo with
-         | _ ->
-         ^^^^bar
-       default 2, which aligns the pattern and the expression *)
-    i_match_clause: int;
-  }
-
-  val help: string
-
-  val default: t
-end
-
-(* Current configuration: *)
-
-val file: string
-val lines: int option * int option
-val numeric_only: bool
-val indent: Indent.t
-val debug: bool
-
-val indent_empty: bool
-
-
-val start_line: int
-
-val in_lines: int -> bool

File ocaml/contrib/ocp-indent/src/globals.ml

-let version = "0.6.0"

File ocaml/contrib/ocp-indent/src/globals.ml.in

-let version = "@PACKAGE_VERSION@"

File ocaml/contrib/ocp-indent/src/indentArgs.ml

+(**************************************************************************)
+(*                                                                        *)
+(*  Copyright 2011 Jun Furuse                                             *)
+(*  Copyright 2013 OCamlPro                                               *)
+(*                                                                        *)
+(*  All rights reserved.  This file is distributed under the terms of     *)
+(*  the GNU Public License version 3.0.                                   *)
+(*                                                                        *)
+(*  TypeRex 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.                          *)
+(*                                                                        *)
+(**************************************************************************)
+
+let version () =
+  Printf.printf "\
+%s version %s\n\
+\n\
+Copyright (C) 2013 OCamlPro\n\
+\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+    Sys.argv.(0) IndentVersion.version;
+  exit 0
+
+let arg_debug = ref false
+let arg_file  = ref false
+let arg_file_out  = ref None
+let arg_lines = ref (None, None)
+let arg_numeric_only = ref false
+let arg_indent = ref IndentConfig.default
+let arg_inplace = ref false
+
+let arg_usage =
+  Printf.sprintf "%s [options] [filename]" Sys.argv.(0)
+
+let arg_list = ref []
+
+let arg_error fmt =
+  Printf.ksprintf (fun s ->
+    Printf.eprintf "Fatal error: %s\n" s;
+    Arg.usage !arg_list arg_usage; exit 2) fmt
+
+let set_lines str =
+  try
+    arg_lines := match Util.string_split '-' str with
+    | [s] ->
+      let li = int_of_string s in Some li, Some li
+    | [s1;""] ->
+      Some (int_of_string s1), None
+    | ["";s2] ->
+      None, Some (int_of_string s2)
+    | [s1;s2] ->
+      Some (int_of_string s1), Some (int_of_string s2)
+    | _ -> arg_error "Bad --lines parameter: %S" str
+  with
+  | Failure "int_of_string" ->
+    arg_error "Bad --lines parameter: %S" str
+
+(*
+let add_file s = match !file with
+  | None   -> file := Some s
+  | Some _ -> error "Unknown parameter %S" s
+in
+*)
+
+let set_indent s =
+  if s = "help" then (print_endline IndentConfig.help; exit 0) else
+    try
+      arg_indent := IndentConfig.update_from_string !arg_indent s
+    with
+    | Invalid_argument s ->
+      arg_error "Bad --config parameter %S.\n%s" s IndentConfig.help
+    | Failure _ ->
+      arg_error "Bad --config value %S.\n%s" s IndentConfig.help
+
+
+let _ =
+  arg_list := Arg.align [
+  "--config" , Arg.String set_indent, " ";
+  "-c"       , Arg.String set_indent, "var=value[,var=value...] \
+                                           Configure the indentation \
+                                           parameters. Try \"--config help\"";
+  "--debug"  , Arg.Set arg_debug        , " ";
+  "-d"       , Arg.Set arg_debug        , " Output debug info to stderr";
+  "--inplace", Arg.Set arg_inplace      , " ";
+  "-i"       , Arg.Set arg_inplace      , " Modify file in place";
+  "--lines"  , Arg.String set_lines , " ";
+  "-l"       , Arg.String set_lines , "n1-n2 Only indent the lines in the \
+                                           given interval (eg. 10-12)";
+  "--numeric", Arg.Set arg_numeric_only , " Only print the indentation values, \
+                                           not the contents. Useful in editors";
+  "--version", Arg.Unit version     , " ";
+  "-v"       , Arg.Unit version     , " Display version information and \
+                                           exit";
+  "--output",  Arg.String (fun s -> arg_file_out := Some s), " ";
+  "-o",  Arg.String (fun s -> arg_file_out := Some s),
+                                       "file Save output in file";
+]
+
+let arg_list = !arg_list
+
+(*
+Arg.parse (Arg.align options) add_file usage;
+Util.default "/dev/stdin" !file, !lines, !numeric_only, !indent, !debug
+
+let file, lines, numeric_only, indent, debug = init_config ()
+*)
+
+(* indent_empty is set if and only if reindenting a single line *)
+let indent_empty () =
+  match !arg_lines with
+  | Some fst, Some lst when fst = lst -> true
+  | _ -> false
+
+let start_line ()=
+  match !arg_lines with None,_ -> 1 | Some n,_ -> n
+
+let in_lines l =
+  match !arg_lines with
+    None, None -> true
+  | Some first, Some last -> first <= l && l <= last
+  | Some first, None -> first <= l
+  | None, Some last -> l <= last

File ocaml/contrib/ocp-indent/src/indentArgs.mli

+(**************************************************************************)
+(*                                                                        *)
+(*  Copyright 2011 Jun Furuse                                             *)
+(*  Copyright 2013 OCamlPro                                               *)
+(*                                                                        *)
+(*  All rights reserved.  This file is distributed under the terms of     *)
+(*  the GNU Public License version 3.0.                                   *)
+(*                                                                        *)
+(*  TypeRex 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.                          *)
+(*                                                                        *)
+(**************************************************************************)
+
+(* Current configuration: *)
+
+val arg_file: bool ref
+val arg_file_out : string option ref
+(*val arg_lines: int option * int option *)
+val arg_numeric_only: bool ref
+val arg_indent: IndentConfig.t ref
+val arg_debug: bool ref
+val arg_inplace : bool ref
+val arg_error : ('a, unit, string, 'b) format4 -> 'a
+
+val indent_empty: unit -> bool
+val start_line: unit -> int
+val in_lines: int -> bool
+
+val arg_usage : string
+val arg_list : (Arg.key * Arg.spec * Arg.doc) list
+

File ocaml/contrib/ocp-indent/src/indentBlock.ml

+(**************************************************************************)
+(*                                                                        *)
+(*  Copyright 2011 Jun Furuse                                             *)
+(*  Copyright 2012,2013 OCamlPro                                          *)
+(*                                                                        *)
+(*  All rights reserved.  This file is distributed under the terms of     *)
+(*  the GNU Public License version 3.0.                                   *)
+(*                                                                        *)
+(*  TypeRex 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.                          *)
+(*                                                                        *)
+(**************************************************************************)
+
+open Pos
+open Nstream
+open Approx_lexer
+open Util
+
+module Node = struct
+
+  (* Node kind *)
+  type kind =
+    | KParen
+    | KBrace
+    | KBracket
+    | KBracketBar
+    | KLet
+    | KAnd of kind
+    | KLetIn
+    | KIn
+
+    | KExpr of int
+    (* actually handles also patterns / types / ... *)
+    (* Parameter:Priority - next expression is deindented if the op has
+       lower priority *)
+
+    | KBody of kind
+    | KArrow of kind
+    | KColon
+    | KType
+    | KException
+    | KOpen
+    | KInclude
+    | KVal
+    | KBar of kind
+    | KNone
+    | KStruct
+    | KSig
+    | KModule
+    | KBegin
+    | KObject
+    | KMatch
+    | KTry
+    | KWith of kind
+    | KLoop
+    | KIf
+    | KThen
+    | KElse
+    | KDo
+    | KFun
+    | KWhen
+    | KExternal
+
+  (* Priority of open expression constructs (see below for operators) *)
+  let prio = function
+    | KIn | KArrow _ -> 0
+    | KThen | KElse -> 10
+    | KExpr i -> i
+    | _ -> -10
+
+  let prio_max = 200
+  let prio_apply = 140
+  let expr_atom = KExpr prio_max
+  let expr_apply = KExpr 140
+  (* Special operators that should break arrow indentation have this prio
+     (eg monad operators, >>=) *)
+  let prio_flatop = 59
+
+  let rec follow = function
+    | KAnd k
+    | KBody k
+    | KWith k -> follow k
+    | k -> k
+
+  let rec string_of_kind = function
+    | KExpr i -> Printf.sprintf "KExpr(%d)" i
+    | KParen -> "KParen"
+    | KBrace -> "KBrace"
+    | KBracket -> "KBracket"
+    | KBracketBar -> "KBracketBar"
+    (* | KField -> "KField" *)
+    | KLet -> "KLet"
+    | KIn -> "KIn"
+    | KAnd k -> aux "KAnd" k
+    | KLetIn -> "KLetIn"
+    | KBody k -> aux "KBody" k
+    | KArrow k -> aux "KArrow" k
+    | KColon -> "KColon"
+    | KVal -> "KVal"
+    | KBar k -> aux "KBar" k
+    | KOpen -> "KOpen"
+    | KInclude -> "KInclude"
+    | KNone -> "KNone"
+    | KType -> "Ktype"
+    | KException -> "KException"
+    | KStruct -> "KStruct"
+    | KSig -> "KSig"
+    | KModule -> "KModule"
+    | KBegin -> "KBegin"
+    | KObject -> "KObject"
+    | KMatch -> "KMatch"
+    | KTry -> "KTry"
+    | KWith k -> aux "KWith" k
+    | KLoop -> "KLoop"
+    | KIf -> "KIf"
+    | KThen -> "Kthen"
+    | KElse -> "KElse"
+    | KDo -> "KDo"
+    | KFun -> "KFun"
+    | KWhen -> "KWhen"
+    | KExternal -> "KExternal"
+
+  and aux str k =
+    Printf.sprintf "%s(%s)" str (string_of_kind k)
+
+  (* A node:
+     - has a kind
+     - has the current line offset [l]
+     - has the current token offset [t]
+     - has a inner padding [pad]
+     - has a line count [count]
+
+         XXX XXX XXX [
+                            XXX
+                     ]
+
+         XXX XXX XXX [
+               XXX
+         ]
+
+<---l--->
+<----------x-------->
+                     <-pad->
+        <-pad->
+*)
+
+  type t = {
+    k:   kind;
+    l:   int;
+    t:   int;
+    pad : int;
+    line: int;
+  }
+
+  let to_string i t =
+    Printf.sprintf "%s%s %d|%d-%d(%d)"
+      (String.make i ' ') (string_of_kind t.k) t.line t.l t.t t.pad
+
+  let create k l t pad line =
+    { k; l; t; pad; line }
+
+  let shift node n =
+    let n = max n (- node.l) in
+    { node with l = node.l + n; t = node.t + n }
+
+end
+
+module Path = struct
+
+  open Node
+  type t = Node.t list
+
+  let to_string t =
+    String.concat " \027[35m/\027[m "
+      (List.map (fun n -> Node.to_string 0 n) (List.rev t))
+
+  let l = function
+    | [] -> 0
+    | t :: _ -> t.l
+
+  let t = function
+    | [] -> 0
+    | t :: _ -> t.t
+
+  let pad = function
+    | [] -> 0
+    | t :: _ -> t.pad
+
+  let maptop f = function
+    | []   -> []
+    | t::l -> f t :: l
+
+  let shift path n =
+    maptop (fun t -> Node.shift t n) path
+end
+
+open Node
+
+(* A block is:
+   - a node path to go to this block
+   - the last token of this block
+   - the last token offset
+   - the original indentation for this block *)
+type t = {
+  path: Path.t;
+  last: Nstream.token option;
+  toff: int;
+  orig: int;
+}
+
+let shift t n =
+  { t with path = Path.shift t.path n }
+
+let to_string t =
+  Path.to_string t.path
+    (* Printf.sprintf "%s\n%d %b" (Path.to_string t.path) t.toff *)
+
+let empty = {
+  path = [];
+  last = None;
+  toff = 0;
+  orig = 0;
+}
+
+(*
+(* Does the token close a top LET construct ? *)
+(* NB: we do this with another way below, but this one might be more robust *)
+let rec close_top_let = function
+  | None -> true
+  | Some t ->
+      match t.token with
+      | COMMENT _ -> assert false (* COMMENT must be skipped *)
+
+      (* Tokens that allow a let-in after them *)
+      | AMPERSAND | AMPERAMPER | BARBAR | BEGIN | COLONCOLON | COLONEQUAL
+      | COMMA | DO | DOWNTO | ELSE | EQUAL | GREATER | IF | IN
+      | INFIXOP0 _ | INFIXOP1 _ | INFIXOP2 _ | INFIXOP3 _ | INFIXOP4 _
+      | LBRACE | LBRACELESS
+      | LBRACKET | LBRACKETBAR | LBRACKETLESS | LBRACKETGREATER
+      | LESS | LESSMINUS | LPAREN | MATCH | MINUS | MINUSDOT | MINUSGREATER | OR
+      | PLUS | PLUSDOT | QUESTION | QUESTIONQUESTION | SEMI | STAR | THEN
+      | TO | TRY | WHEN | WHILE
+      | TILDE -> false
+
+      | _ -> true
+*)
+
+(* Go back to the node path path until [f] holds *)
+let rec unwind f path = match path with
+  | { k } :: _ when f k -> path
+  | _ :: path -> unwind f path
+  | [] -> []
+
+(* Unwinds the path while [f] holds, returning the last step for which it does *)
+let unwind_while f path =
+  let rec aux acc = function
+    | { k } as h :: p when f k -> aux h p
+    | p -> acc :: p
+  in
+  match path with
+  | { k } as h :: p when f k -> Some (aux h p)
+  | _ -> None
+
+(* Unwind the struct/sig top *)
+let unwind_top =
+  unwind (function KStruct|KSig|KParen|KBegin|KObject -> true | _ -> false)
+
+(* Get the parent node *)
+let parent = function
+  | []     -> []
+  | _ :: t -> t
+
+(* Get the next token *)
+let rec next_token_full stream =
+  match Nstream.next stream with
+  | None
+  | Some ({token=EOF},_)       -> None
+  | Some ({token=COMMENT _},s) -> next_token_full s
+  | Some (t,_)                 -> Some t
+
+let next_token stream =
+  match next_token_full stream with
+  | None -> None
+  | Some t -> Some t.token
+
+let last_token t =
+  match t.last with
+  | None   -> None
+  | Some t -> Some t.token
+
+let stacktrace t =
+    Printf.eprintf "\027[32m%8s\027[m %s\n%!"
+      (match t.last with Some tok -> tok.substr | _ -> "")
+      (to_string t)
+
+(* different kinds of position:
+   [T]: token aligned: the child is aligned with the token position
+   [L]: line aligned: the child is aligned with the begining of line
+   [A]: absolute position *)
+type pos = L | T | A of int (* position *)
+
+(* Take a block, a token stream and a token.
+   Return the new block stack. *)
+let rec update_path config t stream tok =
+  let open IndentConfig in
+  let is_first_line = Region.char_offset tok.region = tok.offset in
+  let starts_line = tok.newlines > 0 || is_first_line in
+  let node replace k pos pad path =
+    let line = Region.start_line tok.region in
+    if starts_line then
+      let l = match pos with
+        | A p -> p
+        | L   -> Path.l path + if replace then 0 else Path.pad path
+        | T   -> Path.t path + if replace then 0 else Path.pad path in
+      Node.create k l l pad line
+    else
+      let l = Path.l path in
+      let t = t.toff + tok.offset in
+      Node.create k l t pad line
+  in
+  (* Add a new child block *)
+  let append k pos ?(pad=config.i_base) path =
+    node false k pos pad path :: path
+  in
+  (* replace the current block with a new one *)
+  let replace k pos ?(pad=config.i_base) path = match path with
+    | []   -> [node true k pos pad path]
+    | _::t -> node true k pos pad path :: t
+  in
+  (* Used when expressions are merged together (for example in "3 +" the "+"
+     extends the lower-priority expression "3") *)
+  let extend k pos ?(pad=config.i_base) = function
+    | [] -> [node true k pos pad []]
+    | h::p ->
+        let negative_indent () =
+          (* Special negative indent: relative, only at beginning of line,
+             and when prio is changed or there is a paren to back-align to *)
+          if pad >= 0 || not starts_line then None else
+            match p with
+            | {k=KParen|KBracket|KBracketBar|KBrace|KBar _} as paren :: _
+              when paren.line = h.line
+              ->
+                let l = paren.t in
+                Some ({ h with k; l; t=l; pad = h.t - l } :: p)
+            | _ ->
+                match k,h.k with
+                | KExpr pk, KExpr ph when ph = pk -> None
+                | _ ->
+                    let l = max 0 (h.t + pad) in
+                    Some ({ h with k; l; t=l; pad = -pad } :: p)
+        in
+        match negative_indent () with
+        | Some p -> p
+        | None -> (* normal case *)
+            (* change l to set the starting column of the expression *)
+            let pad = max 0 pad in
+            let l,pad =
+              if pos = T then h.t + pad, 0
+              else
+                (* set indent of the whole expr accoring to its parent *)
+                Path.l p + Path.pad p, pad
+            in
+            { h with k; l; pad } :: p
+  in
+  (* use before appending a new expr_atom: checks if that may cause an
+     apply and folds parent exprs accordingly *)
+  let fold_expr path =
+    match path with
+    | {k=KExpr i}::_ when i = prio_max ->
+        (* we are appending two expr_atom next to each other:
+           this is an apply. *)
+        (* this "folds" the left-side of the apply *)
+        let p = match unwind_while (fun k -> prio k >= prio_apply) path with
+          | Some({k=KExpr i}::_ as p) when i = prio_apply -> p
+          | Some({k=KExpr _}::{k=KArrow (KMatch|KTry)}::_ as p) ->
+              (* Special case: switch to token-aligned (see test js-args) *)
+              extend (KExpr prio_apply) T p
+          | Some p -> extend (KExpr prio_apply) L p
+          | None -> assert false
+        in
+        p
+    | _ -> path
+  in
+  let before_append_atom = function
+    | {k=KWith(KTry|KMatch as m)}::_ as path ->
+        (* Special case: 'match with' and no bar for the 1st case:
+           we append a virtual bar for alignment *)
+        let p =
+          append (KBar m) L ~pad:(config.i_with + 2) path
+        in
+        if not starts_line then
+          let t = max 0 (t.toff + tok.offset - 2) in
+          Path.maptop (fun h -> {h with t}) p
+        else p
+    | path -> fold_expr path
+  in
+  let atom path =
+    let path = before_append_atom path in
+    append expr_atom L ~pad:(max config.i_base (Path.pad path)) path
+  in
+  let open_paren k path =
+    let path = before_append_atom path in
+    let p = append k L (fold_expr path) in
+    match p,next_token_full stream with
+    | {k=KParen|KBegin} :: {k=KArrow _} :: _, _
+      when not starts_line ->
+        (* Special case: paren/begin after arrow has extra indent
+           (see test js-begin) *)
+        Path.shift p config.i_base
+    | h::p, Some ({newlines=0} as next) ->
+        if not starts_line then
+          if k <> KParen && k <> KBegin then
+            let l = t.toff + tok.offset in