/* * This file is part of dicepwgen * * Copyright (C) 2015 T.v.Dein. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * You can contact me by mail: . */ #include "dictfile.h" int *incr_dicedigit(int *digits) { /* increment an array of dice digits, we expect the first to be a multiple of 10000, the 2nd a multiple of 1000 and so on. */ if (digits[4] == 6) { digits[4] = 1; if (digits[3] == 60) { digits[3] = 10; if (digits[2] == 600) { digits[2] = 100; if (digits[1] == 6000) { digits[1] = 1000; digits[0] += 10000; /* may overflow to 71111, must be catched by caller */ } else digits[1] += 1000; } else digits[2] += 100; } else digits[3] += 10; } else digits[4]++; return digits; } int get_dicenum(int *digits) { /* get the actual number of an array of dice digits */ int i = 0; int pos = 0; for (i = 0; i < 5; i++) pos += digits[i]; return pos; } char **fetch_dict(char *dictfile) { /* read in the dictionary file. we generate an array of max 66666 entries from the dictionary, each entry's index will be a dice number (1 <=> 6). to enhance randomness, we jump over a number of lines (1-32 lines) and start from the beginning of the file if we reach the end before our array is full. */ char **words; int pos, i, next, jump; char *line = NULL; size_t len = 0; ssize_t linelen; FILE *DICT; int *digits; if ((DICT = fopen(dictfile, "rb")) == NULL) { perror("Could not open dictfile"); exit(1); } words = malloc(66667 * sizeof(char *)); digits = malloc(5 * sizeof(int)); jump = rand_lim(32); digits[0] = 10000; digits[1] = 1000; digits[2] = 100; digits[3] = 10; digits[4] = 1; pos = 11111; next = 0; for (i = 0; i < 66667; i++) words[i] = NULL; LOOP: while ((linelen = getline(&line, &len, DICT)) != -1) { if (!dontjump) { if (jump > 0) { jump--; continue; } else { jump = rand_lim(32); } } if (linelen >= WMIN + 1 && linelen <= WMAX + 1) { line[linelen - 1] = '\0'; /* remove newline */ for (i = 0; i < linelen - 1; i++) { if (isalnum((int)line[i]) == 0) { next = 1; break; } } if (next) { next = 0; continue; } words[pos] = malloc(linelen); strncpy(words[pos], line, linelen); if (verbose > 1) debug("add to wordlist at index %d: %s", pos, line); digits = incr_dicedigit(digits); pos = get_dicenum(digits); /* this is what pos gets next after 66666, which is max reachable with 5 * dices */ if (pos == 71111) break; } /* endif word 4<=>10 */ } /* while read */ if (pos < 66666) { fseek(DICT, 0L, SEEK_SET); goto LOOP; } fclose(DICT); free(line); free(digits); return words; }