Update to commit e33eef4f8fab800eaf4a32b2d159cde6c4bbb38e
[inform.git] / src / memory.c
index 21dcf57efc10b500d9e95cd0f2988d0dcd2a5e37..a160788d9b51b3195374afa3d7e5c17e6ed2a0a0 100644 (file)
@@ -2,9 +2,8 @@
 /*   "memory" : Memory management and ICL memory setting commands            */
 /*              (For "memoryerror", see "errors.c")                          */
 /*                                                                           */
-/* Copyright (c) Graham Nelson 1993 - 2020                                   */
-/*                                                                           */
-/* This file is part of Inform.                                              */
+/*   Part of Inform 6.35                                                     */
+/*   copyright (c) Graham Nelson 1993 - 2021                                 */
 /*                                                                           */
 /* Inform is free software: you can redistribute it and/or modify            */
 /* it under the terms of the GNU General Public License as published by      */
@@ -17,7 +16,7 @@
 /* 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/                  */
+/* along with Inform. If not, see https://gnu.org/licenses/                  *
 /*                                                                           */
 /* ------------------------------------------------------------------------- */
 
@@ -256,6 +255,7 @@ int MAX_DICT_ENTRIES;
 int MAX_STATIC_DATA;
 int MAX_PROP_TABLE_SIZE;
 int MAX_ABBREVS;
+int MAX_DYNAMIC_STRINGS;
 int MAX_EXPRESSION_NODES;
 int MAX_VERBS;
 int MAX_VERBSPACE;
@@ -288,6 +288,7 @@ int32 MEMORY_MAP_EXTENSION;
 int ALLOC_CHUNK_SIZE;
 int WARN_UNUSED_ROUTINES; /* 0: no, 1: yes except in system files, 2: yes always */
 int OMIT_UNUSED_ROUTINES; /* 0: no, 1: yes */
+int TRANSCRIPT_FORMAT; /* 0: classic, 1: prefixed */
 
 /* The way memory sizes are set causes great nuisance for those parameters
    which have different defaults under Z-code and Glulx. We have to get
@@ -300,6 +301,7 @@ static int MAX_LOCAL_VARIABLES_z, MAX_LOCAL_VARIABLES_g;
 static int DICT_WORD_SIZE_z, DICT_WORD_SIZE_g;
 static int NUM_ATTR_BYTES_z, NUM_ATTR_BYTES_g;
 static int ALLOC_CHUNK_SIZE_z, ALLOC_CHUNK_SIZE_g;
+static int MAX_DYNAMIC_STRINGS_z, MAX_DYNAMIC_STRINGS_g;
 
 /* ------------------------------------------------------------------------- */
 /*   Memory control from the command line                                    */
@@ -320,6 +322,7 @@ static void list_memory_sizes(void)
     printf("|  %25s = %-7d |\n","DICT_WORD_SIZE",DICT_WORD_SIZE);
     if (glulx_mode)
       printf("|  %25s = %-7d |\n","DICT_CHAR_SIZE",DICT_CHAR_SIZE);
+    printf("|  %25s = %-7d |\n","MAX_DYNAMIC_STRINGS",MAX_DYNAMIC_STRINGS);
     printf("|  %25s = %-7d |\n","MAX_EXPRESSION_NODES",MAX_EXPRESSION_NODES);
     printf("|  %25s = %-7d |\n","MAX_GLOBAL_VARIABLES",MAX_GLOBAL_VARIABLES);
     printf("|  %25s = %-7d |\n","HASH_TAB_SIZE",HASH_TAB_SIZE);
@@ -363,6 +366,7 @@ static void list_memory_sizes(void)
            (long int) MAX_STATIC_STRINGS);
     printf("|  %25s = %-7d |\n","MAX_SYMBOLS",MAX_SYMBOLS);
     printf("|  %25s = %-7d |\n","SYMBOLS_CHUNK_SIZE",SYMBOLS_CHUNK_SIZE);
