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);
     }

Reply via email to