Added printf() and variants to stdio

git-svn-id: http://picoc.googlecode.com/svn/trunk@424 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2010-06-11 17:12:49 +00:00
parent 8bd5cfa054
commit 40e338b823
8 changed files with 357 additions and 68 deletions

View file

@ -1,10 +1,5 @@
#include "picoc.h"
struct OutputStream CStdOut;
static int TRUEValue = 1;
static int ZeroValue = 0;
/* initialise a library */
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[])
{
@ -16,8 +11,6 @@ void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct Libr
void *Tokens;
const char *IntrinsicName = TableStrRegister("c library");
CStdOut.Putch = &PlatformPutc;
for (Count = 0; (*FuncList)[Count].Prototype != NULL; Count++)
{
Tokens = LexAnalyse(IntrinsicName, (*FuncList)[Count].Prototype, strlen((char *)(*FuncList)[Count].Prototype), NULL);
@ -29,6 +22,53 @@ void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct Libr
}
}
/* print a type to a stream without using printf/sprintf */
void PrintType(struct ValueType *Typ, IOFILE *Stream)
{
switch (Typ->Base)
{
case TypeVoid: PrintStr("void", Stream); break;
case TypeInt: PrintStr("int", Stream); break;
case TypeShort: PrintStr("short", Stream); break;
case TypeChar: PrintStr("char", Stream); break;
case TypeLong: PrintStr("long", Stream); break;
case TypeUnsignedInt: PrintStr("unsigned int", Stream); break;
case TypeUnsignedShort: PrintStr("unsigned short", Stream); break;
case TypeUnsignedLong: PrintStr("unsigned long", Stream); break;
#ifndef NO_FP
case TypeFP: PrintStr("double", Stream); break;
#endif
case TypeFunction: PrintStr("function", Stream); break;
case TypeMacro: PrintStr("macro", Stream); break;
case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break;
case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintSimpleInt(Typ->ArraySize, Stream); PrintCh(']', Stream); break;
case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break;
case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break;
case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break;
case Type_Type: PrintStr("type ", Stream); break;
}
}
#ifdef BUILTIN_MINI_STDLIB
/*
* This is a simplified standard library for small embedded systems. It doesn't require
* a system stdio library to operate.
*
* A more complete standard library for larger computers is in the library_XXX.c files.
*/
struct OutputStream CStdOut;
static int TRUEValue = 1;
static int ZeroValue = 0;
void BasicIOInit()
{
CStdOut.Putch = &PlatformPutc;
}
/* initialise the C library */
void CLibraryInit()
{
@ -148,33 +188,6 @@ void PrintFP(double Num, struct OutputStream *Stream)
}
#endif
/* print a type to a stream without using printf/sprintf */
void PrintType(struct ValueType *Typ, struct OutputStream *Stream)
{
switch (Typ->Base)
{
case TypeVoid: PrintStr("void", Stream); break;
case TypeInt: PrintStr("int", Stream); break;
case TypeShort: PrintStr("short", Stream); break;
case TypeChar: PrintStr("char", Stream); break;
case TypeLong: PrintStr("long", Stream); break;
case TypeUnsignedInt: PrintStr("unsigned int", Stream); break;
case TypeUnsignedShort: PrintStr("unsigned short", Stream); break;
case TypeUnsignedLong: PrintStr("unsigned long", Stream); break;
#ifndef NO_FP
case TypeFP: PrintStr("double", Stream); break;
#endif
case TypeFunction: PrintStr("function", Stream); break;
case TypeMacro: PrintStr("macro", Stream); break;
case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break;
case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintInt(Typ->ArraySize, 0, FALSE, FALSE, Stream); PrintCh(']', Stream); break;
case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break;
case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break;
case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break;
case Type_Type: PrintStr("type ", Stream); break;
}
}
/* intrinsic functions made available to the language */
void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs, struct OutputStream *Stream)
{
@ -626,3 +639,5 @@ struct LibraryFunction CLibrary[] =
#endif
{ NULL, NULL }
};
#endif /* BUILTIN_MINI_STDLIB */

View file

@ -40,7 +40,7 @@ void IncludeFile(char *FileName)
if (LInclude->SetupFunction != NULL)
(*LInclude->SetupFunction)();
/* parse the setup C source code - may define types etc. */
/* run an extra startup function if there is one */
if (LInclude->SetupCSource != NULL)
Parse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE);

View file

