diff options
Diffstat (limited to 'kochgen.c')
-rw-r--r-- | kochgen.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/kochgen.c b/kochgen.c new file mode 100644 index 0000000..2f823ec --- /dev/null +++ b/kochgen.c @@ -0,0 +1,148 @@ +/* + +BSD Zero Clause License + +Copyright (c) 2023 Samuel Wirajaya + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +================================================================================ + + K O C H G E N + +================================================================================ + +*/ + +#include <ctype.h> /* toupper */ +#include <limits.h> /* strtoul */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> /* strnlen */ +#include <time.h> +#include <unistd.h> + +#define VERSION "0.9.0" + +char *progname; +int wrlenmax; +int wrlenmin; +int nwrs; +char *charset; +FILE *ofile; + +void +usage(void) { + printf( + "Koch Training Generator (version " VERSION ")\n" + "usage: %s [-h] [-M WRLENMAX] [-m WRLENMIN] [-n NWRS] [-o OFILE] " + "CHARSET\n" + "CHARSET is a string containing all letters to be trained on\n" + "e.g. 'km' for the first lesson, 'kmr' for the second lesson,\n" + "etc.\n" + " -h: displays this message\n" + " -M: sets the maximum n. of letters in a word [%d]\n" + " -m: sets the minimum n. of letters in a word [%d]\n" + " -n: sets the number of words to be generated [%d]\n" + " -o: writes a copy of the output to OFILE\n" + , progname, wrlenmax, wrlenmin, nwrs); +} + +void +teeputc(int c) { + fputc(c, stdout); + if (ofile) { + fputc(c, ofile); + } +} + +int +main(int argc, char **argv) { + int i, j, wrlen; + int k, setsz; + int opt; + + srand(time(NULL)); + + progname = argv[0]; + wrlenmax = 5; + wrlenmin = 5; + nwrs = 50; + ofile = NULL; + + while ((opt = getopt(argc, argv, "M:hm:n:o:")) != -1) { + switch (opt) { + case 'M': + wrlenmax = (int)strtoul(optarg, NULL, 10); + break; + case 'h': + usage(); + return 0; + case 'm': + wrlenmin = (int)strtoul(optarg, NULL, 10); + break; + case 'n': + nwrs = (int)strtoul(optarg, NULL, 10); + break; + case 'o': + ofile = fopen(optarg, "w"); + if (!ofile) { + perror("warning: cannot open output file"); + } + break; + case '?': + default: + usage(); + return 1; + } + } + argc -= optind; + argv += optind; + if (argc == 1) { + charset = argv[0]; + } else { + fprintf(stderr, "error: one charset must be supplied\n"); + usage(); + return 1; + } + + if ((wrlenmax < 1) || (wrlenmax > 1023)) { + fprintf(stderr, "error: wrlenmax out of range (1--1023)\n"); + usage(); + return 1; + } + if ((wrlenmin < 1) || (wrlenmin > wrlenmax)) { + fprintf(stderr, "error: wrlenmin out of range (1--wrlenmax)\n"); + usage(); + return 1; + } + + setsz = (int)strnlen(charset, 127); + for (k = 0; k < setsz; ++k) { + charset[k] = toupper(charset[k]); + } + + for (i = 0; i < nwrs; ++i) { + if (wrlenmin == wrlenmax) { + wrlen = wrlenmin; + } else { + wrlen = wrlenmin + rand() % (1 + wrlenmax - wrlenmin); + } + for (j = 0; j < wrlen; ++j) { + k = rand() % setsz; + teeputc(charset[k]); + } + teeputc('\n'); + } + + return 0; +} |