1 #line 228 "opt2glkc.pl"
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)
147 str = glkunix_stream_open_pathname((char *) name, fileusage_Data | fileusage_BinaryMode, 0);
149 set_game_filename(name);
151 char *path = search_path;
154 char *newname = (char *) n_malloc(strlen(path) + strlen(name) + 2);
155 path = n_strdup(path);
156 for(p = n_strtok(path, ":"); p; p = n_strtok(NULL, ":")) {
157 n_strcpy(newname, p);
158 n_strcat(newname, "/");
159 n_strcat(newname, name);
160 str = glkunix_stream_open_pathname((char *) newname, fileusage_Data |
161 fileusage_BinaryMode, 0);
163 set_game_filename(newname);
172 fprintf(stderr, "Cannot open '%s'\n", name);
177 #line 717 "opt2glkc.pl"
178 static strid_t startup_wopen(const char *name)
180 return n_file_name(fileusage_Data | fileusage_BinaryMode,
181 filemode_Write, name);
183 glkunix_argumentlist_t glkunix_arguments[] = {
184 { (char *) "", glkunix_arg_ValueCanFollow, (char *) "filename file to load" },
185 { (char *) "-help", glkunix_arg_NoValue, (char *) "list command-line options" },
186 { (char *) "--help", glkunix_arg_NoValue, (char *) "list command-line options" },
187 { (char *) "-version", glkunix_arg_NoValue, (char *) "get version number" },
188 { (char *) "--version", glkunix_arg_NoValue, (char *) "get version number" },
189 { (char *) "-i", glkunix_arg_NoValue, (char *) "-i" },
190 { (char *) "-no-ignore", glkunix_arg_NoValue, (char *) "-no-ignore" },
191 { (char *) "--no-ignore", glkunix_arg_NoValue, (char *) "--no-ignore" },
192 { (char *) "-ignore", glkunix_arg_NoValue, (char *) "-ignore" },
193 { (char *) "--ignore", glkunix_arg_NoValue, (char *) "--ignore Ignore Z-machine strictness errors" },
194 { (char *) "-f", glkunix_arg_NoValue, (char *) "-f" },
195 { (char *) "-no-fullname", glkunix_arg_NoValue, (char *) "-no-fullname" },
196 { (char *) "--no-fullname", glkunix_arg_NoValue, (char *) "--no-fullname" },
197 { (char *) "-fullname", glkunix_arg_NoValue, (char *) "-fullname" },
198 { (char *) "--fullname", glkunix_arg_NoValue, (char *) "--fullname For running under Emacs or DDD" },
199 { (char *) "-x", glkunix_arg_ValueFollows, (char *) "-x" },
200 { (char *) "-command", glkunix_arg_ValueFollows, (char *) "-command" },
201 { (char *) "--command", glkunix_arg_ValueFollows, (char *) "--command Read commands from this file" },
202 { (char *) "-P", glkunix_arg_NoValue, (char *) "-P" },
203 { (char *) "-no-pirate", glkunix_arg_NoValue, (char *) "-no-pirate" },
204 { (char *) "--no-pirate", glkunix_arg_NoValue, (char *) "--no-pirate" },
205 { (char *) "-pirate", glkunix_arg_NoValue, (char *) "-pirate" },
206 { (char *) "--pirate", glkunix_arg_NoValue, (char *) "--pirate Aye, matey" },
207 { (char *) "-q", glkunix_arg_NoValue, (char *) "-q" },
208 { (char *) "-no-quiet", glkunix_arg_NoValue, (char *) "-no-quiet" },
209 { (char *) "--no-quiet", glkunix_arg_NoValue, (char *) "--no-quiet" },
210 { (char *) "-quiet", glkunix_arg_NoValue, (char *) "-quiet" },
211 { (char *) "--quiet", glkunix_arg_NoValue, (char *) "--quiet Do not print introductory messages" },
212 { (char *) "-no-spell", glkunix_arg_NoValue, (char *) "-no-spell" },
213 { (char *) "--no-spell", glkunix_arg_NoValue, (char *) "--no-spell" },
214 { (char *) "-spell", glkunix_arg_NoValue, (char *) "-spell" },
215 { (char *) "--spell", glkunix_arg_NoValue, (char *) "--spell Perform spelling correction" },
216 { (char *) "-no-expand", glkunix_arg_NoValue, (char *) "-no-expand" },
217 { (char *) "--no-expand", glkunix_arg_NoValue, (char *) "--no-expand" },
218 { (char *) "-expand", glkunix_arg_NoValue, (char *) "-expand" },
219 { (char *) "--expand", glkunix_arg_NoValue, (char *) "--expand Expand one letter abbreviations" },
220 { (char *) "-s", glkunix_arg_ValueFollows, (char *) "-s" },
221 { (char *) "-symbols", glkunix_arg_ValueFollows, (char *) "-symbols" },
222 { (char *) "--symbols", glkunix_arg_ValueFollows, (char *) "--symbols Specify symbol file for game" },
223 { (char *) "-t", glkunix_arg_NoValue, (char *) "-t" },
224 { (char *) "-no-tandy", glkunix_arg_NoValue, (char *) "-no-tandy" },
225 { (char *) "--no-tandy", glkunix_arg_NoValue, (char *) "--no-tandy" },
226 { (char *) "-tandy", glkunix_arg_NoValue, (char *) "-tandy" },
227 { (char *) "--tandy", glkunix_arg_NoValue, (char *) "--tandy Censors some Infocom games" },
228 { (char *) "-T", glkunix_arg_ValueFollows, (char *) "-T" },
229 { (char *) "-transcript", glkunix_arg_ValueFollows, (char *) "-transcript" },
230 { (char *) "--transcript", glkunix_arg_ValueFollows, (char *) "--transcript Write transcript to this file" },
231 { (char *) "-d", glkunix_arg_NoValue, (char *) "-d" },
232 { (char *) "-no-debug", glkunix_arg_NoValue, (char *) "-no-debug" },
233 { (char *) "--no-debug", glkunix_arg_NoValue, (char *) "--no-debug" },
234 { (char *) "-debug", glkunix_arg_NoValue, (char *) "-debug" },
235 { (char *) "--debug", glkunix_arg_NoValue, (char *) "--debug Enter debugger immediatly" },
236 { (char *) "-prompt", glkunix_arg_ValueFollows, (char *) "-prompt" },
237 { (char *) "--prompt", glkunix_arg_ValueFollows, (char *) "--prompt Specify debugging prompt" },
238 { (char *) "-path", glkunix_arg_ValueFollows, (char *) "-path" },
239 { (char *) "--path", glkunix_arg_ValueFollows, (char *) "--path Look for games in this directory" },
240 { (char *) "-no-autoundo", glkunix_arg_NoValue, (char *) "-no-autoundo" },
241 { (char *) "--no-autoundo", glkunix_arg_NoValue, (char *) "--no-autoundo" },
242 { (char *) "-autoundo", glkunix_arg_NoValue, (char *) "-autoundo" },
243 { (char *) "--autoundo", glkunix_arg_NoValue, (char *) "--autoundo Ensure @code{@@save_undo} is called every turn" },
244 { (char *) "-S", glkunix_arg_NumberValue, (char *) "-S" },
245 { (char *) "-stacklimit", glkunix_arg_NumberValue, (char *) "-stacklimit" },
246 { (char *) "--stacklimit", glkunix_arg_NumberValue, (char *) "--stacklimit Exit when the stack is this deep" },
247 { (char *) "-a", glkunix_arg_ValueFollows, (char *) "-a" },
248 { (char *) "-alias", glkunix_arg_ValueFollows, (char *) "-alias" },
249 { (char *) "--alias", glkunix_arg_ValueFollows, (char *) "--alias Specify an alias" },
250 { (char *) "-ralias", glkunix_arg_ValueFollows, (char *) "-ralias" },
251 { (char *) "--ralias", glkunix_arg_ValueFollows, (char *) "--ralias Specify an recursive alias" },
252 { (char *) "-unalias", glkunix_arg_ValueFollows, (char *) "-unalias" },
253 { (char *) "--unalias", glkunix_arg_ValueFollows, (char *) "--unalias Remove an alias" },
254 { (char *) "-r", glkunix_arg_NumberValue, (char *) "-r" },
255 { (char *) "-random", glkunix_arg_NumberValue, (char *) "-random" },
256 { (char *) "--random", glkunix_arg_NumberValue, (char *) "--random Set random seed" },
257 { (char *) "-mapsym", glkunix_arg_ValueFollows, (char *) "-mapsym" },
258 { (char *) "--mapsym", glkunix_arg_ValueFollows, (char *) "--mapsym Specify mapping glyphs" },
259 { (char *) "-mapsize", glkunix_arg_NumberValue, (char *) "-mapsize" },
260 { (char *) "--mapsize", glkunix_arg_NumberValue, (char *) "--mapsize Specify map size" },
261 { (char *) "-maploc", glkunix_arg_ValueFollows, (char *) "-maploc" },
262 { (char *) "--maploc", glkunix_arg_ValueFollows, (char *) "--maploc Specify map location" },
263 { (char *) "-terpnum", glkunix_arg_NumberValue, (char *) "-terpnum" },
264 { (char *) "--terpnum", glkunix_arg_NumberValue, (char *) "--terpnum Specify interpreter number" },
265 { (char *) "-terpver", glkunix_arg_ValueFollows, (char *) "-terpver" },
266 { (char *) "--terpver", glkunix_arg_ValueFollows, (char *) "--terpver Specify interpreter version" },
267 { NULL, glkunix_arg_End, NULL }
270 static void code_ignore(int flag)
272 { ignore_errors = flag; }
274 static void code_fullname(int flag)
278 static void code_command(strid_t stream)
279 #line 12 "nitfol.opt"
280 { if(stream) input_stream1 = stream; }
282 static void code_pirate(int flag)
283 #line 15 "nitfol.opt"
284 { aye_matey = flag; }
286 static void code_quiet(int flag)
287 #line 18 "nitfol.opt"
290 static void code_spell(int flag)
291 #line 21 "nitfol.opt"
292 { do_spell_correct = flag; }
294 static void code_expand(int flag)
295 #line 24 "nitfol.opt"
296 { do_expand = flag; }
298 static void code_symbols(strid_t stream)
299 #line 27 "nitfol.opt"
300 { if(stream) init_infix(stream); }
302 static void code_tandy(int flag)
303 #line 30 "nitfol.opt"
306 static void code_transcript(strid_t stream)
307 #line 33 "nitfol.opt"
308 { if(stream) set_transcript(stream); }
310 static void code_debug(int flag)
311 #line 36 "nitfol.opt"
312 { enter_debugger = flag; do_check_watches = flag; }
314 static void code_prompt(const char *string)
315 #line 39 "nitfol.opt"
316 { n_free(db_prompt); db_prompt = n_strdup(string); }
318 static void code_path(const char *string)
319 #line 42 "nitfol.opt"
320 { n_free(search_path); search_path = n_strdup(string); }
322 static void code_autoundo(int flag)
323 #line 45 "nitfol.opt"
324 { auto_save_undo = flag; }
326 static void code_stacklimit(int number)
327 #line 52 "nitfol.opt"
328 { stacklimit = number; }
330 static void code_alias(const char *string)
331 #line 55 "nitfol.opt"
332 { if(string) parse_new_alias(string, FALSE); }
334 static void code_ralias(const char *string)
335 #line 58 "nitfol.opt"
336 { if(string) parse_new_alias(string, TRUE); }
338 static void code_unalias(const char *string)
339 #line 61 "nitfol.opt"
340 { if(string) remove_alias(string); }
342 static void code_random(int number)
343 #line 64 "nitfol.opt"
344 { faked_random_seed = number; }
346 static void code_mapsym(const char *string)
347 #line 67 "nitfol.opt"
348 { n_free(roomsymbol); roomsymbol = n_strdup(string); }
350 static void code_mapsize(int number)
351 #line 70 "nitfol.opt"
352 { automap_size = number; }
354 static void code_maploc(const char *string)
355 #line 73 "nitfol.opt"
356 { 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; } }
358 static void code_terpnum(int number)
359 #line 76 "nitfol.opt"
360 { interp_num = number; }
362 static void code_terpver(const char *string)
363 #line 79 "nitfol.opt"
364 { if(string) { if(n_strlen(string) == 1) interp_ver = *string; else interp_ver = n_strtol(string, NULL, 10); } }
366 #line 760 "opt2glkc.pl"
367 typedef enum { option_flag, option_file, option_wfile, option_number, option_string } option_type;
368 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;
370 static option_option options[] = {
371 { "ignore", 'i', "Ignore Z-machine strictness errors", option_flag, code_ignore, 0, NULL, NULL, NULL, NULL },
372 { "fullname", 'f', "For running under Emacs or DDD", option_flag, code_fullname, 0, NULL, NULL, NULL, NULL },
373 { "command", 'x', "Read commands from this file", option_file, NULL, 0, code_command, NULL, NULL, NULL },
374 { "pirate", 'P', "Aye, matey", option_flag, code_pirate, 0, NULL, NULL, NULL, NULL },
375 { "quiet", 'q', "Do not print introductory messages", option_flag, code_quiet, 1, NULL, NULL, NULL, NULL },
376 { "spell", '-', "Perform spelling correction", option_flag, code_spell, 1, NULL, NULL, NULL, NULL },
377 { "expand", '-', "Expand one letter abbreviations", option_flag, code_expand, 1, NULL, NULL, NULL, NULL },
378 { "symbols", 's', "Specify symbol file for game", option_file, NULL, 0, code_symbols, NULL, NULL, NULL },
379 { "tandy", 't', "Censors some Infocom games", option_flag, code_tandy, 0, NULL, NULL, NULL, NULL },
380 { "transcript", 'T', "Write transcript to this file", option_wfile, NULL, 0, code_transcript, NULL, NULL, NULL },
381 { "debug", 'd', "Enter debugger immediatly", option_flag, code_debug, 0, NULL, NULL, NULL, NULL },
382 { "prompt", '-', "Specify debugging prompt", option_string, NULL, 0, NULL, NULL, code_prompt, "(nitfol) " },
383 { "path", '-', "Look for games in this directory", option_string, NULL, 0, NULL, NULL, code_path, NULL },
384 { "autoundo", '-', "Ensure '@save_undo' is called every turn", option_flag, code_autoundo, 1, NULL, NULL, NULL, NULL },
385 { "stacklimit", 'S', "Exit when the stack is this deep", option_number, code_stacklimit, 0, NULL, NULL, NULL, NULL },
386 { "alias", 'a', "Specify an alias", option_string, NULL, 0, NULL, NULL, code_alias, NULL },
387 { "ralias", '-', "Specify an recursive alias", option_string, NULL, 0, NULL, NULL, code_ralias, NULL },
388 { "unalias", '-', "Remove an alias", option_string, NULL, 0, NULL, NULL, code_unalias, NULL },
389 { "random", 'r', "Set random seed", option_number, code_random, 0, NULL, NULL, NULL, NULL },
390 { "mapsym", '-', "Specify mapping glyphs", option_string, NULL, 0, NULL, NULL, code_mapsym, "*udb@UDB+" },
391 { "mapsize", '-', "Specify map size", option_number, code_mapsize, 12, NULL, NULL, NULL, NULL },
392 { "maploc", '-', "Specify map location", option_string, NULL, 0, NULL, NULL, code_maploc, "above" },
393 { "terpnum", '-', "Specify interpreter number", option_number, code_terpnum, 2, NULL, NULL, NULL, NULL },
394 { "terpver", '-', "Specify interpreter version", option_string, NULL, 0, NULL, NULL, code_terpver, "N" }
397 #line 811 "opt2glkc.pl"
398 static void set_defaults(void)
401 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
402 if(options[n].int_func)
403 options[n].int_func(options[n].defint);
404 if(options[n].str_func)
405 options[n].str_func(options[n].defstream);
406 if(options[n].string_func)
407 options[n].string_func(options[n].defstring);
411 #line 829 "opt2glkc.pl"
412 static void read_textpref(strid_t pref, const char *progname)
416 int prognamelen = n_strlen(progname);
419 while(glk_get_line_stream(pref, buffer, sizeof(buffer))) {
426 while(buffer[0] == '[') {
427 if(n_strncasecmp(buffer+1, progname, prognamelen) != 0
428 || buffer[1+prognamelen] != ']') {
429 while(glk_get_line_stream(pref, buffer, sizeof(buffer)))
433 glk_get_line_stream(pref, buffer, sizeof(buffer));
438 while(isspace(*optname))
440 if((optval = n_strchr(optname, '=')) != NULL) {
445 if((p = n_strchr(optname, ' ')) != NULL)
448 while(isspace(*optval))
451 while(isspace(optval[strlen(optval)-1]))
452 optval[strlen(optval)-1] = 0;
454 optnum = n_strtol(optval, NULL, 0);
455 if(n_strcasecmp(optval, "false") == 0
456 || n_strcasecmp(optval, "f") == 0)
458 if(n_strcasecmp(optval, "true") == 0
459 || n_strcasecmp(optval, "t") == 0)
462 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
463 if(n_strcmp(options[n].longname, optname) == 0) {
464 switch(options[n].type) {
467 options[n].int_func(optnum);
470 options[n].str_func(startup_open(optval));
473 options[n].str_func(startup_wopen(optval));
476 options[n].string_func(optval);
484 glk_stream_close(pref, NULL);
487 #line 910 "opt2glkc.pl"
488 static void show_help(void)
491 printf("Usage: nitfol [OPTIONS] gamefile\n");
492 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
493 if(options[n].shortname != '-')
494 printf(" -%c, ", options[n].shortname);
497 printf("-%-15s %s\n", options[n].longname, options[n].description);
501 #line 928 "opt2glkc.pl"
502 static BOOL parse_commands(int argc, char **argv)
507 for(i = 1; i < argc; i++) {
510 const char *p = argv[i];
517 if(n_strncmp(p, "no-", 3) == 0) {
522 if(n_strcasecmp(p, "help") == 0) {
526 if(n_strcasecmp(p, "version") == 0) {
527 printf("nitfol version %d.%d\n", NITFOL_MAJOR, NITFOL_MINOR);
531 for(n = 0; n < sizeof(options) / sizeof(*options); n++) {
532 if((n_strlen(p) == 1 && *p == options[n].shortname) ||
533 n_strcmp(options[n].longname, p) == 0) {
536 switch(options[n].type) {
538 options[n].int_func(flag);
543 options[n].str_func(startup_open(argv[i]));
548 options[n].str_func(startup_wopen(argv[i]));
553 options[n].int_func(n_strtol(argv[i], NULL, 0));
558 options[n].string_func(argv[i]);
568 strid_t s = startup_open(argv[i]);
571 if(!game_use_file(s))
579 #line 415 "opt2glkc.pl"
582 static void sighandle(int unused);
584 static void sighandle(int unused)
586 /* signal(SIGINT, sighandle); */ /* SysV resets default behaviour - foil it */
587 enter_debugger = TRUE;
594 int glkunix_startup_code(glkunix_startup_t *data)
597 const char *configname;
598 char *configdir, *prefname;
601 username = getenv("LOGNAME"); /* SysV */
603 username = getenv("USER"); /* BSD */
606 /* signal(SIGINT, sighandle); */
609 execname = n_strrchr(data->argv[0], '/');
614 execname = data->argv[0];
617 configdir = n_strdup(data->argv[0]); if(n_strrchr(configdir, '/')) *n_strrchr(configdir, '/') = 0;
618 configname = "/nitfol.cfg";
619 prefname = n_malloc(n_strlen(configdir) + n_strlen(configname) + 1);
620 n_strcpy(prefname, configdir);
621 n_strcat(prefname, configname);
622 pref = glkunix_stream_open_pathname(prefname, fileusage_Data | fileusage_TextMode, 0);
625 read_textpref(pref, execname);
627 p = getenv("INFOCOM_PATH");
630 search_path = n_strdup(p);
633 return parse_commands(data->argc, data->argv);