X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Ffiles.c;h=68d1c5581a8130a7009848b7e3d9c3f7b383b4b1;hb=HEAD;hp=742e965e67ec379273f000d608ba19f9eb45e11f;hpb=46cb3ffad9e3ed318a9109ff96421882f6642b2b;p=inform.git diff --git a/src/files.c b/src/files.c index 742e965..68d1c55 100644 --- a/src/files.c +++ b/src/files.c @@ -7,9 +7,8 @@ /* routines in "inform.c", since they are tied up with ICL */ /* settings and are very host OS-dependent. */ /* */ -/* Copyright (c) Graham Nelson 1993 - 2020 */ -/* */ -/* This file is part of Inform. */ +/* 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 */ @@ -41,7 +40,7 @@ int32 total_chars_read; /* Characters read in (from all static int checksum_low_byte, /* For calculating the Z-machine's */ checksum_high_byte; /* "verify" checksum */ -static int32 checksum_long; /* For the Glulx checksum, */ +static uint32 checksum_long; /* For the Glulx checksum, */ static int checksum_count; /* similarly */ /* ------------------------------------------------------------------------- */ @@ -49,10 +48,9 @@ static int checksum_count; /* similarly */ /* level is only concerned with file names and handles. */ /* ------------------------------------------------------------------------- */ -FileId *InputFiles=NULL; /* Ids for all the source files */ -static char *filename_storage, /* Translated filenames */ - *filename_storage_p; -static int filename_storage_left; +FileId *InputFiles=NULL; /* Ids for all the source files + Allocated to total_files */ +static memory_list InputFiles_memlist; /* ------------------------------------------------------------------------- */ /* When emitting debug information, we won't have addresses of routines, */ @@ -88,13 +86,6 @@ static debug_backpatch_accumulator global_backpatch_accumulator; static debug_backpatch_accumulator array_backpatch_accumulator; static debug_backpatch_accumulator grammar_backpatch_accumulator; -/* ------------------------------------------------------------------------- */ -/* File handles and names for temporary files. */ -/* ------------------------------------------------------------------------- */ - -FILE *Temp1_fp=NULL, *Temp2_fp=NULL, *Temp3_fp=NULL; -char Temp1_Name[PATHLEN], Temp2_Name[PATHLEN], Temp3_Name[PATHLEN]; - /* ------------------------------------------------------------------------- */ /* Opening and closing source code files */ /* ------------------------------------------------------------------------- */ @@ -119,23 +110,16 @@ extern void load_sourcefile(char *filename_given, int same_directory_flag) int x = 0; FILE *handle; - if (total_files == MAX_SOURCE_FILES) - memoryerror("MAX_SOURCE_FILES", MAX_SOURCE_FILES); + ensure_memory_list_available(&InputFiles_memlist, total_files+1); do { x = translate_in_filename(x, name, filename_given, same_directory_flag, (total_files==0)?1:0); - handle = fopen(name,"r"); + handle = fopen(name,"rb"); } while ((handle == NULL) && (x != 0)); - if (filename_storage_left <= (int)strlen(name)) - memoryerror("MAX_SOURCE_FILES", MAX_SOURCE_FILES); - - filename_storage_left -= strlen(name)+1; - strcpy(filename_storage_p, name); - InputFiles[total_files].filename = filename_storage_p; - - filename_storage_p += strlen(name)+1; + InputFiles[total_files].filename = my_malloc(strlen(name)+1, "filename storage"); + strcpy(InputFiles[total_files].filename, name); if (debugfile_switch) { debug_file_printf("", total_files); @@ -158,8 +142,10 @@ extern void load_sourcefile(char *filename_given, int same_directory_flag) fatalerror_named("Couldn't open source file", name); InputFiles[total_files].is_input = TRUE; + InputFiles[total_files].initial_buffering = TRUE; - if (line_trace_level > 0) printf("\nOpening file \"%s\"\n",name); + if (files_trace_setting > 0) + printf("Opening file \"%s\"\n",name); total_files++; total_input_files++; @@ -170,7 +156,8 @@ static void close_sourcefile(int file_number) { if (InputFiles[file_number-1].handle == NULL) return; - /* Close this file. */ + /* Close this file. But keep the InputFiles entry around, including + its filename. */ if (ferror(InputFiles[file_number-1].handle)) fatalerror_named("I/O failure: couldn't read from source file", @@ -180,7 +167,10 @@ static void close_sourcefile(int file_number) InputFiles[file_number-1].handle = NULL; - if (line_trace_level > 0) printf("\nClosing file\n"); + if (files_trace_setting > 0) { + char *str = (InputFiles[file_number-1].initial_buffering ? " (in initial buffering)" : ""); + printf("Closing file \"%s\"%s\n", InputFiles[file_number-1].filename, str); + } } extern void close_all_source(void) @@ -196,6 +186,7 @@ extern void close_all_source(void) extern int register_orig_sourcefile(char *filename) { int ix; + char *name; /* If the filename has already been used as an origsource filename, return that entry. We check the most-recently-used file first, and @@ -217,19 +208,12 @@ extern int register_orig_sourcefile(char *filename) /* This filename has never been used before. Allocate a new InputFiles entry. */ - char *name = filename; /* no translation */ + name = filename; /* no translation */ - if (total_files == MAX_SOURCE_FILES) - memoryerror("MAX_SOURCE_FILES", MAX_SOURCE_FILES); + ensure_memory_list_available(&InputFiles_memlist, total_files+1); - if (filename_storage_left <= (int)strlen(name)) - memoryerror("MAX_SOURCE_FILES", MAX_SOURCE_FILES); - - filename_storage_left -= strlen(name)+1; - strcpy(filename_storage_p, name); - InputFiles[total_files].filename = filename_storage_p; - - filename_storage_p += strlen(name)+1; + InputFiles[total_files].filename = my_malloc(strlen(name)+1, "filename storage"); + strcpy(InputFiles[total_files].filename, name); if (debugfile_switch) { debug_file_printf("", total_files); @@ -242,6 +226,7 @@ extern int register_orig_sourcefile(char *filename) InputFiles[total_files].handle = NULL; InputFiles[total_files].is_input = FALSE; + InputFiles[total_files].initial_buffering = FALSE; total_files++; current_origsource_file = total_files; @@ -288,7 +273,7 @@ extern int file_load_chars(int file_number, char *buffer, int length) } /* ------------------------------------------------------------------------- */ -/* Final assembly and output of the story file/module. */ +/* Final assembly and output of the story file. */ /* ------------------------------------------------------------------------- */ FILE *sf_handle; @@ -298,9 +283,7 @@ static void sf_put(int c) if (!glulx_mode) { /* The checksum is the unsigned sum mod 65536 of the bytes in the - story file from 0x0040 (first byte after header) to the end. - - The link data does not contribute to the checksum of a module. */ + story file from 0x0040 (first byte after header) to the end. */ checksum_low_byte += c; if (checksum_low_byte>=256) @@ -317,16 +300,16 @@ static void sf_put(int c) switch (checksum_count) { case 0: - checksum_long += (((int32)(c & 0xFF)) << 24); + checksum_long += (((uint32)(c & 0xFF)) << 24); break; case 1: - checksum_long += (((int32)(c & 0xFF)) << 16); + checksum_long += (((uint32)(c & 0xFF)) << 16); break; case 2: - checksum_long += (((int32)(c & 0xFF)) << 8); + checksum_long += (((uint32)(c & 0xFF)) << 8); break; case 3: - checksum_long += ((int32)(c & 0xFF)); + checksum_long += ((uint32)(c & 0xFF)); break; } @@ -374,7 +357,7 @@ static void output_compression(int entnum, int32 *size, int *count) (*size) += 1; break; case 3: - cx = (char *)abbreviations_at + ent->u.val*MAX_ABBREV_LENGTH; + cx = abbreviation_text(ent->u.val); while (*cx) { sf_put(*cx); cx++; @@ -403,7 +386,7 @@ static void output_compression(int entnum, int32 *size, int *count) } static void output_file_z(void) -{ FILE *fin=NULL; char new_name[PATHLEN]; +{ char new_name[PATHLEN]; int32 length, blanks=0, size, i, j, offset; uint32 code_length, size_before_code, next_cons_check; int use_function; @@ -415,9 +398,6 @@ static void output_file_z(void) /* Enter the length information into the header. */ length=((int32) Write_Strings_At) + static_strings_extent; - if (module_switch) length += link_data_size + - zcode_backpatch_size + - zmachine_backpatch_size; while ((length%length_scale_factor)!=0) { length++; blanks++; } length=length/length_scale_factor; @@ -440,7 +420,7 @@ static void output_file_z(void) /* Set the type and creator to Andrew Plotkin's MaxZip, a popular Z-code interpreter on the Macintosh */ - if (!module_switch) fsetfileinfo(new_name, 'mxZR', 'ZCOD'); + fsetfileinfo(new_name, 'mxZR', 'ZCOD'); #endif /* (1) Output the paged memory. */ @@ -457,14 +437,6 @@ static void output_file_z(void) /* (2) Output the compiled code area. */ - if (temporary_files_switch) - { fclose(Temp2_fp); - Temp2_fp = NULL; - fin=fopen(Temp2_Name,"rb"); - if (fin==NULL) - fatalerror("I/O failure: couldn't reopen temporary file 2"); - } - if (!OMIT_UNUSED_ROUTINES) { /* This is the old-fashioned case, which is easy. All of zcode_area (zmachine_pc bytes) will be output. next_cons_check will be @@ -491,15 +463,14 @@ static void output_file_z(void) size_before_code = size; j=0; - if (!module_switch) for (i=0; i= 0x80) long_flag = FALSE; backpatch_marker &= 0x7f; offset = offset + (backpatch_marker/32)*0x10000; @@ -514,17 +485,13 @@ static void output_file_z(void) while (j> 24)); - sf_put((VersionNum >> 16)); - sf_put((VersionNum >> 8)); - sf_put((VersionNum)); + sf_put((final_glulx_version >> 24)); + sf_put((final_glulx_version >> 16)); + sf_put((final_glulx_version >> 8)); + sf_put((final_glulx_version)); /* RAMSTART */ sf_put((Write_RAM_At >> 24)); sf_put((Write_RAM_At >> 16)); @@ -850,14 +759,6 @@ game features require version 0x%08lx", (long)requested_glulx_version, (long)Ver /* (2) Output the compiled code area. */ - if (temporary_files_switch) - { fclose(Temp2_fp); - Temp2_fp = NULL; - fin=fopen(Temp2_Name,"rb"); - if (fin==NULL) - fatalerror("I/O failure: couldn't reopen temporary file 2"); - } - if (!OMIT_UNUSED_ROUTINES) { /* This is the old-fashioned case, which is easy. All of zcode_area (zmachine_pc bytes) will be output. next_cons_check will be @@ -884,37 +785,32 @@ game features require version 0x%08lx", (long)requested_glulx_version, (long)Ver size_before_code = size; j=0; - if (!module_switch) for (i=0; i static_strings_extent || ch < 0) compiler_error("Read too much not-yet-compressed text."); @@ -1191,13 +1063,13 @@ game features require version 0x%08lx", (long)requested_glulx_version, (long)Ver int32 val, ix, jx; for (ix=0, jx=0; ix> 16) & 0xFFFF; + int32 minor = (final_glulx_version >> 8) & 0xFF; + int32 patch = final_glulx_version & 0xFF; + snprintf(botline_buffer, 256, "[Compiled Glulx version %d.%d.%d]", major, minor, patch); + } + write_to_transcript_file(botline_buffer, STRCTX_INFO); + write_serial_number(sn_buffer); - sprintf(botline_buffer, "\n[End of transcript: release %d.%s]\n", + snprintf(botline_buffer, 256, "[End of transcript: release %d, serial %s]", release_number, sn_buffer); - write_to_transcript_file(botline_buffer); + write_to_transcript_file(botline_buffer, STRCTX_INFO); + write_to_transcript_file("", STRCTX_INFO); if (ferror(transcript_file_handle)) fatalerror("I/O failure: couldn't write to transcript file"); @@ -1528,45 +1448,45 @@ extern void write_debug_locations(debug_locations locations) } extern void write_debug_optional_identifier(int32 symbol_index) -{ if (stypes[symbol_index] != ROUTINE_T) +{ if (symbols[symbol_index].type != ROUTINE_T) { compiler_error ("Attempt to write a replaceable identifier for a non-routine"); } - if (replacement_debug_backpatch_positions[symbol_index].valid) + if (symbol_debug_info[symbol_index].replacement_backpatch_pos.valid) { if (fsetpos (Debug_fp, - &replacement_debug_backpatch_positions[symbol_index].position)) + &symbol_debug_info[symbol_index].replacement_backpatch_pos.position)) { fatalerror("I/O failure: can't seek in debugging information file"); } debug_file_printf ("%s " "(superseded replacement)", - symbs[symbol_index]); + symbols[symbol_index].name); if (fseek(Debug_fp, 0L, SEEK_END)) { fatalerror("I/O failure: can't seek in debugging information file"); } } fgetpos - (Debug_fp, &replacement_debug_backpatch_positions[symbol_index].position); - replacement_debug_backpatch_positions[symbol_index].valid = TRUE; - debug_file_printf("%s", symbs[symbol_index]); + (Debug_fp, &symbol_debug_info[symbol_index].replacement_backpatch_pos.position); + symbol_debug_info[symbol_index].replacement_backpatch_pos.valid = TRUE; + debug_file_printf("%s", symbols[symbol_index].name); /* Space for: artificial="true" (superseded replacement) */ debug_file_printf(" "); } extern void write_debug_symbol_backpatch(int32 symbol_index) -{ if (symbol_debug_backpatch_positions[symbol_index].valid) { +{ if (symbol_debug_info[symbol_index].backpatch_pos.valid) { compiler_error("Symbol entry incorrectly reused in debug information " "file backpatching"); } - fgetpos(Debug_fp, &symbol_debug_backpatch_positions[symbol_index].position); - symbol_debug_backpatch_positions[symbol_index].valid = TRUE; + fgetpos(Debug_fp, &symbol_debug_info[symbol_index].backpatch_pos.position); + symbol_debug_info[symbol_index].backpatch_pos.valid = TRUE; /* Reserve space for up to 10 digits plus a negative sign. */ debug_file_printf("*BACKPATCH*"); } extern void write_debug_symbol_optional_backpatch(int32 symbol_index) -{ if (symbol_debug_backpatch_positions[symbol_index].valid) { +{ if (symbol_debug_info[symbol_index].backpatch_pos.valid) { compiler_error("Symbol entry incorrectly reused in debug information " "file backpatching"); } @@ -1575,8 +1495,8 @@ extern void write_debug_symbol_optional_backpatch(int32 symbol_index) so that we'll be in the same case as above if the symbol is eventually defined. */ debug_file_printf(""); - fgetpos(Debug_fp, &symbol_debug_backpatch_positions[symbol_index].position); - symbol_debug_backpatch_positions[symbol_index].valid = TRUE; + fgetpos(Debug_fp, &symbol_debug_info[symbol_index].backpatch_pos.position); + symbol_debug_info[symbol_index].backpatch_pos.valid = TRUE; debug_file_printf("*BACKPATCH*"); } @@ -1692,18 +1612,18 @@ extern void end_writing_debug_sections(int32 end_address) } extern void write_debug_undef(int32 symbol_index) -{ if (!symbol_debug_backpatch_positions[symbol_index].valid) +{ if (!symbol_debug_info[symbol_index].backpatch_pos.valid) { compiler_error ("Attempt to erase debugging information never written or since " "erased"); } - if (stypes[symbol_index] != CONSTANT_T) + if (symbols[symbol_index].type != CONSTANT_T) { compiler_error ("Attempt to erase debugging information for a non-constant " "because of an #undef"); } if (fsetpos - (Debug_fp, &symbol_debug_backpatch_positions[symbol_index].position)) + (Debug_fp, &symbol_debug_info[symbol_index].backpatch_pos.position)) { fatalerror("I/O failure: can't seek in debugging information file"); } /* There are 7 characters in ``''. */ @@ -1713,7 +1633,7 @@ extern void write_debug_undef(int32 symbol_index) /* Overwrite: *BACKPATCH* */ debug_file_printf(" "); nullify_debug_file_position - (&symbol_debug_backpatch_positions[symbol_index]); + (&symbol_debug_info[symbol_index].backpatch_pos); if (fseek(Debug_fp, 0L, SEEK_END)) { fatalerror("I/O failure: can't seek in debugging information file"); } @@ -1744,14 +1664,13 @@ static void apply_debug_information_backpatches static void apply_debug_information_symbol_backpatches() { int backpatch_symbol; for (backpatch_symbol = no_symbols; backpatch_symbol--;) - { if (symbol_debug_backpatch_positions[backpatch_symbol].valid) + { if (symbol_debug_info[backpatch_symbol].backpatch_pos.valid) { if (fsetpos(Debug_fp, - &symbol_debug_backpatch_positions - [backpatch_symbol].position)) + &symbol_debug_info[backpatch_symbol].backpatch_pos.position)) { fatalerror ("I/O failure: can't seek in debugging information file"); } - debug_file_printf("%11d", svals[backpatch_symbol]); + debug_file_printf("%11d", symbols[backpatch_symbol].value); } } } @@ -1795,57 +1714,6 @@ extern void end_debug_file() close_debug_file(); } -/* ------------------------------------------------------------------------- */ -/* Temporary storage files: */ -/* */ -/* Temp file 1 is used to hold the static strings area, as compiled */ -/* 2 to hold compiled routines of Z-code */ -/* 3 to hold the link data table (but only for modules) */ -/* */ -/* (Though annoying, this procedure typically saves about 200K of memory, */ -/* an important point for Amiga and sub-386 PC users of Inform) */ -/* ------------------------------------------------------------------------- */ - -extern void open_temporary_files(void) -{ translate_temp_filename(1); - Temp1_fp=fopen(Temp1_Name,"wb"); - if (Temp1_fp==NULL) fatalerror_named("Couldn't open temporary file 1", - Temp1_Name); - translate_temp_filename(2); - Temp2_fp=fopen(Temp2_Name,"wb"); - if (Temp2_fp==NULL) fatalerror_named("Couldn't open temporary file 2", - Temp2_Name); - - if (!module_switch) return; - translate_temp_filename(3); - Temp3_fp=fopen(Temp3_Name,"wb"); - if (Temp3_fp==NULL) fatalerror_named("Couldn't open temporary file 3", - Temp3_Name); -} - -extern void check_temp_files(void) -{ - if (ferror(Temp1_fp)) - fatalerror("I/O failure: couldn't write to temporary file 1"); - if (ferror(Temp2_fp)) - fatalerror("I/O failure: couldn't write to temporary file 2"); - if (module_switch && ferror(Temp3_fp)) - fatalerror("I/O failure: couldn't write to temporary file 3"); -} - -extern void remove_temp_files(void) -{ if (Temp1_fp != NULL) fclose(Temp1_fp); - Temp1_fp = NULL; - if (Temp2_fp != NULL) fclose(Temp2_fp); - Temp2_fp = NULL; - remove(Temp1_Name); remove(Temp2_Name); - if (module_switch) - { if (Temp3_fp != NULL) fclose(Temp3_fp); - Temp3_fp = NULL; - remove(Temp3_Name); - } -} - /* ========================================================================= */ /* Data structure management routines */ /* ------------------------------------------------------------------------- */ @@ -1869,8 +1737,6 @@ extern void files_begin_prepass(void) extern void files_begin_pass(void) { total_chars_read=0; - if (temporary_files_switch) - open_temporary_files(); } static void initialise_accumulator @@ -1888,10 +1754,9 @@ static void initialise_accumulator } extern void files_allocate_arrays(void) -{ filename_storage = my_malloc(MAX_SOURCE_FILES*64, "filename storage"); - filename_storage_p = filename_storage; - filename_storage_left = MAX_SOURCE_FILES*64; - InputFiles = my_malloc(MAX_SOURCE_FILES*sizeof(FileId), +{ + initialise_memory_list(&InputFiles_memlist, + sizeof(FileId), 16, (void**)&InputFiles, "input file storage"); if (debugfile_switch) { if (glulx_mode) @@ -1920,8 +1785,14 @@ static void tear_down_accumulator(debug_backpatch_accumulator *accumulator) } extern void files_free_arrays(void) -{ my_free(&filename_storage, "filename storage"); - my_free(&InputFiles, "input file storage"); +{ + int ix; + for (ix=0; ix