Fix documentation for how to compile using camlp4 directly.
[ocaml-bitstring.git] / bitmatch_persistent.mli
index f390970..8c97a34 100644 (file)
@@ -53,6 +53,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 +87,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 +112,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 +198,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 +217,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 +288,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 +330,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 +423,23 @@ 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. *)
+
 (** {3 Create constructor fields}
 
     These fields are used in constructors ([BITSTRING]). *)
 (** {3 Create constructor fields}
 
     These fields are used in constructors ([BITSTRING]). *)
@@ -471,3 +503,6 @@ 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. *)