@@ -45,6 +45,9 @@ type field = {
45
45
off : int ;
46
46
}
47
47
48
+ let field_is_ignored f =
49
+ String. get f.field 0 = '_'
50
+
48
51
type t = {
49
52
name : string ;
50
53
fields : field list ;
@@ -150,154 +153,138 @@ let op_name s op =
150
153
151
154
let op_pvar s op = Ast. pvar (op_name s op)
152
155
let op_evar s op = Ast. evar (op_name s op)
153
- let op_val_typ loc s op ty =
154
- Sig. value (Val. mk (Loc. mkloc (op_name s op) loc) ty)
155
156
156
- let output_get _loc s f =
157
- let m = mode_mod _loc s.endian in
157
+ let get_expr loc s f =
158
+ let m = mode_mod loc s.endian in
158
159
let num x = Ast. int x in
159
160
match f.ty with
160
161
| Buffer (_ , _ ) ->
161
162
let len = width_of_field f in
162
- [% str
163
- let [% p op_pvar s (Op_get f)] =
164
- fun src -> Cstruct. sub src [% e num f.off] [% e num len]
165
-
166
- let [@ ocaml.warning " -32" ] [% p op_pvar s (Op_copy f)] =
167
- fun src -> Cstruct. copy src [% e num f.off] [% e num len]
163
+ [% expr
164
+ fun src -> Cstruct. sub src [% e num f.off] [% e num len]
168
165
]
169
166
| Prim prim ->
170
- [% str
171
- let [ % p op_pvar s ( Op_get f)] = fun v ->
167
+ [% expr
168
+ fun v ->
172
169
[% e match prim with
173
170
| Char -> [% expr Cstruct. get_char v [% e num f.off]]
174
171
| UInt8 -> [% expr Cstruct. get_uint8 v [% e num f.off]]
175
172
| UInt16 -> [% expr [% e m " get_uint16" ] v [% e num f.off]]
176
173
| UInt32 -> [% expr [% e m " get_uint32" ] v [% e num f.off]]
177
174
| UInt64 -> [% expr [% e m " get_uint64" ] v [% e num f.off]]]]
178
175
179
- let output_get loc s f =
180
- (output_get loc s f) [@ metaloc loc]
181
-
182
176
let type_of_int_field = function
183
177
| Char -> [% type : char ]
184
178
| UInt8 -> [% type : Cstruct. uint8]
185
179
| UInt16 -> [% type : Cstruct. uint16]
186
180
| UInt32 -> [% type : Cstruct. uint32]
187
181
| UInt64 -> [% type : Cstruct. uint64]
188
182
189
- let type_of_int_field _loc x =
190
- type_of_int_field x [@ metaloc loc]
191
-
192
- let output_get_sig loc s f =
193
- match f.ty with
194
- | Buffer (_ ,_ ) ->
195
- [
196
- op_val_typ loc s (Op_get f) [% type : Cstruct. t -> Cstruct. t];
197
- op_val_typ loc s (Op_copy f) [% type : Cstruct. t -> string ]
198
- ]
199
- | Prim prim ->
200
- let retf = type_of_int_field loc prim in
201
- [
202
- op_val_typ loc s (Op_get f) [% type : Cstruct. t -> [% t retf]]
203
- ]
204
-
205
- let output_get_sig _loc s f =
206
- output_get_sig _loc s f [@ metaloc _loc]
207
-
208
- let output_set _loc s f =
209
- let m = mode_mod _loc s.endian in
183
+ let set_expr loc s f =
184
+ let m = mode_mod loc s.endian in
210
185
let num x = Ast. int x in
211
186
match f.ty with
212
187
| Buffer (_ ,_ ) ->
213
188
let len = width_of_field f in
214
- [% str
215
- let [@ ocaml.warning " -32" ] [% p op_pvar s (Op_set f)] = fun src srcoff dst ->
216
- Cstruct. blit_from_string src srcoff dst [% e num f.off] [% e num len]
217
-
218
- let [@ ocaml.warning " -32" ] [% p op_pvar s (Op_blit f)] = fun src srcoff dst ->
219
- Cstruct. blit src srcoff dst [% e num f.off] [% e num len]]
189
+ [% expr
190
+ fun src srcoff dst ->
191
+ Cstruct. blit_from_string src srcoff dst [% e num f.off] [% e num len]]
220
192
| Prim prim ->
221
- [% str
222
- let [@ ocaml.warning " -32" ] [% p op_pvar s (Op_set f)] = fun v x ->
193
+ [% expr fun v x ->
223
194
[% e match prim with
224
195
| Char -> [% expr Cstruct. set_char v [% e num f.off] x]
225
196
| UInt8 -> [% expr Cstruct. set_uint8 v [% e num f.off] x]
226
197
| UInt16 -> [% expr [% e m " set_uint16" ] v [% e num f.off] x]
227
198
| UInt32 -> [% expr [% e m " set_uint32" ] v [% e num f.off] x]
228
199
| UInt64 -> [% expr [% e m " set_uint64" ] v [% e num f.off] x]]]
229
200
230
- let output_set _loc s f =
231
- output_set _loc s f [@ metaloc _loc]
232
-
233
- let output_set_sig loc s f =
201
+ let type_of_set f =
234
202
match f.ty with
235
203
| Buffer (_ ,_ ) ->
236
- [
237
- op_val_typ loc s (Op_set f) [% type : string -> int -> Cstruct. t -> unit ];
238
- op_val_typ loc s (Op_blit f) [% type : Cstruct. t -> int -> Cstruct. t -> unit ]
239
- ] [@ metaloc loc]
204
+ [% type : string -> int -> Cstruct. t -> unit ]
240
205
| Prim prim ->
241
- let retf = type_of_int_field loc prim in
242
- [
243
- op_val_typ loc s (Op_set f) [% type : Cstruct. t -> [% t retf] -> unit ]
244
- ] [@ metaloc loc]
245
-
246
- let output_sizeof _loc s =
247
- [% stri
248
- let [% p op_pvar s Op_sizeof ] = [% e Ast. int s.len]] [@ metaloc _loc]
249
-
250
- let output_sizeof_sig loc s =
251
- op_val_typ loc s Op_sizeof [% type : int ]
252
-
253
- let output_hexdump _loc s =
254
- let hexdump =
255
- List. fold_left (fun a f ->
256
- let get_f = op_evar s (Op_get f) in
257
- [% expr
258
- [% e a]; Buffer. add_string _buf [% e Ast. str (" " ^ f.field^ " = " )];
259
- [% e match f.ty with
260
- | Prim Char ->
261
- [% expr Printf. bprintf _buf " %c\n " ([% e get_f] v)]
262
- | Prim (UInt8 |UInt16 ) ->
263
- [% expr Printf. bprintf _buf " 0x%x\n " ([% e get_f] v)]
264
- | Prim UInt32 ->
265
- [% expr Printf. bprintf _buf " 0x%lx\n " ([% e get_f] v)]
266
- | Prim UInt64 ->
267
- [% expr Printf. bprintf _buf " 0x%Lx\n " ([% e get_f] v)]
268
- | Buffer (_ ,_ ) ->
269
- [% expr Printf. bprintf _buf " <buffer %s>"
270
- [% e Ast. str (field_to_string f)];
271
- Cstruct. hexdump_to_buffer _buf ([% e get_f] v)]
272
- ]]
273
- ) (Ast. unit () ) s.fields
274
- in
275
- [
276
- [% stri
277
- let [% p op_pvar s Op_hexdump_to_buffer ] = fun _buf v ->
278
- [% e hexdump]];
279
- [% stri
280
- let [@ ocaml.warning " -32" ] [% p op_pvar s Op_hexdump ] = fun v ->
281
- let _buf = Buffer. create 128 in
282
- Buffer. add_string _buf [% e Ast. str (s.name ^ " = {\n " )];
283
- [% e op_evar s Op_hexdump_to_buffer ] _buf v;
284
- print_endline (Buffer. contents _buf);
285
- print_endline " }"
286
- ]
287
- ] [@ metaloc _loc]
288
-
289
- let output_hexdump_sig loc s =
290
- [
291
- op_val_typ loc s Op_hexdump_to_buffer [% type : Buffer. t -> Cstruct. t -> unit ];
292
- op_val_typ loc s Op_hexdump [% type : Cstruct. t -> unit ];
206
+ let retf = type_of_int_field prim in
207
+ [% type : Cstruct. t -> [% t retf] -> unit ]
208
+
209
+ let hexdump_expr s =
210
+ [% expr fun v ->
211
+ let buf = Buffer. create 128 in
212
+ Buffer. add_string buf [% e Ast. str (s.name ^ " = {\n " )];
213
+ [% e op_evar s Op_hexdump_to_buffer ] buf v;
214
+ print_endline (Buffer. contents buf);
215
+ print_endline " }"
293
216
]
294
217
295
- let output_struct_one_endian _loc s =
296
- (* Generate functions of the form {get/set}_<struct>_<field> *)
297
- let expr = List. fold_left (fun a f ->
298
- a @ output_get _loc s f @ output_set _loc s f
299
- ) [output_sizeof _loc s] s.fields
300
- in expr @ output_hexdump _loc s
218
+ let hexdump_to_buffer_expr s =
219
+ let prim_format_string = function
220
+ | Char -> [% expr " %c\n " ]
221
+ | UInt8 | UInt16 -> [% expr " 0x%x\n " ]
222
+ | UInt32 -> [% expr " 0x%lx\n " ]
223
+ | UInt64 -> [% expr " 0x%Lx\n " ]
224
+ in
225
+ let hexdump_field f =
226
+ if field_is_ignored f then
227
+ [% expr () ]
228
+ else
229
+ let get_f = op_evar s (Op_get f) in
230
+ let expr =
231
+ match f.ty with
232
+ | Prim p ->
233
+ [% expr Printf. bprintf buf [% e prim_format_string p] ([% e get_f] v)]
234
+ | Buffer (_ ,_ ) ->
235
+ [% expr Printf. bprintf buf " <buffer %s>" [% e Ast. str (field_to_string f)];
236
+ Cstruct. hexdump_to_buffer buf ([% e get_f] v)]
237
+ in
238
+ [% expr
239
+ Printf. bprintf buf " %s = " [% e Ast. str f.field];
240
+ [% e expr]]
241
+ in
242
+ [% expr fun buf v -> [% e Ast. sequence (List. map hexdump_field s.fields)]]
243
+
244
+ let op_expr loc s = function
245
+ | Op_sizeof -> Ast. int s.len
246
+ | Op_hexdump -> hexdump_expr s
247
+ | Op_hexdump_to_buffer -> hexdump_to_buffer_expr s
248
+ | Op_get f -> get_expr loc s f
249
+ | Op_set f -> set_expr loc s f
250
+ | Op_copy f ->
251
+ let len = width_of_field f in
252
+ [% expr fun src -> Cstruct. copy src [% e Ast. int f.off] [% e Ast. int len] ]
253
+ | Op_blit f ->
254
+ let len = width_of_field f in
255
+ [% expr fun src srcoff dst ->
256
+ Cstruct. blit src srcoff dst [% e Ast. int f.off] [% e Ast. int len]]
257
+
258
+ let field_ops_for f =
259
+ if field_is_ignored f then
260
+ []
261
+ else
262
+ let if_buffer x =
263
+ match f.ty with
264
+ | Buffer (_ ,_ ) -> [x]
265
+ | Prim _ -> []
266
+ in
267
+ List. concat
268
+ [ [Op_get f]
269
+ ; if_buffer (Op_copy f)
270
+ ; [Op_set f]
271
+ ; if_buffer (Op_blit f)
272
+ ]
273
+
274
+ let ops_for s =
275
+ ( [Op_sizeof ]
276
+ @ List. concat (List. map field_ops_for s.fields)
277
+ @ [Op_hexdump_to_buffer ;
278
+ Op_hexdump ;
279
+ ])
280
+
281
+ (* * Generate functions of the form {get/set}_<struct>_<field> *)
282
+ let output_struct_one_endian loc s =
283
+ List. map
284
+ (fun op ->
285
+ [% stri let [@ ocaml.warning " -32" ] [% p op_pvar s op] =
286
+ [% e op_expr loc s op]])
287
+ (ops_for s)
301
288
302
289
let output_struct _loc s =
303
290
match s.endian with
@@ -315,12 +302,32 @@ let output_struct _loc s =
315
302
]
316
303
| _ -> output_struct_one_endian _loc s
317
304
318
- let output_struct_sig _loc s =
319
- (* Generate signaturs of the form {get/set}_<struct>_<field> *)
320
- let expr = List. fold_left (fun a f ->
321
- a @ output_get_sig _loc s f @ output_set_sig _loc s f
322
- ) [output_sizeof_sig _loc s] s.fields
323
- in expr @ output_hexdump_sig _loc s
305
+ let type_of_get f =
306
+ match f.ty with
307
+ | Buffer (_ ,_ ) ->
308
+ [% type : Cstruct. t -> Cstruct. t]
309
+ | Prim prim ->
310
+ let retf = type_of_int_field prim in
311
+ [% type : Cstruct. t -> [% t retf]]
312
+
313
+ let op_typ = function
314
+ | Op_sizeof -> [% type : int ]
315
+ | Op_hexdump_to_buffer -> [% type : Buffer. t -> Cstruct. t -> unit ]
316
+ | Op_hexdump -> [% type : Cstruct. t -> unit ]
317
+ | Op_get f -> type_of_get f
318
+ | Op_set f -> type_of_set f
319
+ | Op_copy _ -> [% type : Cstruct. t -> string ]
320
+ | Op_blit _ -> [% type : Cstruct. t -> int -> Cstruct. t -> unit ]
321
+
322
+ (* * Generate signatures of the form {get/set}_<struct>_<field> *)
323
+ let output_struct_sig loc s =
324
+ List. map
325
+ (fun op ->
326
+ Sig. value
327
+ (Val. mk
328
+ (Loc. mkloc (op_name s op) loc)
329
+ (op_typ op)))
330
+ (ops_for s)
324
331
325
332
let output_enum _loc name fields width ~sexp =
326
333
let intfn,pattfn = match ty_of_string width with
0 commit comments