X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Finform.c;h=93bfcc7964f738609f7f4a418a9743e81ce78e5b;hb=8760c1ba6442153afe76bcac742e086f90c59fe8;hp=8888077c9addfa4aa4ba9726381dd6590a9a3762;hpb=81ffe9a7de1db0b3a318a053b38882d1b7ab304c;p=inform.git diff --git a/src/inform.c b/src/inform.c index 8888077..93bfcc7 100644 --- a/src/inform.c +++ b/src/inform.c @@ -2,9 +2,8 @@ /* "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. */ +/* Part of Inform 6.35 */ +/* copyright (c) Graham Nelson 1993 - 2020 */ /* */ /* 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,13 +16,15 @@ /* 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/ * /* */ /* ------------------------------------------------------------------------- */ #define MAIN_INFORM_FILE #include "header.h" +#define CMD_BUF_SIZE (256) + /* ------------------------------------------------------------------------- */ /* Compiler progress */ /* ------------------------------------------------------------------------- */ @@ -602,7 +603,7 @@ static void set_default_paths(void) 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(Language_Name, Default_Language); set_path_value(Charset_Map, ""); } @@ -1236,7 +1237,8 @@ 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"); +story files, as well as \"Glulx\" story files:\n\ +Copyright (c) Graham Nelson 1993 - 2020.\n\n"); /* For people typing just "inform", a summary only: */ @@ -1259,23 +1261,38 @@ 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\ + ++dir add this directory to Include_Path\n\ + +PATH=dir change the PATH to this directory\n\ + ++PATH=dir add this directory to the PATH\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", + $SETTING=number change SETTING to given number\n\n", (DEFAULT_MEMORY_SIZE==HUGE_SIZE)?"(default)":"", (DEFAULT_MEMORY_SIZE==LARGE_SIZE)?"(default)":"", (DEFAULT_MEMORY_SIZE==SMALL_SIZE)?"(default)":""); + printf( +" (filename) read in a list of commands (in the format above)\n\ + from this \"setup file\"\n\n"); + + printf("Alternate command-line formats for the above:\n\ + --help (this page)\n\ + --path PATH=dir\n\ + --addpath PATH=dir\n\ + --list\n\ + --size huge, --size large, --size small\n\ + --helpopt SETTING\n\ + --opt SETTING=number\n\ + --config filename (setup file)\n\n"); + #ifndef PROMPT_INPUT - printf("For example: \"inform -dexs $huge curses\".\n\n"); + printf("For example: \"inform -dexs $huge curses\".\n"); #endif return; @@ -1327,7 +1344,7 @@ One or more words can be supplied as \"commands\". These may be:\n\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"); + z print memory map of the virtual machine\n\n"); printf("\ B use big memory model (for large V6/V7 files)\n\ @@ -1515,6 +1532,8 @@ extern void switches(char *p, int cmode) r_e_c_s_set = TRUE; break; case 'G': if (cmode == 0) error("The switch '-G' can't be set with 'Switches'"); + else if (version_set_switch) + error("The '-G' switch cannot follow the '-v' switch"); else { glulx_mode = state; adjust_memory_sizes(); @@ -1604,12 +1623,29 @@ static int copy_icl_word(char *from, char *to, int max) return i; } +/* Copy a string, converting to uppercase. The to array should be + (at least) max characters. Result will be null-terminated, so + at most max-1 characters will be copied. +*/ +static int strcpyupper(char *to, char *from, int max) +{ + int ix; + for (ix=0; ix to <%s>]\n", story_name, code_name); compile(x, story_name, code_name); - copy_icl_word(cli_buff + i, fw, 256); + copy_icl_word(cli_buff + i, fw, CMD_BUF_SIZE); if (fw[0]!=0) { icl_error(filename, line); printf("Expected comment or nothing but found '%s'\n", @@ -1710,49 +1746,146 @@ static void run_icl_file(char *filename, FILE *command_file) } } +/* This should only be called if the argument has been verified to be + an ICL command, e.g. by checking icl_command(). +*/ static void execute_icl_command(char *p) -{ char filename[PATHLEN], cli_buff[256]; +{ char filename[PATHLEN], cli_buff[CMD_BUF_SIZE]; FILE *command_file; - + int len; + 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; + case '(': len = strlen(p); + if (p[len-1] != ')') { + printf("Error in ICL: (command) missing closing paren\n"); + break; + } + len -= 2; /* omit parens */ + if (len > CMD_BUF_SIZE-1) len = CMD_BUF_SIZE-1; + strncpy(cli_buff, p+1, len); + cli_buff[len]=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) + 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; } + run_icl_file(filename, command_file); + fclose(command_file); break; } } +/* Convert a --command into the equivalent ICL command and call + execute_icl_command(). The dashes have already been stripped. + + The second argument is the following command-line argument + (or NULL if there was none). This may or may not be consumed. + Returns TRUE if it was. +*/ +static int execute_dashdash_command(char *p, char *p2) +{ + char cli_buff[CMD_BUF_SIZE]; + int consumed2 = FALSE; + + if (!strcmp(p, "help")) { + strcpy(cli_buff, "-h"); + } + else if (!strcmp(p, "list")) { + strcpy(cli_buff, "$LIST"); + } + else if (!strcmp(p, "size")) { + consumed2 = TRUE; + if (!(p2 && (!strcmpcis(p2, "HUGE") || !strcmpcis(p2, "LARGE") || !strcmpcis(p2, "SMALL")))) { + printf("--size must be followed by \"huge\", \"large\", or \"small\"\n"); + return consumed2; + } + strcpy(cli_buff, "$"); + strcpyupper(cli_buff+1, p2, CMD_BUF_SIZE-1); + } + else if (!strcmp(p, "opt")) { + consumed2 = TRUE; + if (!p2 || !strchr(p2, '=')) { + printf("--opt must be followed by \"setting=number\"\n"); + return consumed2; + } + strcpy(cli_buff, "$"); + strcpyupper(cli_buff+1, p2, CMD_BUF_SIZE-1); + } + else if (!strcmp(p, "helpopt")) { + consumed2 = TRUE; + if (!p2) { + printf("--helpopt must be followed by \"setting\"\n"); + return consumed2; + } + strcpy(cli_buff, "$?"); + strcpyupper(cli_buff+2, p2, CMD_BUF_SIZE-2); + } + else if (!strcmp(p, "path")) { + consumed2 = TRUE; + if (!p2 || !strchr(p2, '=')) { + printf("--path must be followed by \"name=path\"\n"); + return consumed2; + } + snprintf(cli_buff, CMD_BUF_SIZE, "+%s", p2); + } + else if (!strcmp(p, "addpath")) { + consumed2 = TRUE; + if (!p2 || !strchr(p2, '=')) { + printf("--addpath must be followed by \"name=path\"\n"); + return consumed2; + } + snprintf(cli_buff, CMD_BUF_SIZE, "++%s", p2); + } + else if (!strcmp(p, "config")) { + consumed2 = TRUE; + if (!p2) { + printf("--config must be followed by \"file.icl\"\n"); + return consumed2; + } + snprintf(cli_buff, CMD_BUF_SIZE, "(%s)", p2); + } + else { + printf("Option \"--%s\" unknown (try \"inform -h\")\n", p); + return FALSE; + } + + execute_icl_command(cli_buff); + return consumed2; +} + /* ------------------------------------------------------------------------- */ /* Opening and closing banners */ /* ------------------------------------------------------------------------- */ -char banner_line[80]; +char banner_line[CMD_BUF_SIZE]; +/* We store the banner text for use elsewhere (see files.c). +*/ static void banner(void) { - sprintf(banner_line, "Inform %s", - (VERSION)); + int len; + snprintf(banner_line, CMD_BUF_SIZE, "Inform %d.%d%d", + (VNUMBER/100)%10, (VNUMBER/10)%10, VNUMBER%10); #ifdef RELEASE_SUFFIX - strcat(banner_line, RELEASE_SUFFIX); + len = strlen(banner_line); + snprintf(banner_line+len, CMD_BUF_SIZE-len, "%s", RELEASE_SUFFIX); #endif #ifdef MACHINE_STRING - sprintf(banner_line+strlen(banner_line), " for %s", MACHINE_STRING); + len = strlen(banner_line); + snprintf(banner_line+len, CMD_BUF_SIZE-len, " for %s", MACHINE_STRING); #endif - sprintf(banner_line+strlen(banner_line), " (%s)", RELEASE_DATE); + len = strlen(banner_line); + snprintf(banner_line+len, CMD_BUF_SIZE-len, " (%s)", RELEASE_DATE); + printf("%s\n", banner_line); } @@ -1782,9 +1915,18 @@ static void read_command_line(int argc, char **argv) if (argc==1) switches("-h",1); for (i=1, cli_files_specified=0; i