X-Git-Url: https://git.stderr.nl/gitweb?p=projects%2Fchimara%2Fchimara.git;a=blobdiff_plain;f=interpreters%2Fbocfel%2Futil.c;fp=interpreters%2Fbocfel%2Futil.c;h=6cd3d9a40ea0f572f5d55867df670029fb4e7403;hp=0000000000000000000000000000000000000000;hb=aa30979369091c96bca34499c28cb01bc16efb1d;hpb=61180dab8f5c29f5a29b83fcb7d62942f7a741d1 diff --git a/interpreters/bocfel/util.c b/interpreters/bocfel/util.c new file mode 100644 index 0000000..6cd3d9a --- /dev/null +++ b/interpreters/bocfel/util.c @@ -0,0 +1,260 @@ +/*- + * Copyright 2010-2012 Chris Spiegel. + * + * This file is part of Bocfel. + * + * Bocfel is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version + * 2 or 3, as published by the Free Software Foundation. + * + * Bocfel is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bocfel. If not, see . + */ + +#include +#include +#include +#include + +#include "util.h" +#include "screen.h" +#include "unicode.h" +#include "zterp.h" + +#ifdef ZTERP_GLK +#include +#include +#endif + +#ifndef ZTERP_NO_SAFETY_CHECKS +unsigned long zassert_pc; + +void assert_fail(const char *fmt, ...) +{ + va_list ap; + char str[1024]; + + va_start(ap, fmt); + vsnprintf(str, sizeof str, fmt, ap); + va_end(ap); + + snprintf(str + strlen(str), sizeof str - strlen(str), " (pc = 0x%lx)", zassert_pc); + + die("%s", str); +} +#endif + +void warning(const char *fmt, ...) +{ + va_list ap; + char str[1024]; + + va_start(ap, fmt); + vsnprintf(str, sizeof str, fmt, ap); + va_end(ap); + + show_message("WARNING: %s", str); +} + +void die(const char *fmt, ...) +{ + va_list ap; + char str[1024]; + + va_start(ap, fmt); + vsnprintf(str, sizeof str, fmt, ap); + va_end(ap); + + show_message("fatal error: %s", str); + +#ifdef ZTERP_GLK +#ifdef GARGLK + fprintf(stderr, "%s\n", str); +#endif + glk_exit(); +#endif + + exit(EXIT_FAILURE); +} + +/* This is not POSIX compliant, but it gets the job done. + * It should not be called more than once. + */ +static int zoptind = 0; +static const char *zoptarg; +static int zgetopt(int argc, char **argv, const char *optstring) +{ + static const char *p = ""; + const char *optp; + int c; + + if(*p == 0) + { + /* No more arguments. */ + if(++zoptind >= argc) return -1; + + p = argv[zoptind]; + + /* No more options. */ + if(p[0] != '-' || p[1] == 0) return -1; + + /* Handle “--” */ + if(*++p == '-') + { + zoptind++; + return -1; + } + } + + c = *p++; + + optp = strchr(optstring, c); + if(optp == NULL) return '?'; + + if(optp[1] == ':') + { + if(*p != 0) zoptarg = p; + else zoptarg = argv[++zoptind]; + + p = ""; + if(zoptarg == NULL) return '?'; + } + + return c; +} + +char *xstrdup(const char *s) +{ + size_t n; + char *r; + + n = strlen(s) + 1; + + r = malloc(n); + if(r != NULL) memcpy(r, s, n); + + return r; +} + +int process_arguments(int argc, char **argv) +{ + int c; + + while( (c = zgetopt(argc, argv, "a:A:cCdDeE:fFgGiklLmn:N:rR:sS:tT:u:UvxXyz:Z:")) != -1 ) + { + switch(c) + { + case 'a': + options.eval_stack_size = strtol(zoptarg, NULL, 10); + break; + case 'A': + options.call_stack_size = strtol(zoptarg, NULL, 10); + break; + case 'c': + options.disable_color = 1; + break; + case 'C': + options.disable_config = 1; + break; + case 'd': + options.disable_timed = 1; + break; + case 'D': + options.disable_sound = 1; + break; + case 'e': + options.enable_escape = 1; + break; + case 'E': + options.escape_string = xstrdup(zoptarg); + break; + case 'f': + options.disable_fixed = 1; + break; + case 'F': + options.assume_fixed = 1; + break; + case 'g': + options.disable_graphics_font = 1; + break; + case 'G': + options.enable_alt_graphics = 1; + break; + case 'i': + options.show_id = 1; + break; + case 'k': + options.disable_term_keys = 1; + break; + case 'l': + options.disable_utf8 = 1; + break; + case 'L': + options.force_utf8 = 1; + break; + case 'm': + options.disable_meta_commands = 1; + break; + case 'n': + options.int_number = strtol(zoptarg, NULL, 10); + break; + case 'N': + options.int_version = zoptarg[0]; + break; + case 'r': + options.replay_on = 1; + break; + case 'R': + options.replay_name = xstrdup(zoptarg); + break; + case 's': + options.record_on = 1; + break; + case 'S': + options.record_name = xstrdup(zoptarg); + break; + case 't': + options.transcript_on = 1; + break; + case 'T': + options.transcript_name = xstrdup(zoptarg); + break; + case 'u': + options.max_saves = strtol(zoptarg, NULL, 10); + break; + case 'U': + options.disable_undo_compression = 1; + break; + case 'v': + options.show_version = 1; + break; + case 'x': + options.disable_abbreviations = 1; + break; + case 'X': + options.enable_censorship = 1; + break; + case 'y': + options.overwrite_transcript = 1; + break; + case 'z': + options.random_seed = strtol(zoptarg, NULL, 10); + break; + case 'Z': + options.random_device = xstrdup(zoptarg); + break; + default: + return 0; + } + } + + /* Just ignore excess stories for now. */ + if(zoptind < argc) game_file = argv[zoptind]; + + return 1; +}