Changeset 08053f7 in mainline


Ignore:
Timestamp:
2011-07-06T23:33:02Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
324d46b
Parents:
d9eaa43
Message:

Implementation of scanf (not tested yet, just compiles).

Location:
uspace/lib/posix
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/posix/Makefile

    rd9eaa43 r08053f7  
    4747        signal.c \
    4848        stdio.c \
     49        stdio/scanf.c \
    4950        stdlib.c \
    5051        stdlib/strtol.c \
  • uspace/lib/posix/stdio.c

    rd9eaa43 r08053f7  
    4949#include "libc/io/printf_core.h"
    5050#include "libc/str.h"
     51#include "libc/malloc.h"
    5152
    5253
     
    9293 * @param c Byte to be pushed back.
    9394 * @param stream Stream to where the byte shall be pushed.
    94  * @return Provided byte on succes or EOF if not possible.
     95 * @return Provided byte on success or EOF if not possible.
    9596 */
    9697int posix_ungetc(int c, FILE *stream)
     
    128129
    129130/**
    130  *
    131  * @param lineptr
    132  * @param n
    133  * @param delimiter
    134  * @param stream
    135  * @return
     131 * Read a stream until the delimiter (or EOF) is encountered.
     132 *
     133 * @param lineptr Pointer to the output buffer in which there will be stored
     134 *     nul-terminated string together with the delimiter (if encountered).
     135 *     Will be resized if necessary.
     136 * @param n Pointer to the size of the output buffer. Will be increased if
     137 *     necessary.
     138 * @param delimiter Delimiter on which to finish reading the stream.
     139 * @param stream Input stream.
     140 * @return Number of fetched characters (including delimiter if encountered)
     141 *     or -1 on error (set in errno).
    136142 */
    137143ssize_t posix_getdelim(char **restrict lineptr, size_t *restrict n,
    138144    int delimiter, FILE *restrict stream)
    139145{
    140         // TODO
    141         not_implemented();
    142 }
    143 
    144 /**
    145  *
    146  * @param lineptr
    147  * @param n
    148  * @param stream
    149  * @return
     146        /* Check arguments for sanity. */
     147        if (!lineptr || !n) {
     148                errno = EINVAL;
     149                return -1;
     150        }
     151
     152        size_t alloc_step = 80; /* Buffer size gain during reallocation. */
     153        char *pos = *lineptr; /* Next free byte of the output buffer. */
     154        size_t cnt = 0; /* Number of fetched characters. */
     155        int c = fgetc(stream); /* Current input character. Might be EOF. */
     156
     157        do {
     158                /* Mask EOF as NUL to terminate string. */
     159                if (c == EOF) {
     160                        c = '\0';
     161                }
     162
     163                /* Ensure there is still space left in the buffer. */
     164                if (pos == *lineptr + *n) {
     165                        *lineptr = realloc(*lineptr, *n + alloc_step);
     166                        if (*lineptr) {
     167                                pos = *lineptr + *n;
     168                                *n += alloc_step;
     169                        } else {
     170                                errno = ENOMEM;
     171                                return -1;
     172                        }
     173                }
     174
     175                /* Store the fetched character. */
     176                *pos = c;
     177
     178                /* Fetch the next character according to the current character. */
     179                if (c != '\0') {
     180                        ++pos;
     181                        ++cnt;
     182                        if (c == delimiter) {
     183                                /* Delimiter was just stored. Provide EOF as the next
     184                                 * character - it will be masked as NUL and output string
     185                                 * will be properly terminated. */
     186                                c = EOF;
     187                        } else {
     188                                /* Neither delimiter nor EOF were encountered. Just fetch
     189                                 * the next character from the stream. */
     190                                c = fgetc(stream);
     191                        }
     192                }
     193        } while (c != '\0');
     194
     195        if (errno == EOK && cnt > 0) {
     196                return cnt;
     197        } else {
     198                /* Either some error occured or the stream was already at EOF. */
     199                return -1;
     200        }
     201}
     202
     203/**
     204 * Read a stream until the newline (or EOF) is encountered.
     205 *
     206 * @param lineptr Pointer to the output buffer in which there will be stored
     207 *     nul-terminated string together with the delimiter (if encountered).
     208 *     Will be resized if necessary.
     209 * @param n Pointer to the size of the output buffer. Will be increased if
     210 *     necessary.
     211 * @param stream Input stream.
     212 * @return Number of fetched characters (including newline if encountered)
     213 *     or -1 on error (set in errno).
    150214 */
    151215ssize_t posix_getline(char **restrict lineptr, size_t *restrict n,
    152216    FILE *restrict stream)
    153217{
    154         // TODO
    155         not_implemented();
     218        return posix_getdelim(lineptr, n, '\n', stream);
    156219}
    157220
     
    421484 *     negative value on error.
    422485 */
    423 int posix_sprintf(char *s, const char *format, ...)
     486int posix_sprintf(char *s, const char *restrict format, ...)
    424487{
    425488        va_list list;
     
    439502 *     negative value on error.
    440503 */
    441 int posix_vsprintf(char *s, const char *format, va_list ap)
     504int posix_vsprintf(char *s, const char *restrict format, va_list ap)
    442505{
    443506        return vsnprintf(s, STR_NO_LIMIT, format, ap);
     
    461524
    462525/**
    463  * Convert formatted input from the stream.
    464  *
    465  * @param stream Input stream.
    466  * @param format Format description.
    467  * @param arg Output items.
    468  * @return The number of converted output items or EOF on failure.
    469  */
    470 int posix_vfscanf(FILE *restrict stream, const char *restrict format, va_list arg)
    471 {
    472         // TODO
    473         not_implemented();
    474 }
    475 
    476 /**
    477526 * Convert formatted input from the standard input.
    478527 *
     
    508557 * @return The number of converted output items or EOF on failure.
    509558 */
    510 int posix_sscanf(const char *s, const char *format, ...)
     559int posix_sscanf(const char *restrict s, const char *restrict format, ...)
    511560{
    512561        va_list list;
     
    518567
    519568/**
    520  * Convert formatted input from the string.
    521  *
    522  * @param s Input string.
    523  * @param format Format description.
    524  * @param arg Output items.
    525  * @return The number of converted output items or EOF on failure.
    526  */
    527 int posix_vsscanf(
    528     const char *restrict s, const char *restrict format, va_list arg)
    529 {
    530         // TODO
    531         not_implemented();
    532 }
    533 
    534 /**
    535569 * Acquire file stream for the thread.
    536570 *
Note: See TracChangeset for help on using the changeset viewer.