mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2024-12-28 04:23:38 +01:00
stdio: basic fread/fwrite (WIP)
This commit is contained in:
parent
b6dbdf321d
commit
4461bdb96a
14 changed files with 222 additions and 33 deletions
|
@ -130,10 +130,15 @@ set(SOURCES
|
|||
src/libc/stdio/fileutil.c
|
||||
src/libc/stdio/fopen.c
|
||||
src/libc/stdio/fprintf.c
|
||||
src/libc/stdio/fread.c
|
||||
src/libc/stdio/freopen.c
|
||||
src/libc/stdio/fseek.c
|
||||
src/libc/stdio/fsetpos.c
|
||||
src/libc/stdio/ftell.c
|
||||
src/libc/stdio/fwrite.c
|
||||
src/libc/stdio/getc.c
|
||||
src/libc/stdio/getchar.c
|
||||
src/libc/stdio/gets.c
|
||||
src/libc/stdio/printf.c
|
||||
src/libc/stdio/printf/format_fixed.c
|
||||
src/libc/stdio/printf/format_fp.c
|
||||
|
@ -141,6 +146,7 @@ set(SOURCES
|
|||
src/libc/stdio/printf/print.c
|
||||
src/libc/stdio/printf/util.c
|
||||
src/libc/stdio/putc.c
|
||||
src/libc/stdio/putchar.c
|
||||
src/libc/stdio/puts.c
|
||||
src/libc/stdio/remove.c
|
||||
src/libc/stdio/rewind.c
|
||||
|
|
16
STATUS
16
STATUS
|
@ -122,16 +122,16 @@ TEST: Function/symbol/macro needs to be tested
|
|||
7.19.7.2 fgets TODO
|
||||
7.19.7.3 fputc TODO
|
||||
7.19.7.4 fputs TODO
|
||||
7.19.7.5 getc TODO
|
||||
7.19.7.6 getchar TODO
|
||||
7.19.7.7 gets TODO
|
||||
7.19.7.8 putc TODO
|
||||
7.19.7.9 putchar TODO
|
||||
7.19.7.10 puts TODO
|
||||
7.19.7.5 getc LDEPS(fgetc)
|
||||
7.19.7.6 getchar LDEPS(fgetc)
|
||||
7.19.7.7 gets LDEPS(fgets)
|
||||
7.19.7.8 putc LDPES(fputc)
|
||||
7.19.7.9 putchar LDEPS(fputc)
|
||||
7.19.7.10 puts LDEPS(fputs)
|
||||
7.19.7.11 ungetc TODO
|
||||
|
||||
7.19.8.1 fread TODO
|
||||
7.19.8.2 fwrite TODO
|
||||
7.19.8.1 fread TEST
|
||||
7.19.8.2 fwrite TEST
|
||||
|
||||
7.19.9.1 fgetpos TEST
|
||||
7.19.9.2 fseek TEST
|
||||
|
|
|
@ -175,7 +175,60 @@ extern int vasprintf(char ** __restrict__ __str,
|
|||
char const * __restrict__ __format, va_list __args);
|
||||
|
||||
/*
|
||||
** File positioning functions;
|
||||
** Character input/output functions.
|
||||
*/
|
||||
|
||||
/* Read a character from a stream. */
|
||||
extern int fgetc(FILE *__fp);
|
||||
|
||||
/* Read at most n characters from a stream, stopping after a newline. */
|
||||
extern char *fgets(char * __restrict__ __s, int __n,
|
||||
FILE * __restrict__ __fp);
|
||||
|
||||
/* Write a character to a stream. */
|
||||
extern int fputc(int __c, FILE *__fp);
|
||||
|
||||
/* Write a string to a stream (excluding the NUL nyte). */
|
||||
extern int fputs(char const * __restrict__ s, FILE * __restrict__ fp);
|
||||
|
||||
extern int getc(FILE *__fp);
|
||||
#define getc fgetc
|
||||
|
||||
/* Get a character from stdin */
|
||||
extern int getchar(void);
|
||||
#define getchar() fgetc(stdin)
|
||||
|
||||
/* (DEPRECATED; use fgets() instead) Read a string from stdin. */
|
||||
extern char *gets(char *__s);
|
||||
|
||||
extern int putc(int __c, FILE *__fp);
|
||||
#define putc fputc
|
||||
|
||||
/* Write a character to stdout */
|
||||
extern int putchar(int __c);
|
||||
#define putchar(__c) fputc(__c, stdout)
|
||||
|
||||
/* Write a string to stdout, followed by a newline */
|
||||
extern int puts(char const *__s);
|
||||
|
||||
/* Un-read a character back to the stream; only one ungetc() is guaranteed, and
|
||||
the character is lost after reading, writing or flushing. */
|
||||
extern int ungetc(int __c, FILE *__fp);
|
||||
|
||||
/*
|
||||
** Direct input/output functions.
|
||||
*/
|
||||
|
||||
/* Read an array of items from a stream. */
|
||||
extern size_t fread(void * __restrict__ __ptr, size_t __size, size_t __nmemb,
|
||||
FILE * __restrict__ __fp);
|
||||
|
||||
/* Write an array of items to a stream. */
|
||||
extern size_t fwrite(void const * __restrict__ __ptr, size_t __size,
|
||||
size_t __nmemb, FILE * __restrict__ __fp);
|
||||
|
||||
/*
|
||||
** File positioning functions.
|
||||
*/
|
||||
|
||||
/* Get current position (same as ftell() unless wide-oriented). */
|
||||
|
|
|
@ -14,7 +14,7 @@ int fflush(FILE *fp)
|
|||
return 0;
|
||||
|
||||
/* In reading mode, reset the file offset */
|
||||
if(fp->bufmode == __FILE_BUF_READ && fp->bufpos < fp->bufread) {
|
||||
if(fp->bufdir == __FILE_BUF_READ && fp->bufpos < fp->bufread) {
|
||||
fp->fdpos = fp->fdpos - fp->bufread + fp->bufpos;
|
||||
lseek(fp->fd, fp->fdpos, SEEK_SET);
|
||||
fp->bufpos = 0;
|
||||
|
@ -23,7 +23,7 @@ int fflush(FILE *fp)
|
|||
}
|
||||
|
||||
/* In writing mode, write pending data */
|
||||
if(fp->bufmode == __FILE_BUF_WRITE && fp->bufpos > 0) {
|
||||
if(fp->bufdir == __FILE_BUF_WRITE && fp->bufpos > 0) {
|
||||
ssize_t written = __fp_write(fp, fp->buf, fp->bufpos);
|
||||
fp->bufpos = 0;
|
||||
return (written == (ssize_t)fp->bufpos ? 0 : EOF);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "fileutil.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
int __fp_open(FILE *fp, int fd, bool use_buffering)
|
||||
|
@ -28,6 +29,23 @@ void __fp_close(FILE *fp, bool free_fp)
|
|||
free(fp);
|
||||
}
|
||||
|
||||
void __fp_buffer_mode_read(FILE *fp)
|
||||
{
|
||||
if(fp->buf && fp->bufdir == __FILE_BUF_WRITE && fp->bufpos > 0) {
|
||||
fflush(fp);
|
||||
fp->bufdir = __FILE_BUF_READ;
|
||||
}
|
||||
}
|
||||
|
||||
void __fp_buffer_mode_write(FILE *fp)
|
||||
{
|
||||
if(fp->buf && fp->bufdir == __FILE_BUF_READ
|
||||
&& fp->bufpos < fp->bufread) {
|
||||
fflush(fp);
|
||||
fp->bufdir = __FILE_BUF_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t __fp_read(FILE *fp, void *data, size_t size)
|
||||
{
|
||||
size_t read_ = 0;
|
||||
|
@ -39,8 +57,10 @@ ssize_t __fp_read(FILE *fp, void *data, size_t size)
|
|||
fp->error = 1;
|
||||
return EOF;
|
||||
}
|
||||
if(rc == 0)
|
||||
if(rc == 0) {
|
||||
fp->eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
fp->fdpos += rc;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,12 @@ int __fp_open(FILE *fp, int fd, bool use_buffering);
|
|||
/* Close fp and free all of its resources. */
|
||||
void __fp_close(FILE *fp, bool free_fp);
|
||||
|
||||
/* Set reading mode on the buffer. */
|
||||
void __fp_buffer_mode_read(FILE *fp);
|
||||
|
||||
/* Set writing mode on the buffer. */
|
||||
void __fp_buffer_mode_write(FILE *fp);
|
||||
|
||||
/* Reads data from a file descriptor; updates the fdpos and sets the error
|
||||
indicator. Returns 0 on success, EOF on error. */
|
||||
ssize_t __fp_read(FILE *fp, void *data, size_t size);
|
||||
|
|
45
src/libc/stdio/fread.c
Normal file
45
src/libc/stdio/fread.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fileutil.h"
|
||||
|
||||
size_t fread(void *data, size_t membsize, size_t nmemb, FILE *fp)
|
||||
{
|
||||
size_t size;
|
||||
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
|
||||
fp->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!fp->buf) {
|
||||
ssize_t rc = __fp_read(fp, data, size);
|
||||
return (rc == EOF) ? 0 : rc;
|
||||
}
|
||||
|
||||
__fp_buffer_mode_read(fp);
|
||||
|
||||
size_t size_read = 0;
|
||||
while(size_read < size) {
|
||||
/* Take what's available in the buffer (may be 0) */
|
||||
size_t size_frag = fp->bufread - fp->bufpos;
|
||||
if(size_frag > size - size_read)
|
||||
size_frag = size - size_read;
|
||||
memcpy(data + size_read, fp->buf + fp->bufpos, size_frag);
|
||||
size_read += size_frag;
|
||||
fp->bufpos += size_frag;
|
||||
|
||||
if(fp->bufpos >= fp->bufread) {
|
||||
fp->bufread = 0;
|
||||
fp->bufpos = 0;
|
||||
}
|
||||
if(size_read >= size)
|
||||
break;
|
||||
|
||||
/* Get more data */
|
||||
ssize_t rc = __fp_read(fp, fp->buf, fp->bufsize);
|
||||
if(rc <= 0) /* EOF or error */
|
||||
break;
|
||||
fp->bufread = rc;
|
||||
}
|
||||
|
||||
return size_read;
|
||||
}
|
42
src/libc/stdio/fwrite.c
Normal file
42
src/libc/stdio/fwrite.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fileutil.h"
|
||||
|
||||
size_t fwrite(void const *data, size_t membsize, size_t nmemb, FILE *fp)
|
||||
{
|
||||
size_t size;
|
||||
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
|
||||
fp->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!fp->buf) {
|
||||
ssize_t rc = __fp_write(fp, data, size);
|
||||
return (rc == EOF) ? 0 : rc;
|
||||
}
|
||||
|
||||
__fp_buffer_mode_write(fp);
|
||||
|
||||
// TODO: fwrite: line buffering
|
||||
|
||||
size_t size_written = 0;
|
||||
while(size_written < size) {
|
||||
/* Fill the buffer */
|
||||
size_t size_frag = fp->bufsize - fp->bufpos;
|
||||
if(size_frag > size - size_written)
|
||||
size_frag = size - size_written;
|
||||
|
||||
memcpy(fp->buf + fp->bufpos, data + size_written, size_frag);
|
||||
size_written += size_frag;
|
||||
fp->bufpos += size_frag;
|
||||
|
||||
if(fp->bufpos >= fp->bufsize) {
|
||||
ssize_t rc = __fp_write(fp, fp->buf, fp->bufpos);
|
||||
if(rc <= 0) /* error */
|
||||
break;
|
||||
fp->bufpos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return size_written;
|
||||
}
|
7
src/libc/stdio/getc.c
Normal file
7
src/libc/stdio/getc.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#undef getc
|
||||
|
||||
int getc(FILE *fp)
|
||||
{
|
||||
return fgetc(fp);
|
||||
}
|
7
src/libc/stdio/getchar.c
Normal file
7
src/libc/stdio/getchar.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#undef getchar
|
||||
|
||||
int getchar(void)
|
||||
{
|
||||
return fgetc(stdin);
|
||||
}
|
7
src/libc/stdio/gets.c
Normal file
7
src/libc/stdio/gets.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
extern char *gets(char *s)
|
||||
{
|
||||
return fgets(s, INT_MAX, stdin);
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#undef putc
|
||||
|
||||
int putchar(int c)
|
||||
int putc(int c, FILE *fp)
|
||||
{
|
||||
char n;
|
||||
|
||||
n = (char)c;
|
||||
write(STDOUT_FILENO, &n, 1);
|
||||
return (n);
|
||||
return fputc(c, fp);
|
||||
}
|
||||
|
|
7
src/libc/stdio/putchar.c
Normal file
7
src/libc/stdio/putchar.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#undef putchar
|
||||
|
||||
int putchar(int c)
|
||||
{
|
||||
return fputc(c, stdout);
|
||||
}
|
|
@ -1,18 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
** puts() writes the string s and a trailing newline to stdout.
|
||||
** FIXME: check last write error !
|
||||
*/
|
||||
int puts(const char *s)
|
||||
int puts(char const *s)
|
||||
{
|
||||
size_t size;
|
||||
size_t n;
|
||||
|
||||
size = strlen(s);
|
||||
n = write(STDOUT_FILENO, s, size);
|
||||
write(STDOUT_FILENO, "\n", 1);
|
||||
return (-(n == size));
|
||||
int rc = 0;
|
||||
if(fputs(s, stdout) != 0)
|
||||
rc = -1;
|
||||
if(fputc('\n', stdout) == EOF)
|
||||
rc = -1;
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue