Match and link most of Runtime

Former-commit-id: 8b0c414ae0
This commit is contained in:
Phillip Stephens 2022-10-13 01:02:37 -07:00
parent 6380e4db68
commit aab14dc7b0
17 changed files with 641 additions and 129 deletions

View File

@ -12,15 +12,117 @@ stdout_buff:
stdin_buff:
.skip 0x100
.section .data, "wa"
.balign 8
.global __files
__files:
# ROM: 0x3EF778
.4byte 0
.4byte 0x0A800000
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte stdin_buff
.4byte 0x00000100
.4byte stdin_buff
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte __read_console
.4byte __write_console
.4byte __close_console
.4byte 0
.4byte lbl_803F27C8
.global lbl_803F27C8
lbl_803F27C8:
# ROM: 0x3EF7C8
.4byte 0x00000001
.4byte 0x12800000
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte stdout_buff
.4byte 0x00000100
.4byte stdout_buff
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte __read_console
.4byte __write_console
.4byte __close_console
.4byte 0
.4byte lbl_803F2818
.global lbl_803F2818
lbl_803F2818:
# ROM: 0x3EF818
.4byte 0x00000002
.4byte 0x10800000
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte stderr_buff
.4byte 0x00000100
.4byte stderr_buff
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte __read_console
.4byte __write_console
.4byte __close_console
.4byte 0
.4byte lbl_803F2868
.global lbl_803F2868
lbl_803F2868:
# ROM: 0x3EF868
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.section .text, "ax"
.global __flush_all
__flush_all:
/* 8038B0A8 00388008 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8038B0AC 0038800C 7C 08 02 A6 */ mflr r0
/* 8038B0B0 00388010 3C 60 80 3F */ lis r3, lbl_803F2778@ha
/* 8038B0B0 00388010 3C 60 80 3F */ lis r3, __files@ha
/* 8038B0B4 00388014 90 01 00 14 */ stw r0, 0x14(r1)
/* 8038B0B8 00388018 38 03 27 78 */ addi r0, r3, lbl_803F2778@l
/* 8038B0B8 00388018 38 03 27 78 */ addi r0, r3, __files@l
/* 8038B0BC 0038801C 93 E1 00 0C */ stw r31, 0xc(r1)
/* 8038B0C0 00388020 3B E0 00 00 */ li r31, 0
/* 8038B0C4 00388024 93 C1 00 08 */ stw r30, 8(r1)
@ -52,9 +154,9 @@ lbl_8038B0F4:
__close_all:
/* 8038B118 00388078 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8038B11C 0038807C 7C 08 02 A6 */ mflr r0
/* 8038B120 00388080 3C 60 80 3F */ lis r3, lbl_803F2778@ha
/* 8038B120 00388080 3C 60 80 3F */ lis r3, __files@ha
/* 8038B124 00388084 90 01 00 14 */ stw r0, 0x14(r1)
/* 8038B128 00388088 38 03 27 78 */ addi r0, r3, lbl_803F2778@l
/* 8038B128 00388088 38 03 27 78 */ addi r0, r3, __files@l
/* 8038B12C 0038808C 93 E1 00 0C */ stw r31, 0xc(r1)
/* 8038B130 00388090 7C 1F 03 78 */ mr r31, r0
/* 8038B134 00388094 48 00 00 60 */ b lbl_8038B194

View File

@ -3,105 +3,6 @@
.section .data, "wa"
.balign 8
.global lbl_803F2778
lbl_803F2778:
# ROM: 0x3EF778
.4byte 0
.4byte 0x0A800000
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte stdin_buff
.4byte 0x00000100
.4byte stdin_buff
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte __read_console
.4byte __write_console
.4byte __close_console
.4byte 0
.4byte lbl_803F27C8
.global lbl_803F27C8
lbl_803F27C8:
# ROM: 0x3EF7C8
.4byte 0x00000001
.4byte 0x12800000
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte stdout_buff
.4byte 0x00000100
.4byte stdout_buff
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte __read_console
.4byte __write_console
.4byte __close_console
.4byte 0
.4byte lbl_803F2818
.global lbl_803F2818
lbl_803F2818:
# ROM: 0x3EF818
.4byte 0x00000002
.4byte 0x10800000
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte stderr_buff
.4byte 0x00000100
.4byte stderr_buff
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte __read_console
.4byte __write_console
.4byte __close_console
.4byte 0
.4byte lbl_803F2868
.global lbl_803F2868
lbl_803F2868:
# ROM: 0x3EF868
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.global lbl_803F28B8
lbl_803F28B8:
# ROM: 0x3EF8B8
@ -2389,4 +2290,3 @@ lbl_805AEC80:
lbl_805AEC88:
# ROM: 0x3FB528
.double 4.503601774854144E15

