From f40d6851514c7840a8d068689c28e6df83c68fbe Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 16 Jul 2024 14:17:57 -0400 Subject: listbas: initial support for autodetecting BASIC dialect (-A option). --- listbas.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 5 deletions(-) (limited to 'listbas.c') diff --git a/listbas.c b/listbas.c index bcdb052..d0a87fd 100644 --- a/listbas.c +++ b/listbas.c @@ -8,6 +8,8 @@ #include #include +#include + #include "bas.h" #include "bcdfp.h" #include "tokens.h" @@ -74,6 +76,7 @@ int immediate = 0; /* 1 with -i */ int underline = 0; /* 1 with -u */ int skip_lineno = 0; /* 1 with -l */ int dump_tables = 0; /* 1 with -D */ +int autodetect = 0; /* 1 with -a */ /* change these with -c */ int color_cmd = C_YELLOW; @@ -85,6 +88,8 @@ int color_rem = C_BLUE; int color_data = C_CYAN; int color_varnames = NO_COLOR; +const char *input_filename; + int badtok = 0; /* set to 1 if we find a bad token */ int inv = 0; /* set to 1 when we're printing inverse */ int cur_color = -1; /* -1 = no color */ @@ -162,14 +167,15 @@ void parse_args(int argc, char **argv, int from_env) { optind = 1; - while( (opt = getopt(argc, argv, "Db:UCviamnBdhxulc:")) != -1) { + while( (opt = getopt(argc, argv, "ADb:UCviamnBdhxulc:")) != -1) { switch(opt) { - case 'D': dump_tables = 1; break; case 'U': output_mode = M_UTF8; break; case 'a': output_mode = M_ATASCII; break; case 'm': output_mode = M_MAG; break; case 'd': output_mode = M_DOTS; break; case 'x': output_mode = M_UTF8_I; break; + case 'A': autodetect = 1; break; + case 'D': dump_tables = 1; break; case 'v': verbose = 1; break; case 'i': immediate = 1; break; case 'B': bold = 1; break; @@ -187,10 +193,12 @@ void parse_args(int argc, char **argv, int from_env) { } if(!from_env) { - if(optind >= argc) + if(optind >= argc) { die("No input file given (use - for stdin)."); - else - open_input(argv[optind]); + } else { + input_filename = argv[optind]; + open_input(input_filename); + } } } @@ -705,7 +713,67 @@ void init_token_tables() { } } +void set_bas_dialect(int d) { + if(verbose) + fprintf(stderr, "set_bas_dialect(%d)\n", d); + + switch(d) { + case 0: + case 1: + die("whichbas child process failed"); + break; + case SRET_ATARI: + case SRET_APLUS: + case SRET_TURBO: + case SRET_BXL: + case SRET_BXE: + bas_type = d; + break; + default: + fprintf(stderr, "whichbas results ambiguous; guessing Turbo BASIC\n"); + bas_type = SRET_TURBO; + break; + } +} + +void detect_bas_dialect() { + pid_t pid, status; + int wstatus; + const char *args[4]; + + args[0] = "whichbas"; + args[1] = "-s"; + args[2] = input_filename; + args[3] = 0; + + pid = fork(); + if(pid == -1) { + perror("fork()"); + die("Can't spawn child process"); + } else if(pid) { + /* we are the parent */ + status = waitpid(pid, &wstatus, 0); + if(status < 0) { + perror("waitpid()"); + die("Child process went south"); + } + if(!WIFEXITED(wstatus)) { + die("Child process went south"); + } + set_bas_dialect(WEXITSTATUS(wstatus)); + } else { + /* we are the child */ + if(execvp(args[0], (char * const *)args) < 0) { + perror("exec()"); + exit(1); + } + } +} + void init_bas_dialect() { + if(autodetect) + detect_bas_dialect(); + if(bas_type == B_BXL || bas_type == B_BXE) allow_hex_const = 1; -- cgit v1.2.3