[svn:parrot] r43854 - in trunk: compilers/imcc compilers/pirc/src include/parrot src

bacek at svn.parrot.org bacek at svn.parrot.org
Wed Feb 10 12:29:39 UTC 2010


Author: bacek
Date: Wed Feb 10 12:29:38 2010
New Revision: 43854
URL: https://trac.parrot.org/parrot/changeset/43854

Log:
Split handling of command line args into 2 parts.

- C<parseargs> contains general handling
- C<imcc_handle_flag> contains IMCC specific handling

This will give us ability to easily replace IMCC with PIRC.

Work isn't finished yet because we still have longopt_opt_decl with all
options, but it's good start.

Modified:
   trunk/compilers/imcc/main.c
   trunk/compilers/pirc/src/main.c
   trunk/include/parrot/imcc.h
   trunk/src/main.c

Modified: trunk/compilers/imcc/main.c
==============================================================================
--- trunk/compilers/imcc/main.c	Wed Feb 10 10:31:22 2010	(r43853)
+++ trunk/compilers/imcc/main.c	Wed Feb 10 12:29:38 2010	(r43854)
@@ -67,8 +67,6 @@
 static void do_pre_process(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-static void help(void);
-static void help_debug(void);
 static void imcc_get_optimization_description(
     const PARROT_INTERP,
     int opt_level,
@@ -93,13 +91,6 @@
 static int is_all_hex_digits(ARGIN(const char *s))
         __attribute__nonnull__(1);
 
-static void Parrot_version(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-static void usage(ARGMOD(FILE *fp))
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*fp);
-
 #define ASSERT_ARGS_compile_to_bytecode __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(sourcefile))
@@ -125,198 +116,16 @@
     , PARROT_ASSERT_ARG(output_file))
 #define ASSERT_ARGS_is_all_hex_digits __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(s))
-#define ASSERT_ARGS_Parrot_version __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_usage __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(fp))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
 
-/*
-
-=item C<static void usage(FILE *fp)>
-
-Outputs usage error message.
-
-=cut
-
-*/
-
-static void
-usage(ARGMOD(FILE *fp))
-{
-    ASSERT_ARGS(usage)
-    fprintf(fp,
-            "parrot -[acEGhprtvVwy.] [-d [FLAGS]] [-D [FLAGS]]"
-            "[-O [level]] [-R runcore] [-o FILE] <file>\n");
-}
-
-/*
-
-=item C<static void help_debug(void)>
-
-Print out list of debugging flag values.
-
-=cut
-
-*/
-
-static void
-help_debug(void)
-{
-    ASSERT_ARGS(help_debug)
-    /* split printf for C89 compliance on string length */
-    printf(
-    "--imcc-debug -d [Flags] ...\n"
-    "    0002    lexer\n"
-    "    0004    parser\n"
-    "    0008    imc\n"
-    "    0010    CFG\n"
-    "    0020    optimization 1\n"
-    "    0040    optimization 2\n"
-    "    0100    AST\n"
-    "    1000    PBC\n"
-    "    2000    PBC constants\n"
-    "    4000    PBC fixups\n"
-    "\n");
-    printf(
-    "--parrot-debug -D [Flags] ...\n"
-    "    0001    memory statistics\n"
-    "    0002    print backtrace on exception\n"
-    "    0004    JIT debugging\n"
-    "    0008    interpreter startup\n"
-    "    0010    thread debugging\n"
-    "    0020    eval/compile\n"
-    "    0040    fill I, N registers with garbage\n"
-    "    0080    show when a context is destroyed\n"
-    "\n"
-    "--trace -t [Flags] ...\n"
-    "    0001    opcodes\n"
-    "    0002    find_method\n"
-    "    0004    function calls\n");
-}
-
-/*
-
-=item C<static void help(void)>
-
-Print out "help" list of options.
-
-=cut
-
-*/
-
-static void
-help(void)
-{
-    ASSERT_ARGS(help)
-    /* split printf for C89 compliance on string length */
-    printf(
-    "parrot [Options] <file>\n"
-    "  Options:\n"
-    "    -h --help\n"
-    "    -V --version\n"
-    "    -I --include add path to include search\n"
-    "    -L --library add path to library search\n"
-    "    -X --dynext add path to dynamic extension search\n"
-    "   <Run core options>\n"
-    "    -R --runcore slow|bounds|fast|cgoto|cgp\n"
-    "    -R --runcore switch|trace|profiling|gcdebug\n"
-    "    -t --trace [flags]\n"
-    "   <VM options>\n"
-    "    -D --parrot-debug[=HEXFLAGS]\n"
-    "       --help-debug\n");
-    printf(
-    "    -w --warnings\n"
-    "    -G --no-gc\n"
-    "       --gc-debug\n"
-    "       --leak-test|--destroy-at-end\n"
-    "    -. --wait    Read a keystroke before starting\n"
-    "       --runtime-prefix\n"
-    "   <Compiler options>\n"
-    "    -d --imcc-debug[=HEXFLAGS]\n"
-    "    -v --verbose\n"
-    "    -E --pre-process-only\n"
-    "    -o --output=FILE\n"
-    "       --output-pbc\n"
-    "    -O --optimize[=LEVEL]\n"
-    "    -a --pasm\n"
-    "    -c --pbc\n"
-    "    -r --run-pbc\n"
-    "    -y --yydebug\n"
-    "   <Language options>\n"
-    "see docs/running.pod for more\n");
-}
-
-
-/*
-
-=item C<static void Parrot_version(PARROT_INTERP)>
-
-Print out parrot version number.
-
-=cut
-
-*/
-
-static void
-Parrot_version(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_version)
-    printf("This is Parrot version " PARROT_VERSION);
-    printf(" built for " PARROT_ARCHNAME ".\n");
-    printf("Copyright (C) 2001-2010, Parrot Foundation.\n\
-\n\
-This code is distributed under the terms of the Artistic License 2.0.\
-\n\
-For more details, see the full text of the license in the LICENSE file\
-\n\
-included in the Parrot source tree.\n\n");
-
-    Parrot_exit(interp, 0);
-}
-
-#define SET_FLAG(flag)   Parrot_set_flag(interp, (flag))
-#define SET_DEBUG(flag)  Parrot_set_debug(interp, (flag))
-#define SET_TRACE(flag)  Parrot_set_trace(interp, (flag))
-
 #define OPT_GC_DEBUG       128
 #define OPT_DESTROY_FLAG   129
 #define OPT_HELP_DEBUG     130
 #define OPT_PBC_OUTPUT     131
 #define OPT_RUNTIME_PREFIX 132
 
