pax_global_header00006660000000000000000000000064146164733610014525gustar00rootroot0000000000000052 comment=962c110ab13a2d511aa059738ee3a28fb256869c stdio-0.17.0/000077500000000000000000000000001461647336100127345ustar00rootroot00000000000000stdio-0.17.0/.gitignore000066400000000000000000000000411461647336100147170ustar00rootroot00000000000000_build *.install *.merlin _opam stdio-0.17.0/.ocamlformat000066400000000000000000000000231461647336100152340ustar00rootroot00000000000000profile=janestreet stdio-0.17.0/CHANGES.md000066400000000000000000000006551461647336100143340ustar00rootroot00000000000000## Release v0.17.0 - Added `Out_channel.output_line` - Added `Out_channel.fprint_s`, used to share implementation of `print_s` and `eprint_s` ## v0.12 - Added function `Out_channel.print_s`. ## v0.10 - Enabled `-safe-string`. - Added functions `Out_channel.output_bytes`, `Out_channel.output_substring`. - Added functions `In_channel.equal` and `Out_channel.equal`, implemented as `phys_equal`. ## v0.9 Initial release. stdio-0.17.0/CONTRIBUTING.md000066400000000000000000000044101461647336100151640ustar00rootroot00000000000000This repository contains open source software that is developed and maintained by [Jane Street][js]. Contributions to this project are welcome and should be submitted via GitHub pull requests. Signing contributions --------------------- We require that you sign your contributions. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: if you can certify the below (from [developercertificate.org][dco]): ``` Developer Certificate of Origin Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 1 Letterman Drive Suite D4700 San Francisco, CA, 94129 Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` Then you just add a line to every git commit message: ``` Signed-off-by: Joe Smith ``` Use your real name (sorry, no pseudonyms or anonymous contributions.) If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with git commit -s. [dco]: http://developercertificate.org/ [js]: https://opensource.janestreet.com/ stdio-0.17.0/LICENSE.md000066400000000000000000000021461461647336100143430ustar00rootroot00000000000000The MIT License Copyright (c) 2016--2024 Jane Street Group, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. stdio-0.17.0/Makefile000066400000000000000000000004031461647336100143710ustar00rootroot00000000000000INSTALL_ARGS := $(if $(PREFIX),--prefix $(PREFIX),) default: dune build install: dune install $(INSTALL_ARGS) uninstall: dune uninstall $(INSTALL_ARGS) reinstall: uninstall install clean: dune clean .PHONY: default install uninstall reinstall clean stdio-0.17.0/README.md000066400000000000000000000004741461647336100142200ustar00rootroot00000000000000# Standard IO Library for OCaml Stdio provides input/output functions for OCaml. It re-exports the buffered channels of the stdlib distributed with OCaml but with some improvements. API documentation for the latest release can be found [here](https://ocaml.janestreet.com/ocaml-core/latest/doc/stdio/index.html). stdio-0.17.0/dune-project000066400000000000000000000000211461647336100152470ustar00rootroot00000000000000(lang dune 3.11) stdio-0.17.0/src/000077500000000000000000000000001461647336100135235ustar00rootroot00000000000000stdio-0.17.0/src/dune000066400000000000000000000003231461647336100143770ustar00rootroot00000000000000(library (name stdio) (public_name stdio) (libraries base) (preprocess no_preprocessing) (lint (pps ppx_base -check-doc-comments -type-conv-keep-w32=impl -apply=js_style,type_conv))) (documentation) stdio-0.17.0/src/in_channel.ml000066400000000000000000000047531461647336100161640ustar00rootroot00000000000000open! Base type t = Stdlib.in_channel let equal (t1 : t) t2 = phys_equal t1 t2 let seek = Stdlib.LargeFile.seek_in let pos = Stdlib.LargeFile.pos_in let length = Stdlib.LargeFile.in_channel_length let stdin = Stdlib.stdin let create ?(binary = true) file = let flags = [ Open_rdonly ] in let flags = if binary then Open_binary :: flags else flags in Stdlib.open_in_gen flags 0o000 file ;; let close = Stdlib.close_in let with_file ?binary file ~f = Exn.protectx (create ?binary file) ~f ~finally:close let may_eof f = try Some (f ()) with | End_of_file -> None ;; let input t ~buf ~pos ~len = Stdlib.input t buf pos len let really_input t ~buf ~pos ~len = may_eof (fun () -> Stdlib.really_input t buf pos len) let really_input_exn t ~buf ~pos ~len = Stdlib.really_input t buf pos len let input_byte t = may_eof (fun () -> Stdlib.input_byte t) let input_char t = may_eof (fun () -> Stdlib.input_char t) let input_binary_int t = may_eof (fun () -> Stdlib.input_binary_int t) let unsafe_input_value t = may_eof (fun () -> Stdlib.input_value t) let input_buffer t buf ~len = may_eof (fun () -> Stdlib.Buffer.add_channel buf t len) let set_binary_mode = Stdlib.set_binary_mode_in let input_all t = (* We use 65536 because that is the size of OCaml's IO buffers. *) let chunk_size = 65536 in let buffer = Buffer.create chunk_size in let rec loop () = Stdlib.Buffer.add_channel buffer t chunk_size; loop () in try loop () with | End_of_file -> Buffer.contents buffer ;; let trim ~fix_win_eol line = if fix_win_eol then ( let len = String.length line in if len > 0 && Char.equal (String.get line (len - 1)) '\r' then String.sub line ~pos:0 ~len:(len - 1) else line) else line ;; let input_line ?(fix_win_eol = true) t = match may_eof (fun () -> Stdlib.input_line t) with | None -> None | Some line -> Some (trim ~fix_win_eol line) ;; let input_line_exn ?(fix_win_eol = true) t = let line = Stdlib.input_line t in trim ~fix_win_eol line ;; let fold_lines ?fix_win_eol t ~init ~f = let rec loop ac = match input_line ?fix_win_eol t with | None -> ac | Some line -> loop (f ac line) in loop init ;; let input_lines ?fix_win_eol t = List.rev (fold_lines ?fix_win_eol t ~init:[] ~f:(fun lines line -> line :: lines)) ;; let iter_lines ?fix_win_eol t ~f = fold_lines ?fix_win_eol t ~init:() ~f:(fun () line -> f line) ;; let read_lines ?fix_win_eol fname = with_file fname ~f:(input_lines ?fix_win_eol) let read_all fname = with_file fname ~f:input_all stdio-0.17.0/src/in_channel.mli000066400000000000000000000106521461647336100163300ustar00rootroot00000000000000(** An input channel for doing blocking reads from input sources like files and sockets. Note that an [In_channel.t] is a custom block with a finalizer, and so is allocated directly to the major heap. Creating a lot of in_channels can result in many major collections and poor performance. Note that this is simply another interface on the [in_channel] type in the OCaml standard library. *) open! Base type t = Stdlib.in_channel include Equal.S with type t := t val stdin : t (** Channels are opened in binary mode iff [binary] is true. This only has an effect on Windows. *) val create : ?binary:bool (** defaults to [true] *) -> string -> t (** [with_file ~f fname] executes [~f] on the open channel from [fname], and closes it afterwards. *) val with_file : ?binary:bool (** defaults to [true] *) -> string -> f:(t -> 'a) -> 'a (** [close t] closes [t], or does nothing if [t] is already closed, and may raise an exception. *) val close : t -> unit val input : t -> buf:bytes -> pos:int -> len:int -> int val really_input : t -> buf:bytes -> pos:int -> len:int -> unit option (** Same as [Pervasives.really_input], for backwards compatibility *) val really_input_exn : t -> buf:bytes -> pos:int -> len:int -> unit (** Read one character from the given input channel. Return [None] if there are no more characters to read. *) val input_char : t -> char option (** Same as [input_char], but return the 8-bit integer representing the character. Return [None] if an end of file was reached. *) val input_byte : t -> int option (** Read an integer encoded in binary format (4 bytes, big-endian) from the given input channel. See {!Pervasives.output_binary_int}. Return [None] if an end of file was reached while reading the integer. *) val input_binary_int : t -> int option (** OCaml's built-in marshal format *) val unsafe_input_value : t -> _ option (** [input_buffer t buf ~len] reads at most [len] characters from the input channel [t] and stores them at the end of buffer [buf]. Return [None] if the channel contains fewer than [len] characters. In this case, the characters are still added to the buffer, so as to avoid loss of data. *) val input_buffer : t -> Buffer.t -> len:int -> unit option val input_all : t -> string (** [input_line ?fix_win_eol t] reads a line from [t] and returns it, without the newline ("\n") character at the end, and, if [fix_win_eol] the trailing "\r\n" is dropped. *) val input_line : ?fix_win_eol:bool (** defaults to [true] *) -> t -> string option val input_line_exn : ?fix_win_eol:bool (** defaults to [true] *) -> t -> string (** [fold_lines ?fix_win_eol t ~init ~f] folds over the lines read from [t] using [input_line]. Lines are provided to [f] in the order they are found in the file. *) val fold_lines : ?fix_win_eol:bool (** defaults to [true] *) -> t -> init:'a -> f:('a -> string -> 'a) -> 'a (** Completely reads an input channel and returns the results as a list of strings. Each line in one string. *) val input_lines : ?fix_win_eol:bool (** defaults to [true] *) -> t -> string list (** [iter_lines ?fix_win_eol t ~f] applies [f] to each line read from [t] using [input_line]. *) val iter_lines : ?fix_win_eol:bool (** defaults to [true] *) -> t -> f:(string -> unit) -> unit (** This works only for regular files. On files of other kinds, the behavior is unspecified. *) val seek : t -> int64 -> unit val pos : t -> int64 (** Return the size (number of characters) of the regular file on which the given channel is opened. If the channel is opened on a file that is not a regular file, the result is meaningless. The returned size does not take into account the end-of-line translations that can be performed when reading from a channel opened in text mode. *) val length : t -> int64 (** same as [Pervasives.set_binary_mode_in], only applicable for Windows or Cygwin, no-op otherwise *) val set_binary_mode : t -> bool -> unit (** [read_lines filename] reads the full contents of file and returns it as a list of lines, closing the file when it's done. It's the equivalent of [with_file fname ~f:input_lines] *) val read_lines : ?fix_win_eol:bool -> string -> string list (** [read_all filename] reads the full contents of file and returns it as a single string, closing the file when it's done. It's the equivalent of [with_file fname ~f:input_all] *) val read_all : string -> string stdio-0.17.0/src/index.mld000066400000000000000000000003571461647336100153350ustar00rootroot00000000000000{0 Stdio: Standard IO Library for OCaml} Stdio provides input/output functions for OCaml. It re-exports the buffered channels of the stdlib distributed with OCaml but with some improvements. The full API is browsable {{!Stdio}{b here}}. stdio-0.17.0/src/out_channel.ml000066400000000000000000000050701461647336100163560ustar00rootroot00000000000000open! Base type t = Stdlib.out_channel let equal (t1 : t) t2 = phys_equal t1 t2 let seek = Stdlib.LargeFile.seek_out let pos = Stdlib.LargeFile.pos_out let length = Stdlib.LargeFile.out_channel_length let stdout = Stdlib.stdout let stderr = Stdlib.stderr let sexp_of_t t = if phys_equal t stderr then Sexp.Atom "" else if phys_equal t stdout then Sexp.Atom "" else Sexp.Atom "" ;; type 'a with_create_args = ?binary:bool -> ?append:bool -> ?fail_if_exists:bool -> ?perm:int -> 'a let create ?(binary = true) ?(append = false) ?(fail_if_exists = false) ?(perm = 0o666) file = let flags = [ Open_wronly; Open_creat ] in let flags = (if binary then Open_binary else Open_text) :: flags in let flags = (if append then Open_append else Open_trunc) :: flags in let flags = if fail_if_exists then Open_excl :: flags else flags in Stdlib.open_out_gen flags perm file ;; let set_binary_mode = Stdlib.set_binary_mode_out let flush = Stdlib.flush let close = Stdlib.close_out let close_no_err = Stdlib.close_out_noerr let output t ~buf ~pos ~len = Stdlib.output t buf pos len let output_substring t ~buf ~pos ~len = Stdlib.output_substring t buf pos len let output_string = Stdlib.output_string let output_bytes = Stdlib.output_bytes let output_char = Stdlib.output_char let output_byte = Stdlib.output_byte let output_binary_int = Stdlib.output_binary_int let output_buffer = Stdlib.Buffer.output_buffer let output_value = Stdlib.output_value let newline t = output_string t "\n" let output_line t line = output_string t line; newline t ;; let output_lines t lines = List.iter lines ~f:(fun line -> output_line t line) let printf = Stdlib.Printf.printf let eprintf = Stdlib.Printf.eprintf let fprintf = Stdlib.Printf.fprintf let kfprintf = Stdlib.Printf.kfprintf let print_string = Stdlib.print_string let print_endline = Stdlib.print_endline let prerr_endline = Stdlib.prerr_endline let fprint_endline t string = output_string t string; output_char t '\n'; flush t ;; let fprint_s ?mach t sexp = fprint_endline t (match mach with | Some () -> Sexp.to_string_mach sexp | None -> Sexp.to_string_hum sexp) ;; let print_s ?mach sexp = fprint_s ?mach stdout sexp let eprint_s ?mach sexp = fprint_s ?mach stderr sexp let with_file ?binary ?append ?fail_if_exists ?perm file ~f = Exn.protectx (create ?binary ?append ?fail_if_exists ?perm file) ~f ~finally:close ;; let write_lines file lines = with_file file ~f:(fun t -> output_lines t lines) let write_all file ~data = with_file file ~f:(fun t -> output_string t data) stdio-0.17.0/src/out_channel.mli000066400000000000000000000115271461647336100165330ustar00rootroot00000000000000(** An output channel for doing blocking writes to destinations like files and sockets. Note that an [Out_channel.t] is a custom block with a finalizer, and so is allocated directly to the major heap. Creating a lot of out_channels can result in many major collections and poor performance. Note that this is simply another interface on the [out_channel] type in the OCaml standard library. As for the output functions in the standard library, all the functions in this module, unless otherwise specified, can raise [Sys_error] when the system calls they invoke fail. *) open! Base type t = Stdlib.out_channel [@@deriving_inline sexp_of] include sig [@@@ocaml.warning "-32"] val sexp_of_t : t -> Sexplib0.Sexp.t end [@@ocaml.doc "@inline"] [@@@end] include Equal.S with type t := t val stdout : t val stderr : t type 'a with_create_args = ?binary:bool (** defaults to [true] *) -> ?append:bool (** defaults to [false] *) -> ?fail_if_exists:bool (** defaults to [false] *) -> ?perm:int -> 'a val create : (string -> t) with_create_args val with_file : (string -> f:(t -> 'a) -> 'a) with_create_args (** [close t] flushes and closes [t], and may raise an exception. [close] returns () and does not raise if [t] is already closed. [close] raises an exception if the close() system call on the underlying file descriptor fails (i.e. returns -1), which would happen in the following cases: EBADF -- this would happen if someone else did close() system call on the underlying fd, which I would think a rare event. EINTR -- would happen if the system call was interrupted by a signal, which would be rare. Also, I think we should probably just catch EINTR and re-attempt the close. Unfortunately, we can't do that in OCaml because the OCaml library marks the out_channel as closed even if the close syscall fails, so a subsequent call [close_out_channel] will be a no-op. This should really be fixed in the OCaml library C code, having it restart the close() syscall on EINTR. I put a couple CRs in [fixed_close_channel], our rework of OCaml's [caml_ml_close_channel], EIO -- I don't recall seeing this. I think it's rare. See "man 2 close" for details. *) val close : t -> unit (** [close_no_err] tries to flush and close [t]. It does not raise.*) val close_no_err : t -> unit val set_binary_mode : t -> bool -> unit val flush : t -> unit val output : t -> buf:bytes -> pos:int -> len:int -> unit val output_string : t -> string -> unit val output_substring : t -> buf:string -> pos:int -> len:int -> unit val output_bytes : t -> Bytes.t -> unit val output_char : t -> char -> unit val output_byte : t -> int -> unit val output_binary_int : t -> int -> unit val output_buffer : t -> Buffer.t -> unit (** OCaml's internal Marshal format *) val output_value : t -> _ -> unit val newline : t -> unit (** Outputs a list of lines, each terminated by a newline character *) val output_lines : t -> string list -> unit (** Outputs a single line, terminated by a newline character *) val output_line : t -> string -> unit (** Formatted printing to an out channel. This is the same as [Printf.sprintf] except that it outputs to [t] instead of returning a string. Similarly, the function arguments corresponding to conversions specifications such as [%a] or [%t] takes [t] as argument and must print to it instead of returning a string. *) val fprintf : t -> ('a, t, unit) format -> 'a (** [printf fmt] is the same as [fprintf stdout fmt] *) val printf : ('a, t, unit) format -> 'a (** [fprint_s t sexp] outputs [sexp] to [t], by default using [Sexp.to_string_hum], or, with [~mach:()], [Sexp.to_string_mach]. *) val fprint_s : ?mach:unit -> t -> Sexp.t -> unit (** [print_s ?mach sexp] is the same as [fprint_s ?mach stdout sexp]. *) val print_s : ?mach:unit -> Sexp.t -> unit (** [eprint_s ?mach sexp] is the same as [fprint_s ?mach stderr sexp]. *) val eprint_s : ?mach:unit -> Sexp.t -> unit (** [eprintf fmt] is the same as [fprintf stderr fmt] *) val eprintf : ('a, t, unit) format -> 'a (** [kfprintf k t fmt] is the same as [fprintf t fmt], but instead of returning immediately, passes the out channel to [k] at the end of printing. *) val kfprintf : (t -> 'a) -> t -> ('b, t, unit, 'a) format4 -> 'b (** [print_string s] = [output_string stdout s] *) val print_string : string -> unit (** [print_endline str] outputs [str] to [stdout] followed by a newline then flushes [stdout] *) val print_endline : string -> unit (** [prerr_endline str] outputs [str] to [stderr] followed by a newline then flushes [stderr] *) val prerr_endline : string -> unit val seek : t -> int64 -> unit val pos : t -> int64 val length : t -> int64 (** The first argument of these is the file name to write to. *) val write_lines : string -> string list -> unit val write_all : string -> data:string -> unit stdio-0.17.0/src/stdio.ml000066400000000000000000000006711461647336100152030ustar00rootroot00000000000000open! Base module In_channel = In_channel module Out_channel = Out_channel let stdin = In_channel.stdin let stdout = Out_channel.stdout let stderr = Out_channel.stderr let eprintf = Out_channel.eprintf let printf = Out_channel.printf let print_s = Out_channel.print_s let eprint_s = Out_channel.eprint_s let print_string = Out_channel.print_string let print_endline = Out_channel.print_endline let prerr_endline = Out_channel.prerr_endline stdio-0.17.0/src/stdio.mli000066400000000000000000000015241461647336100153520ustar00rootroot00000000000000open! Base module In_channel = In_channel module Out_channel = Out_channel (** Same as {!In_channel.stdin} *) val stdin : In_channel.t (** Same as {!Out_channel.stdout} *) val stdout : Out_channel.t (** Same as {!Out_channel.stderr} *) val stderr : Out_channel.t (** Same as {!Out_channel.printf} *) val printf : ('a, Out_channel.t, unit) format -> 'a (** Same as {!Out_channel.print_s} *) val print_s : ?mach:unit -> Sexp.t -> unit (** Same as {!Out_channel.eprint_s} *) val eprint_s : ?mach:unit -> Sexp.t -> unit (** Same as {!Out_channel.eprintf} *) val eprintf : ('a, Out_channel.t, unit) format -> 'a (** Same as {!Out_channel.print_string} *) val print_string : string -> unit (** Same as {!Out_channel.print_endline} *) val print_endline : string -> unit (** Same as {!Out_channel.prerr_endline} *) val prerr_endline : string -> unit stdio-0.17.0/stdio.opam000066400000000000000000000014151461647336100147350ustar00rootroot00000000000000opam-version: "2.0" version: "v0.17.0" maintainer: "Jane Street developers" authors: ["Jane Street Group, LLC"] homepage: "https://github.com/janestreet/stdio" bug-reports: "https://github.com/janestreet/stdio/issues" dev-repo: "git+https://github.com/janestreet/stdio.git" doc: "https://ocaml.janestreet.com/ocaml-core/latest/doc/stdio/index.html" license: "MIT" build: [ ["dune" "build" "-p" name "-j" jobs] ] depends: [ "ocaml" {>= "5.1.0"} "base" {>= "v0.17" & < "v0.18"} "dune" {>= "3.11.0"} ] available: arch != "arm32" & arch != "x86_32" synopsis: "Standard IO library for OCaml" description: " Stdio implements simple input/output functionalities for OCaml. It re-exports the input/output functions of the OCaml standard libraries using a more consistent API. "