PageRenderTime 89ms CodeModel.GetById 7ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 0ms

/src/core/stdc/stdio.d

http://github.com/AlexeyProkhin/druntime
D | 821 lines | 682 code | 101 blank | 38 comment | 26 complexity | bbd5e3a9e42b79b9070e13ba62074c53 MD5 | raw file
  1/**
  2 * D header file for C99.
  3 *
  4 * Copyright: Copyright Sean Kelly 2005 - 2009.
  5 * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
  6 * Authors:   Sean Kelly,
  7              Alex Rønne Petersen
  8 * Standards: ISO/IEC 9899:1999 (E)
  9 */
 10
 11/*          Copyright Sean Kelly 2005 - 2009.
 12 * Distributed under the Boost Software License, Version 1.0.
 13 *    (See accompanying file LICENSE or copy at
 14 *          http://www.boost.org/LICENSE_1_0.txt)
 15 */
 16module core.stdc.stdio;
 17
 18private
 19{
 20    import core.stdc.config;
 21    import core.stdc.stddef; // for size_t
 22    import core.stdc.stdarg; // for va_list
 23
 24  version (FreeBSD)
 25  {
 26    import core.sys.posix.sys.types;
 27  }
 28}
 29
 30extern (C):
 31@system:
 32nothrow:
 33
 34version( Win32 )
 35{
 36    enum
 37    {
 38        BUFSIZ       = 0x4000,
 39        EOF          = -1,
 40        FOPEN_MAX    = 20,
 41        FILENAME_MAX = 256, // 255 plus NULL
 42        TMP_MAX      = 32767,
 43        SYS_OPEN     = 20,      // non-standard
 44    }
 45
 46    enum int     _NFILE     = 60;       // non-standard
 47    enum string  _P_tmpdir  = "\\"; // non-standard
 48    enum wstring _wP_tmpdir = "\\"; // non-standard
 49    enum int     L_tmpnam   = _P_tmpdir.length + 12;
 50}
 51else version( Win64 )
 52{
 53    enum
 54    {
 55        BUFSIZ       = 512,
 56        EOF          = -1,
 57        FOPEN_MAX    = 20,
 58        FILENAME_MAX = 260,
 59        TMP_MAX      = 32767,
 60        _SYS_OPEN    = 20,      // non-standard
 61    }
 62
 63    enum int     _NFILE     = 512;       // non-standard
 64    enum string  _P_tmpdir  = "\\"; // non-standard
 65    enum wstring _wP_tmpdir = "\\"; // non-standard
 66    enum int     L_tmpnam   = _P_tmpdir.length + 12;
 67}
 68else version( linux )
 69{
 70    enum
 71    {
 72        BUFSIZ       = 8192,
 73        EOF          = -1,
 74        FOPEN_MAX    = 16,
 75        FILENAME_MAX = 4095,
 76        TMP_MAX      = 238328,
 77        L_tmpnam     = 20
 78    }
 79}
 80else version( OSX )
 81{
 82    enum
 83    {
 84        BUFSIZ       = 1024,
 85        EOF          = -1,
 86        FOPEN_MAX    = 20,
 87        FILENAME_MAX = 1024,
 88        TMP_MAX      = 308915776,
 89        L_tmpnam     = 1024,
 90    }
 91
 92    private
 93    {
 94        struct __sbuf
 95        {
 96            ubyte*  _base;
 97            int     _size;
 98        }
 99
100        struct __sFILEX
101        {
102
103        }
104    }
105}
106else version ( FreeBSD )
107{
108    enum
109    {
110        BUFSIZ       = 1024,
111        EOF          = -1,
112        FOPEN_MAX    = 20,
113        FILENAME_MAX = 1024,
114        TMP_MAX      = 308915776,
115        L_tmpnam     = 1024
116    }
117
118    struct __sbuf
119    {
120        ubyte *_base;
121        int _size;
122    }
123    alias _iobuf __sFILE;
124
125    union __mbstate_t // <sys/_types.h>
126    {
127        char[128]   _mbstate8;
128        long        _mbstateL;
129    }
130}
131else version (Solaris)
132{
133    enum
134    {
135        BUFSIZ = 1024,
136        EOF = -1,
137        FOPEN_MAX = _NFILE,
138        FILENAME_MAX = 1024,
139        TMP_MAX = 17576,
140        L_tmpnam = 25,
141    }
142
143    version (X86)
144        enum int _NFILE = 60;
145    else
146        enum int _NFILE = 20;
147}
148else
149{
150    static assert( false, "Unsupported platform" );
151}
152
153enum
154{
155    SEEK_SET,
156    SEEK_CUR,
157    SEEK_END
158}
159
160version( Win32 )
161{
162    struct _iobuf
163    {
164        char* _ptr;
165        int   _cnt;
166        char* _base;
167        int   _flag;
168        int   _file;
169        int   _charbuf;
170        int   _bufsiz;
171        char* __tmpnum;
172    }
173}
174else version( Win64 )
175{
176    struct _iobuf
177    {
178        char* _ptr;
179        int   _cnt;
180        char* _base;
181        int   _flag;
182        int   _file;
183        int   _charbuf;
184        int   _bufsiz;
185        char* _tmpfname;
186    }
187}
188else version( linux )
189{
190    align(1) struct _iobuf
191    {
192        int     _flags;
193        char*   _read_ptr;
194        char*   _read_end;
195        char*   _read_base;
196        char*   _write_base;
197        char*   _write_ptr;
198        char*   _write_end;
199        char*   _buf_base;
200        char*   _buf_end;
201        char*   _save_base;
202        char*   _backup_base;
203        char*   _save_end;
204        void*   _markers;
205        _iobuf* _chain;
206        int     _fileno;
207        int     _blksize;
208        int     _old_offset;
209        ushort  _cur_column;
210        byte    _vtable_offset;
211        char[1] _shortbuf;
212        void*   _lock;
213    }
214}
215else version( OSX )
216{
217    align (1) struct _iobuf
218    {
219        ubyte*    _p;
220        int       _r;
221        int       _w;
222        short     _flags;
223        short     _file;
224        __sbuf    _bf;
225        int       _lbfsize;
226
227        int* function(void*)                    _close;
228        int* function(void*, char*, int)        _read;
229        fpos_t* function(void*, fpos_t, int)    _seek;
230        int* function(void*, char *, int)       _write;
231
232        __sbuf    _ub;
233        __sFILEX* _extra;
234        int       _ur;
235
236        ubyte[3]  _ubuf;
237        ubyte[1]  _nbuf;
238
239        __sbuf    _lb;
240
241        int       _blksize;
242        fpos_t    _offset;
243    }
244}
245else version( FreeBSD )
246{
247    align (1) struct _iobuf
248    {
249        ubyte*          _p;
250        int             _r;
251        int             _w;
252        short           _flags;
253        short           _file;
254        __sbuf          _bf;
255        int             _lbfsize;
256
257        void*           _cookie;
258        int     function(void*)                 _close;
259        int     function(void*, char*, int)     _read;
260        fpos_t  function(void*, fpos_t, int)    _seek;
261        int     function(void*, in char*, int)  _write;
262
263        __sbuf          _ub;
264        ubyte*          _up;
265        int             _ur;
266
267        ubyte[3]        _ubuf;
268        ubyte[1]        _nbuf;
269
270        __sbuf          _lb;
271
272        int             _blksize;
273        fpos_t          _offset;
274
275        pthread_mutex_t _fl_mutex;
276        pthread_t       _fl_owner;
277        int             _fl_count;
278        int             _orientation;
279        __mbstate_t     _mbstate;
280    }
281}
282else version (Solaris)
283{
284    align (1) struct _iobuf
285    {
286        char* _ptr;
287        int _cnt;
288        char* _base;
289        char _flag;
290        char _magic;
291        ushort __flags; // __orientation:2
292                        // __ionolock:1
293                        // __seekable:1
294                        // __extendedfd:1
295                        // __xf_nocheck:1
296                        // __filler:10
297    }
298}
299else
300{
301    static assert( false, "Unsupported platform" );
302}
303
304
305alias shared(_iobuf) FILE;
306
307enum
308{
309    _F_RDWR = 0x0003, // non-standard
310    _F_READ = 0x0001, // non-standard
311    _F_WRIT = 0x0002, // non-standard
312    _F_BUF  = 0x0004, // non-standard
313    _F_LBUF = 0x0008, // non-standard
314    _F_ERR  = 0x0010, // non-standard
315    _F_EOF  = 0x0020, // non-standard
316    _F_BIN  = 0x0040, // non-standard
317    _F_IN   = 0x0080, // non-standard
318    _F_OUT  = 0x0100, // non-standard
319    _F_TERM = 0x0200, // non-standard
320}
321
322version( Win32 )
323{
324    enum
325    {
326        _IOFBF   = 0,
327        _IOLBF   = 0x40,
328        _IONBF   = 4,
329        _IOREAD  = 1,     // non-standard
330        _IOWRT   = 2,     // non-standard
331        _IOMYBUF = 8,     // non-standard
332        _IOEOF   = 0x10,  // non-standard
333        _IOERR   = 0x20,  // non-standard
334        _IOSTRG  = 0x40,  // non-standard
335        _IORW    = 0x80,  // non-standard
336        _IOTRAN  = 0x100, // non-standard
337        _IOAPP   = 0x200, // non-standard
338    }
339
340    extern shared void function() _fcloseallp;
341
342    private extern shared FILE[_NFILE] _iob;
343
344    shared stdin  = &_iob[0];
345    shared stdout = &_iob[1];
346    shared stderr = &_iob[2];
347    shared stdaux = &_iob[3];
348    shared stdprn = &_iob[4];
349}
350else version( Win64 )
351{
352    enum
353    {
354        _IOFBF   = 0,
355        _IOLBF   = 0x40,
356        _IONBF   = 4,
357        _IOREAD  = 1,     // non-standard
358        _IOWRT   = 2,     // non-standard
359        _IOMYBUF = 8,     // non-standard
360        _IOEOF   = 0x10,  // non-standard
361        _IOERR   = 0x20,  // non-standard
362        _IOSTRG  = 0x40,  // non-standard
363        _IORW    = 0x80,  // non-standard
364        _IOAPP   = 0x200, // non-standard
365        _IOAPPEND = 0x200, // non-standard
366    }
367
368    extern shared void function() _fcloseallp;
369
370    private extern shared FILE[_NFILE] _iob;
371
372    shared(FILE)* __iob_func();
373
374    shared FILE* stdin;  // = &__iob_func()[0];
375    shared FILE* stdout; // = &__iob_func()[1];
376    shared FILE* stderr; // = &__iob_func()[2];
377}
378else version( linux )
379{
380    enum
381    {
382        _IOFBF = 0,
383        _IOLBF = 1,
384        _IONBF = 2,
385    }
386
387    extern shared FILE* stdin;
388    extern shared FILE* stdout;
389    extern shared FILE* stderr;
390}
391else version( OSX )
392{
393    enum
394    {
395        _IOFBF = 0,
396        _IOLBF = 1,
397        _IONBF = 2,
398    }
399
400    private extern shared FILE* __stdinp;
401    private extern shared FILE* __stdoutp;
402    private extern shared FILE* __stderrp;
403
404    alias __stdinp  stdin;
405    alias __stdoutp stdout;
406    alias __stderrp stderr;
407}
408else version( FreeBSD )
409{
410    enum
411    {
412        _IOFBF = 0,
413        _IOLBF = 1,
414        _IONBF = 2,
415    }
416
417    private extern shared FILE* __stdinp;
418    private extern shared FILE* __stdoutp;
419    private extern shared FILE* __stderrp;
420
421    alias __stdinp  stdin;
422    alias __stdoutp stdout;
423    alias __stderrp stderr;
424}
425else version (Solaris)
426{
427    enum
428    {
429        _IOFBF = 0x00,
430        _IOLBF = 0x40,
431        _IONBF = 0x04,
432        _IOEOF = 0x20,
433        _IOERR = 0x40,
434        _IOREAD = 0x01,
435        _IOWRT = 0x02,
436        _IORW = 0x80,
437        _IOMYBUF = 0x08,
438    }
439
440    private extern shared FILE[_NFILE] __iob;
441
442    shared stdin = &__iob[0];
443    shared stdout = &__iob[1];
444    shared stderr = &__iob[2];
445}
446else
447{
448    static assert( false, "Unsupported platform" );
449}
450
451alias int fpos_t;
452
453int remove(in char* filename);
454int rename(in char* from, in char* to);
455
456@trusted FILE* tmpfile(); // No unsafe pointer manipulation.
457char* tmpnam(char* s);
458
459int   fclose(FILE* stream);
460
461// No unsafe pointer manipulation.
462@trusted
463{
464    int   fflush(FILE* stream);
465}
466
467FILE* fopen(in char* filename, in char* mode);
468FILE* freopen(in char* filename, in char* mode, FILE* stream);
469
470void setbuf(FILE* stream, char* buf);
471int  setvbuf(FILE* stream, char* buf, int mode, size_t size);
472
473version (MinGW)
474{
475    // Prefer the MinGW versions over the MSVC ones, as the latter don't handle
476    // reals at all.
477    int __mingw_fprintf(FILE* stream, in char* format, ...);
478    alias __mingw_fprintf fprintf;
479
480    int __mingw_fscanf(FILE* stream, in char* format, ...);
481    alias __mingw_fscanf fscanf;
482
483    int __mingw_sprintf(char* s, in char* format, ...);
484    alias __mingw_sprintf sprintf;
485
486    int __mingw_sscanf(in char* s, in char* format, ...);
487    alias __mingw_sscanf sscanf;
488
489    int __mingw_vfprintf(FILE* stream, in char* format, va_list arg);
490    alias __mingw_vfprintf vfprintf;
491
492    int __mingw_vfscanf(FILE* stream, in char* format, va_list arg);
493    alias __mingw_vfscanf vfscanf;
494
495    int __mingw_vsprintf(char* s, in char* format, va_list arg);
496    alias __mingw_vsprintf vsprintf;
497
498    int __mingw_vsscanf(in char* s, in char* format, va_list arg);
499    alias __mingw_vsscanf vsscanf;
500
501    int __mingw_vprintf(in char* format, va_list arg);
502    alias __mingw_vprintf vprintf;
503
504    int __mingw_vscanf(in char* format, va_list arg);
505    alias __mingw_vscanf vscanf;
506
507    int __mingw_printf(in char* format, ...);
508    alias __mingw_printf printf;
509
510    int __mingw_scanf(in char* format, ...);
511    alias __mingw_scanf scanf;
512}
513else
514{
515    int fprintf(FILE* stream, in char* format, ...);
516    int fscanf(FILE* stream, in char* format, ...);
517    int sprintf(char* s, in char* format, ...);
518    int sscanf(in char* s, in char* format, ...);
519    int vfprintf(FILE* stream, in char* format, va_list arg);
520    int vfscanf(FILE* stream, in char* format, va_list arg);
521    int vsprintf(char* s, in char* format, va_list arg);
522    int vsscanf(in char* s, in char* format, va_list arg);
523    int vprintf(in char* format, va_list arg);
524    int vscanf(in char* format, va_list arg);
525    int printf(in char* format, ...);
526    int scanf(in char* format, ...);
527}
528
529// No usafe pointer manipulation.
530@trusted
531{
532    int fgetc(FILE* stream);
533    int fputc(int c, FILE* stream);
534}
535
536char* fgets(char* s, int n, FILE* stream);
537int   fputs(in char* s, FILE* stream);
538char* gets(char* s);
539int   puts(in char* s);
540
541// No unsafe pointer manipulation.
542extern (D) @trusted
543{
544    int getchar()                 { return getc(stdin);     }
545    int putchar(int c)            { return putc(c,stdout);  }
546    int getc(FILE* stream)        { return fgetc(stream);   }
547    int putc(int c, FILE* stream) { return fputc(c,stream); }
548}
549
550@trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation.
551
552size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
553size_t fwrite(in void* ptr, size_t size, size_t nmemb, FILE* stream);
554
555// No unsafe pointer manipulation.
556@trusted
557{
558    int fgetpos(FILE* stream, fpos_t * pos);
559    int fsetpos(FILE* stream, in fpos_t* pos);
560
561    int    fseek(FILE* stream, c_long offset, int whence);
562    c_long ftell(FILE* stream);
563}
564
565version( MinGW )
566{
567  // No unsafe pointer manipulation.
568  extern (D) @trusted
569  {
570    // TODO: Check if this is correct.
571    void rewind(FILE* stream)   { fseek(stream,0L,SEEK_SET); stream._flag&=~_IOERR; }
572    pure void clearerr(FILE* stream) { stream._flag &= ~(_IOERR|_IOEOF);                 }
573    pure int  feof(FILE* stream)     { return stream._flag&_IOEOF;                       }
574    pure int  ferror(FILE* stream)   { return stream._flag&_IOERR;                       }
575  }
576    int   __mingw_snprintf(char* s, size_t n, in char* fmt, ...);
577    alias __mingw_snprintf _snprintf;
578    alias __mingw_snprintf snprintf;
579
580    int   __mingw_vsnprintf(char* s, size_t n, in char* format, va_list arg);
581    alias __mingw_vsnprintf _vsnprintf;
582    alias __mingw_vsnprintf vsnprintf;
583}
584else version( Win32 )
585{
586  // No unsafe pointer manipulation.
587  extern (D) @trusted
588  {
589    void rewind(FILE* stream)   { fseek(stream,0L,SEEK_SET); stream._flag&=~_IOERR; }
590    pure void clearerr(FILE* stream) { stream._flag &= ~(_IOERR|_IOEOF);                 }
591    pure int  feof(FILE* stream)     { return stream._flag&_IOEOF;                       }
592    pure int  ferror(FILE* stream)   { return stream._flag&_IOERR;                       }
593  }
594    int   _snprintf(char* s, size_t n, in char* fmt, ...);
595    alias _snprintf snprintf;
596
597    int   _vsnprintf(char* s, size_t n, in char* format, va_list arg);
598    alias _vsnprintf vsnprintf;
599}
600else version( Win64 )
601{
602  // No unsafe pointer manipulation.
603  extern (D) @trusted
604  {
605    void rewind(FILE* stream)   { fseek(stream,0L,SEEK_SET); stream._flag&=~_IOERR; }
606    pure void clearerr(FILE* stream) { stream._flag &= ~(_IOERR|_IOEOF);                 }
607    pure int  feof(FILE* stream)     { return stream._flag&_IOEOF;                       }
608    pure int  ferror(FILE* stream)   { return stream._flag&_IOERR;                       }
609    pure int  fileno(FILE* stream)   { return stream._file;                              }
610  }
611    int   _snprintf(char* s, size_t n, in char* fmt, ...);
612    alias _snprintf snprintf;
613
614    int   _vsnprintf(char* s, size_t n, in char* format, va_list arg);
615    alias _vsnprintf vsnprintf;
616
617    int _filbuf(FILE *fp);
618    int _flsbuf(int c, FILE *fp);
619
620    int _fputc_nolock(int c, FILE *fp)
621    {
622        if (--fp._cnt >= 0)
623            return *fp._ptr++ = cast(char)c;
624        else
625            return _flsbuf(c, fp);
626    }
627
628    int _fgetc_nolock(FILE *fp)
629    {
630        if (--fp._cnt >= 0)
631            return *fp._ptr++;
632        else
633            return _filbuf(fp);
634    }
635
636    int _lock_file(FILE *fp);
637    int _unlock_file(FILE *fp);
638}
639else version( linux )
640{
641  // No unsafe pointer manipulation.
642  @trusted
643  {
644    void rewind(FILE* stream);
645    pure void clearerr(FILE* stream);
646    pure int  feof(FILE* stream);
647    pure int  ferror(FILE* stream);
648    int  fileno(FILE *);
649  }
650
651    int  snprintf(char* s, size_t n, in char* format, ...);
652    int  vsnprintf(char* s, size_t n, in char* format, va_list arg);
653}
654else version( OSX )
655{
656  // No unsafe pointer manipulation.
657  @trusted
658  {
659    void rewind(FILE*);
660    pure void clearerr(FILE*);
661    pure int  feof(FILE*);
662    pure int  ferror(FILE*);
663    int  fileno(FILE*);
664  }
665
666    int  snprintf(char* s, size_t n, in char* format, ...);
667    int  vsnprintf(char* s, size_t n, in char* format, va_list arg);
668}
669else version( FreeBSD )
670{
671  // No unsafe pointer manipulation.
672  @trusted
673  {
674    void rewind(FILE*);
675    pure void clearerr(FILE*);
676    pure int  feof(FILE*);
677    pure int  ferror(FILE*);
678    int  fileno(FILE*);
679  }
680
681    int  snprintf(char* s, size_t n, in char* format, ...);
682    int  vsnprintf(char* s, size_t n, in char* format, va_list arg);
683}
684else version (Solaris)
685{
686  // No unsafe pointer manipulation.
687  @trusted
688  {
689    void rewind(FILE*);
690    pure void clearerr(FILE*);
691    pure int  feof(FILE*);
692    pure int  ferror(FILE*);
693    int  fileno(FILE*);
694  }
695
696    int  snprintf(char* s, size_t n, in char* format, ...);
697    int  vsnprintf(char* s, size_t n, in char* format, va_list arg);
698}
699else
700{
701    static assert( false, "Unsupported platform" );
702}
703
704void perror(in char* s);
705
706version (DigitalMars) version (Win32)
707{
708    import core.sys.windows.windows;
709
710    enum
711    {
712        FHND_APPEND     = 0x04,
713        FHND_DEVICE     = 0x08,
714        FHND_TEXT       = 0x10,
715        FHND_BYTE       = 0x20,
716        FHND_WCHAR      = 0x40,
717    }
718
719    private enum _MAX_SEMAPHORES = 10 + _NFILE;
720    private enum _semIO = 3;
721
722    private extern __gshared short _iSemLockCtrs[_MAX_SEMAPHORES];
723    private extern __gshared int _iSemThreadIds[_MAX_SEMAPHORES];
724    private extern __gshared int _iSemNestCount[_MAX_SEMAPHORES];
725    private extern __gshared HANDLE[_NFILE] _osfhnd;
726    private extern __gshared ubyte[_NFILE] __fhnd_info;
727
728    private void _WaitSemaphore(int iSemaphore);
729    private void _ReleaseSemaphore(int iSemaphore);
730
731    // this is copied from semlock.h in DMC's runtime.
732    private void LockSemaphore(uint num)
733    {
734        asm
735        {
736            mov EDX, num;
737            lock;
738            inc _iSemLockCtrs[EDX * 2];
739            jz lsDone;
740            push EDX;
741            call _WaitSemaphore;
742            add ESP, 4;
743        }
744
745    lsDone: {}
746    }
747
748    // this is copied from semlock.h in DMC's runtime.
749    private void UnlockSemaphore(uint num)
750    {
751        asm
752        {
753            mov EDX, num;
754            lock;
755            dec _iSemLockCtrs[EDX * 2];
756            js usDone;
757            push EDX;
758            call _ReleaseSemaphore;
759            add ESP, 4;
760        }
761
762    usDone: {}
763    }
764
765    // This converts a HANDLE to a file descriptor in DMC's runtime
766    int _handleToFD(HANDLE h, int flags)
767    {
768        LockSemaphore(_semIO);
769        scope(exit) UnlockSemaphore(_semIO);
770
771        foreach (fd; 0 .. _NFILE)
772        {
773            if (!_osfhnd[fd])
774            {
775                _osfhnd[fd] = h;
776                __fhnd_info[fd] = cast(ubyte)flags;
777                return fd;
778            }
779        }
780
781        return -1;
782    }
783
784    HANDLE _fdToHandle(int fd)
785    {
786        // no semaphore is required, once inserted, a file descriptor
787        // doesn't change.
788        if (fd < 0 || fd >= _NFILE)
789            return null;
790
791        return _osfhnd[fd];
792    }
793
794    enum
795    {
796        O_RDONLY = 0x000,
797        O_WRONLY = 0x001,
798        O_RDWR   = 0x002,
799        O_APPEND = 0x008,
800        O_CREAT  = 0x100,
801        O_TRUNC  = 0x200,
802        O_EXCL   = 0x400,
803    }
804
805    enum
806    {
807        S_IREAD = 0x0100,
808        S_IWRITE = 0x0080,
809    }
810
811    enum
812    {
813        STDIN_FILENO  = 0,
814        STDOUT_FILENO = 1,
815        STDERR_FILENO = 2,
816    }
817
818    int open(const(char)* filename, int flags, ...);
819    int close(int fd);
820    FILE *fdopen(int fd, const(char)* flags);
821}