Improved test.
[ocaml-bitstring.git] / bitmatch_persistent.mli
index f390970..9c12d99 100644 (file)
@@ -4,7 +4,8 @@
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2 of the License, or (at your option) any later version,
+ * with the OCaml linking exception described in COPYING.LIB.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -53,6 +54,19 @@ let is_pascal_string bits =
       str strlen
 v}
 
       str strlen
 v}
 
+   or:
+
+{v
+(* Load a persistent pattern from a file. *)
+open bitmatch "pascal.bmpp"
+
+let is_pascal_string bits =
+  bitmatch bits with
+  | \{ :pascal_string } ->
+    printf "matches a Pascal string %s, len %d bytes\n"
+      str strlen
+v}
+
    {3 Important notes}
 
    There are some important things you should know about
    {3 Important notes}
 
    There are some important things you should know about
@@ -74,10 +88,10 @@ v}
    link to camlp4.  Since camlp4 in OCaml >= 3.10 is rather large, we
    have placed this code into this separate submodule, so that
    programs which just use bitmatch don't need to pull in the whole of
    link to camlp4.  Since camlp4 in OCaml >= 3.10 is rather large, we
    have placed this code into this separate submodule, so that
    programs which just use bitmatch don't need to pull in the whole of
-   camlp4.  This restriction does not apply to generated code which
-   only uses persistent patterns.  If the distinction isn't clear,
-   use [ocamlobjinfo] to look at the dependencies of your [*.cmo]
-   files.
+   camlp4.  This restriction does not apply to code which only uses
+   persistent patterns but does not generate them.  If the distinction
+   isn't clear, use [ocamlobjinfo] to look at the dependencies of your
+   [*.cmo] files.
 
    Persistent patterns can be generated in several ways, but they
    can only be {i used} by the [pa_bitmatch] syntax extension.
 
    Persistent patterns can be generated in several ways, but they
    can only be {i used} by the [pa_bitmatch] syntax extension.
@@ -99,7 +113,7 @@ v}
 
    [bitmatch bits with { :name } -> ...]
 
 
    [bitmatch bits with { :name } -> ...]
 
-   You can use named patterns within named patterns.
+   You can nest named patterns within named patterns to any depth.
 
    Currently the use of named patterns is somewhat limited.
    The restrictions are:
 
    Currently the use of named patterns is somewhat limited.
    The restrictions are:
@@ -185,18 +199,18 @@ v}
    the file that your tool reads for input.  By convention,
    locations are bound to name [_loc]:
 
    the file that your tool reads for input.  By convention,
    locations are bound to name [_loc]:
 
-{v
+   {v
    let _loc = Loc.move_line 42 (Loc.mk "input.xml")
    let _loc = Loc.move_line 42 (Loc.mk "input.xml")
-v}
+   v}
 
    Create a pattern field representing a length field which is 8 bits wide,
    bound to the identifier [len]:
 
 
    Create a pattern field representing a length field which is 8 bits wide,
    bound to the identifier [len]:
 
-{v
+   {v
    let len_field = create_pattern_field _loc
    let len_field = set_length_int len_field 8
    let len_field = set_lident_patt len_field "len"
    let len_field = create_pattern_field _loc
    let len_field = set_length_int len_field 8
    let len_field = set_lident_patt len_field "len"
-v}
+   v}
 
    Create a pattern field representing a string of [len*8] bits.
    Note that the use of [<:expr< >>] quotation requires
 
    Create a pattern field representing a string of [len*8] bits.
    Note that the use of [<:expr< >>] quotation requires
