Argh, I accidentally sent TWO patch.txt's.  The one attached to THIS
message is the right one.

--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        Tue Feb  5 00:36:28 2002
+++ /parrot/MANIFEST    Tue Feb  5 00:40:00 2002
@@ -93,6 +93,7 @@
 include/parrot/jit.h
 include/parrot/key.h
 include/parrot/memory.h
+include/parrot/misc.h
 include/parrot/op.h
 include/parrot/oplib.h
 include/parrot/packfile.h
@@ -109,6 +110,7 @@
 include/parrot/string_funcs.h
 include/parrot/trace.h
 include/parrot/unicode.h
+include/parrot/warnings.h
 interpreter.c
 io.ops
 io/TODO
@@ -200,6 +202,7 @@
 make_vtable_ops.pl
 manicheck.pl
 memory.c
+misc.c
 obscure.ops
 ops2c.pl
 ops2pm.pl
@@ -250,3 +253,4 @@
 trace.c
 vtable.tbl
 vtable_h.pl
+warnings.c
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/Makefile.in /parrot/Makefile.in
--- /parrot-cvs/Makefile.in     Tue Feb  5 00:36:28 2002
+++ /parrot/Makefile.in Tue Feb  5 00:35:48 2002
@@ -63,10 +63,12 @@
 GENERAL_H_FILES = $(INC)/config.h $(INC)/exceptions.h $(INC)/io.h $(INC)/op.h \
 $(INC)/register.h $(INC)/string.h $(INC)/events.h $(INC)/interpreter.h \
 $(INC)/memory.h $(INC)/parrot.h $(INC)/stacks.h $(INC)/packfile.h \
-$(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)/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} $(INC)/rx.h $(INC)/rxstacks.h $(INC)/embed.h
+$(INC)/interp_guts.h ${jit_h} $(INC)/rx.h $(INC)/rxstacks.h \
+$(INC)/embed.h $(INC)/warnings.h $(INC)/misc.h
+
 ALL_H_FILES = $(GENERAL_H_FILES) ${jit_struct_h}
 
 CLASS_O_FILES = classes/default$(O) classes/array$(O) \
@@ -84,7 +86,8 @@
 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) embed$(O)
+platform$(O) ${jit_o} resources$(O) rx$(O) rxstacks$(O) embed$(O) warnings$(O) \
+misc$(O)
 
 O_FILES = $(INTERP_O_FILES) $(IO_O_FILES) $(CLASS_O_FILES) $(ENCODING_O_FILES) 
$(CHARTYPE_O_FILES)
 
@@ -167,30 +170,30 @@
        $(LD) $(LD_SHARED) -Wl,-soname,libparrot$(SO).${MAJOR} $(LDFLAGS) 
$(LD_OUT)blib/lib/libparrot$(SO).${VERSION} $(O_FILES)
 
 blib/lib/libparrot$(SO).${MAJOR}.${MINOR}: blib/lib/libparrot$(SO).${VERSION}
-       rm -f $@
+       $(RM_F) $@
        cd blib/lib; ln -s libparrot$(SO).${VERSION} libparrot$(SO).${MAJOR}.${MINOR}
 
 blib/lib/libparrot$(SO).${MAJOR}: blib/lib/libparrot$(SO).${MAJOR}.${MINOR}
-       rm -f $@
+       $(RM_F) $@
        cd blib/lib; ln -s libparrot$(SO).${MAJOR}.${MINOR} libparrot$(SO).${MAJOR}
 
 blib/lib/libparrot$(SO): blib/lib/libparrot$(SO).${MAJOR}
-       rm -f $@
+       $(RM_F) $@
        cd blib/lib; ln -s libparrot$(SO).${MAJOR} libparrot$(SO)
 
 blib/lib/libcore_prederef$(SO).${VERSION}: blib_lib core_ops_prederef$(O)
        $(LD) $(LD_SHARED) -Wl,-soname,libparrot$(SO).${MAJOR} $(LDFLAGS) 
$(LD_OUT)blib/lib/libcore_prederef$(SO).${VERSION} core_ops_prederef$(O)
 
 blib/lib/libcore_prederef$(SO).${MAJOR}.${MINOR}: 
blib/lib/libcore_prederef$(SO).${VERSION}
-       rm -f $@
+       $(RM_F) $@
        cd blib/lib; ln -s libcore_prederef$(SO).${VERSION} 
libcore_prederef$(SO).${MAJOR}.${MINOR}
 
 blib/lib/libcore_prederef$(SO).${MAJOR}: 
blib/lib/libcore_prederef$(SO).${MAJOR}.${MINOR}
-       rm -f $@
+       $(RM_F) $@
        cd blib/lib; ln -s libcore_prederef$(SO).${MAJOR}.${MINOR} 
libcore_prederef$(SO).${MAJOR}
 
 blib/lib/libcore_prederef$(SO): blib/lib/libcore_prederef$(SO).${MAJOR}
-       rm -f $@
+       $(RM_F) $@
        cd blib/lib; ln -s libcore_prederef$(SO).${MAJOR} libcore_prederef$(SO)
 
 $(TEST_PROG_SO): test_main$(O) blib/lib/libparrot$(SO) lib/Parrot/OpLib/core.pm 
lib/Parrot/PMC.pm
@@ -332,6 +335,10 @@
 
 core_ops_prederef.c $(INC)/oplib/core_ops_prederef.h: $(OPS_FILES) ops2c.pl 
lib/Parrot/OpsFile.pm lib/Parrot/Op.pm
        $(PERL) ops2c.pl CPrederef $(OPS_FILES)
+
+warnings$(O): $(H_FILES)
+
+misc$(O): $(H_FILES)
 
 vtable.ops: make_vtable_ops.pl
        $(PERL) make_vtable_ops.pl > vtable.ops
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/classes/perlundef.pmc 
/parrot/classes/perlundef.pmc
--- /parrot-cvs/classes/perlundef.pmc   Mon Jan 28 23:28:20 2002
+++ /parrot/classes/perlundef.pmc       Sun Feb  3 01:39:52 2002
@@ -45,6 +45,7 @@
    }
 
    INTVAL get_integer () {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+integer context");
       return 0;
    }
 
@@ -52,6 +53,7 @@
    }
 
    FLOATVAL get_number () {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+numeric context");
       return 0;
    }
 
@@ -60,7 +62,8 @@
    }
 
    STRING* get_string () {
-      return string_make(INTERP,NULL,0,NULL,0,NULL);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+string context");
+      return NULL;
    }
 
    STRING* get_string_index (INTVAL idx) {
@@ -68,10 +71,12 @@
    }
 
    BOOLVAL get_bool () {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+boolean context");
       return 0;
    }
 
    void* get_value () {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of unintialized value");
       return NULL;
    }
 
@@ -155,182 +160,259 @@
    }
 
    void add (PMC * value,  PMC* dest) {
-        if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) {
-           dest->vtable->set_integer_native(INTERP, dest, 0);
-       }
-        else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) {
-           dest->vtable->set_integer(INTERP, dest, value);
-       }
-       else {
-           dest->vtable->set_number(INTERP, dest, value);
-       }
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+addition");
+      
+      if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) {
+         dest->vtable->set_integer_native(INTERP, dest, 0);
+      }
+      else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) {
+         dest->vtable->set_integer(INTERP, dest, value);
+      }
+      else {
+         dest->vtable->set_number(INTERP, dest, value);
+      }
    }
 
    void add_int (INTVAL value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, value);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+integer addition");
+      dest->vtable->set_integer_native(INTERP, dest, value);
    }
 
    void add_bigint (BIGINT value,  PMC* dest) {
    }
 
    void add_float (FLOATVAL value,  PMC* dest) {
-       dest->vtable->set_number_native(INTERP, dest, value);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+numeric addition");
+      dest->vtable->set_number_native(INTERP, dest, value);
    }
 
    void add_bigfloat (BIGFLOAT value,  PMC* dest) {
    }
 
    void add_same (PMC * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of two uninitialized 
+values in addition");
       dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void subtract (PMC * value,  PMC* dest) {
-        if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) {
-           dest->vtable->set_integer_native(INTERP, dest, 0);
-       }
-        else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) {
-           dest->vtable->set_integer_native(INTERP, dest,
-               -value->vtable->get_integer(INTERP, value));
-       }
-       else {
-           dest->vtable->set_number_native(INTERP, dest,
-               -value->vtable->get_number(INTERP, value));
-       }
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+subtraction");
+      
+      if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) {
+         dest->vtable->set_integer_native(INTERP, dest, 0);
+      }
+      else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) {
+         dest->vtable->set_integer_native(
+           INTERP, dest, 0-value->vtable->get_integer(INTERP, value) 
+           /* It doesn't hurt to be more explicit */
+         );
+      }
+      else {
+         dest->vtable->set_number_native(INTERP, dest, 
+0-value->vtable->get_number(INTERP, value));
+      }
    }
 
    void subtract_int (INTVAL value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, -value);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+integer subtraction");
+      dest->vtable->set_integer_native(INTERP, dest, 0-value);
    }
 
    void subtract_bigint (BIGINT value,  PMC* dest) {
    }
 
    void subtract_float (FLOATVAL value,  PMC* dest) {
-       dest->vtable->set_number_native(INTERP, dest, -value);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+numeric subtraction");
+      dest->vtable->set_number_native(INTERP, dest, 0-value);
    }
 
    void subtract_bigfloat (BIGFLOAT value,  PMC* dest) {
    }
 
    void subtract_same (PMC * value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of two uninitialized 
+values in subtraction");
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void multiply (PMC * value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+multiplication");
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void multiply_int (INTVAL value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+integer multiplication");
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void multiply_bigint (BIGINT value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+bigint multiplication");
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void multiply_float (FLOATVAL value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+numeric multiplication");
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void multiply_bigfloat (BIGFLOAT value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+bigfloat multiplication");
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void multiply_same (PMC * value,  PMC* dest) {
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of two uninitialized 
+values in multiplication");
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void divide (PMC * value,  PMC* dest) {
-       if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) {
-               internal_exception(DIV_BY_ZERO, "division by zero!\n");
-       }
-       else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) {
-           if(value->vtable->get_integer(INTERP, value) == 0) {
-                       internal_exception(DIV_BY_ZERO, "division by zero!\n");
-           }
-       }
-       else if(value->vtable->get_number(INTERP, value) == 0) {
-               internal_exception(DIV_BY_ZERO, "division by zero!\n");
-       }
-
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+division");
+      if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) {
+         if(value->vtable->get_integer(INTERP, value) == 0) {
+            internal_exception(DIV_BY_ZERO, "division by zero!\n");
+         }
+      }
+      else if(value->vtable->get_number(INTERP, value) == 0) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void divide_int (INTVAL value,  PMC* dest) {
-       if(value == 0) {
-               internal_exception(DIV_BY_ZERO, "division by zero!\n");
-       }
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+integer division");
+      if(value == 0) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void divide_bigint (BIGINT value,  PMC* dest) {
-       /* need test for value == 0 */
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+bigint division");
+      /* need test for value == 0 */
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void divide_float (FLOATVAL value,  PMC* dest) {
-       if(value == 0) {
-               internal_exception(DIV_BY_ZERO, "division by zero!\n");
-       }
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+numeric division");
+      if(value == 0) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void divide_bigfloat (BIGFLOAT value,  PMC* dest) {
-       /* need test for value == 0 */
-       dest->vtable->set_integer_native(INTERP, dest, 0);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+bigfloat division");
+      /* need test for value == 0 */
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void divide_same (PMC * value,  PMC* dest) {
-       internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of two uninitialized 
+values in division");
+      internal_exception(DIV_BY_ZERO, "division by zero!\n");
    }
 
    void modulus (PMC * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+modulus");
+      if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) {
+         if(value->vtable->get_integer(INTERP, value) == 0) {
+            internal_exception(DIV_BY_ZERO, "division by zero!\n");
+         }
+      }
+      else if(value->vtable->get_number(INTERP, value) == 0) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void modulus_int (INTVAL value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+integer modulus");
+      if(value == 0) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void modulus_bigint (BIGINT value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+bigint modulus");
+      /* need test for value == 0 */
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void modulus_float (FLOATVAL value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+numeric modulus");
+      if(value == 0) {
+         internal_exception(DIV_BY_ZERO, "division by zero!\n");
+      }
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void modulus_bigfloat (BIGFLOAT value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+bigfloat modulus");
+      /* need test for value == 0 */
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void modulus_same (PMC * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of two uninitialized 
+values in modulus");
+      internal_exception(DIV_BY_ZERO, "division by zero!\n");
    }
 
    void concatenate (PMC * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+concatenation");
+      dest->vtable->set_string(INTERP, dest, value);
    }
 
    void concatenate_native (STRING * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+concatenation");
+      dest->vtable->set_string_native(INTERP, dest, value);
    }
 
    void concatenate_unicode (STRING * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+concatenation");
+      dest->vtable->set_string_native(INTERP, dest, value);
    }
 
    void concatenate_other (STRING * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+concatenation");
+      dest->vtable->set_string_native(INTERP, dest, value);
    }
 
    void concatenate_same (PMC * value,  PMC* dest) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+concatenation");
+      dest->vtable->set_string_native(INTERP, dest, NULL);
    }
 
    BOOLVAL is_equal (PMC* value) {
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+equals");
+      if(value->vtable==SELF->vtable) {
+         return 1;
+      }
+      else if(value->vtable->get_integer(INTERP, value) == 0) {
+         return 1;
+      }
+      else if(0==string_compare(INTERP, value->vtable->get_string(INTERP, value), 
+NULL)) {
+         return 1;
+      }
+      else {
+         return 0;
+      }
    }
 
    void logical_or (PMC* value,  PMC* dest) {
-        dest->vtable->set_integer_native(INTERP, dest,
-           value->vtable->get_bool(INTERP, value));
+      dest->vtable->set_integer_native(INTERP, dest, value->vtable->get_bool(INTERP, 
+value));
    }
 
    void logical_and (PMC* value,  PMC* dest) {
-        dest->vtable->set_integer_native(INTERP, dest, 0);
+      dest->vtable->set_integer_native(INTERP, dest, 0);
    }
 
    void logical_not (PMC* dest) {
-        dest->vtable->set_integer_native(INTERP, dest, 1);
+      dest->vtable->set_integer_native(INTERP, dest, 1);
    }
 
    void match (PMC * value,  REGEX* re) {
@@ -349,28 +431,28 @@
    }
 
    void repeat (PMC * value,  PMC* dest) {
-       dest->vtable = &Parrot_base_vtables[enum_class_PerlString];
-       dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+repeat");
+      dest->vtable->set_string(INTERP, dest, NULL);
    }
 
    void repeat_native (STRING * value,  PMC* dest) {
-       dest->vtable = &Parrot_base_vtables[enum_class_PerlString];
-       dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+repeat");
+      dest->vtable->set_string(INTERP, dest, NULL);
    }
 
    void repeat_unicode (STRING * value,  PMC* dest) {
-       dest->vtable = &Parrot_base_vtables[enum_class_PerlString];
-       dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+repeat");
+      dest->vtable->set_string(INTERP, dest, NULL);
    }
 
    void repeat_other (STRING * value,  PMC* dest) {
-       dest->vtable = &Parrot_base_vtables[enum_class_PerlString];
-       dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+repeat");
+      dest->vtable->set_string(INTERP, dest, NULL);
    }
 
    void repeat_same (PMC * value,  PMC* dest) {
-       dest->vtable = &Parrot_base_vtables[enum_class_PerlString];
-       dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL);
+      Parrot_warn(INTERP, PARROT_WARNINGS_UNDEF_FLAG, "Use of uninitialized value in 
+repeat");
+      dest->vtable->set_string(INTERP, dest, NULL);
    }
 
 }
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/core.ops /parrot/core.ops
--- /parrot-cvs/core.ops        Tue Feb  5 00:36:28 2002
+++ /parrot/core.ops    Tue Feb  5 00:34:44 2002
@@ -2632,6 +2632,44 @@
   goto NEXT();
 }
 
+=item B<warningson>(in INT)
+
+Turns on warnings categories.  Categories already turned on will 
+stay on.  Current categories and the numbers they map to are:
+
+=over 4
+
+=item 1: undef
+
+=item 2: IO
+
+=item -1: all
+
+=back
+
+To turn on multiple categories, OR the category numbers together.
+
+=cut
+
+inline op warningson(in INT) {
+  PARROT_WARNINGS_on(interpreter, $1);
+  goto NEXT();
+}
+
+=item B<warningsoff>(in INT)
+
+Turns off warnings categories.  Categories already turned off will 
+stay off.  See the documentation for B<warningson> for category 
+numbers.
+
+=cut
+
+inline op warningsoff(in INT) {
+  PARROT_WARNINGS_off(interpreter, $1);
+  goto NEXT();
+}
+
+
 =back
 
 =cut
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/embed.c /parrot/embed.c
--- /parrot-cvs/embed.c Tue Feb  5 00:36:28 2002
+++ /parrot/embed.c     Tue Feb  5 00:34:44 2002
@@ -40,6 +40,12 @@
     interpreter->flags |= flag;
 }
 
+void
+Parrot_setwarnings(struct Parrot_Interp *interpreter, Parrot_warnclass wc) {
+       char* msg=mem_sys_allocate(32);
+       PARROT_WARNINGS_on(interpreter, wc);
+}
+
 struct PackFile *
 Parrot_readbc(struct Parrot_Interp *interpreter, char *filename) {
     /* XXX This ugly mess ought to be cleanupable. */
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/include/parrot/embed.h 
/parrot/include/parrot/embed.h
--- /parrot-cvs/include/parrot/embed.h  Wed Jan 30 05:54:28 2002
+++ /parrot/include/parrot/embed.h      Fri Feb  1 14:32:36 2002
@@ -14,18 +14,14 @@
 #if !defined(PARROT_EMBED_H_GUARD)
 #define PARROT_EMBED_H_GUARD
 
-#include "parrot/config.h"
+#include "parrot/config.h"             /* PARROT_VERSION, PARROT_JIT_CAPABLE... */
+#include "parrot/interpreter.h" /* give us the interpreter flags */
+#include "parrot/warnings.h"   /* give us the warnings flags    */
 
 typedef int Parrot_flag;
+typedef int Parrot_warnclass;
 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;
@@ -36,6 +32,8 @@
 void Parrot_init(struct Parrot_Interp *);
 
 void Parrot_setflag(struct Parrot_Interp *, Parrot_flag, Parrot_flag_val);
+
+void Parrot_setwarnings(struct Parrot_Interp *, Parrot_warnclass);
 
 struct PackFile * Parrot_readbc(struct Parrot_Interp *, char *);
 
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/include/parrot/interpreter.h 
/parrot/include/parrot/interpreter.h
--- /parrot-cvs/include/parrot/interpreter.h    Mon Jan 28 23:28:22 2002
+++ /parrot/include/parrot/interpreter.h        Fri Feb  1 15:59:46 2002
@@ -12,14 +12,18 @@
 
 #if !defined(PARROT_INTERPRETER_H_GUARD)
 #define PARROT_INTERPRETER_H_GUARD
+
+#if defined(PARROT_IN_CORE)
+
 #include "parrot/register.h"
 #include "parrot/parrot.h"
 
 #include "parrot/op.h"
 #include "parrot/oplib.h"
 
-
-
+typedef struct warnings_t {
+       INTVAL classes;
+} * Warnings;
 
 #if 0
 typedef STRING_FUNCS * (str_func_t)();
@@ -68,6 +72,9 @@
     INTVAL flags;                                        /* Various interpreter 
flagBut whBut what 
                                              that signal that runops
                                              should do something */
+       
+       Warnings warns;                                            /* Keeps track of 
+what warnings have been activated */
+
     ProfData* profile;                     /* The array where we keep the profile 
counters */
 
     INTVAL resume_flag;
@@ -82,13 +89,6 @@
     UINTVAL pmc_count;
 };
 
-#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 */
-
 #define PCONST(i) PF_CONST(interpreter->code, (i))
 #define PNCONST   PF_NCONST(interpreter->code)
 
@@ -104,6 +104,18 @@
 runops(struct Parrot_Interp *, struct PackFile *, size_t offset);
 
 VAR_SCOPE opcode_t* (*run_native)(struct Parrot_Interp *interpreter, opcode_t 
*cur_opcode, opcode_t *start_code);
+
+#endif
+
+/* These should be visible to embedders. */
+
+/* General flags */
+#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 */
 
 #endif
 
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/include/parrot/misc.h 
/parrot/include/parrot/misc.h
--- /parrot-cvs/include/parrot/misc.h   Wed Dec 31 16:00:00 1969
+++ /parrot/include/parrot/misc.h       Sun Feb  3 00:57:52 2002
@@ -0,0 +1,24 @@
+#if !defined(PARROT_MISC_H_GUARD)
+#define PARROT_MISC_H_GUARD
+
+#include "parrot/parrot.h"
+#include <stdarg.h>
+
+STRING* Parrot_vsprintf_s(struct Parrot_Interp *, STRING* pat, va_list *);
+
+STRING* Parrot_vsprintf_c(struct Parrot_Interp *, char * pat, va_list *);
+
+void Parrot_vsprintf(struct Parrot_Interp *, char *targ, char *pat, va_list *);
+
+void Parrot_vsnprintf(struct Parrot_Interp *, char *targ, INTVAL len, char *pat, 
+va_list *);
+
+STRING* Parrot_sprintf_s(struct Parrot_Interp *, STRING* pat, ...);
+
+STRING* Parrot_sprintf_c(struct Parrot_Interp *, char * pat, ...);
+
+void Parrot_sprintf(struct Parrot_Interp *, char *targ, char *pat, ....);
+
+void Parrot_snprintf(struct Parrot_Interp *, char *targ, INTVAL len, char *pat, ...);
+
+
+#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 Thu Jan 31 01:18:18 2002
+++ /parrot/include/parrot/parrot.h     Sun Feb  3 01:15:08 2002
@@ -88,6 +88,7 @@
 #include "parrot/register.h"
 #include "parrot/regfuncs.h"
 #include "parrot/exceptions.h"
+#include "parrot/warnings.h"
 #include "parrot/memory.h"
 #include "parrot/packfile.h"
 #include "parrot/io.h"
@@ -98,6 +99,7 @@
 #include "parrot/stacks.h"
 #include "parrot/resources.h"
 #include "parrot/string_funcs.h"
+#include "parrot/misc.h"
 #endif
 
 /*
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/include/parrot/warnings.h 
/parrot/include/parrot/warnings.h
--- /parrot-cvs/include/parrot/warnings.h       Wed Dec 31 16:00:00 1969
+++ /parrot/include/parrot/warnings.h   Sun Feb  3 01:28:00 2002
@@ -0,0 +1,25 @@
+#if !defined(PARROT_WARNINGS_H_GUARD)
+#define PARROT_WARNINGS_H_GUARD
+
+#define PARROT_WARNINGS_ALL_FLAG       -1
+#define PARROT_WARNINGS_NONE_FLAG       0
+#define PARROT_WARNINGS_UNDEF_FLAG   1
+#define PARROT_WARNINGS_IO_FLAG                 2
+
+#if defined(PARROT_IN_CORE)
+
+#include "parrot/parrot.h"
+
+#define PARROT_WARNINGS_on(interp, flag)       interp->warns->classes |=  flag
+#define PARROT_WARNINGS_off(interp, flag)      interp->warns->classes &= ~flag
+#define PARROT_WARNINGS_test(interp, flag)     interp->warns->classes &   flag
+
+INTVAL
+Parrot_warn(struct Parrot_Interp *, INTVAL warnclass, char* message, ....);
+
+INTVAL
+Parrot_warn_s(struct Parrot_Interp *, INTVAL warnclass, STRING* message, ...);
+
+#endif
+
+#endif
\ No newline at end of file
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/interpreter.c /parrot/interpreter.c
--- /parrot-cvs/interpreter.c   Thu Jan 31 01:18:18 2002
+++ /parrot/interpreter.c       Tue Feb  5 00:25:02 2002
@@ -466,14 +466,16 @@
     
     /* Initialize interpreter's flags */
     interpreter->flags = flags;
+       interpreter->warns = mem_sys_allocate(sizeof(struct warnings_t));
+       PARROT_WARNINGS_off(interpreter, PARROT_WARNINGS_ALL_FLAG);
 
     interpreter->pmc_count = 0;
     interpreter->string_count = 0;
 
     /* Set up defaults for line/package/file */
     interpreter->current_line = 0;
-    interpreter->current_file = NULL;
-    interpreter->current_package = NULL;
+    interpreter->current_file = string_make(interpreter, "(unknown file)", 14, NULL, 
+0, NULL);
+    interpreter->current_package = string_make(interpreter, "(unknown package)", 18, 
+NULL, 0, NULL);;
     
     /* Set up the initial register chunks */
     interpreter->int_reg_base = mem_allocate_aligned(sizeof(struct IRegChunk));
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/misc.c /parrot/misc.c
--- /parrot-cvs/misc.c  Wed Dec 31 16:00:00 1969
+++ /parrot/misc.c      Tue Feb  5 00:07:56 2002
@@ -0,0 +1,1241 @@
+#include "parrot/parrot.h"
+
+#include <stdarg.h>
+
+typedef long HUGEINTVAL;
+typedef unsigned long UHUGEINTVAL;
+
+typedef struct spfinfo_t {
+       INTVAL flags;
+       INTVAL width;
+       INTVAL prec;
+       INTVAL type;
+       INTVAL phase;
+} * SpfInfo;
+
+#define cstr2pstr(cstr) string_make(interpreter, cstr, strlen(cstr), NULL, 0, NULL)
+#define char2pstr(ch)   string_make(interpreter, &ch, 1, NULL, 0, NULL)
+
+#define PHASE_FLAGS 0
+#define PHASE_WIDTH 1
+#define PHASE_PREC  2
+#define PHASE_TYPE  3
+#define PHASE_TERM  4
+#define PHASE_DONE  5
+
+#define FLAG_MINUS  1
+#define FLAG_PLUS   2
+#define FLAG_ZERO   4
+#define FLAG_SPACE  8
+#define FLAG_SHARP  16
+
+#define SIZE_REG       0
+#define SIZE_SHORT     1
+#define SIZE_LONG      2
+#define SIZE_HUGE      3
+#define SIZE_XVAL      4
+
+#define GetInt(targ, whichone)                                                        
+                                                                 \
+       switch(whichone) {                                                             
+                                                                                 \
+               case SIZE_REG:                                                         
+                                                                                 \
+                       targ=(HUGEINTVAL)(int)va_arg(*args, int);                      
+                                                         \
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_SHORT:                                                       
+                                                                                 \
+                       targ=(HUGEINTVAL)(short)va_arg(*args, short);                  
+                                                 \
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_LONG:                                                        
+                                                                                 \
+                       targ=(HUGEINTVAL)(long)va_arg(*args, long);                    
+                                                         \
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_HUGE:                                                        
+                                                                                 \
+                       targ=(HUGEINTVAL)(long /*long*/)va_arg(*args, long /*long*/);  
+                                 \
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_XVAL:                                                        
+                                                                                 \
+                       targ=(HUGEINTVAL)(INTVAL)va_arg(*args, INTVAL);                
+                                                 \
+                       break;                                                         
+                                                                                      
+   \
+       }
+
+#define GetUInt(targ, whichone)                                                       
+                                                                         \
+       switch(whichone) {                                                             
+                                                                                 \
+               case SIZE_REG:                                                         
+                                                                                 \
+                       targ=(UHUGEINTVAL)(unsigned int)va_arg(*args, unsigned int);   
+                                 \
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_SHORT:                                                       
+                                                                                 \
+                       targ=(UHUGEINTVAL)(unsigned short)va_arg(*args, unsigned 
+short);                                \
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_LONG:                                                        
+                                                                                 \
+                       targ=(UHUGEINTVAL)(unsigned long)va_arg(*args, unsigned long); 
+                                 \
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_HUGE:                                                        
+                                                                                 \
+                       targ=(UHUGEINTVAL)(unsigned long /*long*/)va_arg(*args, 
+unsigned long /*long*/);\
+                       break;                                                         
+                                                                                      
+   \
+               case SIZE_XVAL:                                                        
+                                                                                 \
+                       targ=(UHUGEINTVAL)(UINTVAL)va_arg(*args, UINTVAL);             
+                                                 \
+                       break;                                                         
+                                                                                      
+   \
+       }
+
+void
+uint_to_str(char *buf1, char *buf2, UHUGEINTVAL num, INTVAL base) {
+       int i=0, cur;
+
+       do {
+               cur=num % base;
+
+               if(cur < 10) {
+                       buf2[i]='0'+cur;
+               }
+               else {
+                       buf2[i]='a'+cur;
+               }
+               
+               i++;
+       } while(num /= base);
+
+       cur=i;
+
+       for(i=0; i <= cur; i++) {
+               buf1[i]=buf2[cur-i];
+       }
+}
+
+void
+int_to_str(char *buf1, char *buf2, HUGEINTVAL num, INTVAL base) {
+       BOOLVAL neg;
+       int i=0, cur;
+
+       if(num < 0) {
+               neg=1;
+               num= -num;
+       }
+       else {
+               neg=0;
+       }
+
+       do {
+               cur=num % base;
+
+               if(cur < 10) {
+                       buf2[i]='0'+cur;
+               }
+               else {
+                       buf2[i]='a'+cur;
+               }
+               
+               i++;
+       } while(num /= base);
+
+       if(neg) {
+               buf2[i++]='-';
+       }
+       
+       cur=i;
+       
+       for(i=0; i < cur; i++) {
+               buf1[i]=buf2[cur-i-1];
+       }
+
+       buf1[i]=0;
+}
+
+void
+Pad_it(SpfInfo info, char *buf) {
+       int i;
+       int len=strlen(buf);
+       int howmuch=info->width - len;
+       
+       if(!info->width || howmuch == 0) {
+               return;
+       }
+       else if(howmuch < 0) {
+               memmove(buf, buf-howmuch, len+howmuch);
+       }
+       else if(info->flags & FLAG_MINUS) { //left-align
+               for(i=0; i < howmuch; i++) {
+                       buf[i+len]=' ';
+               }
+
+               buf[i+len]=0;
+       }
+       else { //right-align
+               memmove(buf+howmuch, buf, len);
+
+               for(i=0; i < howmuch; i++) {
+                       buf[i]=' ';
+               }
+       }
+}
+
+void
+gen_sprintf_call(char *buf, char* buf2, SpfInfo info, char thingy) {
+       int i=0;
+       buf[i++]='%';
+
+       if(info->flags) {
+               if(info->flags & FLAG_MINUS) {
+                       buf[i++]='-';
+               }
+               if(info->flags & FLAG_PLUS) {
+                       buf[i++]='+';
+               }
+               if(info->flags & FLAG_ZERO) {
+                       buf[i++]='0';
+               }
+               if(info->flags & FLAG_SPACE) {
+                       buf[i++]=' ';
+               }
+               if(info->flags & FLAG_SHARP) {
+                       buf[i++]='#';
+               }
+       }
+
+       if(info->width) {
+               int_to_str(buf+i, buf2, info->width, 10);
+               i=strlen(buf);
+       }
+
+       if(info->prec) {
+               buf[i++]='.';
+               int_to_str(buf+i, buf2, info->prec, 10);
+               i=strlen(buf);
+       }
+
+       buf[i++]=thingy;
+       buf[i]=0;
+}
+
+STRING *
+Parrot_vsprintf_s(struct Parrot_Interp *interpreter, STRING* pat, va_list *args) {
+       INTVAL i;
+       STRING* targ=NULL;
+       register char   *       t1=mem_sys_allocate(4096);
+       register char   *       t2=mem_sys_allocate(4096);
+
+       for(i=0; i < string_length(pat); i++) {
+               if(string_ord(pat, i) == '%') {
+                       if(string_ord(pat, i+1) == '%') {
+                               i++;
+                       }
+                       else {
+                               /* hoo boy, here we go... */
+                                        char   *               chptr;
+                                        STRING *               string;
+                                        double                 dbl;
+                                        FLOATVAL               fv;
+                               register HUGEINTVAL             theint;
+                               register UHUGEINTVAL    theuint;
+       
+                               struct spfinfo_t info={0, 0, 0, 0, 0};
+       
+                               for(i++; i < string_length(pat) && info.phase != 
+PHASE_DONE; i++) {
+                                       char ch=string_ord(pat, i);
+AGAIN:
+                                       switch(info.phase) {
+                                               case PHASE_FLAGS:
+                                                       switch(ch) {
+                                                               case '-':
+                                                                       info.flags |= 
+FLAG_MINUS; break;
+                       
+                                                               case '+':
+                                                                       info.flags |= 
+FLAG_PLUS;  break;
+
+                                                               case '0':
+                                                                       info.flags |= 
+FLAG_ZERO;  break;
+
+                                                               case ' ':
+                                                                       info.flags |= 
+FLAG_SPACE; break;
+
+                                                               case '#':
+                                                                       info.flags |= 
+FLAG_SHARP; break;
+
+                                                               default:
+                                                                       
+info.phase=PHASE_WIDTH;
+                                                                       goto AGAIN;
+                                                       }
+
+                                               case PHASE_WIDTH:
+                                                       switch(ch) {
+                                                               case '0':
+                                                               case '1':
+                                                               case '2':
+                                                               case '3':
+                                                               case '4':
+                                                               case '5':
+                                                               case '6':
+                                                               case '8':
+                                                               case '9':
+                                                                       info.width *= 
+10;
+                                                                       info.width += 
+ch-'0';
+                                                                       break;
+                                                       
+                                                               case '.':
+                                                                       
+info.phase=PHASE_PREC;
+                                                                       continue;
+
+                                                               default:
+                                                                       
+info.phase=PHASE_PREC;
+                                                                       goto AGAIN;
+                                                       }
+
+                                               case PHASE_PREC:
+                                                       switch(ch) {
+                                                               case '0':
+                                                               case '1':
+                                                               case '2':
+                                                               case '3':
+                                                               case '4':
+                                                               case '5':
+                                                               case '6':
+                                                               case '8':
+                                                               case '9':
+                                                                       info.prec *= 
+10;
+                                                                       info.prec += 
+ch-'0';
+                                                                       continue;
+                                                       
+                                                               default:
+                                                                       
+info.phase=PHASE_TYPE;
+                                                                       goto AGAIN;
+                                                       }
+
+                                               case PHASE_TYPE:
+                                                       switch(ch) {
+                                                               case 'h':
+                                                                       
+info.type=SIZE_SHORT; break;
+
+                                                               case 'l':
+                                                                       
+info.type=SIZE_LONG; break;
+
+                                                               case 'H':
+                                                                       
+info.type=SIZE_HUGE; break;
+
+                                                               case 'v':
+                                                                       
+info.type=SIZE_XVAL; break;
+
+                                                               default:
+                                                                       
+info.phase=PHASE_TERM;
+                                                                       goto AGAIN;
+                                                       }
+
+                                                       info.phase=PHASE_TERM;
+                                                       continue;
+
+                                               case PHASE_TERM:
+                                                       switch(ch) {
+                                                               /* INTEGERS */
+                                                               case 'c':
+                                                                       
+targ=string_concat(interpreter, targ, char2pstr(ch), 0);
+                                                                       break;
+
+                                                               case 'd':
+                                                               case 'i':
+                                                                       GetInt(theint, 
+info.type);
+                                                                       int_to_str(t1, 
+t2, theint, 10);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t1), 0);
+                                                                       break;
+
+                                                               case 'o':
+                                                                       GetInt(theint, 
+info.type);
+                                                                       int_to_str(t1, 
+t2, theint, 8);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t1), 0);
+                                                                       break;
+
+                                                               case 'x':
+                                                                       GetInt(theint, 
+info.type);
+                                                                       int_to_str(t1, 
+t2, theint, 16);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t1), 0);
+                                                                       break;
+
+                                                               case 'u':
+                                                                       
+GetUInt(theuint, info.type);
+                                                                       
+uint_to_str(t1, t2, theuint, 10);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t1), 0);
+                                                                       break;
+
+                                                               case 'p':
+                                                                       
+chptr=va_arg(*args, void*);
+                                                                       int_to_str(t1, 
+t2, (HUGEINTVAL)chptr, 16);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t1), 0);
+                                                                       break;
+
+                                                               /* FLOATS - We cheat 
+on these and use the system sprintf. */
+                                                               case 'e':
+                                                                       
+dbl=va_arg(*args, double);
+                                                                       
+gen_sprintf_call(t1, t2, &info, 'e');
+                                                                       sprintf(t2, 
+t1, dbl);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t2), 0);
+                                                                       break;
+
+                                                               case 'E':
+                                                                       
+dbl=va_arg(*args, double);
+                                                                       
+gen_sprintf_call(t1, t2, &info, 'E');
+                                                                       sprintf(t2, 
+t1, dbl);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t2), 0);        
+                                                                       break;
+
+                                                               case 'f':
+                                                                       
+dbl=va_arg(*args, double);
+                                                                       
+gen_sprintf_call(t1, t2, &info, 'f');
+                                                                       sprintf(t2, 
+t1, dbl);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t2), 0);
+                                                                       break;
+
+                                                               case 'g':
+                                                                       
+dbl=va_arg(*args, double);
+                                                                       
+gen_sprintf_call(t1, t2, &info, 'g');
+                                                                       sprintf(t2, 
+t1, dbl);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t2), 0);
+                                                                       break;
+
+                                                               case 'G':
+                                                                       
+dbl=va_arg(*args, double);
+                                                                       
+gen_sprintf_call(t1, t2, &info, 'G');
+                                                                       sprintf(t2, 
+t1, dbl);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(t2), 0);
+                                                                       break;
+
+                                                               /* STRINGS */
+                                                               case 's':
+                                                                       
+chptr=va_arg(*args, char*);
+                                                                       
+targ=string_concat(interpreter, targ, cstr2pstr(chptr), 0);
+                                                                       break;
+
+                                                               case 'S':
+                                                                       
+string=va_arg(*args, STRING*);
+                                                                       
+targ=string_concat(interpreter, targ, string, 0);
+                                                                       break;
+                                                       }
+
+                                                       info.phase=PHASE_DONE;
+                                       }
+                               }
+                       }
+
+                       i--;
+               }
+               else {
+                       STRING* substr=NULL;
+                       string_substr(interpreter, pat, i, 1, &substr);
+                       targ=string_concat(interpreter, targ, substr,0);
+               }
+       }
+
+       mem_sys_free(t1);
+       mem_sys_free(t2);
+
+       return targ;
+}
+
+
+STRING *
+Parrot_vsprintf_c(struct Parrot_Interp *interpreter, char *pat, va_list *args) {
+       STRING *realpat=string_make(interpreter, pat, strlen(pat), NULL, 0, NULL);
+
+       return Parrot_vsprintf_s(interpreter, realpat, args);
+}
+void
+Parrot_vsprintf(struct Parrot_Interp *interpreter, char *targ, char *pat, va_list 
+*args) {
+       STRING *ret=Parrot_vsprintf_c(interpreter, pat, args);
+/*     string_transcode(interpreter, ret, NULL, NULL, &ret);*/
+
+       memcpy(targ, ret->bufstart, ret->bufused);
+       targ[ret->bufused+1]=00;
+}
+
+void
+Parrot_vsnprintf(struct Parrot_Interp *interpreter, char *targ, UINTVAL len, char 
+*pat, va_list *args) {
+       STRING *ret=Parrot_vsprintf_c(interpreter, pat, args);
+       string_transcode(interpreter, ret, NULL, NULL, &ret);
+
+       if(len > ret->bufused) {
+               len=ret->bufused;
+       }
+
+       memcpy(targ, ret->bufstart, len);
+       targ[len+1]=0;
+}
+
+STRING *
+Parrot_sprintf_s(struct Parrot_Interp *interpreter, STRING* pat, ...)
+{
+       STRING *ret;
+       va_list args;
+
+       va_start(args, pat);
+
+       ret=Parrot_vsprintf_s(interpreter, pat, &args);
+
+       va_end(args);
+
+       return ret;
+}
+
+STRING *
+Parrot_sprintf_c(struct Parrot_Interp *interpreter, char* pat, ...) {
+       STRING *ret;
+       va_list args;
+
+       va_start(args, pat);
+
+       ret=Parrot_vsprintf_c(interpreter, pat, &args);
+
+       va_end(args);
+
+       return ret;
+}
+
+void
+Parrot_sprintf(struct Parrot_Interp *interpreter, char* targ, char* pat, ...) {
+       va_list args;
+
+       va_start(args, pat);
+
+       Parrot_vsprintf(interpreter, targ, pat, &args);
+
+       va_end(args);
+}
+
+void
+Parrot_snprintf(struct Parrot_Interp *interpreter, char* targ, UINTVAL len, char* 
+pat, ...) {
+       va_list args;
+
+       va_start(args, pat);
+
+       Parrot_vsnprintf(interpreter, targ, len, pat, &args);
+
+       va_end(args);
+}
+
+#if 0
+void   /* barely started conversion to Parrot, but abandoned it. */
+perl5s_vsprintf(struct Parrot_Interp *interpreter, STRING *targ, const char *pat, 
+INTVAL patlen, va_list *args)
+{
+    char *p;
+    char *q;
+    char *patend;
+    INTVAL origlen;
+    INTVAL svix = 0;
+    static char nullstr[] = "(null)";
+    STRING *argsv = NULL;
+
+    /* special-case "", "%s", and "%_" */
+       if (patlen == 0) {
+               return;
+       }
+
+    if (patlen == 2 && pat[0] == '%') {
+       switch (pat[1]) {
+       case 's':
+           if (args) {
+                       char *s = va_arg(*args, char*);
+                       //sv_catpv(sv, s ? s : nullstr);
+                       targ=string_concat(interpreter, "
+           }
+           else if (svix < svmax) {
+               sv_catsv(sv, *svargs);
+               if (DO_UTF8(*svargs))
+                   SvUTF8_on(sv);
+           }
+           return;
+       case '_':
+           if (args) {
+               argsv = va_arg(*args, SV*);
+               sv_catsv(sv, argsv);
+               if (DO_UTF8(argsv))
+                   SvUTF8_on(sv);
+               return;
+           }
+           /* See comment on '_' below */
+           break;
+       }
+    }
+
+    patend = (char*)pat + patlen;
+    for (p = (char*)pat; p < patend; p = q) {
+       bool alt = FALSE;
+       bool left = FALSE;
+       bool vectorize = FALSE;
+       bool vectorarg = FALSE;
+       bool vec_utf = FALSE;
+       char fill = ' ';
+       char plus = 0;
+       char intsize = 0;
+       INTVAL width = 0;
+       INTVAL zeros = 0;
+       bool has_precis = FALSE;
+       INTVAL precis = 0;
+       bool is_utf = FALSE;
+       
+       char esignbuf[4];
+       U8 utf8buf[UTF8_MAXLEN+1];
+       INTVAL esignlen = 0;
+
+       char *eptr = Nullch;
+       INTVAL elen = 0;
+       /* Times 4: a decimal digit takes more than 3 binary digits.
+        * NV_DIG: mantissa takes than many decimal digits.
+        * Plus 32: Playing safe. */
+       char ebuf[IV_DIG * 4 + NV_DIG + 32];
+        /* large enough for "%#.#f" --chip */
+       /* what about long double NVs? --jhi */
+
+       SV *vecsv;
+       U8 *vecstr = Null(U8*);
+       INTVAL veclen = 0;
+       char c;
+       int i;
+       unsigned base = 0;
+       IV iv = 0;
+       UV uv = 0;
+       NV nv;
+       INTVAL have;
+       INTVAL need;
+       INTVAL gap;
+       char *dotstr = ".";
+       INTVAL dotstrlen = 1;
+       INTVAL efix = 0; /* explicit format parameter index */
+       INTVAL ewix = 0; /* explicit width index */
+       INTVAL epix = 0; /* explicit precision index */
+       INTVAL evix = 0; /* explicit vector index */
+       bool asterisk = FALSE;
+
+       /* echo everything up to the next format specification */
+       for (q = p; q < patend && *q != '%'; ++q) ;
+       if (q > p) {
+           sv_catpvn(sv, p, q - p);
+           p = q;
+       }
+       if (q++ >= patend)
+           break;
+
+/*
+    We allow format specification elements in this order:
+       \d+\$              explicit format parameter index
+       [-+ 0#]+           flags
+       \*?(\d+\$)?v       vector with optional (optionally specified) arg
+       \d+|\*(\d+\$)?     width using optional (optionally specified) arg
+       \.(\d*|\*(\d+\$)?) precision using optional (optionally specified) arg
+       [hlqLV]            size
+    [%bcdefginopsux_DFOUX] format (mandatory)
+*/
+       if (EXPECT_NUMBER(q, width)) {
+           if (*q == '$') {
+               ++q;
+               efix = width;
+           } else {
+               goto gotwidth;
+           }
+       }
+
+       /* FLAGS */
+
+       while (*q) {
+           switch (*q) {
+           case ' ':
+           case '+':
+               plus = *q++;
+               continue;
+
+           case '-':
+               left = TRUE;
+               q++;
+               continue;
+
+           case '0':
+               fill = *q++;
+               continue;
+
+           case '#':
+               alt = TRUE;
+               q++;
+               continue;
+
+           default:
+               break;
+           }
+           break;
+       }
+
+      tryasterisk:
+       if (*q == '*') {
+           q++;
+           if (EXPECT_NUMBER(q, ewix))
+               if (*q++ != '$')
+                   goto unknown;
+           asterisk = TRUE;
+       }
+       if (*q == 'v') {
+           q++;
+           if (vectorize)
+               goto unknown;
+           if ((vectorarg = asterisk)) {
+               evix = ewix;
+               ewix = 0;
+               asterisk = FALSE;
+           }
+           vectorize = TRUE;
+           goto tryasterisk;
+       }
+
+       if (!asterisk)
+           EXPECT_NUMBER(q, width);
+
+       if (vectorize) {
+           if (vectorarg) {
+               if (args)
+                   vecsv = va_arg(*args, SV*);
+               else
+                   vecsv = (evix ? evix <= svmax : svix < svmax) ?
+                       svargs[ewix ? ewix-1 : svix++] : &PL_sv_undef;
+               dotstr = SvPVx(vecsv, dotstrlen);
+               if (DO_UTF8(vecsv))
+                   is_utf = TRUE;
+           }
+           if (args) {
+               vecsv = va_arg(*args, SV*);
+               vecstr = (U8*)SvPVx(vecsv,veclen);
+               vec_utf = DO_UTF8(vecsv);
+           }
+           else if (efix ? efix <= svmax : svix < svmax) {
+               vecsv = svargs[efix ? efix-1 : svix++];
+               vecstr = (U8*)SvPVx(vecsv,veclen);
+               vec_utf = DO_UTF8(vecsv);
+           }
+           else {
+               vecstr = (U8*)"";
+               veclen = 0;
+           }
+       }
+
+       if (asterisk) {
+           if (args)
+               i = va_arg(*args, int);
+           else
+               i = (ewix ? ewix <= svmax : svix < svmax) ?
+                   SvIVx(svargs[ewix ? ewix-1 : svix++]) : 0;
+           left |= (i < 0);
+           width = (i < 0) ? -i : i;
+       }
+      gotwidth:
+
+       /* PRECISION */
+
+       if (*q == '.') {
+           q++;
+           if (*q == '*') {
+               q++;
+               if (EXPECT_NUMBER(q, epix) && *q++ != '$') /* epix currently unused */
+                   goto unknown;
+               if (args)
+                   i = va_arg(*args, int);
+               else
+                   i = (ewix ? ewix <= svmax : svix < svmax)
+                       ? SvIVx(svargs[ewix ? ewix-1 : svix++]) : 0;
+               precis = (i < 0) ? 0 : i;
+           }
+           else {
+               precis = 0;
+               while (isDIGIT(*q))
+                   precis = precis * 10 + (*q++ - '0');
+           }
+           has_precis = TRUE;
+       }
+
+       /* SIZE */
+
+       switch (*q) {
+#if defined(HAS_QUAD) || (defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE))
+       case 'L':                       /* Ld */
+           /* FALL THROUGH */
+#endif
+#ifdef HAS_QUAD
+       case 'q':                       /* qd */
+           intsize = 'q';
+           q++;
+           break;
+#endif
+       case 'l':
+#if defined(HAS_QUAD) || (defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE))
+             if (*(q + 1) == 'l') {    /* lld, llf */
+               intsize = 'q';
+               q += 2;
+               break;
+            }
+#endif
+           /* FALL THROUGH */
+       case 'h':
+           /* FALL THROUGH */
+       case 'V':
+           intsize = *q++;
+           break;
+       }
+
+       /* CONVERSION */
+
+       if (*q == '%') {
+           eptr = q++;
+           elen = 1;
+           goto string;
+       }
+
+       if (!args)
+           argsv = (efix ? efix <= svmax : svix < svmax) ?
+                   svargs[efix ? efix-1 : svix++] : &PL_sv_undef;
+
+       switch (c = *q++) {
+
+           /* STRINGS */
+
+       case 'c':
+           uv = args ? va_arg(*args, int) : SvIVx(argsv);
+           if ((uv > 255 ||
+                (!UNI_IS_INVARIANT(uv) && SvUTF8(sv)))
+               && !IN_BYTES) {
+               eptr = (char*)utf8buf;
+               elen = uvchr_to_utf8((U8*)eptr, uv) - utf8buf;
+               is_utf = TRUE;
+           }
+           else {
+               c = (char)uv;
+               eptr = &c;
+               elen = 1;
+           }
+           goto string;
+
+       case 's':
+           if (args) {
+               eptr = va_arg(*args, char*);
+               if (eptr)
+#ifdef MACOS_TRADITIONAL
+                 /* On MacOS, %#s format is used for Pascal strings */
+                 if (alt)
+                   elen = *eptr++;
+                 else
+#endif
+                   elen = strlen(eptr);
+               else {
+                   eptr = nullstr;
+                   elen = sizeof nullstr - 1;
+               }
+           }
+           else {
+               eptr = SvPVx(argsv, elen);
+               if (DO_UTF8(argsv)) {
+                   if (has_precis && precis < elen) {
+                       INTVAL p = precis;
+                       sv_pos_u2b(argsv, &p, 0); /* sticks at end */
+                       precis = p;
+                   }
+                   if (width) { /* fudge width (can't fudge elen) */
+                       width += elen - sv_len_utf8(argsv);
+                   }
+                   is_utf = TRUE;
+               }
+           }
+           goto string;
+
+       case '_':
+           /*
+            * The "%_" hack might have to be changed someday,
+            * if ISO or ANSI decide to use '_' for something.
+            * So we keep it hidden from users' code.
+            */
+           if (!args)
+               goto unknown;
+           argsv = va_arg(*args, SV*);
+           eptr = SvPVx(argsv, elen);
+           if (DO_UTF8(argsv))
+               is_utf = TRUE;
+
+       string:
+           vectorize = FALSE;
+           if (has_precis && elen > precis)
+               elen = precis;
+           break;
+
+           /* INTEGERS */
+
+       case 'p':
+           if (alt)
+               goto unknown;
+           uv = PTR2UV(args ? va_arg(*args, void*) : argsv);
+           base = 16;
+           goto integer;
+
+       case 'D':
+#ifdef IV_IS_QUAD
+           intsize = 'q';
+#else
+           intsize = 'l';
+#endif
+           /* FALL THROUGH */
+       case 'd':
+       case 'i':
+           if (vectorize) {
+               INTVAL ulen;
+               if (!veclen)
+                   continue;
+               if (vec_utf)
+                   uv = utf8n_to_uvchr(vecstr, veclen, &ulen, UTF8_ALLOW_ANYUV);
+               else {
+                   uv = *vecstr;
+                   ulen = 1;
+               }
+               vecstr += ulen;
+               veclen -= ulen;
+               if (plus)
+                    esignbuf[esignlen++] = plus;
+           }
+           else if (args) {
+               switch (intsize) {
+               case 'h':       iv = (short)va_arg(*args, int); break;
+               default:        iv = va_arg(*args, int); break;
+               case 'l':       iv = va_arg(*args, long); break;
+               case 'V':       iv = va_arg(*args, IV); break;
+#ifdef HAS_QUAD
+               case 'q':       iv = va_arg(*args, Quad_t); break;
+#endif
+               }
+           }
+           else {
+               iv = SvIVx(argsv);
+               switch (intsize) {
+               case 'h':       iv = (short)iv; break;
+               default:        break;
+               case 'l':       iv = (long)iv; break;
+               case 'V':       break;
+#ifdef HAS_QUAD
+               case 'q':       iv = (Quad_t)iv; break;
+#endif
+               }
+           }
+           if ( !vectorize )   /* we already set uv above */
+           {
+               if (iv >= 0) {
+                   uv = iv;
+                   if (plus)
+                       esignbuf[esignlen++] = plus;
+               }
+               else {
+                   uv = -iv;
+                   esignbuf[esignlen++] = '-';
+               }
+           }
+           base = 10;
+           goto integer;
+
+       case 'U':
+#ifdef IV_IS_QUAD
+           intsize = 'q';
+#else
+           intsize = 'l';
+#endif
+           /* FALL THROUGH */
+       case 'u':
+           base = 10;
+           goto uns_integer;
+
+       case 'b':
+           base = 2;
+           goto uns_integer;
+
+       case 'O':
+#ifdef IV_IS_QUAD
+           intsize = 'q';
+#else
+           intsize = 'l';
+#endif
+           /* FALL THROUGH */
+       case 'o':
+           base = 8;
+           goto uns_integer;
+
+       case 'X':
+       case 'x':
+           base = 16;
+
+       uns_integer:
+           if (vectorize) {
+               INTVAL ulen;
+       vector:
+               if (!veclen)
+                   continue;
+               if (vec_utf)
+                   uv = utf8n_to_uvchr(vecstr, veclen, &ulen, UTF8_ALLOW_ANYUV);
+               else {
+                   uv = *vecstr;
+                   ulen = 1;
+               }
+               vecstr += ulen;
+               veclen -= ulen;
+           }
+           else if (args) {
+               switch (intsize) {
+               case 'h':  uv = (unsigned short)va_arg(*args, unsigned); break;
+               default:   uv = va_arg(*args, unsigned); break;
+               case 'l':  uv = va_arg(*args, unsigned long); break;
+               case 'V':  uv = va_arg(*args, UV); break;
+#ifdef HAS_QUAD
+               case 'q':  uv = va_arg(*args, Quad_t); break;
+#endif
+               }
+           }
+           else {
+               uv = SvUVx(argsv);
+               switch (intsize) {
+               case 'h':       uv = (unsigned short)uv; break;
+               default:        break;
+               case 'l':       uv = (unsigned long)uv; break;
+               case 'V':       break;
+#ifdef HAS_QUAD
+               case 'q':       uv = (Quad_t)uv; break;
+#endif
+               }
+           }
+
+       integer:
+           eptr = ebuf + sizeof ebuf;
+           switch (base) {
+               unsigned dig;
+           case 16:
+               if (!uv)
+                   alt = FALSE;
+               p = (char*)((c == 'X')
+                           ? "0123456789ABCDEF" : "0123456789abcdef");
+               do {
+                   dig = uv & 15;
+                   *--eptr = p[dig];
+               } while (uv >>= 4);
+               if (alt) {
+                   esignbuf[esignlen++] = '0';
+                   esignbuf[esignlen++] = c;  /* 'x' or 'X' */
+               }
+               break;
+           case 8:
+               do {
+                   dig = uv & 7;
+                   *--eptr = '0' + dig;
+               } while (uv >>= 3);
+               if (alt && *eptr != '0')
+                   *--eptr = '0';
+               break;
+           case 2:
+               do {
+                   dig = uv & 1;
+                   *--eptr = '0' + dig;
+               } while (uv >>= 1);
+               if (alt) {
+                   esignbuf[esignlen++] = '0';
+                   esignbuf[esignlen++] = 'b';
+               }
+               break;
+           default:            /* it had better be ten or less */
+#if defined(PERL_Y2KWARN)
+               if (ckWARN(WARN_Y2K)) {
+                   INTVAL n;
+                   char *s = SvPV(sv,n);
+                   if (n >= 2 && s[n-2] == '1' && s[n-1] == '9'
+                       && (n == 2 || !isDIGIT(s[n-3])))
+                   {
+                       Perl_warner(aTHX_ WARN_Y2K,
+                                   "Possible Y2K bug: %%%c %s",
+                                   c, "format string following '19'");
+                   }
+               }
+#endif
+               do {
+                   dig = uv % base;
+                   *--eptr = '0' + dig;
+               } while (uv /= base);
+               break;
+           }
+           elen = (ebuf + sizeof ebuf) - eptr;
+           if (has_precis) {
+               if (precis > elen)
+                   zeros = precis - elen;
+               else if (precis == 0 && elen == 1 && *eptr == '0')
+                   elen = 0;
+           }
+           break;
+
+           /* FLOATING POINT */
+
+       case 'F':
+           c = 'f';            /* maybe %F isn't supported here */
+           /* FALL THROUGH */
+       case 'e': case 'E':
+       case 'f':
+       case 'g': case 'G':
+
+           /* This is evil, but floating point is even more evil */
+
+           vectorize = FALSE;
+           nv = args ? va_arg(*args, NV) : SvNVx(argsv);
+
+           need = 0;
+           if (c != 'e' && c != 'E') {
+               i = PERL_INT_MIN;
+               (void)Perl_frexp(nv, &i);
+               if (i == PERL_INT_MIN)
+                   Perl_die(aTHX_ "panic: frexp");
+               if (i > 0)
+                   need = BIT_DIGITS(i);
+           }
+           need += has_precis ? precis : 6; /* known default */
+           if (need < width)
+               need = width;
+
+           need += 20; /* fudge factor */
+           if (PL_efloatsize < need) {
+               Safefree(PL_efloatbuf);
+               PL_efloatsize = need + 20; /* more fudge */
+               New(906, PL_efloatbuf, PL_efloatsize, char);
+               PL_efloatbuf[0] = '\0';
+           }
+
+           eptr = ebuf + sizeof ebuf;
+           *--eptr = '\0';
+           *--eptr = c;
+#if defined(USE_LONG_DOUBLE) && defined(PERL_PRIfldbl)
+           {
+               /* Copy the one or more characters in a long double
+                * format before the 'base' ([efgEFG]) character to
+                * the format string. */
+               static char const prifldbl[] = PERL_PRIfldbl;
+               char const *p = prifldbl + sizeof(prifldbl) - 3;
+               while (p >= prifldbl) { *--eptr = *p--; }
+           }
+#endif
+           if (has_precis) {
+               base = precis;
+               do { *--eptr = '0' + (base % 10); } while (base /= 10);
+               *--eptr = '.';
+           }
+           if (width) {
+               base = width;
+               do { *--eptr = '0' + (base % 10); } while (base /= 10);
+           }
+           if (fill == '0')
+               *--eptr = fill;
+           if (left)
+               *--eptr = '-';
+           if (plus)
+               *--eptr = plus;
+           if (alt)
+               *--eptr = '#';
+           *--eptr = '%';
+
+           /* No taint.  Otherwise we are in the strange situation
+            * where printf() taints but print($float) doesn't.
+            * --jhi */
+           (void)sprintf(PL_efloatbuf, eptr, nv);
+
+           eptr = PL_efloatbuf;
+           elen = strlen(PL_efloatbuf);
+           break;
+
+           /* SPECIAL */
+
+       case 'n':
+           vectorize = FALSE;
+           i = SvCUR(sv) - origlen;
+           if (args) {
+               switch (intsize) {
+               case 'h':       *(va_arg(*args, short*)) = i; break;
+               default:        *(va_arg(*args, int*)) = i; break;
+               case 'l':       *(va_arg(*args, long*)) = i; break;
+               case 'V':       *(va_arg(*args, IV*)) = i; break;
+#ifdef HAS_QUAD
+               case 'q':       *(va_arg(*args, Quad_t*)) = i; break;
+#endif
+               }
+           }
+           else
+               sv_setuv_mg(argsv, (UV)i);
+           continue;   /* not "break" */
+
+           /* UNKNOWN */
+
+       default:
+      unknown:
+           vectorize = FALSE;
+           if (!args && ckWARN(WARN_PRINTF) &&
+                 (PL_op->op_type == OP_PRTF || PL_op->op_type == OP_SPRINTF)) {
+               SV *msg = sv_newmortal();
+               Perl_sv_setpvf(aTHX_ msg, "Invalid conversion in %s: ",
+                         (PL_op->op_type == OP_PRTF) ? "printf" : "sprintf");
+               if (c) {
+                   if (isPRINT(c))
+                       Perl_sv_catpvf(aTHX_ msg,
+                                      "\"%%%c\"", c & 0xFF);
+                   else
+                       Perl_sv_catpvf(aTHX_ msg,
+                                      "\"%%\\%03"UVof"\"",
+                                      (UV)c & 0xFF);
+               } else
+                   sv_catpv(msg, "end of string");
+               Perl_warner(aTHX_ WARN_PRINTF, "%"SVf, msg); /* yes, this is reentrant 
+*/
+           }
+
+           /* output mangled stuff ... */
+           if (c == '\0')
+               --q;
+           eptr = p;
+           elen = q - p;
+
+           /* ... right here, because formatting flags should not apply */
+           SvGROW(sv, SvCUR(sv) + elen + 1);
+           p = SvEND(sv);
+           Copy(eptr, p, elen, char);
+           p += elen;
+           *p = '\0';
+           SvCUR(sv) = p - SvPVX(sv);
+           continue;   /* not "break" */
+       }
+
+       have = esignlen + zeros + elen;
+       need = (have > width ? have : width);
+       gap = need - have;
+
+       SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1);
+       p = SvEND(sv);
+       if (esignlen && fill == '0') {
+           for (i = 0; i < esignlen; i++)
+               *p++ = esignbuf[i];
+       }
+       if (gap && !left) {
+           memset(p, fill, gap);
+           p += gap;
+       }
+       if (esignlen && fill != '0') {
+           for (i = 0; i < esignlen; i++)
+               *p++ = esignbuf[i];
+       }
+       if (zeros) {
+           for (i = zeros; i; i--)
+               *p++ = '0';
+       }
+       if (elen) {
+           Copy(eptr, p, elen, char);
+           p += elen;
+       }
+       if (gap && left) {
+           memset(p, ' ', gap);
+           p += gap;
+       }
+       if (vectorize) {
+           if (veclen) {
+               Copy(dotstr, p, dotstrlen, char);
+               p += dotstrlen;
+           }
+           else
+               vectorize = FALSE;              /* done iterating over vecstr */
+       }
+       if (is_utf)
+           SvUTF8_on(sv);
+       *p = '\0';
+       SvCUR(sv) = p - SvPVX(sv);
+       if (vectorize) {
+           esignlen = 0;
+           goto vector;
+       }
+    }
+}
+#endif
\ No newline at end of file
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/test_main.c /parrot/test_main.c
--- /parrot-cvs/test_main.c     Tue Feb  5 00:36:28 2002
+++ /parrot/test_main.c Mon Feb  4 22:25:00 2002
@@ -73,13 +73,19 @@
            case 'P':
                setopt(PARROT_PREDEREF_FLAG); break;
            case 't':
