From bb2b8e0fcad10cf896acd1bfd42267c40f4f21ea Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 5 Apr 2022 08:31:10 -0400 Subject: [PATCH] Support execution of command script arguments. --- Makefile | 2 +- advent.adoc | 6 +++++- advent.h | 7 +++++++ cheat.c | 12 ++++++++++++ main.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++-- misc.c | 4 ++-- saveresume.c | 5 ++--- 7 files changed, 80 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 70d004e..80ac01f 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ VERS=$(shell sed -n " + /* * DESTROY(N) = Get rid of an item by putting it in LOC_NOWHERE * MOD(N,M) = Arithmetic modulus @@ -194,6 +196,10 @@ struct settings_t { FILE *logfp; bool oldstyle; bool prompt; + char **argv; + int argc; + int optind; + FILE *scriptfp; }; typedef struct { @@ -215,6 +221,7 @@ typedef struct { extern struct game_t game; extern struct settings_t settings; +extern char *myreadline(const char *); extern bool get_command_input(command_t *); extern void clear_command(command_t *); extern void speak(const char*, ...); diff --git a/cheat.c b/cheat.c index 0eee14b..d25e218 100644 --- a/cheat.c +++ b/cheat.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "advent.h" int main(int argc, char *argv[]) @@ -96,3 +97,14 @@ int main(int argc, char *argv[]) return EXIT_SUCCESS; } + +/* + * Ugh...unused, but required for linkage. + * See thje actually useful version of this in main.c + */ + +char *myreadline(const char *prompt) +{ + return readline(prompt); +} + diff --git a/main.c b/main.c index ea9bf8f..dfc682e 100644 --- a/main.c +++ b/main.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "advent.h" #include "dungeon.h" @@ -50,11 +52,11 @@ int main(int argc, char *argv[]) #ifndef ADVENT_NOSAVE const char* opts = "l:or:"; - const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename]\n"; + const char* usage = "Usage: %s [-l logfilename] [-o] [-r restorefilename] [script...]\n"; FILE *rfp = NULL; #else const char* opts = "l:o"; - const char* usage = "Usage: %s [-l logfilename] [-o]\n"; + const char* usage = "Usage: %s [-l logfilename] [-o] [script...]\n"; #endif while ((ch = getopt(argc, argv, opts)) != EOF) { switch (ch) { @@ -95,6 +97,11 @@ int main(int argc, char *argv[]) } } + /* copy inncation line part after switches */ + settings.argc = argc - optind; + settings.argv = argv + optind; + settings.optind = 0; + /* Initialize game variables */ int seedval = initialise(); @@ -129,6 +136,48 @@ int main(int argc, char *argv[]) terminate(quitgame); } +char *myreadline(const char *prompt) +{ + /* + * This function isbn't required for gameplay, readline() straight + * up would suffice for tat. It's where we interpret command-line + * logfiles for testing purposes. + */ + /* Normal case - no script arguments */ + if (settings.argc == 0) + return readline(prompt); + + for (;;) { + if (settings.scriptfp == NULL || feof(settings.scriptfp)) { + if (settings.optind >= settings.argc) { + return NULL; + } + + char *next = settings.argv[settings.optind++]; + + if (settings.scriptfp != NULL && feof(settings.scriptfp)) + fclose(settings.scriptfp); + if (strcmp(next, "-") == 0) + settings.scriptfp = stdin; + else + settings.scriptfp = fopen(next, "r"); + } + + if (isatty(fileno(settings.scriptfp))) { + return readline(prompt); + } else { + char *ln = fgets(malloc(BUFSIZ), BUFSIZ-1, settings.scriptfp); + if (ln != NULL) { + fputs(PROMPT, stdout); + fputs(ln, stdout); + return ln; + } + } + } + + return NULL; +} + /* Check if this loc is eligible for any hints. If been here int * enough, display. Ignore "HINTS" < 4 (special stuff, see database * notes). */ diff --git a/misc.c b/misc.c index f2d6742..a0f6c36 100644 --- a/misc.c +++ b/misc.c @@ -211,7 +211,7 @@ static int word_count(char* str) static char* get_input(void) { // Set up the prompt - char input_prompt[] = "> "; + char input_prompt[] = PROMPT; if (!settings.prompt) input_prompt[0] = '\0'; @@ -220,7 +220,7 @@ static char* get_input(void) char* input; while (true) { - input = readline(input_prompt); + input = myreadline(input_prompt); if (input == NULL) // Got EOF; return with it. return (input); diff --git a/saveresume.c b/saveresume.c index 15d14c1..fb247c9 100644 --- a/saveresume.c +++ b/saveresume.c @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -74,7 +73,7 @@ int suspend(void) game.saved = game.saved + 5; while (fp == NULL) { - char* name = readline("\nFile name: "); + char* name = myreadline("\nFile name: "); if (name == NULL) return GO_TOP; fp = fopen(name, WRITE_MODE); @@ -107,7 +106,7 @@ int resume(void) } while (fp == NULL) { - char* name = readline("\nFile name: "); + char* name = myreadline("\nFile name: "); // Autocomplete can leave the input with an extra traoling space. if (name != NULL && strlen(name) > 0 && name[strlen(name) - 1] == ' ') name[strlen(name) - 1] = '\0'; -- 2.31.1