From 5cf0a2c09f040809afdf411347092b92d7ed68ff Mon Sep 17 00:00:00 2001 From: Jeff Quast Date: Wed, 16 Aug 2023 16:31:22 -0400 Subject: [PATCH] Squashed commit of the following: commit cb5fdb9616edd09f3bf0c0cc84bdc142c74a4d80 Author: Jeff Quast Date: Wed Aug 16 16:31:04 2023 -0400 hope you like it .. commit 32ea6c9094afbe59574d82a35219ec5028ef7128 Author: Jeff Quast Date: Wed Aug 16 16:26:02 2023 -0400 try to use getopt portably twice commit d4df85200d0fd0cdb9e1da4b96a78094628ef878 Author: Jeff Quast Date: Wed Aug 16 15:55:14 2023 -0400 narf commit e803ea1373f9e8d31e08f7084889ae478e2aca9c Author: Jeff Quast Date: Wed Aug 16 15:43:43 2023 -0400 bah commit 74bbe19accc5c03ac8ef27774068619d37b44e6e Author: Jeff Quast Date: Wed Aug 16 15:41:22 2023 -0400 narf commit bd63cd61dac977b9a60d96d55b711555ca3d51e5 Author: Jeff Quast Date: Wed Aug 16 15:35:24 2023 -0400 really gum up the works, here commit ea18e16a73f130221fd1a451cd441839793c457c Author: Jeff Quast Date: Wed Aug 16 15:22:29 2023 -0400 this abomination commit b834ca34caa769799196b66ccfa132bfdbe27231 Author: Jeff Quast Date: Wed Aug 16 15:14:34 2023 -0400 narf commit c07eebf829b69f595a92b4397a546233b444b5ae Author: Jeff Quast Date: Wed Aug 16 15:07:02 2023 -0400 optind++ and debug code commit fbfb7fbeb5e551561ff2135112aa84bcd6c82f7b Author: Jeff Quast Date: Wed Aug 16 15:05:24 2023 -0400 sneaky workaround of optind ? --- utils/dos33fs-utils/dos33.c | 85 +++++++++++++++++++------ utils/dos33fs-utils/tests/test_bsave.sh | 11 +++- 2 files changed, 73 insertions(+), 23 deletions(-) diff --git a/utils/dos33fs-utils/dos33.c b/utils/dos33fs-utils/dos33.c index 5764ab550..82c85c8e8 100644 --- a/utils/dos33fs-utils/dos33.c +++ b/utils/dos33fs-utils/dos33.c @@ -1058,17 +1058,30 @@ int main(int argc, char **argv) { char *temp,*endptr; int c; int address=0, length=0; + int swp_optind=0; unsigned char vtoc[BYTES_PER_SECTOR]; int retval=0; /* Check command line arguments */ - while ((c = getopt (argc, argv,"a:l:t:s:dhvxy"))!=-1) { - switch (c) { - - case 'd': - fprintf(stderr,"DEBUG enabled\n"); - debug=1; - break; + while ((c = getopt(argc, argv, "a:l:t:s:dhvxy")) != -1) + { + switch (c) + { + + case 'd': + fprintf(stderr, "DEBUG enabled\n"); + debug = 1; + break; + case 'l': + length = strtol(optarg, &endptr, 0); + if (debug) + fprintf(stderr, "Length=%d\n", length); + break; + case 'a': + address = strtol(optarg, &endptr, 0); + if (debug) + fprintf(stderr, "Address=%d\n", address); + break; #if 0 case 't': @@ -1093,8 +1106,11 @@ int main(int argc, char **argv) { break; } } - - if (optind==argc) { + for (c = 0; c < argc;c++) { + printf("+ argv[%d]=%s\n",c,argv[c]); + } + if (optind == argc) + { fprintf(stderr,"ERROR! Must specify disk image!\n\n"); return -ERROR_INVALID_PARAMATER; } @@ -1117,6 +1133,7 @@ int main(int argc, char **argv) { retval=-ERROR_INVALID_PARAMATER; goto exit_and_close; } + printf("after next argument, optind=%d (%s) (command)\n", optind, argv[optind]); /* Grab command */ strncpy(temp_string,argv[optind],BUFSIZ-1); @@ -1128,6 +1145,7 @@ int main(int argc, char **argv) { /* Move to next argument */ optind++; + printf("after next argument, optind=%d (%s) [...]\n", optind, argv[optind]); command=lookup_command(temp_string); @@ -1217,20 +1235,47 @@ int main(int argc, char **argv) { if (debug) printf("\ttype=%c\n",type); if (command==COMMAND_BSAVE) { - // check for optional BSAVE [-a addr] and [-l len] arguments - while ((c = getopt (argc, argv,"a:l:"))!=-1) { + // Find position of 'BSAVE' command in argv, and call getopt(3) a + // second time to forward position of optind beyond optional -a and + // -l arguments on BSD. + // + // This is necessary because BSD and Linux getopt(3) differs, linux + // will process '-a' and '-l' options and mutate argv for the value + // of optind to point to remaining arguments, "local_filename // + // [apple_file]". + // + // While BSD does not mutate argv, leaving optind at the position of + // the first unknown option, 'BSAVE' with remaining arguments, "[-a + // addr] [-l len] local_filename [apple_file]" still remaining for + // processing, and this is why we must call getopt(3) a second time, + // in such a peculiar way. + optind = 1; + while ((strncmp(argv[swp_optind], "BSAVE", 5)) && swp_optind < argc) + { + swp_optind++; + } + swp_optind++; + + // forward argv and decrement argc past BSAVE command and reset optind + argv += (swp_optind - 1); + argc -= (swp_optind - 1); + optind = 1; + while ((c = getopt(argc, argv, "a:l:")) != -1) + { switch (c) { - case 'a': - address=strtol(optarg,&endptr,0); - if (debug) fprintf(stderr,"Address=%d\n",address); - break; + case 'h': + display_help(argv[0], 0); + return 0; case 'l': - length=strtol(optarg,&endptr,0); - if (debug) fprintf(stderr,"Length=%d\n",length); + length = strtol(optarg, &endptr, 0); + if (debug) + fprintf(stderr, "Length=%d\n", length); + break; + case 'a': + address = strtol(optarg, &endptr, 0); + if (debug) + fprintf(stderr, "Address=%d\n", address); break; - case 'h': display_help(argv[0],0); - return 0; - } } } diff --git a/utils/dos33fs-utils/tests/test_bsave.sh b/utils/dos33fs-utils/tests/test_bsave.sh index 8ed729bbb..f01cbc47f 100755 --- a/utils/dos33fs-utils/tests/test_bsave.sh +++ b/utils/dos33fs-utils/tests/test_bsave.sh @@ -21,9 +21,14 @@ run_test() { } cp empty.dsk test.dsk -run_test "BSAVE SINCOS EX1" "Local filename: SINCOS" "Apple filename: EX1" -run_test "BSAVE -a 0x2000 SINCOS EX2" "Local filename: SINCOS" "Apple filename: EX2" "Address=8192" -run_test "BSAVE -a 0x2000 -l 146 SINCOS EX3" "Local filename: SINCOS" "Apple filename: EX3" "Address=8192" "Length=146" +run_test "BSAVE SINCOS" \ + "type=b" "Local filename: SINCOS" "Apple filename: SINCOS" +run_test "BSAVE SINCOS EX1" \ + "type=b" "Local filename: SINCOS" "Apple filename: EX1" +run_test "BSAVE -a 0x2000 SINCOS EX2" \ + "type=b" "Local filename: SINCOS" "Apple filename: EX2" "Address=8192" +run_test "BSAVE -a 0x2000 -l 146 SINCOS EX3" \ + "type=b" "Local filename: SINCOS" "Apple filename: EX3" "Address=8192" "Length=146" rm "$tempfile" if [ "$num_failed" -gt 0 ]; then echo "Test failed. $num_failed tests failed."