// Written in the D programming language. /**$(SCRIPT inhibitQuickIndex = 1;)$(DIVC quickindex,$(BOOKTABLE,$(TR $(TH Category) $(TH Symbols))$(TR $(TD File handles) $(TD $(MYREF __popen) $(MYREF File) $(MYREF isFileHandle) $(MYREF openNetwork) $(MYREF stderr) $(MYREF stdin) $(MYREF stdout)))$(TR $(TD Reading) $(TD $(MYREF chunks) $(MYREF lines) $(MYREF readf) $(MYREF readfln) $(MYREF readln)))$(TR $(TD Writing) $(TD $(MYREF toFile) $(MYREF write) $(MYREF writef) $(MYREF writefln) $(MYREF writeln)))$(TR $(TD Misc) $(TD $(MYREF KeepTerminator) $(MYREF LockType) $(MYREF StdioException))))) Standard I/O functions that extend $(LINK2 https://dlang.org/phobos/core_stdc_stdio.html, core.stdc.stdio). $(B core.stdc.stdio)is $(D_PARAM public)ally imported when importing $(B std.stdio). There are three layers of I/O:$(OL$(LI The lowest layer is the operating system layer. The two main schemes are Windows and Posix.)$(LI C's $(TT stdio.h) which unifies the two operating system schemes.)$(LI $(TT std.stdio), this module, unifies the various $(TT stdio.h) implementations intoa high level package for D programs.)) Source: $(PHOBOSSRC std/stdio.d)Copyright: Copyright The D Language Foundation 2007-.License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).Authors: $(HTTP digitalmars.com, Walter Bright), $(HTTP erdani.org, Andrei Alexandrescu), Alex Rønne PetersenMacros:CSTDIO=$(HTTP cplusplus.com/reference/cstdio/$1/, $1) */module std.stdio; /*# Glossary The three layers have many terms for their data structures and types.Here we try to bring some sanity to them for the intrepid code spelunker. ## Windows Handle A Windows handle is an opaque object of type HANDLE. The `HANDLE` for standard devices can be retrieved with Windows `GetStdHandle()`. ## Posix file descriptor, aka fileno, aka fildes An int from 0..`FOPEN_MAX`, which is an index into some internal data structure. 0 is for `stdin`, 1 for `stdout`, 2 for `stderr`. Negative values usually indicate an error. ## stdio.h `FILE` A struct that encapsulates the C library's view of the operating system files. A `FILE` should only be referred to via a pointer. `fileno` A field of `FILE` which is the Posix file descriptor for Posix systems, and and an index into an array of file `HANDLE`s for Windows. This array is how Posix behavior is emulated on Windows. For Digital Mars C, that array is `__osfhnd[]`, and is initialized at program start by the C runtime library. In this module, they are typed as `fileno_t`. `stdin`, `stdout`, `stderr` Global pointers to `FILE` representing standard input, output, and error streams. Being global means there are synchronization issues when multiple threads are doing I/O on the same streams. ## std.stdio */ import core.stdc.stddef : wchar_t;public import core.stdc.stdio;import std.algorithm.mutation : copy;import std.meta : allSatisfy;import std.range : ElementEncodingType, empty, front, isBidirectionalRange, isInputRange, isSomeFiniteCharInputRange, put;import std.traits : isSomeChar, isSomeString, Unqual;import std.typecons : Flag, No, Yes; /++If flag `KeepTerminator` is set to `KeepTerminator.yes`, then the delimiteris included in the strings returned.+/alias KeepTerminator = Flag!"keepTerminator"; version (CRuntime_Microsoft){}else version (CRuntime_Glibc){}else version (CRuntime_Bionic){ version = GENERIC_IO;}else version (CRuntime_Musl){ version = GENERIC_IO;}else version (CRuntime_UClibc){ version = GENERIC_IO;}else version (OSX){ version = GENERIC_IO; version = Darwin;}else version (iOS){ version = GENERIC_IO; version = Darwin;}else version (TVOS){ version = GENERIC_IO; version = Darwin;}else version (WatchOS){ version = GENERIC_IO; version = Darwin;}else version (FreeBSD){ version = GENERIC_IO;}else version (NetBSD){ version = GENERIC_IO;}else version (OpenBSD){ version = GENERIC_IO;}else version (DragonFlyBSD){ version = GENERIC_IO;}else version (Solaris){ version = GENERIC_IO;}else{ static assert(0, "unsupported operating system");} // Character type used for operating system filesystem APIsversion (Windows){ private alias FSChar = wchar;}else{ private alias FSChar = char;} private alias fileno_t = int; // file descriptor, fildes, fileno version (Windows){ // core.stdc.stdio.fopen expects file names to be // encoded in CP_ACP on Windows instead of UTF-8. /+ Waiting for druntime pull 299 +/ extern (C) nothrow @nogc FILE* _wfopen(scope const wchar* filename, scope const wchar* mode); extern (C) nothrow @nogc FILE* _wfreopen(scope const wchar* filename, scope const wchar* mode, FILE* fp); import core.sys.windows.basetsd : HANDLE;} version (Posix){ static import core.sys.posix.stdio; // getdelim, flockfile} version (CRuntime_Microsoft){ private alias _FPUTC = _fputc_nolock; private alias _FPUTWC = _fputwc_nolock; private alias _FGETC = _fgetc_nolock; private alias _FGETWC = _fgetwc_nolock; private alias _FLOCK = _lock_file; private alias _FUNLOCK = _unlock_file;}else version (CRuntime_Glibc){ private alias _FPUTC = fputc_unlocked; private alias _FPUTWC = fputwc_unlocked; private alias _FGETC = fgetc_unlocked; private alias _FGETWC = fgetwc_unlocked; private alias _FLOCK = core.sys.posix.stdio.flockfile; private alias _FUNLOCK = core.sys.posix.stdio.funlockfile;}else version (GENERIC_IO){ nothrow: @nogc: extern (C) private { static import core.stdc.wchar_; pragma(mangle, fputc.mangleof) int _FPUTC(int c, _iobuf* fp); pragma(mangle, core.stdc.wchar_.fputwc.mangleof) int _FPUTWC(wchar_t c, _iobuf* fp); pragma(mangle, fgetc.mangleof) int _FGETC(_iobuf* fp); pragma(mangle, core.stdc.wchar_.fgetwc.mangleof) int _FGETWC(_iobuf* fp); } version (Posix) { private alias _FLOCK = core.sys.posix.stdio.flockfile; private alias _FUNLOCK = core.sys.posix.stdio.funlockfile; } else { static assert(0, "don't know how to lock files on GENERIC_IO"); }}else{ static assert(0, "unsupported C I/O system");} private extern (C) @nogc nothrow{ pragma(mangle, _FPUTC.mangleof) int trustedFPUTC(int ch, _iobuf* h) @trusted; pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted;} //------------------------------------------------------------------------------private struct ByRecordImpl(Fields...){private: import std.typecons : Tuple; File file; char[] line; Tuple!(Fields) current; string format; public: this(File f, string format) { assert(f.isOpen); file = f; this.format = format; popFront(); // prime the range } /// Range primitive implementations. @property bool empty() { return !file.isOpen; } /// Ditto @property ref Tuple!(Fields) front() { return current; } /// Ditto void popFront() { import std.conv : text; import std.exception : enforce; import std.format.read : formattedRead; import std.string : chomp; enforce(file.isOpen, "ByRecord: File must be open"); file.readln(line); if (!line.length) { file.detach(); } else { line = chomp(line); formattedRead(line, format, ¤t); enforce(line.empty, text("Leftover characters in record: `", line, "'")); } }} template byRecord(Fields...){ auto byRecord(File f, string format) { return typeof(return)(f, format); }} /**Encapsulates a `FILE*`. Generally D does not attempt to providethin wrappers over equivalent functions in the C standard library, butmanipulating `FILE*` values directly is unsafe and error-prone inmany ways. The `File` type ensures safe manipulation, automaticfile closing, and a lot of convenience. The underlying `FILE*` handle is maintained in a reference-countedmanner, such that as soon as the last `File` variable bound to agiven `FILE*` goes out of scope, the underlying `FILE*` isautomatically closed. Example:----// test.dimport std.stdio; void main(string[] args){ auto f = File("test.txt", "w"); // open for writing f.write("Hello"); if (args.length > 1) { auto g = f; // now g and f write to the same file // internal reference count is 2 g.write(", ", args[1]); // g exits scope, reference count decreases to 1 } f.writeln("!"); // f exits scope, reference count falls to zero, // underlying `FILE*` is closed.}----$(CONSOLE% rdmd test.d Jimmy% cat test.txtHello, Jimmy!% __) */struct File{ import core.atomic : atomicOp, atomicStore, atomicLoad; import std.range.primitives : ElementEncodingType; import std.traits : isScalarType, isArray; enum Orientation { unknown, narrow, wide } private struct Impl { FILE * handle = null; // Is null iff this Impl is closed by another File shared uint refs = uint.max / 2; bool isPopened; // true iff the stream has been created by popen() Orientation orientation; } private Impl* _p; private string _name; package this(FILE* handle, string name, uint refs = 1, bool isPopened = false) @trusted @nogc nothrow { import core.stdc.stdlib : malloc; assert(!_p); _p = cast(Impl*) malloc(Impl.sizeof); if (!_p) { import core.exception : onOutOfMemoryError; onOutOfMemoryError(); } initImpl(handle, name, refs, isPopened); } private void initImpl(FILE* handle, string name, uint refs = 1, bool isPopened = false) @nogc nothrow pure @safe { assert(_p); _p.handle = handle; atomicStore(_p.refs, refs); _p.isPopened = isPopened; _p.orientation = Orientation.unknown; _name = name; } /**Constructor taking the name of the file to open and the open mode. Copying one `File` object to another results in the two `File`objects referring to the same underlying file. The destructor automatically closes the file as soon as no `File`object refers to it anymore. Params: name = range or string representing the file _name stdioOpenmode = range or string represting the open mode (with the same semantics as in the C standard library $(CSTDIO fopen) function) Throws: `ErrnoException` if the file could not be opened. */ this(string name, scope const(char)[] stdioOpenmode = "rb") @safe { import std.conv : text; import std.exception : errnoEnforce; this(errnoEnforce(_fopen(name, stdioOpenmode), text("Cannot open file `", name, "' in mode `", stdioOpenmode, "'")), name); // MSVCRT workaround (https://issues.dlang.org/show_bug.cgi?id=14422) version (CRuntime_Microsoft) { setAppendWin(stdioOpenmode); } } /// ditto this(R1, R2)(R1 name) if (isSomeFiniteCharInputRange!R1) { import std.conv : to; this(name.to!string, "rb"); } /// ditto this(R1, R2)(R1 name, R2 mode) if (isSomeFiniteCharInputRange!R1 && isSomeFiniteCharInputRange!R2) { import std.conv : to; this(name.to!string, mode.to!string); } @safe unittest { static import std.file; import std.utf : byChar; auto deleteme = testFilename(); auto f = File(deleteme.byChar, "w".byChar); f.close(); std.file.remove(deleteme); } ~this() @safe { detach(); } this(this) @safe pure nothrow @nogc { if (!_p) return; assert(atomicLoad(_p.refs)); atomicOp!"+="(_p.refs, 1); } /**Assigns a file to another. The target of the assignment gets detachedfrom whatever file it was attached to, and attaches itself to the newfile. */ ref File opAssign(File rhs) @safe return { import std.algorithm.mutation : swap; swap(this, rhs); return this; } Lines 1–500 of 5871. Load more
// Written in the D programming language. /** $(SCRIPT inhibitQuickIndex = 1;) $(DIVC quickindex, $(BOOKTABLE, $(TR $(TH Category) $(TH Symbols)) $(TR $(TD File handles) $(TD $(MYREF __popen) $(MYREF File) $(MYREF isFileHandle) $(MYREF openNetwork) $(MYREF stderr) $(MYREF stdin) $(MYREF stdout) )) $(TR $(TD Reading) $(TD $(MYREF chunks) $(MYREF lines) $(MYREF readf) $(MYREF readfln) $(MYREF readln) )) $(TR $(TD Writing) $(TD $(MYREF toFile) $(MYREF write) $(MYREF writef) $(MYREF writefln) $(MYREF writeln) )) $(TR $(TD Misc) $(TD $(MYREF KeepTerminator) $(MYREF LockType) $(MYREF StdioException) )) )) Standard I/O functions that extend $(LINK2 https://dlang.org/phobos/core_stdc_stdio.html, core.stdc.stdio). $(B core.stdc.stdio) is $(D_PARAM public)ally imported when importing $(B std.stdio). There are three layers of I/O: $(OL $(LI The lowest layer is the operating system layer. The two main schemes are Windows and Posix.) $(LI C's $(TT stdio.h) which unifies the two operating system schemes.) $(LI $(TT std.stdio), this module, unifies the various $(TT stdio.h) implementations into a high level package for D programs.) ) Source: $(PHOBOSSRC std/stdio.d) Copyright: Copyright The D Language Foundation 2007-. License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: $(HTTP digitalmars.com, Walter Bright), $(HTTP erdani.org, Andrei Alexandrescu), Alex Rønne Petersen Macros: CSTDIO=$(HTTP cplusplus.com/reference/cstdio/$1/, $1) */ module std.stdio; /* # Glossary The three layers have many terms for their data structures and types. Here we try to bring some sanity to them for the intrepid code spelunker. ## Windows Handle A Windows handle is an opaque object of type HANDLE. The `HANDLE` for standard devices can be retrieved with Windows `GetStdHandle()`. ## Posix file descriptor, aka fileno, aka fildes An int from 0..`FOPEN_MAX`, which is an index into some internal data structure. 0 is for `stdin`, 1 for `stdout`, 2 for `stderr`. Negative values usually indicate an error. ## stdio.h `FILE` A struct that encapsulates the C library's view of the operating system files. A `FILE` should only be referred to via a pointer. `fileno` A field of `FILE` which is the Posix file descriptor for Posix systems, and and an index into an array of file `HANDLE`s for Windows. This array is how Posix behavior is emulated on Windows. For Digital Mars C, that array is `__osfhnd[]`, and is initialized at program start by the C runtime library. In this module, they are typed as `fileno_t`. `stdin`, `stdout`, `stderr` Global pointers to `FILE` representing standard input, output, and error streams. Being global means there are synchronization issues when multiple threads are doing I/O on the same streams. ## std.stdio */ import core.stdc.stddef : wchar_t; public import core.stdc.stdio; import std.algorithm.mutation : copy; import std.meta : allSatisfy; import std.range : ElementEncodingType, empty, front, isBidirectionalRange, isInputRange, isSomeFiniteCharInputRange, put; import std.traits : isSomeChar, isSomeString, Unqual; import std.typecons : Flag, No, Yes; /++ If flag `KeepTerminator` is set to `KeepTerminator.yes`, then the delimiter is included in the strings returned. +/ alias KeepTerminator = Flag!"keepTerminator"; version (CRuntime_Microsoft) { } else version (CRuntime_Glibc) { } else version (CRuntime_Bionic) { version = GENERIC_IO; } else version (CRuntime_Musl) { version = GENERIC_IO; } else version (CRuntime_UClibc) { version = GENERIC_IO; } else version (OSX) { version = GENERIC_IO; version = Darwin; } else version (iOS) { version = GENERIC_IO; version = Darwin; } else version (TVOS) { version = GENERIC_IO; version = Darwin; } else version (WatchOS) { version = GENERIC_IO; version = Darwin; } else version (FreeBSD) { version = GENERIC_IO; } else version (NetBSD) { version = GENERIC_IO; } else version (OpenBSD) { version = GENERIC_IO; } else version (DragonFlyBSD) { version = GENERIC_IO; } else version (Solaris) { version = GENERIC_IO; } else { static assert(0, "unsupported operating system"); } // Character type used for operating system filesystem APIs version (Windows) { private alias FSChar = wchar; } else { private alias FSChar = char; } private alias fileno_t = int; // file descriptor, fildes, fileno version (Windows) { // core.stdc.stdio.fopen expects file names to be // encoded in CP_ACP on Windows instead of UTF-8. /+ Waiting for druntime pull 299 +/ extern (C) nothrow @nogc FILE* _wfopen(scope const wchar* filename, scope const wchar* mode); extern (C) nothrow @nogc FILE* _wfreopen(scope const wchar* filename, scope const wchar* mode, FILE* fp); import core.sys.windows.basetsd : HANDLE; } version (Posix) { static import core.sys.posix.stdio; // getdelim, flockfile } version (CRuntime_Microsoft) { private alias _FPUTC = _fputc_nolock; private alias _FPUTWC = _fputwc_nolock; private alias _FGETC = _fgetc_nolock; private alias _FGETWC = _fgetwc_nolock; private alias _FLOCK = _lock_file; private alias _FUNLOCK = _unlock_file; } else version (CRuntime_Glibc) { private alias _FPUTC = fputc_unlocked; private alias _FPUTWC = fputwc_unlocked; private alias _FGETC = fgetc_unlocked; private alias _FGETWC = fgetwc_unlocked; private alias _FLOCK = core.sys.posix.stdio.flockfile; private alias _FUNLOCK = core.sys.posix.stdio.funlockfile; } else version (GENERIC_IO) { nothrow: @nogc: extern (C) private { static import core.stdc.wchar_; pragma(mangle, fputc.mangleof) int _FPUTC(int c, _iobuf* fp); pragma(mangle, core.stdc.wchar_.fputwc.mangleof) int _FPUTWC(wchar_t c, _iobuf* fp); pragma(mangle, fgetc.mangleof) int _FGETC(_iobuf* fp); pragma(mangle, core.stdc.wchar_.fgetwc.mangleof) int _FGETWC(_iobuf* fp); } version (Posix) { private alias _FLOCK = core.sys.posix.stdio.flockfile; private alias _FUNLOCK = core.sys.posix.stdio.funlockfile; } else { static assert(0, "don't know how to lock files on GENERIC_IO"); } } else { static assert(0, "unsupported C I/O system"); } private extern (C) @nogc nothrow { pragma(mangle, _FPUTC.mangleof) int trustedFPUTC(int ch, _iobuf* h) @trusted; pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted; } //------------------------------------------------------------------------------ private struct ByRecordImpl(Fields...) { private: import std.typecons : Tuple; File file; char[] line; Tuple!(Fields) current; string format; public: this(File f, string format) { assert(f.isOpen); file = f; this.format = format; popFront(); // prime the range } /// Range primitive implementations. @property bool empty() { return !file.isOpen; } /// Ditto @property ref Tuple!(Fields) front() { return current; } /// Ditto void popFront() { import std.conv : text; import std.exception : enforce; import std.format.read : formattedRead; import std.string : chomp; enforce(file.isOpen, "ByRecord: File must be open"); file.readln(line); if (!line.length) { file.detach(); } else { line = chomp(line); formattedRead(line, format, ¤t); enforce(line.empty, text("Leftover characters in record: `", line, "'")); } } } template byRecord(Fields...) { auto byRecord(File f, string format) { return typeof(return)(f, format); } } /** Encapsulates a `FILE*`. Generally D does not attempt to provide thin wrappers over equivalent functions in the C standard library, but manipulating `FILE*` values directly is unsafe and error-prone in many ways. The `File` type ensures safe manipulation, automatic file closing, and a lot of convenience. The underlying `FILE*` handle is maintained in a reference-counted manner, such that as soon as the last `File` variable bound to a given `FILE*` goes out of scope, the underlying `FILE*` is automatically closed. Example: ---- // test.d import std.stdio; void main(string[] args) { auto f = File("test.txt", "w"); // open for writing f.write("Hello"); if (args.length > 1) { auto g = f; // now g and f write to the same file // internal reference count is 2 g.write(", ", args[1]); // g exits scope, reference count decreases to 1 } f.writeln("!"); // f exits scope, reference count falls to zero, // underlying `FILE*` is closed. } ---- $(CONSOLE % rdmd test.d Jimmy % cat test.txt Hello, Jimmy! % __ ) */ struct File { import core.atomic : atomicOp, atomicStore, atomicLoad; import std.range.primitives : ElementEncodingType; import std.traits : isScalarType, isArray; enum Orientation { unknown, narrow, wide } private struct Impl { FILE * handle = null; // Is null iff this Impl is closed by another File shared uint refs = uint.max / 2; bool isPopened; // true iff the stream has been created by popen() Orientation orientation; } private Impl* _p; private string _name; package this(FILE* handle, string name, uint refs = 1, bool isPopened = false) @trusted @nogc nothrow { import core.stdc.stdlib : malloc; assert(!_p); _p = cast(Impl*) malloc(Impl.sizeof); if (!_p) { import core.exception : onOutOfMemoryError; onOutOfMemoryError(); } initImpl(handle, name, refs, isPopened); } private void initImpl(FILE* handle, string name, uint refs = 1, bool isPopened = false) @nogc nothrow pure @safe { assert(_p); _p.handle = handle; atomicStore(_p.refs, refs); _p.isPopened = isPopened; _p.orientation = Orientation.unknown; _name = name; } /** Constructor taking the name of the file to open and the open mode. Copying one `File` object to another results in the two `File` objects referring to the same underlying file. The destructor automatically closes the file as soon as no `File` object refers to it anymore. Params: name = range or string representing the file _name stdioOpenmode = range or string represting the open mode (with the same semantics as in the C standard library $(CSTDIO fopen) function) Throws: `ErrnoException` if the file could not be opened. */ this(string name, scope const(char)[] stdioOpenmode = "rb") @safe { import std.conv : text; import std.exception : errnoEnforce; this(errnoEnforce(_fopen(name, stdioOpenmode), text("Cannot open file `", name, "' in mode `", stdioOpenmode, "'")), name); // MSVCRT workaround (https://issues.dlang.org/show_bug.cgi?id=14422) version (CRuntime_Microsoft) { setAppendWin(stdioOpenmode); } } /// ditto this(R1, R2)(R1 name) if (isSomeFiniteCharInputRange!R1) { import std.conv : to; this(name.to!string, "rb"); } /// ditto this(R1, R2)(R1 name, R2 mode) if (isSomeFiniteCharInputRange!R1 && isSomeFiniteCharInputRange!R2) { import std.conv : to; this(name.to!string, mode.to!string); } @safe unittest { static import std.file; import std.utf : byChar; auto deleteme = testFilename(); auto f = File(deleteme.byChar, "w".byChar); f.close(); std.file.remove(deleteme); } ~this() @safe { detach(); } this(this) @safe pure nothrow @nogc { if (!_p) return; assert(atomicLoad(_p.refs)); atomicOp!"+="(_p.refs, 1); } /** Assigns a file to another. The target of the assignment gets detached from whatever file it was attached to, and attaches itself to the new file. */ ref File opAssign(File rhs) @safe return { import std.algorithm.mutation : swap; swap(this, rhs); return this; }