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