View File

@ -289,12 +289,12 @@ lbl_8038DE20:
vprintf:
/* 8038DE34 0038AD94 94 21 FF E0 */ stwu r1, -0x20(r1)
/* 8038DE38 0038AD98 7C 08 02 A6 */ mflr r0
/* 8038DE3C 0038AD9C 3C A0 80 3F */ lis r5, lbl_803F2778@ha
/* 8038DE3C 0038AD9C 3C A0 80 3F */ lis r5, __files@ha
/* 8038DE40 0038ADA0 90 01 00 24 */ stw r0, 0x24(r1)
/* 8038DE44 0038ADA4 93 E1 00 1C */ stw r31, 0x1c(r1)
/* 8038DE48 0038ADA8 93 C1 00 18 */ stw r30, 0x18(r1)
/* 8038DE4C 0038ADAC 7C 9E 23 78 */ mr r30, r4
/* 8038DE50 0038ADB0 38 85 27 78 */ addi r4, r5, lbl_803F2778@l
/* 8038DE50 0038ADB0 38 85 27 78 */ addi r4, r5, __files@l
/* 8038DE54 0038ADB4 93 A1 00 14 */ stw r29, 0x14(r1)
/* 8038DE58 0038ADB8 3B E4 00 50 */ addi r31, r4, 0x50
/* 8038DE5C 0038ADBC 7C 7D 1B 78 */ mr r29, r3
@ -339,9 +339,9 @@ printf:
/* 8038DEE4 0038AE44 D8 E1 00 58 */ stfd f7, 0x58(r1)
/* 8038DEE8 0038AE48 D9 01 00 60 */ stfd f8, 0x60(r1)
lbl_8038DEEC:
/* 8038DEEC 0038AE4C 3D 60 80 3F */ lis r11, lbl_803F2778@ha
/* 8038DEEC 0038AE4C 3D 60 80 3F */ lis r11, __files@ha
/* 8038DEF0 0038AE50 90 81 00 0C */ stw r4, 0xc(r1)
/* 8038DEF4 0038AE54 39 6B 27 78 */ addi r11, r11, lbl_803F2778@l
/* 8038DEF4 0038AE54 39 6B 27 78 */ addi r11, r11, __files@l
/* 8038DEF8 0038AE58 38 80 FF FF */ li r4, -1
/* 8038DEFC 0038AE5C 90 61 00 08 */ stw r3, 8(r1)
/* 8038DF00 0038AE60 3B EB 00 50 */ addi r31, r11, 0x50
@ -2572,4 +2572,3 @@ lbl_805AEC98:
# ROM: 0x3FB538
.4byte 0
.4byte 0

View File

@ -852,14 +852,14 @@ LIBS = [
["Runtime/Gecko_ExceptionPPC", True],
["Runtime/abort_exit", True],
"Runtime/alloc",
"Runtime/ansi_files",
["Runtime/ansi_files", True],
"Runtime/ansi_fp",
"Runtime/arith",
"Runtime/buffer_io",
["Runtime/buffer_io", True],
["Runtime/ctype", True],
["Runtime/locale", True],
"Runtime/direct_io",
"Runtime/file_io",
["Runtime/direct_io", True],
["Runtime/file_io", True],
"Runtime/FILE_POS",
"Runtime/mbstring",
["Runtime/mem", True],

30
libc/ansi_files.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _DOLPHIN_ANSI_FILES_H
#define _DOLPHIN_ANSI_FILES_H
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif // ifdef __cplusplus
#define set_eof(file) \
do { \
(file)->state.io_state = __neutral; \
(file)->state.eof = 1; \
(file)->buffer_len = 0; \
} while (0)
#define set_error(file) \
do { \
(file)->state.error = 1; \
(file)->buffer_len = 0; \
} while (0)
int __flush_buffer(FILE* file, size_t* length);
void __prep_buffer(FILE* file);
int __flush_all();
#ifdef __cplusplus
};
#endif // ifdef __cplusplus
#endif