-static struct longopt_opt_decl options[] = {
-    { '.', '.', (OPTION_flags)0, { "--wait" } },
-    { 'D', 'D', OPTION_optional_FLAG, { "--parrot-debug" } },
-    { 'E', 'E', (OPTION_flags)0, { "--pre-process-only" } },
-    { 'G', 'G', (OPTION_flags)0, { "--no-gc" } },
-    { 'I', 'I', OPTION_required_FLAG, { "--include" } },
-    { 'L', 'L', OPTION_required_FLAG, { "--library" } },
-    { 'O', 'O', OPTION_optional_FLAG, { "--optimize" } },
-    { 'R', 'R', OPTION_required_FLAG, { "--runcore" } },
-    { 'V', 'V', (OPTION_flags)0, { "--version" } },
-    { 'X', 'X', OPTION_required_FLAG, { "--dynext" } },
-    { '\0', OPT_DESTROY_FLAG, (OPTION_flags)0,
-                                 { "--leak-test", "--destroy-at-end" } },
-    { '\0', OPT_GC_DEBUG, (OPTION_flags)0, { "--gc-debug" } },
-    { 'a', 'a', (OPTION_flags)0, { "--pasm" } },
-    { 'c', 'c', (OPTION_flags)0, { "--pbc" } },
-    { 'd', 'd', OPTION_optional_FLAG, { "--imcc-debug" } },
-    { '\0', OPT_HELP_DEBUG, (OPTION_flags)0, { "--help-debug" } },
-    { 'h', 'h', (OPTION_flags)0, { "--help" } },
-    { 'o', 'o', OPTION_required_FLAG, { "--output" } },
-    { '\0', OPT_PBC_OUTPUT, (OPTION_flags)0, { "--output-pbc" } },
-    { 'r', 'r', (OPTION_flags)0, { "--run-pbc" } },
-    { '\0', OPT_RUNTIME_PREFIX, (OPTION_flags)0, { "--runtime-prefix" } },
-    { 't', 't', OPTION_optional_FLAG, { "--trace" } },
-    { 'v', 'v', (OPTION_flags)0, { "--verbose" } },
-    { 'w', 'w', (OPTION_flags)0, { "--warnings" } },
-    { 'y', 'y', (OPTION_flags)0, { "--yydebug" } },
-    { 0, 0, (OPTION_flags)0, { NULL } }
-};
-
 /*
 
 =item C<static int is_all_hex_digits(const char *s)>
@@ -342,223 +151,120 @@
 
 /*
 
-=item C<const char * parseflags(PARROT_INTERP, int *argc, char **argv[])>
+=item C<void imcc_start_handling_flags(PARROT_INTERP)>
 
-Parse Parrot's command line for options and set appropriate flags.
+Initialize handling of IMCC related command line flags.
 
 =cut
 
 */
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-const char *
-parseflags(PARROT_INTERP, int *argc, char **argv[])
+void
+imcc_start_handling_flags(PARROT_INTERP)
 {
-    struct longopt_opt_info opt  = LONGOPT_OPT_INFO_INIT;
-    INTVAL                  core = 0;
-    int                     status;
-
-    if (*argc == 1) {
-        usage(stderr);
-        exit(EXIT_SUCCESS);
-    }
-
     SET_STATE_RUN_PBC(interp);
+}
 
-    while ((status = longopt_get(interp, *argc, (const char **)*argv, options,
-            &opt)) > 0) {
-        switch (opt.opt_id) {
-          case 'R':
-            if (STREQ(opt.opt_arg, "slow") || STREQ(opt.opt_arg, "bounds"))
-                core = PARROT_SLOW_CORE;
-            else if (STREQ(opt.opt_arg, "fast") || STREQ(opt.opt_arg, "function"))
-                core = PARROT_FAST_CORE;
-            else if (STREQ(opt.opt_arg, "switch"))
-                core = PARROT_SWITCH_CORE;
-            else if (STREQ(opt.opt_arg, "cgp"))
-                core = PARROT_CGP_CORE;
-            else if (STREQ(opt.opt_arg, "cgoto"))
-                core = PARROT_CGOTO_CORE;
-            else if (STREQ(opt.opt_arg, "jit"))
-                core = PARROT_FAST_CORE;
-            else if (STREQ(opt.opt_arg, "cgp-jit"))
-                core = PARROT_CGP_CORE;
-            else if (STREQ(opt.opt_arg, "switch-jit"))
-                core = PARROT_SWITCH_CORE;
-            else if (STREQ(opt.opt_arg, "exec"))
-                core = PARROT_EXEC_CORE;
-            else if (STREQ(opt.opt_arg, "trace"))
-                core = PARROT_SLOW_CORE;
-            else if (STREQ(opt.opt_arg, "profiling"))
-                core = PARROT_PROFILING_CORE;
-            else if (STREQ(opt.opt_arg, "gcdebug"))
-                core = PARROT_GC_DEBUG_CORE;
-            else
-                Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                        "main: Unrecognized runcore '%s' specified."
-                        "\n\nhelp: parrot -h\n", opt.opt_arg);
-            break;
-          case 't':
-            if (opt.opt_arg && is_all_hex_digits(opt.opt_arg))
-                SET_TRACE(strtoul(opt.opt_arg, NULL, 16));
-            else
-                SET_TRACE(PARROT_TRACE_OPS_FLAG);
-            break;
-          case 'd':
-            if (opt.opt_arg && is_all_hex_digits(opt.opt_arg)) {
-                IMCC_INFO(interp)->debug = strtoul(opt.opt_arg, NULL, 16);
-            }
-            else {
-                IMCC_INFO(interp)->debug++;
-            }
-            break;
-          case 'D':
-            if (opt.opt_arg && is_all_hex_digits(opt.opt_arg)) {
-                SET_DEBUG(strtoul(opt.opt_arg, NULL, 16));
-            }
-            else
-                SET_DEBUG(PARROT_MEM_STAT_DEBUG_FLAG);
-            break;
-          case 'w':
-            Parrot_setwarnings(interp, PARROT_WARNINGS_ALL_FLAG);
-            IMCC_INFO(interp)->imcc_warn = 1;
-            break;
-          case 'G':
-            IMCC_INFO(interp)->gc_off = 1;
-            break;
-          case '.':  /* Give Windows Parrot hackers an opportunity to
-                      * attach a debuggger. */
-            fgetc(stdin);
-            break;
-          case 'a':
-            SET_STATE_PASM_FILE(interp);
-            break;
-          case 'h':
-            help();
-            exit(EX_USAGE);
-            break;
-          case OPT_HELP_DEBUG:
-            help_debug();
-            exit(EX_USAGE);
-            break;
-          case OPT_RUNTIME_PREFIX:
-            Parrot_io_printf(interp, "%Ss\n",
-                    Parrot_get_runtime_path(interp));
-            exit(EXIT_SUCCESS);
-          case 'V':
-            Parrot_version(interp);
-            break;
-          case 'r':
-            if (STATE_RUN_PBC(interp))
-                SET_STATE_RUN_FROM_FILE(interp);
-            SET_STATE_RUN_PBC(interp);
-            break;
-          case 'c':
-            SET_STATE_LOAD_PBC(interp);
-            break;
-          case 'v':
-            IMCC_INFO(interp)->verbose++;
-            break;
-          case 'y':
-            yydebug = 1;
-            break;
-          case 'E':
-            SET_STATE_PRE_PROCESS(interp);
-            break;
-          case 'o':
-            UNSET_STATE_RUN_PBC(interp);
-            interp->output_file = opt.opt_arg;
-            break;
+/*
 
-          case OPT_PBC_OUTPUT:
-            UNSET_STATE_RUN_PBC(interp);
-            SET_STATE_WRITE_PBC(interp);
-            if (!interp->output_file)
-                interp->output_file = "-";
-            break;
+=item C<int imcc_handle_flag(PARROT_INTERP, struct longopt_opt_info *opt)>
 
-          case 'O':
-            if (!opt.opt_arg) {
-                IMCC_INFO(interp)->optimizer_level |= OPT_PRE;
-                break;
-            }
-            if (strchr(opt.opt_arg, 'p'))
-                IMCC_INFO(interp)->optimizer_level |= OPT_PASM;
-            if (strchr(opt.opt_arg, 'c'))
-                IMCC_INFO(interp)->optimizer_level |= OPT_SUB;
-
-            IMCC_INFO(interp)->allocator = IMCC_GRAPH_ALLOCATOR;
-            /* currently not ok due to different register allocation */
-            if (strchr(opt.opt_arg, '1')) {
-                IMCC_INFO(interp)->optimizer_level |= OPT_PRE;
-            }
-            if (strchr(opt.opt_arg, '2')) {
-                IMCC_INFO(interp)->optimizer_level |= (OPT_PRE | OPT_CFG);
-            }
-            if (strchr(opt.opt_arg, 't')) {
-#ifdef HAVE_COMPUTED_GOTO
-                core = PARROT_CGP_CORE;
-#else
-                core = PARROT_SWITCH_CORE;
-#endif
-            }
-            break;
+Handle Parrot's command line for IMCC related option and set appropriate flags.
 
-          case OPT_GC_DEBUG:
-#if DISABLE_GC_DEBUG
-            Parrot_warn(interp, PARROT_WARNINGS_ALL_FLAG,
-                        "PARROT_GC_DEBUG is set but the binary was "
-                        "compiled with DISABLE_GC_DEBUG.");
-#endif
-            SET_FLAG(PARROT_GC_DEBUG_FLAG);
-            break;
-          case OPT_DESTROY_FLAG:
-            SET_FLAG(PARROT_DESTROY_FLAG);
-            break;
-          case 'I':
-            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
-                    PARROT_LIB_PATH_INCLUDE);
-            break;
-          case 'L':
-            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
-                    PARROT_LIB_PATH_LIBRARY);
-            break;
-          case 'X':
-            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
-                    PARROT_LIB_PATH_DYNEXT);
-            break;
-          default:
-            Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                    "main: Invalid flag '%s' used.\n\nhelp: parrot -h\n",
-                    (*argv)[0]);
-        }
-    }
+Return 1 if flag handled, 0 if not.
 
-    if (status == -1) {
-        fprintf(stderr, "%s\n", opt.opt_error);
-        usage(stderr);
-        exit(EX_USAGE);
-    }
+=cut
 
-    /* reached the end of the option list and consumed all of argv */
-    if (*argc == opt.opt_index) {
-        if (interp->output_file) {
-            fprintf(stderr, "Missing program name or argument for -o\n");
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+int
+imcc_handle_flag(PARROT_INTERP, struct longopt_opt_info *opt, INTVAL *core)
+{
+    PARROT_ASSERT(opt);
+    PARROT_ASSERT(core);
+
+    switch (opt->opt_id) {
+      case 'd':
+        if (opt->opt_arg && is_all_hex_digits(opt->opt_arg)) {
+            IMCC_INFO(interp)->debug = strtoul(opt->opt_arg, NULL, 16);
         }
         else {
-            /* We are not looking at an option, so it must be a program name */
-            fprintf(stderr, "Missing program name\n");
+            IMCC_INFO(interp)->debug++;
         }
-        usage(stderr);
-        exit(EX_USAGE);
-    }
+        break;
+      case 'w':
+        /* FIXME It's not best way to set warnings... */
+        Parrot_setwarnings(interp, PARROT_WARNINGS_ALL_FLAG);
+        IMCC_INFO(interp)->imcc_warn = 1;
+        break;
+      case 'G':
+        IMCC_INFO(interp)->gc_off = 1;
+        break;
+      case 'a':
+        SET_STATE_PASM_FILE(interp);
+        break;
+      case 'r':
+        if (STATE_RUN_PBC(interp))
+            SET_STATE_RUN_FROM_FILE(interp);
+        SET_STATE_RUN_PBC(interp);
+        break;
+      case 'c':
+        SET_STATE_LOAD_PBC(interp);
+        break;
+      case 'v':
+        IMCC_INFO(interp)->verbose++;
+        break;
+      case 'y':
+        yydebug = 1;
+        break;
+      case 'E':
+        SET_STATE_PRE_PROCESS(interp);
+        break;
+      case 'o':
+        UNSET_STATE_RUN_PBC(interp);
+        interp->output_file = opt->opt_arg;
+        break;
+
+      case OPT_PBC_OUTPUT:
+        UNSET_STATE_RUN_PBC(interp);
+        SET_STATE_WRITE_PBC(interp);
+        if (!interp->output_file)
+            interp->output_file = "-";
+        break;
+
+      case 'O':
+        if (!opt->opt_arg) {
+            IMCC_INFO(interp)->optimizer_level |= OPT_PRE;
+            break;
+        }
+        if (strchr(opt->opt_arg, 'p'))
+            IMCC_INFO(interp)->optimizer_level |= OPT_PASM;
+        if (strchr(opt->opt_arg, 'c'))
+            IMCC_INFO(interp)->optimizer_level |= OPT_SUB;
+
+        IMCC_INFO(interp)->allocator = IMCC_GRAPH_ALLOCATOR;
+        /* currently not ok due to different register allocation */
+        if (strchr(opt->opt_arg, '1')) {
+            IMCC_INFO(interp)->optimizer_level |= OPT_PRE;
+        }
+        if (strchr(opt->opt_arg, '2')) {
+            IMCC_INFO(interp)->optimizer_level |= (OPT_PRE | OPT_CFG);
+        }
+        if (strchr(opt->opt_arg, 't')) {
+#ifdef HAVE_COMPUTED_GOTO
+            *core = PARROT_CGP_CORE;
+#else
+            *core = PARROT_SWITCH_CORE;
+#endif
+        }
+        break;
 
-    *argc -= opt.opt_index;
-    *argv += opt.opt_index;
+      default:
+        return 0;
+    }
 
-    Parrot_set_run_core(interp, (Parrot_Run_core_t) core);
-    return (*argv)[0];
+    return 1;
 }
 
 /*

Modified: trunk/compilers/pirc/src/main.c
==============================================================================
--- trunk/compilers/pirc/src/main.c	Wed Feb 10 10:31:22 2010	(r43853)
+++ trunk/compilers/pirc/src/main.c	Wed Feb 10 12:29:38 2010	(r43854)
@@ -47,6 +47,8 @@
 
 void * process_file(void *a);
 
+/* HEADERIZER HFILE: none */
+
 /*
 
 =head1 FUNCTIONS
@@ -54,8 +56,7 @@
 =over 4
 
 
-=item C<static void
-print_help(char const * const program_name)>
+=item C<static void print_help(char const * const program_name)>
 
 Routine to print usage of this program.
 
@@ -137,8 +138,7 @@
 
 /*
 
-=item C<static void
-runcode(PARROT_INTERP, int argc, char *argv[])>
+=item C<static void runcode(PARROT_INTERP, int argc, char *argv[])>
 
 This function runs the code in the interpreter's (in C<PARROT_INTERP>)
 code segment.

Modified: trunk/include/parrot/imcc.h
==============================================================================
--- trunk/include/parrot/imcc.h	Wed Feb 10 10:31:22 2010	(r43853)
+++ trunk/include/parrot/imcc.h	Wed Feb 10 12:29:38 2010	(r43854)
@@ -7,7 +7,8 @@
 #define PARROT_IMCC_H_GUARD
 
 PARROT_EXPORT void imcc_initialize(PARROT_INTERP);
-PARROT_EXPORT const char * parseflags(PARROT_INTERP, int *argc, char **argv[]);
+PARROT_EXPORT void imcc_start_handling_flags(PARROT_INTERP);
+PARROT_EXPORT int imcc_handle_flag(PARROT_INTERP, struct longopt_opt_info *opt, INTVAL *core);
 PARROT_EXPORT int imcc_run(PARROT_INTERP, const char *sourcefile, int argc, char **argv);
 
 #endif /* PARROT_IMCC_H_GUARD */

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	Wed Feb 10 10:31:22 2010	(r43853)
+++ trunk/src/main.c	Wed Feb 10 12:29:38 2010	(r43854)
@@ -23,6 +23,46 @@
 #include "parrot/parrot.h"
 #include "parrot/embed.h"
 #include "parrot/imcc.h"
+#include "parrot/longopt.h"
+#include "parrot/runcore_api.h"
+#include "pmc/pmc_callcontext.h"
+
+/* HEADERIZER HFILE: none */
+
+/* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+static void help(void);
+static void help_debug(void);
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+static int is_all_hex_digits(ARGIN(const char *s))
+        __attribute__nonnull__(1);
+
+static void Parrot_version(PARROT_INTERP)
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+static const char * parseflags(PARROT_INTERP, int *argc, char **argv[])
+        __attribute__nonnull__(1);
+
+static void usage(ARGMOD(FILE *fp))
+        __attribute__nonnull__(1)
+        FUNC_MODIFIES(*fp);
+
+#define ASSERT_ARGS_help __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_help_debug __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_is_all_hex_digits __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(s))
+#define ASSERT_ARGS_Parrot_version __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_parseflags __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_usage __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(fp))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: static */
 
 /*
 
@@ -65,6 +105,363 @@
     Parrot_exit(interp, 0);
 }
 
+#define OPT_GC_DEBUG       128
+#define OPT_DESTROY_FLAG   129
+#define OPT_HELP_DEBUG     130
+#define OPT_PBC_OUTPUT     131
+#define OPT_RUNTIME_PREFIX 132
+
+#define SET_FLAG(flag)   Parrot_set_flag(interp, (flag))
+#define SET_DEBUG(flag)  Parrot_set_debug(interp, (flag))
+#define SET_TRACE(flag)  Parrot_set_trace(interp, (flag))
+
+static struct longopt_opt_decl options[] = {
+    { '.', '.', (OPTION_flags)0, { "--wait" } },
+    { 'D', 'D', OPTION_optional_FLAG, { "--parrot-debug" } },
+    { 'E', 'E', (OPTION_flags)0, { "--pre-process-only" } },
+    { 'G', 'G', (OPTION_flags)0, { "--no-gc" } },
+    { 'I', 'I', OPTION_required_FLAG, { "--include" } },
+    { 'L', 'L', OPTION_required_FLAG, { "--library" } },
+    { 'O', 'O', OPTION_optional_FLAG, { "--optimize" } },
+    { 'R', 'R', OPTION_required_FLAG, { "--runcore" } },
+    { 'V', 'V', (OPTION_flags)0, { "--version" } },
+    { 'X', 'X', OPTION_required_FLAG, { "--dynext" } },
+    { '\0', OPT_DESTROY_FLAG, (OPTION_flags)0,
+                                 { "--leak-test", "--destroy-at-end" } },
+    { '\0', OPT_GC_DEBUG, (OPTION_flags)0, { "--gc-debug" } },
+    { 'a', 'a', (OPTION_flags)0, { "--pasm" } },
+    { 'c', 'c', (OPTION_flags)0, { "--pbc" } },
+    { 'd', 'd', OPTION_optional_FLAG, { "--imcc-debug" } },
+    { '\0', OPT_HELP_DEBUG, (OPTION_flags)0, { "--help-debug" } },
+    { 'h', 'h', (OPTION_flags)0, { "--help" } },
+    { 'o', 'o', OPTION_required_FLAG, { "--output" } },
+    { '\0', OPT_PBC_OUTPUT, (OPTION_flags)0, { "--output-pbc" } },
+    { 'r', 'r', (OPTION_flags)0, { "--run-pbc" } },
+    { '\0', OPT_RUNTIME_PREFIX, (OPTION_flags)0, { "--runtime-prefix" } },
+    { 't', 't', OPTION_optional_FLAG, { "--trace" } },
+    { 'v', 'v', (OPTION_flags)0, { "--verbose" } },
+    { 'w', 'w', (OPTION_flags)0, { "--warnings" } },
+    { 'y', 'y', (OPTION_flags)0, { "--yydebug" } },
+    { 0, 0, (OPTION_flags)0, { NULL } }
+};
+
+/*
+
+=item C<static int is_all_hex_digits(const char *s)>
+
+Tests all characters in a string are hexadecimal digits.
+Returns 1 if true, 0 as soon as a non-hex found
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_PURE_FUNCTION
+static int
+is_all_hex_digits(ARGIN(const char *s))
+{
+    ASSERT_ARGS(is_all_hex_digits)
+    for (; *s; s++)
+        if (!isxdigit(*s))
+            return 0;
+    return 1;
+}
+
+/*
+
+=item C<static void usage(FILE *fp)>
+
+Outputs usage error message.
+
+=cut
+
+*/
+
+static void
+usage(ARGMOD(FILE *fp))
+{
+    ASSERT_ARGS(usage)
+    fprintf(fp,
+            "parrot -[acEGhprtvVwy.] [-d [FLAGS]] [-D [FLAGS]]"
+            "[-O [level]] [-R runcore] [-o FILE] <file>\n");
+}
+
+/*
+
+=item C<static void help_debug(void)>
+
+Print out list of debugging flag values.
+
+=cut
+
+*/
+
+static void
+help_debug(void)
+{
+    ASSERT_ARGS(help_debug)
+    /* split printf for C89 compliance on string length */
+    printf(
+    "--imcc-debug -d [Flags] ...\n"
+    "    0002    lexer\n"
+    "    0004    parser\n"
+    "    0008    imc\n"
+    "    0010    CFG\n"
+    "    0020    optimization 1\n"
+    "    0040    optimization 2\n"
+    "    0100    AST\n"
+    "    1000    PBC\n"
+    "    2000    PBC constants\n"
+    "    4000    PBC fixups\n"
+    "\n");
+    printf(
+    "--parrot-debug -D [Flags] ...\n"
+    "    0001    memory statistics\n"
+    "    0002    print backtrace on exception\n"
+    "    0004    JIT debugging\n"
+    "    0008    interpreter startup\n"
+    "    0010    thread debugging\n"
+    "    0020    eval/compile\n"
+    "    0040    fill I, N registers with garbage\n"
+    "    0080    show when a context is destroyed\n"
+    "\n"
+    "--trace -t [Flags] ...\n"
+    "    0001    opcodes\n"
+    "    0002    find_method\n"
+    "    0004    function calls\n");
+}
+
+/*
+
+=item C<static void help(void)>
+
+Print out "help" list of options.
+
+=cut
+
+*/
+
+static void
+help(void)
+{
+    ASSERT_ARGS(help)
+    /* split printf for C89 compliance on string length */
+    printf(
+    "parrot [Options] <file>\n"
+    "  Options:\n"
+    "    -h --help\n"
+    "    -V --version\n"
+    "    -I --include add path to include search\n"
+    "    -L --library add path to library search\n"
+    "    -X --dynext add path to dynamic extension search\n"
+    "   <Run core options>\n"
+    "    -R --runcore slow|bounds|fast|cgoto|cgp\n"
+    "    -R --runcore switch|trace|profiling|gcdebug\n"
+    "    -t --trace [flags]\n"
+    "   <VM options>\n"
+    "    -D --parrot-debug[=HEXFLAGS]\n"
+    "       --help-debug\n");
+    printf(
+    "    -w --warnings\n"
+    "    -G --no-gc\n"
+    "       --gc-debug\n"
+    "       --leak-test|--destroy-at-end\n"
+    "    -. --wait    Read a keystroke before starting\n"
+    "       --runtime-prefix\n"
+    "   <Compiler options>\n"
+    "    -d --imcc-debug[=HEXFLAGS]\n"
+    "    -v --verbose\n"
+    "    -E --pre-process-only\n"
+    "    -o --output=FILE\n"
+    "       --output-pbc\n"
+    "    -O --optimize[=LEVEL]\n"
+    "    -a --pasm\n"
+    "    -c --pbc\n"
+    "    -r --run-pbc\n"
+    "    -y --yydebug\n"
+    "   <Language options>\n"
+    "see docs/running.pod for more\n");
+}
+
+
+/*
+
+=item C<static void Parrot_version(PARROT_INTERP)>
+
+Print out parrot version number.
+
+=cut
+
+*/
+
+static void
+Parrot_version(PARROT_INTERP)
+{
+    ASSERT_ARGS(Parrot_version)
+    printf("This is Parrot version " PARROT_VERSION);
+    printf(" built for " PARROT_ARCHNAME ".\n");
+    printf("Copyright (C) 2001-2010, Parrot Foundation.\n\
+\n\
+This code is distributed under the terms of the Artistic License 2.0.\
+\n\
+For more details, see the full text of the license in the LICENSE file\
+\n\
+included in the Parrot source tree.\n\n");
+
+    Parrot_exit(interp, 0);
+}
+/*
+
+=item C<static const char * parseflags(PARROT_INTERP, int *argc, char **argv[])>
+
+Parse Parrot's command line for options and set appropriate flags.
+
+=cut
+
+*/
+
+PARROT_CAN_RETURN_NULL
+static const char *
+parseflags(PARROT_INTERP, int *argc, char **argv[])
+{
+    struct longopt_opt_info opt  = LONGOPT_OPT_INFO_INIT;
+    INTVAL                  core = 0;
+    int                     status;
+
+    if (*argc == 1) {
+        usage(stderr);
+        exit(EXIT_SUCCESS);
+    }
+
+    imcc_start_handling_flags(interp);
+
+    while ((status = longopt_get(interp, *argc, (const char **)*argv, options,
+            &opt)) > 0) {
+        switch (opt.opt_id) {
+          case 'R':
+            if (STREQ(opt.opt_arg, "slow") || STREQ(opt.opt_arg, "bounds"))
+                core = PARROT_SLOW_CORE;
+            else if (STREQ(opt.opt_arg, "fast") || STREQ(opt.opt_arg, "function"))
+                core = PARROT_FAST_CORE;
+            else if (STREQ(opt.opt_arg, "switch"))
+                core = PARROT_SWITCH_CORE;
+            else if (STREQ(opt.opt_arg, "cgp"))
+                core = PARROT_CGP_CORE;
+            else if (STREQ(opt.opt_arg, "cgoto"))
+                core = PARROT_CGOTO_CORE;
+            else if (STREQ(opt.opt_arg, "jit"))
+                core = PARROT_FAST_CORE;
+            else if (STREQ(opt.opt_arg, "cgp-jit"))
+                core = PARROT_CGP_CORE;
+            else if (STREQ(opt.opt_arg, "switch-jit"))
+                core = PARROT_SWITCH_CORE;
+            else if (STREQ(opt.opt_arg, "exec"))
+                core = PARROT_EXEC_CORE;
+            else if (STREQ(opt.opt_arg, "trace"))
+                core = PARROT_SLOW_CORE;
+            else if (STREQ(opt.opt_arg, "profiling"))
+                core = PARROT_PROFILING_CORE;
+            else if (STREQ(opt.opt_arg, "gcdebug"))
+                core = PARROT_GC_DEBUG_CORE;
+            else
+                Parrot_ex_throw_from_c_args(interp, NULL, 1,
+                        "main: Unrecognized runcore '%s' specified."
+                        "\n\nhelp: parrot -h\n", opt.opt_arg);
+            break;
+          case 't':
+            if (opt.opt_arg && is_all_hex_digits(opt.opt_arg))
+                SET_TRACE(strtoul(opt.opt_arg, NULL, 16));
+            else
+                SET_TRACE(PARROT_TRACE_OPS_FLAG);
+            break;
+          case 'D':
+            if (opt.opt_arg && is_all_hex_digits(opt.opt_arg)) {
+                SET_DEBUG(strtoul(opt.opt_arg, NULL, 16));
+            }
+            else
+                SET_DEBUG(PARROT_MEM_STAT_DEBUG_FLAG);
+            break;
+          case '.':  /* Give Windows Parrot hackers an opportunity to
+                      * attach a debuggger. */
+            fgetc(stdin);
+            break;
+          case 'h':
+            help();
+            exit(EXIT_FAILURE);
+            break;
+          case OPT_HELP_DEBUG:
+            help_debug();
+            exit(EXIT_FAILURE);
+            break;
+          case OPT_RUNTIME_PREFIX:
+            Parrot_io_printf(interp, "%Ss\n",
+                    Parrot_get_runtime_path(interp));
+            exit(EXIT_SUCCESS);
+          case 'V':
+            Parrot_version(interp);
+            break;
+
+          case OPT_GC_DEBUG:
+#if DISABLE_GC_DEBUG
+            Parrot_warn(interp, PARROT_WARNINGS_ALL_FLAG,
+                        "PARROT_GC_DEBUG is set but the binary was "
+                        "compiled with DISABLE_GC_DEBUG.");
+#endif
+            SET_FLAG(PARROT_GC_DEBUG_FLAG);
+            break;
+          case OPT_DESTROY_FLAG:
+            SET_FLAG(PARROT_DESTROY_FLAG);
+            break;
+          case 'I':
+            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
+                    PARROT_LIB_PATH_INCLUDE);
+            break;
+          case 'L':
+            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
+                    PARROT_LIB_PATH_LIBRARY);
+            break;
+          case 'X':
+            Parrot_lib_add_path_from_cstring(interp, opt.opt_arg,
+                    PARROT_LIB_PATH_DYNEXT);
+            break;
+          default:
+            /* Delegate handling of IMCC flags to IMCC */
+            if (imcc_handle_flag(interp, &opt, &core))
+                break;
+
+            /* PIRC flags handling goes here */
+            Parrot_ex_throw_from_c_args(interp, NULL, 1,
+                    "main: Invalid flag '%s' used.\n\nhelp: parrot -h\n",
+                    (*argv)[0]);
+        }
+    }
+
+    if (status == -1) {
+        fprintf(stderr, "%s\n", opt.opt_error);
+        usage(stderr);
+        exit(EXIT_FAILURE);
+    }
+
+    /* reached the end of the option list and consumed all of argv */
+    if (*argc == opt.opt_index) {
+        if (interp->output_file) {
+            fprintf(stderr, "Missing program name or argument for -o\n");
+        }
+        else {
+            /* We are not looking at an option, so it must be a program name */
+            fprintf(stderr, "Missing program name\n");
+        }
+        usage(stderr);
+        exit(EXIT_FAILURE);
+    }
+
+    *argc -= opt.opt_index;
+    *argv += opt.opt_index;
+
+    Parrot_set_run_core(interp, (Parrot_Run_core_t) core);
+    return (*argv)[0];
+}
 /*
 
 =back


More information about the parrot-commits mailing list