all repos — nimisewi_c @ 44c234cfdf8588e5c53a9534cc2ee1c627682f7c

simple random toki pona phrase generator

nimisewi.c (view raw)

  1/* Copyright (c) 2021, la-ninpre
  2 * 
  3 * Permission to use, copy, modify, and/or distribute this software for any
  4 * purpose with or without fee is hereby granted, provided that the above
  5 * copyright notice and this permission notice appear in all copies.
  6 * 
  7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 13 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 14 *
 15 * *************************************************************************
 16 * 
 17 * this file contains main code for nimisewi.
 18 * 
 19 * nimisewi is a small program that generates random toki pona noun phrase.
 20 * toki pona is a small constructed language created by sonja lang 
 21 * (see https://tokipona.org).
 22 *
 23 * functions and variables here a primarily named in tokipona, just because i
 24 * can. but just in case there are annotations in english.
 25 *
 26 * sona nanpa li ike. taso ona li pali e nimi pona.
 27 */
 28
 29#include <err.h>
 30#include <stdio.h>
 31#include <stdlib.h>
 32#include <unistd.h>
 33
 34#include <sys/types.h>
 35#include <sys/time.h>
 36
 37#include "nimisewi.h"
 38#include "nimitoki.h" /* nimi_toki, suli_pi_nimi_toki */
 39
 40void
 41open_e_nanpa_sewi()
 42{
 43    /* initialize pseudorandom generator using pid, microseconds and seconds
 44     *
 45     * for such silly program there's no need to implement cryptographically
 46     * secure random number generator.
 47     */
 48
 49    pid_t pid;
 50    struct timeval time;
 51
 52    gettimeofday(&time, NULL);
 53    pid = getpid();
 54    srand(pid * time.tv_usec * time.tv_sec);
 55}
 56
 57const char
 58*pana_e_nimi(const char *nimi_mute[],
 59             const int suli_pi_nimi_mute,
 60             const int nanpa_nimi)
 61{
 62    /* wrapper function to get word from array
 63     *
 64     * noun phrases in toki pona could have arbitrary amount of words and they
 65     * are left grouped (the leftmost word is main, and words to the right
 66     * are modifying it:
 67     *
 68     * ((nimi) sewi)
 69     *
 70     * special word 'pi' could be used to alter this grouping order to achieve
 71     * something like english preposition 'of'
 72     *
 73     * ((suli) pi ((nimi) mute))
 74     *
 75     * this functions inserts 'pi' in the middle to avoid generating
 76     * very heavy phrases.
 77     */
 78
 79    if (nanpa_nimi > suli_pi_nimi_mute) {
 80        err(EXIT_FAILURE, "index out of bounds");
 81    } else if (nanpa_nimi == -1) {
 82        return "pi";
 83    } else {
 84        return nimi_mute[nanpa_nimi];
 85    }
 86}
 87
 88void
 89pana_e_nanpa_nimi(struct nanpa_nimi *nn)
 90{
 91    /* generate random number, which is later used as number of words
 92     * in the phrase
 93     *
 94     * also here is made decision, whether to insert 'pi'
 95     */
 96    nn->pi_li_lon = 0;
 97    nn->nanpa_pi = -1;
 98    nn->nanpa_nimi = (rand() % 6);
 99
100    if (nn->nanpa_nimi == 2) {
101        nn->pi_li_lon = rand() % 2;
102    } else if (nn->nanpa_nimi > 2) {
103        nn->pi_li_lon = 1;
104    }
105    if (nn->pi_li_lon) {
106        nn->nanpa_nimi++;
107        nn->nanpa_pi = (nn->nanpa_nimi / 2);
108    }
109}
110
111void
112pana_e_nanpa_pi_nimi_sewi(int *nanpa_sewi_mute,
113                          const int suli_nimi,
114                          struct nanpa_nimi *nn)
115{
116    /* create specified amount of random numbers
117     *
118     * they are used later as indices to get words from wordlist
119     */
120
121    int i;
122
123    for (i = 0; i <= nn->nanpa_nimi; i++) {
124        nanpa_sewi_mute[i] = rand() % suli_nimi;
125    }
126
127    if (nn->pi_li_lon) {
128        nanpa_sewi_mute[nn->nanpa_pi] = -1;
129    }
130}
131
132int
133main(void)
134{
135    int *nanpa_sewi_nimi; /* container for random indices */
136    int i;
137    struct nanpa_nimi nn; /* see nimisewi.h */
138
139#ifdef __OpenBSD__
140    if (pledge("stdio", NULL) == -1) {
141        err(EXIT_FAILURE, "pledge");
142    }
143#endif
144    open_e_nanpa_sewi();
145
146    pana_e_nanpa_nimi(&nn);
147
148    nanpa_sewi_nimi = (int *) calloc(nn.nanpa_nimi + 1, sizeof(int));
149    if (nanpa_sewi_nimi == NULL) {
150        err(EXIT_FAILURE, "calloc");
151    }
152
153    pana_e_nanpa_pi_nimi_sewi(nanpa_sewi_nimi, suli_pi_nimi_toki, &nn);
154
155    /* i think that this section could be improved. i had an idea that
156     * it would be cool to include options to output in cgi format instead
157     * of just text
158     */
159    for (i = 0; i < nn.nanpa_nimi; i++) {
160        printf("%s ",
161                pana_e_nimi(nimi_toki, suli_pi_nimi_toki, nanpa_sewi_nimi[i]));
162    }
163    printf("%s", pana_e_nimi(nimi_toki, suli_pi_nimi_toki, nanpa_sewi_nimi[i]));
164    printf("\n");
165
166    free(nanpa_sewi_nimi);
167
168    return 0;
169}
170