5e64c801f05246e7cc45c36923258d6669c346ee
[rodin/chimara.git] / interpreters / nitfol / startwin.c
1 #line 488 "opt2glkc.pl"
2 #include "nitfol.h"
3 #include "WinGlk.h"
4
5 #line 671 "opt2glkc.pl"
6 strid_t intd_filehandle_open(strid_t savefile, glui32 operating_id,
7                              glui32 contents_id, glui32 interp_id,
8                              glui32 length)
9 {
10   return 0;
11 }
12
13 void intd_filehandle_make(strid_t savefile)
14 {
15   ;
16 }
17
18 glui32 intd_get_size(void)
19 {
20   return 0;
21 }
22 #line 694 "opt2glkc.pl"
23 strid_t startup_findfile(void)
24 {
25   ;
26 }
27 #line 705 "opt2glkc.pl"
28 strid_t startup_open(const char *name)
29 {
30   return n_file_name(fileusage_Data | fileusage_BinaryMode,
31                      filemode_Read, name);
32 }
33 #line 717 "opt2glkc.pl"
34 static strid_t startup_wopen(const char *name)
35 {
36   return n_file_name(fileusage_Data | fileusage_BinaryMode,
37                      filemode_Write, name);
38 }
39 static void code_ignore(int flag)
40 #line 6 "nitfol.opt"
41 { ignore_errors = flag; }
42
43 static void code_fullname(int flag)
44 #line 9 "nitfol.opt"
45 { fullname = flag; }
46
47 static void code_command(strid_t stream)
48 #line 12 "nitfol.opt"
49 { if(stream) input_stream1 = stream; }
50
51 static void code_pirate(int flag)
52 #line 15 "nitfol.opt"
53 { aye_matey = flag; }
54
55 static void code_quiet(int flag)
56 #line 18 "nitfol.opt"
57 { quiet = flag; }
58
59 static void code_spell(int flag)
60 #line 21 "nitfol.opt"
61 { do_spell_correct = flag; }
62
63 static void code_expand(int flag)
64 #line 24 "nitfol.opt"
65 { do_expand = flag; }
66
67 static void code_symbols(strid_t stream)
68 #line 27 "nitfol.opt"
69 { if(stream) init_infix(stream); }
70
71 static void code_tandy(int flag)
72 #line 30 "nitfol.opt"
73 { do_tandy = flag; }
74
75 static void code_transcript(strid_t stream)
76 #line 33 "nitfol.opt"
77 { if(stream) set_transcript(stream); }
78
79 static void code_debug(int flag)
80 #line 36 "nitfol.opt"
81 { enter_debugger = flag; do_check_watches = flag; }
82
83 static void code_prompt(const char *string)
84 #line 39 "nitfol.opt"
85 { n_free(db_prompt); db_prompt = n_strdup(string); }
86
87 static void code_path(const char *string)
88 #line 42 "nitfol.opt"
89 { n_free(search_path); search_path = n_strdup(string); }
90
91 static void code_autoundo(int flag)
92 #line 45 "nitfol.opt"
93 { auto_save_undo = flag; }
94
95 static void code_stacklimit(int number)
96 #line 52 "nitfol.opt"
97 { stacklimit = number; }
98
99 static void code_alias(const char *string)
100 #line 55 "nitfol.opt"
101 { if(string) parse_new_alias(string, FALSE); }
102
103 static void code_ralias(const char *string)
104 #line 58 "nitfol.opt"
105 { if(string) parse_new_alias(string, TRUE); }
106
107 static void code_unalias(const char *string)
108 #line 61 "nitfol.opt"
109 { if(string) remove_alias(string); }
110
111 static void code_random(int number)
112 #line 64 "nitfol.opt"
113 { faked_random_seed = number; }
114
115 static void code_mapsym(const char *string)
116 #line 67 "nitfol.opt"
117 { n_free(roomsymbol); roomsymbol = n_strdup(string); }
118
119 static void code_mapsize(int number)
120 #line 70 "nitfol.opt"
121 { automap_size = number; }
122
123 static void code_maploc(const char *string)
124 #line 73 "nitfol.opt"
125 { switch(glk_char_to_lower(*string)) { case 'a': case 't': case 'u': automap_split = winmethod_Above; break; case 'b': case 'd': automap_split = winmethod_Below; break; case 'l': automap_split = winmethod_Left; break; case 'r': automap_split = winmethod_Right; } }
126
127 static void code_terpnum(int number)
128 #line 76 "nitfol.opt"
129 { interp_num = number; }
130
131 static void code_terpver(const char *string)
132 #line 79 "nitfol.opt"
133 { if(string) { if(n_strlen(string) == 1) interp_ver = *string; else interp_ver = n_strtol(string, NULL, 10); } }
134
135 #line 760 "opt2glkc.pl"
136 typedef enum { option_flag, option_file, option_wfile, option_number, option_string } option_type;
137 typedef struct { const char *longname; char shortname; const char *description; option_type type; void (*int_func)(int); int defint; void (*str_func)(strid_t); strid_t defstream; void (*string_func)(const char *); const char *defstring; } option_option;
138
139 static option_option options[] = {
140   { "ignore", 'i', "Ignore Z-machine strictness errors", option_flag, code_ignore, 0, NULL, NULL, NULL, NULL },
141   { "fullname", 'f', "For running under Emacs or DDD", option_flag, code_fullname, 0, NULL, NULL, NULL, NULL },
142   { "command", 'x', "Read commands from this file", option_file, NULL, 0, code_command, NULL, NULL, NULL },
143   { "pirate", 'P', "Aye, matey", option_flag, code_pirate, 0, NULL, NULL, NULL, NULL },
144   { "quiet", 'q', "Do not print introductory messages", option_flag, code_quiet, 1, NULL, NULL, NULL, NULL },
145   { "spell", '-', "Perform spelling correction", option_flag, code_spell, 1, NULL, NULL, NULL, NULL },
146   { "expand", '-', "Expand one letter abbreviations", option_flag, code_expand, 1, NULL, NULL, NULL, NULL },
147   { "symbols", 's', "Specify symbol file for game", option_file, NULL, 0, code_symbols, NULL, NULL, NULL },
148   { "tandy", 't', "Censors some Infocom games", option_flag, code_tandy, 0, NULL, NULL, NULL, NULL },
149   { "transcript", 'T', "Write transcript to this file", option_wfile, NULL, 0, code_transcript, NULL, NULL, NULL },
150   { "debug", 'd', "Enter debugger immediatly", option_flag, code_debug, 0, NULL, NULL, NULL, NULL },
151   { "prompt", '-', "Specify debugging prompt", option_string, NULL, 0, NULL, NULL, code_prompt, "(nitfol) " },
152   { "path", '-', "Look for games in this directory", option_string, NULL, 0, NULL, NULL, code_path, NULL },
153   { "autoundo", '-', "Ensure '@save_undo' is called every turn", option_flag, code_autoundo, 1, NULL, NULL, NULL, NULL },
154   { "stacklimit", 'S', "Exit when the stack is this deep", option_number, code_stacklimit, 0, NULL, NULL, NULL, NULL },
155   { "alias", 'a', "Specify an alias", option_string, NULL, 0, NULL, NULL, code_alias, NULL },
156   { "ralias", '-', "Specify an recursive alias", option_string, NULL, 0, NULL, NULL, code_ralias, NULL },
157   { "unalias", '-', "Remove an alias", option_string, NULL, 0, NULL, NULL, code_unalias, NULL },
158   { "random", 'r', "Set random seed", option_number, code_random, 0, NULL, NULL, NULL, NULL },
159   { "mapsym", '-', "Specify mapping glyphs", option_string, NULL, 0, NULL, NULL, code_mapsym, "*udb@UDB+" },
160   { "mapsize", '-', "Specify map size", option_number, code_mapsize, 12, NULL, NULL, NULL, NULL },
161   { "maploc", '-', "Specify map location", option_string, NULL, 0, NULL, NULL, code_maploc, "above" },
162   { "terpnum", '-', "Specify interpreter number", option_number, code_terpnum, 2, NULL, NULL, NULL, NULL },
163   { "terpver", '-', "Specify interpreter version", option_string, NULL, 0, NULL, NULL, code_terpver, "N" }
164 };
165
166 #line 811 "opt2glkc.pl"
167 static void set_defaults(void)
168 {
169   unsigned n;
170   for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
171     if(options[n].int_func)
172       options[n].int_func(options[n].defint);
173     if(options[n].str_func)
174       options[n].str_func(options[n].defstream);
175     if(options[n].string_func)
176       options[n].string_func(options[n].defstring);
177   }
178 }
179
180 #line 910 "opt2glkc.pl"
181 static void show_help(void)
182 {
183   unsigned n;
184   printf("Usage: nitfol [OPTIONS] gamefile\n");
185   for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
186     if(options[n].shortname != '-')
187       printf(" -%c, ", options[n].shortname);
188     else
189       printf("     ");
190     printf("-%-15s %s\n", options[n].longname, options[n].description);
191   }
192 }
193
194 #line 928 "opt2glkc.pl"
195 static BOOL parse_commands(int argc, char **argv)
196 {
197   int i;
198   unsigned n;
199
200   for(i = 1; i < argc; i++) {
201     BOOL flag = TRUE;
202
203     const char *p = argv[i];
204     
205     if(p[0] == '-') {
206       BOOL found = FALSE;
207
208       while(*p == '-')
209         p++;
210       if(n_strncmp(p, "no-", 3) == 0) {
211         flag = FALSE;
212         p+=3;
213       }
214
215       if(n_strcasecmp(p, "help") == 0) {
216         show_help();
217         exit(0);
218       }
219       if(n_strcasecmp(p, "version") == 0) {
220         printf("nitfol version %d.%d\n", NITFOL_MAJOR, NITFOL_MINOR);
221         exit(0);
222       }
223       
224       for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
225         if((n_strlen(p) == 1 && *p == options[n].shortname) ||
226            n_strcmp(options[n].longname, p) == 0) {
227           found = TRUE;
228
229           switch(options[n].type) {
230           case option_flag:
231             options[n].int_func(flag);
232             break;
233
234           case option_file:
235             i++;
236             options[n].str_func(startup_open(argv[i]));
237             break;
238
239           case option_wfile:
240             i++;
241             options[n].str_func(startup_wopen(argv[i]));
242             break;
243
244           case option_number:
245             i++;
246             options[n].int_func(n_strtol(argv[i], NULL, 0));
247             break;
248
249           case option_string:
250             i++;
251             options[n].string_func(argv[i]);
252             break;
253           }
254         }
255       }
256
257       if(!found)
258         return FALSE;
259
260     } else {
261       strid_t s = startup_open(argv[i]);
262       if(!s)
263         return FALSE;
264       if(!game_use_file(s))
265         return FALSE;
266     }
267   }
268
269   return TRUE;
270 }
271
272 #line 504 "opt2glkc.pl"
273 void shift_string_left(char *str)
274 {
275   int len = strlen(str);
276   int i;
277   for(i = 0; i < len; i++)
278     str[i] = str[i+1];
279 }
280
281 int winglk_startup_code(void)
282 {
283   BOOL status;
284   char *commandline = strdup(GetCommandLine());
285   char **argv = (char **) n_malloc(sizeof(char *) * strlen(commandline));
286   int argc = 0;
287
288   int i;
289
290   while(*commandline) {
291     while(*commandline && isspace(*commandline))
292       commandline++;
293     
294     argv[argc++] =  commandline;
295     
296     while(*commandline && !isspace(*commandline)) {
297       if(*commandline == '"') {
298         shift_string_left(commandline);
299         while(*commandline && *commandline != '"')
300           commandline++;
301         shift_string_left(commandline);
302       } else {
303         commandline++;
304       }
305     }
306     
307     *commandline++ = 0;
308   }
309
310   argv[argc] = NULL;
311   
312   status = parse_commands(argc, argv);
313
314   n_free(argv);
315   n_free(commandline);
316
317   winglk_app_set_name("nitfol");
318   winglk_window_set_title("nitfol");
319   set_defaults();
320
321   return status;
322 }