@@ -204,36 +218,37 @@ v}
    (see {{:http://brion.inria.fr/gallium/index.php/Reflective_OCaml}this
    page on Reflective OCaml}).
 
    (see {{:http://brion.inria.fr/gallium/index.php/Reflective_OCaml}this
    page on Reflective OCaml}).
 
-{v
+   {v
    let str_field = create_pattern_field _loc
    let str_field = set_length str_field <:expr< len*8 >>
    let str_field = set_lident_patt str_field "str"
    let str_field = set_type_string str_field
    let str_field = create_pattern_field _loc
    let str_field = set_length str_field <:expr< len*8 >>
    let str_field = set_lident_patt str_field "str"
    let str_field = set_type_string str_field
-v}
+   v}
 
    Join the two fields together and name it:
 
 
    Join the two fields together and name it:
 
-{v
-   let named_pattern = "pascal_string", Pattern [len_field; str_field]
-v}
+   {v
+   let pattern = [len_field; str_field]
+   let named_pattern = "pascal_string", Pattern pattern
+   v}
 
    Save it to a file:
 
 
    Save it to a file:
 
-{v
+   {v
    let chan = open_out "output.bmpp" in
    named_to_channel chan named_pattern;
    close_out chan
    let chan = open_out "output.bmpp" in
    named_to_channel chan named_pattern;
    close_out chan
-v}
+   v}
 
    You can now use this pattern in another program like this:
 
 
    You can now use this pattern in another program like this:
 
-{v
+   {v
    open bitmatch "output.bmpp" ;;
    let parse_pascal_string bits =
    open bitmatch "output.bmpp" ;;
    let parse_pascal_string bits =
-     bitmatch bits with
-     | \{ :pascal_string } -> str, len
-     | \{ _ } -> invalid_arg "not a Pascal string"
-v}
+   bitmatch bits with
+   | \{ :pascal_string } -> str, len
+   | \{ _ } -> invalid_arg "not a Pascal string"
+   v}
 
    You can write more than one named pattern to the output file, and
    they will all be loaded at the same time by [open bitmatch ".."]
 
    You can write more than one named pattern to the output file, and
    they will all be loaded at the same time by [open bitmatch ".."]
@@ -274,7 +289,8 @@ and alt =
 
 val string_of_pattern : pattern -> string
 val string_of_constructor : constructor -> string
 
 val string_of_pattern : pattern -> string
 val string_of_constructor : constructor -> string
-val string_of_field : 'a field -> string
+val string_of_pattern_field : patt field -> string
+val string_of_constructor_field : expr field -> string
 (** Convert patterns, constructors or individual fields
     into printable strings for debugging purposes.
 
 (** Convert patterns, constructors or individual fields
     into printable strings for debugging purposes.
 
@@ -315,7 +331,7 @@ val create_pattern_field : loc_t -> patt field
 
     The pattern is unbound, the type is set to [int], bit length to [32],
     endianness to [BigEndian], signedness to unsigned ([false]),
 
     The pattern is unbound, the type is set to [int], bit length to [32],
     endianness to [BigEndian], signedness to unsigned ([false]),
-    and source code location to the [_loc] parameter.
+    source code location to the [_loc] parameter, and no offset expression.
 
     To create a complete field you need to call the [set_*]
     functions.  For example, to create [{ len : 8 : int }]
 
     To create a complete field you need to call the [set_*]
     functions.  For example, to create [{ len : 8 : int }]
@@ -408,6 +424,44 @@ val set_location : 'a field -> loc_t -> 'a field
 (** Sets the source code location of a field.  This is used when
     pa_bitmatch displays error messages. *)
 
 (** Sets the source code location of a field.  This is used when
     pa_bitmatch displays error messages. *)
 
+val set_offset_int : 'a field -> int -> 'a field
+(** Set the offset expression for a field to the given number.
+
+    The effect is that the field [{ _ : 8 : offset(160) }] could
+    be created by calling [set_offset_int field 160]. *)
+
+val set_offset : 'a field -> expr -> 'a field
+(** Set the offset expression for a field to the given expression.
+
+    The effect is that the field [{ _ : 8 : offset(160) }] could
+    be created by calling [set_offset_int field <:expr< 160 >>]. *)
+
+val set_no_offset : 'a field -> 'a field
+(** Remove the offset expression from a field.  The field will
+    follow the previous field, or if it is the first field will
+    be at offset zero. *)
+
+val set_check : 'a field -> expr -> 'a field
+(** Set the check expression for a field to the given expression. *)
+
+val set_no_check : 'a field -> 'a field
+(** Remove the check expression from a field. *)
+
+val set_bind : 'a field -> expr -> 'a field
+(** Set the bind-expression for a field to the given expression. *)
+
+val set_no_bind : 'a field -> 'a field
+(** Remove the bind-expression from a field. *)
+
+val set_save_offset_to : 'a field -> patt -> 'a field
+(** Set the save_offset_to pattern for a field to the given pattern. *)
+
+val set_save_offset_to_lident : 'a field -> string -> 'a field
+(** Set the save_offset_to pattern for a field to identifier. *)
+
+val set_no_save_offset_to : 'a field -> 'a field
+(** Remove the save_offset_to from a field. *)
+
 (** {3 Create constructor fields}
 
     These fields are used in constructors ([BITSTRING]). *)
 (** {3 Create constructor fields}
 
     These fields are used in constructors ([BITSTRING]). *)
@@ -471,3 +525,15 @@ val get_type : 'a field -> field_type
 
 val get_location : 'a field -> loc_t
 (** Get the source code location of a field. *)
 
 val get_location : 'a field -> loc_t
 (** Get the source code location of a field. *)
+
+val get_offset : 'a field -> expr option
+(** Get the offset expression of a field, or [None] if there is none. *)
+
+val get_check : 'a field -> expr option
+(** Get the check expression of a field, or [None] if there is none. *)
+
+val get_bind : 'a field -> expr option
+(** Get the bind expression of a field, or [None] if there is none. *)
+
+val get_save_offset_to : 'a field -> patt option
+(** Get the save_offset_to pattern of a field, or [None] if there is none. *)