Remove O_EXCL from flags used to create files to be copied out of a
[pintos-anon] / src / examples / insult.c
1 /* Insult.c
2
3    This is a version of the famous CS 107 random sentence
4    generator.  I wrote a program that reads a grammar definition
5    file and writes a C file containing that grammar as hard code
6    static C strings.  Thus the majority of the code below in
7    machine generated and totally unreadable.  The arrays created
8    are specially designed to make generating the sentences as
9    easy as possible.
10
11    Originally by Greg Hutchins, March 1998.
12    Modified by Ben Pfaff for Pintos, Sept 2004. */
13 char *start[] =
14   { "You", "1", "5", ".", "May", "13", ".", "With", "the", "19", "of", "18",
15 ",", "may", "13", "."
16 };
17 char startLoc[] = { 3, 0, 4, 7, 16 };
18 char *adj[] = { "3", "4", "2", ",", "1" };
19 char adjLoc[] = { 3, 0, 1, 2, 5 };
20 char *adj3[] = { "3", "4" };
21 char adj3Loc[] = { 2, 0, 1, 2 };
22 char *adj1[] =
23   { "lame", "dried", "up", "par-broiled", "bloated", "half-baked", "spiteful",
24 "egotistical", "ungrateful", "stupid", "moronic", "fat", "ugly", "puny", "pitiful",
25 "insignificant", "blithering", "repulsive", "worthless", "blundering", "retarded",
26 "useless", "obnoxious", "low-budget", "assinine", "neurotic", "subhuman", "crochety",
27 "indescribable", "contemptible", "unspeakable", "sick", "lazy", "good-for-nothing",
28 "slutty", "mentally-deficient", "creepy", "sloppy", "dismal", "pompous", "pathetic",
29 "friendless", "revolting", "slovenly", "cantankerous", "uncultured", "insufferable",
30 "gross", "unkempt", "defective", "crumby"
31 };
32 char adj1Loc[] =
33   { 50, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
34 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
35 43, 44, 45, 46, 47, 48, 49, 50, 51 };
36 char *adj2[] =
37   { "putrefied", "festering", "funky", "moldy", "leprous", "curdled", "fetid",
38 "slimy", "crusty", "sweaty", "damp", "deranged", "smelly", "stenchy", "malignant",
39 "noxious", "grimy", "reeky", "nasty", "mutilated", "sloppy", "gruesome", "grisly",
40 "sloshy", "wormy", "mealy", "spoiled", "contaminated", "rancid", "musty",
41 "fly-covered", "moth-eaten", "decaying", "decomposed", "freeze-dried", "defective",
42 "petrified", "rotting", "scabrous", "hirsute"
43 };
44 char adj2Loc[] =
45   { 40, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
46 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };
47 char *name[] =
48   { "10", ",", "bad", "excuse", "for", "6", ",", "6", "for", "brains", ",",
49 "4", "11", "8", "for", "brains", "offspring", "of", "a", "motherless", "10", "7", "6",
50 "7", "4", "11", "8"
51 };
52 char nameLoc[] = { 7, 0, 1, 6, 10, 16, 21, 23, 27 };
53 char *stuff[] =
54   { "shit", "toe", "jam", "filth", "puss", "earwax", "leaf", "clippings",
55 "bat", "guano", "mucus", "fungus", "mung", "refuse", "earwax", "spittoon", "spittle",
56 "phlegm"
57 };
58 char stuffLoc[] = { 14, 0, 1, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14, 15, 17, 18 };
59 char *noun_and_prep[] =
60   { "bit", "of", "piece", "of", "vat", "of", "lump", "of", "crock", "of",
61 "ball", "of", "tub", "of", "load", "of", "bucket", "of", "mound", "of", "glob", "of", "bag",
62 "of", "heap", "of", "mountain", "of", "load", "of", "barrel", "of", "sack", "of", "blob", "of",
63 "pile", "of", "truckload", "of", "vat", "of"
64 };
65 char noun_and_prepLoc[] =
66   { 21, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
67 38, 40, 42 };
68 char *organics[] =
69   { "droppings", "mung", "zits", "puckies", "tumors", "cysts", "tumors",
70 "livers", "froth", "parts", "scabs", "guts", "entrails", "blubber", "carcuses", "gizards",
71 "9"
72 };
73 char organicsLoc[] =
74   { 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
75 char *body_parts[] =
76   { "kidneys", "genitals", "buttocks", "earlobes", "innards", "feet"
77 };
78 char body_partsLoc[] = { 6, 0, 1, 2, 3, 4, 5, 6 };
79 char *noun[] =
80   { "pop", "tart", "warthog", "twinkie", "barnacle", "fondue", "pot",
81 "cretin", "fuckwad", "moron", "ass", "neanderthal", "nincompoop", "simpleton", "11"
82 };
83 char nounLoc[] = { 13, 0, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
84 char *animal[] =
85   { "donkey", "llama", "dingo", "lizard", "gekko", "lemur", "moose", "camel",
86 "goat", "eel"
87 };
88 char animalLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
89 char *good_verb[] =
90   { "love", "cuddle", "fondle", "adore", "smooch", "hug", "caress", "worship",
91 "look", "at", "touch"
92 };
93 char good_verbLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11 };
94 char *curse[] =
95   { "14", "20", "23", "14", "17", "20", "23", "14", "find", "your", "9",
96 "suddenly", "delectable", "14", "and", "14", "seek", "a", "battleground", "23"
97 };
98 char curseLoc[] = { 4, 0, 3, 7, 13, 20 };
99 char *afflictors[] =
100   { "15", "21", "15", "21", "15", "21", "15", "21", "a", "22", "Rush",
101 "Limbaugh", "the", "hosts", "of", "Hades"
102 };
103 char afflictorsLoc[] = { 6, 0, 2, 4, 6, 8, 12, 16 };
104 char *quantity[] =
105   { "a", "4", "hoard", "of", "a", "4", "pack", "of", "a", "truckload", "of",
106 "a", "swarm", "of", "many", "an", "army", "of", "a", "4", "heard", "of", "a", "4",
107 "platoon", "of", "a", "4", "and", "4", "group", "of", "16"
108 };
109 char quantityLoc[] = { 10, 0, 4, 8, 11, 14, 15, 18, 22, 26, 32, 33 };
110 char *numbers[] =
111   { "a", "thousand", "three", "million", "ninty-nine", "nine-hundred,",
112 "ninty-nine", "forty-two", "a", "gazillion", "sixty-eight", "times", "thirty-three"
113 };
114 char numbersLoc[] = { 7, 0, 2, 4, 5, 7, 8, 10, 13 };
115 char *adv[] =
116   { "viciously", "manicly", "merrily", "happily", ",", "with", "the", "19",
117 "of", "18", ",", "gleefully", ",", "with", "much", "ritualistic", "celebration", ",",
118 "franticly"
119 };
120 char advLoc[] = { 8, 0, 1, 2, 3, 4, 11, 12, 18, 19 };
121 char *metaphor[] =
122   { "an", "irate", "manticore", "Thor's", "belch", "Alah's", "fist", "16",
123 "titans", "a", "particularly", "vicious", "she-bear", "in", "the", "midst", "of", "her",
124 "menstrual", "cycle", "a", "pissed-off", "Jabberwock"
125 };
126 char metaphorLoc[] = { 6, 0, 3, 5, 7, 9, 20, 23 };
127 char *force[] = { "force", "fury", "power", "rage" };
128 char forceLoc[] = { 4, 0, 1, 2, 3, 4 };
129 char *bad_action[] =
130   { "spit", "shimmy", "slobber", "find", "refuge", "find", "shelter", "dance",
131 "retch", "vomit", "defecate", "erect", "a", "strip", "mall", "build", "a", "26", "have", "a",
132 "religious", "experience", "discharge", "bodily", "waste", "fart", "dance", "drool",
133 "lambada", "spill", "16", "rusty", "tacks", "bite", "you", "sneeze", "sing", "16",
134 "campfire", "songs", "smite", "you", "16", "times", "construct", "a", "new", "home", "throw",
135 "a", "party", "procreate"
136 };
137 char bad_actionLoc[] =
138   { 25, 0, 1, 2, 3, 5, 7, 8, 9, 10, 11, 15, 18, 22, 25, 26, 27, 28, 29, 33,
139 35, 36, 40, 44, 48, 51, 52 };
140 char *beasties[] =
141   { "yaks", "22", "maggots", "22", "cockroaches", "stinging", "scorpions",
142 "fleas", "22", "weasels", "22", "gnats", "South", "American", "killer", "bees", "spiders",
143 "4", "monkeys", "22", "wiener-dogs", "22", "rats", "22", "wolverines", "4", ",", "22",
144 "pit-fiends"
145 };
146 char beastiesLoc[] =
147   { 14, 0, 1, 3, 5, 7, 8, 10, 12, 16, 17, 19, 21, 23, 25, 29 };
148 char *condition[] =
149   { "frothing", "manic", "crazed", "plague-ridden", "disease-carrying",
150 "biting", "rabid", "blood-thirsty", "ravaging", "slavering"
151 };
152 char conditionLoc[] = { 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
153 char *place[] =
154   { "in", "24", "25", "upon", "your", "mother's", "grave", "on", "24", "best",
155 "rug", "in", "the", "26", "you", "call", "home", "upon", "your", "heinie"
156 };
157 char placeLoc[] = { 5, 0, 3, 7, 11, 17, 20 };
158 char *relation[] =
159   { "your", "your", "your", "your", "father's", "your", "mother's", "your",
160 "grandma's"
161 };
162 char relationLoc[] = { 6, 0, 1, 2, 3, 5, 7, 9 };
163 char *in_something[] =
164   { "entrails", "anal", "cavity", "shoes", "house", "pantry", "general",
165 "direction", "pants", "bed"
166 };
167 char in_somethingLoc[] = { 8, 0, 1, 3, 4, 5, 6, 8, 9, 10 };
168 char *bad_place[] =
169   { "rat", "hole", "sewer", "toxic", "dump", "oil", "refinery", "landfill",
170 "porto-pottie"
171 };
172 char bad_placeLoc[] = { 6, 0, 2, 3, 5, 7, 8, 9 };
173 char **daGrammar[27];
174 char *daGLoc[27];
175
176 static void
177 init_grammar (void)
178 {
179   daGrammar[0] = start;
180   daGLoc[0] = startLoc;
181   daGrammar[1] = adj;
182   daGLoc[1] = adjLoc;
183   daGrammar[2] = adj3;
184   daGLoc[2] = adj3Loc;
185   daGrammar[3] = adj1;
186   daGLoc[3] = adj1Loc;
187   daGrammar[4] = adj2;
188   daGLoc[4] = adj2Loc;
189   daGrammar[5] = name;
190   daGLoc[5] = nameLoc;
191   daGrammar[6] = stuff;
192   daGLoc[6] = stuffLoc;
193   daGrammar[7] = noun_and_prep;
194   daGLoc[7] = noun_and_prepLoc;
195   daGrammar[8] = organics;
196   daGLoc[8] = organicsLoc;
197   daGrammar[9] = body_parts;
198   daGLoc[9] = body_partsLoc;
199   daGrammar[10] = noun;
200   daGLoc[10] = nounLoc;
201   daGrammar[11] = animal;
202   daGLoc[11] = animalLoc;
203   daGrammar[12] = good_verb;
204   daGLoc[12] = good_verbLoc;
205   daGrammar[13] = curse;
206   daGLoc[13] = curseLoc;
207   daGrammar[14] = afflictors;
208   daGLoc[14] = afflictorsLoc;
209   daGrammar[15] = quantity;
210   daGLoc[15] = quantityLoc;
211   daGrammar[16] = numbers;
212   daGLoc[16] = numbersLoc;
213   daGrammar[17] = adv;
214   daGLoc[17] = advLoc;
215   daGrammar[18] = metaphor;
216   daGLoc[18] = metaphorLoc;
217   daGrammar[19] = force;
218   daGLoc[19] = forceLoc;
219   daGrammar[20] = bad_action;
220   daGLoc[20] = bad_actionLoc;
221   daGrammar[21] = beasties;
222   daGLoc[21] = beastiesLoc;
223   daGrammar[22] = condition;
224   daGLoc[22] = conditionLoc;
225   daGrammar[23] = place;
226   daGLoc[23] = placeLoc;
227   daGrammar[24] = relation;
228   daGLoc[24] = relationLoc;
229   daGrammar[25] = in_something;
230   daGLoc[25] = in_somethingLoc;
231   daGrammar[26] = bad_place;
232   daGLoc[26] = bad_placeLoc;
233 }
234 \f
235 #include <ctype.h>
236 #include <debug.h>
237 #include <random.h>
238 #include <stdio.h>
239 #include <stdlib.h>
240 #include <string.h>
241 #include <syscall.h>
242
243 void expand (int num, char **grammar[], char *location[], int handle);
244
245 static void
246 usage (int ret_code, const char *message, ...) PRINTF_FORMAT (2, 3);
247
248 static void
249 usage (int ret_code, const char *message, ...)
250 {
251   va_list args;
252
253   if (message != NULL) 
254     {
255       va_start (args, message);
256       vprintf (message, args);
257       va_end (args);
258     }
259   
260   printf ("\n"
261           "Usage: insult [OPTION]...\n"
262           "Prints random insults to screen.\n\n"
263           "  -h:               this help message\n"
264           "  -s <integer>:     set the random seed (default 4951)\n"
265           "  -n <integer>:     choose number of insults (default 4)\n"
266           "  -f <file>:        redirect output to <file>\n");
267
268   exit (ret_code);
269 }
270
271 int
272 main (int argc, char *argv[])
273 {
274   int sentence_cnt, new_seed, i, file_flag, sent_flag, seed_flag;
275   int handle;
276   
277   new_seed = 4951;
278   sentence_cnt = 4;
279   file_flag = 0;
280   seed_flag = 0;
281   sent_flag = 0;
282   handle = STDOUT_FILENO;
283
284   for (i = 1; i < argc; i++)
285     {
286       if (strcmp (argv[1], "-h") == 0)
287         usage (0, NULL);
288       else if (strcmp (argv[i], "-s") == 0)
289         {
290           if (seed_flag++)
291             usage (-1, "Can't have more than one seed");
292           if (++i >= argc)
293             usage (-1, "Missing value for -s");
294           new_seed = atoi (argv[i]);
295         }
296       else if (strcmp (argv[i], "-n") == 0)
297         {
298           if (sent_flag++)
299             usage (-1, "Can't have more than one sentence option");
300           if (++i >= argc)
301             usage (-1, "Missing value for -n");
302           sentence_cnt = atoi (argv[i]);
303           if (sentence_cnt < 1)
304             usage (-1, "Must have at least one sentence");
305         }
306       else if (strcmp (argv[i], "-f") == 0)
307         {
308           if (file_flag++)
309             usage (-1, "Can't have more than one output file");
310           if (++i >= argc)
311             usage (-1, "Missing value for -f");
312
313           /* Because files have fixed length in the basic Pintos
314              file system, the 0 argument means that this option
315              will not be useful until project 4 is
316              implemented. */
317           create (argv[i], 0);
318           handle = open (argv[i]);
319           if (handle < 0)
320             {
321               printf ("%s: open failed\n", argv[i]);
322               return EXIT_FAILURE;
323             }
324         }
325       else
326         usage (-1, "Unrecognized flag");
327     }
328
329   init_grammar ();
330
331   random_init (new_seed);
332   hprintf (handle, "\n");
333
334   for (i = 0; i < sentence_cnt; i++)
335     {
336       hprintf (handle, "\n");
337       expand (0, daGrammar, daGLoc, handle);
338       hprintf (handle, "\n\n");
339     }
340   
341   if (file_flag)
342     close (handle);
343
344   return EXIT_SUCCESS;
345 }
346
347 void
348 expand (int num, char **grammar[], char *location[], int handle)
349 {
350   char *word;
351   int i, which, listStart, listEnd;
352
353   which = random_ulong () % location[num][0] + 1;
354   listStart = location[num][which];
355   listEnd = location[num][which + 1];
356   for (i = listStart; i < listEnd; i++)
357     {
358       word = grammar[num][i];
359       if (!isdigit (*word))
360         {
361           if (!ispunct (*word))
362             hprintf (handle, " ");
363           hprintf (handle, "%s", word);
364         }
365       else
366         expand (atoi (word), grammar, location, handle);
367     }
368
369 }