zB8F55.5.0+dev0-2025-04-28/%Scanfӱ(Scanning!A@*in_channelB;@@@A@@@@@6../../stdlib/scanf.mlieSSeSb@@@@%Scanf@@A@'scanbufC;@@ A%ScanfJ(Scanning*in_channel@@@@@@@q||q|@@@@A@A@%stdin%ScanfK(Scanning*in_channel@@@@)}*}@@(B@@)file_nameD;@@3A&stringL@@@@@@@9:@@@@8C@A@'open_in@%ScanfM(Scanning)file_name@@@%ScanfN(Scanning*in_channel@@@@@@X55Y5Z@@WD@@+open_in_bin@%ScanfO(Scanning)file_name@@@%ScanfP(Scanning*in_channel@@@@@@w  x 6@@vE@@(close_in@%ScanfQ(Scanning*in_channel@@@$unitR@@@@@@@@F@@)from_file@%ScanfS(Scanning)file_name@@@%ScanfT(Scanning*in_channel@@@@@@@@G@@-from_file_bin@U@@@%ScanfV(Scanning*in_channel@@@@@@@@H@@+from_string@W@@@%ScanfX(Scanning*in_channel@@@@@@;;;a@@I@@-from_function@@fY@@@$charZ@@@@@%Scanf[(Scanning*in_channel@@@@@@kkk@@J@@,from_channel@&Stdlib\*in_channel@@@%Scanf](Scanning*in_channel@@@@@@$%:@@#K@@,end_of_input@%Scanf^(Scanning*in_channel@@@$bool_@@@@@@? & &@ & K@@>L@@2beginning_of_input@%Scanf`(Scanning*in_channel@@@a@@@@@@Y  Z  @@XM@@-name_of_input @%Scanfb(Scanning*in_channel@@@;c@@@@@@s!!t!!@@rN@@@@wc<<x"V"Y@vO@@@'scanner"E;!a@ؠ!b@٠!c@ڠ!d@@DA@&Stdlibe'format6 F@ܠ%Scanfd(Scanning*in_channel@@@)F@'F@@'F@@@@@@ @@OO@@@@@@@@""""@@@@P@A@+scanner_opt@%Scanfi(Scanning*in_channel@@@ %Scanfj'scanner!a@ H@ !b@ H@ !c@ H@ !d@ H@ @@@ @@ @^((_((@@]S@@*bscanf_opt?@%Scanfk(Scanning*in_channel@@@ %Scanfl+scanner_opt!a@ %H@ !b@ 'H@ !c@ )H@ !d@ +H@ @@@ "@@ #@ +B+B +B+@@T@@&sscanf@@om@@@ ,%Scanfn'scanner!a@ 8H@ -!b@ :H@ .!c@ H@ 0@@@ 5@@ 6@WWWW@@U@@*sscanf_optA@o@@@ ?%Scanfp+scanner_opt!a@ KH@ @!b@ MH@ A!c@ OH@ B!d@ QH@ C@@@ H@@ I@XXXXN@@V@@%scanfB%Scanfq'scanner!a@ \H@ R!b@ ^H@ S!c@ `H@ T!d@ bH@ U@@@ Z@,XX-XX@@+W@@)scanf_optC%Scanfr+scanner_opt!a@ mH@ c!b@ oH@ d!c@ qH@ e!d@ sH@ f@@@ k@YYnYnZYnY@@XX@@&kscanfD@%Scanfs(Scanning*in_channel@@@ t@@%Scanft(Scanning*in_channel@@@ u@eu@@@ v!d@ H@ w@@ x@@ y%Scanfv'scanner!a@ H@ z!b@ H@ {!c@ H@ |#@@@ @@ @@ @YYZGZc@@Y@@'ksscanfE@w@@@ @@%Scanfx(Scanning*in_channel@@@ @y@@@ !d@ H@ @@ @@ %Scanfz'scanner!a@ H@ !b@ H@ !c@ H@ #@@@ @@ @@ @[[\\@@Z@@-bscanf_formatF@%Scanf{(Scanning*in_channel@@@ @&Stdlib|'format6!a@ H@ !b@ H@ !c@ H@ !d@ H@ !e@ H@ !f@ H@ @@@ @@&Stdlib}'format660*$@@@ !g@ H@ @@ @@ @@ @@ @Q \\R \]!@@P[@@-sscanf_formatG@)~@@@ @&Stdlib'format6!a@ H@ ͠!b@ H@ Π!c@ H@ Ϡ!d@ H@ Р!e@ H@ Ѡ!f@ H@ @@@ @@&Stdlib'format660*$@@@ !g@ H@ @@ @@ @@ @@ @^b^b^^@@\@@2format_from_stringH@@@@ @&Stdlib'format6!a@ H@ !b@ H@ !c@ H@ !d@ H@ !e@ H@ !f@ H@ @@@ &Stdlib'format62,& @@@ @@ @@ @_2_2_W_@@]@@)unescapedI@@@@ @@@ @@ @'``'``@@^@@@3:Formatted input functions.@@@@@@@@@@@5unsynchronized_access GUnsynchronized accesses to Scanning.in_channel are a programming error.@A6../../stdlib/scanf.mliA@,Introduction@@B@ $Functional input with format strings@@+The module H@@ ' provides formatted input functions or (scanners@!.@ The formatted input functions can read from any kind of input, including strings, files, or anything that can return characters. The more general source of characters is named a 7formatted input channel@% (or 3 scanning buffer@/) and has type 9Scanf.Scanning.in_channelE@ `. The more general formatted input function reads from any scanning buffer and is named &bscanf!.@ H Generally speaking, the formatted input functions have 3 arguments: ;the first argument is a source of characters for the input,@ Othe second argument is a format string that specifies the values to read,@8the third argument is a 1receiver function@ * that is applied to the values read.@@ ; Hence, a typical call to the formatted input function ,Scanf.bscanfD@( is /bscanf ic fmt f(, where:@"ic ( is a source of characters (typically a ; formatted input channel@+ with type IE@"),@@#fmt ] is a format string (the same format strings as those used to print material with module &Printf@@$ or &Format@@"),@@!f h is a function that has as many arguments as the number of values to read in the input according to #fmt!.@@@B@0A simple example@@ #As suggested above, the expression 0bscanf ic "%d" f= reads a decimal integer !n? from the source of characters "ic- and returns #f n!.@2 For instance,@*if we use %stdin> as the source of characters (4Scanf.Scanning.stdinD@ O is the predefined formatted input channel that reads from standard input),@@:if we define the receiver !f$ as /let f x = x + 1!,@@* then may lead to an invalid  E@ + state. Thus, concurrent accesses to E@ 2s must be synchronized (for instance with a 'Mutex.t@@").@A@7Formatted input channel@@/.Scanf.Scanning@A`#+3 $The notion of input channel for the @@ u module: those channels provide all the machinery necessary to read from any source of characters, including a 1Stdlib.in_channel@@ > value. A Scanf.Scanning.in_channel value is also called a :formatted input channel@3 or equivalently a /scanning buffer@.. The type 6Scanf.Scanning.scanbufE@7 below is an alias for 3Scanning.in_channel1. Note that a 3Scanning.in_channel W is not concurrency-safe: concurrent use may produce arbitrary values or exceptions.@@@@$3.12@@@@@@@@@A@@@@#3 %The type of scanning buffers. A scanning buffer is the source from which a formatted input function gets characters. The scanning buffer holds the current state of the scan, plus a function to get the next char from the input, and a token buffer to store the string matched so far.@ Note: a scanning action may often require to examine one character in advance; when this 'lookahead' character does not belong to the token read, it is stored back in the scanning buffer and becomes the next character yet to be read.@@@@@@@@@@@@@@AĠ@@@Ґ3 "The standard input notion for the @@- module. .Scanning.stdin( is the E@ ) formatted input channel attached to ,Stdlib.stdin@@!.@ B Note: in the interactive system, when input is read from ,Stdlib.stdin@@ , the newline character that triggers evaluation is part of the input; thus, the scanning specifications must properly skip this additional newline character (for instance, simply add a $'\n' 1 as the last character of the format string).@@@@$3.12@@@@@@@@@@@ߠ#8Scanf.Scanning.file_name3 ,A convenient alias to designate a file name.@@@@$4.00@@@@@@@@@A@@@6Scanf.Scanning.open_in36Scanning.open_in fname+ returns a ̐E@ K formatted input channel for bufferized reading in text mode from file %fname!.@/ Note: 'open_in g returns a formatted input channel that efficiently reads characters in large chunks; in contrast, ,from_channel  below returns formatted input channels that must read one character at a time, leading to a much slower scanning rate.@@@@$3.12@@@@@@@@ @@@@:Scanf.Scanning.open_in_bin3:Scanning.open_in_bin fname+ returns a E@ M formatted input channel for bufferized reading in binary mode from file %fname!.@@@@$3.12@@@@@@@@!@@@@7Scanf.Scanning.close_in3+Closes the 1Stdlib.in_channel@@= associated with the given  E@9 formatted input channel.@@@@$3.12@@@@@@@@>@@@@8Scanf.Scanning.from_file3-An alias for wD@' above.@@@@@@@@@@@@@S@@@@렕Scanning.beginning_of_input ic 9 tests the beginning of input condition of the given E@9 formatted input channel.@@@@@@@@@@@@@@@@@ i + 1+, then Scanf.sscanf "x = 1" "%s = %i" f) returns !2!.@/ Arguments "r1$ to "rN R are user-defined input functions that read the argument corresponding to the "%r 0 conversions specified in the format string.@0Scanf.bscanf_opt3(Same as HD@., but returns $None= in case of scanning failure.@@@@#5.0@@@@@@@s@t@@@@HA@9Format string description@@ RThe format string is a character string which contains three types of objects: plain characters, which are simply matched with the characters of the input (with a special case for space and line feed, see +Scanf.space %The space character in format strings@@"),@ nconversion specifications, each of which causes reading and conversion of one argument for the function !f& (see 0Scanf.conversion +Conversion specifications in format strings@@"),@ Iscanning indications to specify boundaries of tokens (see scanning 0Scanf.indication &Scanning indications in format strings@@").@@@B%space0@@ As mentioned above, a plain character in the format string is just matched with the next character of the input; however, two characters are special exceptions to this rule: the space character (#' ' 4 or ASCII code 32) and the line feed character ($'\n' or ASCII code 10). A space does not match a single space character, but any amount of 'whitespace' in the input. More precisely, a space inside the format string matches *any number@ of tab, space, line feed and carriage return characters. Similarly, a line feed character in the format string matches either a single line feed or a carriage return followed by a line feed.@. Matching #any@ u amount of whitespace, a space in the format string also matches no amount of whitespace at all; hence, the call )bscanf ib "Price = %d $" (fun p -> p)6 succeeds and returns !1 B when reading an input with various whitespace in it, such as +Price = 1 $&, 0Price = 1 $*, or even (Price=1$!.@B*conversione@@ )Conversion specifications consist in the !% | character, followed by an optional flag, an optional field width, and followed by one or two conversion characters.@ 6 The conversion characters and their meanings are:@!d .: reads an optionally signed decimal integer (#0-9#+).@!i Q: reads an optionally signed integer (usual input conventions for decimal (#0-98+), hexadecimal (+0x[0-9a-f]+% and +0X[0-9A-F]+*), octal ((0o[0-7]+6), and binary ((0b[0-1]+<) notations are understood).@!u $: reads an unsigned decimal integer.@!x$ or !X ): reads an unsigned hexadecimal integer (,[0-9a-fA-F]+").@!o #: reads an unsigned octal integer (&[0-7]+").@!s v: reads a string argument that spreads as much as possible, until the following bounding condition holds: !a whitespace has been found (see +Scanf.space@"),@ $a scanning indication (see scanning 0Scanf.indication@ ) has been encountered,@ "the end-of-input has been reached.@@ Hence, this conversion always succeeds: it returns an empty string if the bounding condition holds when the scan begins.@!S ~: reads a delimited string argument (delimiters and special escaped characters follow the lexical conventions of OCaml).@!c : reads a single character. To test the current input character without reading it, specify a null field width, i.e. use specification #%0c(. Raise 0Invalid_argument ;, if the field width specification is greater than 1.@!C : reads a single delimited character (delimiters and special escaped characters follow the lexical conventions of OCaml).@!f", !e", !E", !g", !G [: reads an optionally signed floating-point number in decimal notation, in the style 6dddd.ddd e/E+-dd!.@!h", !H Q: reads an optionally signed floating-point number in hexadecimal notation.@!F : reads a floating point number according to the lexical conventions of OCaml (hence the decimal point is mandatory if the exponent part is not mentioned).@!B<: reads a boolean argument ($true$ or %false").@!b Z: reads a boolean argument (for backward compatibility; do not use in new programs).@"ld", "li", "lu", "lx", "lX", "lo+: reads an %int32 R argument to the format specified by the second letter for regular integers.@"nd", "ni", "nu", "nx", "nX", "no*: reads a )nativeint R argument to the format specified by the second letter for regular integers.@"Ld", "Li", "Lu", "Lx", "LX", "Lo+: reads an %int64 R argument to the format specified by the second letter for regular integers.@)[ range ] a: reads characters that matches one of the characters mentioned in the range of characters %range 9 (or not mentioned in it, if the range starts with !^+). Reads a &string q that can be empty, if the next input character does not match the range. The set of characters from "c1$ to "c2= (inclusively) is denoted by %c1-c2/. Hence, &%[0-9] x returns a string representing a decimal number or an empty string if no decimal digit is found; similarly, )%[0-9a-f] returns a string of hexadecimal digits. If a closing bracket appears in a range, it must occur as the first character of the range (or just after the !^ ) in case of range negation); hence #[]]+ matches a !]5 character and $[^]] # matches any character that is not !],. Use "%%% and "%@. to include a !%& or a !@, in a range.@!r &: user-defined reader. Takes the next "ri F formatted input function and applies it to the scanning buffer "ib 5 to read the next argument. The input function "ri must therefore have type 9Scanning.in_channel -> 'a and the argument read has type "'a!.@({ fmt %} : reads a format string argument. The format string read must have the same type as the format string specification #fmt0. For instance, *"%{ %i %}" = reads any format string that can read a value of type #int,; hence, if !s5 is the string 6"fmt:\"number is %u\""', then fmt, i)4 evaluates to -("%4d", 1234) . This behaviour is not mere format substitution, since the conversion returns the format string read as additional argument. If you need pure format substitution, use special flag !_ 6 to discard the extraneous argument: conversion *%_( fmt %)= reads a format string "rf , and then behaves the same as format string "rf-. Hence, if !s5 is the string 0"\"%4d\"1234.00"', then 8Scanf.sscanf s "%_(%i%)"? is simply equivalent to i + 1&, and !s3 is the string '"x = 1"', then ;Scanf.sscanf s "%_s = %i" f) returns !2!.@ The field width is composed of an optional integer literal indicating the maximal width of the token to read. For instance, #%6d 8 reads an integer, having at most 6 decimal digits; #%4f . reads a float with at most 4 characters; and -%8[\000-\255] returns the next 8 characters (or all the characters still available, if fewer than 8 characters are available in the input).@+ Notes:@6as mentioned above, a "%s r conversion always succeeds, even if there is nothing to read in the input: in this case, it simply returns """!.@@ $in addition to the relevant digits, #'_' characters may appear inside numbers (this is reminiscent to the usual OCaml lexical conventions). If stricter scanning is desired, use the range conversion facility instead of the number conversions.@@$the %scanf facility is not intended for heavy duty lexical analysis and parsing. If it appears not expressive enough for your needs, several alternative exists: regular expressions (module #Str@@3), stream parsers, (ocamllex7-generated lexers, )ocamlyacc3-generated parsers.@@@B*indication@@ >Scanning indications appear just after the string conversions "%s) and *%[ range ] O to delimit the end of the token. A scanning indication is introduced by a !@ 1 character, followed by some plain character !c N. It means that the string token should end just before the next matching !c; (which is skipped). If no !c _ character is encountered, the string token spreads as much as possible. For instance, '"%s@\t" N reads a string up to the next tab character or to the end of input. If a !@ ^ character appears anywhere else in the format string, it is treated as a plain character.@* Note:@