/* */ #include #include #include #include "../interpreter.h" #define MAX_FORMAT (80) #define MAX_SCANF_ARGS (10) static int Stdio_ZeroValue = 0; 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 */ static FILE *stdinValue; static FILE *stdoutValue; static FILE *stderrValue; /* our own internal output stream which can output to FILE * or strings */ typedef struct StdOutStreamStruct { FILE *FilePtr; char *StrOutPtr; int StrOutLen; int CharCount; } StdOutStream; /* our representation of varargs within picoc */ struct StdVararg { struct Value **Param; int NumArgs; }; /* initializes the I/O system so error reporting works */ void BasicIOInit(Picoc *pc) { pc->CStdOut = stdout; stdinValue = stdin; stdoutValue = stdout; stderrValue = stderr; } /* output a single character to either a FILE * or a string */ void StdioOutPutc(int OutCh, StdOutStream *Stream) { if (Stream->FilePtr != NULL) { /* output to stdio stream */ putc(OutCh, Stream->FilePtr); Stream->CharCount++; } else if (Stream->StrOutLen < 0 || Stream->StrOutLen > 1) { /* output to a string */ *Stream->StrOutPtr = OutCh; Stream->StrOutPtr++; if (Stream->StrOutLen > 1) Stream->StrOutLen--; Stream->CharCount++; } } /* output a string to either a FILE * or a string */ void StdioOutPuts(const char *Str, StdOutStream *Stream) { if (Stream->FilePtr != NULL) { /* output to stdio stream */ fputs(Str, Stream->FilePtr); } else { /* output to a string */ while (*Str != '\0') { if (Stream->StrOutLen < 0 || Stream->StrOutLen > 1) { /* output to a string */ *Stream->StrOutPtr = *Str; Str++; Stream->StrOutPtr++; if (Stream->StrOutLen > 1) Stream->StrOutLen--; Stream->CharCount++; } } } } /* printf-style format of an int or other word-sized object */ void StdioFprintfWord(StdOutStream *Stream, const char *Format, unsigned int Value) { if (Stream->FilePtr != NULL) Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); else if (Stream->StrOutLen >= 0) { #ifndef WIN32 int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); #else int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); #endif Stream->StrOutPtr += CCount; Stream->StrOutLen -= CCount; Stream->CharCount += CCount; } else { int CCount = sprintf(Stream->StrOutPtr, Format, Value); Stream->CharCount += CCount; Stream->StrOutPtr += CCount; } } /* 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) { if (Stream->FilePtr != NULL) Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); else if (Stream->StrOutLen >= 0) { #ifndef WIN32 int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); #else int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); #endif Stream->StrOutPtr += CCount; Stream->StrOutLen -= CCount; Stream->CharCount += CCount; } else { int CCount = sprintf(Stream->StrOutPtr, Format, Value); Stream->CharCount += CCount; Stream->StrOutPtr += CCount; } } /* printf-style format of a pointer */ void StdioFprintfPointer(StdOutStream *Stream, const char *Format, void *Value) { if (Stream->FilePtr != NULL) Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); else if (Stream->StrOutLen >= 0) { #ifndef WIN32 int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); #else int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, Format, Value); #endif Stream->StrOutPtr += CCount; Stream->StrOutLen -= CCount; Stream->CharCount += CCount; } else { int CCount = sprintf(Stream->StrOutPtr, Format, Value); Stream->CharCount += CCount; Stream->StrOutPtr += CCount; } } /* internal do-anything v[s][n]printf() formatting system with output to strings or FILE * */ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, int StrOutLen, char *Format, struct StdVararg *Args) { struct Value *ThisArg = Args->Param[0]; int ArgCount = 0; char *FPos; char OneFormatBuf[MAX_FORMAT+1]; int OneFormatCount; int ShowLong = 0; struct ValueType *ShowType; StdOutStream SOStream; Picoc *pc = Parser->pc; if (Format == NULL) Format = "[null format]\n"; FPos = Format; SOStream.FilePtr = Stream; SOStream.StrOutPtr = StrOut; SOStream.StrOutLen = StrOutLen; SOStream.CharCount = 0; while (*FPos != '\0') { if (*FPos == '%') { /* work out what type we're printing */ FPos++; ShowType = NULL; OneFormatBuf[0] = '%'; OneFormatCount = 1; do { switch (*FPos) { case 'd': case 'i': if (ShowLong) { ShowLong = 0; ShowType = &pc->LongType; } else { ShowType = &pc->IntType; } break; case 'u': if (ShowLong) { ShowLong = 0; ShowType = &pc->UnsignedLongType; break; } case 'o': case 'x': case 'X': ShowType = &pc->IntType; break; /* integer base conversions */ case 'l': ShowLong = 1; break; /* long integer */ case 'e': case 'E': ShowType = &pc->FPType; break; /* double, exponent form */ case 'f': case 'F': ShowType = &pc->FPType; break; /* double, fixed-point */ case 'g': case 'G': ShowType = &pc->FPType; break; /* double, flexible format */ case 'a': case 'A': ShowType = &pc->IntType; break; /* hexadecimal, 0x- format */ case 'c': ShowType = &pc->IntType; break; /* character */ case 's': ShowType = pc->CharPtrType; break; /* string */ case 'p': ShowType = pc->VoidPtrType; break; /* pointer */ case 'n': ShowType = &pc->VoidType; break; /* number of characters written */ case 'm': ShowType = &pc->VoidType; break; /* strerror(errno) */ case '%': ShowType = &pc->VoidType; break; /* just a '%' character */ case '\0': ShowType = &pc->VoidType; break; /* end of format string */ } /* copy one character of format across to the OneFormatBuf */ if (*FPos != 'l') { OneFormatBuf[OneFormatCount] = *FPos; OneFormatCount++; } /* do special actions depending on the conversion type */ if (ShowType == &pc->VoidType) { switch (*FPos) { case 'm': StdioOutPuts(strerror(errno), &SOStream); break; case '%': StdioOutPutc(*FPos, &SOStream); break; case '\0': OneFormatBuf[OneFormatCount] = '\0'; StdioOutPutc(*FPos, &SOStream); break; case 'n': ThisArg = (struct Value*)((char*)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeInt) *(int *)ThisArg->Val->Pointer = SOStream.CharCount; break; } } FPos++; } while (ShowType == NULL && OneFormatCount < MAX_FORMAT); if (ShowType != &pc->VoidType) { if (ArgCount >= Args->NumArgs) StdioOutPuts("XXX", &SOStream); else { /* null-terminate the buffer */ OneFormatBuf[OneFormatCount] = '\0'; /* print this argument */ ThisArg = (struct Value*)((char*)ThisArg + MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg))); if (ShowType == &pc->LongType) { /* show a signed long */ if (IS_NUMERIC_COERCIBLE(ThisArg)) StdioFprintfLong(&SOStream, OneFormatBuf, ThisArg->Val->LongInteger); else StdioOutPuts("XXX", &SOStream); } else if (ShowType == &pc->UnsignedLongType) { /* show a unsigned long */ if (IS_NUMERIC_COERCIBLE(ThisArg)) StdioFprintfLong(&SOStream, OneFormatBuf, ThisArg->Val->UnsignedLongInteger); else StdioOutPuts("XXX", &SOStream); } else if (ShowType == &pc->IntType) { /* show a signed integer */ if (IS_NUMERIC_COERCIBLE(ThisArg)) StdioFprintfWord(&SOStream, OneFormatBuf, (unsigned int)ExpressionCoerceUnsignedInteger(ThisArg)); else StdioOutPuts("XXX", &SOStream); } else if (ShowType == &pc->FPType) { /* show a floating point number */ if (IS_NUMERIC_COERCIBLE(ThisArg)) StdioFprintfFP(&SOStream, OneFormatBuf, ExpressionCoerceFP(ThisArg)); else StdioOutPuts("XXX", &SOStream); } else if (ShowType == pc->CharPtrType) { if (ThisArg->Typ->Base == TypePointer) StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer); else if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeChar) StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); else StdioOutPuts("XXX", &SOStream); } else if (ShowType == pc->VoidPtrType) { if (ThisArg->Typ->Base == TypePointer) StdioFprintfPointer(&SOStream, OneFormatBuf, ThisArg->Val->Pointer); else if (ThisArg->Typ->Base == TypeArray) StdioFprintfPointer(&SOStream, OneFormatBuf, &ThisArg->Val->ArrayMem[0]); else StdioOutPuts("XXX", &SOStream); } ArgCount++; } } } else { /* just output a normal character */ StdioOutPutc(*FPos, &SOStream); FPos++; } } /* null-terminate */ if (SOStream.StrOutPtr != NULL && SOStream.StrOutLen > 0) *SOStream.StrOutPtr = '\0'; return SOStream.CharCount; } /* internal do-anything v[s][n]scanf() formatting system with input from strings or FILE * */ int StdioBaseScanf(struct ParseState *Parser, FILE *Stream, char *StrIn, char *Format, struct StdVararg *Args) { struct Value *ThisArg = Args->Param[0]; int ArgCount = 0; void *ScanfArg[MAX_SCANF_ARGS]; if (Args->NumArgs > MAX_SCANF_ARGS) ProgramFail(Parser, "too many arguments to scanf() - %d max", MAX_SCANF_ARGS); for (ArgCount = 0; ArgCount < Args->NumArgs; ArgCount++) { ThisArg = (struct Value*)((char*)ThisArg + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); if (ThisArg->Typ->Base == TypePointer) ScanfArg[ArgCount] = ThisArg->Val->Pointer; else if (ThisArg->Typ->Base == TypeArray) ScanfArg[ArgCount] = &ThisArg->Val->ArrayMem[0]; else ProgramFail(Parser, "non-pointer argument to scanf() - argument %d after format", ArgCount+1); } if (Stream != NULL) return fscanf(Stream, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2], ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7], ScanfArg[8], ScanfArg[9]); else return sscanf(StrIn, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2], ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7], ScanfArg[8], ScanfArg[9]); } /* stdio calls */ void StdioFopen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Pointer = fopen(Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioFreopen(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Pointer = freopen(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer); } void StdioFclose(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fclose(Param[0]->Val->Pointer); } void StdioFread(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fread(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer); } void StdioFwrite(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fwrite(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer); } void StdioFgetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fgetc(Param[0]->Val->Pointer); } void StdioFgets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer); } void StdioRemove(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = remove(Param[0]->Val->Pointer); } void StdioRename(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = rename(Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioRewind(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { rewind(Param[0]->Val->Pointer); } void StdioTmpfile(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Pointer = tmpfile(); } void StdioClearerr(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { clearerr((FILE *)Param[0]->Val->Pointer); } void StdioFeof(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = feof((FILE *)Param[0]->Val->Pointer); } void StdioFerror(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = ferror((FILE *)Param[0]->Val->Pointer); } void StdioFileno(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { #ifndef WIN32 ReturnValue->Val->Integer = fileno(Param[0]->Val->Pointer); #else ReturnValue->Val->Integer = _fileno(Param[0]->Val->Pointer); #endif } void StdioFflush(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fflush(Param[0]->Val->Pointer); } void StdioFgetpos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fgetpos(Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioFsetpos(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fsetpos(Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioFputc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fputc(Param[0]->Val->Integer, Param[1]->Val->Pointer); } void StdioFputs(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fputs(Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioFtell(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = ftell(Param[0]->Val->Pointer); } void StdioFseek(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = fseek(Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Integer); } void StdioPerror(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { perror(Param[0]->Val->Pointer); } void StdioPutc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = putc(Param[0]->Val->Integer, Param[1]->Val->Pointer); } void StdioPutchar(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = putchar(Param[0]->Val->Integer); } void StdioSetbuf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { setbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioSetvbuf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { setvbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Integer, Param[3]->Val->Integer); } void StdioUngetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = ungetc(Param[0]->Val->Integer, Param[1]->Val->Pointer); } void StdioPuts(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = puts(Param[0]->Val->Pointer); } void StdioGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer, GETS_MAXValue, stdin); if (ReturnValue->Val->Pointer != NULL) { char *EOLPos = strchr(Param[0]->Val->Pointer, '\n'); if (EOLPos != NULL) *EOLPos = '\0'; } } 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; PrintfArgs.NumArgs = NumArgs - 1; ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0, Param[0]->Val->Pointer, &PrintfArgs); } void StdioVprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0, Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioFprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg PrintfArgs; PrintfArgs.Param = Param + 1; PrintfArgs.NumArgs = NumArgs - 2; ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer, NULL, 0, Param[1]->Val->Pointer, &PrintfArgs); } void StdioVfprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer, NULL, 0, Param[1]->Val->Pointer, Param[2]->Val->Pointer); } void StdioSprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg PrintfArgs; PrintfArgs.Param = Param + 1; PrintfArgs.NumArgs = NumArgs - 2; ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer, &PrintfArgs); } void StdioSnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg PrintfArgs; PrintfArgs.Param = Param + 2; PrintfArgs.NumArgs = NumArgs - 3; ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, &PrintfArgs); } void StdioScanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg ScanfArgs; ScanfArgs.Param = Param; ScanfArgs.NumArgs = NumArgs - 1; ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL, Param[0]->Val->Pointer, &ScanfArgs); } void StdioFscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg ScanfArgs; ScanfArgs.Param = Param+1; ScanfArgs.NumArgs = NumArgs - 2; ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer, NULL, Param[1]->Val->Pointer, &ScanfArgs); } void StdioSscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { struct StdVararg ScanfArgs; ScanfArgs.Param = Param+1; ScanfArgs.NumArgs = NumArgs - 2; ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Pointer, &ScanfArgs); } void StdioVsprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer, Param[2]->Val->Pointer); } void StdioVsnprintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer, Param[3]->Val->Pointer); } void StdioVscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL, Param[0]->Val->Pointer, Param[1]->Val->Pointer); } void StdioVfscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer, NULL, Param[1]->Val->Pointer, Param[2]->Val->Pointer); } void StdioVsscanf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL, Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer); } /* handy structure definitions */ const char StdioDefs[] = "\ typedef struct __va_listStruct va_list; \ typedef struct __FILEStruct FILE;\ "; /* all stdio functions */ struct LibraryFunction StdioFunctions[] = { {StdioFopen, "FILE *fopen(char *, char *);"}, {StdioFreopen, "FILE *freopen(char *, char *, FILE *);"}, {StdioFclose, "int fclose(FILE *);"}, {StdioFread, "int fread(void *, int, int, FILE *);"}, {StdioFwrite, "int fwrite(void *, int, int, FILE *);"}, {StdioFgetc, "int fgetc(FILE *);"}, {StdioFgetc, "int getc(FILE *);"}, {StdioFgets, "char *fgets(char *, int, FILE *);"}, {StdioFputc, "int fputc(int, FILE *);"}, {StdioFputs, "int fputs(char *, FILE *);"}, {StdioRemove, "int remove(char *);"}, {StdioRename, "int rename(char *, char *);"}, {StdioRewind, "void rewind(FILE *);"}, {StdioTmpfile, "FILE *tmpfile();"}, {StdioClearerr,"void clearerr(FILE *);"}, {StdioFeof, "int feof(FILE *);"}, {StdioFerror, "int ferror(FILE *);"}, {StdioFileno, "int fileno(FILE *);"}, {StdioFflush, "int fflush(FILE *);"}, {StdioFgetpos, "int fgetpos(FILE *, int *);"}, {StdioFsetpos, "int fsetpos(FILE *, int *);"}, {StdioFtell, "int ftell(FILE *);"}, {StdioFseek, "int fseek(FILE *, int, int);"}, {StdioPerror, "void perror(char *);"}, {StdioPutc, "int putc(char *, FILE *);"}, {StdioPutchar, "int putchar(int);"}, {StdioPutchar, "int fputchar(int);"}, {StdioSetbuf, "void setbuf(FILE *, char *);"}, {StdioSetvbuf, "void setvbuf(FILE *, char *, int, int);"}, {StdioUngetc, "int ungetc(int, FILE *);"}, {StdioPuts, "int puts(char *);"}, {StdioGets, "char *gets(char *);"}, {StdioGetchar, "int getchar();"}, {StdioPrintf, "int printf(char *, ...);"}, {StdioFprintf, "int fprintf(FILE *, char *, ...);"}, {StdioSprintf, "int sprintf(char *, char *, ...);"}, {StdioSnprintf,"int snprintf(char *, int, char *, ...);"}, {StdioScanf, "int scanf(char *, ...);"}, {StdioFscanf, "int fscanf(FILE *, char *, ...);"}, {StdioSscanf, "int sscanf(char *, char *, ...);"}, {StdioVprintf, "int vprintf(char *, va_list);"}, {StdioVfprintf,"int vfprintf(FILE *, char *, va_list);"}, {StdioVsprintf,"int vsprintf(char *, char *, va_list);"}, {StdioVsnprintf,"int vsnprintf(char *, int, char *, va_list);"}, {StdioVscanf, "int vscanf(char *, va_list);"}, {StdioVfscanf, "int vfscanf(FILE *, char *, va_list);"}, {StdioVsscanf, "int vsscanf(char *, char *, va_list);"}, {NULL, NULL} }; /* creates various system-dependent definitions */ void StdioSetupFunc(Picoc *pc) { struct ValueType *StructFileType; struct ValueType *FilePtrType; /* make a "struct __FILEStruct" which is the same size as a native FILE structure */ StructFileType = TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__FILEStruct"), sizeof(FILE)); /* get a FILE * type */ FilePtrType = TypeGetMatching(pc, NULL, StructFileType, TypePointer, 0, pc->StrEmpty, true); /* make a "struct __va_listStruct" which is the same size as our struct StdVararg */ TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__va_listStruct"), sizeof(FILE)); /* define EOF equal to the system EOF */ VariableDefinePlatformVar(pc, NULL, "EOF", &pc->IntType, (union AnyValue*)&EOFValue, false); VariableDefinePlatformVar(pc, NULL, "SEEK_SET", &pc->IntType, (union AnyValue*)&SEEK_SETValue, false); VariableDefinePlatformVar(pc, NULL, "SEEK_CUR", &pc->IntType, (union AnyValue*)&SEEK_CURValue, false); VariableDefinePlatformVar(pc, NULL, "SEEK_END", &pc->IntType, (union AnyValue*)&SEEK_ENDValue, false); VariableDefinePlatformVar(pc, NULL, "BUFSIZ", &pc->IntType, (union AnyValue*)&BUFSIZValue, false); VariableDefinePlatformVar(pc, NULL, "FILENAME_MAX", &pc->IntType, (union AnyValue*)&FILENAME_MAXValue, false); VariableDefinePlatformVar(pc, NULL, "_IOFBF", &pc->IntType, (union AnyValue*)&_IOFBFValue, false); VariableDefinePlatformVar(pc, NULL, "_IOLBF", &pc->IntType, (union AnyValue*)&_IOLBFValue, false); VariableDefinePlatformVar(pc, NULL, "_IONBF", &pc->IntType, (union AnyValue*)&_IONBFValue, false); VariableDefinePlatformVar(pc, NULL, "L_tmpnam", &pc->IntType, (union AnyValue*)&L_tmpnamValue, false); VariableDefinePlatformVar(pc, NULL, "GETS_MAX", &pc->IntType, (union AnyValue*)&GETS_MAXValue, false); /* define stdin, stdout and stderr */ VariableDefinePlatformVar(pc, NULL, "stdin", FilePtrType, (union AnyValue*)&stdinValue, false); VariableDefinePlatformVar(pc, NULL, "stdout", FilePtrType, (union AnyValue*)&stdoutValue, false); VariableDefinePlatformVar(pc, NULL, "stderr", FilePtrType, (union AnyValue*)&stderrValue, false); /* define NULL, true and false */ if (!VariableDefined(pc, TableStrRegister(pc, "NULL"))) VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType, (union AnyValue*)&Stdio_ZeroValue, false); } /* portability-related I/O calls */ 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); }