Changeset 9d8307a in mainline


Ignore:
Timestamp:
2018-07-19T11:55:19Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0d83cf6f
Parents:
42f5860
git-author:
Jiri Svoboda <jiri@…> (2018-07-18 17:54:45)
git-committer:
Jiri Svoboda <jiri@…> (2018-07-19 11:55:19)
Message:

Reimplement strtold function in libc.

Location:
uspace/lib
Files:
1 added
1 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/private/sstream.h

    r42f5860 r9d8307a  
    3939
    4040extern void __sstream_init(const char *, FILE *);
     41extern const char *__sstream_getpos(FILE *);
    4142
    4243#endif
  • uspace/lib/c/generic/stdio/scanf.c

    r42f5860 r9d8307a  
    4646#include <stdio.h>
    4747#include <stdlib.h>
     48
     49#include "../private/scanf.h"
    4850
    4951typedef enum {
     
    348350 * @return EOK on success, ENOMEM if out of memory
    349351 */
    350 static int strbuf_init(strbuf_t *strbuf, cvtspec_t *spec, va_encaps_t *va)
     352static errno_t strbuf_init(strbuf_t *strbuf, cvtspec_t *spec, va_encaps_t *va)
    351353{
    352354        if (spec->noassign) {
     
    393395 * @return EOK on sucess, ENOMEM if out of memory
    394396 */
    395 static int strbuf_write(strbuf_t *strbuf, size_t idx, char c)
     397static errno_t strbuf_write(strbuf_t *strbuf, size_t idx, char c)
    396398{
    397399        if (strbuf->memalloc && idx >= strbuf->size) {
     
    449451
    450452/* Skip whitespace in input stream */
    451 static int vfscanf_skip_ws(FILE *f, int *numchar)
     453static errno_t vfscanf_skip_ws(FILE *f, int *numchar)
    452454{
    453455        int c;
     
    471473
    472474/* Match whitespace. */
    473 static int vfscanf_match_ws(FILE *f, int *numchar, const char **fmt)
    474 {
    475         int rc;
     475static errno_t vfscanf_match_ws(FILE *f, int *numchar, const char **fmt)
     476{
     477        errno_t rc;
    476478
    477479        rc = vfscanf_skip_ws(f, numchar);
     
    492494 * @return EOK on success, EIO on I/O error, EINVAL if input is not valid
    493495 */
    494 static int __fstrtoimax(FILE *f, int *numchar, int base, size_t width,
     496static errno_t __fstrtoimax(FILE *f, int *numchar, int base, size_t width,
    495497    intmax_t *dest)
    496498{
     499        errno_t rc;
    497500        int c;
    498501        intmax_t v;
    499502        int digit;
    500503        int sign;
     504
     505        rc = vfscanf_skip_ws(f, numchar);
     506        if (rc == EIO)
     507                return EIO;
    501508
    502509        c = __fgetc(f, numchar);
     
    579586 * @return EOK on success, EIO on I/O error, EINVAL if input is not valid
    580587 */
    581 static int __fstrtoumax(FILE *f, int *numchar, int base, size_t width,
     588static errno_t __fstrtoumax(FILE *f, int *numchar, int base, size_t width,
    582589    uintmax_t *dest)
    583590{
     591        errno_t rc;
    584592        int c;
    585593        uintmax_t v;
    586594        int digit;
     595
     596        rc = vfscanf_skip_ws(f, numchar);
     597        if (rc == EIO)
     598                return EIO;
    587599
    588600        c = __fgetc(f, numchar);
     
    653665 * @return EOK on success, EIO on I/O error, EINVAL if input is not valid
    654666 */
    655 static int __fstrtold(FILE *f, int *numchar, size_t width, long double *dest)
    656 {
     667errno_t __fstrtold(FILE *f, int *numchar, size_t width,
     668    long double *dest)
     669{
     670        errno_t rc;
    657671        int c;
    658672        long double v;
     
    665679        int exp;
    666680        int expsign;
     681
     682        rc = vfscanf_skip_ws(f, numchar);
     683        if (rc == EIO)
     684                return EIO;
    667685
    668686        c = __fgetc(f, numchar);
     
    823841
    824842/* Read characters from stream */
    825 static int __fgetchars(FILE *f, int *numchar, size_t width, strbuf_t *strbuf,
    826     size_t *nread)
     843static errno_t __fgetchars(FILE *f, int *numchar, size_t width,
     844    strbuf_t *strbuf, size_t *nread)
    827845{
    828846        size_t cnt;
    829847        int c;
    830         int rc;
    831 
     848        errno_t rc;
     849
     850        *nread = 0;
    832851        for (cnt = 0; cnt < width; cnt++) {
    833852                c = __fgetc(f, numchar);
     
    849868
    850869/* Read non-whitespace string from stream */
    851 static int __fgetstr(FILE *f, int *numchar, size_t width, strbuf_t *strbuf,
     870static errno_t __fgetstr(FILE *f, int *numchar, size_t width, strbuf_t *strbuf,
    852871    size_t *nread)
    853872{
    854873        size_t cnt;
    855874        int c;
    856         int rc;
    857         int rc2;
     875        errno_t rc;
     876        errno_t rc2;
     877
     878        *nread = 0;
     879
     880        rc = vfscanf_skip_ws(f, numchar);
     881        if (rc == EIO)
     882                return EIO;
    858883
    859884        rc = EOK;
     
    949974
    950975/* Read string of characters from scanset from stream */
    951 static int __fgetscanstr(FILE *f, int *numchar, size_t width,
     976static errno_t __fgetscanstr(FILE *f, int *numchar, size_t width,
    952977    const char *scanset, strbuf_t *strbuf, size_t *nread)
    953978{
    954979        size_t cnt;
    955980        int c;
    956         int rc;
    957         int rc2;
     981        errno_t rc;
     982        errno_t rc2;
    958983
    959984        rc = EOK;
     
    9901015
    9911016/** Perform a single conversion. */
    992 static int vfscanf_cvt(FILE *f, const char **fmt, va_encaps_t *va,
     1017static errno_t vfscanf_cvt(FILE *f, const char **fmt, va_encaps_t *va,
    9931018    int *numchar, unsigned *ncvt)
    9941019{
    995         int rc;
     1020        errno_t rc;
    9961021        int c;
    9971022        intmax_t ival;
     
    10271052        cvtspec_parse(fmt, &cvtspec);
    10281053
    1029         if (cvtspec.spcr != cs_set && cvtspec.spcr != cs_char &&
    1030             cvtspec.spcr != cs_numchar) {
    1031                 /* Skip whitespace */
    1032                 rc = vfscanf_skip_ws(f, numchar);
    1033                 if (rc == EIO)
    1034                         return EIO;
    1035 
    1036                 assert(rc == EOK);
    1037         }
    1038 
    10391054        width = cvtspec.have_width ? cvtspec.width : SIZE_MAX;
    10401055
     
    10421057        case cs_percent:
    10431058                /* Match % character */
     1059                rc = vfscanf_skip_ws(f, numchar);
     1060                if (rc == EOF)
     1061                        return EIO;
     1062
    10441063                c = __fgetc(f, numchar);
    10451064                if (c == EOF)
  • uspace/lib/c/generic/stdio/sstream.c

    r42f5860 r9d8307a  
    9999}
    100100
     101/** Return current string stream position.
     102 *
     103 * @param stream String stream
     104 * @return Pointer into the backing string at the current position
     105 */
     106const char *__sstream_getpos(FILE *stream)
     107{
     108        assert(stream->ops == &stdio_str_ops);
     109        return (char *) stream->arg;
     110}
     111
    101112/** @}
    102113 */
  • uspace/lib/c/generic/stdlib.c

    r42f5860 r9d8307a  
    3838#include <stdlib.h>
    3939#include "private/libc.h"
     40#include "private/scanf.h"
    4041#include "private/stdlib.h"
     42#include "private/stdio.h"
     43#include "private/sstream.h"
    4144
    4245static int glbl_seed = 1;
     
    4851static FIBRIL_MUTEX_INITIALIZE(quick_exit_handlers_lock);
    4952
     53/** Convert string to long double.
     54 *
     55 */
     56long double strtold(const char *nptr, char **endptr)
     57{
     58        int numchar;
     59        long double ld;
     60        errno_t rc;
     61        FILE f;
     62
     63        numchar = 0;
     64        __sstream_init(nptr, &f);
     65
     66        rc = __fstrtold(&f, &numchar, SIZE_MAX, &ld);
     67        if (rc != EOK) {
     68                ld = 0;
     69                if (endptr != NULL)
     70                        *endptr = (char *) nptr;
     71                errno = rc;
     72        } else {
     73                if (endptr != NULL)
     74                        *endptr = (char *) __sstream_getpos(&f);
     75        }
     76
     77        return ld;
     78}
    5079
    5180int rand(void)
  • uspace/lib/c/include/stdlib.h

    r42f5860 r9d8307a  
    7878#define MB_CUR_MAX 4
    7979
     80extern long double strtold(const char *, char **);
     81
    8082extern int rand(void);
    8183extern void srand(unsigned int);
  • uspace/lib/c/test/stdlib.c

    r42f5860 r9d8307a  
    9090}
    9191
     92/** strtold function */
     93#include <stdio.h>
     94PCUT_TEST(strtold)
     95{
     96        long double ld;
     97        const char *str = " \t4.2e1@";
     98        char *endptr;
     99
     100        ld = strtold(str, &endptr);
     101        printf("ld=%.10lf\n", (double)ld);
     102        PCUT_ASSERT_TRUE(ld == 42.0);
     103}
     104
    92105/** strtol function */
    93106PCUT_TEST(strtol)
  • uspace/lib/posix/Makefile

    r42f5860 r9d8307a  
    7070        src/stdio.c \
    7171        src/stdlib.c \
    72         src/stdlib/strtold.c \
    7372        src/string.c \
    7473        src/strings.c \
  • uspace/lib/posix/include/posix/stdlib.h

    r42f5860 r9d8307a  
    5252extern float strtof(const char *__restrict__ nptr, char **__restrict__ endptr);
    5353extern double strtod(const char *__restrict__ nptr, char **__restrict__ endptr);
    54 extern long double strtold(const char *__restrict__ nptr, char **__restrict__ endptr);
    5554
    5655/* Temporary Files */
Note: See TracChangeset for help on using the changeset viewer.