14
libc/buffer_io.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _BUFFER_IO
#define _BUFFER_IO
#include <stdio.h>
enum { __align_buffer, __dont_align_buffer };
void __convert_from_newlines(unsigned char* p, size_t* n);
void __convert_to_newlines(unsigned char* p, size_t* n);
void __prep_buffer(FILE*);
int __load_buffer(FILE*, size_t* bytes_loaded, int alignment);
int __flush_buffer(FILE*, size_t* bytes_flushed);
#endif // _BUFFER_IO

View File

@ -1,6 +1,7 @@
#ifndef _STDIO_H_
#define _STDIO_H_
#ifndef _STDIO
#define _STDIO
#include "types.h"
#include <stdarg.h>
#include <stddef.h>
@ -8,6 +9,10 @@
extern "C" {
#endif
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define __ungetc_buffer_size 2
typedef unsigned long __file_handle;
@ -16,8 +21,29 @@ typedef unsigned long fpos_t;
typedef unsigned short wchar_t;
#endif
enum __file_kinds { __closed_file, __disk_file, __console_file, __unavailable_file };
enum __file_orientation { __unoriented, __char_oriented, __wide_oriented };
enum __io_modes {
__read = 1,
__write = 2,
__read_write = 3,
__append = 4,
};
enum __file_kinds {
__closed_file,
__disk_file,
__console_file,
__unavailable_file,
};
enum __file_orientation {
__unoriented,
__char_oriented,
__wide_oriented,
};
enum __io_results {
__no_io_error,
__io_error,
__io_EOF,
};
typedef struct {
unsigned int open_mode : 2;
@ -28,6 +54,13 @@ typedef struct {
unsigned int binary_io : 1;
} __file_modes;
enum __io_states {
__neutral,
__writing,
__reading,
__rereading,
};
typedef struct {
unsigned int io_state : 3;
unsigned int free_buffer : 1;
@ -35,12 +68,13 @@ typedef struct {
unsigned char error;
} __file_state;
typedef void* __ref_con;
typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __ref_con ref_con);
typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count, __ref_con ref_con);
typedef void (*__idle_proc)(void);
typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __idle_proc idle_proc);
typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count,
__idle_proc idle_proc);
typedef int (*__close_proc)(__file_handle file);
typedef struct _FILE {
typedef struct _IO_FILE {
__file_handle handle;
__file_modes mode;
__file_state state;
@ -61,18 +95,24 @@ typedef struct _FILE {
__io_proc read_proc;
__io_proc write_proc;
__close_proc close_proc;
__ref_con ref_con;
struct _FILE* next_file_struct;
__idle_proc idle_proc;
struct _IO_FILE* next_file_struct;
} FILE;
#define _IONBF 0
#define _IOLBF 1
#define _IOFBF 2
int puts(const char* s);
int printf(const char*, ...);
int sprintf(char* s, const char* format, ...);
int vprintf(const char* format, va_list arg);
int vsprintf(char* s, const char* format, va_list arg);
size_t fwrite(const void*, size_t memb_size, size_t num_memb, FILE*);
size_t __fwrite(const void*, size_t, size_t, FILE*);
#ifdef __cplusplus
}
#endif
#endif
#endif // _STDIO

View File

@ -727,14 +727,14 @@ MSL_PPCEABI_BARE_H :=\
$(BUILD_DIR)/src/Runtime/Gecko_ExceptionPPC.o\
$(BUILD_DIR)/src/Runtime/abort_exit.o\
$(BUILD_DIR)/asm/Runtime/alloc.o\
$(BUILD_DIR)/asm/Runtime/ansi_files.o\
$(BUILD_DIR)/src/Runtime/ansi_files.o\
$(BUILD_DIR)/asm/Runtime/ansi_fp.o\
$(BUILD_DIR)/asm/Runtime/arith.o\
$(BUILD_DIR)/asm/Runtime/buffer_io.o\
$(BUILD_DIR)/src/Runtime/buffer_io.o\
$(BUILD_DIR)/src/Runtime/ctype.o\
$(BUILD_DIR)/src/Runtime/locale.o\
$(BUILD_DIR)/asm/Runtime/direct_io.o\
$(BUILD_DIR)/asm/Runtime/file_io.o\
$(BUILD_DIR)/src/Runtime/direct_io.o\
$(BUILD_DIR)/src/Runtime/file_io.o\
$(BUILD_DIR)/asm/Runtime/FILE_POS.o\
$(BUILD_DIR)/asm/Runtime/mbstring.o\
$(BUILD_DIR)/src/Runtime/mem.o\

View File

@ -0,0 +1,28 @@
#include "Kyoto/Streams/CMemoryStreamOut.hpp"
#include "Kyoto/Alloc/CMemory.hpp"
#include <string.h>
CMemoryStreamOut::CMemoryStreamOut(void* buffer, size_t len, EOwnerShip ownerShip, int blockLen)
: COutputStream(blockLen)
, mOutPtr(buffer)
, mOutLength(len)
, mCurrentPosition(0)
, mBufferOwned(ownerShip == kOS_Owned) {}
CMemoryStreamOut::~CMemoryStreamOut() {
COutputStream::Flush();
if (mBufferOwned) {
delete[] mOutPtr;
}
}
void CMemoryStreamOut::Write(const void* ptr, size_t len) {
len = (mOutLength - mCurrentPosition) < len ? (mOutLength - mCurrentPosition) : len;
if (len != 0) {
memcpy(static_cast<uchar*>(mOutPtr) + mCurrentPosition, ptr, len);
mCurrentPosition += len;
}
}

View File

@ -0,0 +1,32 @@
#include "Kyoto/Streams/CZipInputStream.hpp"
#include "Kyoto/Streams/CZipSupport.hpp"
CZipInputStream::CZipInputStream(rstl::auto_ptr<CInputStream> in)
: CInputStream(4096)
, mCompBuf(new uchar[4096])
, mStream(in)
, mZStream(new z_stream_s) {
z_stream_s* zs = mZStream.get();
zs->next_in = mCompBuf.get();
mZStream->avail_in = 0;
mZStream->zalloc = CZipSupport::Alloc;
mZStream->zfree = CZipSupport::Free;
mZStream->opaque = 0;
inflateInit2(mZStream.get());
}
CZipInputStream::~CZipInputStream() {
inflateEnd(mZStream.get());
}
size_t CZipInputStream::Read(void* buf, size_t len) {
mZStream->next_out = static_cast<Bytef*>(buf);
mZStream->avail_out = len;
if (mZStream->avail_in == 0) {
mZStream->avail_in = mStream->ReadBytes(mCompBuf.get(), 4096);
mZStream->next_in = mCompBuf.get();
}
inflate(mZStream.get(), Z_NO_FLUSH);
return len - mZStream->avail_out;
}

View File

@ -0,0 +1,18 @@
#include "Kyoto/Streams/CZipSupport.hpp"
#include "Kyoto/Alloc/CMemory.hpp"
#include "zlib/zlib.h"
static char* hack() {
return ZLIB_VERSION;
}
void* CZipSupport::Alloc(void* ptr1, uint w1, uint w2) {
return new uchar[w1 * w2];
}
void CZipSupport::Free(void* ptr1, void* ptr2) {
if (ptr2 == nullptr) {
return;
}
delete[] ptr2;
}

View File

@ -1,4 +1,5 @@
#include "MetroTRK/TrkInit.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
@ -11,7 +12,9 @@ void EnableMetroTRKInterrupts() {}
void InitMetroTRK() {}
// 80003648
int __read_console() { return 0; }
int __read_console(__file_handle file, fpos_t* position, int mode, __idle_proc __idle_proc) {
return 0;
}
// 80003650
int __TRK_write_console() { return 0; }

0
src/Runtime/alloc.c Normal file
View File

119
src/Runtime/ansi_files.c Normal file
View File

@ -0,0 +1,119 @@
#include "ansi_files.h"
static unsigned char stdin_buff[0x100];
static unsigned char stdout_buff[0x100];
static unsigned char stderr_buff[0x100];
extern int fclose(FILE*);
extern int __read_console(__file_handle file, unsigned char* buff, size_t* count,
__idle_proc idle_proc);
extern int __write_console(__file_handle file, unsigned char* buff, size_t* count,
__idle_proc idle_proc);
extern int __close_console(__file_handle file);
FILE __files[4] = {
{0,
{0, 1, 1, 2, 0},
{0, 0, 0, 0},
0,
0,
0,
{0, 0},
{0, 0},
0,
stdin_buff,
sizeof(stdin_buff),
stdin_buff,
0,
0,
0,
0,
NULL,
&__read_console,
&__write_console,
&__close_console,
0,
&__files[1]},
{1,
{0, 2, 1, 2, 0},
{0, 0, 0, 0},
0,
0,
0,
{0, 0},
{0, 0},
0,
stdout_buff,
sizeof(stdout_buff),
stdout_buff,
0,
0,
0,
0,
NULL,
&__read_console,
&__write_console,
&__close_console,
0,
&__files[2]},
{2,
{0, 2, 0, 2, 0},
{0, 0, 0, 0},
0,
0,
0,
{0, 0},
{0, 0},
0,
stderr_buff,
sizeof(stderr_buff),
stderr_buff,
0,
0,
0,
0,
NULL,
&__read_console,
&__write_console,
&__close_console,
0,
&__files[3]},
};
void __close_all() {
FILE* p = &__files[0];
FILE* plast;
// __begin_critical_region(2);
while (p != NULL) {
if (p->mode.file_kind != __closed_file) {
fclose(p);
}
plast = p;
p = p->next_file_struct;
if (plast->is_dynamically_allocated)
free(plast);
else {
plast->mode.file_kind = __unavailable_file;
if ((p != NULL) && p->is_dynamically_allocated)
plast->next_file_struct = NULL;
}
}
// __end_critical_region(2);
}
int __flush_all() {
int retval = 0;
FILE* __stream;
__stream = &__files[0];
while (__stream) {
if ((__stream->mode.file_kind) && (fflush(__stream))) {
retval = -1;
}
__stream = __stream->next_file_struct;
};
return retval;
}

43
src/Runtime/buffer_io.c Normal file
View File

@ -0,0 +1,43 @@
#include "buffer_io.h"
void __convert_from_newlines(unsigned char* buf, size_t* n) {
}
void __convert_to_newlines(unsigned char* buf, size_t* n) {
}
void __prep_buffer(FILE* file) {
file->buffer_ptr = file->buffer;
file->buffer_len = file->buffer_size;
file->buffer_len -= file->position & file->buffer_alignment;
file->buffer_pos = file->position;
}
int __flush_buffer(FILE* file, size_t* bytes_flushed) {
size_t buffer_len;
int ioresult;
buffer_len = file->buffer_ptr - file->buffer;
if (buffer_len) {
file->buffer_len = buffer_len;
if (!file->mode.binary_io)
__convert_from_newlines(file->buffer, (size_t*)&file->buffer_len);
ioresult = (*file->write_proc)(file->handle, file->buffer, (size_t*)&file->buffer_len,
file->idle_proc);
if (bytes_flushed)
*bytes_flushed = file->buffer_len;
if (ioresult)
return (ioresult);
file->position += file->buffer_len;
}
__prep_buffer(file);
return 0;
}

114
src/Runtime/direct_io.c Normal file
View File

@ -0,0 +1,114 @@
#include <ansi_files.h>
#include <stdio.h>
size_t fwrite(const void* ptr, size_t memb_size, size_t num_memb, FILE* file) {
size_t retval;
retval = __fwrite(ptr, memb_size, num_memb, file);
return (retval);
}
size_t __fwrite(const void* ptr, size_t memb_size, size_t num_memb, FILE* file) {
unsigned char* write_ptr;
size_t num_bytes, bytes_to_go, bytes_written;
int ioresult, always_buffer;
#ifndef __NO_WIDE_CHAR
if (fwide(file, 0) == 0)
fwide(file, -1);
#endif
bytes_to_go = memb_size * num_memb;
if (!bytes_to_go || file->state.error || file->mode.file_kind == __closed_file)
return 0;
if (file->mode.file_kind == __console_file)
__stdio_atexit();
always_buffer =
!file->mode.binary_io || file->mode.buffer_mode == _IOFBF || file->mode.buffer_mode == _IOLBF;
if (file->state.io_state == __neutral) {
if (file->mode.io_mode & __write) {
if (file->mode.io_mode & __append) {
if (fseek(file, 0, SEEK_END))
return 0;
}
file->state.io_state = __writing;
__prep_buffer(file);
}
}
if (file->state.io_state != __writing) {
set_error(file);
return 0;
}
write_ptr = (unsigned char*)ptr;
bytes_written = 0;
if (bytes_to_go && (file->buffer_ptr != file->buffer || always_buffer)) {
file->buffer_len = file->buffer_size - (file->buffer_ptr - file->buffer);
do {
unsigned char* newline = NULL;
num_bytes = file->buffer_len;
if (num_bytes > bytes_to_go)
num_bytes = bytes_to_go;
if (file->mode.buffer_mode == _IOLBF && num_bytes)
if ((newline = (unsigned char*)__memrchr(write_ptr, '\n', num_bytes)) != NULL)
num_bytes = newline + 1 - write_ptr;
if (num_bytes) {
memcpy(file->buffer_ptr, write_ptr, num_bytes);
write_ptr += num_bytes;
bytes_written += num_bytes;
bytes_to_go -= num_bytes;
file->buffer_ptr += num_bytes;
file->buffer_len -= num_bytes;
}
if (!file->buffer_len || newline != NULL ||
(file->mode.buffer_mode == _IONBF))
{
ioresult = __flush_buffer(file, NULL);
if (ioresult) {
set_error(file);
bytes_to_go = 0;
break;
}
}
} while (bytes_to_go && always_buffer);
}
if (bytes_to_go && !always_buffer) {
unsigned char* save_buffer = file->buffer;
size_t save_size = file->buffer_size;
file->buffer = write_ptr;
file->buffer_size = bytes_to_go;
file->buffer_ptr = write_ptr + bytes_to_go;
if (__flush_buffer(file, &num_bytes) != __no_io_error)
set_error(file);
bytes_written += num_bytes;
file->buffer = save_buffer;
file->buffer_size = save_size;
__prep_buffer(file);
file->buffer_len = 0;
}
if (file->mode.buffer_mode != _IOFBF)
file->buffer_len = 0;
return ((bytes_written + memb_size - 1) / memb_size);
}

70
src/Runtime/file_io.c Normal file
View File

@ -0,0 +1,70 @@
#include "ansi_files.h"
#include "types.h"
#pragma dont_inline on
int fclose(FILE* file) {
int flush_result, close_result;
if (file == nullptr)
return (-1);
if (file->mode.file_kind == __closed_file)
return (0);
flush_result = fflush(file);
close_result = (*file->close_proc)(file->handle);
file->mode.file_kind = __closed_file;
file->handle = NULL;
if (file->state.free_buffer)
free(file->buffer);
return ((flush_result || close_result) ? -1 : 0);
}
int fflush(FILE* file) {
int pos;
if (file == nullptr) {
return __flush_all();
}
if (file->state.error != 0 || file->mode.file_kind == __closed_file) {
return -1;
}
if (file->mode.io_mode == 1) {
return 0;
}
if (file->state.io_state >= 3) {
file->state.io_state = 2;
}
if (file->state.io_state == 2) {
file->buffer_len = 0;
}
if (file->state.io_state != 1) {
file->state.io_state = 0;
return 0;
}
if (file->mode.file_kind != __disk_file) {
pos = 0;
} else {
pos = ftell(file);
}
if (__flush_buffer(file, 0) != 0) {
file->state.error = 1;
file->buffer_len = 0;
return -1;
}
file->state.io_state = 0;
file->position = pos;
file->buffer_len = 0;
return 0;
}
#pragma dont_inline reset