This patch implements optional arguments for the longopt subsystem, and modifies imcc to use them.
Luke Index: longopt.c =================================================================== RCS file: /cvs/public/parrot/longopt.c,v retrieving revision 1.4 diff -u -r1.4 longopt.c --- longopt.c 27 May 2003 02:27:50 -0000 1.4 +++ longopt.c 2 Jul 2003 15:47:48 -0000 @@ -95,16 +95,42 @@ /* XXX: (LP) if a longopt is given an argument when it's * not expecting one, it is just ignored. Bad. */ - if (dptr->opt_flags & OPTION_required_FLAG) { - if (argv[dex][optlen] == '=') { + if (argv[dex][optlen] == '=') { + if (dptr->opt_flags & (OPTION_required_FLAG | OPTION_optional_FLAG)) { info_buf->opt_arg = &argv[dex][optlen+1]; } else { - info_buf->opt_arg = argv[dex+1]; - ++info_buf->opt_index; + Parrot_snprintf(interp, longopt_error_buffer, + sizeof(longopt_error_buffer), + "Option %s does not expect an argument", + dptr->opt_long[sptr]); + info_buf->opt_error = longopt_error_buffer; + return -1; + } + } + else { + if (dptr->opt_flags & OPTION_required_FLAG) { + if (dex+1 < argc) { + info_buf->opt_arg = argv[dex+1]; + ++info_buf->opt_index; + } + else { + Parrot_snprintf(interp, longopt_error_buffer, + sizeof(longopt_error_buffer), + "Option %s needs an argument", + dptr->opt_long[sptr]); + info_buf->opt_error = longopt_error_buffer; + return -1; + } + } + else if (dptr->opt_flags & OPTION_optional_FLAG) { + if (dex+1 < argc && argv[dex+1][0] && argv[dex+1][0] != '-') { + info_buf->opt_arg = argv[dex+1]; + ++info_buf->opt_index; + } } } - + return dptr->opt_id; } } @@ -148,6 +174,27 @@ info_buf->opt_arg = pos + 1; } else { + if (dex+1 < argc) { + info_buf->opt_arg = argv[dex+1]; + ++info_buf->opt_index; + } + else { + Parrot_snprintf(interp, longopt_error_buffer, + sizeof(longopt_error_buffer), + "Option -%c expects an argument", + *pos); + info_buf->opt_error = longopt_error_buffer; + return -1; + } + } + info_buf->_shortopt_pos = NULL; + ++info_buf->opt_index; + } + else if (dptr->opt_flags & OPTION_optional_FLAG) { + if (*(pos + 1)) { + info_buf->opt_arg = pos + 1; + } + else if (dex+1 < argc && argv[dex+1][0] && argv[dex+1][0] != '-') { info_buf->opt_arg = argv[dex+1]; ++info_buf->opt_index; } Index: include/parrot/longopt.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/longopt.h,v retrieving revision 1.3 diff -u -r1.3 longopt.h --- include/parrot/longopt.h 21 May 2003 18:22:12 -0000 1.3 +++ include/parrot/longopt.h 2 Jul 2003 15:47:49 -0000 @@ -20,7 +20,8 @@ typedef const char* longopt_string_t; typedef enum { - OPTION_required_FLAG = 0x1 + OPTION_required_FLAG = 0x1, + OPTION_optional_FLAG = 0x2 } OPTION_flags; struct longopt_opt_decl { Index: languages/imcc/main.c =================================================================== RCS file: /cvs/public/parrot/languages/imcc/main.c,v retrieving revision 1.28 diff -u -r1.28 main.c --- languages/imcc/main.c 2 Jul 2003 08:29:18 -0000 1.28 +++ languages/imcc/main.c 2 Jul 2003 15:47:49 -0000 @@ -29,13 +29,13 @@ static void usage(FILE* fp) { fprintf(fp, - "imcc -[abcgGhjpPrStvVwy.] [-d FLAGS] [-o FILE] [-O level] <file>\n"); + "parrot -[abcgGhjpPrStvVwy.] [-d [FLAGS]] [-O [level]] [-o FILE] <file>\n"); } static void help(void) { printf( - "imcc [Options] <file>\n" + "parrot [Options] <file>\n" " Options:\n" " -h --help\n" " -V --version\n" @@ -47,7 +47,7 @@ " -S --switched-core\n" " -g --no-computed-goto\n" " -t --trace\n" - " -d --debug=HEXFLAGS\n" + " -d --debug[=HEXFLAGS]\n" " -w --warnings\n" " -G --no-gc\n" " --gc-debug\n" @@ -55,7 +55,7 @@ " <Compiler options>\n" " -v --verbose\n" " -o --output=FILE\n" - " -O --optimize=LEVEL\n" + " -O --optimize[=LEVEL]\n" " -a --pasm\n" " -c --pbc\n" " -r --run-pbc\n" @@ -95,7 +95,7 @@ { 'S', 'S', 0, { "--switched-core" } }, { 'g', 'g', 0, { "--no-computed-goto" } }, { 't', 't', 0, { "--trace" } }, - { 'd', 'd', OPTION_required_FLAG, { "--debug" } }, + { 'd', 'd', OPTION_optional_FLAG, { "--debug" } }, { 'w', 'w', 0, { "--warnings" } }, { 'G', 'G', 0, { "--no-gc" } }, { '.', '.', 0, { "--wait" } }, @@ -107,7 +107,7 @@ { 'v', 'v', 0, { "--verbose" } }, { 'y', 'y', 0, { "--yydebug" } }, { 'o', 'o', OPTION_required_FLAG, { "--output" } }, - { 'O', 'O', OPTION_required_FLAG, { "--optimize" } }, + { 'O', 'O', OPTION_optional_FLAG, { "--optimize" } }, { '\0', OPT_GC_DEBUG, 0, { "--gc-debug" } }, {'\0', OPT_DESTROY_FLAG, 0, { "--leak_test", "--destroy-at-end" } }, { 0, 0, 0, { NULL } } @@ -153,8 +153,12 @@ setopt(PARROT_TRACE_FLAG); break; case 'd': - IMCC_DEBUG++; - IMCC_DEBUG = strtoul(opt.opt_arg, 0, 16); + if (opt.opt_arg) { + IMCC_DEBUG = strtoul(opt.opt_arg, 0, 16); + } + else { + IMCC_DEBUG++; + } if (IMCC_DEBUG & 1) setopt(PARROT_DEBUG_FLAG); break; @@ -197,8 +201,13 @@ break; case 'O': - strncpy(optimizer_opt, opt.opt_arg, sizeof(optimizer_opt)); - optimizer_opt[sizeof(optimizer_opt)-1] = '\0'; + if (opt.opt_arg) { + strncpy(optimizer_opt, opt.opt_arg, sizeof(optimizer_opt)); + optimizer_opt[sizeof(optimizer_opt)-1] = '\0'; + } + else { + strcpy(optimizer_opt, "1"); + } if (strchr(optimizer_opt, '1')) optimizer_level |= OPT_PRE; if (strchr(optimizer_opt, '2')) @@ -231,6 +240,7 @@ } } if (status == -1) { + fprintf(stderr, "%s\n", opt.opt_error); usage(stderr); exit(EX_USAGE); }