On Wed, 9 Oct 2002, Andy Dougherty wrote: > > # Unfortunately, the compact-looking > > # > > # ch=va_arg((va_list)obj->data, char); > > # > > # gave Sun's compiler indigestion.
> Hmm. Just removing the (va_list) cast makes both Sun's compiler and > gcc happy. (That's because va_list is ultimately typedef'd to void * > anyway under Solaris, and probably most other Unix systems. I don't > know about elsewhere, so this could be tricky.) Here's a version that should make even picky compilers without va_list=void* happy. If you prefer the version with just removing the (va_list) cast, that's ok with me. (Just don't throw this out, in case we ever need it!) However, you probably *do* want the 'float promoted to double' fix, the (int) casts for the two internal_exception calls, and the INTVAL2PTR cast near the end. You'll probably also want the enhanced sprintf tests (or something like them.) Currently, the only one that fails for me is the %5.3f test, which gives 0.500 in stdio, but 0.500000000000000000000000000000000 from Parrot. Thanks again for all this work, diff -r -u parrot-orig/spf_vtable.c parrot-andy/spf_vtable.c --- parrot-orig/spf_vtable.c Wed Oct 9 16:12:13 2002 +++ parrot-andy/spf_vtable.c Wed Oct 9 16:15:09 2002 @@ -33,102 +33,164 @@ /* VARARGS CORE */ +/* Sun's WorkShop Compilers 4.2 can't handle the compact expression + va_arg((va_list) obj->data, type); + where obj->data is of type (void *). Hence we copy obj->data to + a local variable and the recopy back to obj->data afterwards. + A. D. 10/2002. +*/ + static STRING* getchr_va(struct Parrot_Interp *interpreter, INTVAL size, SPRINTF_OBJ *obj) { - char ch=va_arg((va_list)obj->data, char); + char ch; + va_list arg; + arg = (va_list) obj->data; + ch=va_arg(arg, char); + obj->data = arg; return string_make(interpreter, &ch, 1, NULL, 0, NULL); } static HUGEINTVAL getint_va(struct Parrot_Interp *interpreter, INTVAL size, SPRINTF_OBJ *obj) { + HUGEINTVAL rtn; + va_list arg; + arg = (va_list) obj->data; switch(size) { case SIZE_REG: - return (HUGEINTVAL)(int)va_arg((va_list)obj->data, int); + rtn = (HUGEINTVAL)(int)va_arg(arg, int); + break; case SIZE_SHORT: /* "'short int' is promoted to 'int' when passed through '...'" */ - return (HUGEINTVAL)(short)va_arg((va_list)obj->data, int); + rtn = (HUGEINTVAL)(short)va_arg(arg, int); + break; case SIZE_LONG: - return (HUGEINTVAL)(long)va_arg((va_list)obj->data, long); + rtn = (HUGEINTVAL)(long)va_arg(arg, long); + break; case SIZE_HUGE: - return (HUGEINTVAL)(HUGEINTVAL)va_arg((va_list)obj->data, HUGEINTVAL); + rtn = (HUGEINTVAL)(HUGEINTVAL)va_arg(arg, HUGEINTVAL); + break; case SIZE_XVAL: - return (HUGEINTVAL)(INTVAL)va_arg((va_list)obj->data, INTVAL); + rtn = (HUGEINTVAL)(INTVAL)va_arg(arg, INTVAL); + break; case SIZE_OPCODE: - return (HUGEINTVAL)(opcode_t)va_arg((va_list)obj->data, opcode_t); + rtn = (HUGEINTVAL)(opcode_t)va_arg(arg, opcode_t); + break; case SIZE_PMC: { - PMC *pmc=(PMC*)va_arg((va_list)obj->data, PMC*); - return (HUGEINTVAL)(INTVAL)(pmc->vtable->get_integer(interpreter, pmc)); + PMC *pmc=(PMC*)va_arg(arg, PMC*); + rtn = (HUGEINTVAL)(INTVAL)(pmc->vtable->get_integer(interpreter, pmc)); + break; } default: PANIC("Invalid int type!"); - return 0; + rtn = 0; } + obj->data = (void *) arg; + return rtn; } static UHUGEINTVAL getuint_va(struct Parrot_Interp *interpreter, INTVAL size, SPRINTF_OBJ *obj) { + UHUGEINTVAL rtn; + va_list arg; + arg = (va_list) obj->data; switch(size) { case SIZE_REG: - return (UHUGEINTVAL)(unsigned int)va_arg((va_list)obj->data, unsigned int); + rtn = (UHUGEINTVAL)(unsigned int)va_arg(arg, unsigned int); + break; case SIZE_SHORT: /* short int promoted HLAGHLAGHLAGH. See note above */ - return (UHUGEINTVAL)(unsigned short)va_arg((va_list)obj->data, unsigned int); + rtn = (UHUGEINTVAL)(unsigned short)va_arg(arg, unsigned int); + break; case SIZE_LONG: - return (UHUGEINTVAL)(unsigned long)va_arg((va_list)obj->data, unsigned long); + rtn = (UHUGEINTVAL)(unsigned long)va_arg(arg, unsigned long); + break; case SIZE_HUGE: - return (UHUGEINTVAL)(UHUGEINTVAL)va_arg((va_list)obj->data, UHUGEINTVAL); \ + rtn = (UHUGEINTVAL)(UHUGEINTVAL)va_arg(arg, UHUGEINTVAL); + break; case SIZE_XVAL: - return (UHUGEINTVAL)(UINTVAL)va_arg((va_list)obj->data, UINTVAL); + rtn = (UHUGEINTVAL)(UINTVAL)va_arg(arg, UINTVAL); + break; case SIZE_OPCODE: - return (UHUGEINTVAL)(opcode_t)va_arg((va_list)obj->data, opcode_t); + rtn = (UHUGEINTVAL)(opcode_t)va_arg(arg, opcode_t); + break; case SIZE_PMC: { - PMC* pmc=(PMC*)va_arg((va_list)obj->data, PMC*); - return (UHUGEINTVAL)(UINTVAL)(pmc->vtable->get_integer(interpreter, pmc)); \ + PMC* pmc=(PMC*)va_arg(arg, PMC*); + rtn = (UHUGEINTVAL)(UINTVAL)(pmc->vtable->get_integer(interpreter, pmc)); + break; } default: PANIC("Invalid uint type!"); - return 0; + rtn = 0; } + obj->data = (void *) arg; + return rtn; } static HUGEFLOATVAL getfloat_va(struct Parrot_Interp *interpreter, INTVAL size, SPRINTF_OBJ *obj) { - switch(size) { - case SIZE_SHORT: - return (HUGEFLOATVAL)(float)va_arg((va_list)obj->data, float); + HUGEFLOATVAL rtn; + va_list arg; + arg = (va_list) obj->data; + switch(size) { + case SIZE_SHORT: /* XXX Do we want to support %hf? */ + /* 'float' is promoted to 'double' when passed through '...' */ + rtn = (HUGEFLOATVAL)(float)va_arg(arg, double); + break; case SIZE_REG: - return (HUGEFLOATVAL)(double)va_arg((va_list)obj->data, double); + rtn = (HUGEFLOATVAL)(double)va_arg(arg, double); + break; case SIZE_HUGE: - return (HUGEFLOATVAL)(HUGEFLOATVAL)va_arg((va_list)obj->data, HUGEFLOATVAL); + rtn = (HUGEFLOATVAL)(HUGEFLOATVAL)va_arg(arg, HUGEFLOATVAL); + break; case SIZE_XVAL: - return (HUGEFLOATVAL)(FLOATVAL)va_arg((va_list)obj->data, FLOATVAL); + rtn = (HUGEFLOATVAL)(FLOATVAL)va_arg(arg, FLOATVAL); + break; case SIZE_PMC: { - PMC* pmc=(PMC*)va_arg((va_list)obj->data, PMC*); - return (HUGEFLOATVAL)(pmc->vtable->get_number(interpreter, pmc)); + PMC* pmc=(PMC*)va_arg(arg, PMC*); + rtn = (HUGEFLOATVAL)(pmc->vtable->get_number(interpreter, pmc)); + break; } default: - internal_exception(INVALID_CHARACTER, "Internal sprintf doesn't recognize size %d for a float", size); - return (HUGEFLOATVAL)0.0; + internal_exception(INVALID_CHARACTER, + "Internal sprintf doesn't recognize size %d for a float", (int) size); + rtn = (HUGEFLOATVAL)0.0; } + obj->data = (void *) arg; + return rtn; } static STRING * getstring_va(struct Parrot_Interp *interpreter, INTVAL size, SPRINTF_OBJ *obj) { + STRING * rtn; + va_list arg; + arg = (va_list) obj->data; switch(size) { case SIZE_REG: { - char *cstr=(char*)va_arg((va_list)obj->data, char*); - return cstr2pstr(cstr); + char *cstr=(char*)va_arg(arg, char*); + rtn = cstr2pstr(cstr); + break; } case SIZE_PSTR: - return string_copy(interpreter, (STRING*)va_arg((va_list)obj->data, STRING*)); + rtn = string_copy(interpreter, (STRING*)va_arg(arg, STRING*)); + break; case SIZE_PMC: { - PMC* pmc=(PMC*)va_arg((va_list)obj->data, PMC*); - return pmc->vtable->get_string(interpreter, pmc); + PMC* pmc=(PMC*)va_arg(arg, PMC*); + rtn = pmc->vtable->get_string(interpreter, pmc); + break; } default: - internal_exception(INVALID_CHARACTER, "Internal sprintf doesn't recognize size %d for a string", size); - return NULL; + internal_exception(INVALID_CHARACTER, + "Internal sprintf doesn't recognize size %d for a string", (int) size); + rtn = NULL; + break; } + obj->data = (void *) arg; + return rtn; } static void * getptr_va(struct Parrot_Interp *interpreter, INTVAL size, SPRINTF_OBJ *obj) { - return (void*)va_arg((va_list)obj->data, void*); + void * rtn; + va_list arg; + arg = (va_list) obj->data; + rtn = (void*)va_arg(arg, void*); + obj->data = (void *) arg; + return rtn; } SPRINTF_OBJ va_core={NULL, getchr_va, getint_va, getuint_va, getfloat_va, getstring_va, getptr_va}; @@ -208,8 +270,10 @@ } static void * getptr_pmc(struct Parrot_Interp *interpreter, INTVAL size, SPRINTF_OBJ *obj) { + INTVAL rtn; PMC *tmp=((PMC*)obj->data)->vtable->pop_pmc(interpreter, ((PMC*)obj->data)); - return (void*)(tmp->vtable->get_integer(interpreter, tmp)); /* XXX correct? */ + rtn = tmp->vtable->get_integer(interpreter, tmp); /* XXX correct? */ + return INTVAL2PTR(void*,rtn); } SPRINTF_OBJ pmc_core={NULL, getchr_pmc, getint_pmc, getuint_pmc, getfloat_pmc, getstring_pmc, getptr_pmc}; @@ -222,4 +286,4 @@ * End: * * vim: expandtab shiftwidth=4: -*/ \ No newline at end of file +*/ diff -r -u parrot-orig/t/src/sprintf.t parrot-andy/t/src/sprintf.t --- parrot-orig/t/src/sprintf.t Wed Oct 9 16:12:13 2002 +++ parrot-andy/t/src/sprintf.t Wed Oct 9 15:59:26 2002 @@ -15,6 +15,12 @@ int dummy_var; STRING *S; PMC *pmc; + INTVAL ival; + UINTVAL uval; + float fval; + double dval; + FLOATVAL fltval; + char *fmt; struct Parrot_Interp * interpreter; interpreter = Parrot_new(); @@ -34,8 +40,41 @@ printf(string_to_cstring(interpreter, S)); S = Parrot_sprintf_c(interpreter, "Hello, %Ss", S); printf(string_to_cstring(interpreter, S)); - S = Parrot_sprintf_c(interpreter, "%d = %Pd\n", 1, pmc); + S = Parrot_sprintf_c(interpreter, "%d == %Pd\n", 1, pmc); printf(string_to_cstring(interpreter, S)); + + ival = -255; + S = Parrot_sprintf_c(interpreter, "== %vd\n", ival); + printf("%d %s", (int) ival, string_to_cstring(interpreter, S)); + + uval = 256; + S = Parrot_sprintf_c(interpreter, "== %vu\n", uval); + printf("%u %s", (unsigned) uval, string_to_cstring(interpreter, S)); + + fval = 0.5; + S = Parrot_sprintf_c(interpreter, "== %f\n", fval); + printf("%f %s", fval, string_to_cstring(interpreter, S)); + + dval = 0.5; + S = Parrot_sprintf_c(interpreter, "== %5.3f\n", dval); + printf("%5.3f %s", dval, string_to_cstring(interpreter, S)); + + dval = 0.001; + S = Parrot_sprintf_c(interpreter, "== %g\n", dval); + printf("%g %s", dval, string_to_cstring(interpreter, S)); + + dval = 1.0e6; + S = Parrot_sprintf_c(interpreter, "== %g\n", dval); + printf("%g %s", dval, string_to_cstring(interpreter, S)); + + fltval = 0.5; + S = Parrot_sprintf_c(interpreter, "== %3.3g\n", fltval); + printf("%3.3g %s", (double) fltval, string_to_cstring(interpreter, S)); + + /* Test we've not left junk behind on the stack */ + S = Parrot_sprintf_c(interpreter, "That's all, %s\n", "folks!"); + printf(string_to_cstring(interpreter, S)); + return 0; } CODE Hello, Parrot! @@ -43,6 +82,14 @@ PerlHash[0x100] Hello, Pa! Hello, Hello, Pa! -1 = 1 +1 == 1 +-255 == -255 +256 == 256 +0.500000 == 0.500000 +0.500 == 0.500 +0.001 == 0.001 +1e+06 == 1e+06 +0.5 == 0.5 +That's all, folks! OUTPUT -} \ No newline at end of file +} -- Andy Dougherty [EMAIL PROTECTED]