mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2025-04-20 01:47:12 +02: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/fileutil.c
|
||||||
src/libc/stdio/fopen.c
|
src/libc/stdio/fopen.c
|
||||||
src/libc/stdio/fprintf.c
|
src/libc/stdio/fprintf.c
|
||||||
|
src/libc/stdio/fread.c
|
||||||
src/libc/stdio/freopen.c
|
src/libc/stdio/freopen.c
|
||||||
src/libc/stdio/fseek.c
|
src/libc/stdio/fseek.c
|
||||||
src/libc/stdio/fsetpos.c
|
src/libc/stdio/fsetpos.c
|
||||||
src/libc/stdio/ftell.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.c
|
||||||
src/libc/stdio/printf/format_fixed.c
|
src/libc/stdio/printf/format_fixed.c
|
||||||
src/libc/stdio/printf/format_fp.c
|
src/libc/stdio/printf/format_fp.c
|
||||||
|
@ -141,6 +146,7 @@ set(SOURCES
|
||||||
src/libc/stdio/printf/print.c
|
src/libc/stdio/printf/print.c
|
||||||
src/libc/stdio/printf/util.c
|
src/libc/stdio/printf/util.c
|
||||||
src/libc/stdio/putc.c
|
src/libc/stdio/putc.c
|
||||||
|
src/libc/stdio/putchar.c
|
||||||
src/libc/stdio/puts.c
|
src/libc/stdio/puts.c
|
||||||
src/libc/stdio/remove.c
|
src/libc/stdio/remove.c
|
||||||
src/libc/stdio/rewind.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.2 fgets TODO
|
||||||
7.19.7.3 fputc TODO
|
7.19.7.3 fputc TODO
|
||||||
7.19.7.4 fputs TODO
|
7.19.7.4 fputs TODO
|
||||||
7.19.7.5 getc TODO
|
7.19.7.5 getc LDEPS(fgetc)
|
||||||
7.19.7.6 getchar TODO
|
7.19.7.6 getchar LDEPS(fgetc)
|
||||||
7.19.7.7 gets TODO
|
7.19.7.7 gets LDEPS(fgets)
|
||||||
7.19.7.8 putc TODO
|
7.19.7.8 putc LDPES(fputc)
|
||||||
7.19.7.9 putchar TODO
|
7.19.7.9 putchar LDEPS(fputc)
|
||||||
7.19.7.10 puts TODO
|
7.19.7.10 puts LDEPS(fputs)
|
||||||
7.19.7.11 ungetc TODO
|
7.19.7.11 ungetc TODO
|
||||||
|
|
||||||
7.19.8.1 fread TODO
|
7.19.8.1 fread TEST
|
||||||
7.19.8.2 fwrite TODO
|
7.19.8.2 fwrite TEST
|
||||||
|
|
||||||
7.19.9.1 fgetpos TEST
|
7.19.9.1 fgetpos TEST
|
||||||
7.19.9.2 fseek TEST
|
7.19.9.2 fseek TEST
|
||||||
|
|
|
@ -175,7 +175,60 @@ extern int vasprintf(char ** __restrict__ __str,
|
||||||
char const * __restrict__ __format, va_list __args);
|
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). */
|
/* Get current position (same as ftell() unless wide-oriented). */
|
||||||
|
|
|
@ -14,7 +14,7 @@ int fflush(FILE *fp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* In reading mode, reset the file offset */
|
/* 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;
|
fp->fdpos = fp->fdpos - fp->bufread + fp->bufpos;
|
||||||
lseek(fp->fd, fp->fdpos, SEEK_SET);
|
lseek(fp->fd, fp->fdpos, SEEK_SET);
|
||||||
fp->bufpos = 0;
|
fp->bufpos = 0;
|
||||||
|
@ -23,7 +23,7 @@ int fflush(FILE *fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In writing mode, write pending data */
|
/* 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);
|
ssize_t written = __fp_write(fp, fp->buf, fp->bufpos);
|
||||||
fp->bufpos = 0;
|
fp->bufpos = 0;
|
||||||
return (written == (ssize_t)fp->bufpos ? 0 : EOF);
|
return (written == (ssize_t)fp->bufpos ? 0 : EOF);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "fileutil.h"
|
#include "fileutil.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
int __fp_open(FILE *fp, int fd, bool use_buffering)
|
int __fp_open(FILE *fp, int fd, bool use_buffering)
|
||||||
|
@ -28,6 +29,23 @@ void __fp_close(FILE *fp, bool free_fp)
|
||||||
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)
|
ssize_t __fp_read(FILE *fp, void *data, size_t size)
|
||||||
{
|
{
|
||||||
size_t read_ = 0;
|
size_t read_ = 0;
|
||||||
|
@ -39,8 +57,10 @@ ssize_t __fp_read(FILE *fp, void *data, size_t size)
|
||||||
fp->error = 1;
|
fp->error = 1;
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
if(rc == 0)
|
if(rc == 0) {
|
||||||
|
fp->eof = 1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
fp->fdpos += rc;
|
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. */
|
/* Close fp and free all of its resources. */
|
||||||
void __fp_close(FILE *fp, bool free_fp);
|
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
|
/* Reads data from a file descriptor; updates the fdpos and sets the error
|
||||||
indicator. Returns 0 on success, EOF on error. */
|
indicator. Returns 0 on success, EOF on error. */
|
||||||
ssize_t __fp_read(FILE *fp, void *data, size_t size);
|
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 <stdio.h>
|
||||||
#include <unistd.h>
|
#undef putc
|
||||||
|
|
||||||
int putchar(int c)
|
int putc(int c, FILE *fp)
|
||||||
{
|
{
|
||||||
char n;
|
return fputc(c, fp);
|
||||||
|
|
||||||
n = (char)c;
|
|
||||||
write(STDOUT_FILENO, &n, 1);
|
|
||||||
return (n);
|
|
||||||
}
|
}
|
||||||
|
|
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 <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/*
|
int puts(char const *s)
|
||||||
** puts() writes the string s and a trailing newline to stdout.
|
|
||||||
** FIXME: check last write error !
|
|
||||||
*/
|
|
||||||
int puts(const char *s)
|
|
||||||
{
|
{
|
||||||
size_t size;
|
int rc = 0;
|
||||||
size_t n;
|
if(fputs(s, stdout) != 0)
|
||||||
|
rc = -1;
|
||||||
size = strlen(s);
|
if(fputc('\n', stdout) == EOF)
|
||||||
n = write(STDOUT_FILENO, s, size);
|
rc = -1;
|
||||||
write(STDOUT_FILENO, "\n", 1);
|
return rc;
|
||||||
return (-(n == size));
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue