Patch attached implements an embedding interface for Parrot and
re-writes test_main.c to use it.  It also rewrites the switch handling
stuff into something that looks decent and adds -h (help) and -v
(version) switches.

I'd like to emphasize that this interface is preliminary.  Several
functions are missing, and at least one function is temporary.  Still,
this'll probably be enough to be usable.

Unfortunately, I will probably not be able to apply this myself.  In the
course of making the patch, I accidentally did a 'make distclean'
instead of 'make cvsclean', and I *still* don't have a usable patch
program, so I'll probably have to resync from the original and lose all
my changes, plus my work-in-progress on jsr and friends.  Ugh.

--Brent Dax
[EMAIL PROTECTED]
Parrot Configure pumpking and regex hacker
Check out the Parrot FAQ: http://www.panix.com/~ziggy/parrot.html (no,
it's not mine)

<obra> mmmm. hawt sysadmin chx0rs
<lathos> This is sad. I know of *a* hawt sysamin chx0r.
<obra> I know more than a few.
<lathos> obra: There are two? Are you sure it's not the same one?
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/MANIFEST /parrot/MANIFEST
--- /parrot-cvs/MANIFEST        Mon Jan 28 23:28:18 2002
+++ /parrot/MANIFEST    Mon Jan 28 23:30:38 2002
@@ -69,6 +69,7 @@
 docs/strings.pod
 docs/tests.pod
 docs/vtables.pod
+embed.c
 encoding.c
 encodings/singlebyte.c
 encodings/utf16.c
@@ -106,6 +107,7 @@
 hints/vms.pl
 include/parrot/chartype.h
 include/parrot/encoding.h
+include/parrot/embed.h
 include/parrot/events.h
 include/parrot/exceptions.h
 include/parrot/global_setup.h
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/Makefile.in /parrot/Makefile.in
--- /parrot-cvs/Makefile.in     Mon Jan 28 23:28:18 2002
+++ /parrot/Makefile.in Mon Jan 28 23:28:48 2002
@@ -63,7 +63,7 @@
 $(INC)/global_setup.h $(INC)/vtable.h $(INC)/oplib/core_ops.h 
$(INC)/oplib/core_ops_prederef.h \
 $(INC)/runops_cores.h $(INC)/trace.h \
 $(INC)/pmc.h $(INC)/key.h $(INC)/resources.h $(INC)/platform.h \
-$(INC)/interp_guts.h ${jit_h} ${jit_struct_h} $(INC)/rx.h $(INC)/rxstacks.h
+$(INC)/interp_guts.h ${jit_h} ${jit_struct_h} $(INC)/rx.h $(INC)/rxstacks.h 
+$(INC)/embed.h
 
 CLASS_O_FILES = classes/default$(O) classes/array$(O) \
 classes/perlint$(O) classes/perlstring$(O) classes/perlnum$(O) \
@@ -80,7 +80,7 @@
 INTERP_O_FILES = exceptions$(O) global_setup$(O) interpreter$(O) parrot$(O) 
register$(O) \
 core_ops$(O) core_ops_prederef$(O) memory$(O) packfile$(O) stacks$(O) \
 string$(O) encoding$(O) chartype$(O) runops_cores$(O) trace$(O) pmc$(O) key$(O) \
-platform$(O) ${jit_o} resources$(O) rx$(O) rxstacks$(O)
+platform$(O) ${jit_o} resources$(O) rx$(O) rxstacks$(O) embed$(O)
 
 O_FILES = $(INTERP_O_FILES) $(IO_O_FILES) $(CLASS_O_FILES) $(ENCODING_O_FILES) 
$(CHARTYPE_O_FILES)
 
@@ -308,6 +308,8 @@
 rxstacks$(O): $(H_FILES)
 
 stacks$(O): $(H_FILES)
+
+embed$(O): $(H_FILES)
 
 core_ops$(O): $(H_FILES) core_ops.c
 
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/config_h.in /parrot/config_h.in
--- /parrot-cvs/config_h.in     Mon Jan 14 01:19:28 2002
+++ /parrot/config_h.in Mon Jan 28 21:48:34 2002
@@ -6,7 +6,11 @@
 
 #if !defined(PARROT_CONFIG_H_GUARD)
 #define PARROT_CONFIG_H_GUARD
+
+#if defined(PARROT_IN_CORE
+
 #include <stddef.h>
