From 403b1001a00217af1b3d673028dddd3f1747da2e Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Sat, 13 Mar 2010 07:53:13 -0800 Subject: [PATCH] Add find-random-word script --- random-word.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 112 insertions(+), 0 deletions(-) create mode 100644 random-word.c diff --git a/random-word.c b/random-word.c new file mode 100644 index 0000000..c75047b --- /dev/null +++ b/random-word.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include + +#define DICT "/usr/share/dict/linux.words" +#define STARTING_SZ 8192 +#define MAX_ARRAY_SZ 1073741824 + +struct dict { + int num_words; + int array_sz; + char *words[0]; +}; + +static int alloc_dict(struct dict **d, int array_sz) +{ + struct dict *nd; + int num_bytes; + if (array_sz > MAX_ARRAY_SZ) { + fprintf(stderr, "can't allocate a words array bigger " + "than %d\n", MAX_ARRAY_SZ); + return EINVAL; + } + + num_bytes = sizeof(struct dict) + (array_sz * sizeof(char*)); + nd = realloc(*d, num_bytes); + if (!nd) { + fprintf(stderr, "failed to realloc to size %d\n", + num_bytes); + return ENOSPC; + } + *d = nd; + + nd->array_sz = array_sz; + return 0; +} + +static struct dict* read_dict(FILE *fp) +{ + char word[500]; + struct dict *d = + malloc(sizeof(struct dict) + (STARTING_SZ * sizeof(char*))); + if (! d) { + fprintf(stderr, "failed to allocate dict\n"); + return NULL; + } + d->num_words = 0; + d->array_sz = STARTING_SZ; + + while (1) { + if (! fgets(word, sizeof(word), fp)) { + if (ferror(fp)) { + int err = errno; + fprintf(stderr, "%s: error reading line %d: " + "%s (%d)\n", + __func__, d->num_words + 1, + strerror(err), err); + } + else { + return d; + } + } + d->words[d->num_words] = strdup(word); + if (!d->words[d->num_words]) { + fprintf(stderr, "failed to allocate word %d\n", + d->num_words); + free(d); + return NULL; + } + d->num_words++; + if (d->num_words >= d->array_sz) { + if (alloc_dict(&d, d->array_sz * 2)) { + free(d); + return NULL; + } + } + } +} + +static const char* choose_random_word(struct dict *dict) +{ + int choice = random() % dict->num_words; + + return dict->words[choice]; +} + +int main(void) +{ + FILE *fp; + const char *word; + struct dict *dict; + srandom(time(NULL)); + + fp = fopen(DICT, "r"); + if (! fp) { + int err = errno; + fprintf(stderr, "failed to open %s: %s (%d).\n", + DICT, strerror(err), err); + return 1; + } + dict = read_dict(fp); + if (! dict) + return 1; + fclose(fp); + + word = choose_random_word(dict); + printf("%s\n", word); + + return 0; +} -- 1.6.6.rc1.39.g9a42