github.com/gotranspile/cxgo@v0.3.8-0.20240118201721-29871598a6a2/libs/stdio.go (about)

     1  package libs
     2  
     3  import (
     4  	"github.com/gotranspile/cxgo/runtime/stdio"
     5  	"github.com/gotranspile/cxgo/types"
     6  )
     7  
     8  // TODO: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html
     9  
    10  const (
    11  	StdioH = "stdio.h"
    12  )
    13  
    14  func init() {
    15  	// TODO: must #include <stdarg.h>
    16  	// TODO: must #include <sys/types.h>
    17  	// TODO: off_t and ssize_t must be in <sys/types.h>
    18  	RegisterLibrary(StdioH, func(c *Env) *Library {
    19  		gintT := c.Go().Int()
    20  		gstrT := c.Go().String()
    21  		intT := types.IntT(4)
    22  		longT := types.IntT(8)
    23  		cstrT := c.C().String()
    24  		cbytesT := c.C().String()
    25  		bytesT := c.C().String()
    26  		filePtr := c.PtrT(nil)
    27  		valistT := c.GetLibraryType(BuiltinH, "__builtin_va_list")
    28  		fileT := types.NamedTGo("FILE", "stdio.File", c.MethStructT(map[string]*types.FuncType{
    29  			"PutC":   c.FuncTT(intT, gintT),
    30  			"PutS":   c.FuncTT(intT, cstrT),
    31  			"WriteN": c.FuncTT(intT, cbytesT, gintT, gintT),
    32  			"Write":  c.FuncTT(intT, cbytesT, gintT),
    33  			"ReadN":  c.FuncTT(intT, bytesT, gintT, gintT),
    34  			"Read":   c.FuncTT(intT, bytesT, gintT),
    35  			"Tell":   c.FuncTT(longT),
    36  			"Seek":   c.FuncTT(intT, longT, intT),
    37  			"GetC":   c.FuncTT(gintT),
    38  			"UnGetC": c.FuncTT(intT, gintT),
    39  			"GetS":   c.FuncTT(cstrT, cstrT, intT),
    40  			"IsEOF":  c.FuncTT(intT),
    41  			"FileNo": c.FuncTT(c.Go().Uintptr()),
    42  			"Flush":  c.FuncTT(intT),
    43  			"Close":  c.FuncTT(intT),
    44  		}))
    45  		filePtr.SetElem(fileT)
    46  		l := &Library{
    47  			Imports: map[string]string{
    48  				"stdio": RuntimePrefix + "stdio",
    49  			},
    50  			Types: map[string]types.Type{
    51  				"FILE": fileT,
    52  			},
    53  			Idents: map[string]*types.Ident{
    54  				"SEEK_SET": c.NewIdent("SEEK_SET", "stdio.SEEK_SET", stdio.SEEK_SET, intT),
    55  				"SEEK_CUR": c.NewIdent("SEEK_CUR", "stdio.SEEK_CUR", stdio.SEEK_CUR, intT),
    56  				"SEEK_END": c.NewIdent("SEEK_END", "stdio.SEEK_END", stdio.SEEK_END, intT),
    57  
    58  				"_cxgo_EOF": c.NewIdent("_cxgo_EOF", "stdio.EOF", stdio.EOF, types.UntypedIntT(1)),
    59  			},
    60  			Header: `
    61  #include <` + stddefH + `>
    62  #include <` + StdargH + `>
    63  #include <` + StdlibH + `>
    64  #include <` + sysTypesH + `>
    65  
    66  typedef struct FILE FILE;
    67  
    68  typedef struct FILE {
    69  	_cxgo_sint32 (*PutC)(_cxgo_go_int);
    70  	_cxgo_sint32 (*PutS)(const char*);
    71  	_cxgo_sint32 (*WriteN)(const void*, _cxgo_go_int, _cxgo_go_int);
    72  	_cxgo_sint32 (*Write)(const void*, _cxgo_go_int);
    73  	_cxgo_sint32 (*ReadN)(void*, _cxgo_go_int, _cxgo_go_int);
    74  	_cxgo_sint32 (*Read)(void*, _cxgo_go_int);
    75  	_cxgo_sint64 (*Tell)(void);
    76  	_cxgo_sint32 (*Seek)(_cxgo_sint64, _cxgo_sint32);
    77  	_cxgo_go_int (*GetC)(void);
    78  	_cxgo_sint32 (*UnGetC)(_cxgo_go_int);
    79  	char* (*GetS)(char*, _cxgo_sint32);
    80  	_cxgo_sint32 (*IsEOF)(void);
    81  	_cxgo_go_uintptr (*FileNo)(void);
    82  	_cxgo_sint32 (*Flush)(void);
    83  	_cxgo_sint32 (*Close)(void);
    84  } FILE;
    85  
    86  #define fpos_t _cxgo_uint64
    87  #define int _cxgo_int64
    88  
    89  #define FILENAME_MAX 255
    90  
    91  const _cxgo_sint32 SEEK_SET = 0;
    92  const _cxgo_sint32 SEEK_CUR = 1;
    93  const _cxgo_sint32 SEEK_END = 2;
    94  
    95  const int _cxgo_EOF = -1;
    96  #define EOF _cxgo_EOF
    97  
    98  `,
    99  		}
   100  
   101  		l.Declare(
   102  			c.NewIdent("_cxgo_getStdout", "stdio.Stdout", stdio.Stdout, c.FuncTT(filePtr)),
   103  			c.NewIdent("_cxgo_getStderr", "stdio.Stderr", stdio.Stderr, c.FuncTT(filePtr)),
   104  			c.NewIdent("_cxgo_getStdin", "stdio.Stdin", stdio.Stdin, c.FuncTT(filePtr)),
   105  			c.NewIdent("_cxgo_fileByFD", "stdio.ByFD", stdio.ByFD, c.FuncTT(filePtr, c.Go().Uintptr())),
   106  			c.NewIdent("fopen", "stdio.FOpen", stdio.FOpen, c.FuncTT(filePtr, gstrT, gstrT)),
   107  			c.NewIdent("fdopen", "stdio.FDOpen", stdio.FDOpen, c.FuncTT(filePtr, c.Go().Uintptr(), gstrT)),
   108  			// note: printf itself is considered a builtin
   109  			c.NewIdent("vprintf", "stdio.Vprintf", stdio.Vprintf, c.FuncTT(gintT, gstrT, valistT)),
   110  			c.NewIdent("sprintf", "stdio.Sprintf", stdio.Sprintf, c.VarFuncTT(gintT, cstrT, gstrT)),
   111  			c.NewIdent("vsprintf", "stdio.Vsprintf", stdio.Vsprintf, c.FuncTT(gintT, cstrT, gstrT, valistT)),
   112  			c.NewIdent("snprintf", "stdio.Snprintf", stdio.Snprintf, c.VarFuncTT(gintT, cstrT, gintT, gstrT)),
   113  			c.NewIdent("vsnprintf", "stdio.Vsnprintf", stdio.Vsnprintf, c.FuncTT(gintT, cstrT, gintT, gstrT, valistT)),
   114  			c.NewIdent("fprintf", "stdio.Fprintf", stdio.Fprintf, c.VarFuncTT(gintT, filePtr, gstrT)),
   115  			c.NewIdent("vfprintf", "stdio.Vfprintf", stdio.Vfprintf, c.FuncTT(gintT, filePtr, gstrT, valistT)),
   116  			c.NewIdent("scanf", "stdio.Scanf", stdio.Scanf, c.VarFuncTT(gintT, gstrT)),
   117  			c.NewIdent("vscanf", "stdio.Vscanf", stdio.Vscanf, c.FuncTT(gintT, gstrT, valistT)),
   118  			c.NewIdent("sscanf", "stdio.Sscanf", stdio.Sscanf, c.VarFuncTT(gintT, cstrT, gstrT)),
   119  			c.NewIdent("vsscanf", "stdio.Vsscanf", stdio.Vsscanf, c.FuncTT(gintT, cstrT, gstrT, valistT)),
   120  			c.NewIdent("fscanf", "stdio.Fscanf", stdio.Fscanf, c.VarFuncTT(gintT, filePtr, gstrT)),
   121  			c.NewIdent("vfscanf", "stdio.Vfscanf", stdio.Vfscanf, c.FuncTT(gintT, filePtr, gstrT, valistT)),
   122  			c.NewIdent("remove", "stdio.Remove", stdio.Remove, c.VarFuncTT(gintT, gstrT)),
   123  			c.NewIdent("rename", "stdio.Rename", stdio.Rename, c.VarFuncTT(gintT, gstrT, gstrT)),
   124  		)
   125  
   126  		l.Header += `
   127  #define stdout _cxgo_getStdout()
   128  #define stderr _cxgo_getStderr()
   129  #define stdin _cxgo_getStdin()
   130  
   131  #define fclose(f) ((FILE*)f)->Close()
   132  #define feof(f) ((FILE*)f)->IsEOF()
   133  #define fflush(f) ((FILE*)f)->Flush()
   134  #define fgetc(f) ((FILE*)f)->GetC()
   135  #define fgets(buf, sz, f) ((FILE*)f)->GetS(buf, sz)
   136  #define fileno(f) ((FILE*)f)->FileNo()
   137  #define fputc(v, f) ((FILE*)f)->PutC(v)
   138  #define fputs(v, f) ((FILE*)f)->PutS(v)
   139  #define fread(p, sz, cnt, f) ((FILE*)f)->ReadN(p, sz, cnt)
   140  #define fwrite(p, sz, cnt, f) ((FILE*)f)->WriteN(p, sz, cnt)
   141  #define fseek(f, a1, a2) ((FILE*)f)->Seek(a1, a2)
   142  #define ftell(f) ((FILE*)f)->Tell()
   143  #define getc(f) ((FILE*)f)->GetC()
   144  #define ungetc(c, f) ((FILE*)f)->UnGetC(c)
   145  #define putchar(v) ((FILE*)stdout)->PutC(c)
   146  
   147  void     clearerr(FILE *);
   148  char    *ctermid(char *);
   149  _cxgo_go_int      dprintf(_cxgo_go_int, const char *restrict, ...);
   150  int      ferror(FILE *);
   151  int      fgetpos(FILE *restrict, fpos_t *restrict);
   152  void     flockfile(FILE *);
   153  FILE    *fmemopen(void *restrict, size_t, const char *restrict);
   154  FILE    *freopen(const char *restrict, const char *restrict, FILE *restrict);
   155  int      fseeko(FILE *, off_t, int);
   156  int      fsetpos(FILE *, const fpos_t *);
   157  off_t    ftello(FILE *);
   158  int      ftrylockfile(FILE *);
   159  void     funlockfile(FILE *);
   160  int      getchar(void);
   161  int      getc_unlocked(FILE *);
   162  int      getchar_unlocked(void);
   163  ssize_t  getdelim(char **restrict, size_t *restrict, int, FILE *restrict);
   164  ssize_t  getline(char **restrict, size_t *restrict, FILE *restrict);
   165  char    *gets(char *);
   166  FILE    *open_memstream(char **, size_t *);
   167  int      pclose(FILE *);
   168  void     perror(const char *);
   169  FILE    *popen(const char *, const char *);
   170  int      putc(int, FILE *);
   171  int      putc_unlocked(int, FILE *);
   172  int      putchar_unlocked(int);
   173  int      puts(const char *);
   174  int      renameat(int, const char *, int, const char *);
   175  void     rewind(FILE *);
   176  void     setbuf(FILE *restrict, char *restrict);
   177  int      setvbuf(FILE *restrict, char *restrict, int, size_t);
   178  char    *tempnam(const char *, const char *);
   179  FILE    *tmpfile(void);
   180  char    *tmpnam(char *);
   181  int      vdprintf(int, const char *restrict, va_list);
   182  
   183  #undef int
   184  `
   185  		return l
   186  	})
   187  }