@ -1,13 +1,172 @@
/* stdio.h library */
#include <errno.h>
#include "picoc.h"
#ifndef NO_HASH_INCLUDE
#ifndef BUILTIN_MINI_STDLIB
#define MAX_FORMAT 80
FILE *CStdOut;
static int EOFValue = EOF;
static int SEEK_SETValue = SEEK_SET;
static int SEEK_CURValue = SEEK_CUR;
static int SEEK_ENDValue = SEEK_END;
static int BUFSIZValue = BUFSIZ;
static int FILENAME_MAXValue = FILENAME_MAX;
static int _IOFBFValue = _IOFBF;
static int _IOLBFValue = _IOLBF;
static int _IONBFValue = _IONBF;
static int L_tmpnamValue = L_tmpnam;
static int GETS_MAXValue = 255; /* arbitrary maximum size of a gets() file */
struct StdVararg
{
struct Value **Param;
int NumArgs;
};
void BasicIOInit()
{
CStdOut = stdout;
}
int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *Format, struct StdVararg *Args)
{
struct Value **ArgPos = Args->Param;
int ArgCount = 0;
char *FPos = Format;
char OneFormatBuf[MAX_FORMAT+1];
int OneFormatCount;
struct ValueType *ShowType;
int TotalCharsPrinted = 0;
while (*FPos != '\0')
{
if (*FPos == '%')
{
/* work out what type we're printing */
FPos++;
ShowType = NULL;
OneFormatBuf[OneFormatCount] = '%';
OneFormatCount = 1;
do
{
switch (*FPos)
{
case 'd': case 'i': ShowType = &IntType; break; /* integer decimal */
case 'o': case 'u': case 'x': case 'X': ShowType = &UnsignedIntType; break; /* integer base conversions */
case 'e': case 'E': ShowType = &FPType; break; /* double, exponent form */
case 'f': case 'F': ShowType = &FPType; break; /* double, fixed-point */
case 'g': case 'G': ShowType = &FPType; break; /* double, flexible format */
case 'a': case 'A': ShowType = &UnsignedIntType; break; /* hexadecimal, 0x- format */
case 'c': ShowType = &UnsignedIntType; break; /* character */
case 's': ShowType = CharPtrType; break; /* string */
case 'p': ShowType = VoidPtrType; break; /* pointer */
case 'n': ShowType = &VoidType; break; /* number of characters written */
case 'm': ShowType = &VoidType; break; /* strerror(errno) */
case '%': ShowType = &VoidType; break; /* just a '%' character */
case '\0': ShowType = &VoidType; break; /* end of format string */
}
/* copy one character of format across to the OneFormatBuf */
OneFormatBuf[OneFormatCount] = *FPos;
OneFormatCount++;
/* do special actions depending on the conversion type */
if (ShowType == &VoidType)
{
switch (*FPos)
{
case 'm': fputs(strerror(errno), Stream); break;
case '%': fputc(*FPos, Stream); break;
case '\0': OneFormatBuf[OneFormatCount] = '\0'; fputc(*FPos, Stream); break;
case 'n':
if ((*ArgPos)->Typ->Base == TypeArray && (*ArgPos)->Typ->FromType->Base == TypeInt)
*(int *)(*ArgPos)->Val->Integer = TotalCharsPrinted;
break;
}
}
} while (ShowType == NULL && OneFormatCount < MAX_FORMAT);
if (ShowType != &VoidType)
{
if (ArgCount >= Args->NumArgs)
fputs("XXX", Stream);
else
{
/* null-terminate the buffer */
OneFormatBuf[OneFormatCount] = '\0';
if (ShowType == &IntType)
{
/* show a signed integer */
if (IS_INTEGER_NUMERIC(*ArgPos))
fprintf(Stream, OneFormatBuf, ExpressionCoerceInteger(*ArgPos));
else
fputs("XXX", Stream);
}
else if (ShowType == &UnsignedIntType)
{
/* show an unsigned integer */
if (IS_INTEGER_NUMERIC(*ArgPos))
fprintf(Stream, OneFormatBuf, ExpressionCoerceUnsignedInteger(*ArgPos));
else
fputs("XXX", Stream);
}
else if (ShowType == &FPType)
{
/* show a floating point number */
if (IS_FP(*ArgPos))
fprintf(Stream, OneFormatBuf, ExpressionCoerceFP(*ArgPos));
else
fputs("XXX", Stream);
}
else if (ShowType == CharPtrType)
{
if ((*ArgPos)->Typ->Base == TypePointer)
fprintf(Stream, OneFormatBuf, (*ArgPos)->Val->NativePointer);
else if ((*ArgPos)->Typ->Base == TypeArray && (*ArgPos)->Typ->FromType->Base == TypeChar)
fprintf(Stream, OneFormatBuf, &(*ArgPos)->Val->ArrayMem[0]);
else
fputs("XXX", Stream);
}
else if (ShowType == VoidPtrType)
{
if ((*ArgPos)->Typ->Base == TypePointer)
fprintf(Stream, OneFormatBuf, (*ArgPos)->Val->NativePointer);
else if ((*ArgPos)->Typ->Base == TypeArray)
fprintf(Stream, OneFormatBuf, &(*ArgPos)->Val->ArrayMem[0]);
else
fputs("XXX", Stream);
}
ArgPos++;
ArgCount++;
}
}
}
else
{
/* just output a normal character */
putc(*FPos, Stream);
}
}
return TotalCharsPrinted;
}
int StdioBaseSprintf(struct ParseState *Parser, char *Str, int MaxStrSize, char *Format, struct StdVararg *Args)
{
return 0;
}
void StdioFopen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
@ -154,9 +313,76 @@ void StdioPuts(struct ParseState *Parser, struct Value *ReturnValue, struct Valu
ReturnValue->Val->Integer = puts(Param[0]->Val->NativePointer);
}
void StdioGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->NativePointer = fgets(Param[0]->Val->NativePointer, GETS_MAXValue, stdin);
}
void StdioGetchar(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = getchar();
}
void StdioPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
struct StdVararg PrintfArgs;
PrintfArgs.Param = Param+1;
PrintfArgs.NumArgs = NumArgs;
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, Param[0]->Val->NativePointer, &PrintfArgs);
}
void StdioVprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, Param[0]->Val->NativePointer, Param[1]->Val->NativePointer);
}
void StdioFprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
struct StdVararg PrintfArgs;
PrintfArgs.Param = Param+1;
PrintfArgs.NumArgs = NumArgs;
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->NativePointer, &PrintfArgs);
}
void StdioVfprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->NativePointer, Param[2]->Val->NativePointer);
}
void StdioSprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
struct StdVararg PrintfArgs;
PrintfArgs.Param = Param+2;
PrintfArgs.NumArgs = NumArgs;
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, -1, Param[1]->Val->NativePointer, &PrintfArgs);
}
void StdioSnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
struct StdVararg PrintfArgs;
PrintfArgs.Param = Param+3;
PrintfArgs.NumArgs = NumArgs;
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->Integer, Param[2]->Val->NativePointer, &PrintfArgs);
}
void StdioVsprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, -1, Param[1]->Val->NativePointer, Param[2]->Val->NativePointer);
}
void StdioVsnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
ReturnValue->Val->Integer = StdioBaseSprintf(Parser, Param[0]->Val->NativePointer, Param[1]->Val->Integer, Param[2]->Val->NativePointer, Param[3]->Val->NativePointer);
}
const char StdioDefs[] = "\
typedef struct FILEStruct FILE; \
typedef struct __FILEStruct FILE; \
typedef struct __va_listStruct va_list; \
";
struct LibraryFunction StdioFunctions[] =
@ -193,28 +419,67 @@ struct LibraryFunction StdioFunctions[] =
{ StdioSetvbuf, "void setvbuf(FILE *, char *, int, int);" },
{ StdioUngetc, "int ungetc(int, FILE *);" },
{ StdioPuts, "int puts(char *);" },
{ StdioPrintf, "void printf(char *, ...);" },
{ StdioSprintf, "char *sprintf(char *, char *, ...);" },
{ StdioGets, "char *gets(char *);" },
{ StdioGetchar, "int getchar();" },
{ StdioGetchar, "int printf(char *format, ...);" },
{ StdioGetchar, "int fprintf(FILE *stream, char *format, ...);" },
{ StdioGetchar, "int sprintf(char *str, char *format, ...);" },
{ StdioGetchar, "int snprintf(char *str, size_t size, char *format, ...);" },
{ StdioGetchar, "int vprintf(const char *format, va_list ap);" },
{ StdioGetchar, "int vfprintf(FILE *stream, char *format, va_list ap);" },
{ StdioGetchar, "int vsprintf(char *str, char *format, va_list ap);" },
{ StdioGetchar, "int vsnprintf(char *str, size_t size, char *format, va_list ap);" },
{ NULL, NULL }
};
void StdioSetupFunc(void)
{
/* make a "struct FILEStruct" which is the same size as a native FILE structure */
TypeCreateOpaqueStruct(NULL, TableStrRegister("FILEStruct"), sizeof(FILE));
/* make a "struct __FILEStruct" which is the same size as a native FILE structure */
TypeCreateOpaqueStruct(NULL, TableStrRegister("__FILEStruct"), sizeof(FILE));
/* make a "struct __va_listStruct" which is the same size as our struct StdVararg */
TypeCreateOpaqueStruct(NULL, TableStrRegister("__va_listStruct"), sizeof(FILE));
/* define EOF equal to the system EOF */
VariableDefinePlatformVar(NULL, "EOF", &IntType, (union AnyValue *)&EOFValue, FALSE);
VariableDefinePlatformVar(NULL, "SEEK_SET", &IntType, (union AnyValue *)&SEEK_SETValue, FALSE);
VariableDefinePlatformVar(NULL, "SEEK_CUR", &IntType, (union AnyValue *)&SEEK_CURValue, FALSE);
VariableDefinePlatformVar(NULL, "SEEK_END", &IntType, (union AnyValue *)&SEEK_ENDValue, FALSE);
VariableDefinePlatformVar(NULL, "BUFSIZ", &IntType, (union AnyValue *)&BUFSIZValue, FALSE);
VariableDefinePlatformVar(NULL, "FILENAME_MAX", &IntType, (union AnyValue *)&FILENAME_MAXValue, FALSE);
VariableDefinePlatformVar(NULL, "_IOFBF", &IntType, (union AnyValue *)&_IOFBFValue, FALSE);
VariableDefinePlatformVar(NULL, "_IOLBF", &IntType, (union AnyValue *)&_IOLBFValue, FALSE);
VariableDefinePlatformVar(NULL, "_IONBF", &IntType, (union AnyValue *)&_IONBFValue, FALSE);
VariableDefinePlatformVar(NULL, "L_tmpnam", &IntType, (union AnyValue *)&L_tmpnamValue, FALSE);
VariableDefinePlatformVar(NULL, "GETS_MAX", &IntType, (union AnyValue *)&GETS_MAXValue, FALSE);
}
#endif /* NO_HASH_INCLUDE */
void PrintCh(char OutCh, FILE *Stream)
{
putc(OutCh, Stream);
}
void PrintSimpleInt(long Num, FILE *Stream)
{
fprintf(Stream, "%ld", Num);
}
void PrintStr(const char *Str, FILE *Stream)
{
fputs(Str, Stream);
}
void PrintFP(double Num, FILE *Stream)
{
fprintf(Stream, "%f", Num);
}
#endif /* !BUILTIN_MINI_STDLIB */
/*
TODO:
vprintf used to print to the standard output stream
fprintf, vfprintf used to print to a file
snprintf, vsprintf, vsnprintf used to print to a char array (C string)
scanf, vscanf used to input from the standard input stream
fscanf, vfscanf used to input from a file
sscanf, vsscanf used to input from a char array (e.g., a C string)

View file

@ -15,18 +15,11 @@ void Clineno (struct ParseState *Parser, struct Value *ReturnValue, struct Value
ReturnValue->Val->Integer = Parser->Line;
}
void Cerrormsg (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
PlatformErrorPrefix(Parser);
LibPrintf(Parser, ReturnValue, Param, NumArgs);
}
/* list of all library functions and their prototypes */
struct LibraryFunction PlatformLibrary[] =
{
{ Ctest, "void test(int);" },
{ Clineno, "int lineno();" },
{ Cerrormsg, "void errorprintf(char *,...);" },
{ NULL, NULL }
};