+    printf("|  %25s = %-7d |\n","TRANSCRIPT_FORMAT",TRANSCRIPT_FORMAT);
     printf("|  %25s = %-7ld |\n","MAX_TRANSCRIPT_SIZE",
            (long int) MAX_TRANSCRIPT_SIZE);
     if (glulx_mode)
@@ -397,8 +401,6 @@ extern void set_memory_sizes(int size_flag)
         MAX_PROP_TABLE_SIZE_z = 30000;
         MAX_PROP_TABLE_SIZE_g = 60000;
 
-        MAX_ABBREVS = 64;
-
         MAX_EXPRESSION_NODES = 100;
         MAX_VERBS = 200;
         MAX_VERBSPACE = 4096;
@@ -447,8 +449,6 @@ extern void set_memory_sizes(int size_flag)
         MAX_PROP_TABLE_SIZE_z = 15000;
         MAX_PROP_TABLE_SIZE_g = 30000;
 
-        MAX_ABBREVS = 64;
-
         MAX_EXPRESSION_NODES = 100;
         MAX_VERBS = 140;
         MAX_VERBSPACE = 4096;
@@ -497,8 +497,6 @@ extern void set_memory_sizes(int size_flag)
         MAX_PROP_TABLE_SIZE_z = 8000;
         MAX_PROP_TABLE_SIZE_g = 16000;
 
-        MAX_ABBREVS = 64;
-
         MAX_EXPRESSION_NODES = 40;
         MAX_VERBS = 110;
         MAX_VERBSPACE = 2048;
@@ -540,6 +538,9 @@ extern void set_memory_sizes(int size_flag)
     DICT_WORD_SIZE_g = 9;
     NUM_ATTR_BYTES_z = 6;
     NUM_ATTR_BYTES_g = 7;
+    MAX_ABBREVS = 64;
+    MAX_DYNAMIC_STRINGS_z = 32;
+    MAX_DYNAMIC_STRINGS_g = 64;
     /* Backwards-compatible behavior: allow for a unicode table
        whether we need one or not. The user can set this to zero if
        there's no unicode table. */
@@ -556,6 +557,7 @@ extern void set_memory_sizes(int size_flag)
     MAX_STACK_SIZE = 4096;
     OMIT_UNUSED_ROUTINES = 0;
     WARN_UNUSED_ROUTINES = 0;
+    TRANSCRIPT_FORMAT = 0;
 
     adjust_memory_sizes();
 }
@@ -570,6 +572,7 @@ extern void adjust_memory_sizes()
     DICT_WORD_SIZE = DICT_WORD_SIZE_z;
     NUM_ATTR_BYTES = NUM_ATTR_BYTES_z;
     ALLOC_CHUNK_SIZE = ALLOC_CHUNK_SIZE_z;
+    MAX_DYNAMIC_STRINGS = MAX_DYNAMIC_STRINGS_z;
     INDIV_PROP_START = 64;
   }
   else {
@@ -580,6 +583,7 @@ extern void adjust_memory_sizes()
     DICT_WORD_SIZE = DICT_WORD_SIZE_g;
     NUM_ATTR_BYTES = NUM_ATTR_BYTES_g;
     ALLOC_CHUNK_SIZE = ALLOC_CHUNK_SIZE_g;
+    MAX_DYNAMIC_STRINGS = MAX_DYNAMIC_STRINGS_g;
     INDIV_PROP_START = 256;
   }
 }
@@ -697,7 +701,13 @@ static void explain_parameter(char *command)
     if (strcmp(command,"MAX_ABBREVS")==0)
     {   printf(
 "  MAX_ABBREVS is the maximum number of declared abbreviations.  It is not \n\
-  allowed to exceed 64.\n");
+  allowed to exceed 96 in Z-code.\n");
+        return;
+    }
+    if (strcmp(command,"MAX_DYNAMIC_STRINGS")==0)
+    {   printf(
+"  MAX_DYNAMIC_STRINGS is the maximum number of string substitution variables\n\
+  (\"@00\").  It is not allowed to exceed 96 in Z-code or 100 in Glulx.\n");
         return;
     }
     if (strcmp(command,"MAX_ARRAYS")==0)
