Changeset 01cc7b4 in mainline


Ignore:
Timestamp:
2018-06-13T10:59:47Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f47a905
Parents:
ed18e14
git-author:
Jiri Svoboda <jiri@…> (2018-06-11 18:54:14)
git-committer:
Jiri Svoboda <jiri@…> (2018-06-13 10:59:47)
Message:

Implement sscanf via virtualizing FILE and implementing string backend for FILE.

Location:
uspace/lib/c
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    red18e14 r01cc7b4  
    132132        generic/malloc.c \
    133133        generic/stdio/scanf.c \
     134        generic/stdio/sstream.c \
    134135        generic/sysinfo.c \
    135136        generic/ipc.c \
  • uspace/lib/c/generic/io/io.c

    red18e14 r01cc7b4  
    5353static void _fflushbuf(FILE *stream);
    5454
     55static size_t stdio_kio_read(void *, size_t, size_t, FILE *);
     56static size_t stdio_kio_write(const void *, size_t, size_t, FILE *);
     57static int stdio_kio_flush(FILE *);
     58
     59static size_t stdio_vfs_read(void *, size_t, size_t, FILE *);
     60static size_t stdio_vfs_write(const void *, size_t, size_t, FILE *);
     61
     62static int stdio_vfs_flush(FILE *);
     63
     64/** KIO stream ops */
     65static __stream_ops_t stdio_kio_ops = {
     66        .read = stdio_kio_read,
     67        .write = stdio_kio_write,
     68        .flush = stdio_kio_flush
     69};
     70
     71/** VFS stream ops */
     72static __stream_ops_t stdio_vfs_ops = {
     73        .read = stdio_vfs_read,
     74        .write = stdio_vfs_write,
     75        .flush = stdio_vfs_flush
     76};
     77
    5578static FILE stdin_null = {
    5679        .fd = -1,
     
    5881        .error = true,
    5982        .eof = true,
    60         .kio = false,
     83        .ops = &stdio_vfs_ops,
     84        .arg = NULL,
    6185        .sess = NULL,
    6286        .btype = _IONBF,
     
    7397        .error = false,
    7498        .eof = false,
    75         .kio = true,
     99        .ops = &stdio_kio_ops,
     100        .arg = NULL,
    76101        .sess = NULL,
    77102        .btype = _IOLBF,
     
    88113        .error = false,
    89114        .eof = false,
    90         .kio = true,
     115        .ops = &stdio_kio_ops,
     116        .arg = NULL,
    91117        .sess = NULL,
    92118        .btype = _IONBF,
     
    328354        stream->error = false;
    329355        stream->eof = false;
    330         stream->kio = false;
     356        stream->ops = &stdio_vfs_ops;
     357        stream->arg = NULL;
    331358        stream->sess = NULL;
    332359        stream->need_sync = false;
     
    352379        stream->error = false;
    353380        stream->eof = false;
    354         stream->kio = false;
     381        stream->ops = &stdio_vfs_ops;
     382        stream->arg = NULL;
    355383        stream->sess = NULL;
    356384        stream->need_sync = false;
     
    435463static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)
    436464{
    437         errno_t rc;
    438         size_t nread;
    439 
    440         if (size == 0 || nmemb == 0)
    441                 return 0;
    442 
    443         rc = vfs_read(stream->fd, &stream->pos, buf, size * nmemb, &nread);
    444         if (rc != EOK) {
    445                 errno = rc;
    446                 stream->error = true;
    447         } else if (nread == 0) {
    448                 stream->eof = true;
    449         }
    450 
    451         return (nread / size);
     465        return stream->ops->read(buf, size, nmemb, stream);
    452466}
    453467
     
    464478static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
    465479{
    466         errno_t rc;
    467480        size_t nwritten;
    468481
     
    470483                return 0;
    471484
    472         if (stream->kio) {
    473                 rc = kio_write(buf, size * nmemb, &nwritten);
    474                 if (rc != EOK) {
    475                         stream->error = true;
    476                         nwritten = 0;
    477                 }
    478         } else {
    479                 rc = vfs_write(stream->fd, &stream->pos, buf, size * nmemb,
    480                     &nwritten);
    481                 if (rc != EOK) {
    482                         errno = rc;
    483                         stream->error = true;
    484                 }
    485         }
     485        nwritten = stream->ops->write(buf, size, nmemb, stream);
    486486
    487487        if (nwritten > 0)
     
    905905        }
    906906
    907         if (stream->kio) {
    908                 kio_update();
    909                 return 0;
    910         }
    911 
    912         if ((stream->fd >= 0) && (stream->need_sync)) {
    913                 errno_t rc;
    914 
     907        if (stream->need_sync) {
    915908                /**
    916909                 * Better than syncing always, but probably still not the
    917910                 * right thing to do.
    918911                 */
     912                if (stream->ops->flush(stream) == EOF)
     913                        return EOF;
     914
    919915                stream->need_sync = false;
    920                 rc = vfs_sync(stream->fd);
    921                 if (rc != EOK) {
    922                         errno = rc;
    923                         return EOF;
    924                 }
    925 
    926                 return 0;
    927916        }
    928917
     
    948937int fileno(FILE *stream)
    949938{
    950         if (stream->kio) {
     939        if (stream->ops != &stdio_vfs_ops) {
    951940                errno = EBADF;
    952941                return EOF;
     
    978967}
    979968
     969/** Read from KIO stream. */
     970static size_t stdio_kio_read(void *buf, size_t size, size_t nmemb, FILE *stream)
     971{
     972        stream->eof = true;
     973        return 0;
     974}
     975
     976/** Write to KIO stream. */
     977static size_t stdio_kio_write(const void *buf, size_t size, size_t nmemb,
     978    FILE *stream)
     979{
     980        errno_t rc;
     981        size_t nwritten;
     982
     983        rc = kio_write(buf, size * nmemb, &nwritten);
     984        if (rc != EOK) {
     985                stream->error = true;
     986                nwritten = 0;
     987        }
     988
     989        return nwritten / size;
     990}
     991
     992/** Flush KIO stream. */
     993static int stdio_kio_flush(FILE *stream)
     994{
     995        kio_update();
     996        return 0;
     997}
     998
     999/** Read from VFS stream. */
     1000static size_t stdio_vfs_read(void *buf, size_t size, size_t nmemb, FILE *stream)
     1001{
     1002        errno_t rc;
     1003        size_t nread;
     1004
     1005        if (size == 0 || nmemb == 0)
     1006                return 0;
     1007
     1008        rc = vfs_read(stream->fd, &stream->pos, buf, size * nmemb, &nread);
     1009        if (rc != EOK) {
     1010                errno = rc;
     1011                stream->error = true;
     1012        } else if (nread == 0) {
     1013                stream->eof = true;
     1014        }
     1015
     1016        return (nread / size);
     1017}
     1018
     1019/** Write to VFS stream. */
     1020static size_t stdio_vfs_write(const void *buf, size_t size, size_t nmemb,
     1021    FILE *stream)
     1022{
     1023        errno_t rc;
     1024        size_t nwritten;
     1025
     1026        rc = vfs_write(stream->fd, &stream->pos, buf, size * nmemb, &nwritten);
     1027        if (rc != EOK) {
     1028                errno = rc;
     1029                stream->error = true;
     1030        }
     1031
     1032        return nwritten / size;
     1033}
     1034
     1035/** Flush VFS stream. */
     1036static int stdio_vfs_flush(FILE *stream)
     1037{
     1038        errno_t rc;
     1039
     1040        rc = vfs_sync(stream->fd);
     1041        if (rc != EOK) {
     1042                errno = rc;
     1043                return EOF;
     1044        }
     1045
     1046        return 0;
     1047}
     1048
    9801049/** @}
    9811050 */
  • uspace/lib/c/generic/private/stdio.h

    red18e14 r01cc7b4  
    3939#include <stdio.h>
    4040#include <async.h>
     41#include <stddef.h>
    4142
    4243/** Maximum characters that can be pushed back by ungetc() */
    4344#define UNGETC_MAX 1
     45
     46/** Stream operations */
     47typedef struct {
     48        /** Read from stream */
     49        size_t (*read)(void *buf, size_t size, size_t nmemb, FILE *stream);
     50        /** Write to stream */
     51        size_t (*write)(const void *buf, size_t size, size_t nmemb,
     52            FILE *stream);
     53        /** Flush stream */
     54        int (*flush)(FILE *stream);
     55} __stream_ops_t;
    4456
    4557struct _IO_FILE {
     
    4759        link_t link;
    4860
     61        /** Stream operations */
     62        __stream_ops_t *ops;
     63
    4964        /** Underlying file descriptor. */
    5065        int fd;
     66
     67        /** Instance argument */
     68        void *arg;
    5169
    5270        /** File position. */
     
    5876        /** End-of-file indicator. */
    5977        int eof;
    60 
    61         /** KIO indicator */
    62         int kio;
    6378
    6479        /** Session to the file provider */
  • uspace/lib/c/generic/stdio/scanf.c

    red18e14 r01cc7b4  
    4646#include <stdio.h>
    4747#include <stdlib.h>
     48#include "../private/stdio.h"
     49#include "../private/sstream.h"
    4850
    4951typedef enum {
     
    13381340{
    13391341        va_list args;
    1340         FILE *f;
     1342        FILE f;
    13411343        int rc;
    13421344
    1343         f = fopen("/tmp/test.tmp", "wt");
    1344         if (f == NULL)
    1345                 return EOF;
    1346 
    1347         if (fputs(s, f) == EOF)
    1348                 return EOF;
    1349 
    1350         if (fclose(f) == EOF)
    1351                 return EOF;
    1352 
    1353         f = fopen("/tmp/test.tmp", "rt");
    1354         if (f == NULL) {
    1355                 printf("failed to open for reading\n");
    1356                 return EOF;
    1357         }
     1345        __sstream_init(s, &f);
    13581346
    13591347        va_start(args, fmt);
    1360         rc = xxvfscanf(f, fmt, args);
     1348        rc = xxvfscanf(&f, fmt, args);
    13611349        va_end(args);
    13621350
    1363         fclose(f);
    1364 
    13651351        return rc;
    13661352}
Note: See TracChangeset for help on using the changeset viewer.