From: Niki Roo Date: Fri, 21 Jun 2024 18:09:34 +0000 (+0200) Subject: cstring: improve readline X-Git-Url: http://git.nikiroo.be/?a=commitdiff_plain;h=201682e2328086431c86a36358ba5569d51048ad;p=cutils.git cstring: improve readline --- diff --git a/cstring.c b/cstring.c index d25d4c9..58481ec 100644 --- a/cstring.c +++ b/cstring.c @@ -633,66 +633,19 @@ void cstring_change_case(cstring_t *self, int up) { free_cstring(rep); } -static char buffer[BUFFER_SIZE]; int cstring_readline(cstring_t *self, FILE *file) { - size_t size = 0; - int full_line; - - // sanity check: - if (!file) - return 0; - - if (!feof(file)) { - // Allow '\0' in data (1/4) - //buffer[BUFFER_SIZE - 1] = '\0'; // just in case - memset(buffer, ~0, BUFFER_SIZE); - - cstring_clear(self); - buffer[0] = '\0'; - - // Note: fgets() could return NULL if EOF is reached - if (!fgets(buffer, (int) BUFFER_SIZE - 1, file)) - return 0; - - // Allow '\0' in data (2/4) - //size = strlen(buffer); - size = BUFFER_SIZE; - while(size && buffer[size - 1]) - size--; - if (size) - size--; - - full_line = ((file && feof(file)) || size == 0 - || buffer[size - 1] == '\n'); - size = cstring_remove_crlf_sz(buffer, size); - cstring_addfN(self, buffer, 0, size); - - // No luck, we need to continue getting data - while (!full_line) { - // Allow '\0' in data (3/4) - //buffer[BUFFER_SIZE - 1] = '\0'; // just in case - memset(buffer, ~0, BUFFER_SIZE); - - if (!fgets(buffer, (int) BUFFER_SIZE - 1, file)) - break; - - // Allow '\0' in data (4/4) - //size = strlen(buffer); - size = BUFFER_SIZE; - while(size && buffer[size - 1]) - size--; - if (size) - size--; - - full_line = ((file && feof(file)) || size == 0 - || buffer[size - 1] == '\n'); - size = cstring_remove_crlf_sz(buffer, size); - cstring_addfN(self, buffer, 0, size); - } - + ssize_t sz = getline( + &(self->string), + &(((priv_t *) self->priv)->buffer_length), + file + ); + + if (sz > 0) { + self->length = cstring_remove_crlf_sz(self->string, sz); return 1; } - + + cstring_clear(self); return 0; } diff --git a/cutils.c b/cutils.c index 1141c2c..4547c4b 100644 --- a/cutils.c +++ b/cutils.c @@ -42,3 +42,43 @@ char *strdup(const char *source) { return new; } #endif + +#ifndef getline +ssize_t getline(char **strp, size_t *n, FILE *f) { + char *str = *strp; + size_t max = *n; + ssize_t sz = 0; + + if (!str) { + max = 1024; + str = malloc(max); + } + + int car = '\0'; + for (sz = 0 ; car >= 0 ; sz++) { + int car = fgetc(f); + if (car < 0) + break; + + if (max <= sz) { + max *= 2; + str = realloc(str, max); + } + + str[sz] = car; + + if (car == '\n') + break; + } + + if ((car < 0) && !sz) + sz = -1; + + if (sz >= 0) + str[sz] = '\0'; + + *strp = str; + *n = max; + return sz; +} +#endif diff --git a/cutils.h b/cutils.h index 0090a31..8fcaadd 100644 --- a/cutils.h +++ b/cutils.h @@ -20,10 +20,11 @@ /** * @file cutils.h * @author Niki - * @date 2020 - 2022 + * @date 2020 - 2024 * * @brief Include all the other .h as well as C99-compatible - * strdup/strnlen functions if they are not already defined + * strdup/strnlen/getline functions + * if they are not already defined */ #ifndef CUTILS_H #define CUTILS_H @@ -32,6 +33,8 @@ extern "C" { #endif +#include + #include "cstring.h" #include "array.h" #include "desktop.h" @@ -68,6 +71,16 @@ size_t strnlen(const char *s, size_t maxlen); */ char *strdup(const char *source); #endif +//#if _POSIX_C_SOURCE < 200809L +//#ifndef _GNU_SOURCE +/** + * getline() reads an entire line from stream, storing the address of the + * buffer containing the text into *lineptr. The buffer is null- + * terminated and includes the newline character, if one was found. + */ +ssize_t getline(char **strp, size_t *n, FILE *f); +//#endif +//#endif /* */ diff --git a/desktop.c b/desktop.c index 1892811..4f2cb24 100644 --- a/desktop.c +++ b/desktop.c @@ -25,7 +25,9 @@ #include #include -#include "cutils.h" +#include "desktop.h" +#include "array.h" +#include "cstring.h" #define EXT "desktop"