From 3b800edbde32e77a4edb6031b9a9649eaf2a0950 Mon Sep 17 00:00:00 2001 From: Joseph Poirier Date: Tue, 15 Aug 2017 00:23:31 -0500 Subject: [PATCH] initial long printf fix --- cstdlib/stdio.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/cstdlib/stdio.c b/cstdlib/stdio.c index 44ffd26..5be68cc 100644 --- a/cstdlib/stdio.c +++ b/cstdlib/stdio.c @@ -1,6 +1,7 @@ /* */ #include #include +#include #include "../interpreter.h" @@ -118,6 +119,64 @@ void StdioFprintfWord(StdOutStream *Stream, const char *Format, } } +/* printf-style format of a long */ +void StdioFprintfLong(StdOutStream *Stream, const char *Format, uint64_t Value) { + char PlatformFormat[MAX_FORMAT+1], *FPos = PlatformFormat; + + while (*Format) { + char *UseFormat = NULL; + + switch (*Format) { + case 'd': + UseFormat = PRId64; + break; + case 'i': + UseFormat = PRIi64; + break; + case 'o': + UseFormat = PRIo64; + break; + case 'u': + UseFormat = PRIu64; + break; + case 'x': + UseFormat = PRIx64; + break; + case 'X': + UseFormat = PRIX64; + break; + /* Ignore the %l (long) specifier, because of course we're doing longs in this function */ + case 'l': + break; + default: + *FPos++ = *Format; + break; + } + ++Format; + if (UseFormat) { + strcpy(FPos, UseFormat); + FPos += strlen(UseFormat); + } + } + + if (Stream->FilePtr != NULL) + Stream->CharCount += fprintf(Stream->FilePtr, PlatformFormat, Value); + else if (Stream->StrOutLen >= 0) { +#ifndef WIN32 + int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, PlatformFormat, Value); +#else + int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, PlatformFormat, Value); +#endif + Stream->StrOutPtr += CCount; + Stream->StrOutLen -= CCount; + Stream->CharCount += CCount; + } else { + int CCount = sprintf(Stream->StrOutPtr, PlatformFormat, Value); + Stream->CharCount += CCount; + Stream->StrOutPtr += CCount; + } +} + /* printf-style format of a floating point number */ void StdioFprintfFP(StdOutStream *Stream, const char *Format, double Value) { @@ -174,6 +233,7 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, char *FPos; char OneFormatBuf[MAX_FORMAT+1]; int OneFormatCount; + int ShowLong = 0; struct ValueType *ShowType; StdOutStream SOStream; Picoc *pc = Parser->pc; @@ -207,6 +267,9 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, case 'X': ShowType = &pc->IntType; break; /* integer base conversions */ + case 'l': + ShowLong = 1; + break; /* long integer */ case 'e': case 'E': ShowType = &pc->FPType; @@ -289,10 +352,12 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg))); if (ShowType == &pc->IntType) { /* show a signed integer */ - if (IS_NUMERIC_COERCIBLE(ThisArg)) - StdioFprintfWord(&SOStream, OneFormatBuf, - ExpressionCoerceUnsignedInteger(ThisArg)); - else + if (IS_NUMERIC_COERCIBLE(ThisArg)) { + if (ShowLong && ShowType == &pc->IntType) + StdioFprintfLong(&SOStream, OneFormatBuf, ExpressionCoerceUnsignedInteger(ThisArg)); + else + StdioFprintfWord(&SOStream, OneFormatBuf, (unsigned int)ExpressionCoerceUnsignedInteger(ThisArg)); + } else StdioOutPuts("XXX", &SOStream); } else if (ShowType == &pc->FPType) { /* show a floating point number */