+
 typedef ${iv} INTVAL;
 typedef unsigned ${iv} UINTVAL;
 typedef ${nv} FLOATVAL;
@@ -41,11 +45,6 @@
 #define JIT_ARCHNAME "${jitarchname}"
 #define JIT_CAPABLE  ${jitcapable}
 
-#define PARROT_VERSION         "${VERSION}"
-#define PARROT_MAJOR_VERSION   ${MAJOR}
-#define PARROT_MINOR_VERSION   ${MINOR}
-#define PARROT_PATCH_VERSION   ${PATCH}
-
 #define PARROT_CORE_OPLIB_NAME "core"
 #define PARROT_CORE_OPLIB_INIT Parrot_DynOp_core_${MAJOR}_${MINOR}_${PATCH}
 
@@ -54,5 +53,12 @@
 
 ${headers}
 
+#endif
+
+#define PARROT_VERSION         "${VERSION}"
+#define PARROT_MAJOR_VERSION   ${MAJOR}
+#define PARROT_MINOR_VERSION   ${MINOR}
+#define PARROT_PATCH_VERSION   ${PATCH}
+#define PARROT_ARCHNAME        "${jitarchname}"
 
 #endif
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/embed.c /parrot/embed.c
--- /parrot-cvs/embed.c Wed Dec 31 16:00:00 1969
+++ /parrot/embed.c     Mon Jan 28 23:23:28 2002
@@ -0,0 +1,183 @@
+#include "parrot/parrot.h"
+#include "parrot/embed.h"
+
+static BOOLVAL world_inited=0;
+
+struct Parrot_Interp *
+Parrot_new() {
+    return make_interpreter(0);
+}
+
+void
+Parrot_init(struct Parrot_Interp *interpreter) {
+    if(!world_inited) {
+        world_inited=1;
+        init_world();
+    }
+}
+
+void
+Parrot_setflag(struct Parrot_Interp *interpreter, Parrot_flag flag, Parrot_flag_val 
+value) {
+    interpreter->flags |= flag;
+}
+
+struct PackFile *
+Parrot_readbc(struct Parrot_Interp *interpreter, char *filename) {
+    /* XXX This ugly mess ought to be cleanupable. */
+    int fd;
+    struct stat file_stat;
+
+    opcode_t program_size;
+    char *program_code;
+    struct PackFile *pf;
+
+    if(strcmp(filename, "-")==0) { /* read from STDIN */
+        char *cursor;
+        INTVAL read_result;
+
+        program_size = 0;
+           
+        program_code = (char*)malloc(program_size + 1024);
+        if (NULL == program_code) {
+            fprintf(stderr, "Parrot VM: Could not allocate buffer to read packfile 
+from stdin.\n");
+            return NULL;
+        }
+        cursor = (char*)program_code;
+
+        while ((read_result = read(0, cursor, 1024)) > 0) {
+            program_size += read_result;
+            program_code = realloc(program_code, program_size + 1024);
+
+            if (NULL == program_code) {
+                fprintf(stderr, "Parrot VM: Could not reallocate buffer while reading 
+packfile from stdin.\n");
+                return NULL;
+            }
+
+            cursor = (char*)program_code + program_size;
+        }
+
+        if (read_result < 0) {
+            fprintf(stderr, "Parrot VM: Problem reading packfile from stdin.\n");
+            return NULL;
+        }
+    }
+    else {
+        if (stat(filename, &file_stat)) {
+            fprintf(stderr, "Parrot VM: Can't stat %s, code %i.\n", filename, errno);
+            return NULL;
+        }
+        fd = open(filename, O_RDONLY);
+        if (!fd) {
+             fprintf(stderr, "Parrot VM: Can't open %s, code %i.\n", filename, errno);
+             return NULL;
+        }
+            
+        program_size = file_stat.st_size;
+
+#ifndef HAS_HEADER_SYSMMAN
+
+        program_code = (char*)mem_sys_allocate(program_size);
+        read(fd, (void*)program_code, program_size);
+
+        if (!program_code) {
+            fprintf(stderr, "Parrot VM: Can't read file %s, code %i.\n", filename, 
+errno);
+            return NULL;
+        }
+
+#else
+
+        program_code = mmap(0, program_size, PROT_READ, MAP_SHARED, fd, (off_t)0);
+
+        if (!program_code) {
+            fprintf(stderr, "Parrot VM: Can't read file %s, code %i.\n", filename, 
+errno);
+            return NULL;
+        }
+
+#endif
+
+    }
+
+    pf = PackFile_new();
+
+    if(!PackFile_unpack(interpreter, pf, program_code, program_size) ) {
+        fprintf(stderr, "Parrot VM: Can't unpack packfile %s.\n", filename);
+        return NULL;
+    }
+
+    return pf;
+}
+
+void
+Parrot_loadbc(struct Parrot_Interp *interpreter, struct PackFile *pf) {
+    interpreter->code=pf;
+}
+
+void
+Parrot_runcode(struct Parrot_Interp *interpreter, int argc, char *argv[]) {
+    if(interpreter->flags & PARROT_DEBUG_FLAG) {
+        fprintf(stderr, "Parrot VM: Debugging enabled.\n");
+
+        if(interpreter->flags & PARROT_BOUNDS_FLAG) {
+            fprintf(stderr, "Parrot VM: Bounds checking enabled.\n");
+        }
+        if(interpreter->flags & PARROT_PREDEREF_FLAG) {
+            fprintf(stderr, "Parrot VM: Predereferencing enabled.\n");
+        }
+        if(interpreter->flags & PARROT_JIT_FLAG) {
+            fprintf(stderr, "Parrot VM: JIT enabled.\n");
+        }
+    }
+
+    if(!JIT_CAPABLE && interpreter->flags & PARROT_JIT_FLAG) {
+        fprintf(stderr, "Parrot VM: Platform " JIT_ARCHNAME " is not JIT-capable.\n");
+        exit(1);
+    }
+
+    runops(interpreter, interpreter->code, 0);
+
+    /*
+    ** If any profile information was gathered, print it out:
+    */
+
+    if (interpreter->profile != NULL) {
+        unsigned int j;
+        int op_count   = 0;
+        int call_count = 0;
+        FLOATVAL time = 0.0;
+
+        printf("Operation profile:\n\n");
+
+        printf("  CODE   OP FULL NAME  CALLS         TOTAL TIME  AVG TIME  \n");
+        printf("  -----  ------------  ------------  ----------  ----------\n");
+
+        for (j = 0; j < interpreter->op_count; j++) {
+            if(interpreter->profile[j].numcalls > 0) {
+                op_count++;
+                call_count += interpreter->profile[j].numcalls;
+                time += interpreter->profile[j].time;
+
+                printf("  %5d  %-12s  %12ld  %5.6f  %5.6f\n", j, 
+                       interpreter->op_info_table[j].full_name,
+                       interpreter->profile[j].numcalls,
+                       interpreter->profile[j].time,
+                       interpreter->profile[j].time / 
+(FLOATVAL)interpreter->profile[j].numcalls
+                );
+            }
+        }
+
+        printf("  -----  ------------  ------------  ----------  ----------\n");
+        printf("  %5d  %-12s  %12d  %5.6f  %5.6f\n", 
+            op_count,
+            "",
+            call_count,
+            time,
+            time / (FLOATVAL)call_count
+        );
+    }
+}
+
+void
+Parrot_destroy(struct Parrot_Interp *interp) {
+    free(interp);
+}
+
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/include/parrot/embed.h 
/parrot/include/parrot/embed.h
--- /parrot-cvs/include/parrot/embed.h  Wed Dec 31 16:00:00 1969
+++ /parrot/include/parrot/embed.h      Mon Jan 28 21:49:04 2002
@@ -0,0 +1,35 @@
+#if !defined(PARROT_EMBED_H_GUARD)
+#define PARROT_EMBED_H_GUARD
+
+#include "parrot/config.h"
+
+typedef int Parrot_flag;
+typedef void * Parrot_flag_val;
+
+/* plucked these straight from interpreter.h */
+#define PARROT_DEBUG_FLAG    0x01  /* We're debugging */
+#define PARROT_TRACE_FLAG    0x02  /* We're tracing execution */
+#define PARROT_BOUNDS_FLAG   0x04  /* We're tracking byte code bounds */
+#define PARROT_PROFILE_FLAG  0x08  /* We're gathering profile information */
+#define PARROT_PREDEREF_FLAG 0x10  /* We're using the prederef runops */
+#define PARROT_JIT_FLAG      0x20  /* We're using the jit runops */
+
+/* These two are basically Magic Cookies to the outside world. */
+struct Parrot_Interp;
+struct PackFile;
+
+struct Parrot_Interp *interp_new();
+
+void Parrot_init(struct Parrot_Interp *);
+
+void Parrot_setflag(struct Parrot_Interp *, Parrot_flag, Parrot_flag_val);
+
+struct PackFile * Parrot_readbc(struct Parrot_Interp *, char *);
+
+void Parrot_loadbc(struct Parrot_Interp *, struct PackFile *);
+
+void Parrot_runcode(struct Parrot_Interp *, int argc, char *argv[]);
+
+void Parrot_destroy(struct Parrot_Interp *);
+
+#endif
\ No newline at end of file
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/include/parrot/parrot.h 
/parrot/include/parrot/parrot.h
--- /parrot-cvs/include/parrot/parrot.h Mon Jan 28 23:28:22 2002
+++ /parrot/include/parrot/parrot.h     Mon Jan 28 23:28:54 2002
@@ -24,6 +24,8 @@
 #define VAR_SCOPE extern
 #endif
 
+#define PARROT_IN_CORE
+
 #include "parrot/config.h"
 
 #include <stdlib.h>
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/test_main.c /parrot/test_main.c
--- /parrot-cvs/test_main.c     Mon Jan 28 23:28:18 2002
+++ /parrot/test_main.c Mon Jan 28 23:23:32 2002
@@ -1,7 +1,7 @@
 /* test_main.c
  *  Copyright: (When this is determined...it will go here)
  *  CVS Info
- *     $Id: test_main.c,v 1.39 2002/01/28 15:59:28 simon Exp $
+ *     $Id: test_main.c,v 1.35 2002/01/14 20:03:52 dan Exp $
  *  Overview:
  *     A sample test program
  *  Data Structure and Algorithms:
@@ -9,244 +9,126 @@
  *  Notes:
  *  References:
  */
+#include "parrot/embed.h"
+#include <stdio.h>
 
-#include "parrot/parrot.h"
+#define setopt(flag) Parrot_setflag(interpreter, flag, (*argv)[0]+2);
 
-#include "parrot/oplib/core_ops.h"
+char *
+parseflags(struct Parrot_Interp *interpreter, int *argc, char **argv[]);
+
+void
+usage();
+
+void
+version();
 
 int
-main(int argc, char **argv) {
-    int i;
-    int flags;
-    int bounds_checking;
-    int profiling;
-    int tracing;
-    int debugging;
-    int predereferencing;
-    int jit;
-    int from_stdin;
-    int from_file;
+main(int argc, char *argv[]) {
+    struct Parrot_Interp *interpreter;
     char *filename;
-    char **argp;
+    struct PackFile *pf;
+    
+    interpreter=Parrot_new();
 
-    struct Parrot_Interp *interpreter;
-    init_world();
-  
-    /*
-    ** Look for the switches:
-    **
-    **   -d  debugging
-    **   -b  bounds checking
-    **   -j  JIT
-    **   -p  profiling
-    **   -P  predereferencing
-    **   -t  tracing
-    **   -f  filename or stdin
-    **
-    */
-    argp             = argv+1;
-    flags            = 0;
-    bounds_checking  = 0;
-    profiling        = 0;
-    tracing          = 0;
-    debugging        = 0;
-    predereferencing = 0;
-    jit              = 0;
-    from_stdin       = 0;
-    from_file        = 0;
-    filename         = NULL;
-
-    while (*argp && (*argp)[0] == '-') {
-        if((*argp)[2] != '\0')
-            internal_exception(PARROT_USAGE_ERROR,
-                        "%s: Invalid switch: %s\n", argv[0], (*argp));
- 
-        switch((*argp)[1]) {
-            case 'd':   debugging = 1;
-                        argp++; break;
-            case 'b':   bounds_checking = 1;
-                        argp++; break;
-            case 'j':   jit = 1;
-                        argp++; break;
-            case 'p':   profiling = 1;
-                        argp++; break;
-            case 'P':   predereferencing = 1;
-                        argp++; break;
-            case 't':   tracing = 1;
-                        argp++; break;
-            case 'f':   if(*(++argp) == NULL)
-                                internal_exception(PARROT_USAGE_ERROR,
-                                        "%s: -f requires an argument\n",
-                                                argv[0]);
-
-                        if(strcmp("-", (*argp)) == 0) {
-                            from_stdin = 1;
-                        } else {
-                            filename = malloc(strlen((*argp))+1);
-                            filename = strcpy(filename, (*argp));
-                        }
-                        argp++; break;
-            default:
-                        internal_exception(PARROT_USAGE_ERROR,
-                                "%s: Invalid switch: %s\n",
-                                        argv[0], (*argp));
-        }
+    if(!interpreter) {
+        return 1;
     }
 
-    if (debugging)              flags |= PARROT_DEBUG_FLAG;
-    if (profiling)              flags |= PARROT_PROFILE_FLAG;
-    if (predereferencing)       flags |= PARROT_PREDEREF_FLAG;
-    if (tracing)                flags |= PARROT_TRACE_FLAG;
-    if (bounds_checking)        flags |= PARROT_BOUNDS_FLAG;
-    if (jit)                    flags |= PARROT_JIT_FLAG;
- 
-#if !JIT_CAPABLE
-    if(jit)
-        internal_exception( JIT_UNAVAILABLE, "%s: Cannot use the '-j' JIT-enabling 
flag on this architecture: " JIT_ARCHNAME "\n", argv[0]);
-#endif
+    Parrot_init(interpreter);
 
-    if(debugging)
-        fprintf(stderr, "Parrot VM: Debugging enabled.\n");
+    filename=parseflags(interpreter, &argc, &argv);
 
-    interpreter = make_interpreter(flags);
-    
-    /* If we got only the program name, complain */
+    pf=Parrot_readbc(interpreter, filename);
 
-    if (*argp == NULL && !filename && !from_stdin) {
-        internal_exception(PARROT_USAGE_ERROR, "%s: usage: %s prog\n", argv[0], 
argv[0]);
+    if(!pf) {
+        return 1;
     }
-    /* Otherwise load in the program they gave and try that, or - */
-    else {
-        opcode_t *program_code;
-#ifdef __LCC__
-        /* work around for a code generation bug in our lcc test environment */
-        int program_size;
-#else       
-        size_t program_size;
-#endif       
-        struct stat file_stat;
-        int fd;
-        struct PackFile * pf;
-
-        if (from_stdin) {
-            char *cursor;
-            INTVAL read_result;
-
-            program_size = 0;
-            
-            program_code = (opcode_t*)malloc(program_size + 1024);
-            if (NULL == program_code) {
-                fprintf(stderr, "Could not allocate buffer to read stdin\n");
-            }
-            cursor = (char*)program_code;
-
-            while ((read_result = read(0, cursor, 1024)) > 0) {
-                program_size += read_result;
-                program_code = realloc(program_code, program_size + 1024);
-                if (NULL == program_code) {
-                    fprintf(stderr,
-                            "Could not reallocate buffer to read stdin\n");
-                }
-                cursor = (char*)program_code + program_size;
-            }
-
-            if (read_result < 0) {
-                internal_exception(PIO_ERROR,"Problem reading from stdin\n");
-            }
-        }
-        else { /* read from file */
-            if (!filename) {
-                filename = malloc(strlen((*argp))+1);
-                strcpy(filename, (*argp));
-            }
-
-            if (stat(filename, &file_stat)) {
-                printf("can't stat %s, code %i\n", filename, errno);
-                return 1;
-            }
-            if (!S_ISREG(file_stat.st_mode)) {
-                printf("%s is not a regular file\n", filename);
-                return 1;
-            }
-            fd = open(filename, O_RDONLY);
-            if (!fd) {
-                printf("Can't open, error %i\n", errno);
-                return 1;
-            }
-            
-            program_size = file_stat.st_size;
-
-#ifndef HAS_HEADER_SYSMMAN
-            program_code = (opcode_t*)mem_sys_allocate(program_size);
-            read(fd, (void*)program_code, program_size);
-#else
-            program_code = 
-                (opcode_t *) mmap(0, program_size, PROT_READ,
-                                  MAP_SHARED, fd, (off_t)0);
-#endif
-        } /* end reading from file */
-
-        if (!program_code) {
-            printf("Can't mmap, code %i\n", errno);
-            return 1;
-        }
-        
-        pf = PackFile_new();
-        if( !PackFile_unpack(interpreter, pf, (char *)program_code, 
-                             (size_t)program_size) ) {
-            printf( "Can't unpack.\n" );
-            return 1;
-        }
 
-        /*
-        ** Run the interpreter loop:
-        */
-
-        runops(interpreter, pf, 0);
-
-        /*
-        ** If any profile information was gathered, print it out:
-        */
-
-        if (interpreter->profile != NULL) {
-            unsigned int j;
-            int op_count   = 0;
-            int call_count = 0;
-            FLOATVAL sum_time = 0.0;
-
-            printf("Operation profile:\n\n");
-
-            printf("  CODE   OP FULL NAME  CALLS        TOTAL TIME AVG TIME  \n");
-            printf("  -----  ------------  ------------ ---------- ----------\n");
-
-            for (j = 0; j < interpreter->op_count; j++) {
-                if(interpreter->profile[j].numcalls > 0) {
-                    op_count++;
-                    call_count += interpreter->profile[j].numcalls;
-                    sum_time += interpreter->profile[j].time;
-
-                    printf("  %5d  %-12s  %12ld  %5.6f  %5.6f\n", j, 
-                           interpreter->op_info_table[j].full_name,
-                           interpreter->profile[j].numcalls,
-                           interpreter->profile[j].time,
-                           interpreter->profile[j].time / 
(FLOATVAL)interpreter->profile[j].numcalls
-                    );
-                }
-
-            }
-
-            printf("  -----  ------------  ------------ ---------- ----------\n");
-            printf("  %5d  %-12s  %12d  %5.6f  %5.6f\n", 
-                op_count,
-                "",
-                call_count,
-                sum_time,
-                sum_time / (FLOATVAL)call_count
-            );
+    Parrot_loadbc(interpreter, pf);
+    Parrot_runcode(interpreter, argc, argv);
+    Parrot_destroy(interpreter);
+
+    return 0;
+}
+
+char *
+parseflags(struct Parrot_Interp *interpreter, int *argc, char **argv[]) {
+    if(*argc==1) {
+        usage();
+    }
+
+    /* skip the program name arg */
+    (*argc)--;
+    (*argv)++;
+
+    while ((*argc) && (*argv)[0][0] == '-') {
+        switch((*argv)[0][1]) {
+           case 'b':
+               setopt(PARROT_BOUNDS_FLAG); break;
+           case 'j':
+               setopt(PARROT_JIT_FLAG); break;
+           case 'p':
+               setopt(PARROT_PROFILE_FLAG); break;
+           case 'P':
+               setopt(PARROT_PREDEREF_FLAG); break;
+           case 't':
+               setopt(PARROT_TRACE_FLAG); break;
+           case 'd':
+               setopt(PARROT_DEBUG_FLAG); break;
+           case 'h':
+               usage(); break;
+           case 'v':
+               version(); break;
+           case '-':
+               (*argc)--;
+               (*argv)++;
+               goto OUT;
+           case '\0': /* bare '-' means read from stdin */
+               goto OUT;
+           default:
+               fprintf(stderr, "test_parrot: Invalid flag %c used", (*argv)[0][1]);
+               exit(1);
         }
+        
+        (*argc)--;
+        (*argv)++;
     }
+    
+OUT:
+    (*argc)--;
+    return (*(argv++))[0];
+}
+
+void usage() {
+    fprintf(stderr,
+"Usage: test_parrot [switches] [--] programfile [arguments]\n\
+  -b   Activate bounds checks\n\
+  -d   Activate debugging\n\
+  -h   Display this message\n\
+  -j   Activate Just-In-Time compiler\n\
+  -p   Activate profiling\n\
+  -P   Activate predereferencing\n\
+  -t   Activate tracing\n\
+  -v   Display version information\n\n");
+
+    exit(0);
+}
+
+void version() {
+    fprintf(stderr, 
+"This is parrot version " PARROT_VERSION " (with development patches) built for " 
+PARROT_ARCHNAME "\n\
+Copyright (C) 2001-2002 Yet Another Society.  All Rights Reserved.\n\
+\n\
+Parrot may be copied only under the terms of either the Artistic License or the\n\
+GNU General Public License, which may be found in the Parrot source kit.\n\
+\n\
+This program is distributed in the hope that it will be useful,\n\
+but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either\n\
+the GNU General Public License or the Artistic License for more details.\n\n");
 
-    return 0;
+    exit(0);
 }
 
 /*

Reply via email to