commit 12af0d1b5fbd996026c80f09ec5f6812fe6224f2 from: Omar Polo date: Mon May 16 16:44:35 2022 UTC rewrite readlines use getline instead of rolling a custom version; swap the argument and return type to avoid being a "three star" programmer. Then, gargabe collect the now unused read_stdin, STDIN_CHUNKS and LINES_CHUNK. commit - 0a5eab1ea24e7fa8c0072d9ef949437c1fa3ca8c commit + 12af0d1b5fbd996026c80f09ec5f6812fe6224f2 blob - 725b51550815dd275b7fff5a5028f393045fe224 blob + 4d3492bcf70668ba2cb6d2dd2242fce784c24f2f --- mymenu.c +++ mymenu.c @@ -54,12 +54,6 @@ #define strcasestr strstr #endif -/* The number of char to read */ -#define STDIN_CHUNKS 128 - -/* The number of lines to allocate in advance */ -#define LINES_CHUNK 64 - #define inner_height(r) (r->height - r->borders[0] - r->borders[2]) #define inner_width(r) (r->width - r->borders[1] - r->borders[3]) @@ -417,91 +411,40 @@ normalize_str(const char *str) return s; } -size_t -read_stdin(char **buf) +char ** +readlines(size_t *lineslen) { - size_t offset = 0; - size_t len = STDIN_CHUNKS; + size_t len = 0, cap = 0; + size_t linesize = 0; + ssize_t linelen; + char *line = NULL, **lines = NULL; - *buf = malloc(len * sizeof(char)); - if (*buf == NULL) - goto err; + while ((linelen = getline(&line, &linesize, stdin)) != -1) { + if (linelen != 0 && line[linelen-1] == '\n') + line[linelen-1] = '\0'; - while (1) { - ssize_t r; - size_t i; + if (len == cap) { + size_t newcap; + void *t; - r = read(0, *buf + offset, STDIN_CHUNKS); + newcap = MAX(cap * 1.5, 32); + t = recallocarray(lines, cap, newcap, sizeof(char *)); + if (t == NULL) + err(1, "recallocarray"); + cap = newcap; + lines = t; + } - if (r < 1) - return len; - - offset += r; - - len += STDIN_CHUNKS; - *buf = realloc(*buf, len); - if (*buf == NULL) - goto err; - - for (i = offset; i < len; ++i) - (*buf)[i] = '\0'; + if ((lines[len++] = strdup(line)) == NULL) + err(1, "strdup"); } -err: - fprintf(stderr, "Error in allocating memory for stdin.\n"); - exit(EX_UNAVAILABLE); -} + if (ferror(stdin)) + err(1, "getline"); + free(line); -size_t -readlines(char ***lns, char **buf) -{ - size_t i, len, ll, lines; - short in_line = 0; - - lines = 0; - - *buf = NULL; - len = read_stdin(buf); - - ll = LINES_CHUNK; - *lns = malloc(ll * sizeof(char *)); - - if (*lns == NULL) - goto err; - - for (i = 0; i < len; i++) { - char c = (*buf)[i]; - - if (c == '\0') - break; - - if (c == '\n') - (*buf)[i] = '\0'; - - if (in_line && c == '\n') - in_line = 0; - - if (!in_line && c != '\n') { - in_line = 1; - (*lns)[lines] = (*buf) + i; - lines++; - - if (lines == ll) { /* resize */ - ll += LINES_CHUNK; - *lns = realloc(*lns, ll * sizeof(char *)); - if (*lns == NULL) - goto err; - } - } - } - - (*lns)[lines] = NULL; - + *lineslen = len; return lines; - -err: - fprintf(stderr, "Error in memory allocation.\n"); - exit(EX_UNAVAILABLE); } /* @@ -1544,7 +1487,7 @@ main(int argc, char **argv) int textlen, d_width, d_height; short embed; char *sep, *parent_window_id; - char **lines, *buf, **vlines; + char **lines, **vlines; char *fontname, *text, *xrm; sep = NULL; @@ -1582,10 +1525,7 @@ main(int argc, char **argv) } } - /* Read the completions */ - lines = NULL; - buf = NULL; - nlines = readlines(&lines, &buf); + lines = readlines(&nlines); vlines = NULL; if (sep != NULL) { @@ -2231,7 +2171,6 @@ main(int argc, char **argv) free(fontname); free(text); - free(buf); free(lines); free(vlines); compls_delete(cs);