Wolfgang Thallergcc 15.1.0ada185d1 year agoHistory
5871 lines · 163.3 KB · D
RawDownload
// 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, &current);            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.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t