-               setopt(PARROT_TRACE_FLAG); break;
+                               setopt(PARROT_TRACE_FLAG); break;
            case 'd':
-               setopt(PARROT_DEBUG_FLAG); break;
+                               setopt(PARROT_DEBUG_FLAG); break;
            case 'h':
-               usage(); break;
+                               usage(); break;
            case 'v':
-               version(); break;
+                               version(); break;
+                  case 'w':
+                               Parrot_setwarnings(interpreter, 
+PARROT_WARNINGS_ALL_FLAG); break;
+
+                  case '.':
+                          fgetc(stdin); break;
+                               
            case '-':
                (*argc)--;
                (*argv)++;
diff -uNrx CVS -x .cvs -x .# /parrot-cvs/warnings.c /parrot/warnings.c
--- /parrot-cvs/warnings.c      Wed Dec 31 16:00:00 1969
+++ /parrot/warnings.c  Sun Feb  3 01:23:08 2002
@@ -0,0 +1,61 @@
+#include "parrot/parrot.h"
+
+#include <stdarg.h>
+
+INTVAL
+Parrot_warn(struct Parrot_Interp *interpreter, INTVAL warnclass, char* message, ...) {
+       STRING * targ;
+
+       va_list args;
+       va_start(args, message);
+
+       if(!PARROT_WARNINGS_test(interpreter, warnclass)) {
+               return 2;
+       }
+
+       if(!(targ=Parrot_vsprintf_c(interpreter, message, &args))) {
+               return -1;
+       }
+
+       va_end(args);
+
+       if(!(targ=Parrot_sprintf_c(interpreter, "%S at %S line %d.\n", targ, 
+interpreter->current_file, interpreter->current_line))) {
+               return -1;
+       }
+
+       if(PIO_write(interpreter, PIO_STDERR(interpreter), targ->bufstart, 
+targ->bufused) < 0) {
+               return -2;
+       }
+       else {
+               return 1;
+       }
+}
+
+INTVAL
+Parrot_warn_s(struct Parrot_Interp *interpreter, INTVAL warnclass, STRING* message, 
+...) {
+       STRING * targ;
+
+       va_list args;
+       va_start(args, message);
+
+       if(!PARROT_WARNINGS_test(interpreter, warnclass)) {
+               return 2;
+       }
+
+       if(!(targ=Parrot_vsprintf_s(interpreter, message, &args))) {
+               return -1;
+       }
+
+       va_end(args);
+
+       if(!(targ=Parrot_sprintf_c(interpreter, "%S at %S line %d.\n", targ, 
+interpreter->current_file, interpreter->current_line))) {
+               return -1;
+       }
+
+       if(PIO_write(interpreter, PIO_STDERR(interpreter), targ->bufstart, 
+targ->bufused) < 0) {
+               return -2;
+       }
+       else {
+               return 1;
+       }
+}
\ No newline at end of file

Reply via email to