Also refactored and added comments.
| ... | ... |
@@ -1,5 +1,6 @@ |
| 1 | 1 |
#include <stdlib.h> |
| 2 | 2 |
#include <stdio.h> |
| 3 |
+#include <string.h> |
|
| 3 | 4 |
|
| 4 | 5 |
#include "choices.h" |
| 5 | 6 |
#include "match.h" |
| ... | ... |
@@ -18,14 +19,49 @@ static int cmpchoice(const void *_idx1, const void *_idx2) {
|
| 18 | 19 |
return -1; |
| 19 | 20 |
} |
| 20 | 21 |
|
| 21 |
-static void choices_resize(choices_t *c, size_t new_capacity) {
|
|
| 22 |
- c->strings = realloc(c->strings, new_capacity * sizeof(const char *)); |
|
| 23 |
- |
|
| 24 |
- if (!c->strings) {
|
|
| 25 |
- fprintf(stderr, "Error: Can't allocate memory\n"); |
|
| 22 |
+static void *safe_realloc(void *buffer, size_t size) {
|
|
| 23 |
+ buffer = realloc(buffer, size); |
|
| 24 |
+ if (!buffer) {
|
|
| 25 |
+ fprintf(stderr, "Error: Can't allocate memory (%zu bytes)\n", size); |
|
| 26 | 26 |
abort(); |
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 |
+ return buffer; |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+void choices_fread(choices_t *c, FILE *file) {
|
|
| 33 |
+ size_t bufsize = 65536, pos = 0; |
|
| 34 |
+ char *buf = safe_realloc(NULL, bufsize); |
|
| 35 |
+ |
|
| 36 |
+ /* Continue reading until we get a "short" read, indicating EOF */ |
|
| 37 |
+ while ((pos += fread(buf + pos, 1, bufsize - pos, file)) == bufsize) {
|
|
| 38 |
+ bufsize *= 2; |
|
| 39 |
+ buf = safe_realloc(buf, bufsize); |
|
| 40 |
+ } |
|
| 41 |
+ buf[pos] = 0; |
|
| 42 |
+ |
|
| 43 |
+ /* Truncate buffer to used size, (maybe) freeing some memory for |
|
| 44 |
+ * future allocations. |
|
| 45 |
+ */ |
|
| 46 |
+ buf = safe_realloc(buf, pos + 1); |
|
| 47 |
+ |
|
| 48 |
+ /* Tokenize input and add to choices */ |
|
| 49 |
+ char *line = buf; |
|
| 50 |
+ do {
|
|
| 51 |
+ char *nl = strchr(line, '\n'); |
|
| 52 |
+ if (nl) |
|
| 53 |
+ *nl++ = '\0'; |
|
| 54 |
+ |
|
| 55 |
+ /* Skip empty lines */ |
|
| 56 |
+ if (*line) |
|
| 57 |
+ choices_add(c, line); |
|
| 58 |
+ |
|
| 59 |
+ line = nl; |
|
| 60 |
+ } while (line); |
|
| 61 |
+} |
|
| 62 |
+ |
|
| 63 |
+static void choices_resize(choices_t *c, size_t new_capacity) {
|
|
| 64 |
+ c->strings = safe_realloc(c->strings, new_capacity * sizeof(const char *)); |
|
| 29 | 65 |
c->capacity = new_capacity; |
| 30 | 66 |
} |
| 31 | 67 |
|
| ... | ... |
@@ -1,6 +1,8 @@ |
| 1 | 1 |
#ifndef CHOICES_H |
| 2 | 2 |
#define CHOICES_H CHOICES_H |
| 3 | 3 |
|
| 4 |
+#include <stdio.h> |
|
| 5 |
+ |
|
| 4 | 6 |
struct scored_result {
|
| 5 | 7 |
double score; |
| 6 | 8 |
const char *str; |
| ... | ... |
@@ -18,6 +20,7 @@ typedef struct {
|
| 18 | 20 |
} choices_t; |
| 19 | 21 |
|
| 20 | 22 |
void choices_init(choices_t *c); |
| 23 |
+void choices_fread(choices_t *c, FILE *file); |
|
| 21 | 24 |
void choices_free(choices_t *c); |
| 22 | 25 |
void choices_add(choices_t *c, const char *choice); |
| 23 | 26 |
size_t choices_available(choices_t *c); |
| ... | ... |
@@ -18,37 +18,6 @@ static size_t scrolloff = 1; |
| 18 | 18 |
|
| 19 | 19 |
static const char *prompt = "> "; |
| 20 | 20 |
|
| 21 |
-static void read_choices(choices_t *c) {
|
|
| 22 |
- size_t bufsize = 65536; |
|
| 23 |
- size_t pos = 0; |
|
| 24 |
- size_t sizeread; |
|
| 25 |
- |
|
| 26 |
- /* Read entire file into contiguous memory buffer */ |
|
| 27 |
- char *buf = malloc(bufsize); |
|
| 28 |
- while ((sizeread = fread(buf + pos, 1, bufsize - pos, stdin))) {
|
|
| 29 |
- pos += sizeread; |
|
| 30 |
- bufsize *= 2; |
|
| 31 |
- buf = realloc(buf, bufsize); |
|
| 32 |
- } |
|
| 33 |
- buf = realloc(buf, pos + 1); |
|
| 34 |
- |
|
| 35 |
- buf[pos] = 0; |
|
| 36 |
- |
|
| 37 |
- /* Tokenize input and add to choices */ |
|
| 38 |
- char *line = buf; |
|
| 39 |
- do {
|
|
| 40 |
- char *nl = strchr(line, '\n'); |
|
| 41 |
- if (nl) |
|
| 42 |
- *nl++ = '\0'; |
|
| 43 |
- |
|
| 44 |
- /* Skip empty lines */ |
|
| 45 |
- if (*line) |
|
| 46 |
- choices_add(c, line); |
|
| 47 |
- |
|
| 48 |
- line = nl; |
|
| 49 |
- } while (line); |
|
| 50 |
-} |
|
| 51 |
- |
|
| 52 | 21 |
#define SEARCH_SIZE_MAX 4096 |
| 53 | 22 |
static size_t search_size; |
| 54 | 23 |
static char search[SEARCH_SIZE_MAX + 1] = {0};
|
| ... | ... |
@@ -279,7 +248,7 @@ int main(int argc, char *argv[]) {
|
| 279 | 248 |
|
| 280 | 249 |
choices_t choices; |
| 281 | 250 |
choices_init(&choices); |
| 282 |
- read_choices(&choices); |
|
| 251 |
+ choices_fread(&choices, stdin); |
|
| 283 | 252 |
|
| 284 | 253 |
if (num_lines > choices.size) |
| 285 | 254 |
num_lines = choices.size; |