mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2025-04-20 01:47:12 +02:00
stdio: line buffering, test fgetpos and fsetpos (DONE)
This commit is contained in:
parent
0c2f81e5bb
commit
06b66252c9
5 changed files with 46 additions and 18 deletions
24
STATUS
24
STATUS
|
@ -91,13 +91,13 @@ TEST: Function/symbol/macro needs to be tested
|
||||||
7.19.4.3 tmpfile TODO
|
7.19.4.3 tmpfile TODO
|
||||||
7.19.4.4 tmpnam TODO
|
7.19.4.4 tmpnam TODO
|
||||||
|
|
||||||
7.19.5.1 fclose TEST
|
7.19.5.1 fclose -
|
||||||
7.19.5.2 fflush TEST
|
7.19.5.2 fflush -
|
||||||
7.19.5.3 fopen TEST
|
7.19.5.3 fopen TEST ("a" and "+" modes remain)
|
||||||
(EXT) fdopen TEST
|
(EXT) fdopen TEST
|
||||||
7.19.5.4 freopen TEST
|
7.19.5.4 freopen TEST
|
||||||
7.19.5.5 setbuf TEST
|
7.19.5.5 setbuf -
|
||||||
7.19.5.6 setvbuf TEST
|
7.19.5.6 setvbuf -
|
||||||
|
|
||||||
7.19.6.1 fprintf LDEPS(fwrite)
|
7.19.6.1 fprintf LDEPS(fwrite)
|
||||||
7.19.6.2 fscanf TODO
|
7.19.6.2 fscanf TODO
|
||||||
|
@ -130,14 +130,14 @@ TEST: Function/symbol/macro needs to be tested
|
||||||
7.19.7.10 puts LDEPS(fputs)
|
7.19.7.10 puts LDEPS(fputs)
|
||||||
7.19.7.11 ungetc TODO
|
7.19.7.11 ungetc TODO
|
||||||
|
|
||||||
7.19.8.1 fread TEST
|
7.19.8.1 fread TEST ("a" and "+" modes remain)
|
||||||
7.19.8.2 fwrite TEST
|
7.19.8.2 fwrite TEST ("a" and "+" modes remain)
|
||||||
|
|
||||||
7.19.9.1 fgetpos TEST
|
7.19.9.1 fgetpos -
|
||||||
7.19.9.2 fseek TEST
|
7.19.9.2 fseek -
|
||||||
7.19.9.3 fsetpos TEST
|
7.19.9.3 fsetpos -
|
||||||
7.19.9.4 ftell TEST
|
7.19.9.4 ftell -
|
||||||
7.19.9.5 rewind TEST
|
7.19.9.5 rewind -
|
||||||
|
|
||||||
7.19.10.1 clearerr -
|
7.19.10.1 clearerr -
|
||||||
7.19.10.2 feof -
|
7.19.10.2 feof -
|
||||||
|
|
|
@ -77,6 +77,12 @@ ssize_t __fp_write(FILE *fp, void const *data, size_t size)
|
||||||
{
|
{
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
|
||||||
|
if(fp->append) {
|
||||||
|
int rc = fseek(fp, 0, SEEK_END);
|
||||||
|
if(rc < 0)
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
while(written < size) {
|
while(written < size) {
|
||||||
ssize_t rc = write(fp->fd, data + written, size - written);
|
ssize_t rc = write(fp->fd, data + written, size - written);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
|
|
||||||
size_t fread(void *data, size_t membsize, size_t nmemb, FILE *fp)
|
size_t fread(void *data, size_t membsize, size_t nmemb, FILE *fp)
|
||||||
{
|
{
|
||||||
|
if(!fp->readable) {
|
||||||
|
fp->error = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
|
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
|
||||||
fp->error = 1;
|
fp->error = 1;
|
||||||
|
|
|
@ -6,7 +6,10 @@ int fsetpos(FILE *fp, fpos_t const *pos)
|
||||||
if(fflush(fp) == EOF)
|
if(fflush(fp) == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
lseek(fp->fd, *pos, SEEK_SET);
|
off_t rc = lseek(fp->fd, *pos, SEEK_SET);
|
||||||
|
if(rc < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
fp->fdpos = *pos;
|
fp->fdpos = *pos;
|
||||||
fp->eof = 0;
|
fp->eof = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
|
|
||||||
size_t fwrite(void const *data, size_t membsize, size_t nmemb, FILE *fp)
|
size_t fwrite(void const *data, size_t membsize, size_t nmemb, FILE *fp)
|
||||||
{
|
{
|
||||||
|
if(!fp->writable) {
|
||||||
|
fp->error = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
|
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
|
||||||
fp->error = 1;
|
fp->error = 1;
|
||||||
|
@ -17,20 +22,29 @@ size_t fwrite(void const *data, size_t membsize, size_t nmemb, FILE *fp)
|
||||||
|
|
||||||
__fp_buffer_mode_write(fp);
|
__fp_buffer_mode_write(fp);
|
||||||
|
|
||||||
// TODO: fwrite: line buffering
|
|
||||||
|
|
||||||
size_t size_written = 0;
|
size_t size_written = 0;
|
||||||
|
|
||||||
while(size_written < size) {
|
while(size_written < size) {
|
||||||
/* Fill the buffer */
|
|
||||||
size_t size_frag = fp->bufsize - fp->bufpos;
|
size_t size_frag = fp->bufsize - fp->bufpos;
|
||||||
if(size_frag > size - size_written)
|
void const *last_line = NULL;
|
||||||
|
|
||||||
|
if(size_frag >= size - size_written) {
|
||||||
size_frag = size - size_written;
|
size_frag = size - size_written;
|
||||||
|
|
||||||
|
/* In the last run, if line buffering is enabled and
|
||||||
|
there is a newline, stop at that newline and flush
|
||||||
|
before the last write to buffer */
|
||||||
|
if(fp->bufmode == _IOLBF) last_line = memrchr(
|
||||||
|
data + size_written, '\n', size_frag);
|
||||||
|
}
|
||||||
|
if(last_line)
|
||||||
|
size_frag = (last_line + 1) - (data + size_written);
|
||||||
|
|
||||||
memcpy(fp->buf + fp->bufpos, data + size_written, size_frag);
|
memcpy(fp->buf + fp->bufpos, data + size_written, size_frag);
|
||||||
size_written += size_frag;
|
size_written += size_frag;
|
||||||
fp->bufpos += size_frag;
|
fp->bufpos += size_frag;
|
||||||
|
|
||||||
if(fp->bufpos >= fp->bufsize) {
|
if(fp->bufpos >= fp->bufsize || last_line) {
|
||||||
ssize_t rc = __fp_write(fp, fp->buf, fp->bufpos);
|
ssize_t rc = __fp_write(fp, fp->buf, fp->bufpos);
|
||||||
if(rc <= 0) /* error */
|
if(rc <= 0) /* error */
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue