summaryrefslogtreecommitdiff
path: root/kochgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'kochgen.c')
-rw-r--r--kochgen.c148
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;
+}