Commit | Line | Data |
---|---|---|
feec80c3 C |
1 | (****************************************************************************** |
2 | * Sexplib * | |
3 | * * | |
4 | * Copyright (C) 2005- Jane Street Holding, LLC * | |
5 | * Contact: opensource@janestreet.com * | |
6 | * WWW: http://www.janestreet.com/ocaml * | |
7 | * Author: Markus Mottl * | |
8 | * * | |
9 | * This library is free software; you can redistribute it and/or * | |
10 | * modify it under the terms of the GNU Lesser General Public * | |
11 | * License as published by the Free Software Foundation; either * | |
12 | * version 2 of the License, or (at your option) any later version. * | |
13 | * * | |
14 | * This library is distributed in the hope that it will be useful, * | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * | |
17 | * Lesser General Public License for more details. * | |
18 | * * | |
19 | * You should have received a copy of the GNU Lesser General Public * | |
20 | * License along with this library; if not, write to the Free Software * | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * | |
22 | * * | |
23 | ******************************************************************************) | |
24 | ||
25 | (** Sexp_intf: interface specification for handling S-expressions (I/O, etc.) *) | |
26 | ||
27 | open Format | |
28 | open Bigarray | |
29 | ||
30 | module type S = sig | |
31 | ||
32 | (** Type of S-expressions *) | |
33 | type t = Type.t = Atom of string | List of t list | |
34 | ||
35 | (** Type of bigstrings *) | |
36 | type bigstring = (char, int8_unsigned_elt, c_layout) Array1.t | |
37 | ||
38 | ||
39 | (** {6 Defaults} *) | |
40 | ||
41 | val default_indent : int ref | |
42 | (** [default_indent] reference to default indentation level for | |
43 | human-readable conversions. Initialisation value: 2. *) | |
44 | ||
45 | ||
46 | (** {6 S-expression size} *) | |
47 | ||
48 | val size : t -> int * int | |
49 | (** [size sexp] @return [(n_atoms, n_chars)], where [n_atoms] is | |
50 | the number of atoms in S-expression [sexp], and [n_chars] is the | |
51 | number of characters in the atoms of the S-expression. *) | |
52 | ||
53 | ||
54 | (** {6 Scan functions} *) | |
55 | ||
56 | val scan_sexp : ?buf : Buffer.t -> Lexing.lexbuf -> t | |
57 | (** [scan_sexp ?buf lexbuf] scans an S-expression from lex buffer | |
58 | [lexbuf] using the optional string buffer [buf] for storing | |
59 | intermediate strings. *) | |
60 | ||
61 | val scan_sexps : ?buf : Buffer.t -> Lexing.lexbuf -> t list | |
62 | (** [scan_sexps ?buf lexbuf] reads a list of whitespace separated | |
63 | S-expressions from lex buffer [lexbuf] using the optional string | |
64 | buffer [buf] for storing intermediate strings. *) | |
65 | ||
66 | val scan_iter_sexps : | |
67 | ?buf : Buffer.t -> f : (t -> unit) -> Lexing.lexbuf -> unit | |
68 | (** [scan_iter_sexps ?buf ~f lexbuf] iterates over all whitespace | |
69 | separated S-expressions scanned from lex buffer [lexbuf] using | |
70 | function [f], and the optional string buffer [buf] for storing | |
71 | intermediate strings. *) | |
72 | ||
73 | val scan_fold_sexps : | |
74 | ?buf : Buffer.t -> f : ('a -> t -> 'a) -> init : 'a -> Lexing.lexbuf -> 'a | |
75 | (** [scan_fold_sexps ?buf ~f ~init lexbuf] folds over all whitespace | |
76 | separated S-expressions scanned from lex buffer [lexbuf] using | |
77 | function [f], initial state [init], and the optional string buffer | |
78 | [buf] for storing intermediate strings. *) | |
79 | ||
80 | val scan_sexps_conv : | |
81 | ?buf : Buffer.t -> f : (t -> 'a) -> Lexing.lexbuf -> 'a list | |
82 | (** [scan_sexps_conv ?buf ~f lexbuf] maps all whitespace separated | |
83 | S-expressions scanned from lex buffer [lexbuf] to some list using | |
84 | function [f], and the optional string buffer [buf] for storing | |
85 | intermediate strings. *) | |
86 | ||
87 | ||
88 | (** {6 Type and exception definitions for (partial) parsing} *) | |
89 | ||
90 | module Parse_pos : sig | |
91 | (** Position information after complete parse *) | |
92 | type t = Pre_sexp.Parse_pos.t = | |
93 | private | |
94 | { | |
95 | mutable text_line : int; (** Line position in parsed text *) | |
96 | mutable text_char : int; (** Character position in parsed text *) | |
97 | mutable global_offset : int; (** Global/logical offset *) | |
98 | mutable buf_pos : int; (** Read position in string buffer *) | |
99 | } | |
100 | ||
101 | val create : | |
102 | ?text_line : int -> ?text_char : int -> | |
103 | ?buf_pos : int -> ?global_offset : int -> unit -> t | |
104 | (** [create ?text_line ?text_char ?buf_pos ?global_offset ()] @return | |
105 | a parse position with the given parameters. | |
106 | ||
107 | @param text_line default = [1] | |
108 | @param text_char default = [0] | |
109 | @param global_offset default = [0] | |
110 | @param buf_pos default = [0] | |
111 | *) | |
112 | ||
113 | val with_buf_pos : t -> int -> t | |
114 | (** [with_buf_pos t pos] @return a copy of the parse position [t] where | |
115 | [buf_pos] is set to [pos]. *) | |
116 | end | |
117 | ||
118 | (** Type of result from calling {!Sexp.parse}. *) | |
119 | type ('a, 't) parse_result = ('a, 't) Pre_sexp.parse_result = | |
120 | | Done of 't * Parse_pos.t (** [Done (t, parse_pos)] finished parsing | |
121 | an S-expression. Current parse position | |
122 | is [parse_pos]. *) | |
123 | | Cont of bool * ('a, 't) parse_fun | |
124 | (** [Cont (ws_only, parse_fun)] met the end of input before completely | |
125 | parsing an S-expression. The user has to call [parse_fun] to | |
126 | continue parsing the S-expression in another buffer. If [ws_only] | |
127 | is true, only whitespace has been parsed so far (or comments!). | |
128 | NOTE: the continuation may only be called once and will raise | |
129 | [Failure] otherwise! *) | |
130 | ||
131 | (** Type of parsing functions with given offsets and lengths. *) | |
132 | and ('a, 't) parse_fun = pos : int -> len : int -> 'a -> ('a, 't) parse_result | |
133 | ||
134 | (** Module for parsing S-expressions annotated with location information *) | |
135 | module Annotated : sig | |
136 | (** Position information for annotated S-expressions *) | |
137 | type pos = Pre_sexp.Annotated.pos = { | |
138 | line : int; | |
139 | col : int; | |
140 | offset : int; | |
141 | } | |
142 | ||
143 | (** Range information for annotated S-expressions *) | |
144 | type range = Pre_sexp.Annotated.range = { start_pos : pos; end_pos : pos } | |
145 | ||
146 | (** S-expression annotated with location information *) | |
147 | type t = Pre_sexp.Annotated.t = | |
148 | | Atom of range * Type.t | |
149 | | List of range * t list * Type.t | |
150 | ||
151 | (** Type of conversion results of annotated S-expressions. *) | |
152 | type 'a conv = [ `Result of 'a | `Error of exn * t ] | |
153 | ||
154 | (** Exception associated with conversion errors. First argument describes | |
155 | the location, the second the reason. *) | |
156 | exception Conv_exn of string * exn | |
157 | ||
158 | (** Stack used by annotation parsers *) | |
159 | type stack = Pre_sexp.Annotated.stack = { | |
160 | mutable positions : pos list; | |
161 | mutable stack : t list list; | |
162 | } | |
163 | ||
164 | val get_sexp : t -> Type.t | |
165 | (** [get_sexp annot_sexp] @return S-expression associated with annotated | |
166 | S-expression [annot_sexp]. *) | |
167 | ||
168 | val get_range : t -> range | |
169 | (** [get_range annot_sexp] @return the range associated with annotated | |
170 | S-expression [annot_sexp]. *) | |
171 | ||
172 | val find_sexp : t -> Type.t -> t option | |
173 | (** [find_sexp annot_sexp sexp] @return [Some res] where [res] is the | |
174 | annotated S-expression that is physically equivalent to [sexp] in | |
175 | [annot_sexp], or [None] if there is no such S-expression. *) | |
176 | ||
177 | ||
178 | (** {6 Annotated (partial) parsing} *) | |
179 | ||
180 | val parse : | |
181 | ?parse_pos : Parse_pos.t -> ?len : int -> string | |
182 | -> (string, t) parse_result | |
183 | (** [parse ?parse_pos ?len str] same as {!parse}, but returns an | |
184 | S-expression annotated with location information. *) | |
185 | ||
186 | val parse_bigstring : | |
187 | ?parse_pos : Parse_pos.t -> ?len : int -> bigstring | |
188 | -> (bigstring, t) parse_result | |
189 | (** [parse_bigstring ?parse_pos ?len str] same as {!parse_bigstring}, | |
190 | but returns an S-expression annotated with location information. *) | |
191 | ||
192 | val input_sexp : ?parse_pos : Parse_pos.t -> in_channel -> t | |
193 | (** [input_sexp ?parse_pos ic] like {!input_sexp}, but returns an | |
194 | annotated S-expression instead. *) | |
195 | ||
196 | val input_sexps : | |
197 | ?parse_pos : Parse_pos.t -> ?buf : string -> in_channel -> t list | |
198 | (** [input_sexps ?parse_pos ?buf ic] like {!input_sexps}, but returns | |
199 | a list of annotated S-expressions. *) | |
200 | ||
201 | val input_rev_sexps : | |
202 | ?parse_pos : Parse_pos.t -> ?buf : string -> in_channel -> t list | |
203 | (** [input_sexps ?parse_pos ?buf ic] like {!input_rev_sexps}, but | |
204 | returns a list of annotated S-expressions. *) | |
205 | ||
206 | ||
207 | (** {6 Loading of annotated S-expressions} *) | |
208 | ||
209 | (** NOTE: these functions should only be used if an annotated S-expression | |
210 | is required. *) | |
211 | ||
212 | val load_sexp : ?strict : bool -> ?buf : string -> string -> t | |
213 | (** [load_sexp ?strict ?buf file] like {!load_sexp}, but returns an | |
214 | annotated S-expression. *) | |
215 | ||
216 | val load_sexps : ?buf : string -> string -> t list | |
217 | (** [load_sexps ?buf file] like {!load_sexps}, but returns a list of | |
218 | annotated S-expressions. *) | |
219 | ||
220 | val load_rev_sexps : ?buf : string -> string -> t list | |
221 | (** [load_rev_sexps ?buf file] like {!load_rev_sexps}, but returns a | |
222 | list of annotated S-expressions. *) | |
223 | ||
224 | ||
225 | (** {6 String and bigstring conversions} *) | |
226 | ||
227 | val of_string : string -> t | |
228 | (** [of_string str] same as {!of_string}, but returns an annotated | |
229 | S-expression. *) | |
230 | ||
231 | val of_bigstring : bigstring -> t | |
232 | (** [of_bigstring bstr] same as {!of_string}, but operates on bigstrings. *) | |
233 | ||
234 | ||
235 | (** Converters using annotations for determining error locations *) | |
236 | ||
237 | val conv : (Type.t -> 'a) -> t -> 'a conv | |
238 | (** [conv f annot_sexp] converts the S-expression associated with | |
239 | annotated S-expression [annot_sexp] using [f]. @return [`Result | |
240 | res] on success, or [`Error (exn, sub_annot_sexp)] otherwise, where | |
241 | [exn] is the exception associated with the conversion error, and | |
242 | [sub_annot_sexp] is the annotated S-expression on which conversion | |
243 | failed. *) | |
244 | ||
245 | val get_conv_exn : file : string -> exc : exn -> t -> exn | |
246 | (** [get_conv_exn ~file ~exc annot_sexp] @return the exception that | |
247 | would be raised for a given [file] and exception [exc] | |
248 | if conversion had failed on annotated S-expression [annot_sexp]. | |
249 | The format of the exception message is "file:line:col" *) | |
250 | end | |
251 | ||
252 | (** Type of state maintained during parsing *) | |
253 | type 't parse_state = 't Pre_sexp.parse_state = | |
254 | private | |
255 | { | |
256 | parse_pos : Parse_pos.t; (** Current parse position *) | |
257 | mutable pstack : 't; (** Stack of found S-expression lists *) | |
258 | pbuf : Buffer.t; (** Current atom buffer *) | |
259 | } | |
260 | ||
261 | (** Type of parse errors *) | |
262 | type parse_error = Pre_sexp.parse_error = | |
263 | { | |
264 | location : string; (** Function in which the parse failed *) | |
265 | err_msg : string; (** Reason why parsing failed *) | |
266 | parse_state : | |
267 | [ | |
268 | | `Sexp of t list list parse_state | |
269 | | `Annot of Annotated.stack parse_state | |
270 | ] | |
271 | (** State of parser *) | |
272 | } | |
273 | ||
274 | (** Exception raised during partial parsing *) | |
275 | exception Parse_error of parse_error | |
276 | ||
277 | ||
278 | (** {6 Unannotated (partial) parsing} *) | |
279 | ||
280 | val parse : | |
281 | ?parse_pos : Parse_pos.t -> ?len : int -> string -> (string, t) parse_result | |
282 | (** [parse ?parse_pos ?len str] (partially) parses an S-expression in | |
283 | string buffer [str] starting out with position information provided in | |
284 | [parse_pos] and reading at most [len] characters. To parse a single | |
285 | atom that is not delimited by whitespace it is necessary to call this | |
286 | function a second time with the returned continuation, and a dummy | |
287 | buffer that contains whitespace. | |
288 | ||
289 | @param parse_pos default = [Parse_pos.create ()] | |
290 | @param len default = [String.length str - parse_pos.Parse_pos.buf_pos] | |
291 | *) | |
292 | ||
293 | val parse_bigstring : | |
294 | ?parse_pos : Parse_pos.t -> ?len : int -> bigstring | |
295 | -> (bigstring, t) parse_result | |
296 | (** [parse_bigstring ?parse_pos ?len str] same as {!parse}, but operates on | |
297 | bigstrings. *) | |
298 | ||
299 | val input_sexp : ?parse_pos : Parse_pos.t -> in_channel -> t | |
300 | (** [input_sexp ?parse_pos ic] parses an S-expression from input channel | |
301 | [ic] using initial position information in [parse_pos]. NOTE: this | |
302 | function is not as fast on files as {!Sexp.load_sexp}, and is also | |
303 | slightly slower than the scan-functions. But it is guaranteed that | |
304 | [input_sexp] is only going to read data parseable as an S-expression. | |
305 | Thus, subsequent input functions will see the data immediately | |
306 | following it. | |
307 | ||
308 | @param parse_pos default = [Parse_pos.create ()] | |
309 | *) | |
310 | ||
311 | val input_sexps : | |
312 | ?parse_pos : Parse_pos.t -> ?buf : string -> in_channel -> t list | |
313 | (** [input_sexps ?parse_pos ?buf ic] parses whitespace separated | |
314 | S-expressions from input channel [ic] until EOF is reached. Faster than | |
315 | the scan-functions. | |
316 | ||
317 | @param parse_pos default = [Parse_pos.create ()] | |
318 | *) | |
319 | ||
320 | val input_rev_sexps : | |
321 | ?parse_pos : Parse_pos.t -> ?buf : string -> in_channel -> t list | |
322 | (** [input_rev_sexps ?parse_pos ?buf ic] same as {!Sexp.input_sexps}, | |
323 | but returns a reversed list of S-expressions, which is slightly more | |
324 | efficient. *) | |
325 | ||
326 | ||
327 | (** {6 Loading of (converted) S-expressions} *) | |
328 | ||
329 | val load_sexp : ?strict : bool -> ?buf : string -> string -> t | |
330 | (** [load_sexp ?strict ?buf file] reads one S-expression from [file] using | |
331 | buffer [buf] for storing intermediate data. Faster than the | |
332 | scan-functions. | |
333 | ||
334 | @raise Parse_error if the S-expression is unparseable. | |
335 | ||
336 | @raise Failure if parsing reached the end of file before one S-expression | |
337 | could be read. | |
338 | ||
339 | @raise Failure if [strict] is true and there is more than one | |
340 | S-expression in the file. | |
341 | ||
342 | @param strict default = [true] | |
343 | *) | |
344 | ||
345 | val load_sexps : ?buf : string -> string -> t list | |
346 | (** [load_sexps ?buf file] reads a list of whitespace separated S-expressions | |
347 | from [file] using buffer [buf] for storing intermediate data. | |
348 | Faster than the scan-functions. | |
349 | ||
350 | @raise Parse_error if there is unparseable data in the file. | |
351 | ||
352 | @raise Failure if parsing reached the end of file before the last | |
353 | S-expression could be fully read. | |
354 | *) | |
355 | ||
356 | val load_rev_sexps : ?buf : string -> string -> t list | |
357 | (** [load_rev_sexps ?buf file] same as {!Sexp.load_sexps}, but returns a | |
358 | reversed list of S-expressions, which is slightly more efficient. *) | |
359 | ||
360 | val load_sexp_conv : | |
361 | ?strict : bool -> ?buf : string -> string -> (t -> 'a) -> 'a Annotated.conv | |
362 | (** [load_sexp_conv ?strict ?buf file f] like {!Sexp.load_sexp}, but | |
363 | performs a conversion on the fly using [f]. Performance is equivalent | |
364 | to executing {!Sexp.load_sexp} and performing conversion when there | |
365 | are no errors. In contrast to the plain S-expression loader, this | |
366 | function not only performs the conversion, it will give exact error | |
367 | ranges for conversion errors. | |
368 | ||
369 | @raise Parse_error if there is unparseable data in the file. | |
370 | ||
371 | @raise Failure if parsing reached the end of file before the last | |
372 | S-expression could be fully read. | |
373 | *) | |
374 | ||
375 | val load_sexp_conv_exn : | |
376 | ?strict : bool -> ?buf : string -> string -> (t -> 'a) -> 'a | |
377 | (** [load_sexp_conv_exn ?strict ?buf file f] like {!load_sexp_conv}, | |
378 | but returns the converted value or raises [Of_sexp_error] with exact | |
379 | location information in the case of a conversion error. *) | |
380 | ||
381 | val load_sexps_conv : | |
382 | ?buf : string -> string -> (t -> 'a) -> 'a Annotated.conv list | |
383 | (** [load_sexps_conv ?buf file f] like {!Sexp.load_sexps}, but performs | |
384 | a conversion on the fly using [f]. Performance is equivalent to | |
385 | executing {!Sexp.load_sexps} and performing conversion when there | |
386 | are no errors. In contrast to the plain S-expression loader, this | |
387 | function not only performs the conversion, it will give exact error | |
388 | ranges for conversion errors. | |
389 | ||
390 | @raise Parse_error if there is unparseable data in the file. | |
391 | ||
392 | @raise Failure if parsing reached the end of file before the last | |
393 | S-expression could be fully read. | |
394 | *) | |
395 | ||
396 | val load_sexps_conv_exn : ?buf : string -> string -> (t -> 'a) -> 'a list | |
397 | (** [load_sexps_conv_exn ?buf file f] like {!load_sexps_conv}, but returns | |
398 | the converted value or raises [Of_sexp_error] with exact location | |
399 | information in the case of a conversion error. *) | |
400 | ||
401 | ||
402 | (** {6 Output of S-expressions to I/O-channels} *) | |
403 | ||
404 | (** NOTE: for performance reasons these output functions may need to | |
405 | allocate large strings to write out huge S-expressions. This may | |
406 | cause problems on 32-bit platforms. If you think that you may need to | |
407 | write huge S-expressions on such platforms, you might want to use the | |
408 | pretty-printers that write to formatters instead (see further below). *) | |
409 | ||
410 | val output_hum : out_channel -> t -> unit | |
411 | (** [output_hum oc sexp] outputs S-expression [sexp] to output channel | |
412 | [oc] in human readable form. *) | |
413 | ||
414 | val output_hum_indent : int -> out_channel -> t -> unit | |
415 | (** [output_hum_indent indent oc sexp] outputs S-expression [sexp] | |
416 | to output channel [oc] in human readable form using indentation level | |
417 | [indent]. | |
418 | *) | |
419 | ||
420 | val output_mach : out_channel -> t -> unit | |
421 | (** [output_mach oc sexp] outputs S-expression [sexp] to output channel | |
422 | [oc] in machine readable (i.e. most compact) form. *) | |
423 | ||
424 | val output : out_channel -> t -> unit | |
425 | (** [output oc sexp] same as [output_mach]. *) | |
426 | ||
427 | ||
428 | (** {6 Output of S-expressions to file} *) | |
429 | ||
430 | (** All save-functions write to a temporary file before moving it into | |
431 | place to avoid intermittent garbling of existing files, which may | |
432 | cause problems for other processes that try to read. *) | |
433 | ||
434 | val save_hum : ?perm : int -> string -> t -> unit | |
435 | (** [save_hum ?perm file sexp] outputs S-expression [sexp] to [file] in human | |
436 | readable form. | |
437 | ||
438 | @param perm default = umask | |
439 | *) | |
440 | ||
441 | val save_mach : ?perm : int -> string -> t -> unit | |
442 | (** [save_mach ?perm file sexp] outputs S-expression [sexp] to [file] | |
443 | in machine readable (i.e. most compact) form. | |
444 | ||
445 | @param perm default = umask | |
446 | *) | |
447 | ||
448 | val save : ?perm : int -> string -> t -> unit | |
449 | (** [save ?perm file sexp] same as {!save_mach}. *) | |
450 | ||
451 | val save_sexps_hum : ?perm : int -> string -> t list -> unit | |
452 | (** [save_sexps_hum ?perm file sexps] outputs S-expression list [sexps] to | |
453 | [file] in human readable form, each sexp being followed by a newline. | |
454 | ||
455 | @param perm default = umask | |
456 | *) | |
457 | ||
458 | val save_sexps_mach : ?perm : int -> string -> t list -> unit | |
459 | (** [save_sexps_mach ?perm file sexps] outputs S-expression list [sexps] to | |
460 | [file] in machine readable form, each sexp being followed by a | |
461 | newline. | |
462 | ||
463 | @param perm default = umask | |
464 | *) | |
465 | ||
466 | val save_sexps : ?perm : int -> string -> t list -> unit | |
467 | (** [save_sexps ?perm file sexp] same as {!save_sexps_mach}. *) | |
468 | ||
469 | ||
470 | (** {6 Output of S-expressions to formatters} *) | |
471 | ||
472 | val pp_hum : formatter -> t -> unit | |
473 | (** [pp_hum ppf sexp] outputs S-expression [sexp] to formatter [ppf] | |
474 | in human readable form. *) | |
475 | ||
476 | val pp_hum_indent : int -> formatter -> t -> unit | |
477 | (** [pp_hum_indent n ppf sexp] outputs S-expression [sexp] to formatter | |
478 | [ppf] in human readable form and indentation level [n]. *) | |
479 | ||
480 | val pp_mach : formatter -> t -> unit | |
481 | (** [pp_mach ppf sexp] outputs S-expression [sexp] to formatter [ppf] | |
482 | in machine readable (i.e. most compact) form. *) | |
483 | ||
484 | val pp : formatter -> t -> unit | |
485 | (** [pp ppf sexp] same as [pp_mach]. *) | |
486 | ||
487 | ||
488 | (** {6 String and bigstring conversions} *) | |
489 | ||
490 | (** Module encapsulating the exception raised by string converters when | |
491 | type conversions fail. *) | |
492 | module Of_string_conv_exn : sig | |
493 | type t = { exc : exn; sexp : Type.t; sub_sexp : Type.t } | |
494 | ||
495 | exception E of t | |
496 | end | |
497 | ||
498 | val of_string : string -> t | |
499 | (** [of_string str] converts string [str] to an S-expression. NOTE: | |
500 | trailing whitespace is considered an error, which may be overly | |
501 | strict for some applications. Either strip the string of trailing | |
502 | whitespace first, or, even cheaper, use {!parse} instead. *) | |
503 | ||
504 | val of_string_conv : string -> (t -> 'a) -> 'a Annotated.conv | |
505 | (** [of_string_conv str conv] like {!of_string}, but performs type conversion | |
506 | with [conv]. @return conversion result. *) | |
507 | ||
508 | val of_string_conv_exn : string -> (t -> 'a) -> 'a | |
509 | (** [of_string_conv_exn str conv] like {!of_string_conv}, but raises | |
510 | {!Of_string_conv_exn.E} if type conversion fails. @return converted | |
511 | value. *) | |
512 | ||
513 | val of_bigstring : bigstring -> t | |
514 | (** [of_bigstring bstr] same as {!of_string}, but operates on bigstrings. *) | |
515 | ||
516 | val of_bigstring_conv : bigstring -> (t -> 'a) -> 'a Annotated.conv | |
517 | (** [of_bigstring_conv bstr conv] like {!of_bigstring}, but performs | |
518 | type conversion with [conv]. @return conversion result. *) | |
519 | ||
520 | val of_bigstring_conv_exn : bigstring -> (t -> 'a) -> 'a | |
521 | (** [of_bigstring_conv_exn bstr conv] like {!of_bigstring_conv}, but raises | |
522 | {!Of_string_conv_exn.E} if type conversion fails. @return converted | |
523 | value. *) | |
524 | ||
525 | val to_string_hum : ?indent : int -> t -> string | |
526 | (** [to_string_hum ?indent sexp] converts S-expression [sexp] to a | |
527 | string in human readable form with indentation level [indent]. | |
528 | ||
529 | @param indent default = [!default_indent] | |
530 | *) | |
531 | ||
532 | val to_string_mach : t -> string | |
533 | (** [to_string_mach sexp] converts S-expression [sexp] to a string in | |
534 | machine readable (i.e. most compact) form. *) | |
535 | ||
536 | val to_string : t -> string | |
537 | (** [to_string sexp] same as [to_string_mach]. *) | |
538 | ||
539 | ||
540 | (** {6 Buffer conversions} *) | |
541 | ||
542 | val to_buffer_hum : buf : Buffer.t -> ?indent : int -> t -> unit | |
543 | (** [to_buffer_hum ~buf ?indent sexp] outputs the S-expression [sexp] | |
544 | converted to a string in human readable form to buffer [buf]. | |
545 | ||
546 | @param indent default = [!default_indent] | |
547 | *) | |
548 | ||
549 | val to_buffer_mach : buf : Buffer.t -> t -> unit | |
550 | (** [to_buffer_mach ~buf sexp] outputs the S-expression [sexp] converted | |
551 | to a string in machine readable (i.e. most compact) form to buffer [buf]. | |
552 | *) | |
553 | ||
554 | val to_buffer : buf : Buffer.t -> t -> unit | |
555 | (** [to_buffer ~buf sexp] same as {!to_buffer_mach}. *) | |
556 | ||
557 | ||
558 | (** {6 Utilities for automated type conversions} *) | |
559 | ||
560 | val unit : t | |
561 | (** [unit] the unit-value as expressed by an S-expression. *) | |
562 | ||
563 | external sexp_of_t : t -> t = "%identity" | |
564 | (** [sexp_of_t sexp] maps S-expressions which are part of a type with | |
565 | automated S-expression conversion to themselves. *) | |
566 | ||
567 | external t_of_sexp : t -> t = "%identity" | |
568 | (** [t_of_sexp sexp] maps S-expressions which are part of a type with | |
569 | automated S-expression conversion to themselves. *) | |
570 | ||
571 | ||
572 | (** {6 Utilities for conversion error handling} *) | |
573 | ||
574 | type found = [ `Found | `Pos of int * found ] | |
575 | (** Type of successful search results. [`Found] means that an | |
576 | S-expression was found at the immediate position, and [`Pos (pos, | |
577 | found)] indicates that it was found at position [pos] within a | |
578 | structure (= S-expression list) where [found] describes recursively | |
579 | where it was found in that structure. *) | |
580 | ||
581 | type search_result = [ `Not_found | found ] | |
582 | (** Type of search results. [`Not_found] means that an | |
583 | S-expression was not found within another S-expression. *) | |
584 | ||
585 | val search_physical : t -> contained : t -> search_result | |
586 | (** [search_physical sexp ~contained] @return the search result | |
587 | indicating whether, and if, where the S-expression [contained] | |
588 | was found within S-expression [sexp]. *) | |
589 | ||
590 | val subst_found : t -> subst : t -> found -> t | |
591 | (** [subst_found sexp ~subst found] @return the S-expression that | |
592 | results from substituting [subst] within S-expression [sexp] | |
593 | at the location described by [found]. *) | |
594 | end |