Added various origin projects
[name-generation.git] / element-lists / names-2.0.1 / src / names.c
1 /* Names v2.01 Copyright 1995 by Michael Harvey */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "names.h"
8 #include "keyb.h"
9
10 void clear(void);
11 void version(void);
12 void gen(void);
13 void display(void);
14 void helpscr(void);
15
16 #ifndef TRUE
17 #define TRUE 1
18 #endif
19 #ifndef FALSE
20 #define FALSE 0
21 #endif
22
23 #define LINES 20
24 #define COLUMNS 2
25 #define BUFLEN 40
26
27 #define SAVED ' '
28 #define ready() move(21,1)
29
30 #ifdef UNIX
31 #define getkey() getchar()
32 #endif
33
34 #ifdef TURBOC
35 #include <conio.h>
36 #define getkey() getch()
37 #define kb_init() /**/
38 #define kb_wait() /**/
39 #define kb_done() /**/
40
41 #define clear() clrscr()
42 #define move(y,x) gotoxy(x,y)
43 #endif
44
45 enum { O_PS, O_PMS, O_N, O_X, O_NA, O_XA, O_NX };
46
47 char scr[LINES][COLUMNS][BUFLEN];
48 int saved[LINES][COLUMNS];
49
50 char buf1[80];
51 char buf2[80];
52
53 #ifndef TURBOC
54 void clear()
55 {
56 if (ansi) printf("\033c");
57 else putchar('\n');
58 }
59
60 void move(int y, int x)
61 {
62 if (ansi) printf("\033[%d;%df",y,x);
63 }
64 #endif
65
66 void helpscr()
67 {
68 clear();
69 version();
70 puts("\nPress SPACE to generate a screenful of names.");
71 puts("Individual names can be saved to the output file by pressing");
72 puts("the appropriate key. ENTER quits the program.");
73 puts("\nOther commands:\n");
74 puts(" ! invoke a shell");
75 puts(" ? this help screen");
76 getkey();
77 }
78
79 char * cap(char *buf) /* capitalize one word */
80 {
81 char *p;
82 if (caps==1)
83 {
84 dprint2("cap(%s)",buf);
85 p=buf;
86 while (*p==' ') p++;
87
88 if (*p >= 'a' && *p <= 'z')
89 *p -= ('a' - 'A');
90 dprint2("=\"%s\"\n",buf);
91 }
92 if (strlen(buf)==0) dprint("==========> cap() buf=\"%s\"\n",buf);
93 return buf;
94 }
95
96 void cap2(char *buf) /* capitalize everything in buffer */
97 {
98 char *p;
99 int newword=1;
100
101 for (p=buf; *p; p++)
102 {
103 if (*p==' ')
104 newword=1;
105 else if (newword) /* capitalize */
106 {
107 if (*p >= 'a' && *p <= 'z')
108 *p -= ('a' - 'A');
109 newword=0;
110 }
111 /* else ignore */
112 }
113 }
114
115 char * plur(char *buf)
116 {
117 char *p;
118
119 if (!plurs) return buf;
120 dprint2("plur(%s)",buf);
121
122 for (p=buf; *p; p++) ; /* find end of string */
123 p--; /* find last char */
124
125 if (*p=='a' || *p=='e' || *p=='i' || *p=='o' || *p=='u') {
126 strcat(buf,"s");
127 } else if (*p=='y') {
128 p--;
129 if (*p=='a' || *p=='e' || *p=='i' || *p=='o' || *p=='u') {
130 strcat(buf,"s");
131 } else {
132 p++;
133 *p=0;
134 strcat(buf,"ies");
135 }
136 } else if (*p=='s') {
137 p--;
138 if (*p=='s') strcat(buf,"es");
139 } else if (*p=='h') {
140 p--;
141 if (*p=='t' || *p=='s' || *p=='c' || *p=='r' || *p=='z')
142 strcat(buf,"es");
143 else strcat(buf,"s");
144 }else if (*p=='f') {
145 p-=2;
146
147 if (strncmp(p,"aff",3)==0)
148 strcpy(p,"aves");
149 else if (strncmp(p,"arf",3)==0)
150 strcpy(p,"arves"); /* or "arrows" */
151 else if (strncmp(p,"elf",3)==0)
152 strcpy(p,"elves");
153 } else if (*p!='c' && *p!='j' && *p!='v' && *p!='x' && *p!='z')
154 strcat(buf,"s");
155
156 dprint2("=\"%s\"\n",buf);
157 if (strlen(buf)==0) dprint("==========> plur() buf=\"%s\"\n",buf);
158 return buf;
159 }
160
161 int rnd(int n)
162 {
163 if (n<=0)
164 {
165 dprint("error: rnd(0)\n");
166 return 0;
167 }
168 return (rand() % n);
169 }
170
171 char * my_select(int n)
172 {
173 int i;
174 char *p;
175
176 if (n>=NONE) dprint("error: n==NONE\n");
177
178 i = rnd(siz[n]);
179
180 if (i<0 || i>=siz[n])
181 {
182 dprint("error: i==%d siz[%d]==%d\n",i,siz[n],n);
183 i=0;
184 }
185 p = data[n][i];
186
187 if (strlen(p)==0)
188 {
189 dprint("###### data[%2d][%d] = \"%s\"\n",n,i,p);
190 }
191
192 if (p==NULL)
193 {
194 dprint("error: data[%d][%d]==NULL\n",n,i);
195 p="ERR";
196 }
197 dprint1("my_select(%d): data[%d][%d]='%s'\n",n,n,i,p);
198 return p;
199 }
200
201 char * number(char *buf, char *n1)
202 {
203 switch(rnd(16))
204 {
205 case 0: sprintf(buf,"No %s",plur(n1)); break;
206 case 1: sprintf(buf,"One %s",n1); break;
207 case 2: sprintf(buf,"Two %s",plur(n1)); break;
208 case 3: sprintf(buf,"Three %s",plur(n1)); break;
209 case 4: sprintf(buf,"Four %s",plur(n1)); break;
210 case 5: sprintf(buf,"Five %s",plur(n1)); break;
211 case 6: sprintf(buf,"Six %s",plur(n1)); break;
212 case 7: sprintf(buf,"Seven %s",plur(n1)); break;
213 case 8: sprintf(buf,"Eight %s",plur(n1)); break;
214 case 9: sprintf(buf,"Nine %s",plur(n1)); break;
215 case 10: sprintf(buf,"Ten %s",plur(n1)); break;
216 case 11: sprintf(buf,"Eleven %s",plur(n1)); break;
217 case 12: sprintf(buf,"Twelve %s",plur(n1)); break;
218
219 case 13: sprintf(buf,"Hundred %s",plur(n1)); break;
220 case 14: sprintf(buf,"Lone %s",n1); break;
221 case 15: sprintf(buf,"Many %s",plur(n1)); break;
222 }
223 if (strlen(buf)==0) dprint("==========> number() buf=\"%s\"\n",buf);
224 return buf;
225 }
226
227 void type1(char *buf, char *n1, char *n2) /* noun / noun */
228 {
229 char *fmt;
230 int i;
231
232 if (simple) i = 0;
233 else i = rnd(5);
234
235 switch(i)
236 {
237 case 0: sprintf(buf,"%s%s",cap(n1),n2);
238 dprint2("(nn)");
239 break;
240 case 1: sprintf(buf,"%s and %s",cap(n1), cap(n2));
241 switch (rnd(2)) {
242 case 0: strcat(buf," Inn"); break;
243 case 1: strcat(buf," Tavern"); break;
244 }
245 dprint2("(n and n x)");
246 break;
247 case 2: if (rnd(2)) {
248 sprintf(buf,"%s of %s",plur(cap(n1)),cap(n2));
249 dprint2("(ns of n)");
250 } else {
251 sprintf(buf,"%s of %s",cap(n1),plur(cap(n2)));
252 dprint2("(n of ns)");
253 } break;
254 case 3: switch(rnd(3)) {
255 case 0:
256 sprintf(buf,"%s of the %s",cap(n1),plur(cap(n2)));
257 dprint2("(n of the ns)");
258 break;
259 case 1:
260 sprintf(buf,"%s of the %s",plur(cap(n1)),cap(n2));
261 dprint2("(ns of the n)");
262 break;
263 case 2: sprintf(buf,"%s of the %s",plur(cap(n1)),plur(cap(n2)));
264 dprint2("(ns of the ns)");
265 break;
266 } break;
267 case 4: number(buf,cap(n1));
268 switch(rnd(5)) {
269 case 2: strcat(buf," Inn"); break;
270 case 3: strcat(buf," Harbor"); break;
271 case 4: strcat(buf," Tower"); break;
272 }
273 dprint2("(# ns [x])");
274 break;
275 }
276 if (strlen(buf)==0) dprint("==========> type1() buf=\"%s\"\n",buf);
277 }
278
279 void type2(char *buf, char *n, char *a) /* noun / adj */
280 {
281 char *fmt;
282 int i;
283 char tmp[80];
284
285 if (simple) i = rnd(2);
286 else i = rnd(4);
287
288 switch(i)
289 {
290 case 0: sprintf(buf,"%s%s",a,n);
291 dprint2("(na)");
292 cap(buf);
293 break;
294 case 1: sprintf(buf,"%s %s",a,n);
295 dprint2("(n a)");
296 cap(buf);
297 break;
298 case 2: sprintf(buf,"%s %s",cap(a),cap(n));
299 dprint2("(n a [x])");
300 #ifdef NEVER
301 switch (rnd(6)) {
302 /* 0,1,2 leave as is */
303 case 3: strcat(buf," Inn"); break;
304 case 4: strcat(buf," Town"); break;
305 case 5: strcat(buf," Tower"); break;
306 }
307 #endif
308 break;
309 case 3: sprintf(tmp,"%s %s",cap(a), cap(n));
310 number(buf,tmp);
311 dprint2("(# a ns)");
312 break;
313 }
314 if (strlen(buf)==0) dprint("==========> type2() buf=\"%s\"\n",buf);
315 }
316
317
318 void newname(char *buf)
319 {
320 int option[10], opt;
321 int numopt=0;
322 char *noun, *adj;
323
324 if (siz[PRE] && siz[SUF]) option[numopt++]=O_PS;
325 if (siz[PRE] && siz[MID] && siz[SUF]) option[numopt++]=O_PMS;
326 if (siz[NOUN]) option[numopt++]=O_N;
327 if (siz[NADJ]) option[numopt++]=O_X;
328 if (siz[NOUN] && siz[ADJ]) option[numopt++]=O_NA;
329 if (siz[NOUN] && siz[NADJ]) option[numopt++]=O_NX;
330 if (siz[NADJ] && siz[ADJ]) option[numopt++]=O_XA;
331
332 if(debug) for (opt=0; opt<numopt; opt++)
333 dprint3("%c", "PMNX123"[option[opt]]);
334
335 opt = option[rnd(numopt)];
336 dprint3(" -> %c ","PMNX123"[opt]);
337
338 switch(opt)
339 {
340 case O_PMS:
341 dprint3("M");
342 case O_PS:
343 dprint3("PS ");
344 strcpy(buf,my_select(PRE));
345 if (opt==O_PMS) strcat(buf,my_select(MID));
346 strcat(buf,my_select(SUF));
347 cap(buf);
348 break;
349
350 case O_N:
351 dprint3("N ");
352 strcpy(buf1,my_select(NOUN));
353 strcpy(buf2,my_select(NOUN));
354 type1(buf,buf1,buf2);
355 break;
356
357 case O_X:
358 dprint3("X ");
359 strcpy(buf1,my_select(NADJ));
360 strcpy(buf2,my_select(NADJ));
361 type1(buf,buf1,buf2);
362 break;
363
364 case O_NA:
365 dprint3("NA ");
366 strcpy(buf1,my_select(NOUN));
367 strcpy(buf2,my_select(ADJ));
368 type2(buf,buf1,buf2);
369 break;
370
371 case O_XA:
372 dprint3("XA ");
373 strcpy(buf1,my_select(NOUN));
374 if (rnd(2))
375 strcpy(buf2,my_select(ADJ));
376 else strcpy(buf2,my_select(NADJ));
377 type2(buf,buf1,buf2);
378 break;
379
380 case O_NX:
381 dprint3("NX ");
382 if (rnd(2))
383 strcpy(buf1,my_select(NOUN));
384 else strcpy(buf1,my_select(NADJ));
385 strcpy(buf2,my_select(ADJ));
386 type2(buf,buf1,buf2);
387 break;
388
389 default:
390 dprint3("? ");
391 strcpy(buf,"[err]");
392 break;
393 }
394 if (caps==2)
395 {
396 cap2(buf);
397 }
398 }
399
400 void gen()
401 {
402 int lin,col;
403
404 for (lin=0; lin<LINES; lin++)
405 for (col=0; col<COLUMNS; col++)
406 {
407 dprint1("gen: [%2d][%d]\n",lin,col);
408 newname(scr[lin][col]);
409 dprint1(" = \"%s\"\n",scr[lin][col]);
410 saved[lin][col]=0;
411 }
412 }
413
414 void display()
415 {
416 int lin;
417 static char tmp[200],*p;
418
419 clear();
420 for (lin=0; lin<LINES; lin++)
421 {
422 if (ansi)
423 {
424 /* this should be a tad faster on slow terminals */
425 move(lin+1,1);
426 printf("(%c) %s",
427 (saved[lin][0]?SAVED:lin+'a'), scr[lin][0]);
428
429 move(lin+1,41);
430 printf("(%c) %s",
431 (saved[lin][1]?SAVED:lin+'A'), scr[lin][1]);
432 }
433 else
434 {
435 printf("(%c) %-35s (%c) %-35s\n",
436 (saved[lin][0]?SAVED:lin+'a'), scr[lin][0],
437 (saved[lin][1]?SAVED:lin+'A'), scr[lin][1]);
438 }
439
440 if (debug>3)
441 {
442 sprintf(tmp,"(%c) %-35s (%c) %-35s\n",
443 (saved[lin][0]?SAVED:lin+'a'), scr[lin][0],
444 (saved[lin][1]?SAVED:lin+'A'), scr[lin][1]);
445
446 p=tmp;
447
448 while (*p)
449 {
450 if (*p=='\n') putchar('\n');
451 else if (*p<' ') switch(*p)
452 {
453 case '\a': printf("\\a"); break;
454 case '\b': printf("\\b"); break;
455 case '\f': printf("\\f"); break;
456 case '\r': printf("\\r"); break;
457 case '\t': printf("\\t"); break;
458 case '\v': printf("\\v"); break;
459 default: printf("[%d]",*p); break;
460 }
461 else putchar(*p);
462 p++;
463 }
464 } /* debug */
465 }
466 move(LINES+2,1); printf("(SPACE) more (ENTER) quit (?) help\n");
467 ready();
468 }
469
470 void savename(int row, int col)
471 {
472 if (saved[row][col]) return;
473 if (row<0 || col<0 || row>=LINES || col>=COLUMNS)
474 {
475 putchar(7); /* beep */
476 return;
477 }
478
479 /* open output file if it isn't already open */
480 if (!isopen)
481 {
482 outfp = fopen(outfile,"a"); /* append */
483 if (outfp)
484 isopen=1;
485 }
486
487 /* if its open, write the name */
488 if (isopen)
489 {
490 fprintf(outfp,"%s\n",scr[row][col]);
491 saved[row][col] = 1; /* remember we saved this one */
492 move(row+1,(col*40)+2);
493 putchar(SAVED);
494 ready();
495 }
496 }
497
498 void names()
499 {
500 int c;
501 int done=FALSE;
502
503 if (forever)
504 {
505 for(;;)
506 {
507 newname(scr[0][0]);
508 puts(scr[0][0]);
509 }
510 }
511 else
512 {
513 kb_init();
514 kb_wait();
515
516 gen();
517 display();
518
519 do
520 {
521 c = getkey();
522 switch(c)
523 {
524 case ' ':
525 gen();
526 display();
527 break;
528 case '?':
529 helpscr();
530 display();
531 break;
532 case '!':
533 system("/bin/csh");
534 break;
535 case '\r':
536 case '\n':
537 done=TRUE;
538 break;
539
540 default:
541 if (c>='a' && c<=('a'+19))
542 {
543 savename(c-'a', 0);
544 }
545 else if (c>='A' && c<=('A'+19))
546 {
547 savename(c-'A', 1);
548 }
549 break;
550 }
551 }
552 while (!done);
553
554 move(LINES+3,1);
555 if (isopen) fclose(outfp);
556 kb_done();
557 }
558 }
559