@@ -871,6 +881,13 @@ static void explain_parameter(char *command)
   memory after the game file. (Glulx only)\n");
         return;
     }
+    if (strcmp(command,"TRANSCRIPT_FORMAT")==0)
+    {
+        printf(
+"  TRANSCRIPT_FORMAT, if set to 1, adjusts the gametext.txt transcript for \n\
+  easier machine processing; each line will be prefixed by its context.\n");
+        return;
+    }
     if (strcmp(command,"WARN_UNUSED_ROUTINES")==0)
     {
         printf(
@@ -953,6 +970,48 @@ static int parse_memory_setting(char *str, char *label, int32 *result)
     return 1;
 }
 
+static void add_predefined_symbol(char *command)
+{
+    int ix;
+    
+    int value = 0;
+    char *valpos = NULL;
+    
+    for (ix=0; command[ix]; ix++) {
+        if (command[ix] == '=') {
+            valpos = command+(ix+1);
+            command[ix] = '\0';
+            break;
+        }
+    }
+    
+    for (ix=0; command[ix]; ix++) {
+        if ((ix == 0 && isdigit(command[ix]))
+            || !(isalnum(command[ix]) || command[ix] == '_')) {
+            printf("Attempt to define invalid symbol: %s\n", command);
+            return;
+        }
+    }
+
+    if (valpos) {
+        if (!parse_memory_setting(valpos, command, &value)) {
+            return;
+        };
+    }
+
+    add_config_symbol_definition(command, value);
+}
+
+/* Handle a dollar-sign command option: $LIST, $FOO=VAL, and so on.
+   The option may come from the command line, an ICL file, or a header
+   comment.
+
+   (Unix-style command-line options are converted to dollar-sign format
+   before being sent here.)
+
+   The name of this function is outdated. Many of these settings are not
+   really about memory allocation.
+*/
 extern void memory_command(char *command)
 {   int i, k, flag=0; int32 j;
 
@@ -960,6 +1019,7 @@ extern void memory_command(char *command)
         if (islower(command[k])) command[k]=toupper(command[k]);
 
     if (command[0]=='?') { explain_parameter(command+1); return; }
+    if (command[0]=='#') { add_predefined_symbol(command+1); return; }
 
     if (strcmp(command, "HUGE")==0) { set_memory_sizes(HUGE_SIZE); return; }
     if (strcmp(command, "LARGE")==0) { set_memory_sizes(LARGE_SIZE); return; }
@@ -1034,6 +1094,10 @@ extern void memory_command(char *command)
                 flag=2;
             if (strcmp(command,"MAX_ABBREVS")==0)
                 MAX_ABBREVS=j, flag=1;
+            if (strcmp(command,"MAX_DYNAMIC_STRINGS")==0)
+            {   MAX_DYNAMIC_STRINGS=j, flag=1;
+                MAX_DYNAMIC_STRINGS_g=MAX_DYNAMIC_STRINGS_z=j;
+            }
             if (strcmp(command,"MAX_ARRAYS")==0)
                 MAX_ARRAYS=j, flag=1;
             if (strcmp(command,"MAX_EXPRESSION_NODES")==0)
@@ -1103,6 +1167,12 @@ extern void memory_command(char *command)
                 /* Adjust up to a 256-byte boundary. */
                 MEMORY_MAP_EXTENSION = (MEMORY_MAP_EXTENSION + 0xFF) & (~0xFF);
             }
+            if (strcmp(command,"TRANSCRIPT_FORMAT")==0)
+            {
+                TRANSCRIPT_FORMAT=j, flag=1;
+                if (TRANSCRIPT_FORMAT > 1 || TRANSCRIPT_FORMAT < 0)
+                    TRANSCRIPT_FORMAT = 1;
+            }
             if (strcmp(command,"WARN_UNUSED_ROUTINES")==0)
             {
                 WARN_UNUSED_ROUTINES=j, flag=1;