1 #line 228 "opt2glkc.pl"
10 #include <sys/types.h>
15 static char *game_filename = NULL;
17 static void set_game_filename(const char *name)
19 n_free(game_filename);
22 #if defined(_GNU_SOURCE)
23 game_filename = canonicalize_file_name(name);
25 #if defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE)
26 game_filename = (char *) n_malloc(PATH_MAX);
27 if(!realpath(name, game_filename)) {
28 n_free(game_filename);
33 game_filename = (char *) n_malloc(FILENAME_MAX);
34 _fixpath(name, game_filename);
40 game_filename = n_strdup(name);
44 strid_t startup_findfile(void)
46 static DIR *dir = NULL;
47 static char *pathstart = NULL;
48 static char *path = NULL;
54 char *p = search_path;
57 pathstart = n_strdup(p);
58 if(!(path = n_strtok(pathstart, ":"))) {
78 if(!(path = n_strtok(NULL, ":"))) {
86 name = (char *) n_malloc(n_strlen(path) + n_strlen(d->d_name) + 2);
89 n_strcat(name, d->d_name);
90 stream = glkunix_stream_open_pathname(name, fileusage_Data |
91 fileusage_BinaryMode, 0);
93 set_game_filename(name);
99 strid_t intd_filehandle_open(strid_t savefile, glui32 operating_id,
100 glui32 contents_id, glui32 interp_id,
105 if(operating_id != 0x554e4958 /* 'UNIX' */)
109 if(interp_id != 0x20202020 /* ' ' */)
112 name = (char *) n_malloc(length+1);
113 glk_get_buffer_stream(savefile, name, length);
115 str = glkunix_stream_open_pathname(name, fileusage_Data |
116 fileusage_BinaryMode, 0);
118 set_game_filename(name);
123 void intd_filehandle_make(strid_t savefile)
127 w_glk_put_string_stream(savefile, "UNIX");
128 glk_put_char_stream(savefile, b00000010); /* Flags */
129 glk_put_char_stream(savefile, 0); /* Contents ID */
130 glk_put_char_stream(savefile, 0); /* Reserved */
131 glk_put_char_stream(savefile, 0); /* Reserved */
132 w_glk_put_string_stream(savefile, " "); /* Interpreter ID */
133 w_glk_put_string_stream(savefile, game_filename);
136 glui32 intd_get_size(void)
140 return n_strlen(game_filename) + 12;
143 strid_t startup_open(const char *name)
148 str = glkunix_stream_open_pathname((char *) name, fileusage_Data | fileusage_BinaryMode, 0);
150 set_game_filename(name);
151 s = strrchr(name, '\\');
152 if (!s) s = strrchr(name, '/');
153 garglk_set_story_name(s ? s + 1 : name);
155 char *path = search_path;
158 char *newname = (char *) n_malloc(strlen(path) + strlen(name) + 2);
159 path = n_strdup(path);
160 for(p = n_strtok(path, ":"); p; p = n_strtok(NULL, ":")) {
161 n_strcpy(newname, p);
162 n_strcat(newname, "/");
163 n_strcat(newname, name);
164 str = glkunix_stream_open_pathname((char *) newname, fileusage_Data |
165 fileusage_BinaryMode, 0);
167 set_game_filename(newname);
168 s = strrchr(newname, '\\');
169 if (!s) s = strrchr(newname, '/');
170 garglk_set_story_name(s ? s + 1 : newname);
179 fprintf(stderr, "Cannot open '%s'\n", name);
184 #line 717 "opt2glkc.pl"
185 static strid_t startup_wopen(const char *name)
187 return n_file_name(fileusage_Data | fileusage_BinaryMode,
188 filemode_Write, name);
190 glkunix_argumentlist_t glkunix_arguments[] = {
191 { (char *) "", glkunix_arg_ValueCanFollow, (char *) "filename file to load" },
192 { (char *) "-help", glkunix_arg_NoValue, (char *) "list command-line options" },
193 { (char *) "--help", glkunix_arg_NoValue, (char *) "list command-line options" },
194 { (char *) "-version", glkunix_arg_NoValue, (char *) "get version number" },
195 { (char *) "--version", glkunix_arg_NoValue, (char *) "get version number" },
196 { (char *) "-i", glkunix_arg_NoValue, (char *) "-i" },
197 { (char *) "-no-ignore", glkunix_arg_NoValue, (char *) "-no-ignore" },
198 { (char *) "--no-ignore", glkunix_arg_NoValue, (char *) "--no-ignore" },
199 { (char *) "-ignore", glkunix_arg_NoValue, (char *) "-ignore" },
200 { (char *) "--ignore", glkunix_arg_NoValue, (char *) "--ignore Ignore Z-machine strictness errors" },
201 { (char *) "-f", glkunix_arg_NoValue, (char *) "-f" },
202 { (char *) "-no-fullname", glkunix_arg_NoValue, (char *) "-no-fullname" },
203 { (char *) "--no-fullname", glkunix_arg_NoValue, (char *) "--no-fullname" },
204 { (char *) "-fullname", glkunix_arg_NoValue, (char *) "-fullname" },
205 { (char *) "--fullname", glkunix_arg_NoValue, (char *) "--fullname For running under Emacs or DDD" },
206 { (char *) "-x", glkunix_arg_ValueFollows, (char *) "-x" },
207 { (char *) "-command", glkunix_arg_ValueFollows, (char *) "-command" },
208 { (char *) "--command", glkunix_arg_ValueFollows, (char *) "--command Read commands from this file" },
209 { (char *) "-P", glkunix_arg_NoValue, (char *) "-P" },
210 { (char *) "-no-pirate", glkunix_arg_NoValue, (char *) "-no-pirate" },
211 { (char *) "--no-pirate", glkunix_arg_NoValue, (char *) "--no-pirate" },
212 { (char *) "-pirate", glkunix_arg_NoValue, (char *) "-pirate" },
213 { (char *) "--pirate", glkunix_arg_NoValue, (char *) "--pirate Aye, matey" },
214 { (char *) "-q", glkunix_arg_NoValue, (char *) "-q" },
215 { (char *) "-no-quiet", glkunix_arg_NoValue, (char *) "-no-quiet" },
216 { (char *) "--no-quiet", glkunix_arg_NoValue, (char *) "--no-quiet" },
217 { (char *) "-quiet", glkunix_arg_NoValue, (char *) "-quiet" },
218 { (char *) "--quiet", glkunix_arg_NoValue, (char *) "--quiet Do not print introductory messages" },
219 { (char *) "-no-spell", glkunix_arg_NoValue, (char *) "-no-spell" },
220 { (char *) "--no-spell", glkunix_arg_NoValue, (char *) "--no-spell" },
221 { (char *) "-spell", glkunix_arg_NoValue, (char *) "-spell" },
222 { (char *) "--spell", glkunix_arg_NoValue, (char *) "--spell Perform spelling correction" },
223 { (char *) "-no-expand", glkunix_arg_NoValue, (char *) "-no-expand" },
224 { (char *) "--no-expand", glkunix_arg_NoValue, (char *) "--no-expand" },
225 { (char *) "-expand", glkunix_arg_NoValue, (char *) "-expand" },
226 { (char *) "--expand", glkunix_arg_NoValue, (char *) "--expand Expand one letter abbreviations" },
227 { (char *) "-s", glkunix_arg_ValueFollows, (char *) "-s" },
228 { (char *) "-symbols", glkunix_arg_ValueFollows, (char *) "-symbols" },
229 { (char *) "--symbols", glkunix_arg_ValueFollows, (char *) "--symbols Specify symbol file for game" },
230 { (char *) "-t", glkunix_arg_NoValue, (char *) "-t" },
231 { (char *) "-no-tandy", glkunix_arg_NoValue, (char *) "-no-tandy" },
232 { (char *) "--no-tandy", glkunix_arg_NoValue, (char *) "--no-tandy" },
233 { (char *) "-tandy", glkunix_arg_NoValue, (char *) "-tandy" },
234 { (char *) "--tandy", glkunix_arg_NoValue, (char *) "--tandy Censors some Infocom games" },
235 { (char *) "-T", glkunix_arg_ValueFollows, (char *) "-T" },
236 { (char *) "-transcript", glkunix_arg_ValueFollows, (char *) "-transcript" },
237 { (char *) "--transcript", glkunix_arg_ValueFollows, (char *) "--transcript Write transcript to this file" },
238 { (char *) "-d", glkunix_arg_NoValue, (char *) "-d" },
239 { (char *) "-no-debug", glkunix_arg_NoValue, (char *) "-no-debug" },
240 { (char *) "--no-debug", glkunix_arg_NoValue, (char *) "--no-debug" },
241 { (char *) "-debug", glkunix_arg_NoValue, (char *) "-debug" },
242 { (char *) "--debug", glkunix_arg_NoValue, (char *) "--debug Enter debugger immediatly" },
243 { (char *) "-prompt", glkunix_arg_ValueFollows, (char *) "-prompt" },
244 { (char *) "--prompt", glkunix_arg_ValueFollows, (char *) "--prompt Specify debugging prompt" },
245 { (char *) "-path", glkunix_arg_ValueFollows, (char *) "-path" },
246 { (char *) "--path", glkunix_arg_ValueFollows, (char *) "--path Look for games in this directory" },
247 { (char *) "-no-autoundo", glkunix_arg_NoValue, (char *) "-no-autoundo" },
248 { (char *) "--no-autoundo", glkunix_arg_NoValue, (char *) "--no-autoundo" },
249 { (char *) "-autoundo", glkunix_arg_NoValue, (char *) "-autoundo" },
250 { (char *) "--autoundo", glkunix_arg_NoValue, (char *) "--autoundo Ensure @code{@@save_undo} is called every turn" },
251 { (char *) "-S", glkunix_arg_NumberValue, (char *) "-S" },
252 { (char *) "-stacklimit", glkunix_arg_NumberValue, (char *) "-stacklimit" },
253 { (char *) "--stacklimit", glkunix_arg_NumberValue, (char *) "--stacklimit Exit when the stack is this deep" },
254 { (char *) "-a", glkunix_arg_ValueFollows, (char *) "-a" },
255 { (char *) "-alias", glkunix_arg_ValueFollows, (char *) "-alias" },
256 { (char *) "--alias", glkunix_arg_ValueFollows, (char *) "--alias Specify an alias" },
257 { (char *) "-ralias", glkunix_arg_ValueFollows, (char *) "-ralias" },
258 { (char *) "--ralias", glkunix_arg_ValueFollows, (char *) "--ralias Specify an recursive alias" },
259 { (char *) "-unalias", glkunix_arg_ValueFollows, (char *) "-unalias" },
260 { (char *) "--unalias", glkunix_arg_ValueFollows, (char *) "--unalias Remove an alias" },
261 { (char *) "-r", glkunix_arg_NumberValue, (char *) "-r" },
262 { (char *) "-random", glkunix_arg_NumberValue, (char *) "-random" },
263 { (char *) "--random", glkunix_arg_NumberValue, (char *) "--random Set random seed" },
264 { (char *) "-mapsym", glkunix_arg_ValueFollows, (char *) "-mapsym" },
265 { (char *) "--mapsym", glkunix_arg_ValueFollows, (char *) "--mapsym Specify mapping glyphs" },
266 { (char *) "-mapsize", glkunix_arg_NumberValue, (char *) "-mapsize" },
267 { (char *) "--mapsize", glkunix_arg_NumberValue, (char *) "--mapsize Specify map size" },
268 { (char *) "-maploc", glkunix_arg_ValueFollows, (char *) "-maploc" },
269 { (char *) "--maploc", glkunix_arg_ValueFollows, (char *) "--maploc Specify map location" },
270 { (char *) "-terpnum", glkunix_arg_NumberValue, (char *) "-terpnum" },
271 { (char *) "--terpnum", glkunix_arg_NumberValue, (char *) "--terpnum Specify interpreter number" },
272 { (char *) "-terpver", glkunix_arg_ValueFollows, (char *) "-terpver" },
273 { (char *) "--terpver", glkunix_arg_ValueFollows, (char *) "--terpver Specify interpreter version" },
274 { NULL, glkunix_arg_End, NULL }
277 static void code_ignore(int flag)
279 { ignore_errors = flag; }
281 static void code_fullname(int flag)
285 static void code_command(strid_t stream)
286 #line 12 "nitfol.opt"
287 { if(stream) input_stream1 = stream; }
289 static void code_pirate(int flag)
290 #line 15 "nitfol.opt"
291 { aye_matey = flag; }
293 static void code_quiet(int flag)
294 #line 18 "nitfol.opt"
297 static void code_spell(int flag)
298 #line 21 "nitfol.opt"
299 { do_spell_correct = flag; }
301 static void code_expand(int flag)
302 #line 24 "nitfol.opt"
303 { do_expand = flag; }
305 static void code_symbols(strid_t stream)
306 #line 27 "nitfol.opt"
307 { if(stream) init_infix(stream); }
309 static void code_tandy(int flag)
310 #line 30 "nitfol.opt"
313 static void code_transcript(strid_t stream)
314 #line 33 "nitfol.opt"
315 { if(stream) set_transcript(stream); }
317 static void code_debug(int flag)
318 #line 36 "nitfol.opt"
319 { enter_debugger = flag; do_check_watches = flag; }
321 static void code_prompt(const char *string)
322 #line 39 "nitfol.opt"
323 { n_free(db_prompt); db_prompt = n_strdup(string); }
325 static void code_path(const char *string)
326 #line 42 "nitfol.opt"
327 { n_free(search_path); search_path = n_strdup(string); }
329 static void code_autoundo(int flag)
330 #line 45 "nitfol.opt"
331 { auto_save_undo = flag; }
333 static void code_stacklimit(int number)
334 #line 52 "nitfol.opt"
335 { stacklimit = number; }
337 static void code_alias(const char *string)
338 #line 55 "nitfol.opt"
339 { if(string) parse_new_alias(string, FALSE); }
341 static void code_ralias(const char *string)
342 #line 58 "nitfol.opt"
343 { if(string) parse_new_alias(string, TRUE); }
345 static void code_unalias(const char *string)
346 #line 61 "nitfol.opt"
347 { if(string) remove_alias(string); }
349 static void code_random(int number)
350 #line 64 "nitfol.opt"
351 { faked_random_seed = number; }
353 static void code_mapsym(const char *string)
354 #line 67 "nitfol.opt"
355 { n_free(roomsymbol); roomsymbol = n_strdup(string); }
357 static void code_mapsize(int number)
358 #line 70 "nitfol.opt"
359 { automap_size = number; }
361 static void code_maploc(const char *string)
362 #line 73 "nitfol.opt"
363 { 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; } }
365 static void code_terpnum(int number)
366 #line 76 "nitfol.opt"
367 { interp_num = number; }
369 static void code_terpver(const char *string)
370 #line 79 "nitfol.opt"
371 { if(string) { if(n_strlen(string) == 1) interp_ver = *string; else interp_ver = n_strtol(string, NULL, 10); } }
373 #line 760 "opt2glkc.pl"
374 typedef enum { option_flag, option_file, option_wfile, option_number, option_string } option_type;
375 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;
377 static option_option options[] = {
378 { "ignore", 'i', "Ignore Z-machine strictness errors", option_flag, code_ignore, 1, NULL, NULL, NULL, NULL },
379 { "fullname", 'f', "For running under Emacs or DDD", option_flag, code_fullname, 0, NULL, NULL, NULL, NULL },
380 { "command", 'x', "Read commands from this file", option_file, NULL, 0, code_command, NULL, NULL, NULL },
381 { "pirate", 'P', "Aye, matey", option_flag, code_pirate, 0, NULL, NULL, NULL, NULL },
382 { "quiet", 'q', "Do not print introductory messages", option_flag, code_quiet, 1, NULL, NULL, NULL, NULL },
383 { "spell", '-', "Perform spelling correction", option_flag, code_spell, 1, NULL, NULL, NULL, NULL },
384 { "expand", '-', "Expand one letter abbreviations", option_flag, code_expand, 1, NULL, NULL, NULL, NULL },
385 { "symbols", 's', "Specify symbol file for game", option_file, NULL, 0, code_symbols, NULL, NULL, NULL },
386 { "tandy", 't', "Censors some Infocom games", option_flag, code_tandy, 0, NULL, NULL, NULL, NULL },
387 { "transcript", 'T', "Write transcript to this file", option_wfile, NULL, 0, code_transcript, NULL, NULL, NULL },
388 { "debug", 'd', "Enter debugger immediatly", option_flag, code_debug, 0, NULL, NULL, NULL, NULL },
389 { "prompt", '-', "Specify debugging prompt", option_string, NULL, 0, NULL, NULL, code_prompt, "(nitfol) " },
390 { "path", '-', "Look for games in this directory", option_string, NULL, 0, NULL, NULL, code_path, NULL },
391 { "autoundo", '-', "Ensure '@save_undo' is called every turn", option_flag, code_autoundo, 1, NULL, NULL, NULL, NULL },
392 { "stacklimit", 'S', "Exit when the stack is this deep", option_number, code_stacklimit, 0, NULL, NULL, NULL, NULL },
393 { "alias", 'a', "Specify an alias", option_string, NULL, 0, NULL, NULL, code_alias, NULL },
394 { "ralias", '-', "Specify an recursive alias", option_string, NULL, 0, NULL, NULL, code_ralias, NULL },
395 { "unalias", '-', "Remove an alias", option_string, NULL, 0, NULL, NULL, code_unalias, NULL },
396 { "random", 'r', "Set random seed", option_number, code_random, 0, NULL, NULL, NULL, NULL },
397 { "mapsym", '-', "Specify mapping glyphs", option_string, NULL, 0, NULL, NULL, code_mapsym, "*udb@UDB+" },
398 { "mapsize", '-', "Specify map size", option_number, code_mapsize, 12, NULL, NULL, NULL, NULL },
399 { "maploc", '-', "Specify map location", option_string, NULL, 0, NULL, NULL, code_maploc, "above" },
400 { "terpnum", '-', "Specify interpreter number", option_number, code_terpnum, 2, NULL, NULL, NULL, NULL },
401 { "terpver", '-', "Specify interpreter version", option_string, NULL, 0, NULL, NULL, code_terpver, "N" }
404 #line 811 "opt2glkc.pl"
405 static void set_defaults(void)
408 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
409 if(options[n].int_func)
410 options[n].int_func(options[n].defint);
411 if(options[n].str_func)
412 options[n].str_func(options[n].defstream);
413 if(options[n].string_func)
414 options[n].string_func(options[n].defstring);
418 #line 829 "opt2glkc.pl"
419 static void read_textpref(strid_t pref, const char *progname)
423 int prognamelen = n_strlen(progname);
426 while(glk_get_line_stream(pref, buffer, sizeof(buffer))) {
433 while(buffer[0] == '[') {
434 if(n_strncasecmp(buffer+1, progname, prognamelen) != 0
435 || buffer[1+prognamelen] != ']') {
436 while(glk_get_line_stream(pref, buffer, sizeof(buffer)))
440 glk_get_line_stream(pref, buffer, sizeof(buffer));
445 while(isspace(*optname))
447 if((optval = n_strchr(optname, '=')) != NULL) {
452 if((p = n_strchr(optname, ' ')) != NULL)
455 while(isspace(*optval))
458 while(isspace(optval[strlen(optval)-1]))
459 optval[strlen(optval)-1] = 0;
461 optnum = n_strtol(optval, NULL, 0);
462 if(n_strcasecmp(optval, "false") == 0
463 || n_strcasecmp(optval, "f") == 0)
465 if(n_strcasecmp(optval, "true") == 0
466 || n_strcasecmp(optval, "t") == 0)
469 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
470 if(n_strcmp(options[n].longname, optname) == 0) {
471 switch(options[n].type) {
474 options[n].int_func(optnum);
477 options[n].str_func(startup_open(optval));
480 options[n].str_func(startup_wopen(optval));
483 options[n].string_func(optval);
491 glk_stream_close(pref, NULL);
494 #line 910 "opt2glkc.pl"
495 static void show_help(void)
498 printf("Usage: nitfol [OPTIONS] gamefile\n");
499 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
500 if(options[n].shortname != '-')
501 printf(" -%c, ", options[n].shortname);
504 printf("-%-15s %s\n", options[n].longname, options[n].description);
508 #line 928 "opt2glkc.pl"
509 static BOOL parse_commands(int argc, char **argv)
514 for(i = 1; i < argc; i++) {
517 const char *p = argv[i];
524 if(n_strncmp(p, "no-", 3) == 0) {
529 if(n_strcasecmp(p, "help") == 0) {
533 if(n_strcasecmp(p, "version") == 0) {
534 printf("nitfol version %d.%d\n", NITFOL_MAJOR, NITFOL_MINOR);
538 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
539 if((n_strlen(p) == 1 && *p == options[n].shortname) ||
540 n_strcmp(options[n].longname, p) == 0) {
543 switch(options[n].type) {
545 options[n].int_func(flag);
550 options[n].str_func(startup_open(argv[i]));
555 options[n].str_func(startup_wopen(argv[i]));
560 options[n].int_func(n_strtol(argv[i], NULL, 0));
565 options[n].string_func(argv[i]);
575 strid_t s = startup_open(argv[i]);
578 if(!game_use_file(s))
586 #line 415 "opt2glkc.pl"
589 static void sighandle(int unused);
591 static void sighandle(int unused)
593 /* signal(SIGINT, sighandle); */ /* SysV resets default behaviour - foil it */
594 enter_debugger = TRUE;
601 int glkunix_startup_code(glkunix_startup_t *data)
605 garglk_set_program_name("Nitfol 0.5");
606 garglk_set_program_info(
607 "Nitfol 0.5 by Evin Robertson\n"
608 "With countless patches by other people.\n");
610 return parse_commands(data->argc, data->argv);