]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/festoon.c
games/nes: fix buffer overrun
[plan9front.git] / sys / src / games / festoon.c
1 #include <u.h>
2 #include <libc.h>
3 #include <stdio.h>
4
5 #define R rand()&32767
6 #define T 0.125
7 #define CHOOSE(x) (x[(R)%(sizeof x / sizeof x[0])])
8 #define EQ(a,b) (strcmp(a,b)==0)
9 #define LAST(x) (x[strlen(x)-1])
10 #define VOWEL(x) (x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
11 #define N 8
12
13 typedef struct xyz {
14         char           *type;
15         union {
16                 struct xyz     *x[N];
17                 char           *s[N];
18         }               list;
19 }              *X, XX;
20 typedef struct {
21         char           *number, *ending, *tense, *an, *unspec, *passive;
22 }              *E, EE;
23
24 char           *tense(), *number();
25 char            buff[1000];
26 int             io;
27 int             flag;
28 int             eqn=0, tbl=0, pic=0;
29 double          makeup = -1.;
30
31 X np(E);
32 X aux(E);
33 X passive(E);
34 X passprep(void);
35 X vp(E);
36 X art(E);
37 X modal(E);
38 X perf(E);
39 X prog(E);
40 X verb(E);
41 X noun(E);
42 X nounal(E);
43 char *prefix(void);
44 char *root(void);
45 int prob(double);
46 char *tense(void);
47 char *number(void);
48 X getxx(void);
49 X verbal(E);
50 X adverb(void);
51 X adjective(void);
52 X adjph(E);
53 X prep(void);
54 X comp(E);
55 X advp(E);
56 X vprep(void);
57 E getenvq(void);
58 X comma(E);
59 X conjadv(void);
60 X lconjadv(void);
61 X conjsub(void);
62 X lconjsub(void);
63 X conj(void);
64 X nomz(void);
65 X equation();
66 X turgid(E);
67 void pr(X);
68 void out(char *);
69 void caps(void);
70 void abo(void);
71 char *splitup(char *);
72
73
74 nomq(E env) {
75         X               v = getxx();
76         v->type = "-nomq";
77         if (EQ(env->number, "sing")) {
78                 if (EQ(tense(), "past"))
79                         v->list.s[0] = "there was";
80                 else
81                         v->list.s[0] = "there is";
82         } else {
83                 if (EQ(tense(), "past"))
84                         v->list.s[0] = "there were";
85                 else
86                         v->list.s[0] = "there are";
87         }
88         if (prob(0.2))
89                 v->list.s[1] = " not";
90         return v;
91 }
92
93
94 rel(void) {
95         static char    *c[] = {"that", "which"};
96         X               v = getxx();
97         v->type = "-rel";
98         v->list.s[0] = CHOOSE(c);
99         return v;
100 }
101
102
103 sent(E env) {
104         X               sentv = getxx();
105         sentv->type = "sent";
106         if (prob(0.09)) {
107                 env->unspec = "";
108                 sentv->list.x[1] = np(env);
109                 sentv->list.x[3] = aux(env);
110                 sentv->list.x[4] = vp(env);
111                 sentv->list.x[0] = nomq(env);
112                 sentv->list.x[2] = rel();
113                 return sentv;
114         }
115         sentv->list.x[0] = np(env);
116         sentv->list.x[1] = aux(env);
117         sentv->list.x[2] = vp(env);
118         return sentv;
119 }
120
121
122 nomy(void) {
123         X               v = getxx();
124         v->type = "-nomq";
125         v->list.s[0] = "the fact that";
126         return v;
127 }
128
129
130 np(env)
131         E               env;
132 {
133         X               npv = getxx();
134         EE              nenv;
135         static EE       empty;
136         npv->type = "np";
137         if (prob(0.025)) {
138                 nenv = empty;
139                 npv->list.x[0] = nomy();
140                 npv->list.x[1] = sent(&nenv);
141                 if (env->number == 0)
142                         env->number = "sing";
143                 return npv;
144         }
145         npv->list.x[1] = nounal(env);
146         npv->list.x[0] = art(env);
147         return npv;
148 }
149
150
151 aux(E env) {
152         X               auxv = getxx();
153         int             i = 0;
154         auxv->type = "aux";
155         if (env->tense == 0)
156                 env->tense = env->ending = tense();
157         if (prob(0.25))
158                 auxv->list.x[i++] = modal(env);
159         if (prob(0.25))
160                 auxv->list.x[i++] = perf(env);
161         if (prob(0.25))
162                 auxv->list.x[i++] = prog(env);
163         USED(i);
164         return auxv;
165 }
166
167
168 passive(env)
169         E               env;
170 {
171         X               v = getxx();
172         v->type = "-passive";
173         if (env->tense == 0)
174                 env->tense = env->ending = tense();
175         if (env->number == 0)
176                 env->number = number();
177         if (EQ(env->ending, "modal"))
178                 v->list.s[0] = "be";
179         else if (EQ(env->ending, "-en"))
180                 v->list.s[0] = "been";
181         else if (EQ(env->ending, "-ing"))
182                 v->list.s[0] = "being";
183         else {
184                 if (EQ(env->tense, "past"))
185                         v->list.s[0] = EQ(env->number, "sing") ? "was" : "were";
186                 else
187                         v->list.s[0] = EQ(env->number, "sing") ? "is" : "are";
188         }
189         env->passive = env->ending = "pass";
190         return v;
191 }
192
193
194 passprep(void) {
195         X               v = getxx();
196         v->type = "-passprep";
197         v->list.s[0] = "by";
198         return v;
199 }
200
201
202 vp(env)
203         E               env;
204 {
205         X               vpv = getxx();
206         int             i = 0;
207         vpv->type = "vp";
208         if (prob(0.5))
209                 vpv->list.x[i++] = passive(env);
210         vpv->list.x[i++] = verbal(env);
211         vpv->list.x[i++] = comp(env);
212         if (prob(0.10))
213                 vpv->list.x[i++] = advp(env);
214         USED(i);
215         return vpv;
216 }
217
218
219 art(env)
220         E               env;
221 {
222         static char    *aspecsg[] = {"the", "the", "the", "the", "the", "this", "this", "that"};
223         static char    *aspecpl[] = {"the", "the", "the", "the", "the", "these", "those"};
224         static char    *aunssg[] = {"a", "a", "a", "a", "a", "a", "a", "much", "each", "any"};
225         static char    *aunspl[] = {"some", "a few", "a couple", "several", "many", "all",
226                 "no",
227                 "an undue number of",
228         "a number of"};
229         X               artv = getxx();
230         artv->type = "-art";
231         if (env->number == 0)
232                 env->number = number();
233         if (env->unspec == 0 && prob(0.33)) {
234                 if (EQ(env->number, "sing"))
235                         artv->list.s[0] = CHOOSE(aspecsg);
236                 else
237                         artv->list.s[0] = CHOOSE(aspecpl);
238         } else if (prob(0.50) || env->an && EQ(env->number, "sing")) {
239                 if (EQ(env->number, "sing"))
240                         artv->list.s[0] = env->an ? "a" : CHOOSE(aunssg);
241                 else
242                         artv->list.s[0] = CHOOSE(aunspl);
243                 if (env->an && EQ(artv->list.s[0], "all"))
244                         artv->list.s[0] = "";
245         } else
246                 artv->list.s[0] = "";
247         env->unspec = 0;
248         if (env->an && EQ(env->an, "an") && EQ(artv->list.s[0], "a"))
249                 artv->list.s[0] = "an";
250         env->an = 0;
251         return artv;
252 }
253
254
255 modal(env)
256         E               env;
257 {
258         static char    *pres[] = {"can", "may", "must", "shall", "will"};
259         static char    *past[] = {"could", "might", "should", "would"};
260         X               modalv = getxx();
261         modalv->type = "-modal";
262         if (env->tense == 0)
263                 env->tense = env->ending = tense();
264         if (EQ(env->ending, "pres"))
265                 modalv->list.s[0] = CHOOSE(pres);
266         else
267                 modalv->list.s[0] = CHOOSE(past);
268         env->ending = "modal";
269         return modalv;
270 }
271
272
273 perf(env)
274         E               env;
275 {
276         X               perfv = getxx();
277         perfv->type = "-perf";
278         if (env->tense == 0)
279                 env->tense = env->ending = tense();
280         if (env->number == 0)
281                 env->number = number();
282         if (EQ(env->ending, "past")) {
283                 perfv->list.s[0] = "had";
284         } else if (EQ(env->ending, "pres")) {
285                 if (EQ(env->number, "sing"))
286                         perfv->list.s[0] = "had";
287                 else
288                         perfv->list.s[0] = "have";
289         } else
290                 perfv->list.s[0] = "have";
291         env->ending = "-en";
292         return perfv;
293 }
294
295
296 prog(env)
297         E               env;
298 {
299         X               progv = getxx();
300         progv->type = "-prog";
301         if (env->tense == 0)
302                 env->tense = env->ending = tense();
303         if (env->number == 0)
304                 env->number = number();
305         if (EQ(env->ending, "pres")) {
306                 if (EQ(env->number, "sing"))
307                         progv->list.s[0] = "is";
308                 else
309                         progv->list.s[0] = "are";
310         } else if (EQ(env->ending, "past")) {
311                 if (EQ(env->number, "sing"))
312                         progv->list.s[0] = "was";
313                 else
314                         progv->list.s[0] = "were";
315         } else if (EQ(env->ending, "-en")) {
316                 progv->list.s[0] = "been";
317         } else if (EQ(env->ending, "modal")) {
318                 progv->list.s[0] = "be";
319         }
320         env->ending = "-ing";
321         return progv;
322 }
323
324
325 verb(env)
326         E               env;
327 {
328         /* they pres, he pres, they past, they perf, they prog, they pass */
329         static char    *ends[][6] = {{"ate", "ates", "ated", "ated", "ating", "ated"},
330         {"en", "ens", "ened", "ened", "ening", "ened"},
331         {"esce", "esces", "esced", "esced", "escing", "esced"},
332         {"fy", "fies", "fied", "fied", "fying", "fied"},
333         {"ize", "izes", "ized", "ized", "izing", "ized"}};
334         X               verbv = getxx();
335         int             i;
336         verbv->type = "-verb";
337         if (env->tense == 0)
338                 env->tense = env->ending = tense();
339         if (env->number == 0)
340                 env->number = number();
341         if (0 && prob(0.1) && EQ(env->tense, env->ending)) {
342                 if (EQ(env->number, "sing")) {
343                         if (EQ(env->tense, "pres"))
344                                 verbv->list.s[0] = "is";
345                         else
346                                 verbv->list.s[0] = "was";
347                 } else {
348                         if (EQ(env->tense, "pres"))
349                                 verbv->list.s[0] = "are";
350                         else
351                                 verbv->list.s[0] = "were";
352                 }
353         } else {
354                 verbv->list.s[0] = prefix();
355                 verbv->list.s[1] = root();
356                 if (EQ(env->ending, "pres") && EQ(env->number, "sing"))
357                         i = 1;
358                 else if (EQ(env->ending, "pres") || EQ(env->ending, "modal"))
359                         i = 0;
360                 else if (EQ(env->ending, "past"))
361                         i = 2;
362                 else if (EQ(env->ending, "-en"))
363                         i = 3;
364                 else if (EQ(env->ending, "-ing"))
365                         i = 4;
366                 else if (EQ(env->ending, "pass"))
367                         i = 5;
368                 else
369                         i = 0;
370                 verbv->list.s[2] = ends[R % (sizeof ends / sizeof *ends)][i];
371         }
372         env->ending = 0;
373         return verbv;
374 }
375
376 static char    *nounlist[] = {"final completion",
377         "final ending", "final outcome",
378         "adaptation", "appearance", "argument", "circumstance",
379         "confession", "confidence", "delimitation", "dilution",
380         "dissertation", "distribution", "duplication",
381         "entertainment", "equipment", "evolution",
382         "existence", "expression", "generation", "impression",
383         "integration", "interaction", "investment", "judgment",
384         "population", "provision", "solution", "statement",
385         "tradition", "transmission",
386         "final result", "added increment", "assistance",
387         "beneficial assistance", "mutual cooperation",
388         "projection", "future projection",
389         "capability", "conjecture", "consensus of opinion",
390         "general consensus", "absence", "deficiency",
391         "inadequacy", "insufficience", "insufficiency",
392         "growing importance", "renewed emphasis",
393         "renewed interest", "changing behavior",
394         "critical thinking", "careful thinking",
395         "comprehensive survey", "high standard",
396         "basic foundation", "system testing",
397         "serious discussion", "serious concern",
398         "organizational framework", "prototype model",
399         "uniform nomenclature", "greater cooperation",
400         "uniform consistency", "early expectation",
401         "standardization", "great similarity",
402         "shortage", "presence", "sufficiency",
403         "consequent result", "construct", "disutility",
404         "early beginning", "emotional feeling", "endeavor",
405         "authorization", "order of magnitude", "preference",
406         "impact", "joint cooperation", "joint partnership",
407         "main essential", "methodology", "modification",
408         "necessary requisite", "past history", "situation",
409         "effectuation", "clarification", "new doubt",
410         "policy", "encouragement", "preparation",
411         "criterion", "material", "interest", "acceptance",
412         "rejection", "publication", "circulation",
413         "protection", "insurance",
414         "assignment", "identification",
415         "submission", "request",
416         "guidance", "correspondence", "inclusion",
417         "attachment", "assumption",
418         "recommendation", "prescription", "approval",
419         "discretion", "responsibility", "relevance",
420         "issuance", "termination", "total effect",
421         "deleterious effect", "consolidation",
422         "aggregation", "definiteness", "commencement",
423         "actual experience", "experience",
424         "combination", "accord", "filing",
425         "idea", "abstraction", "method", "procedure",
426         "complaint", "maintenance", "finance", "travel",
427         "purchase", "repair", "routine",
428         "development", "cancellation",
429         "partitioning", "development effort",
430         "project", "automation", "multilevel architecture",
431         "multilevel heirarchy", "data stream",
432         "objective",
433         "individual assignment", "mode of operation",
434         "clear community", "attendant interest",
435         "task division", "well defined interfacing",
436         "team report", "meeting time", "effective use",
437         "friction",
438         "major objective", "ownership",
439         "overall project time constraint",
440         "functional division", "requirements analysis",
441         "code development", "charter",
442         "requirements definition", "vertical division",
443         "broad range", "strong feeling",
444         "considerable latitude", "overall project constraint",
445         "sufficient resource", "assigned task", "expectation",
446         "critical aspect", "clear understanding",
447         "computing load", "clean interfacing", "natural basis",
448         "team activity", "team responsibility",
449         "main function", "predominant portion",
450         "work plan", "major breakpoint", "work module",
451         "achievable accuracy", "supplementary work",
452         "field version", "internal establishment",
453         "internal communication", "development progress",
454         "internal meeting", "experience level",
455         "high level autonomy", "adherence",
456         "feasibility demonstration", "persistent problem",
457         "internal objective", "idea sharing",
458         "improved performance", "unfamiliar methodology",
459         "new methodology", "development experience",
460         "module specification", "good progress",
461         "optimal number", "natural division",
462         "good relationship", "cross attendance",
463         "attendance", "necessary communication",
464         "evolving organization", "basic principle",
465         "complete revision", "general information",
466         "primary objective", "load-carrying capacity",
467         "necessary revision", "major change",
468         "clarified interpretation", "subsequent attempt",
469         "basic objective", "full utilization",
470         "practical consideration",
471         "proportionate quantity", "substantial change",
472         "database design", "unified framework",
473         "customer service", "strong interest",
474         "unified description", "necessary background information",
475         "provisioning", "physical coverage", "general observation",
476         "new technology", "validity determination",
477         "relation", "regulation", "verification",
478         "impediment", "portal", "practice", "premise",
479         "basis", "movement", "question",
480         "issue", "input", "output", "observation",
481         "input", "output", "input", "output",
482         "mechanization", "function", "evaluation",
483         "result", "further consideration", "category",
484         "performance indicator", "early warning",
485         "analysis purpose", "measurement", "replacement",
486         "utilitarian purpose",
487         "quota", "proposed enhancement", "enhancement",
488         "interfacing", "team organization", "module",
489         "guideline", "continuing study",
490         "required assistance", "major advance",
491         "proposal", "hierarchy",
492         "current view", "refinement", "activity",
493         "external description", "tight schedule pressure",
494         "internal conflict", "internal issue",
495         "reasonable compromise", "next phase",
496         "goal", "time constraint", "constraint",
497         "outcome", "important outcome",
498         "considerable experience", "intelligent choice",
499         "deliverable documentation", "discussion",
500         "timely delivery", "design issue", "large quantity",
501         "general environment", "protocol",
502         "transitioning", "modeling",
503         "considerable difficulty", "abstract interfacing",
504         "data structure", "consideration", "difficulty",
505         "statistical accuracy",
506         "agenda", "technique", "reordering",
507         "reauthorization", "current proposal",
508         "significant change", "criteria", "validation",
509         "validity",
510         "terminology", "current understanding",
511         "incorporation", "staffing impact",
512         "schedule impact", "cost tradeoff",
513         "system architecture",
514         "adequate capacity", "centralization",
515         "current task", "system deployment",
516         "attendant uncertainty", "process",
517         "potential usefulness", "proposed method",
518         "basic assumption", "anomaly",
519         "available data", "potential improvement",
520         "registration", "exemption", "exception",
521         "follow-up", "service",
522         "installation", "construction", "necessity",
523         "occasion", "instrumentation", "disposal",
524         "attractiveness",
525         "convenience", "sponsoring",
526         "signification", "meaningfulness",
527         "significantness", "individuality",
528         "specification", "determination", "affirmation",
529         "recruitment", "supervision", "management",
530         "oversight", "overview", "environment",
531         "effectation", "circumvention", "location",
532         "execution", "effectiveness", "consciousness",
533         "notation", "confirmation", "restriction",
534         "organization", "realization", "actification",
535         "activation", "reification", "beginning", "conclusion",
536         "ending", "finishing", "teamwork", "motivation",
537         "attitude", "good attitude",
538         "progress", "milestone", "deadline", "schedule",
539         "allocation", "resource", "command", "concern",
540         "time", "time frame", "reality",
541         "behaviour", "ability", "advent", "increment",
542         "opportunity", "accomplishment", "aggregate",
543         "analysis", "totality", "matter",
544         "date", "duration", "centrality",
545         "proximity", "collection", "elimination",
546         "investigation", "opinion", "debate",
547         "decision", "benefit", "difference", "discontinuity",
548         "fabrication", "plan", "chart", "forecast",
549         "simplicity", "simplification", "maximization",
550         "minimization", "direction",
551         "agreement",
552         "amount", "quantity", "quality", "essence",
553         "description", "violation", "purpose",
554         "primary purpose", "automatic control", "redefinition",
555         "uniform emphasis", "study activity", "work activity",
556         "concept stage", "concept activity",
557         "possible potential", "summarization", "system function",
558         "rationale", "significant enhancement", "diverse need",
559         "diverse organization", "comprehensive plan", "interim",
560         "functional overview", "system configuration",
561         "configuration", "failure", "quantitative result",
562         "major obstacle", "conception",
563         "effectiveness", "final evaluation",
564         "interrelationship", "functional requirement",
565         "system philosophy", "verbal interchange",
566         "perceived inadequacy", "primary emphasis",
567         "intermingling", "cooperation", "partnership",
568         "adjustment", "application", "implementation",
569         "contact", "mention", "power",
570         "nature", "invention", "importance",
571         "ground", "reason", "permission", "size",
572         "report", "documentation", "priority",
573         "pursuance", "recurrance", "resumption",
574         "presupposition", "continuance",
575         "substantiation", "success", "action", "truth",
576         "past experience", "greater acceptability",
577         "organizational structure", "clear distinction",
578         "clear definition",
579         "significant use", "unmet need", "centralized organization",
580         "vague concept", "negative impact", "detrimental effect",
581         "modularization", "submodularization",
582         "effect", "consistancy",
583         "inconsistancy", "completion", "utilization",
584         "reference", "doubt", "evidence",
585         "viewpoint",
586         "actual fact",
587         "true fact", "underlying purpose", "viable alternative"};
588
589 static char    *adjlist[] = {"concrete", "abstract", "procedural",
590         "real", "ideal", "functional", "prototype",
591         "effective", "capable", "incremental",
592         "perceived", "associated", "interdepartmental",
593         "diverse", "characteristic", "worst-case",
594         "qualitative", "fully automatic", "candidate",
595         "consensual", "consequential", "conjectural",
596         "constructive", "initial", "cooperative",
597         "essential", "methodological", "requisite",
598         "historical", "situational", "political",
599         "prepared", "material", "defined", "well defined",
600         "organizational", "projected", "overall",
601         "accepted", "rejected", "corresponding",
602         "committed", "environmental", "typical", "working", "timely",
603         "growing", "unprecedented", "new", "renewed", "fresh",
604         "rapid", "changing", "careful", "comprehensive", "broad",
605         "massive", "huge", "enormous",
606         "evaluated", "discresionary",
607         "durable", "beneficial",
608         "maximal", "tremendous", "minimal",
609         "on-site", "standardized", "standard",
610         "powerful", "natural", "necessary",
611         "reasonable", "successful",
612         "doubtful", "dubious", "certain",
613         "unified", "different", "similar", "utilitarian",
614         "realizable", "organizable", "motivated",
615         "topical", "valuable", "feasible",
616         "intelligent", "deliverable", "nontrivial",
617         "worthwhile", "complicated",
618         "organized", "organizing", "progressing",
619         "schedulable", "resourceful", "commanding",
620         "important", "allocatable", "temporal",
621         "ponderable", "understandable", "comprehendable",
622         "past", "present", "future",
623         "obvious", "considerable", "finished", "completed",
624         "unique", "abovementioned",
625         "major", "minor", "tendentious", "activating",
626         "actual", "added", "adequate", "affordable",
627         "analyzable", "additional", "intuitive",
628         "artificial", "good", "better",
629         "worse", "bad", "basic", "fundamental", "brief",
630         "general", "very unique", "extreme", "most unique",
631         "central", "proximate", "approximate", "collected",
632         "conductable", "comtemplatable",
633         "continuing", "demonstrable", "desirable",
634         "correctable", "foreseeable",
635         "discontinued", "early", "beginning",
636         "effectuated", "elucidated", "emotional",
637         "enclosed", "enthused", "entire", "exact",
638         "experimental", "fearful", "final",
639         "following", "informative",
640         "full", "complete", "indicated", "authorized",
641         "modularized", "submodularized",
642         "particular", "preferred", "satisfactory",
643         "measurable", "referenced", "literal",
644         "modified",
645         "correct", "prioritized", "prolonged",
646         "regrettable", "apparent",
647         "continued", "subsequent", "sufficient",
648         "suggestive", "true", "ultimate", "separate",
649         "purposeful", "regarded", "resulting",
650         "doubtful", "evident", "interesting", "worthy",
651         "uniform", "vital", "viable",
652         "worthwhile", "alternative",
653         "sophisticated", "employed",
654         "clear", "lucid", "simple", "perspicuous",
655         "incomplete", "concerned"};
656
657
658 noun(env)
659         E               env;
660 {
661         static char    *suff[] = {"ion", "sion", "tion", "age",
662                 "ness", "ment", "ure",
663                 "ity", "iety", "ty", "ence", "ency", "ance",
664                 "ancy", "tude", "hood", "ture", "ate", "art", "ard",
665                 "ism", "ine", "stress", "trix", "ess",
666                 "dom", "ship", "eer", "ster", "ant", "ent", "ary",
667                 "ery", "ory", "ette", "let", "ling", "ule", "kin",
668                 "ar", "or", "ist", "fulness",
669                 "kin", "cule", "icle", "y", "ability", "iosos"};
670         X               nounv = getxx();
671         int             i = 0;
672         nounv->type = "-noun";
673         if (env->number == 0)
674                 env->number = number();
675         if (prob(makeup)) {
676                 if (prob(0.05)) {
677                         nounv->list.s[i++] = CHOOSE(adjlist);
678                         nounv->list.s[i++] = "ness";
679                 } else
680                         nounv->list.s[i++] = CHOOSE(nounlist);
681         } else {
682                 nounv->list.s[i++] = prefix();
683                 nounv->list.s[i++] = root();
684                 nounv->list.s[i++] = CHOOSE(suff);
685         }
686         if (EQ(env->number, "plural")) {
687                 if (LAST(nounv->list.s[i - 1]) == 's')
688                         nounv->list.s[i] = "es";
689                 else if (LAST(nounv->list.s[i - 1]) == 'y')
690                         nounv->list.s[i] = "ies";
691                 else
692                         nounv->list.s[i] = "s";
693         }
694         return nounv;
695 }
696
697
698 adjval(void) {
699         X               adjvalv = getxx();
700         int             i = 0;
701         adjvalv->type = "adjval";
702         if (prob(0.25)) {
703                 adjvalv->list.x[i++] = adverb();
704         }
705         do {
706                 adjvalv->list.x[i++] = adjective();
707         } while (i < N - 1 && prob(0.25));
708         return adjvalv;
709 }
710
711
712 nounal(env)
713         E               env;
714 {
715         X               nounalv = getxx();
716         int             i = 0;
717         X               p;
718         nounalv->type = "nounal";
719         if (prob(0.15)) {
720                 nounalv->list.x[i++] = adjval();
721         }
722         nounalv->list.x[i++] = noun(env);
723         if (prob(0.15)) {
724                 nounalv->list.x[i] = adjph(env);
725         }
726         env->an = "a";
727         for (p = nounalv; p->type[0] != '-'; p = p->list.x[0]);
728         for (i = 0; p->list.s[i]; i++) {
729                 if (p->list.s[i][0] == 0)
730                         continue;
731                 if (VOWEL(p->list.s[i][0])) {
732                         env->an = "an";
733                 }
734                 break;
735         }
736         return nounalv;
737 }
738
739 char           *
740 prefix(void) {
741         static char    *pref[] = {
742                 "amb", "ambi", "super", "hyper", "an", "tra", "trans", "post", "palim",
743                 "omni", "pan", "circ", "circum", "peri", "a", "ab", "abs", "de", "apo",
744                 "re", "ana", "mal", "ante", "pre", "fore", "pro", "infra", "para",
745                 "inter", "ultra", "extra", "trans", "cata", "de", "oct", "octa",
746                 "octo", "equi", "pseudo", "prim", "prot", "proto", "pent", "penta",
747                 "quin", "quint", "quinque", "pro", "tetr", "tetra", "quad", "quadr",
748                 "quadri", "quartet", "off", "bene", "hemi", "demi", "semi", "crypto",
749                 "cent", "centi", "hecto", "en", "em", "in", "im", "intro", "be",
750                 "macro", "poly", "mult", "multi", "neo", "nona", "novem", "ennea",
751                 "in", "un", "im", "il", "ir", "non", "a", "nil", "paleo", "mon", "mono",
752                 "uni", "e", "ex", "ec", "ef", "super", "supr", "sur", "hyper", "vic",
753                 "vice", "hept", "hepta", "sept", "septe", "septem", "septi", "hex",
754                 "hexa", "sex", "dis", "deca", "deka", "deci", "kilo", "mill", "milli",
755                 "tri", "per", "dia", "ad", "com", "di", "amphi", "bi", "bin", "bis",
756         "sub", "hypo", "epi", "eu", "holo"};
757         if (prob(0.65))
758                 return "";
759         return CHOOSE(pref);
760 }
761
762 char           *
763 root(void) {
764         static char    *root[] = {
765                 "pan", "omni", "arch", "zo", "rog", "rogat", "cred", "flect", "flex",
766                 "test", "hem", "hemato", "nasc", "nat", "bibl", "fer", "voc", "port", "lat",
767                 "fortuna", "ped", "chrom", "vinc", "vict", "crea", "cise", "mort", "mors",
768                 "necr", "claim", "clam", "hetero", "pel", "puls", "vac", "iso", "phobe",
769                 "phobia", "prim", "prime", "flu", "flux", "sequ", "liber", "liver", "theo",
770                 "magna", "medi", "man", "manu", "pen", "pend", "pens", "eu", "capit",
771                 "iatr", "aud", "aus", "cor", "cord", "cour", "grav", "ten", "tain",
772                 "tent", "sacr", "sacer", "heiro", "sanct", "cide", "mega", "ultima",
773                 "ridi", "risi", "leg", "jus", "jur", "nom", "duc", "duct", "duce",
774                 "bio", "viv", "vivi", "vita", "lus", "lum", "luc", "photo",
775                 "min", "philo", "phile", "phila", "amic", "anthrop", "poly", "multi",
776                 "fac", "fact", "fic", "fect", "meter", "psych", "mod", "mot", "mov",
777                 "nov", "neo", "neg", "uni", "alter", "ali", "idio", "pop", "dem",
778                 "demo", "lic", "licit", "poten", "posse", "potes", "mem", "simul",
779                 "arch", "homo", "mar", "mer", "vis", "vid", "scope", "auto", "mitt",
780                 "miss", "ac", "acr", "brev", "clud", "clus", "dorm", "micro", "aster",
781                 "astro", "rect", "recti", "forc", "fort", "path", "cap", "cep", "cept",
782                 "put", "tempo", "tempor", "dent", "dont", "ver", "veri",
783                 "feder", "fide", "feal", "fid", "cosm", "migra", "hydro", "aqu",
784                 "endo", "gyn", "logo", "opus", "oper", "graph", "scrib", "scrip",
785         "mis", "miso", "anni", "annu", "enni", "ced", "cede", "ceed", "cess"};
786         return CHOOSE(root);
787 }
788
789 prob(f)
790         double          f;
791 {
792         return (R) < (f * 32767.0);
793 }
794
795 char           *
796 tense()
797 {
798         return prob(0.5) ? "pres" : "past";
799 }
800
801 char           *
802 number()
803 {
804         return prob(0.25) ? "plural" : "sing";
805 }
806
807
808 getxx()
809 {
810         X               rv;
811         static XX       empty;
812
813         rv = (X) malloc(sizeof *rv);
814         if (rv == 0) {
815                 fprintf(stderr, "festoon: outa space\n");
816                 exits("space");
817         }
818         *rv = empty;
819         return rv;
820 }
821
822
823 verbal(env)
824         E               env;
825 {
826         X               verbalv = getxx();
827         int             i = 0;
828         verbalv->type = "verbal";
829         if (prob(0.25))
830                 verbalv->list.x[i++] = adverb();
831         verbalv->list.x[i] = verb(env);
832         return verbalv;
833 }
834
835 static char    *advlist[] = {"absolutely", "functionally",
836         "accordingly", "broadly", "actionably", "actually",
837         "additionally",
838         "ambiguously", "amply",
839         "analogously",
840         "aperiodically",
841         "apparently", "appreciably",
842         "appropriately", "approximately",
843         "arbitrarily",
844         "associatively",
845         "automatically",
846         "awfully",
847         "axiomatically",
848         "badly", "barely", "basically",
849         "beneficially",
850         "blatantly",
851         "capably", "carefully", "carelessly",
852         "casually", "causally", "cautiously",
853         "centrally", "certainly",
854         "cheaply", "cleanly",
855         "closely", "coarsely", "cognizantly",
856         "coincidentally", "collectively", "collaterally",
857         "comparably",
858         "competently", "completely", "comprehensibly",
859         "concededly", "conceivably",
860         "concisely", "conclusively", "concretely",
861         "concurrently", "conjecturally",
862         "currently",
863         "conscientously", "consequently", "consequentially",
864         "consistently", "constantly",
865         "contemporaneuosly", "constructively",
866         "continually", "continuously", "contractually",
867         "contrarily", "contributatively", "conveniently",
868         "conventionally",
869         "correctively",
870         "correctly",
871         "crudely",
872         "curiously",
873         "decidedly",
874         "deeply",
875         "deficiently", "demandingly",
876         "dependably", "desireably",
877         "determinately", "diagnostically",
878         "differentially", "differently",
879         "directly", "discernibly",
880         "distinctly", "doubtfully", "dramatically",
881         "dynamically",
882         "economically",
883         "effecaciously", "efficiently",
884         "elegantly",
885         "emphatically", "encouragingly",
886         "endlessly", "endurably",
887         "entirely", "epistomologically",
888         "functionally", "immediately",
889         "equably", "equally", "equitably", "erroneously",
890         "esoterically", "eternally", "evenly", "eventfully",
891         "eventually", "evidently",
892         "exceedingly", "exactly", "excellently",
893         "exceptionally", "excessively", "exclusively",
894         "experimentally",
895         "explicitly", "extremely",
896         "factually", "faithfully",
897         "faultlessly", "feasibly",
898         "finitely", "firmly", "forcefully",
899         "formally", "formerly", "frankly", "freely",
900         "frugally", "fully", "generally",
901         "globally", "gradually",
902         "harmlessly",
903         "helpfully",
904         "highly", "homogeneously",
905         "hopefully",
906         "ideally", "identically", "ideologically",
907         "idiomatically", "idiosyncratically", "idly",
908         "imaginably", "immaterially", "immensely",
909         "impartially", "imperceptably", "imperfectly", "importantly",
910         "improperly", "imprudently", "inaccurately", "inappropriately",
911         "accurately",
912         "inclusively", "incompletely", "incorrectly",
913         "increasingly", "independently",
914         "indirectly", "ineffectively", "ineffectually", "inefficiently",
915         "infallibly", "instantaneously", "instantly",
916         "insufficiently", "internally", "likely", "only",
917         "invaluably", "inversely", "irrelevantly", "irrespectively",
918         "largely", "lastly", "legitimately", "literally",
919         "locally", "loosely", "manageably", "markedly",
920         "memorably", "mildly", "mindfully", "moderately",
921         "momentarily", "naturally", "needfully", "needlessly",
922         "nominally", "normally", "objectively", "occasionally",
923         "temporarily",
924         "officially", "oppositely", "ordinarily", "ostensibly",
925         "partially", "permissibly",
926         "personally", "pertinently",
927         "physically", "plainly", "plainly",
928         "pleasingly", "politically",
929         "potentially", "predictively",
930         "predominantly", "prematurely", "preparedly", "presently",
931         "previously", "primarily",
932         "primely", "principally", "problematically",
933         "productively", "promptly", "proportionately",
934         "provably", "purely", "quickly", "radically", "randomly", "recently",
935         "repeatedly", "secondarily", "separately",
936         "usually", "specifically",
937         "redundantly", "regardlessly", "reliably",
938         "remarkably", "remotely", "respectively",
939         "probably",
940         "robustly", "seemingly",
941         "sensibly", "singularly", "steadily",
942         "strikingly", "substantially", "successfully",
943         "supposedly", "systematically", "understandably",
944         "necessarily", "unfortunately",
945         "unnecessarily", "unmistakably", "usefully", "weakly"};
946         
947
948 adverb(void) {
949         static char    *wordy[] = {"very ", "extremely ", "generally ",
950                 "reasonably ", "fundamentally ", "essentially ", "particularly ",
951                 "very ",
952                 "very ", "very ",
953                 "very ", "very ",
954                 "very ", "very ",
955                 "very ", "very ",
956                 "very ", "very ",
957                 "very ", "very ",
958                 "very ", "very ",
959                 "entirely ",
960                 "rather ", "fairly ", "relatively ", "comparatively ",
961                 "moderately ",
962                 "totally ", "very ", "quite "};
963         static char    *suff[] = {"wardly", "ably", "wisely",
964                 "ably", "ily", "ly", "ly", "ly"};
965
966         X               adverbv = getxx();
967         int             i = 0;
968
969         adverbv->type = "-adverb";
970         if (prob(0.150)) {
971                 adverbv->list.s[i] = prob(.5) ? "simply" : "easily";
972                 return adverbv;
973         }
974         if (prob(0.4))
975                 adverbv->list.s[i++] = CHOOSE(wordy);
976         if (prob(makeup))
977                 adverbv->list.s[i] = CHOOSE(advlist);
978         else {
979                 adverbv->list.s[i++] = prefix();
980                 adverbv->list.s[i++] = root();
981                 adverbv->list.s[i] = CHOOSE(suff);
982         }
983         return adverbv;
984 }
985
986
987 adjective(void) {
988         static char    *suff[] = {"ive", "ful", "ous", "some", "oid",
989         "ine", "esque", "en", "an",
990         "ile", "able", "ible", "istic", "ic",
991         "an", "ian", "ish", "ite", "al", "less"};
992         X               adjv = getxx();
993         int             i = 0;
994
995         adjv->type = "-adjective";
996         if (prob(0.2)) {
997                 adjv->list.s[i++] = "not ";
998                 adjv->list.s[i++] = "un";
999         }
1000         if (prob(makeup)) {
1001                 adjv->list.s[i] = CHOOSE(adjlist);
1002                 return adjv;
1003         }
1004         adjv->list.s[i++] = prefix();
1005         adjv->list.s[i++] = root();
1006         adjv->list.s[i] = CHOOSE(suff);
1007         return adjv;
1008 }
1009
1010
1011 adjph(env)
1012         E               env;
1013 {
1014         X               adjv = getxx();
1015         EE              nenv;
1016         static EE       empty;
1017         int             i = 0;
1018         adjv->type = "adjph";
1019         if (prob(0.25)) {
1020                 nenv = *env;
1021                 nenv.tense = 0;
1022                 adjv->list.x[i++] = rel();
1023                 adjv->list.x[i++] = aux(&nenv);
1024                 adjv->list.x[i] = vp(&nenv);
1025                 return adjv;
1026         }
1027         nenv = empty;
1028         adjv->list.x[i++] = prep();
1029         adjv->list.x[i] = np(&nenv);
1030         return adjv;
1031 }
1032
1033 static char    *preplist[] = {"across", "by", "in", "of",
1034         "near", "under", "over",
1035         "in back of", "below", "behind", "of", "of", "of", "of",
1036         "centered around", "centered about",
1037         "in close proximity to", "following after",
1038         "in between", "in conflict with", "in conjunction with",
1039         "in the area of", "in the neighborhood of", "in the proximity of",
1040         "in the field of", "for the purpose of",
1041         "giving rise to", "based upon", "being caused by",
1042         "of", "of", "of", "of",
1043         "being effectuated by", "being aggrevated by",
1044         "being used with",
1045         "being collected together with", "being combined together with",
1046         "connected up to", "exhibiting a tendency towards",
1047         "being facilitated by",
1048         "being employed with",
1049         "having a deleterious effect upon", "impacting",
1050         "being joined together with", "being merged together with",
1051         "in the vicinity of"};
1052
1053
1054 prep(void) {
1055         X               pv = getxx();
1056         pv->type = "-prep";
1057         pv->list.s[0] = CHOOSE(preplist);
1058         return pv;
1059 }
1060
1061
1062 comp(env)
1063         E               env;
1064 {
1065         X               v = getxx();
1066         EE              nenv;
1067         static EE       empty;
1068         int             i = 0;
1069         nenv = empty;
1070         v->type = "comp";
1071         if (0 && prob(0.001))
1072                 v->list.x[i++] = adjective();
1073         else if (prob(0.1))
1074                 v->list.x[i++] = advp(&nenv);
1075         else {
1076                 if (env->passive)
1077                         v->list.x[i++] = passprep();
1078                 v->list.x[i++] = np(&nenv);
1079                 env->passive = 0;
1080         }
1081         if (0 && prob(0.05))
1082                 v->list.x[i++] = adverb();
1083         USED(i);
1084         return v;
1085 }
1086
1087
1088 advp(env)
1089         E               env;
1090 {
1091         X               v = getxx();
1092         v->type = "advp";
1093         v->list.x[0] = vprep();
1094         v->list.x[1] = np(env);
1095         return v;
1096 }
1097
1098 static char    *vpreplist[] = {"to", "at", "by", "from", "with", "for"};
1099
1100
1101 vprep(void) {
1102         X               v = getxx();
1103         v->type = "-vprep";
1104         v->list.s[0] = CHOOSE(vpreplist);
1105         return v;
1106 }
1107
1108
1109 getenvq()
1110 {
1111         static EE       empty;
1112         E               v;
1113         v = (E) malloc(sizeof *v);
1114         if (v == 0) {
1115                 printf("outa room\n");
1116                 exits("room");
1117         }
1118         *v = empty;
1119         return v;
1120 }
1121
1122
1123 comma(env)
1124         E               env;
1125 {
1126         X               v = getxx();
1127         static EE       empty;
1128
1129         v->type = "-comma";
1130         v->list.s[0] = ",";
1131         *env = empty;
1132         return v;
1133 }
1134
1135 static char    *conjadvlist[] = {"we believe", "naturally", "therefore",
1136         "moreover", "obviously"};
1137
1138
1139 conjadv(void) {
1140         X               v = getxx();
1141
1142         v->type = "-conjadv";
1143         v->list.s[0] = CHOOSE(conjadvlist);
1144         return v;
1145 }
1146
1147 static char    *lconjlist[] = {"therefore", "however", "nevertheless",
1148         "consequently", "also", "in addition", "moreover",
1149         "accordingly", "essentially", "presumably", "actually",
1150         "basically", "importantly", "clearly", "obviously",
1151         "needless to say", "as already stated",
1152         "generally", "approximately", "presently",
1153         "hopefully", "usually", "in the great majority of cases",
1154         "seen in the above light", "most significantly",
1155         "when the need arises",
1156         "in a large number of cases", "after this is accomplished",
1157         "in all cases",
1158         "having been made aware concerning these matters",
1159         "as an example of this", "as a consequence of this",
1160         "as a matter of fact", "as is often the case",
1161         "as of this date", "assuming that this is the case",
1162         "at the present moment in time", "at this time",
1163         "as a consequent result of this", "as a desireable benefit of this",
1164         "if at all possible", "similarly", "in the same connection",
1165         "in large measure", "in many cases", "in rare cases",
1166         "in some cases", "in the interim", "in the last analysis",
1167         "in light of these facts", "in the majority of instances",
1168         "in the not too distant future", "in the same way as described above",
1169         "in this case", "for all intents and purposes",
1170         "to arrive at an approximation", "for this reason",
1171         "for many reasons, then",
1172         "as is often the case", "last but not least",
1173         "later on", "on a few occasions", "on this occasion",
1174         "in summary", "taking this into consideration",
1175         "with this in mind",
1176         "substantially", "ultimately"};
1177
1178
1179 lconjadv(void) {
1180
1181         X               v = getxx();
1182         v->type = "-lconjadv";
1183         v->list.s[0] = CHOOSE(lconjlist);
1184         return v;
1185 }
1186
1187
1188 conjsub(void) {
1189         static char    *conjsublist[] = {"although", "even though",
1190                 "despite the fact that",
1191                 "for the simple reason that",
1192                 "because", "due to the fact that", "since",
1193                 "whether or not",
1194                 "inasmuch as",
1195         "as"};
1196         X               v = getxx();
1197         v->type = "-conjsub";
1198         v->list.s[0] = CHOOSE(conjsublist);
1199         return v;
1200 }
1201
1202 static char    *lconjsublist[] = {"although", "even though",
1203         "despite the fact that",
1204         "because", "due to the fact that", "since",
1205         "if", "anytime that", "in the case that",
1206         "as a consequence of the fact that",
1207         "as regards the fact that",
1208         "as a desireable benefit of the fact that",
1209         "with reference to the fact that",
1210         "as long as",
1211         "as an important essential of the fact that",
1212         "in conjunction with the fact that",
1213         "in the light of the fact that",
1214         "if", "if", "if", "if",
1215         "leaving out of consideration the fact that",
1216         "just as",
1217         "inasmuch as", "until such time as",
1218         "as soon as", "being as", "in the same way as",
1219         "with the exception of the fact that",
1220         "notwithstanding the fact that",
1221         "on the grounds that",
1222         "on the basis of the fact that",
1223         "persuant to the fact that",
1224         "although it seems apparent that",
1225         "with regard to the fact that",
1226         "as can be seen from the fact that",
1227         "as"};
1228
1229
1230 lconjsub(void) {
1231         X               v = getxx();
1232         v->type = "-lconjsub";
1233         v->list.s[0] = CHOOSE(lconjsublist);
1234         return v;
1235 }
1236
1237 static char    *conjlist[] = {"and", "but", "yet", "and", "and"};
1238
1239
1240 conj(void) {
1241         X               v = getxx();
1242         v->type = "-conj";
1243         v->list.s[0] = CHOOSE(conjlist);
1244         return v;
1245 }
1246 static char    *nomzlist[] = {"it is easy to see that",
1247         "it is a basic fact that",
1248         "it is obvious that", "it is not unimportant that",
1249         "it is easy to overlook the fact that",
1250         "it is within the realm of possibility that",
1251         "it is apparent that",
1252         "this is indicitive of the fact that",
1253         "this is in substantial agreement with the fact that",
1254         "this demonstrates the fact that",
1255         "this leaves out of consideration the fact that",
1256         "it is of the utmost importance that",
1257         "the truth is that",
1258         "the fact is that",
1259         "it turns out that", "it will turn out to be true that",
1260         "it should be noted that",
1261         "it stands to reason that",
1262         "it would not be unreasonable to assume that",
1263         "it is interesting to note that",
1264         "this can be proved by:",
1265         "this is a trivial consequence of",
1266         "it is assumed that",
1267         "it remains to be shown that",
1268         "it is left to the reader to prove"
1269 };
1270
1271
1272 nomz(void) {
1273         X               v = getxx();
1274         v->type = "-nomz";
1275         v->list.s[0] = CHOOSE(nomzlist);
1276         return v;
1277 }
1278
1279 X
1280 equation(void) {
1281         X               v = getxx();
1282         static char eqnbuff[100], x;
1283         static char *eqnelem[] = {"int", "sum", "prod", "union", "inter"};
1284         static char *eqnfn[] = { "sin", "cos", "tan", "arc", "det",
1285                 "log", "exp", "f", "g", "sinh", "O", "J sub 0", "J sub 1",
1286                 "P sub i", "gamma", "zeta" };
1287         static char *eqnval[] = { "0", "DELTA", "GAMMA", "LAMBDA",
1288                 "OMEGA", "PHI", "PSI", "SIGMA", "THETA", "UPSILON",
1289                 "XI", "alpha", "beta", "gamma", "delta", "epsilon",
1290                 "eta", "kappa","lambda", "mu", "omega", "x", "zeta", "inf"};
1291         static char *eqnrel[] = {"=", "<=", ">=", "==", "!=", "approx"};
1292
1293         x = 'a' + (R)%26;
1294         v->type = "-eqn";
1295         sprintf(eqnbuff,"$%s from %c=%d to %s %s ( %c ) d%c %s %s$",
1296                 CHOOSE(eqnelem), x, (R)&077, CHOOSE(eqnval), CHOOSE(eqnfn),
1297                 x, x, CHOOSE(eqnrel), CHOOSE(eqnval));
1298         v->list.s[0] = eqnbuff;
1299         return v;
1300 }
1301
1302
1303 turgid(env)
1304         E               env;
1305 {
1306         X               v = getxx();
1307         int             i = 0;
1308
1309         v->type = "turgid";
1310         if (prob(T * 1.5)) {
1311                 v->list.x[i++] = lconjadv();
1312                 v->list.x[i++] = comma(env);
1313                 v->list.x[i++] = sent(env);
1314         } else if (prob(2 * T)) {
1315                 v->list.x[i++] = turgid(env);
1316                 v->list.x[i++] = comma(env);
1317                 v->list.x[i++] = conj();
1318                 v->list.x[i++] = sent(env);
1319         } else if (prob(1.5 * T)) {
1320                 v->list.x[i++] = lconjsub();
1321                 v->list.x[i++] = sent(env);
1322                 v->list.x[i++] = comma(env);
1323                 v->list.x[i++] = sent(env);
1324         } else if (prob(T * .5)) {
1325                 v->list.x[i++] = sent(env);
1326                 v->list.x[i++] = comma(env);
1327                 v->list.x[i++] = conjadv();
1328         } else if (prob(T)) {
1329                 v->list.x[i++] = turgid(env);
1330                 v->list.x[i++] = comma(env);
1331                 v->list.x[i++] = conjsub();
1332                 v->list.x[i++] = sent(env);
1333         } else if (prob(.5 * T)) {
1334                 v->list.x[i++] = nomz();
1335                 if (eqn && prob(.5)) {
1336                         v->list.x[i++] = equation();
1337                         v->list.x[i++] = comma(env);
1338                         v->list.x[i++] = conj();
1339                 }
1340                 v->list.x[i++] = sent(env);
1341         } else
1342                 v->list.x[i++] = sent(env);
1343         USED(i);
1344         return v;
1345 }
1346
1347 char *
1348 splitup(char *strlab)  {
1349         static char label[64];
1350         int j, c;
1351
1352         label[0]='"';
1353         for (j=1; j<60 &&
1354                 (c = *strlab++) != '\0'; j++)
1355                 if (c == ' ') {
1356                         label[j++]='"';
1357                         label[j++]=' ';
1358                         label[j]='"';
1359                 }
1360                 else
1361                         label[j] = c;
1362         label[j++] = '"'; label[j] = '\0';
1363         return(label);
1364 }
1365
1366 void
1367 abo(void) {
1368         fprintf(stderr, "usage: festoon [-pet] [-sSEED] [SENTENCES] [%%-invented-nouns]\n");
1369         exits("usage");
1370 }
1371
1372 void
1373 caps(void) {
1374         int             i;
1375         for (i = 1; i < io; i++)
1376                 if (buff[i - 1] == ' ' && buff[i] <= 'z' && buff[i] >= 'a')
1377                         buff[i] += 'A' - 'a';
1378 }
1379
1380 void
1381 main(int argc, char *argv[]) {
1382         static char    *furniture[] = {"WASTEBASKET", "ASHTRAY", "TABLE",
1383         "DESK DRAWER", "COAT LOCKER", "BOOKSHELF"};
1384
1385         static char    *ccto[] = {
1386                 "J. N. Akkerhuis",
1387                 "J. J. Argosy",
1388                 "M. D. Banal",
1389                 "H. V. Bandersnatch",
1390                 "L. Bimmler",
1391                 "F. W. Blivet",
1392                 "Z. Brazen",
1393                 "M. Bushido",
1394                 "J. D. Carbuncle",
1395                 "N. Crab",
1396                 "R. H. deTruckle",
1397                 "R. L. Drechsler",
1398                 "C. B. Dudgeon",
1399                 "R. T. Dun",
1400                 "G. R. Emlin",
1401                 "W. G. Fallow",
1402                 "R. S. Flummox",
1403                 "R. N. Fribble",
1404                 "C. R. Glitch",
1405                 "R. H. Hardin",
1406                 "S. A. Hobble",
1407                 "B. W. Kernighan",
1408                 "D. B. Knudsen",
1409                 "C. L'Hommedieu",
1410                 "R. S. Limn",
1411                 "S. T. Livid",
1412                 "Mrs. B. R. Mauve",
1413                 "C. Mee",
1414                 "N-P. Nelson",
1415                 "C. H. Russet",
1416                 "M. Shayegan",
1417                 "M. H. Simper",
1418                 "B. R. Sorrel",
1419                 "G. Swale",
1420                 "R. R. Swarthy",
1421                 "P. Terra-Cotta",
1422                 "U. G. Winnow"};
1423
1424         static char     *picelem[] = { "box", "ellipse", "box", "box"};
1425         static char     *piccon[] = { "arrow", "line", "line <-", "line <->",
1426         "spline", "spline <-", "spline <->"};
1427         static char     *picdir[] = { "right", "down right", "down",
1428         "left", "up left", "left", "down", "down right", NULL};
1429         E               env;
1430         X               tree;
1431         int             i, j = 0, k = 0;
1432         int             lim = 0;
1433         long            t = 0;
1434         char            c, **str;
1435         int             junk, junk2;
1436
1437         for (i = 1, ++argv; i < argc; i++, argv++)
1438                 if (*argv[0] == '-')    /* -pet -snnn */
1439                         while (c = *++argv[0])
1440                                 switch (c) {
1441                                 case 'z':
1442                                         flag = 1;
1443                                         continue;
1444                                 case 'p':
1445                                         pic = 1;
1446                                         continue;
1447                                 case 't':
1448                                         tbl = 1;
1449                                         continue;
1450                                 case 'e':
1451                                         eqn = 1;
1452                                         continue;
1453                                 case 's':
1454                                 t = atoi(argv[0]+1); argv[0][1] = '\0';
1455                                         continue;
1456                                 default:
1457                                         abo();  /* illegal option */
1458                                 }
1459                 else if (lim == 0)
1460                         lim = atoi(argv[0]);
1461                 else
1462                         makeup = 1.0 - (float) atoi(argv[0]) / 100.0;
1463         USED(i);
1464         if (t == 0)
1465                 time(&t);
1466         if (makeup < 0. || makeup > 1.0)
1467                 makeup = 1.0;
1468         if (lim <= 0)
1469                 lim = 25;
1470         srand((int) t);
1471
1472         printf(".TL\n");
1473         env = getenvq();
1474         tree = np(env);
1475         io = 0;
1476         pr(tree);
1477         buff[io] = 0;
1478         caps();
1479         printf("%s\n", buff);
1480         printf(".AU \"C. C. Festoon\" CCF Headquarters %d\n", t);
1481         if (eqn)
1482                 printf(".EQ\ndelim $$\n.EN\n");
1483         printf(".AS\n");
1484         free(env);
1485         do {
1486                 env = getenvq();
1487                 tree = turgid(env);
1488                 io = 0;
1489                 pr(tree);
1490                 buff[io] = 0;
1491                 printf("%s.\n", buff);
1492                 free(env);
1493         } while (prob(0.75));
1494         printf(".AE\n");
1495         printf(".MT \"MEMORANDUM FOR %s\"\n.hy 1\n",
1496                CHOOSE(furniture));
1497         while (i++ < lim) {
1498                 if (i % 23 == 0) {      /* Time for a section header */
1499                         env = getenvq();
1500                         tree = np(env);
1501                         io = 0;
1502                         printf(".H 1 \"");
1503                         pr(tree);
1504                         buff[io] = 0;
1505                         caps();
1506                         printf("%s\"\n", buff);
1507                         free(env);
1508                 }
1509                 if (i % 27 == 0 && pic) {       /* Time for a picture */
1510                         printf(".DS CB\n.ps -1\n.PS\n");
1511                         str = &(CHOOSE(picdir));
1512                         if (*str == NULL) str = &picdir[0];
1513                         junk2 = (R&07) + 3;
1514                         for(junk = 1; junk < junk2; junk++) {
1515                                 printf("%s; ", *str);
1516                                 if (str == &picdir[0]) {
1517                                         pic = 2; printf("A: ");
1518                                 }
1519                                 printf("%s %s ht %3.1f wid %3.1f\n",
1520                                 CHOOSE(picelem), splitup(CHOOSE(nounlist)),
1521                                 0.4+0.5/junk2, 0.8+0.6/junk2);
1522                                 printf("%s %s %3.1f ",
1523                                 CHOOSE(piccon), *str, 0.2+.3/junk2);
1524                                 if (*++str == NULL) str = &picdir[0];
1525                                 printf("then %s %3.1f %s\n",
1526                                 *str, 0.3+.2/junk2,
1527                                 splitup(CHOOSE(adjlist)));
1528                         }
1529                         printf("circle rad .3 \"process\" \"completion\"\n");
1530                         if (pic == 2) {
1531                                 pic =1;
1532                                 printf("line <- dashed up .25 from A.n\n");
1533                                 printf("circle rad .3 \"process\" \"start\"\n");
1534                         }
1535                         printf(".PE\n.ps +1\n.DE\n");
1536                         printf(".ce\n\\fBFigure %d\\fP\n", i/27);
1537                 }
1538                 if (i % 41 == 0 && tbl) {       /* Time for a table */
1539                         printf(".TS\n");
1540                         printf("box, center;\nc\ts\ts\n");
1541                         printf("n | l | lw(%3.1fi).\n", 2.0+(41.0+(t&07))/i);
1542                         printf("Action Plan %d\n=\n", i);
1543                         printf("Item\tWho\tAction\n");
1544                         for (junk = 1; junk < (i&17)+4; junk++) {
1545                                 printf("_\n%d\t", t/i+junk);
1546                                 printf("%s\tT{\n", CHOOSE(ccto));
1547                                 env = getenvq();
1548                                 io = 0;
1549                                 tree = sent(env);
1550                                 pr(tree);
1551                                 buff[io] = 0;
1552                                 printf("%s.\nT}\n", buff);
1553                                 free(env);
1554                         }
1555                         printf(".TE\n");
1556                         printf(".ce\n\\fBTable %d\\fP\n", i/41);
1557                 }
1558                 env = getenvq();
1559                 tree = turgid(env);
1560                 io = 0;
1561                 pr(tree);
1562                 buff[io] = 0;
1563                 if (++k % 13 == 0 && prob(0.35)) {      /* Bullet list */
1564                         printf("%s:\n", buff);
1565                         printf(".BL\n");
1566                         do {
1567                                 printf(".LI\n");
1568                                 free(env);
1569                                 env = getenvq();
1570                                 io = 0;
1571                                 tree = sent(env);
1572                                 pr(tree);
1573                                 buff[io] = 0;
1574                                 printf("%s.\n", buff);
1575                         } while (prob(.83));
1576                         printf(".LE\n");
1577                         printf(".P\n");
1578                 } else {
1579                         if (k % 11 == 0 && prob(.21)) { /* do as footnote */
1580                                 printf("%s\\*F.\n", buff);
1581                                 free(env);
1582                                 env = getenvq();
1583                                 io = 0;
1584                                 tree = sent(env);
1585                                 pr(tree);
1586                                 buff[io] = 0;
1587                                 printf(".FS\n%s.\n.FE\n", buff);
1588                         }
1589                         else printf("%s.\n", buff);     /* normal flush */
1590                 }
1591                 if (++j > 2 && prob(0.4))
1592                         printf(".P\n"), j = 0;
1593                 free(env);
1594         }
1595         USED(i);
1596         printf(".SG\n");
1597         printf(".NS 0\n");
1598         for (j = 0; j == 0;) {
1599                 for (i = 0; i < sizeof ccto / sizeof *ccto; i++) {
1600                         if (prob(.10))
1601                                 j = 1, printf("%s\n", ccto[i]);
1602                 }
1603         }
1604         printf(".NE\n");
1605         USED(i);
1606         exits("");
1607 }
1608
1609 void
1610 pr(tree)
1611         X               tree;
1612 {
1613         int             i;
1614         if (flag ) {
1615                 out("<");
1616                 out(tree->type);
1617                 out(">");
1618         }
1619         if (tree->type[0] == '-') {
1620                 out(" ");
1621                 for (i = 0; tree->list.s[i]; i++) {
1622                         out(tree->list.s[i]);
1623                 }
1624         } else
1625                 for (i = 0; tree->list.x[i]; i++) {
1626                         pr(tree->list.x[i]);
1627                 }
1628         free(tree);
1629         USED(i);
1630         return;
1631 }
1632
1633 void
1634 out(s)
1635         char           *s;
1636 {
1637         if (io == 0 && *s == ' ')
1638                 return;
1639         if (io == 0) {
1640                 for (; s[io]; io++)
1641                         buff[io] = s[io];
1642                 buff[0] += 'A' - 'a';
1643                 return;
1644         }
1645         if ((buff[io - 1] == ' ' || buff[io - 1] == '\n' ) && *s == ' ')
1646                 return;
1647         if (buff[io - 1] == ' ' && *s == ',') {
1648                 buff[io - 1] = ',';
1649                 buff[io++] = '\n';
1650                 return;
1651         }
1652         if (buff[io - 1] == 'y' && *s == 'i' && s[1] == 'e')
1653                 io--;
1654         else if (*s == buff[io - 1] && *s != 's' && *s != 'n')
1655                 io--;
1656         else if (*s == 'e' && buff[io - 1] == 'a')
1657                 io--;
1658         for (; *s;)
1659                 buff[io++] = *s++;
1660         return;
1661 }