View file

@ -3,13 +3,16 @@
/* initialise everything */
void Initialise()
{
BasicIOInit();
HeapInit();
TableInit();
VariableInit();
LexInit();
TypeInit();
#ifdef BUILTIN_MINI_STDLIB
LibraryInit(&GlobalTable, "c library", &CLibrary);
CLibraryInit();
#endif
PlatformLibraryInit();
LibraryInit(&GlobalTable, "platform library", &PlatformLibrary);
}

22
picoc.h
View file

@ -21,6 +21,13 @@
#define GETS_BUF_MAX 256
/* small processors use a simplified FILE * for stdio, otherwise use the system FILE * */
#ifdef BUILTIN_MINI_STDLIB
typedef struct OutputStream IOFILE;
#else
typedef FILE IOFILE;
#endif
/* coercion of numeric types to other numeric types */
#ifndef NO_FP
#define IS_FP(v) ((v)->Typ->Base == TypeFP)
@ -270,6 +277,7 @@ extern struct Table GlobalTable;
extern struct StackFrame *TopStackFrame;
extern struct ValueType UberType;
extern struct ValueType IntType;
extern struct ValueType UnsignedIntType;
extern struct ValueType CharType;
#ifndef NO_FP
extern struct ValueType FPType;
@ -285,7 +293,7 @@ extern char *StrEmpty;
extern struct PointerValue NULLPointer;
extern struct LibraryFunction CLibrary[];
extern struct LibraryFunction PlatformLibrary[];
extern struct OutputStream CStdOut;
extern IOFILE *CStdOut;
/* table.c */
void TableInit();
@ -374,13 +382,15 @@ void VariableStringLiteralDefine(char *Ident, struct Value *Val);
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue);
/* clibrary.c */
void BasicIOInit();
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]);
void CLibraryInit();
void PrintCh(char OutCh, struct OutputStream *Stream);
void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream);
void PrintStr(const char *Str, struct OutputStream *Stream);
void PrintFP(double Num, struct OutputStream *Stream);
void PrintType(struct ValueType *Typ, struct OutputStream *Stream);
void PrintCh(char OutCh, IOFILE *Stream);
void PrintSimpleInt(long Num, FILE *Stream);
void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, IOFILE *Stream);
void PrintStr(const char *Str, IOFILE *Stream);
void PrintFP(double Num, IOFILE *Stream);
void PrintType(struct ValueType *Typ, IOFILE *Stream);
void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs);
/* platform.c */

