1 (** Bitmatch persistent patterns. *)
2 (* Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 {{:#reference}Jump straight to the reference section for
23 documentation on types and functions}.
27 Bitmatch allows you to name sets of fields and reuse them
28 elsewhere. For example if you frequently need to parse
29 Pascal-style strings in the form [length byte + string], then you
30 could name the [{ strlen : 8 : int; str : strlen*8 : string}]
31 pattern and reuse it everywhere by name.
33 These are called {b persistent patterns}.
38 (* Create a persistent pattern called 'pascal' which
39 * matches Pascal-style strings (length byte + string).
43 str : strlen*8 : string }
45 let is_pascal_string bits =
48 printf "matches a Pascal string %s, len %d bytes\n"
54 There are some important things you should know about
55 persistent patterns before you decide to use them:
57 'Persistent' refers to the fact that they can be saved into binary
58 files. However these binary files use OCaml [Marshal] module and
59 depend (sometimes) on the version of OCaml used to generate them
60 and (sometimes) the version of bitmatch used. So your build system
61 should rebuild these files from source when your code is rebuilt.
63 Persistent patterns are syntactic. They work in the same way
64 as cutting and pasting (or [#include]-ing) code. For example
65 if a persistent pattern binds a field named [len], then any
66 uses of [len] following in the surrounding pattern could
69 Programs which generate and manipulate persistent patterns have to
70 link to camlp4. Since camlp4 in OCaml >= 3.10 is rather large, we
71 have placed this code into this separate submodule, so that
72 programs which just use bitmatch don't need to pull in the whole of
73 camlp4. This restriction does not apply to generated code which
74 only uses persistent patterns. If the distinction isn't clear,
75 use [ocamlobjinfo] to look at the dependencies of your [*.cmo]
78 Persistent patterns can be generated in several ways, but they
79 can only be {i used} by the [pa_bitmatch] syntax extension.
80 This means they are purely compile-time constructs. You
81 cannot use them to make arbitrary patterns and run those
82 patterns (not unless your program runs [ocamlc] to make a [*.cmo]
83 file then dynamically links to the [*.cmo] file).
94 {2:reference Reference}
99 type patt = Camlp4.PreCast.Syntax.Ast.patt
100 type expr = Camlp4.PreCast.Syntax.Ast.expr
101 type loc_t = Camlp4.PreCast.Syntax.Ast.Loc.t
106 (** A field in a persistent pattern or persistent constructor. *)
108 type pattern = patt field list
109 (** A persistent pattern (used in [bitmatch] operator), is just a list
110 of pattern fields. *)
112 type constructor = expr field list
113 (** A persistent constructor (used in [BITSTRING] operator), is just a
114 list of constructor fields. *)
118 val string_of_pattern : pattern -> string
119 val string_of_constructor : constructor -> string
120 val string_of_field : 'a field -> string
121 (** Convert patterns, constructors, or individual fields
122 into printable strings for debugging purposes.
124 The strings look similar to the syntax used by bitmatch, but
125 some things cannot be printed fully, eg. length expressions. *)
127 (** {3 Persistence} *)
129 val pattern_to_channel : out_channel -> pattern -> unit
130 val constructor_to_channel : out_channel -> constructor -> unit
131 (** Save a pattern/constructor to an output channel. *)
133 val pattern_to_string : pattern -> string
134 val constructor_to_string : constructor -> string
135 (** Serialize a pattern/constructor to a string. *)
137 val pattern_to_buffer : string -> int -> int -> pattern -> int
138 val constructor_to_buffer : string -> int -> int -> constructor -> int
139 (** Serialize a pattern/constructor to part of a string, return the length. *)
141 val pattern_from_channel : in_channel -> pattern
142 val constructor_from_channel : in_channel -> constructor
143 (** Load a pattern/constructor from an output channel.
145 Note: This is not type safe. The pattern/constructor must
146 have been written out under the same version of OCaml and
147 the same version of bitmatch. *)
149 val pattern_from_string : string -> int -> pattern
150 val constructor_from_string : string -> int -> constructor
151 (** Load a pattern/constructor from a string at offset within the string.
153 Note: This is not type safe. The pattern/constructor must
154 have been written out under the same version of OCaml and
155 the same version of bitmatch. *)
157 (** {3 Create pattern fields}
159 These fields are used in pattern matches ([bitmatch]). *)
161 val create_pattern_field : loc_t -> patt field
162 (** Create a pattern field.
164 The pattern is unbound, the type is set to [int], bit length to [32],
165 endianness to [BigEndian], signedness to unsigned ([false]),
166 and source code location to the [_loc] parameter.
168 To create a complete field you need to call the [set_*]
169 functions. For example, to create [{ len : 8 : int }]
173 let field = create_pattern_field _loc in
174 let field = set_lident_patt field "len" in
175 let field = set_length_int field 8 in
179 val set_lident_patt : patt field -> string -> patt field
180 (** Sets the pattern to the pattern binding an identifier
183 The effect is that the field [{ len : 8 : int }] could
184 be created by calling [set_lident_patt field "len"]. *)
186 val set_int_patt : patt field -> int -> patt field
187 (** Sets the pattern field to the pattern which matches an integer.
189 The effect is that the field [{ 2 : 8 : int }] could
190 be created by calling [set_int_patt field 2]. *)
192 val set_string_patt : patt field -> string -> patt field
193 (** Sets the pattern field to the pattern which matches a string.
195 The effect is that the field [{ "MAGIC" : 8*5 : string }] could
196 be created by calling [set_int_patt field "MAGIC"]. *)
198 val set_unbound_patt : patt field -> patt field
199 (** Sets the pattern field to the unbound pattern (usually written [_]).
201 The effect is that the field [{ _ : 8 : int }] could
202 be created by calling [set_unbound_patt field]. *)
204 val set_patt : patt field -> patt -> patt field
205 (** Sets the pattern field to an arbitrary OCaml pattern match. *)
207 val set_length_int : 'a field -> int -> 'a field
208 (** Sets the length in bits of a field to a constant integer.
210 The effect is that the field [{ len : 8 : string }] could
211 be created by calling [set_length field 8]. *)
213 val set_length : 'a field -> expr -> 'a field
214 (** Sets the length in bits of a field to an OCaml expression.
216 The effect is that the field [{ len : 2*i : string }] could
217 be created by calling [set_length field <:expr< 2*i >>]. *)
219 val set_endian : 'a field -> Bitmatch.endian -> 'a field
220 (** Sets the endianness of a field to the constant endianness.
222 The effect is that the field [{ _ : 16 : bigendian }] could
223 be created by calling [set_endian field Bitmatch.BigEndian]. *)
225 val set_endian_expr : 'a field -> expr -> 'a field
226 (** Sets the endianness of a field to an endianness expression.
228 The effect is that the field [{ _ : 16 : endian(e) }] could
229 be created by calling [set_endian_expr field e]. *)
231 val set_signed : 'a field -> bool -> 'a field
232 (** Sets the signedness of a field to a constant signedness.
234 The effect is that the field [{ _ : 16 : signed }] could
235 be created by calling [set_signed field true]. *)
237 val set_type_int : 'a field -> 'a field
238 (** Sets the type of a field to [int].
240 The effect is that the field [{ _ : 16 : int }] could
241 be created by calling [set_type_int field]. *)
243 val set_type_string : 'a field -> 'a field
244 (** Sets the type of a field to [string].
246 The effect is that the field [{ str : 16 : string }] could
247 be created by calling [set_type_string field]. *)
249 val set_type_bitstring : 'a field -> 'a field
250 (** Sets the type of a field to [bitstring].
252 The effect is that the field [{ _ : 768 : bitstring }] could
253 be created by calling [set_type_bitstring field]. *)
255 val set_location : 'a field -> loc_t -> 'a field
256 (** Sets the source code location of a field. This is used when
257 pa_bitmatch displays error messages. *)
259 (** {3 Create constructor fields}
261 These fields are used in constructors ([BITSTRING]). *)
263 val create_constructor_field : loc_t -> expr field
264 (** Create a constructor field.
266 The defaults are the same as for {!create_pattern_field}
267 except that the expression is initialized to [0].
270 val set_lident_expr : expr field -> string -> expr field
271 (** Sets the expression in a constructor field to an expression
272 which uses the identifier.
274 The effect is that the field [{ len : 8 : int }] could
275 be created by calling [set_lident_expr field "len"]. *)
277 val set_int_expr : expr field -> int -> expr field
278 (** Sets the expression to the value of the integer.
280 The effect is that the field [{ 2 : 8 : int }] could
281 be created by calling [set_int_expr field 2]. *)
283 val set_string_expr : expr field -> string -> expr field
284 (** Sets the expression to the value of the string.
286 The effect is that the field [{ "MAGIC" : 8*5 : string }] could
287 be created by calling [set_int_expr field "MAGIC"]. *)
289 val set_expr : expr field -> expr -> expr field
290 (** Sets the expression field to an arbitrary OCaml expression. *)
294 val get_patt : patt field -> patt
295 (** Get the pattern from a pattern field. *)
297 val get_expr : expr field -> expr
298 (** Get the expression from an expression field. *)
300 val get_length : 'a field -> expr
301 (** Get the length in bits from a field. Note that what is returned
302 is an OCaml expression, since lengths can be non-constant. *)
305 | ConstantEndian of Bitmatch.endian
308 val get_endian : 'a field -> endian_expr
309 (** Get the endianness of a field. This is an {!endian_expr} which
310 could be a constant or an OCaml expression. *)
312 val get_signed : 'a field -> bool
313 (** Get the signedness of a field. *)
315 type field_type = Int | String | Bitstring
317 val get_type : 'a field -> field_type
318 (** Get the type of a field, [Int], [String] or [Bitstring]. *)
320 val get_location : 'a field -> loc_t
321 (** Get the source code location of a field. *)