Implement a Makefile for Inform.
[inform.git] / inform.c
diff --git a/inform.c b/inform.c
deleted file mode 100644 (file)
index 793d534..0000000
--- a/inform.c
+++ /dev/null
@@ -1,1871 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/*   "inform" :  The top level of Inform: switches, pathnames, filenaming    */
-/*               conventions, ICL (Inform Command Line) files, main          */
-/*                                                                           */
-/* Copyright (c) Graham Nelson 1993 - 2018                                   */
-/*                                                                           */
-/* This file is part of Inform.                                              */
-/*                                                                           */
-/* Inform is free software: you can redistribute it and/or modify            */
-/* it under the terms of the GNU General Public License as published by      */
-/* the Free Software Foundation, either version 3 of the License, or         */
-/* (at your option) any later version.                                       */
-/*                                                                           */
-/* Inform 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 Inform. If not, see https://gnu.org/licenses/                  */
-/*                                                                           */
-/* ------------------------------------------------------------------------- */
-
-#define MAIN_INFORM_FILE
-#include "header.h"
-
-/* ------------------------------------------------------------------------- */
-/*   Compiler progress                                                       */
-/* ------------------------------------------------------------------------- */
-
-static int no_compilations;
-
-int endofpass_flag;      /* set to TRUE when an "end" directive is reached
-                            (the inputs routines insert one into the stream
-                            if necessary)                                    */
-
-/* ------------------------------------------------------------------------- */
-/*   Version control                                                         */
-/* ------------------------------------------------------------------------- */
-
-int version_number,      /* 3 to 8 (Z-code)                                  */
-    instruction_set_number,
-                         /* 3 to 6: versions 7 and 8 use instruction set of
-                            version 5                                        */
-    extend_memory_map;   /* extend using function- and string-offsets        */
-int32 scale_factor,      /* packed address multiplier                        */
-    length_scale_factor; /* length-in-header multiplier                      */
-
-int32 requested_glulx_version;
-
-extern void select_version(int vn)
-{   version_number = vn;
-    extend_memory_map = FALSE;
-    if ((version_number==6)||(version_number==7)) extend_memory_map = TRUE;
-
-    scale_factor = 4;
-    if (version_number==3) scale_factor = 2;
-    if (version_number==8) scale_factor = 8;
-
-    length_scale_factor = scale_factor;
-    if ((version_number==6)||(version_number==7)) length_scale_factor = 8;
-
-    instruction_set_number = version_number;
-    if ((version_number==7)||(version_number==8)) instruction_set_number = 5;
-}
-
-static int select_glulx_version(char *str)
-{
-  /* Parse an "X.Y.Z" style version number, and store it for later use. */
-  char *cx = str;
-  int major=0, minor=0, patch=0;
-
-  while (isdigit(*cx))
-    major = major*10 + ((*cx++)-'0');
-  if (*cx == '.') {
-    cx++;
-    while (isdigit(*cx))
-      minor = minor*10 + ((*cx++)-'0');
-    if (*cx == '.') {
-      cx++;
-      while (isdigit(*cx))
-        patch = patch*10 + ((*cx++)-'0');
-    }
-  }
-
-  requested_glulx_version = ((major & 0x7FFF) << 16) 
-    + ((minor & 0xFF) << 8) 
-    + (patch & 0xFF);
-  return (cx - str);
-}
-
-/* ------------------------------------------------------------------------- */
-/*   Target: variables which vary between the Z-machine and Glulx            */
-/* ------------------------------------------------------------------------- */
-
-int   WORDSIZE;            /* Size of a machine word: 2 or 4 */
-int32 MAXINTWORD;          /* 0x7FFF or 0x7FFFFFFF */
-
-/* The first property number which is an individual property. The
-   eight class-system i-props (create, recreate, ... print_to_array)
-   are numbered from INDIV_PROP_START to INDIV_PROP_START+7.
-*/
-int INDIV_PROP_START;
-
-/* The length of an object, as written in tables.c. It's easier to define
-   it here than to repeat the same expression all over the source code.
-   Not used in Z-code. 
-*/
-int OBJECT_BYTE_LENGTH;
-/* The total length of a dict entry, in bytes. Not used in Z-code. 
-*/
-int DICT_ENTRY_BYTE_LENGTH;
-/* The position in a dict entry that the flag values begin.
-   Not used in Z-code. 
-*/
-int DICT_ENTRY_FLAG_POS;
-
-static void select_target(int targ)
-{
-  if (!targ) {
-    /* Z-machine */
-    WORDSIZE = 2;
-    MAXINTWORD = 0x7FFF;
-
-    if (INDIV_PROP_START != 64) {
-        INDIV_PROP_START = 64;
-        fatalerror("You cannot change INDIV_PROP_START in Z-code");
-    }
-    if (DICT_WORD_SIZE != 6) {
-      DICT_WORD_SIZE = 6;
-      fatalerror("You cannot change DICT_WORD_SIZE in Z-code");
-    }
-    if (DICT_CHAR_SIZE != 1) {
-      DICT_CHAR_SIZE = 1;
-      fatalerror("You cannot change DICT_CHAR_SIZE in Z-code");
-    }
-    if (NUM_ATTR_BYTES != 6) {
-      NUM_ATTR_BYTES = 6;
-      fatalerror("You cannot change NUM_ATTR_BYTES in Z-code");
-    }
-    if (MAX_LOCAL_VARIABLES != 16) {
-      MAX_LOCAL_VARIABLES = 16;
-      fatalerror("You cannot change MAX_LOCAL_VARIABLES in Z-code");
-    }
-    if (MAX_GLOBAL_VARIABLES != 240) {
-      MAX_GLOBAL_VARIABLES = 240;
-      fatalerror("You cannot change MAX_GLOBAL_VARIABLES in Z-code");
-    }
-    if (MAX_VERBS > 255) {
-      MAX_VERBS = 255;
-      fatalerror("MAX_VERBS can only go above 255 when Glulx is used");
-    }
-  }
-  else {
-    /* Glulx */
-    WORDSIZE = 4;
-    MAXINTWORD = 0x7FFFFFFF;
-    scale_factor = 0; /* It should never even get used in Glulx */
-
-    if (INDIV_PROP_START < 256) {
-        INDIV_PROP_START = 256;
-        warning_numbered("INDIV_PROP_START should be at least 256 in Glulx. Setting to", INDIV_PROP_START);
-    }
-
-    if (NUM_ATTR_BYTES % 4 != 3) {
-      NUM_ATTR_BYTES += (3 - (NUM_ATTR_BYTES % 4)); 
-      warning_numbered("NUM_ATTR_BYTES must be a multiple of four, plus three. Increasing to", NUM_ATTR_BYTES);
-    }
-
-    if (DICT_CHAR_SIZE != 1 && DICT_CHAR_SIZE != 4) {
-      DICT_CHAR_SIZE = 4;
-      warning_numbered("DICT_CHAR_SIZE must be either 1 or 4. Setting to", DICT_CHAR_SIZE);
-    }
-  }
-
-  if (MAX_LOCAL_VARIABLES >= 120) {
-    MAX_LOCAL_VARIABLES = 119;
-    warning("MAX_LOCAL_VARIABLES cannot exceed 119; resetting to 119");
-    /* This is because the keyword table in the lexer only has 120
-       entries. */
-  }
-  if (DICT_WORD_SIZE > MAX_DICT_WORD_SIZE) {
-    DICT_WORD_SIZE = MAX_DICT_WORD_SIZE;
-    warning_numbered(
-      "DICT_WORD_SIZE cannot exceed MAX_DICT_WORD_SIZE; resetting", 
-      MAX_DICT_WORD_SIZE);
-    /* MAX_DICT_WORD_SIZE can be increased in header.h without fear. */
-  }
-  if (NUM_ATTR_BYTES > MAX_NUM_ATTR_BYTES) {
-    NUM_ATTR_BYTES = MAX_NUM_ATTR_BYTES;
-    warning_numbered(
-      "NUM_ATTR_BYTES cannot exceed MAX_NUM_ATTR_BYTES; resetting",
-      MAX_NUM_ATTR_BYTES);
-    /* MAX_NUM_ATTR_BYTES can be increased in header.h without fear. */
-  }
-
-  /* Set up a few more variables that depend on the above values */
-
-  if (!targ) {
-    /* Z-machine */
-    DICT_WORD_BYTES = DICT_WORD_SIZE;
-    /* The Z-code generator doesn't use the following variables, although 
-       it would be a little cleaner if it did. */
-    OBJECT_BYTE_LENGTH = 0;
-    DICT_ENTRY_BYTE_LENGTH = (version_number==3)?7:9;
-    DICT_ENTRY_FLAG_POS = 0;
-  }
-  else {
-    /* Glulx */
-    OBJECT_BYTE_LENGTH = (1 + (NUM_ATTR_BYTES) + 6*4 + (GLULX_OBJECT_EXT_BYTES));
-    DICT_WORD_BYTES = DICT_WORD_SIZE*DICT_CHAR_SIZE;
-    if (DICT_CHAR_SIZE == 1) {
-      DICT_ENTRY_BYTE_LENGTH = (7+DICT_WORD_BYTES);
-      DICT_ENTRY_FLAG_POS = (1+DICT_WORD_BYTES);
-    }
-    else {
-      DICT_ENTRY_BYTE_LENGTH = (12+DICT_WORD_BYTES);
-      DICT_ENTRY_FLAG_POS = (4+DICT_WORD_BYTES);
-    }
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-/*   Tracery: output control variables                                       */
-/* ------------------------------------------------------------------------- */
-
-int asm_trace_level,     /* trace assembly: 0 for off, 1 for assembly
-                            only, 2 for full assembly tracing with hex dumps */
-    line_trace_level,    /* line tracing: 0 off, 1 on                        */
-    expr_trace_level,    /* expression tracing: 0 off, 1 full, 2 brief       */
-    linker_trace_level,  /* set by -y: 0 to 4 levels of tracing              */
-    tokens_trace_level;  /* lexer output tracing: 0 off, 1 on                */
-
-/* ------------------------------------------------------------------------- */
-/*   On/off switch variables (by default all FALSE); other switch settings   */
-/* ------------------------------------------------------------------------- */
-
-int bothpasses_switch,              /* -b */
-    concise_switch,                 /* -c */
-    economy_switch,                 /* -e */
-    frequencies_switch,             /* -f */
-    ignore_switches_switch,         /* -i */
-    listobjects_switch,             /* -j */
-    debugfile_switch,               /* -k */
-    listing_switch,                 /* -l */
-    memout_switch,                  /* -m */
-    printprops_switch,              /* -n */
-    offsets_switch,                 /* -o */
-    percentages_switch,             /* -p */
-    obsolete_switch,                /* -q */
-    transcript_switch,              /* -r */
-    statistics_switch,              /* -s */
-    optimise_switch,                /* -u */
-    version_set_switch,             /* -v */
-    nowarnings_switch,              /* -w */
-    hash_switch,                    /* -x */
-    memory_map_switch,              /* -z */
-    oddeven_packing_switch,         /* -B */
-    define_DEBUG_switch,            /* -D */
-    temporary_files_switch,         /* -F */
-    module_switch,                  /* -M */
-    runtime_error_checking_switch,  /* -S */
-    define_USE_MODULES_switch,      /* -U */
-    define_INFIX_switch;            /* -X */
-#ifdef ARC_THROWBACK
-int throwback_switch;               /* -T */
-#endif
-#ifdef ARCHIMEDES
-int riscos_file_type_format;        /* set by -R */
-#endif
-int compression_switch;             /* set by -H */
-int character_set_setting,          /* set by -C0 through -C9 */
-    character_set_unicode,          /* set by -Cu */
-    error_format,                   /* set by -E */
-    asm_trace_setting,              /* set by -a and -t: value of
-                                       asm_trace_level to use when tracing */
-    double_space_setting,           /* set by -d: 0, 1 or 2 */
-    trace_fns_setting,              /* set by -g: 0, 1 or 2 */
-    linker_trace_setting,           /* set by -y: ditto for linker_... */
-    store_the_text;                 /* when set, record game text to a chunk
-                                       of memory (used by both -r & -k) */
-static int r_e_c_s_set;             /* has -S been explicitly set? */
-
-int glulx_mode;                     /* -G */
-
-static void reset_switch_settings(void)
-{   asm_trace_setting=0;
-    linker_trace_level=0;
-    tokens_trace_level=0;
-
-    store_the_text = FALSE;
-
-    bothpasses_switch = FALSE;
-    concise_switch = FALSE;
-    double_space_setting = 0;
-    economy_switch = FALSE;
-    frequencies_switch = FALSE;
-    trace_fns_setting = 0;
-    ignore_switches_switch = FALSE;
-    listobjects_switch = FALSE;
-    debugfile_switch = FALSE;
-    listing_switch = FALSE;
-    memout_switch = FALSE;
-    printprops_switch = FALSE;
-    offsets_switch = FALSE;
-    percentages_switch = FALSE;
-    obsolete_switch = FALSE;
-    transcript_switch = FALSE;
-    statistics_switch = FALSE;
-    optimise_switch = FALSE;
-    version_set_switch = FALSE;
-    nowarnings_switch = FALSE;
-    hash_switch = FALSE;
-    memory_map_switch = FALSE;
-    oddeven_packing_switch = FALSE;
-    define_DEBUG_switch = FALSE;
-#ifdef USE_TEMPORARY_FILES
-    temporary_files_switch = TRUE;
-#else
-    temporary_files_switch = FALSE;
-#endif
-    define_USE_MODULES_switch = FALSE;
-    module_switch = FALSE;
-#ifdef ARC_THROWBACK
-    throwback_switch = FALSE;
-#endif
-    runtime_error_checking_switch = TRUE;
-    r_e_c_s_set = FALSE;
-    define_INFIX_switch = FALSE;
-#ifdef ARCHIMEDES
-    riscos_file_type_format = 0;
-#endif
-    error_format=DEFAULT_ERROR_FORMAT;
-
-    character_set_setting = 1;         /* Default is ISO Latin-1 */
-    character_set_unicode = FALSE;
-
-    compression_switch = TRUE;
-    glulx_mode = FALSE;
-    requested_glulx_version = 0;
-}
-
-/* ------------------------------------------------------------------------- */
-/*   Number of files given as command line parameters (0, 1 or 2)            */
-/* ------------------------------------------------------------------------- */
-
-static int cli_files_specified,
-           convert_filename_flag;
-
-char Source_Name[PATHLEN];             /* Processed name of first input file */
-char Code_Name[PATHLEN];               /* Processed name of output file      */
-
-static char *cli_file1, *cli_file2;    /* Unprocessed (and unsafe to alter)  */
-
-/* ========================================================================= */
-/*   Data structure management routines                                      */
-/* ------------------------------------------------------------------------- */
-
-static void init_vars(void)
-{
-    init_arrays_vars();
-    init_asm_vars();
-    init_bpatch_vars();
-    init_chars_vars();
-    init_directs_vars();
-    init_errors_vars();
-    init_expressc_vars();
-    init_expressp_vars();
-    init_files_vars();
-    init_lexer_vars();
-    init_linker_vars();
-    init_memory_vars();
-    init_objects_vars();
-    init_states_vars();
-    init_symbols_vars();
-    init_syntax_vars();
-    init_tables_vars();
-    init_text_vars();
-    init_veneer_vars();
-    init_verbs_vars();
-}
-
-static void begin_pass(void)
-{
-    arrays_begin_pass();
-    asm_begin_pass();
-    bpatch_begin_pass();
-    chars_begin_pass();
-    directs_begin_pass();
-    errors_begin_pass();
-    expressc_begin_pass();
-    expressp_begin_pass();
-    files_begin_pass();
-
-    endofpass_flag = FALSE;
-    line_trace_level = 0; expr_trace_level = 0;
-    asm_trace_level = asm_trace_setting;
-    linker_trace_level = linker_trace_setting;
-    if (listing_switch) line_trace_level=1;
-
-    lexer_begin_pass();
-    linker_begin_pass();
-    memory_begin_pass();
-    objects_begin_pass();
-    states_begin_pass();
-    symbols_begin_pass();
-    syntax_begin_pass();
-    tables_begin_pass();
-    text_begin_pass();
-    veneer_begin_pass();
-    verbs_begin_pass();
-
-    if (!module_switch)
-    {
-        /*  Compile a Main__ routine (see "veneer.c")  */
-
-        compile_initial_routine();
-
-        /*  Make the four metaclasses: Class must be object number 1, so
-            it must come first  */
-
-        veneer_mode = TRUE;
-
-        make_class("Class");
-        make_class("Object");
-        make_class("Routine");
-        make_class("String");
-
-        veneer_mode = FALSE;
-    }
-}
-
-extern void allocate_arrays(void)
-{
-    arrays_allocate_arrays();
-    asm_allocate_arrays();
-    bpatch_allocate_arrays();
-    chars_allocate_arrays();
-    directs_allocate_arrays();
-    errors_allocate_arrays();
-    expressc_allocate_arrays();
-    expressp_allocate_arrays();
-    files_allocate_arrays();
-
-    lexer_allocate_arrays();
-    linker_allocate_arrays();
-    memory_allocate_arrays();
-    objects_allocate_arrays();
-    states_allocate_arrays();
-    symbols_allocate_arrays();
-    syntax_allocate_arrays();
-    tables_allocate_arrays();
-    text_allocate_arrays();
-    veneer_allocate_arrays();
-    verbs_allocate_arrays();
-}
-
-extern void free_arrays(void)
-{
-    /*  One array may survive this routine, all_the_text (used to hold
-        game text until the abbreviations optimiser begins work on it): this
-        array (if it was ever allocated) is freed at the top level.          */
-
-    arrays_free_arrays();
-    asm_free_arrays();
-    bpatch_free_arrays();
-    chars_free_arrays();
-    directs_free_arrays();
-    errors_free_arrays();
-    expressc_free_arrays();
-    expressp_free_arrays();
-    files_free_arrays();
-
-    lexer_free_arrays();
-    linker_free_arrays();
-    memory_free_arrays();
-    objects_free_arrays();
-    states_free_arrays();
-    symbols_free_arrays();
-    syntax_free_arrays();
-    tables_free_arrays();
-    text_free_arrays();
-    veneer_free_arrays();
-    verbs_free_arrays();
-}
-
-/* ------------------------------------------------------------------------- */
-/*    Name translation code for filenames                                    */
-/* ------------------------------------------------------------------------- */
-
-static char Source_Path[PATHLEN];
-static char Include_Path[PATHLEN];
-static char Code_Path[PATHLEN];
-static char Module_Path[PATHLEN];
-static char Temporary_Path[PATHLEN];
-static char current_source_path[PATHLEN];
-       char Debugging_Name[PATHLEN];
-       char Transcript_Name[PATHLEN];
-       char Language_Name[PATHLEN];
-       char Charset_Map[PATHLEN];
-static char ICL_Path[PATHLEN];
-
-/* Set one of the above Path buffers to the given location, or list of
-   locations. (A list is comma-separated, and only accepted for Source_Path,
-   Include_Path, ICL_Path, Module_Path.)
-*/
-static void set_path_value(char *path, char *value)
-{   int i, j;
-
-    for (i=0, j=0;;)
-    {
-        if (i >= PATHLEN-1) {
-            printf("A specified path is longer than %d characters.\n",
-                PATHLEN-1);
-            exit(1);
-        }
-        if ((value[j] == FN_ALT) || (value[j] == 0))
-        {   if ((value[j] == FN_ALT)
-                && (path != Source_Path) && (path != Include_Path)
-                && (path != ICL_Path) && (path != Module_Path))
-            {   printf("The character '%c' is used to divide entries in a list \
-of possible locations, and can only be used in the Include_Path, Source_Path, \
-Module_Path or ICL_Path variables. Other paths are for output only.\n", FN_ALT);
-                exit(1);
-            }
-            if ((path != Debugging_Name) && (path != Transcript_Name)
-                 && (path != Language_Name) && (path != Charset_Map)
-                 && (i>0) && (isalnum(path[i-1]))) path[i++] = FN_SEP;
-            path[i++] = value[j++];
-            if (value[j-1] == 0) return;
-        }
-        else path[i++] = value[j++];
-    }
-}
-
-/* Prepend the given location or list of locations to one of the above
-   Path buffers. This is only permitted for Source_Path, Include_Path, 
-   ICL_Path, Module_Path.
-
-   An empty field (in the comma-separated list) means the current
-   directory. If the Path buffer is entirely empty, we assume that
-   we want to search both value and the current directory, so
-   the result will be "value,".
-*/
-static void prepend_path_value(char *path, char *value)
-{
-    int i, j;
-    int oldlen = strlen(path);
-    int newlen;
-    char new_path[PATHLEN];
-
-    if ((path != Source_Path) && (path != Include_Path)
-        && (path != ICL_Path) && (path != Module_Path))
-    {   printf("The character '+' is used to add to a list \
-of possible locations, and can only be used in the Include_Path, Source_Path, \
-Module_Path or ICL_Path variables. Other paths are for output only.\n");
-        exit(1);
-    }
-
-    for (i=0, j=0;;)
-    {
-        if (i >= PATHLEN-1) {
-            printf("A specified path is longer than %d characters.\n",
-                PATHLEN-1);
-            exit(1);
-        }
-        if ((value[j] == FN_ALT) || (value[j] == 0))
-        {   if ((path != Debugging_Name) && (path != Transcript_Name)
-                 && (path != Language_Name) && (path != Charset_Map)
-                 && (i>0) && (isalnum(new_path[i-1]))) new_path[i++] = FN_SEP;
-            new_path[i++] = value[j++];
-            if (value[j-1] == 0) {
-                newlen = i-1;
-                break;
-            }
-        }
-        else new_path[i++] = value[j++];
-    }
-
-    if (newlen+1+oldlen >= PATHLEN-1) {
-        printf("A specified path is longer than %d characters.\n",
-            PATHLEN-1);
-        exit(1);
-    }
-
-    i = newlen;
-    new_path[i++] = FN_ALT;
-    for (j=0; j<oldlen;)
-        new_path[i++] = path[j++];
-    new_path[i] = 0;
-    
-    strcpy(path, new_path);
-}
-
-static void set_default_paths(void)
-{
-    set_path_value(Source_Path,     Source_Directory);
-    set_path_value(Include_Path,    Include_Directory);
-    set_path_value(Code_Path,       Code_Directory);
-    set_path_value(Module_Path,     Module_Directory);
-    set_path_value(ICL_Path,        ICL_Directory);
-    set_path_value(Temporary_Path,  Temporary_Directory);
-    set_path_value(Debugging_Name,  Debugging_File);
-    set_path_value(Transcript_Name, Transcript_File);
-    set_path_value(Language_Name,   "english");
-    set_path_value(Charset_Map,     "");
-}
-
-/* Parse a path option which looks like "dir", "+dir", "pathname=dir",
-   or "+pathname=dir". If there is no "=", we assume "include_path=...".
-   If the option begins with a "+" the directory is prepended to the
-   existing path instead of replacing it.
-*/
-static void set_path_command(char *command)
-{   int i, j; char *path_to_set = NULL;
-    int prepend = 0;
-
-    if (command[0] == '+') {
-        prepend = 1;
-        command++;
-    }
-
-    for (i=0; (command[i]!=0) && (command[i]!='=');i++) ;
-
-    path_to_set=Include_Path; 
-
-    if (command[i] == '=') { 
-        char pathname[PATHLEN];
-        if (i>=PATHLEN) i=PATHLEN-1;
-        for (j=0;j<i;j++) {
-            char ch = command[j];
-            if (isupper(ch)) ch=tolower(ch);
-            pathname[j]=ch;
-        }
-        pathname[j]=0;
-        command = command+i+1;
-
-        path_to_set = NULL;
-        if (strcmp(pathname, "source_path")==0)  path_to_set=Source_Path;
-        if (strcmp(pathname, "include_path")==0) path_to_set=Include_Path;
-        if (strcmp(pathname, "code_path")==0)    path_to_set=Code_Path;
-        if (strcmp(pathname, "module_path")==0)  path_to_set=Module_Path;
-        if (strcmp(pathname, "icl_path")==0)     path_to_set=ICL_Path;
-        if (strcmp(pathname, "temporary_path")==0) path_to_set=Temporary_Path;
-        if (strcmp(pathname, "debugging_name")==0) path_to_set=Debugging_Name;
-        if (strcmp(pathname, "transcript_name")==0) path_to_set=Transcript_Name;
-        if (strcmp(pathname, "language_name")==0) path_to_set=Language_Name;
-        if (strcmp(pathname, "charset_map")==0) path_to_set=Charset_Map;
-
-        if (path_to_set == NULL)
-        {   printf("No such path setting as \"%s\"\n", pathname);
-            exit(1);
-        }
-    }
-
-    if (!prepend)
-        set_path_value(path_to_set, command);
-    else
-        prepend_path_value(path_to_set, command);
-}
-
-static int contains_separator(char *name)
-{   int i;
-    for (i=0; name[i]!=0; i++)
-        if (name[i] == FN_SEP) return 1;
-    return 0;
-}
-
-static int write_translated_name(char *new_name, char *old_name,
-                                 char *prefix_path, int start_pos,
-                                 char *extension)
-{   int x;
-    if (strlen(old_name)+strlen(extension) >= PATHLEN) {
-        printf("One of your filenames is longer than %d characters.\n", PATHLEN);
-        exit(1);
-    }
-    if (prefix_path == NULL)
-    {   sprintf(new_name,"%s%s", old_name, extension);
-        return 0;
-    }
-    strcpy(new_name, prefix_path + start_pos);
-    for (x=0; (new_name[x]!=0) && (new_name[x]!=FN_ALT); x++) ;
-    if (new_name[x] == 0) start_pos = 0; else start_pos += x+1;
-    if (x+strlen(old_name)+strlen(extension) >= PATHLEN) {
-        printf("One of your pathnames is longer than %d characters.\n", PATHLEN);
-        exit(1);
-    }
-    sprintf(new_name + x, "%s%s", old_name, extension);
-    return start_pos;
-}
-
-#ifdef FILE_EXTENSIONS
-static char *check_extension(char *name, char *extension)
-{   int i;
-
-    /* If a filename ends in '.', remove the dot and add no file extension: */
-    i = strlen(name)-1;
-    if (name[i] == '.') { name[i]=0; return ""; }
-
-    /* Remove the new extension if it's already got one: */
-
-    for (; (i>=0) && (name[i]!=FN_SEP); i--)
-        if (name[i] == '.') return "";
-    return extension;
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-/*    Three translation routines have to deal with path variables which may  */
-/*    contain alternative locations separated by the FN_ALT character.       */
-/*    These have the protocol:                                               */
-/*                                                                           */
-/*        int translate_*_filename(int last_value, ...)                      */
-/*                                                                           */
-/*    and should first be called with last_value equal to 0.  If the         */
-/*    translated filename works, fine.  Otherwise, if the returned integer   */
-/*    was zero, the caller knows that no filename works and can issue an     */
-/*    error message.  If it was non-zero, the caller should pass it on as    */
-/*    the last_value again.                                                  */
-/*                                                                           */
-/*    As implemented below, last_value is the position in the path variable  */
-/*    string at which the next directory name to try begins.                 */
-/* ------------------------------------------------------------------------- */
-
-extern int translate_in_filename(int last_value,
-    char *new_name, char *old_name,
-    int same_directory_flag, int command_line_flag)
-{   char *prefix_path = NULL;
-    char *extension;
-    int add_path_flag = 1;
-    int i;
-
-    if ((same_directory_flag==0)
-        && (contains_separator(old_name)==1)) add_path_flag=0;
-
-    if (add_path_flag==1)
-    {   if (command_line_flag == 0)
-        {   /* File is opened as a result of an Include directive */
-
-            if (same_directory_flag==1)
-                prefix_path = current_source_path;
-            else
-                if (Include_Path[0]!=0) prefix_path = Include_Path;
-        }
-        /* Main file being opened from the command line */
-
-        else if (Source_Path[0]!=0) prefix_path = Source_Path;
-    }
-
-#ifdef FILE_EXTENSIONS
-    /* Which file extension is expected? */
-
-    if ((command_line_flag==1)||(same_directory_flag==1))
-        extension = Source_Extension;
-    else
-        extension = Include_Extension;
-
-    extension = check_extension(old_name, extension);
-#else
-    extension = "";
-#endif
-
-    last_value = write_translated_name(new_name, old_name,
-                     prefix_path, last_value, extension);
-
-    /* Set the "current source path" (for use of Include ">...") */
-
-    if (command_line_flag==1)
-    {   strcpy(current_source_path, new_name);
-        for (i=strlen(current_source_path)-1;
-             ((i>0)&&(current_source_path[i]!=FN_SEP));i--) ;
-
-        if (i!=0) current_source_path[i+1] = 0; /* Current file in subdir   */
-        else current_source_path[0] = 0;        /* Current file at root dir */
-    }
-
-    return last_value;
-}
-
-extern int translate_link_filename(int last_value,
-    char *new_name, char *old_name)
-{   char *prefix_path = NULL;
-    char *extension;
-
-    if (contains_separator(old_name)==0)
-        if (Module_Path[0]!=0)
-            prefix_path = Module_Path;
-
-#ifdef FILE_EXTENSIONS
-    extension = check_extension(old_name, Module_Extension);
-#else
-    extension = "";
-#endif
-
-    return write_translated_name(new_name, old_name,
-               prefix_path, last_value, extension);
-}
-
-static int translate_icl_filename(int last_value,
-    char *new_name, char *old_name)
-{   char *prefix_path = NULL;
-    char *extension = "";
-
-    if (contains_separator(old_name)==0)
-        if (ICL_Path[0]!=0)
-            prefix_path = ICL_Path;
-
-#ifdef FILE_EXTENSIONS
-    extension = check_extension(old_name, ICL_Extension);
-#endif
-
-    return write_translated_name(new_name, old_name,
-               prefix_path, last_value, extension);
-}
-
-extern void translate_out_filename(char *new_name, char *old_name)
-{   char *prefix_path;
-    char *extension = "";
-    int i;
-
-    /* If !convert_filename_flag, then the old_name is just the <file2>
-       parameter on the Inform command line, which we leave alone. */
-
-    if (!convert_filename_flag)
-    {   strcpy(new_name, old_name); return;
-    }
-
-    /* Remove any pathname or extension in <file1>. */
-
-    if (contains_separator(old_name)==1)
-    {   for (i=strlen(old_name)-1; (i>0)&&(old_name[i]!=FN_SEP) ;i--) { };
-        if (old_name[i]==FN_SEP) i++;
-        old_name += i;
-    }
-#ifdef FILE_EXTENSIONS
-    for (i=strlen(old_name)-1; (i>=0)&&(old_name[i]!='.') ;i--) ;
-    if (old_name[i] == '.') old_name[i] = 0;
-#endif
-
-    prefix_path = NULL;
-    if (module_switch)
-    {   extension = Module_Extension;
-        if (Module_Path[0]!=0) prefix_path = Module_Path;
-    }
-    else
-    {
-        if (!glulx_mode) {
-            switch(version_number)
-            {   case 3: extension = Code_Extension;   break;
-                case 4: extension = V4Code_Extension; break;
-                case 5: extension = V5Code_Extension; break;
-                case 6: extension = V6Code_Extension; break;
-                case 7: extension = V7Code_Extension; break;
-                case 8: extension = V8Code_Extension; break;
-            }
-        }
-        else {
-            extension = GlulxCode_Extension;
-        }
-        if (Code_Path[0]!=0) prefix_path = Code_Path;
-    }
-
-#ifdef FILE_EXTENSIONS
-    extension = check_extension(old_name, extension);
-#endif
-
-    write_translated_name(new_name, old_name, prefix_path, 0, extension);
-}
-
-static char *name_or_unset(char *p)
-{   if (p[0]==0) return "(unset)";
-    return p;
-}
-
-static void help_on_filenames(void)
-{   char old_name[PATHLEN];
-    char new_name[PATHLEN];
-    int save_mm = module_switch, x;
-
-    module_switch = FALSE;
-
-    printf("Help information on filenames:\n\n");
-
-    printf(
-"The command line can take one of two forms:\n\n\
-  inform [commands...] <file1>\n\
-  inform [commands...] <file1> <file2>\n\n\
-Inform translates <file1> into a source file name (see below) for its input.\n\
-<file2> is usually omitted: if so, the output filename is made from <file1>\n\
-by cutting out the name part and translating that (see below).\n\
-If <file2> is given, however, the output filename is set to just <file2>\n\
-(not altered in any way).\n\n");
-
-    printf(
-"Filenames given in the game source (with commands like Include \"name\" and\n\
-Link \"name\") are also translated by the rules below.\n\n");
-
-    printf(
-"Rules of translation:\n\n\
-Inform translates plain filenames (such as \"xyzzy\") into full pathnames\n\
-(such as \"adventure%cgames%cxyzzy\") according to the following rules.\n\n\
-1. If the name contains a '%c' character (so it's already a pathname), it\n\
-   isn't changed.\n\n", FN_SEP, FN_SEP, FN_SEP);
-
-    printf(
-"   [Exception: when the name is given in an Include command using the >\n\
-   form (such as Include \">prologue\"), the \">\" is replaced by the path\n\
-   of the file doing the inclusion");
-#ifdef FILE_EXTENSIONS
-                          printf(" and a suitable file extension is added");
-#endif
-    printf(".]\n\n");
-
-    printf(
-"   Filenames must never contain double-quotation marks \".  To use filenames\n\
-   which contain spaces, write them in double-quotes: for instance,\n\n\
-   \"inform +code_path=\"Jigsaw Final Version\" jigsaw\".\n\n");
-
-    printf(
-"2. The file is looked for at a particular \"path\" (the filename of a\n\
-   directory), depending on what kind of file it is.\n\n\
-       File type              Name                Current setting\n\n\
-       Source code (in)       source_path         %s\n\
-       Include file (in)      include_path        %s\n\
-       Story file (out)       code_path           %s\n",
-   name_or_unset(Source_Path), name_or_unset(Include_Path),
-   name_or_unset(Code_Path));
-
-    printf(
-"       Temporary file (out)   temporary_path      %s\n\
-       ICL command file (in)  icl_path            %s\n\
-       Module (in & out)      module_path         %s\n\n",
-   name_or_unset(Temporary_Path),
-   name_or_unset(ICL_Path), name_or_unset(Module_Path));
-
-    printf(
-"   If the path is unset, then the current working directory is used (so\n\
-   the filename doesn't change): if, for instance, include_path is set to\n\
-   \"backup%coldlib\" then when \"parser\" is included it is looked for at\n\
-   \"backup%coldlib%cparser\".\n\n\
-   The paths can be set or unset on the Inform command line by, eg,\n\
-   \"inform +code_path=finished jigsaw\" or\n\
-   \"inform +include_path= balances\" (which unsets include_path).\n\n",
-        FN_SEP, FN_SEP, FN_SEP);
-
-    printf(
-"   The four input path variables can be set to lists of alternative paths\n\
-   separated by '%c' characters: these alternatives are always tried in\n\
-   the order they are specified in, that is, left to right through the text\n\
-   in the path variable.\n\n",
-   FN_ALT);
-    printf(
-"   If two '+' signs are used (\"inform ++include_path=dir jigsaw\") then\n\
-   the path or paths are added to the existing list.\n\n");
-    printf(
-"   (Modules are written to the first alternative in the module_path list;\n\
-   it is an error to give alternatives at all for purely output paths.)\n\n");
-
-#ifdef FILE_EXTENSIONS
-    printf("3. The following file extensions are added:\n\n\
-      Source code:     %s\n\
-      Include files:   %s\n\
-      Story files:     %s (Version 3), %s (v4), %s (v5, the default),\n\
-                       %s (v6), %s (v7), %s (v8), %s (Glulx)\n\
-      Temporary files: .tmp\n\
-      Modules:         %s\n\n",
-      Source_Extension, Include_Extension,
-      Code_Extension, V4Code_Extension, V5Code_Extension, V6Code_Extension,
-      V7Code_Extension, V8Code_Extension, GlulxCode_Extension, 
-      Module_Extension);
-    printf("\
-   except that any extension you give (on the command line or in a filename\n\
-   used in a program) will override these.  If you give the null extension\n\
-   \".\" then Inform uses no file extension at all (removing the \".\").\n\n");
-#endif
-
-    printf("Names of four individual files can also be set using the same\n\
-  + command notation (though they aren't really pathnames).  These are:\n\n\
-      transcript_name  (text written by -r switch): now \"%s\"\n\
-      debugging_name   (data written by -k switch): now \"%s\"\n\
-      language_name    (library file defining natural language of game):\n\
-                       now \"%s\"\n\
-      charset_map      (file for character set mapping): now \"%s\"\n\n",
-    Transcript_Name, Debugging_Name, Language_Name, Charset_Map);
-
-    translate_in_filename(0, new_name, "rezrov", 0, 1);
-    printf("Examples: 1. \"inform rezrov\"\n\
-  the source code is read from \"%s\"\n",
-        new_name);
-    convert_filename_flag = TRUE;
-    translate_out_filename(new_name, "rezrov");
-    printf("  and a story file is compiled to \"%s\".\n\n", new_name);
-
-    translate_in_filename(0, new_name, "frotz", 0, 1);
-    printf("2. \"inform -M frotz\"\n\
-  the source code is read from \"%s\"\n",
-        new_name);
-    module_switch = TRUE;
-    convert_filename_flag = TRUE;
-    translate_out_filename(new_name, "frotz");
-    printf("  and a module is compiled to \"%s\".\n\n", new_name);
-
-    module_switch = FALSE;
-
-    sprintf(old_name, "demos%cplugh", FN_SEP);
-    printf("3. \"inform %s\"\n", old_name);
-    translate_in_filename(0, new_name, old_name, 0, 1);
-    printf("  the source code is read from \"%s\"\n", new_name);
-    sprintf(old_name, "demos%cplugh", FN_SEP);
-    convert_filename_flag = TRUE;
-    translate_out_filename(new_name, old_name);
-    printf("  and a story file is compiled to \"%s\".\n\n", new_name);
-
-    printf("4. \"inform plover my_demo\"\n");
-    translate_in_filename(0, new_name, "plover", 0, 1);
-    printf("  the source code is read from \"%s\"\n", new_name);
-    convert_filename_flag = FALSE;
-    translate_out_filename(new_name, "my_demo");
-    printf("  and a story file is compiled to \"%s\".\n\n", new_name);
-
-    strcpy(old_name, Source_Path);
-    sprintf(new_name, "%cnew%cold%crecent%cold%cancient",
-        FN_ALT, FN_ALT, FN_SEP, FN_ALT, FN_SEP);
-    printf("5. \"inform +source_path=%s zooge\"\n", new_name);
-    printf(
-"   Note that four alternative paths are given, the first being the empty\n\
-   path-name (meaning: where you are now).  Inform looks for the source code\n\
-   by trying these four places in turn, stopping when it finds anything:\n\n");
-
-    set_path_value(Source_Path, new_name);
-    x = 0;
-    do
-    {   x = translate_in_filename(x, new_name, "zooge", 0, 1);
-        printf("     \"%s\"\n", new_name);
-    } while (x != 0);
-    strcpy(Source_Path, old_name);
-    module_switch = save_mm;
-}
-
-/* ------------------------------------------------------------------------- */
-/*  Naming temporary files                                                   */
-/*       (Arguably temporary files should be made using "tmpfile" in         */
-/*        the ANSI C library, but many supposed ANSI libraries lack it.)     */
-/* ------------------------------------------------------------------------- */
-
-extern void translate_temp_filename(int i)
-{   char *p = NULL;
-    switch(i)
-    {   case 1: p=Temp1_Name; break;
-        case 2: p=Temp2_Name; break;
-        case 3: p=Temp3_Name; break;
-    }
-    if (strlen(Temporary_Path)+strlen(Temporary_File)+6 >= PATHLEN) {
-        printf ("Temporary_Path is too long.\n");
-        exit(1);
-    }
-    sprintf(p,"%s%s%d", Temporary_Path, Temporary_File, i);
-#ifdef INCLUDE_TASK_ID
-    sprintf(p+strlen(p), "_proc%08lx", (long int) unique_task_id());
-#endif
-#ifdef FILE_EXTENSIONS
-    sprintf(p+strlen(p), ".tmp");
-#endif
-}
-
-#ifdef ARCHIMEDES
-static char riscos_ft_buffer[4];
-
-extern char *riscos_file_type(void)
-{
-    if (riscos_file_type_format == 1)
-    {   if (module_switch) return("data");
-        return("11A");
-    }
-
-    if (module_switch) return("075");
-
-    sprintf(riscos_ft_buffer, "%03x", 0x60 + version_number);
-    return(riscos_ft_buffer);
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-/*   The compilation pass                                                    */
-/* ------------------------------------------------------------------------- */
-
-static void run_pass(void)
-{
-    lexer_begin_prepass();
-    files_begin_prepass();
-    load_sourcefile(Source_Name, 0);
-
-    begin_pass();
-
-    parse_program(NULL);
-
-    find_the_actions();
-    issue_unused_warnings();
-    compile_veneer();
-
-    lexer_endpass();
-    if (module_switch) linker_endpass();
-
-    close_all_source();
-    if (hash_switch && hash_printed_since_newline) printf("\n");
-
-    if (temporary_files_switch)
-    {   if (module_switch) flush_link_data();
-        check_temp_files();
-    }
-    sort_dictionary();
-    if (track_unused_routines)
-        locate_dead_functions();
-    construct_storyfile();
-}
-
-int output_has_occurred;
-
-static void rennab(int32 time_taken)
-{   /*  rennab = reverse of banner  */
-
-    int t = no_warnings + no_suppressed_warnings;
-
-    if (memout_switch) print_memory_usage();
-
-    if ((no_errors + t)!=0)
-    {   printf("Compiled with ");
-        if (no_errors > 0)
-        {   printf("%d error%s", no_errors,(no_errors==1)?"":"s");
-            if (t > 0) printf(" and ");
-        }
-        if (no_warnings > 0)
-            printf("%d warning%s", t, (t==1)?"":"s");
-        if (no_suppressed_warnings > 0)
-        {   if (no_warnings > 0)
-                printf(" (%d suppressed)", no_suppressed_warnings);
-            else
-            printf("%d suppressed warning%s", no_suppressed_warnings,
-                (no_suppressed_warnings==1)?"":"s");
-        }
-        if (output_has_occurred == FALSE) printf(" (no output)");
-        printf("\n");
-    }
-
-    if (no_compiler_errors > 0) print_sorry_message();
-
-    if (statistics_switch)
-        printf("Completed in %ld seconds\n", (long int) time_taken);
-}
-
-/* ------------------------------------------------------------------------- */
-/*   The compiler abstracted to a routine.                                   */
-/* ------------------------------------------------------------------------- */
-
-static int execute_icl_header(char *file1);
-
-static int compile(int number_of_files_specified, char *file1, char *file2)
-{   int32 time_start;
-
-    if (execute_icl_header(file1))
-      return 1;
-
-    select_target(glulx_mode);
-
-    if (define_INFIX_switch && glulx_mode) {
-        printf("Infix (-X) facilities are not available in Glulx: \
-disabling -X switch\n");
-        define_INFIX_switch = FALSE;
-    }
-
-    if (module_switch && glulx_mode) {
-        printf("Modules are not available in Glulx: \
-disabling -M switch\n");
-        module_switch = FALSE;
-    }
-
-    if (define_INFIX_switch && module_switch)
-    {   printf("Infix (-X) facilities are not available when compiling \
-modules: disabling -X switch\n");
-        define_INFIX_switch = FALSE;
-    }
-    if (runtime_error_checking_switch && module_switch)
-    {   printf("Strict checking (-S) facilities are not available when \
-compiling modules: disabling -S switch\n");
-        runtime_error_checking_switch = FALSE;
-    }
-
-    time_start=time(0); no_compilations++;
-
-    strcpy(Source_Name, file1); convert_filename_flag = TRUE;
-    strcpy(Code_Name, file1);
-    if (number_of_files_specified == 2)
-    {   strcpy(Code_Name, file2); convert_filename_flag = FALSE;
-    }
-
-    init_vars();
-
-    if (debugfile_switch) begin_debug_file();
-
-    allocate_arrays();
-
-    if (transcript_switch) open_transcript_file(Source_Name);
-
-    run_pass();
-
-    if (transcript_switch)
-    {   write_dictionary_to_transcript();
-        close_transcript_file();
-    }
-
-    if (no_errors==0) { output_file(); output_has_occurred = TRUE; }
-    else { output_has_occurred = FALSE; }
-
-    if (debugfile_switch)
-    {   end_debug_file();
-    }
-
-    if (temporary_files_switch && (no_errors>0)) remove_temp_files();
-
-    free_arrays();
-
-    rennab((int32) (time(0)-time_start));
-
-    if (optimise_switch) optimise_abbreviations();
-
-    if (store_the_text) my_free(&all_text,"transcription text");
-
-    return (no_errors==0)?0:1;
-}
-
-/* ------------------------------------------------------------------------- */
-/*   The command line interpreter                                            */
-/* ------------------------------------------------------------------------- */
-
-static void cli_print_help(int help_level)
-{
-    printf(
-"\nThis program is a compiler of Infocom format (also called \"Z-machine\")\n\
-story files: copyright (c) Graham Nelson 1993 - 2017.\n\n");
-
-   /* For people typing just "inform", a summary only: */
-
-   if (help_level==0)
-   {
-
-#ifndef PROMPT_INPUT
-  printf("Usage: \"inform [commands...] <file1> [<file2>]\"\n\n");
-#else
-  printf("When run, Inform prompts you for commands (and switches),\n\
-which are optional, then an input <file1> and an (optional) output\n\
-<file2>.\n\n");
-#endif
-
-  printf(
-"<file1> is the Inform source file of the game to be compiled. <file2>,\n\
-if given, overrides the filename Inform would normally use for the\n\
-compiled output.  Try \"inform -h1\" for file-naming conventions.\n\n\
-One or more words can be supplied as \"commands\". These may be:\n\n\
-  -switches     a list of compiler switches, 1 or 2 letter\n\
-                (see \"inform -h2\" for the full range)\n\n\
-  +dir          set Include_Path to this directory\n\
-  +PATH=dir     change the PATH to this directory\n\n\
-  $...          one of the following memory commands:\n");
-  printf(
-"     $list            list current memory allocation settings\n\
-     $huge            make standard \"huge game\" settings %s\n\
-     $large           make standard \"large game\" settings %s\n\
-     $small           make standard \"small game\" settings %s\n\
-     $?SETTING        explain briefly what SETTING is for\n\
-     $SETTING=number  change SETTING to given number\n\n\
-  (filename)    read in a list of commands (in the format above)\n\
-                from this \"setup file\"\n\n",
-    (DEFAULT_MEMORY_SIZE==HUGE_SIZE)?"(default)":"",
-    (DEFAULT_MEMORY_SIZE==LARGE_SIZE)?"(default)":"",
-    (DEFAULT_MEMORY_SIZE==SMALL_SIZE)?"(default)":"");
-
-#ifndef PROMPT_INPUT
-    printf("For example: \"inform -dexs $huge curses\".\n\n");
-#endif
-
-       return;
-   }
-
-   /* The -h1 (filenaming) help information: */
-
-   if (help_level == 1) { help_on_filenames(); return; }
-
-   /* The -h2 (switches) help information: */
-
-   printf("Help on the full list of legal switch commands:\n\n\
-  a   trace assembly-language (without hex dumps; see -t)\n\
-  c   more concise error messages\n\
-  d   contract double spaces after full stops in text\n\
-  d2  contract double spaces after exclamation and question marks, too\n\
-  e   economy mode (slower): make use of declared abbreviations\n");
-
-   printf("\
-  f   frequencies mode: show how useful abbreviations are\n\
-  g   traces calls to functions (except in the library)\n\
-  g2  traces calls to all functions\n\
-  h   print this information\n");
-
-   printf("\
-  i   ignore default switches set within the file\n\
-  j   list objects as constructed\n\
-  k   output Infix debugging information to \"%s\" (and switch -D on)\n\
-  l   list every statement run through Inform\n\
-  m   say how much memory has been allocated\n\
-  n   print numbers of properties, attributes and actions\n",
-          Debugging_Name);
-   printf("\
-  o   print offset addresses\n\
-  p   give percentage breakdown of story file\n\
-  q   keep quiet about obsolete usages\n\
-  r   record all the text to \"%s\"\n\
-  s   give statistics\n\
-  t   trace assembly-language (with full hex dumps; see -a)\n",
-      Transcript_Name);
-
-   printf("\
-  u   work out most useful abbreviations (very very slowly)\n\
-  v3  compile to version-3 (\"Standard\") story file\n\
-  v4  compile to version-4 (\"Plus\") story file\n\
-  v5  compile to version-5 (\"Advanced\") story file: the default\n\
-  v6  compile to version-6 (graphical) story file\n\
-  v8  compile to version-8 (expanded \"Advanced\") story file\n\
-  w   disable warning messages\n\
-  x   print # for every 100 lines compiled\n\
-  y   trace linking system\n\
-  z   print memory map of the Z-machine\n\n");
-
-printf("\
-  B   use big memory model (for large V6/V7 files)\n\
-  C0  text character set is plain ASCII only\n\
-  Cu  text character set is UTF-8\n\
-  Cn  text character set is ISO 8859-n (n = 1 to 9)\n\
-      (1 to 4, Latin1 to Latin4; 5, Cyrillic; 6, Arabic;\n\
-       7, Greek; 8, Hebrew; 9, Latin5.  Default is -C1.)\n");
-printf("  D   insert \"Constant DEBUG;\" automatically\n");
-printf("  E0  Archimedes-style error messages%s\n",
-      (error_format==0)?" (current setting)":"");
-printf("  E1  Microsoft-style error messages%s\n",
-      (error_format==1)?" (current setting)":"");
-printf("  E2  Macintosh MPW-style error messages%s\n",
-      (error_format==2)?" (current setting)":"");
-#ifdef USE_TEMPORARY_FILES
-printf("  F0  use extra memory rather than temporary files\n");
-#else
-printf("  F1  use temporary files to reduce memory consumption\n");
-#endif
-printf("  G   compile a Glulx game file\n");
-printf("  H   use Huffman encoding to compress Glulx strings\n");
-printf("  M   compile as a Module for future linking\n");
-
-#ifdef ARCHIMEDES
-printf("\
-  R0  use filetype 060 + version number for games (default)\n\
-  R1  use official Acorn filetype 11A for all games\n");
-#endif
-printf("  S   compile strict error-checking at run-time (on by default)\n");
-#ifdef ARC_THROWBACK
-printf("  T   enable throwback of errors in the DDE\n");
-#endif
-printf("  U   insert \"Constant USE_MODULES;\" automatically\n");
-printf("  V   print the version and date of this program\n");
-printf("  Wn  header extension table is at least n words (n = 3 to 99)\n");
-printf("  X   compile with INFIX debugging facilities present\n");
-  printf("\n");
-}
-
-extern void switches(char *p, int cmode)
-{   int i, s=1, state;
-    /* Here cmode is 0 if switches list is from a "Switches" directive
-       and 1 if from a "-switches" command-line or ICL list */
-
-    if (cmode==1)
-    {   if (p[0]!='-')
-        {   printf(
-                "Ignoring second word which should be a -list of switches.\n");
-            return;
-        }
-    }
-    for (i=cmode; p[i]!=0; i+=s, s=1)
-    {   state = TRUE;
-        if (p[i] == '~')
-        {   state = FALSE;
-            i++;
-        }
-        switch(p[i])
-        {
-        case 'a': asm_trace_setting = 1; break;
-        case 'b': bothpasses_switch = state; break;
-        case 'c': concise_switch = state; break;
-        case 'd': switch(p[i+1])
-                  {   case '1': double_space_setting=1; s=2; break;
-                      case '2': double_space_setting=2; s=2; break;
-                      default: double_space_setting=1; break;
-                  }
-                  break;
-        case 'e': economy_switch = state; break;
-        case 'f': frequencies_switch = state; break;
-        case 'g': switch(p[i+1])
-                  {   case '1': trace_fns_setting=1; s=2; break;
-                      case '2': trace_fns_setting=2; s=2; break;
-                      default: trace_fns_setting=1; break;
-                  }
-                  break;
-        case 'h': switch(p[i+1])
-                  {   case '1': cli_print_help(1); s=2; break;
-                      case '2': cli_print_help(2); s=2; break;
-                      case '0': s=2;
-                      default:  cli_print_help(0); break;
-                  }
-                  break;
-        case 'i': ignore_switches_switch = state; break;
-        case 'j': listobjects_switch = state; break;
-        case 'k': if (cmode == 0)
-                      error("The switch '-k' can't be set with 'Switches'");
-                  else
-                  {   debugfile_switch = state;
-                      if (state) define_DEBUG_switch = TRUE;
-                  }
-                  break;
-        case 'l': listing_switch = state; break;
-        case 'm': memout_switch = state; break;
-        case 'n': printprops_switch = state; break;
-        case 'o': offsets_switch = state; break;
-        case 'p': percentages_switch = state; break;
-        case 'q': obsolete_switch = state; break;
-        case 'r': if (cmode == 0)
-                      error("The switch '-r' can't be set with 'Switches'");
-                  else
-                      transcript_switch = state; break;
-        case 's': statistics_switch = state; break;
-        case 't': asm_trace_setting=2; break;
-        case 'u': if (cmode == 0) {
-                      error("The switch '-u' can't be set with 'Switches'");
-                      break;
-                  }
-                  optimise_switch = state; break;
-        case 'v': if (glulx_mode) { s = select_glulx_version(p+i+1)+1; break; }
-                  if ((cmode==0) && (version_set_switch)) { s=2; break; }
-                  version_set_switch = TRUE; s=2;
-                  switch(p[i+1])
-                  {   case '3': select_version(3); break;
-                      case '4': select_version(4); break;
-                      case '5': select_version(5); break;
-                      case '6': select_version(6); break;
-                      case '7': select_version(7); break;
-                      case '8': select_version(8); break;
-                      default:  printf("-v must be followed by 3 to 8\n");
-                                version_set_switch=0; s=1;
-                                break;
-                  }
-                  if ((version_number < 5) && (r_e_c_s_set == FALSE))
-                      runtime_error_checking_switch = FALSE;
-                  break;
-        case 'w': nowarnings_switch = state; break;
-        case 'x': hash_switch = state; break;
-        case 'y': s=2; linker_trace_setting=p[i+1]-'0'; break;
-        case 'z': memory_map_switch = state; break;
-        case 'B': oddeven_packing_switch = state; break;
-        case 'C': s=2;
-                  if (p[i+1] == 'u') {
-                      character_set_unicode = TRUE;
-                      /* Leave the set_setting on Latin-1, because that 
-                         matches the first block of Unicode. */
-                      character_set_setting = 1;
-                  }
-                  else 
-                  {   character_set_setting=p[i+1]-'0';
-                      if ((character_set_setting < 0)
-                          || (character_set_setting > 9))
-                      {   printf("-C must be followed by 'u' or 0 to 9. Defaulting to ISO-8859-1.\n");
-                          character_set_unicode = FALSE;
-                          character_set_setting = 1;
-                      }
-                  }
-                  if (cmode == 0) change_character_set();
-                  break;
-        case 'D': define_DEBUG_switch = state; break;
-        case 'E': switch(p[i+1])
-                  {   case '0': s=2; error_format=0; break;
-                      case '1': s=2; error_format=1; break;
-                      case '2': s=2; error_format=2; break;
-                      default:  error_format=1; break;
-                  }
-                  break;
-        case 'F': if (cmode == 0) {
-                      error("The switch '-F' can't be set with 'Switches'");
-                      break;
-                  }
-                  switch(p[i+1])
-                  {   case '0': s=2; temporary_files_switch = FALSE; break;
-                      case '1': s=2; temporary_files_switch = TRUE; break;
-                      default:  temporary_files_switch = state; break;
-                  }
-                  break;
-        case 'M': module_switch = state;
-                  if (state && (r_e_c_s_set == FALSE))
-                      runtime_error_checking_switch = FALSE;
-                  break;
-#ifdef ARCHIMEDES
-        case 'R': switch(p[i+1])
-                  {   case '0': s=2; riscos_file_type_format=0; break;
-                      case '1': s=2; riscos_file_type_format=1; break;
-                      default:  riscos_file_type_format=1; break;
-                  }
-                  break;
-#endif
-#ifdef ARC_THROWBACK
-        case 'T': throwback_switch = state; break;
-#endif
-        case 'S': runtime_error_checking_switch = state;
-                  r_e_c_s_set = TRUE; break;
-        case 'G': if (cmode == 0)
-                      error("The switch '-G' can't be set with 'Switches'");
-                  else
-                  {   glulx_mode = state;
-                      adjust_memory_sizes();
-                  }
-                  break;
-        case 'H': compression_switch = state; break;
-        case 'U': define_USE_MODULES_switch = state; break;
-        case 'V': exit(0); break;
-        case 'W': if ((p[i+1]>='0') && (p[i+1]<='9'))
-                  {   s=2; ZCODE_HEADER_EXT_WORDS = p[i+1]-'0';
-                      if ((p[i+2]>='0') && (p[i+2]<='9'))
-                      {   s=3; ZCODE_HEADER_EXT_WORDS *= 10;
-                          ZCODE_HEADER_EXT_WORDS += p[i+2]-'0';
-                      }
-                  }
-                  break;
-        case 'X': define_INFIX_switch = state; break;
-        default:
-          printf("Switch \"-%c\" unknown (try \"inform -h2\" for the list)\n",
-              p[i]);
-          break;
-        }
-    }
-
-    if (optimise_switch && (!store_the_text))
-    {   store_the_text=TRUE;
-#ifdef PC_QUICKC
-        if (memout_switch)
-            printf("Allocation %ld bytes for transcription text\n",
-                (long) MAX_TRANSCRIPT_SIZE);
-        all_text = halloc(MAX_TRANSCRIPT_SIZE,1);
-        malloced_bytes += MAX_TRANSCRIPT_SIZE;
-        if (all_text==NULL)
-         fatalerror("Can't hallocate memory for transcription text.  Darn.");
-#else
-        all_text=my_malloc(MAX_TRANSCRIPT_SIZE,"transcription text");
-#endif
-    }
-}
-
-static int icl_command(char *p)
-{   if ((p[0]=='+')||(p[0]=='-')||(p[0]=='$')
-        || ((p[0]=='(')&&(p[strlen(p)-1]==')')) ) return TRUE;
-    return FALSE;
-}
-
-static void icl_error(char *filename, int line)
-{   printf("Error in ICL file '%s', line %d:\n", filename, line);
-}
-
-static void icl_header_error(char *filename, int line)
-{   printf("Error in ICL header of file '%s', line %d:\n", filename, line);
-}
-
-static int copy_icl_word(char *from, char *to, int max)
-{
-    /*  Copies one token from 'from' to 'to', null-terminated:
-        returns the number of chars in 'from' read past (possibly 0).  */
-
-    int i, j, quoted_mode, truncated;
-
-    i = 0; truncated = 0;
-    while ((from[i] == ' ') || (from[i] == TAB_CHARACTER)
-           || (from[i] == (char) 10) || (from[i] == (char) 13)) i++;
-
-    if (from[i] == '!')
-    {   while (from[i] != 0) i++;
-        to[0] = 0; return i;
-    }
-
-    for (quoted_mode = FALSE, j=0;;)
-    {   if (from[i] == 0) break;
-        if (from[i] == 10) break;
-        if (from[i] == 13) break;
-        if (from[i] == TAB_CHARACTER) break;
-        if ((from[i] == ' ') && (!quoted_mode)) break;
-        if (from[i] == '\"') { quoted_mode = !quoted_mode; i++; }
-        else to[j++] = from[i++];
-        if (j == max) {
-            j--;
-            truncated = 1;
-        }
-    }
-    to[j] = 0;
-    if (truncated == 1)
-        printf("The following parameter has been truncated:\n%s\n", to);
-    return i;
-}
-
-static void execute_icl_command(char *p);
-
-static int execute_icl_header(char *argname)
-{
-  FILE *command_file;
-  char cli_buff[256], fw[256];
-  int line = 0;
-  int errcount = 0;
-  int i;
-  char filename[PATHLEN]; 
-  int x = 0;
-
-  do
-    {   x = translate_in_filename(x, filename, argname, 0, 1);
-        command_file = fopen(filename,"r");
-    } while ((command_file == NULL) && (x != 0));
-  if (!command_file) {
-    /* Fail silently. The regular compiler will try to open the file
-       again, and report the problem. */
-    return 0;
-  }
-
-  while (feof(command_file)==0) {
-    if (fgets(cli_buff,256,command_file)==0) break;
-    line++;
-    if (!(cli_buff[0] == '!' && cli_buff[1] == '%'))
-      break;
-    i = copy_icl_word(cli_buff+2, fw, 256);
-    if (icl_command(fw)) {
-      execute_icl_command(fw);
-      copy_icl_word(cli_buff+2 + i, fw, 256);
-      if ((fw[0] != 0) && (fw[0] != '!')) {
-        icl_header_error(filename, line);
-        errcount++;
-        printf("expected comment or nothing but found '%s'\n", fw);
-      }
-    }
-    else {
-      if (fw[0]!=0) {
-        icl_header_error(filename, line);
-        errcount++;
-        printf("Expected command or comment but found '%s'\n", fw);
-      }
-    }
-  }
-  fclose(command_file);
-
-  return (errcount==0)?0:1;
-}
-
-
-static void run_icl_file(char *filename, FILE *command_file)
-{   char cli_buff[256], fw[256];
-    int i, x, line = 0;
-    printf("[Running ICL file '%s']\n", filename);
-
-    while (feof(command_file)==0)
-    {   if (fgets(cli_buff,256,command_file)==0) break;
-        line++;
-        i = copy_icl_word(cli_buff, fw, 256);
-        if (icl_command(fw))
-        {   execute_icl_command(fw);
-            copy_icl_word(cli_buff + i, fw, 256);
-            if ((fw[0] != 0) && (fw[0] != '!'))
-            {   icl_error(filename, line);
-                printf("expected comment or nothing but found '%s'\n", fw);
-            }
-        }
-        else
-        {   if (strcmp(fw, "compile")==0)
-            {   char story_name[PATHLEN], code_name[PATHLEN];
-                i += copy_icl_word(cli_buff + i, story_name, PATHLEN);
-                i += copy_icl_word(cli_buff + i, code_name, PATHLEN);
-
-                if (code_name[0] != 0) x=2;
-                else if (story_name[0] != 0) x=1;
-                else x=0;
-
-                switch(x)
-                {   case 0: icl_error(filename, line);
-                            printf("No filename given to 'compile'\n");
-                            break;
-                    case 1: printf("[Compiling <%s>]\n", story_name);
-                            compile(x, story_name, code_name);
-                            break;
-                    case 2: printf("[Compiling <%s> to <%s>]\n",
-                                story_name, code_name);
-                            compile(x, story_name, code_name);
-                            copy_icl_word(cli_buff + i, fw, 256);
-                            if (fw[0]!=0)
-                            {   icl_error(filename, line);
-                        printf("Expected comment or nothing but found '%s'\n",
-                                fw);
-                            }
-                            break;
-                }
-            }
-            else
-            if (fw[0]!=0)
-            {   icl_error(filename, line);
-                printf("Expected command or comment but found '%s'\n", fw);
-            }
-        }
-    }
-}
-
-static void execute_icl_command(char *p)
-{   char filename[PATHLEN], cli_buff[256];
-    FILE *command_file;
-
-    switch(p[0])
-    {   case '+': set_path_command(p+1); break;
-        case '-': switches(p,1); break;
-        case '$': memory_command(p+1); break;
-        case '(': strcpy(cli_buff,p+1); cli_buff[strlen(cli_buff)-1]=0;
-                  {   int x = 0;
-                      do
-                      {   x = translate_icl_filename(x, filename, cli_buff);
-                          command_file = fopen(filename,"r");
-                      } while ((command_file == NULL) && (x != 0));
-                  }
-                  if (command_file == NULL)
-                      printf("Error in ICL: Couldn't open command file '%s'\n",
-                          filename);
-                  else
-                  {   run_icl_file(filename, command_file);
-                      fclose(command_file);
-                  }
-                  break;
-    }
-}
-
-/* ------------------------------------------------------------------------- */
-/*   Opening and closing banners                                             */
-/* ------------------------------------------------------------------------- */
-
-char banner_line[80];
-
-static void banner(void)
-{
-    sprintf(banner_line, "Inform %d.%d%d",
-        (VNUMBER/100)%10, (VNUMBER/10)%10, VNUMBER%10);
-#ifdef RELEASE_SUFFIX
-    strcat(banner_line, RELEASE_SUFFIX);
-#endif
-#ifdef MACHINE_STRING
-    sprintf(banner_line+strlen(banner_line), " for %s", MACHINE_STRING);
-#endif
-    sprintf(banner_line+strlen(banner_line), " (%s)", RELEASE_DATE);
-    printf("%s\n", banner_line);
-}
-
-/* ------------------------------------------------------------------------- */
-/*   Input from the outside world                                            */
-/* ------------------------------------------------------------------------- */
-
-#ifdef PROMPT_INPUT
-static void read_command_line(int argc, char **argv)
-{   int i;
-    char buffer1[PATHLEN], buffer2[PATHLEN], buffer3[PATHLEN];
-    i=0;
-    printf("Source filename?\n> ");
-    while (gets(buffer1)==NULL); cli_file1=buffer1;
-    printf("Output filename (RETURN for the same)?\n> ");
-    while (gets(buffer2)==NULL); cli_file2=buffer2;
-    cli_files_specified=1;
-    if (buffer2[0]!=0) cli_files_specified=2;
-    do
-    {   printf("List of commands (RETURN to finish; \"-h\" for help)?\n> ");
-        while (gets(buffer3)==NULL); execute_icl_command(buffer3);
-    } while (buffer3[0]!=0);
-}
-#else
-static void read_command_line(int argc, char **argv)
-{   int i;
-    if (argc==1) switches("-h",1);
-
-    for (i=1, cli_files_specified=0; i<argc; i++)
-        if (icl_command(argv[i]))
-            execute_icl_command(argv[i]);
-        else
-            switch(++cli_files_specified)
-            {   case 1: cli_file1 = argv[i]; break;
-                case 2: cli_file2 = argv[i]; break;
-                default:
-                    printf("Command line error: unknown parameter '%s'\n",
-                        argv[i]); return;
-            }
-}
-#endif
-
-/* ------------------------------------------------------------------------- */
-/*   M A I N : An outer shell for machine-specific quirks                    */
-/*   Omitted altogether if EXTERNAL_SHELL is defined, as for instance is     */
-/*   needed for the Macintosh front end.                                     */
-/* ------------------------------------------------------------------------- */
-
-#ifdef EXTERNAL_SHELL
-extern int sub_main(int argc, char **argv);
-#else
-
-static int sub_main(int argc, char **argv);
-#ifdef MAC_MPW
-int main(int argc, char **argv, char *envp[])
-#else
-int main(int argc, char **argv)
-#endif
-{   int rcode;
-#ifdef MAC_MPW
-    InitCursorCtl((acurHandle)NULL); Show_Cursor(WATCH_CURSOR);
-#endif
-    rcode = sub_main(argc, argv);
-#ifdef ARC_THROWBACK
-    throwback_end();
-#endif
-    return rcode;
-}
-
-#endif
-
-/* ------------------------------------------------------------------------- */
-/*   M A I N  II:  Starting up ICL with the command line                     */
-/* ------------------------------------------------------------------------- */
-
-#ifdef EXTERNAL_SHELL
-extern int sub_main(int argc, char **argv)
-#else
-static int sub_main(int argc, char **argv)
-#endif
-{   int return_code;
-
-#ifdef MAC_FACE
-    ProcessEvents (&g_proc);
-    if (g_proc != true)
-    {   free_arrays();
-        if (store_the_text) my_free(&all_text,"transcription text");
-        longjmp (g_fallback, 1);
-    }
-#endif
-
-    banner();
-
-    set_memory_sizes(DEFAULT_MEMORY_SIZE); set_default_paths();
-    reset_switch_settings(); select_version(5);
-
-    cli_files_specified = 0; no_compilations = 0;
-    cli_file1 = "source"; cli_file2 = "output";
-
-    read_command_line(argc, argv);
-
-    if (cli_files_specified > 0)
-    {   return_code = compile(cli_files_specified, cli_file1, cli_file2);
-
-        if (return_code != 0) return(return_code);
-    }
-
-    if (no_compilations == 0)
-        printf("\n[No compilation requested]\n");
-    if (no_compilations > 1)
-        printf("[%d compilations completed]\n", no_compilations);
-
-    return(0);
-}
-
-/* ========================================================================= */