View file

@ -19,23 +19,23 @@ void PrintSourceTextErrorLine(const char *FileName, const char *SourceText, int
/* display the line */
for (CPos = LinePos; *CPos != '\n' && *CPos != '\0'; CPos++)
PrintCh(*CPos, &CStdOut);
PrintCh('\n', &CStdOut);
PrintCh(*CPos, CStdOut);
PrintCh('\n', CStdOut);
/* display the error position */
for (CPos = LinePos, CCount = 0; *CPos != '\n' && *CPos != '\0' && (CCount < CharacterPos || *CPos == ' '); CPos++, CCount++)
{
if (*CPos == '\t')
PrintCh('\t', &CStdOut);
PrintCh('\t', CStdOut);
else
PrintCh(' ', &CStdOut);
PrintCh(' ', CStdOut);
}
}
else
{
/* assume we're in interactive mode - try to make the arrow match up with the input text */
for (CCount = 0; CCount < CharacterPos + strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++)
PrintCh(' ', &CStdOut);
PrintCh(' ', CStdOut);
}
PlatformPrintf("^\n%s:%d: ", FileName, Line, CharacterPos);
@ -122,18 +122,18 @@ void PlatformVPrintf(const char *Format, va_list Args)
FPos++;
switch (*FPos)
{
case 's': PrintStr(va_arg(Args, char *), &CStdOut); break;
case 'd': PrintInt(va_arg(Args, int), 0, FALSE, FALSE, &CStdOut); break;
case 'c': PrintCh(va_arg(Args, int), &CStdOut); break;
case 't': PrintType(va_arg(Args, struct ValueType *), &CStdOut); break;
case 's': PrintStr(va_arg(Args, char *), CStdOut); break;
case 'd': PrintSimpleInt(va_arg(Args, int), CStdOut); break;
case 'c': PrintCh(va_arg(Args, int), CStdOut); break;
case 't': PrintType(va_arg(Args, struct ValueType *), CStdOut); break;
#ifndef NO_FP
case 'f': PrintFP(va_arg(Args, double), &CStdOut); break;
case 'f': PrintFP(va_arg(Args, double), CStdOut); break;
#endif
case '%': PrintCh('%', &CStdOut); break;
case '%': PrintCh('%', CStdOut); break;
case '\0': FPos--; break;
}
}
else
PrintCh(*FPos, &CStdOut);
PrintCh(*FPos, CStdOut);
}
}

View file

@ -73,6 +73,7 @@ extern jmp_buf ExitBuf;
# include <setjmp.h>
# include <math.h>
# define assert(x)
# define BUILTIN_MINI_STDLIB
# undef BIG_ENDIAN
# undef FANCY_ERROR_REPORTING
@ -103,10 +104,12 @@ extern jmp_buf ExitBuf;
# define NO_CALLOC
# define NO_REALLOC
# define BROKEN_FLOAT_CASTS
# define BUILTIN_MINI_STDLIB
# else
# ifdef UMON_HOST
# define HEAP_SIZE (128*1024) /* space for the heap and the stack */
# define NO_FP
# define BUILTIN_MINI_STDLIB
# include <stdlib.h>
# include <string.h>
# include <ctype.h>