123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- /* posix_getline.c
- * RT-Thread POSIX
- * getdelim(), getline() - read a delimited record from stream, ersatz implementation
- * This code is unlicensed -- free and released into the public domain.
- * https://man7.org/linux/man-pages/man3/getline.3.html
- * Authors:
- * https://github.com/ivanrad/getline
- *
- * Meco Man 2020-09-03 porting to RT-Thread
- */
- #include "posix_getline.h"
- #include <stdlib.h>
- #include <limits.h>
- #include <sys/errno.h>
- ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream) {
- char *cur_pos, *new_lineptr;
- size_t new_lineptr_len;
- int c;
- if (lineptr == NULL || n == NULL || stream == NULL) {
- errno = EINVAL;
- return -1;
- }
- if (*lineptr == NULL) {
- *n = 128; /* init len */
- if ((*lineptr = (char *)malloc(*n)) == NULL) {
- errno = ENOMEM;
- return -1;
- }
- }
- cur_pos = *lineptr;
- for (;;) {
- c = getc(stream);
- if (ferror(stream) || (c == EOF && cur_pos == *lineptr))
- return -1;
- if (c == EOF)
- break;
- if ((*lineptr + *n - cur_pos) < 2) {
- if (LONG_MAX / 2 < *n) {
- #ifdef EOVERFLOW
- errno = EOVERFLOW;
- #else
- errno = ERANGE; /* no EOVERFLOW defined */
- #endif
- return -1;
- }
- new_lineptr_len = *n * 2;
- if ((new_lineptr = (char *)realloc(*lineptr, new_lineptr_len)) == NULL) {
- errno = ENOMEM;
- return -1;
- }
- cur_pos = new_lineptr + (cur_pos - *lineptr);
- *lineptr = new_lineptr;
- *n = new_lineptr_len;
- }
- *cur_pos++ = (char)c;
- if (c == delim)
- break;
- }
- *cur_pos = '\0';
- return (ssize_t)(cur_pos - *lineptr);
- }
- ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
- return getdelim(lineptr, n, '\n', stream);
- }
|