/* ------------------------------------------------------------------------- */
/* "memory" : Memory management and ICL memory setting commands */
-/* (For "memoryerror", see "errors.c") */
/* */
-/* Part of Inform 6.35 */
-/* copyright (c) Graham Nelson 1993 - 2021 */
+/* Part of Inform 6.42 */
+/* copyright (c) Graham Nelson 1993 - 2024 */
/* */
/* Inform is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* 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/ */
/* */
/* ------------------------------------------------------------------------- */
#include "header.h"
-int32 malloced_bytes=0; /* Total amount of memory allocated */
+size_t malloced_bytes=0; /* Total amount of memory allocated */
+
+/* Wrappers for malloc(), realloc(), etc.
+
+ Note that all of these functions call fatalerror_memory_out() on failure.
+ This is a fatal error and does not return. However, we check my_malloc()
+ return values anyway as a matter of good habit.
+ */
#ifdef PC_QUICKC
-extern void *my_malloc(int32 size, char *whatfor)
+extern void *my_malloc(size_t size, char *whatfor)
{ char _huge *c;
if (memout_switch)
printf("Allocating %ld bytes for %s\n",size,whatfor);
if (size==0) return(NULL);
- c=(char _huge *)halloc(size,1); malloced_bytes+=size;
- if (c==0) memory_out_error(size, 1, whatfor);
+ c=(char _huge *)halloc(size,1);
+ malloced_bytes+=size;
+ if (c==0) fatalerror_memory_out(size, 1, whatfor);
return(c);
}
-extern void my_realloc(void *pointer, int32 oldsize, int32 size,
+extern void my_realloc(void *pointer, size_t oldsize, size_t size,
char *whatfor)
{ char _huge *c;
if (size==0) {
my_free(pointer, whatfor);
return;
}
- c=halloc(size,1); malloced_bytes+=size;
- if (c==0) memory_out_error(size, 1, whatfor);
+ c=halloc(size,1);
+ malloced_bytes+=(size-oldsize);
+ if (c==0) fatalerror_memory_out(size, 1, whatfor);
if (memout_switch)
- printf("Increasing allocation to %ld bytes for %s was (%08lx) \
-now (%08lx)\n",
- (long int) size,whatfor,(long int) (*(int **)pointer),
+ printf("Increasing allocation from %ld to %ld bytes for %s was (%08lx) now (%08lx)\n",
+ (long int) oldsize, (long int) size, whatfor,
+ (long int) (*(int **)pointer),
(long int) c);
memcpy(c, *(int **)pointer, MIN(oldsize, size));
hfree(*(int **)pointer);
*(int **)pointer = c;
}
-extern void *my_calloc(int32 size, int32 howmany, char *whatfor)
+extern void *my_calloc(size_t size, size_t howmany, char *whatfor)
{ void _huge *c;
if (memout_switch)
printf("Allocating %d bytes: array (%ld entries size %ld) for %s\n",
size*howmany,howmany,size,whatfor);
if ((size*howmany) == 0) return(NULL);
- c=(void _huge *)halloc(howmany*size,1); malloced_bytes+=size*howmany;
- if (c==0) memory_out_error(size, howmany, whatfor);
+ c=(void _huge *)halloc(howmany*size,1);
+ malloced_bytes+=size*howmany;
+ if (c==0) fatalerror_memory_out(size, howmany, whatfor);
return(c);
}
-extern void my_recalloc(void *pointer, int32 size, int32 oldhowmany,
+extern void my_recalloc(void *pointer, size_t size, size_t oldhowmany,
int32 howmany, char *whatfor)
{ void _huge *c;
if (size*howmany==0) {
my_free(pointer, whatfor);
return;
}
- c=(void _huge *)halloc(size*howmany,1); malloced_bytes+=size*howmany;
- if (c==0) memory_out_error(size, howmany, whatfor);
+ c=(void _huge *)halloc(size*howmany,1);
+ malloced_bytes+=size*(howmany-oldhowmany);
+ if (c==0) fatalerror_memory_out(size, howmany, whatfor);
if (memout_switch)
- printf("Increasing allocation to %ld bytes: array (%ld entries size %ld) \
-for %s was (%08lx) now (%08lx)\n",
+ printf("Increasing allocation from %ld to %ld bytes: array (%ld entries size %ld) for %s was (%08lx) now (%08lx)\n",
+ ((long int)size) * ((long int)oldhowmany),
((long int)size) * ((long int)howmany),
- (long int)howmany,(long int)size,whatfor,
+ (long int)howmany, (long int)size, whatfor,
(long int) *(int **)pointer, (long int) c);
memcpy(c, *(int **)pointer, MIN(size*oldhowmany, size*howmany));
hfree(*(int **)pointer);
#else
-extern void *my_malloc(int32 size, char *whatfor)
+extern void *my_malloc(size_t size, char *whatfor)
{ char *c;
if (size==0) return(NULL);
- c=malloc((size_t) size); malloced_bytes+=size;
- if (c==0) memory_out_error(size, 1, whatfor);
+ c=malloc(size);
+ malloced_bytes+=size;
+ if (c==0) fatalerror_memory_out(size, 1, whatfor);
if (memout_switch)
- printf("Allocating %ld bytes for %s at (%08lx)\n",
- (long int) size,whatfor,(long int) c);
+ printf("Allocating %ld bytes for %s at (%p)\n",
+ (long int) size, whatfor, c);
return(c);
}
-extern void my_realloc(void *pointer, int32 oldsize, int32 size,
+extern void my_realloc(void *pointer, size_t oldsize, size_t size,
char *whatfor)
{ void *c;
if (size==0) {
my_free(pointer, whatfor);
return;
}
- c=realloc(*(int **)pointer, (size_t) size); malloced_bytes+=size;
- if (c==0) memory_out_error(size, 1, whatfor);
+ c=realloc(*(int **)pointer, size);
+ malloced_bytes+=(size-oldsize);
+ if (c==0) fatalerror_memory_out(size, 1, whatfor);
if (memout_switch)
- printf("Increasing allocation to %ld bytes for %s was (%08lx) \
-now (%08lx)\n",
- (long int) size,whatfor,(long int) (*(int **)pointer),
- (long int) c);
+ printf("Increasing allocation from %ld to %ld bytes for %s was (%p) now (%p)\n",
+ (long int) oldsize, (long int) size, whatfor, pointer, c);
*(int **)pointer = c;
}
-extern void *my_calloc(int32 size, int32 howmany, char *whatfor)
+extern void *my_calloc(size_t size, size_t howmany, char *whatfor)
{ void *c;
if (size*howmany==0) return(NULL);
- c=calloc(howmany,(size_t) size); malloced_bytes+=size*howmany;
- if (c==0) memory_out_error(size, howmany, whatfor);
+ c=calloc(howmany, size);
+ malloced_bytes+=size*howmany;
+ if (c==0) fatalerror_memory_out(size, howmany, whatfor);
if (memout_switch)
printf("Allocating %ld bytes: array (%ld entries size %ld) \
-for %s at (%08lx)\n",
+for %s at (%p)\n",
((long int)size) * ((long int)howmany),
- (long int)howmany,(long int)size,whatfor,
- (long int) c);
+ (long int)howmany,(long int)size, whatfor, c);
return(c);
}
-extern void my_recalloc(void *pointer, int32 size, int32 oldhowmany,
- int32 howmany, char *whatfor)
+extern void my_recalloc(void *pointer, size_t size, size_t oldhowmany,
+ size_t howmany, char *whatfor)
{ void *c;
if (size*howmany==0) {
my_free(pointer, whatfor);
return;
}
- c=realloc(*(int **)pointer, (size_t)size*(size_t)howmany);
- malloced_bytes+=size*howmany;
- if (c==0) memory_out_error(size, howmany, whatfor);
+ c=realloc(*(int **)pointer, size*howmany);
+ malloced_bytes+=size*(howmany-oldhowmany);
+ if (c==0) fatalerror_memory_out(size, howmany, whatfor);
if (memout_switch)
- printf("Increasing allocation to %ld bytes: array (%ld entries size %ld) \
-for %s was (%08lx) now (%08lx)\n",
+ printf("Increasing allocation from %ld to %ld bytes: array (%ld entries size %ld) for %s was (%p) now (%p)\n",
+ ((long int)size) * ((long int)oldhowmany),
((long int)size) * ((long int)howmany),
- (long int)howmany,(long int)size,whatfor,
- (long int) *(int **)pointer, (long int) c);
+ (long int)howmany, (long int)size, whatfor,
+ pointer, c);
*(int **)pointer = c;
}
{
if (*(int **)pointer != NULL)
{ if (memout_switch)
- printf("Freeing memory for %s at (%08lx)\n",
- whatitwas, (long int) (*(int **)pointer));
+ printf("Freeing memory for %s at (%p)\n",
+ whatitwas, pointer);
#ifdef PC_QUICKC
hfree(*(int **)pointer);
#else
}
/* ------------------------------------------------------------------------- */
-/* Extensible blocks of memory, providing a kind of RAM disc as an */
-/* alternative to the temporary files option */
+/* A dynamic memory array. This grows as needed (but never shrinks). */
+/* Call ensure_memory_list_available(N) before accessing array item N-1. */
+/* */
+/* whatfor must be a static string describing the list. initalloc is */
+/* (optionally) the number of items to allocate right away. */
/* */
-/* The allocation is slightly confusing. A block can store up to 72 */
-/* chunks, which are allocated as needed when data is written. (Data does */
-/* not have to be written in order, but you should not try to read a byte */
-/* before writing it.) The size of a chunk is defined by ALLOC_CHUNK_SIZE. */
-/* So any block can store any amount of data, but you increase the limit */
-/* (for all blocks) by increasing ALLOC_CHUNK_SIZE, not the number of */
-/* chunks. */
+/* You typically initialise this with extpointer referring to an array of */
+/* structs or whatever type you need. Whenever the memory list grows, the */
+/* external array will be updated to refer to the new data. */
+/* */
+/* Add "#define DEBUG_MEMLISTS" to allocate exactly the number of items */
+/* needed, rather than increasing allocations exponentially. This is very */
+/* slow but it lets us track down array overruns. */
/* ------------------------------------------------------------------------- */
-static char chunk_name_buffer[60];
-static char *chunk_name(memory_block *MB, int no)
-{ char *p = "(unknown)";
- if (MB == &static_strings_area) p = "static strings area";
- if (MB == &zcode_area) p = "Z-code area";
- if (MB == &link_data_area) p = "link data area";
- if (MB == &zcode_backpatch_table) p = "Z-code backpatch table";
- if (MB == &staticarray_backpatch_table) p = "Static array backpatch table";
- if (MB == &zmachine_backpatch_table) p = "Z-machine backpatch table";
- sprintf(chunk_name_buffer, "%s chunk %d", p, no);
- return(chunk_name_buffer);
-}
-
-extern void initialise_memory_block(memory_block *MB)
-{ int i;
- MB->chunks = 0;
- for (i=0; i<72; i++) MB->chunk[i] = NULL;
- MB->extent_of_last = 0;
- MB->write_pos = 0;
+void initialise_memory_list(memory_list *ML, size_t itemsize, size_t initalloc, void **extpointer, char *whatfor)
+{
+ #ifdef DEBUG_MEMLISTS
+ initalloc = 0; /* No initial allocation */
+ #endif
+
+ ML->whatfor = whatfor;
+ ML->itemsize = itemsize;
+ ML->count = 0;
+ ML->data = NULL;
+ ML->extpointer = extpointer;
+
+ if (initalloc) {
+ ML->count = initalloc;
+ ML->data = my_calloc(ML->itemsize, ML->count, ML->whatfor);
+ if (ML->data == NULL) return;
+ }
+
+ if (ML->extpointer)
+ *(ML->extpointer) = ML->data;
}
-extern void deallocate_memory_block(memory_block *MB)
-{ int i;
- for (i=0; i<72; i++)
- if (MB->chunk[i] != NULL)
- my_free(&(MB->chunk[i]), chunk_name(MB, i));
- MB->chunks = 0;
- MB->extent_of_last = 0;
+void deallocate_memory_list(memory_list *ML)
+{
+ ML->itemsize = 0;
+ ML->count = 0;
+
+ if (ML->data)
+ my_free(&(ML->data), ML->whatfor);
+
+ if (ML->extpointer)
+ *(ML->extpointer) = NULL;
+ ML->extpointer = NULL;
}
-extern int read_byte_from_memory_block(memory_block *MB, int32 index)
-{ uchar *p;
- p = MB->chunk[index/ALLOC_CHUNK_SIZE];
- if (p == NULL)
- { compiler_error_named("memory: read from unwritten byte in",
- chunk_name(MB, index/ALLOC_CHUNK_SIZE));
- return 0;
+/* After this is called, at least count items will be available in the list.
+ That is, you can freely access array[0] through array[count-1]. */
+void ensure_memory_list_available(memory_list *ML, size_t count)
+{
+ size_t oldcount;
+
+ if (ML->itemsize == 0) {
+ /* whatfor is also null! */
+ compiler_error("memory: attempt to access uninitialized memory_list");
+ return;
}
- return p[index % ALLOC_CHUNK_SIZE];
-}
-extern void write_byte_to_memory_block(memory_block *MB, int32 index, int value)
-{ uchar *p; int ch = index/ALLOC_CHUNK_SIZE;
- if (ch < 0)
- { compiler_error_named("memory: negative index to", chunk_name(MB, 0));
+ if (ML->count >= count) {
return;
}
- if (ch >= 72) memoryerror("ALLOC_CHUNK_SIZE", ALLOC_CHUNK_SIZE);
- if (MB->chunk[ch] == NULL)
- { int i;
- MB->chunk[ch] = my_malloc(ALLOC_CHUNK_SIZE, chunk_name(MB, ch));
- p = MB->chunk[ch];
- for (i=0; i<ALLOC_CHUNK_SIZE; i++) p[i] = 255;
- }
+ oldcount = ML->count;
+ ML->count = 2*count+8; /* Allow headroom for future growth */
+
+ #ifdef DEBUG_MEMLISTS
+ ML->count = count; /* No headroom */
+ #endif
+
+ if (ML->data == NULL)
+ ML->data = my_calloc(ML->itemsize, ML->count, ML->whatfor);
+ else
+ my_recalloc(&(ML->data), ML->itemsize, oldcount, ML->count, ML->whatfor);
+ if (ML->data == NULL) return;
- p = MB->chunk[ch];
- p[index % ALLOC_CHUNK_SIZE] = value;
+ if (ML->extpointer)
+ *(ML->extpointer) = ML->data;
}
/* ------------------------------------------------------------------------- */
/* Where the memory settings are declared as variables */
/* ------------------------------------------------------------------------- */
-int MAX_QTEXT_SIZE;
-int MAX_SYMBOLS;
-int SYMBOLS_CHUNK_SIZE;
int HASH_TAB_SIZE;
-int MAX_OBJECTS;
-int MAX_ARRAYS;
-int MAX_ACTIONS;
-int MAX_ADJECTIVES;
-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;
-int MAX_LABELS;
-int MAX_LINESPACE;
-int32 MAX_STATIC_STRINGS;
-int32 MAX_ZCODE_SIZE;
-int MAX_LOW_STRINGS;
-int32 MAX_TRANSCRIPT_SIZE;
-int MAX_CLASSES;
-int32 MAX_LINK_DATA_SIZE;
-int MAX_INCLUSION_DEPTH;
-int MAX_SOURCE_FILES;
-int32 MAX_INDIV_PROP_TABLE_SIZE;
-int32 MAX_OBJ_PROP_TABLE_SIZE;
-int MAX_OBJ_PROP_COUNT;
int MAX_LOCAL_VARIABLES;
-int MAX_GLOBAL_VARIABLES;
int DICT_WORD_SIZE; /* number of characters in a dict word */
int DICT_CHAR_SIZE; /* (glulx) 1 for one-byte chars, 4 for Unicode chars */
int DICT_WORD_BYTES; /* DICT_WORD_SIZE*DICT_CHAR_SIZE */
int ZCODE_HEADER_EXT_WORDS; /* (zcode 1.0) requested header extension size */
int ZCODE_HEADER_FLAGS_3; /* (zcode 1.1) value to place in Flags 3 word */
+int ZCODE_LESS_DICT_DATA; /* (zcode) use 2 data bytes per dict word instead of 3 */
+int ZCODE_MAX_INLINE_STRING; /* (zcode) length of string literals that can be inlined */
int NUM_ATTR_BYTES;
int GLULX_OBJECT_EXT_BYTES; /* (glulx) extra bytes for each object record */
-int32 MAX_NUM_STATIC_STRINGS;
-int32 MAX_UNICODE_CHARS;
int32 MAX_STACK_SIZE;
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 STRIP_UNREACHABLE_LABELS; /* 0: no, 1: yes (default) */
+int OMIT_SYMBOL_TABLE; /* 0: no, 1: yes */
+int LONG_DICT_FLAG_BUG; /* 0: no bug, 1: bug (default for historic reasons) */
+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
the defaults right whether the user sets "-G $HUGE" or "$HUGE -G".
And an explicit value set by the user should override both defaults. */
-static int32 MAX_ZCODE_SIZE_z, MAX_ZCODE_SIZE_g;
-static int MAX_PROP_TABLE_SIZE_z, MAX_PROP_TABLE_SIZE_g;
-static int MAX_GLOBAL_VARIABLES_z, MAX_GLOBAL_VARIABLES_g;
-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;
/* ------------------------------------------------------------------------- */
printf("| %25s = %-7s |\n","Memory setting","Value");
printf("+--------------------------------------+\n");
printf("| %25s = %-7d |\n","MAX_ABBREVS",MAX_ABBREVS);
- printf("| %25s = %-7d |\n","MAX_ACTIONS",MAX_ACTIONS);
- printf("| %25s = %-7d |\n","MAX_ADJECTIVES",MAX_ADJECTIVES);
- printf("| %25s = %-7d |\n","ALLOC_CHUNK_SIZE",ALLOC_CHUNK_SIZE);
- printf("| %25s = %-7d |\n","MAX_ARRAYS",MAX_ARRAYS);
printf("| %25s = %-7d |\n","NUM_ATTR_BYTES",NUM_ATTR_BYTES);
- printf("| %25s = %-7d |\n","MAX_CLASSES",MAX_CLASSES);
- printf("| %25s = %-7d |\n","MAX_DICT_ENTRIES",MAX_DICT_ENTRIES);
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);
if (!glulx_mode)
printf("| %25s = %-7d |\n","ZCODE_HEADER_EXT_WORDS",ZCODE_HEADER_EXT_WORDS);
if (!glulx_mode)
printf("| %25s = %-7d |\n","ZCODE_HEADER_FLAGS_3",ZCODE_HEADER_FLAGS_3);
- printf("| %25s = %-7d |\n","MAX_INCLUSION_DEPTH",MAX_INCLUSION_DEPTH);
- printf("| %25s = %-7d |\n","MAX_INDIV_PROP_TABLE_SIZE", MAX_INDIV_PROP_TABLE_SIZE);
+ if (!glulx_mode)
+ printf("| %25s = %-7d |\n","ZCODE_LESS_DICT_DATA",ZCODE_LESS_DICT_DATA);
+ if (!glulx_mode)
+ printf("| %25s = %-7d |\n","ZCODE_MAX_INLINE_STRING",ZCODE_MAX_INLINE_STRING);
printf("| %25s = %-7d |\n","INDIV_PROP_START", INDIV_PROP_START);
- printf("| %25s = %-7d |\n","MAX_LABELS",MAX_LABELS);
- printf("| %25s = %-7d |\n","MAX_LINESPACE",MAX_LINESPACE);
- printf("| %25s = %-7d |\n","MAX_LINK_DATA_SIZE",MAX_LINK_DATA_SIZE);
- if (glulx_mode)
- printf("| %25s = %-7d |\n","MAX_LOCAL_VARIABLES",MAX_LOCAL_VARIABLES);
- printf("| %25s = %-7d |\n","MAX_LOW_STRINGS",MAX_LOW_STRINGS);
if (glulx_mode)
printf("| %25s = %-7d |\n","MEMORY_MAP_EXTENSION",
MEMORY_MAP_EXTENSION);
- if (glulx_mode)
- printf("| %25s = %-7d |\n","MAX_NUM_STATIC_STRINGS",
- MAX_NUM_STATIC_STRINGS);
- printf("| %25s = %-7d |\n","MAX_OBJECTS",MAX_OBJECTS);
if (glulx_mode)
printf("| %25s = %-7d |\n","GLULX_OBJECT_EXT_BYTES",
GLULX_OBJECT_EXT_BYTES);
- if (glulx_mode)
- printf("| %25s = %-7d |\n","MAX_OBJ_PROP_COUNT",
- MAX_OBJ_PROP_COUNT);
- if (glulx_mode)
- printf("| %25s = %-7d |\n","MAX_OBJ_PROP_TABLE_SIZE",
- MAX_OBJ_PROP_TABLE_SIZE);
- printf("| %25s = %-7d |\n","MAX_PROP_TABLE_SIZE",MAX_PROP_TABLE_SIZE);
- printf("| %25s = %-7d |\n","MAX_QTEXT_SIZE",MAX_QTEXT_SIZE);
- printf("| %25s = %-7d |\n","MAX_SOURCE_FILES",MAX_SOURCE_FILES);
if (glulx_mode)
printf("| %25s = %-7ld |\n","MAX_STACK_SIZE",
(long int) MAX_STACK_SIZE);
- printf("| %25s = %-7d |\n","MAX_STATIC_DATA",MAX_STATIC_DATA);
- printf("| %25s = %-7ld |\n","MAX_STATIC_STRINGS",
- (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 = %-7ld |\n","MAX_TRANSCRIPT_SIZE",
- (long int) MAX_TRANSCRIPT_SIZE);
- if (glulx_mode)
- printf("| %25s = %-7ld |\n","MAX_UNICODE_CHARS",
- (long int) MAX_UNICODE_CHARS);
+ printf("| %25s = %-7d |\n","TRANSCRIPT_FORMAT",TRANSCRIPT_FORMAT);
printf("| %25s = %-7d |\n","WARN_UNUSED_ROUTINES",WARN_UNUSED_ROUTINES);
printf("| %25s = %-7d |\n","OMIT_UNUSED_ROUTINES",OMIT_UNUSED_ROUTINES);
- printf("| %25s = %-7d |\n","MAX_VERBS",MAX_VERBS);
- printf("| %25s = %-7d |\n","MAX_VERBSPACE",MAX_VERBSPACE);
- printf("| %25s = %-7ld |\n","MAX_ZCODE_SIZE",
- (long int) MAX_ZCODE_SIZE);
+ printf("| %25s = %-7d |\n","STRIP_UNREACHABLE_LABELS",STRIP_UNREACHABLE_LABELS);
+ printf("| %25s = %-7d |\n","OMIT_SYMBOL_TABLE",OMIT_SYMBOL_TABLE);
+ printf("| %25s = %-7d |\n","LONG_DICT_FLAG_BUG",LONG_DICT_FLAG_BUG);
printf("+--------------------------------------+\n");
}
-extern void set_memory_sizes(int size_flag)
+extern void set_memory_sizes(void)
{
- if (size_flag == HUGE_SIZE)
- {
- MAX_QTEXT_SIZE = 4000;
- MAX_SYMBOLS = 10000;
-
- SYMBOLS_CHUNK_SIZE = 5000;
- HASH_TAB_SIZE = 512;
-
- MAX_OBJECTS = 640;
-
- MAX_ACTIONS = 200;
- MAX_ADJECTIVES = 50;
- MAX_DICT_ENTRIES = 2000;
- MAX_STATIC_DATA = 10000;
-
- MAX_PROP_TABLE_SIZE_z = 30000;
- MAX_PROP_TABLE_SIZE_g = 60000;
-
- MAX_EXPRESSION_NODES = 100;
- MAX_VERBS = 200;
- MAX_VERBSPACE = 4096;
- MAX_LABELS = 1000;
- MAX_LINESPACE = 16000;
-
- MAX_STATIC_STRINGS = 8000;
- MAX_ZCODE_SIZE_z = 20000;
- MAX_ZCODE_SIZE_g = 40000;
- MAX_LINK_DATA_SIZE = 2000;
-
- MAX_LOW_STRINGS = 2048;
-
- MAX_TRANSCRIPT_SIZE = 200000;
- MAX_NUM_STATIC_STRINGS = 20000;
-
- MAX_CLASSES = 64;
-
- MAX_OBJ_PROP_COUNT = 128;
- MAX_OBJ_PROP_TABLE_SIZE = 4096;
-
- MAX_INDIV_PROP_TABLE_SIZE = 15000;
- MAX_ARRAYS = 128;
-
- MAX_GLOBAL_VARIABLES_z = 240;
- MAX_GLOBAL_VARIABLES_g = 512;
-
- ALLOC_CHUNK_SIZE_z = 8192;
- ALLOC_CHUNK_SIZE_g = 32768;
- }
- if (size_flag == LARGE_SIZE)
- {
- MAX_QTEXT_SIZE = 4000;
- MAX_SYMBOLS = 6400;
-
- SYMBOLS_CHUNK_SIZE = 5000;
- HASH_TAB_SIZE = 512;
-
- MAX_OBJECTS = 512;
-
- MAX_ACTIONS = 200;
- MAX_ADJECTIVES = 50;
- MAX_DICT_ENTRIES = 1300;
- MAX_STATIC_DATA = 10000;
-
- MAX_PROP_TABLE_SIZE_z = 15000;
- MAX_PROP_TABLE_SIZE_g = 30000;
-
- MAX_EXPRESSION_NODES = 100;
- MAX_VERBS = 140;
- MAX_VERBSPACE = 4096;
- MAX_LINESPACE = 10000;
-
- MAX_LABELS = 1000;
- MAX_STATIC_STRINGS = 8000;
- MAX_ZCODE_SIZE_z = 20000;
- MAX_ZCODE_SIZE_g = 40000;
- MAX_LINK_DATA_SIZE = 2000;
-
- MAX_LOW_STRINGS = 2048;
-
- MAX_TRANSCRIPT_SIZE = 200000;
- MAX_NUM_STATIC_STRINGS = 20000;
-
- MAX_CLASSES = 64;
-
- MAX_OBJ_PROP_COUNT = 64;
- MAX_OBJ_PROP_TABLE_SIZE = 2048;
-
- MAX_INDIV_PROP_TABLE_SIZE = 10000;
- MAX_ARRAYS = 128;
-
- MAX_GLOBAL_VARIABLES_z = 240;
- MAX_GLOBAL_VARIABLES_g = 512;
-
- ALLOC_CHUNK_SIZE_z = 8192;
- ALLOC_CHUNK_SIZE_g = 16384;
- }
- if (size_flag == SMALL_SIZE)
- {
- MAX_QTEXT_SIZE = 4000;
- MAX_SYMBOLS = 3000;
-
- SYMBOLS_CHUNK_SIZE = 2500;
- HASH_TAB_SIZE = 512;
-
- MAX_OBJECTS = 300;
-
- MAX_ACTIONS = 200;
- MAX_ADJECTIVES = 50;
- MAX_DICT_ENTRIES = 700;
- MAX_STATIC_DATA = 10000;
-
- MAX_PROP_TABLE_SIZE_z = 8000;
- MAX_PROP_TABLE_SIZE_g = 16000;
-
- MAX_EXPRESSION_NODES = 40;
- MAX_VERBS = 110;
- MAX_VERBSPACE = 2048;
- MAX_LINESPACE = 10000;
- MAX_LABELS = 1000;
-
- MAX_STATIC_STRINGS = 8000;
- MAX_ZCODE_SIZE_z = 10000;
- MAX_ZCODE_SIZE_g = 20000;
- MAX_LINK_DATA_SIZE = 1000;
-
- MAX_LOW_STRINGS = 1024;
-
- MAX_TRANSCRIPT_SIZE = 100000;
- MAX_NUM_STATIC_STRINGS = 10000;
-
- MAX_CLASSES = 32;
-
- MAX_OBJ_PROP_COUNT = 64;
- MAX_OBJ_PROP_TABLE_SIZE = 1024;
-
- MAX_INDIV_PROP_TABLE_SIZE = 5000;
- MAX_ARRAYS = 64;
-
- MAX_GLOBAL_VARIABLES_z = 240;
- MAX_GLOBAL_VARIABLES_g = 256;
-
- ALLOC_CHUNK_SIZE_z = 8192;
- ALLOC_CHUNK_SIZE_g = 8192;
- }
-
- /* Regardless of size_flag... */
- MAX_SOURCE_FILES = 256;
- MAX_INCLUSION_DEPTH = 5;
- MAX_LOCAL_VARIABLES_z = 16;
- MAX_LOCAL_VARIABLES_g = 32;
+ HASH_TAB_SIZE = 512;
DICT_CHAR_SIZE = 1;
DICT_WORD_SIZE_z = 6;
DICT_WORD_SIZE_g = 9;
NUM_ATTR_BYTES_g = 7;
MAX_ABBREVS = 64;
MAX_DYNAMIC_STRINGS_z = 32;
- MAX_DYNAMIC_STRINGS_g = 64;
+ MAX_DYNAMIC_STRINGS_g = 100;
/* 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. */
ZCODE_HEADER_EXT_WORDS = 3;
ZCODE_HEADER_FLAGS_3 = 0;
+ ZCODE_LESS_DICT_DATA = 0;
+ ZCODE_MAX_INLINE_STRING = 32;
GLULX_OBJECT_EXT_BYTES = 0;
- MAX_UNICODE_CHARS = 64;
MEMORY_MAP_EXTENSION = 0;
/* We estimate the default Glulx stack size at 4096. That's about
enough for 90 nested function calls with 8 locals each -- the
MAX_STACK_SIZE = 4096;
OMIT_UNUSED_ROUTINES = 0;
WARN_UNUSED_ROUTINES = 0;
+ STRIP_UNREACHABLE_LABELS = 1;
+ OMIT_SYMBOL_TABLE = 0;
+ LONG_DICT_FLAG_BUG = 1;
+ TRANSCRIPT_FORMAT = 0;
adjust_memory_sizes();
}
extern void adjust_memory_sizes()
{
if (!glulx_mode) {
- MAX_ZCODE_SIZE = MAX_ZCODE_SIZE_z;
- MAX_PROP_TABLE_SIZE = MAX_PROP_TABLE_SIZE_z;
- MAX_GLOBAL_VARIABLES = MAX_GLOBAL_VARIABLES_z;
- MAX_LOCAL_VARIABLES = MAX_LOCAL_VARIABLES_z;
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 {
- MAX_ZCODE_SIZE = MAX_ZCODE_SIZE_g;
- MAX_PROP_TABLE_SIZE = MAX_PROP_TABLE_SIZE_g;
- MAX_GLOBAL_VARIABLES = MAX_GLOBAL_VARIABLES_g;
- MAX_LOCAL_VARIABLES = MAX_LOCAL_VARIABLES_g;
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;
}
static void explain_parameter(char *command)
{ printf("\n");
- if (strcmp(command,"MAX_QTEXT_SIZE")==0)
- { printf(
-" MAX_QTEXT_SIZE is the maximum length of a quoted string. Increasing\n\
- by 1 costs 5 bytes (for lexical analysis memory). Inform automatically\n\
- ensures that MAX_STATIC_STRINGS is at least twice the size of this.");
- return;
- }
- if (strcmp(command,"MAX_SYMBOLS")==0)
- { printf(
-" MAX_SYMBOLS is the maximum number of symbols - names of variables, \n\
- objects, routines, the many internal Inform-generated names and so on.\n");
- return;
- }
- if (strcmp(command,"SYMBOLS_CHUNK_SIZE")==0)
- { printf(
-" The symbols names are stored in memory which is allocated in chunks \n\
- of size SYMBOLS_CHUNK_SIZE.\n");
- return;
- }
if (strcmp(command,"HASH_TAB_SIZE")==0)
{ printf(
" HASH_TAB_SIZE is the size of the hash tables used for the heaviest \n\
symbols banks.\n");
return;
}
- if (strcmp(command,"MAX_OBJECTS")==0)
- { printf(
-" MAX_OBJECTS is the maximum number of objects. (If compiling a version-3 \n\
- game, 255 is an absolute maximum in any event.)\n");
- return;
- }
- if (strcmp(command,"MAX_ACTIONS")==0)
- { printf(
-" MAX_ACTIONS is the maximum number of actions - that is, routines such as \n\
- TakeSub which are referenced in the grammar table.\n");
- return;
- }
- if (strcmp(command,"MAX_ADJECTIVES")==0)
- { printf(
-" MAX_ADJECTIVES is the maximum number of different \"adjectives\" in the \n\
- grammar table. Adjectives are misleadingly named: they are words such as \n\
- \"in\", \"under\" and the like.\n");
- return;
- }
- if (strcmp(command,"MAX_DICT_ENTRIES")==0)
- { printf(
-" MAX_DICT_ENTRIES is the maximum number of words which can be entered \n\
- into the game's dictionary. It costs 29 bytes to increase this by one.\n");
- return;
- }
if (strcmp(command,"DICT_WORD_SIZE")==0)
{ printf(
" DICT_WORD_SIZE is the number of characters in a dictionary word. In \n\
header extension table (Z-Spec 1.1).\n");
return;
}
- if (strcmp(command,"GLULX_OBJECT_EXT_BYTES")==0)
+ if (strcmp(command,"ZCODE_LESS_DICT_DATA")==0)
{ printf(
-" GLULX_OBJECT_EXT_BYTES is an amount of additional space to add to each \n\
- object record. It is initialized to zero bytes, and the game is free to \n\
- use it as desired. (This is only meaningful in Glulx, since Z-code \n\
- specifies the object structure.)\n");
+" ZCODE_LESS_DICT_DATA, if set, provides each dict word with two data bytes\n\
+ rather than three. (Z-code only.)\n");
return;
}
- if (strcmp(command,"MAX_STATIC_DATA")==0)
+ if (strcmp(command,"ZCODE_MAX_INLINE_STRING")==0)
{ printf(
-" MAX_STATIC_DATA is the size of an array of integers holding initial \n\
- values for arrays and strings stored as ASCII inside the Z-machine. It \n\
- should be at least 1024 but seldom needs much more.\n");
+" ZCODE_MAX_INLINE_STRING is the length beyond which string literals cannot\n\
+ be inlined in assembly opcodes. (Z-code only.)\n");
return;
}
- if (strcmp(command,"MAX_PROP_TABLE_SIZE")==0)
+ if (strcmp(command,"GLULX_OBJECT_EXT_BYTES")==0)
{ printf(
-" MAX_PROP_TABLE_SIZE is the number of bytes allocated to hold the \n\
- properties table.\n");
+" GLULX_OBJECT_EXT_BYTES is an amount of additional space to add to each \n\
+ object record. It is initialized to zero bytes, and the game is free to \n\
+ use it as desired. (This is only meaningful in Glulx, since Z-code \n\
+ specifies the object structure.)\n");
return;
}
if (strcmp(command,"MAX_ABBREVS")==0)
{ printf(
" MAX_ABBREVS is the maximum number of declared abbreviations. It is not \n\
- allowed to exceed 96 in Z-code.\n");
+ allowed to exceed 96 in Z-code. (This is not meaningful in Glulx, where \n\
+ there is no limit on abbreviations.)\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)
- { printf(
-" MAX_ARRAYS is the maximum number of declared arrays.\n");
- return;
- }
- if (strcmp(command,"MAX_EXPRESSION_NODES")==0)
- { printf(
-" MAX_EXPRESSION_NODES is the maximum number of nodes in the expression \n\
- evaluator's storage for parse trees. In effect, it measures how \n\
- complicated algebraic expressions are allowed to be. Increasing it by \n\
- one costs about 80 bytes.\n");
- return;
- }
- if (strcmp(command,"MAX_VERBS")==0)
- { printf(
-" MAX_VERBS is the maximum number of verbs (such as \"take\") which can be \n\
- defined, each with its own grammar. To increase it by one costs about\n\
- 128 bytes. A full game will contain at least 100.\n");
- return;
- }
- if (strcmp(command,"MAX_VERBSPACE")==0)
- { printf(
-" MAX_VERBSPACE is the size of workspace used to store verb words, so may\n\
- need increasing in games with many synonyms: unlikely to exceed 4K.\n");
- return;
- }
- if (strcmp(command,"MAX_LABELS")==0)
- { printf(
-" MAX_LABELS is the maximum number of label points in any one routine.\n\
- (If the -k debugging information switch is set, MAX_LABELS is raised to\n\
- a minimum level of 2000, as about twice the normal number of label points\n\
- are needed to generate tables of how source code corresponds to positions\n\
- in compiled code.)");
- return;
- }
- if (strcmp(command,"MAX_LINESPACE")==0)
- { printf(
-" MAX_LINESPACE is the size of workspace used to store grammar lines, so \n\
- may need increasing in games with complex or extensive grammars.\n");
- return;
- }
- if (strcmp(command,"MAX_STATIC_STRINGS")==0)
- {
- printf(
-" MAX_STATIC_STRINGS is the size in bytes of a buffer to hold compiled\n\
- strings before they're written into longer-term storage. 2000 bytes is \n\
- plenty, allowing string constants of up to about 3000 characters long.\n\
- Inform automatically ensures that this is at least twice the size of\n\
- MAX_QTEXT_SIZE, to be on the safe side.");
- return;
- }
- if (strcmp(command,"MAX_ZCODE_SIZE")==0)
- {
- printf(
-" MAX_ZCODE_SIZE is the size in bytes of a buffer to hold compiled \n\
- code for a single routine. (It applies to both Z-code and Glulx, \n\
- despite the name.) As a guide, the longest library routine is \n\
- about 6500 bytes long in Z-code; about twice that in Glulx.");
- return;
- }
- if (strcmp(command,"MAX_LINK_DATA_SIZE")==0)
- {
- printf(
-" MAX_LINK_DATA_SIZE is the size in bytes of a buffer to hold module \n\
- link data before it's written into longer-term storage. 2000 bytes \n\
- is plenty.");
- return;
- }
- if (strcmp(command,"MAX_LOW_STRINGS")==0)
- { printf(
-" MAX_LOW_STRINGS is the size in bytes of a buffer to hold all the \n\
- compiled \"low strings\" which are to be written above the synonyms table \n\
- in the Z-machine. 1024 is plenty.\n");
- return;
- }
- if (strcmp(command,"MAX_TRANSCRIPT_SIZE")==0)
- { printf(
-" MAX_TRANSCRIPT_SIZE is only allocated for the abbreviations optimisation \n\
- switch, and has the size in bytes of a buffer to hold the entire text of\n\
- the game being compiled: it has to be enormous, say 100000 to 200000.\n");
- return;
- }
- if (strcmp(command,"MAX_CLASSES")==0)
- { printf(
-" MAX_CLASSES maximum number of object classes which can be defined. This\n\
- is cheap to increase.\n");
- return;
- }
- if (strcmp(command,"MAX_INCLUSION_DEPTH")==0)
- { printf(
-" MAX_INCLUSION_DEPTH is the number of nested includes permitted.\n");
- return;
- }
- if (strcmp(command,"MAX_SOURCE_FILES")==0)
- { printf(
-" MAX_SOURCE_FILES is the number of source files that can be read in the \n\
- compilation.\n");
- return;
- }
- if (strcmp(command,"MAX_INDIV_PROP_TABLE_SIZE")==0)
- { printf(
-" MAX_INDIV_PROP_TABLE_SIZE is the number of bytes allocated to hold the \n\
- table of ..variable values.\n");
+ (\"@00\" or \"@(0)\"). It is not allowed to exceed 96 in Z-code.\n");
return;
}
if (strcmp(command,"INDIV_PROP_START")==0)
properties are numbered INDIV_PROP_START and up.\n");
return;
}
- if (strcmp(command,"MAX_OBJ_PROP_COUNT")==0)
- { printf(
-" MAX_OBJ_PROP_COUNT is the maximum number of properties a single object \n\
- can have. (Glulx only)\n");
- return;
- }
- if (strcmp(command,"MAX_OBJ_PROP_TABLE_SIZE")==0)
- { printf(
-" MAX_OBJ_PROP_TABLE_SIZE is the number of words allocated to hold a \n\
- single object's properties. (Glulx only)\n");
- return;
- }
- if (strcmp(command,"MAX_LOCAL_VARIABLES")==0)
- { printf(
-" MAX_LOCAL_VARIABLES is the number of local variables (including \n\
- arguments) allowed in a procedure. (Glulx only)\n");
- return;
- }
- if (strcmp(command,"MAX_GLOBAL_VARIABLES")==0)
- { printf(
-" MAX_GLOBAL_VARIABLES is the number of global variables allowed in the \n\
- program. (Glulx only)\n");
- return;
- }
- if (strcmp(command,"MAX_NUM_STATIC_STRINGS")==0)
- {
- printf(
-" MAX_NUM_STATIC_STRINGS is the maximum number of compiled strings \n\
- allowed in the program. (Glulx only)\n");
- return;
- }
- if (strcmp(command,"MAX_UNICODE_CHARS")==0)
- {
- printf(
-" MAX_UNICODE_CHARS is the maximum number of different Unicode characters \n\
- (beyond the Latin-1 range, $00..$FF) which the game text can use. \n\
- (Glulx only)\n");
- return;
- }
- if (strcmp(command,"ALLOC_CHUNK_SIZE")==0)
- {
- printf(
-" ALLOC_CHUNK_SIZE is a base unit of Inform's internal memory allocation \n\
- for various structures.\n");
- return;
- }
if (strcmp(command,"MAX_STACK_SIZE")==0)
{
printf(
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(
into the game file.\n");
return;
}
+ if (strcmp(command,"STRIP_UNREACHABLE_LABELS")==0)
+ {
+ printf(
+" STRIP_UNREACHABLE_LABELS, if set to 1, will skip labels in unreachable \n\
+ statements. Jumping to a skipped label is an error. If 0, all labels \n\
+ will be compiled, at the cost of less optimized code. The default is 1.\n");
+ return;
+ }
+ if (strcmp(command,"OMIT_SYMBOL_TABLE")==0)
+ {
+ printf(
+" OMIT_SYMBOL_TABLE, if set to 1, will skip compiling debug symbol names \n\
+ into the game file.\n");
+ return;
+ }
+ if (strcmp(command,"LONG_DICT_FLAG_BUG")==0)
+ {
+ printf(
+" LONG_DICT_FLAG_BUG, if set to 0, will fix the old bug which ignores \n\
+ the '//p' flag in long dictionary words. If 1, the buggy behavior is \n\
+ retained.\n");
+ return;
+ }
if (strcmp(command,"SERIAL")==0)
{
printf(
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);
+}
+
+static void set_trace_option(char *command)
+{
+ char *cx;
+ int value;
+
+ /* Parse options of the form STRING or STRING=NUM. (The $! has already been eaten.) If the string is null or empty, show help. */
+
+ if (!command || *command == '\0') {
+ printf("The full list of trace options:\n\n");
+ printf(" ACTIONS: show actions defined\n");
+ printf(" ASM: trace assembly (same as -a)\n");
+ printf(" ASM=2: also show hex dumps\n");
+ printf(" ASM=3: also show branch optimization info\n");
+ printf(" ASM=4: more verbose branch info\n");
+ printf(" BPATCH: show backpatch results\n");
+ printf(" BPATCH=2: also show markers added\n");
+ printf(" DICT: display the dictionary table\n");
+ printf(" DICT=2: also the byte encoding of entries\n");
+ printf(" EXPR: show expression trees\n");
+ printf(" EXPR=2: more verbose\n");
+ printf(" EXPR=3: even more verbose\n");
+ printf(" FILES: show files opened\n");
+ printf(" FINDABBREVS: show selection decisions during abbreviation optimization\n (only meaningful with -u)\n");
+ printf(" FINDABBREVS=2: also show three-letter-block decisions\n");
+ printf(" FREQ: show how efficient abbreviations were (same as -f)\n (only meaningful with -e)\n");
+ printf(" MAP: print memory map of the virtual machine (same as -z)\n");
+ printf(" MAP=2: also show percentage of VM that each segment occupies\n");
+ printf(" MAP=3: also show number of bytes that each segment occupies\n");
+ printf(" MEM: show internal memory allocations\n");
+ printf(" OBJECTS: display the object table\n");
+ printf(" PROPS: show attributes and properties defined\n");
+ printf(" RUNTIME: show game function calls at runtime (same as -g)\n");
+ printf(" RUNTIME=2: also show library calls (not supported in Glulx)\n");
+ printf(" RUNTIME=3: also show veneer calls (not supported in Glulx)\n");
+ printf(" STATS: give compilation statistics (same as -s)\n");
+ printf(" SYMBOLS: display the symbol table\n");
+ printf(" SYMBOLS=2: also show compiler-defined symbols\n");
+ printf(" SYMDEF: show when symbols are noticed and defined\n");
+ printf(" TOKENS: show token lexing\n");
+ printf(" TOKENS=2: also show token types\n");
+ printf(" TOKENS=3: also show lexical context\n");
+ printf(" VERBS: display the verb grammar table\n");
+ return;
+ }
+
+ for (cx=command; *cx && *cx != '='; cx++) {
+ if (!(*cx >= 'A' && *cx <= 'Z')) {
+ printf("Invalid $! trace command \"%s\"\n", command);
+ return;
+ }
+ }
+
+ value = 1;
+ if (*cx == '=') {
+ char *ex;
+ value = strtol(cx+1, &ex, 10);
+
+ if (ex == cx+1 || *ex != '\0' || value < 0) {
+ printf("Bad numerical setting in $! trace command \"%s\"\n", command);
+ return;
+ }
+
+ *cx = '\0';
+ }
+
+ /* We accept some reasonable synonyms, including plausible singular/plural confusion. */
+
+ if (strcmp(command, "ASSEMBLY")==0 || strcmp(command, "ASM")==0) {
+ asm_trace_setting = value;
+ }
+ else if (strcmp(command, "ACTION")==0 || strcmp(command, "ACTIONS")==0) {
+ printactions_switch = value;
+ }
+ else if (strcmp(command, "BPATCH")==0 || strcmp(command, "BACKPATCH")==0) {
+ bpatch_trace_setting = value;
+ }
+ else if (strcmp(command, "DICTIONARY")==0 || strcmp(command, "DICT")==0) {
+ list_dict_setting = value;
+ }
+ else if (strcmp(command, "EXPR")==0 || strcmp(command, "EXPRESSION")==0 || strcmp(command, "EXPRESSIONS")==0) {
+ expr_trace_setting = value;
+ }
+ else if (strcmp(command, "FILE")==0 || strcmp(command, "FILES")==0) {
+ files_trace_setting = value;
+ }
+ else if (strcmp(command, "FINDABBREV")==0 || strcmp(command, "FINDABBREVS")==0) {
+ optabbrevs_trace_setting = value;
+ }
+ else if (strcmp(command, "FREQUENCY")==0 || strcmp(command, "FREQUENCIES")==0 || strcmp(command, "FREQ")==0) {
+ frequencies_setting = value;
+ }
+ else if (strcmp(command, "MAP")==0) {
+ memory_map_setting = value;
+ }
+ else if (strcmp(command, "MEM")==0 || strcmp(command, "MEMORY")==0) {
+ memout_switch = value;
+ }
+ else if (strcmp(command, "OBJECTS")==0 || strcmp(command, "OBJECT")==0 || strcmp(command, "OBJS")==0 || strcmp(command, "OBJ")==0) {
+ list_objects_setting = value;
+ }
+ else if (strcmp(command, "PROP")==0 || strcmp(command, "PROPERTY")==0 || strcmp(command, "PROPS")==0 || strcmp(command, "PROPERTIES")==0) {
+ printprops_switch = value;
+ }
+ else if (strcmp(command, "RUNTIME")==0) {
+ trace_fns_setting = value;
+ }
+ else if (strcmp(command, "STATISTICS")==0 || strcmp(command, "STATS")==0 || strcmp(command, "STAT")==0) {
+ statistics_switch = value;
+ }
+ else if (strcmp(command, "SYMBOLS")==0 || strcmp(command, "SYMBOL")==0) {
+ list_symbols_setting = value;
+ }
+ else if (strcmp(command, "SYMDEF")==0 || strcmp(command, "SYMBOLDEF")==0) {
+ symdef_trace_setting = value;
+ }
+ else if (strcmp(command, "TOKEN")==0 || strcmp(command, "TOKENS")==0) {
+ tokens_trace_setting = value;
+ }
+ else if (strcmp(command, "VERBS")==0 || strcmp(command, "VERB")==0) {
+ list_verbs_setting = value;
+ }
+ else {
+ printf("Unrecognized $! trace command \"%s\"\n", command);
+ }
+}
+
+/* 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;
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 (command[0]=='!') { set_trace_option(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; }
- if (strcmp(command, "SMALL")==0) { set_memory_sizes(SMALL_SIZE); return; }
+ if (strcmp(command, "HUGE")==0
+ || strcmp(command, "LARGE")==0
+ || strcmp(command, "SMALL")==0) {
+ if (!nowarnings_switch)
+ printf("The Inform 6 memory size commands (\"SMALL, LARGE, HUGE\") are no longer needed and has been withdrawn.\n");
+ return;
+ }
+
if (strcmp(command, "LIST")==0) { list_memory_sizes(); return; }
+
for (i=0; command[i]!=0; i++)
{ if (command[i]=='=')
{ command[i]=0;
if (strcmp(command,"BUFFER_LENGTH")==0)
flag=2;
if (strcmp(command,"MAX_QTEXT_SIZE")==0)
- { MAX_QTEXT_SIZE=j, flag=1;
- if (2*MAX_QTEXT_SIZE > MAX_STATIC_STRINGS)
- MAX_STATIC_STRINGS = 2*MAX_QTEXT_SIZE;
- }
+ flag=3;
if (strcmp(command,"MAX_SYMBOLS")==0)
- MAX_SYMBOLS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_BANK_SIZE")==0)
flag=2;
if (strcmp(command,"SYMBOLS_CHUNK_SIZE")==0)
- SYMBOLS_CHUNK_SIZE=j, flag=1;
+ flag=3;
if (strcmp(command,"BANK_CHUNK_SIZE")==0)
flag=2;
if (strcmp(command,"HASH_TAB_SIZE")==0)
HASH_TAB_SIZE=j, flag=1;
if (strcmp(command,"MAX_OBJECTS")==0)
- MAX_OBJECTS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_ACTIONS")==0)
- MAX_ACTIONS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_ADJECTIVES")==0)
- MAX_ADJECTIVES=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_DICT_ENTRIES")==0)
- MAX_DICT_ENTRIES=j, flag=1;
+ flag=3;
if (strcmp(command,"DICT_WORD_SIZE")==0)
{ DICT_WORD_SIZE=j, flag=1;
DICT_WORD_SIZE_g=DICT_WORD_SIZE_z=j;
ZCODE_HEADER_EXT_WORDS=j, flag=1;
if (strcmp(command,"ZCODE_HEADER_FLAGS_3")==0)
ZCODE_HEADER_FLAGS_3=j, flag=1;
+ if (strcmp(command,"ZCODE_LESS_DICT_DATA")==0)
+ ZCODE_LESS_DICT_DATA=j, flag=1;
+ if (strcmp(command,"ZCODE_MAX_INLINE_STRING")==0)
+ ZCODE_MAX_INLINE_STRING=j, flag=1;
if (strcmp(command,"GLULX_OBJECT_EXT_BYTES")==0)
GLULX_OBJECT_EXT_BYTES=j, flag=1;
if (strcmp(command,"MAX_STATIC_DATA")==0)
- MAX_STATIC_DATA=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_OLDEPTH")==0)
flag=2;
if (strcmp(command,"MAX_ROUTINES")==0)
if (strcmp(command,"MAX_GCONSTANTS")==0)
flag=2;
if (strcmp(command,"MAX_PROP_TABLE_SIZE")==0)
- { MAX_PROP_TABLE_SIZE=j, flag=1;
- MAX_PROP_TABLE_SIZE_g=MAX_PROP_TABLE_SIZE_z=j;
- }
+ flag=3;
if (strcmp(command,"MAX_FORWARD_REFS")==0)
flag=2;
if (strcmp(command,"STACK_SIZE")==0)
MAX_DYNAMIC_STRINGS_g=MAX_DYNAMIC_STRINGS_z=j;
}
if (strcmp(command,"MAX_ARRAYS")==0)
- MAX_ARRAYS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_EXPRESSION_NODES")==0)
- MAX_EXPRESSION_NODES=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_VERBS")==0)
- MAX_VERBS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_VERBSPACE")==0)
- MAX_VERBSPACE=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_LABELS")==0)
- MAX_LABELS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_LINESPACE")==0)
- MAX_LINESPACE=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_NUM_STATIC_STRINGS")==0)
- MAX_NUM_STATIC_STRINGS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_STATIC_STRINGS")==0)
- { MAX_STATIC_STRINGS=j, flag=1;
- if (2*MAX_QTEXT_SIZE > MAX_STATIC_STRINGS)
- MAX_STATIC_STRINGS = 2*MAX_QTEXT_SIZE;
- }
+ flag=3;
if (strcmp(command,"MAX_ZCODE_SIZE")==0)
- { MAX_ZCODE_SIZE=j, flag=1;
- MAX_ZCODE_SIZE_g=MAX_ZCODE_SIZE_z=j;
- }
+ flag=3;
if (strcmp(command,"MAX_LINK_DATA_SIZE")==0)
- MAX_LINK_DATA_SIZE=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_LOW_STRINGS")==0)
- MAX_LOW_STRINGS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_TRANSCRIPT_SIZE")==0)
- MAX_TRANSCRIPT_SIZE=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_CLASSES")==0)
- MAX_CLASSES=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_INCLUSION_DEPTH")==0)
- MAX_INCLUSION_DEPTH=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_SOURCE_FILES")==0)
- MAX_SOURCE_FILES=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_INDIV_PROP_TABLE_SIZE")==0)
- MAX_INDIV_PROP_TABLE_SIZE=j, flag=1;
+ flag=3;
if (strcmp(command,"INDIV_PROP_START")==0)
INDIV_PROP_START=j, flag=1;
if (strcmp(command,"MAX_OBJ_PROP_TABLE_SIZE")==0)
- MAX_OBJ_PROP_TABLE_SIZE=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_OBJ_PROP_COUNT")==0)
- MAX_OBJ_PROP_COUNT=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_LOCAL_VARIABLES")==0)
- { MAX_LOCAL_VARIABLES=j, flag=1;
- MAX_LOCAL_VARIABLES_g=MAX_LOCAL_VARIABLES_z=j;
- }
+ flag=3;
if (strcmp(command,"MAX_GLOBAL_VARIABLES")==0)
- { MAX_GLOBAL_VARIABLES=j, flag=1;
- MAX_GLOBAL_VARIABLES_g=MAX_GLOBAL_VARIABLES_z=j;
- }
+ flag=3;
if (strcmp(command,"ALLOC_CHUNK_SIZE")==0)
- { ALLOC_CHUNK_SIZE=j, flag=1;
- ALLOC_CHUNK_SIZE_g=ALLOC_CHUNK_SIZE_z=j;
- }
+ flag=3;
if (strcmp(command,"MAX_UNICODE_CHARS")==0)
- MAX_UNICODE_CHARS=j, flag=1;
+ flag=3;
if (strcmp(command,"MAX_STACK_SIZE")==0)
{
MAX_STACK_SIZE=j, flag=1;
/* 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;
if (OMIT_UNUSED_ROUTINES > 1 || OMIT_UNUSED_ROUTINES < 0)
OMIT_UNUSED_ROUTINES = 1;
}
+ if (strcmp(command,"STRIP_UNREACHABLE_LABELS")==0)
+ {
+ STRIP_UNREACHABLE_LABELS=j, flag=1;
+ if (STRIP_UNREACHABLE_LABELS > 1 || STRIP_UNREACHABLE_LABELS < 0)
+ STRIP_UNREACHABLE_LABELS = 1;
+ }
+ if (strcmp(command,"OMIT_SYMBOL_TABLE")==0)
+ {
+ OMIT_SYMBOL_TABLE=j, flag=1;
+ if (OMIT_SYMBOL_TABLE > 1 || OMIT_SYMBOL_TABLE < 0)
+ OMIT_SYMBOL_TABLE = 1;
+ }
+ if (strcmp(command,"LONG_DICT_FLAG_BUG")==0)
+ {
+ LONG_DICT_FLAG_BUG=j, flag=1;
+ if (LONG_DICT_FLAG_BUG > 1 || LONG_DICT_FLAG_BUG < 0)
+ LONG_DICT_FLAG_BUG = 1;
+ }
if (strcmp(command,"SERIAL")==0)
{
if (j >= 0 && j <= 999999)
if (flag==0)
printf("No such memory setting as \"%s\"\n", command);
- if (flag==2)
- printf("The Inform 5 memory setting \"%s\" has been withdrawn.\n\
-It should be safe to omit it (putting nothing in its place).\n", command);
+ if (flag==2 && !nowarnings_switch)
+ printf("The Inform 5 memory setting \"%s\" has been withdrawn.\n", command);
+ if (flag==3 && !nowarnings_switch)
+ printf("The Inform 6 memory setting \"%s\" is no longer needed and has been withdrawn.\n", command);
return;
}
}