2015-06-10 15:37:21 -04:00
|
|
|
/* */
|
2012-08-29 07:21:45 -04:00
|
|
|
|
2010-06-11 13:12:49 -04:00
|
|
|
#include <errno.h>
|
2011-02-17 02:11:20 -05:00
|
|
|
#include "../interpreter.h"
|
2010-06-05 15:00:46 -04:00
|
|
|
|
2010-06-11 13:12:49 -04:00
|
|
|
#define MAX_FORMAT 80
|
2010-06-13 06:40:39 -04:00
|
|
|
#define MAX_SCANF_ARGS 10
|
2010-06-11 13:12:49 -04:00
|
|
|
|
2013-03-16 03:39:34 -04:00
|
|
|
static int Stdio_ZeroValue = 0;
|
2010-06-06 13:31:12 -04:00
|
|
|
static int EOFValue = EOF;
|
2010-06-08 13:12:20 -04:00
|
|
|
static int SEEK_SETValue = SEEK_SET;
|
|
|
|
static int SEEK_CURValue = SEEK_CUR;
|
|
|
|
static int SEEK_ENDValue = SEEK_END;
|
2010-06-11 13:12:49 -04:00
|
|
|
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;
|
2015-06-10 20:27:30 -04:00
|
|
|
static int GETS_MAXValue = 255; /* arbitrary maximum size of a gets() file */
|
2010-06-11 13:12:49 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
static FILE *stdinValue;
|
|
|
|
static FILE *stdoutValue;
|
|
|
|
static FILE *stderrValue;
|
|
|
|
|
|
|
|
|
|
|
|
/* our own internal output stream which can output to FILE * or strings */
|
2010-06-11 16:47:03 -04:00
|
|
|
typedef struct StdOutStreamStruct
|
|
|
|
{
|
|
|
|
FILE *FilePtr;
|
|
|
|
char *StrOutPtr;
|
|
|
|
int StrOutLen;
|
|
|
|
int CharCount;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-11 16:47:03 -04:00
|
|
|
} StdOutStream;
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* our representation of varargs within picoc */
|
2010-06-11 13:12:49 -04:00
|
|
|
struct StdVararg
|
|
|
|
{
|
|
|
|
struct Value **Param;
|
|
|
|
int NumArgs;
|
|
|
|
};
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* initialises the I/O system so error reporting works */
|
2012-09-22 01:11:44 -04:00
|
|
|
void BasicIOInit(Picoc *pc)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
2012-09-22 01:11:44 -04:00
|
|
|
pc->CStdOut = stdout;
|
2010-06-12 08:45:18 -04:00
|
|
|
stdinValue = stdin;
|
|
|
|
stdoutValue = stdout;
|
|
|
|
stderrValue = stderr;
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
2010-06-08 13:12:20 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* output a single character to either a FILE * or a string */
|
2010-06-11 16:47:03 -04:00
|
|
|
void StdioOutPutc(int OutCh, StdOutStream *Stream)
|
|
|
|
{
|
2015-06-07 00:51:02 -04:00
|
|
|
if (Stream->FilePtr != NULL) {
|
2010-06-11 16:47:03 -04:00
|
|
|
/* output to stdio stream */
|
|
|
|
putc(OutCh, Stream->FilePtr);
|
|
|
|
Stream->CharCount++;
|
2015-06-07 00:51:02 -04:00
|
|
|
} else if (Stream->StrOutLen < 0 || Stream->StrOutLen > 1) {
|
2010-06-11 16:47:03 -04:00
|
|
|
/* output to a string */
|
|
|
|
*Stream->StrOutPtr = OutCh;
|
|
|
|
Stream->StrOutPtr++;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-11 16:47:03 -04:00
|
|
|
if (Stream->StrOutLen > 1)
|
|
|
|
Stream->StrOutLen--;
|
|
|
|
|
|
|
|
Stream->CharCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* output a string to either a FILE * or a string */
|
2010-06-11 16:47:03 -04:00
|
|
|
void StdioOutPuts(const char *Str, StdOutStream *Stream)
|
|
|
|
{
|
2015-06-07 00:51:02 -04:00
|
|
|
if (Stream->FilePtr != NULL) {
|
2010-06-12 08:45:18 -04:00
|
|
|
/* output to stdio stream */
|
|
|
|
fputs(Str, Stream->FilePtr);
|
2015-06-07 00:51:02 -04:00
|
|
|
} else {
|
2010-06-12 08:45:18 -04:00
|
|
|
/* output to a string */
|
2015-06-07 00:51:02 -04:00
|
|
|
while (*Str != '\0') {
|
|
|
|
if (Stream->StrOutLen < 0 || Stream->StrOutLen > 1) {
|
2010-06-12 08:45:18 -04:00
|
|
|
/* output to a string */
|
|
|
|
*Stream->StrOutPtr = *Str;
|
|
|
|
Str++;
|
|
|
|
Stream->StrOutPtr++;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
if (Stream->StrOutLen > 1)
|
|
|
|
Stream->StrOutLen--;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
Stream->CharCount++;
|
2015-06-07 00:51:02 -04:00
|
|
|
}
|
2010-06-12 08:45:18 -04:00
|
|
|
}
|
|
|
|
}
|
2010-06-11 16:47:03 -04:00
|
|
|
}
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* printf-style format of an int or other word-sized object */
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFprintfWord(StdOutStream *Stream, const char *Format,
|
|
|
|
unsigned long Value)
|
2010-06-11 16:47:03 -04:00
|
|
|
{
|
|
|
|
if (Stream->FilePtr != NULL)
|
|
|
|
Stream->CharCount += fprintf(Stream->FilePtr, Format, Value);
|
2015-06-07 00:51:02 -04:00
|
|
|
else if (Stream->StrOutLen >= 0) {
|
2011-10-05 06:57:24 -04:00
|
|
|
#ifndef WIN32
|
2015-06-10 19:49:09 -04:00
|
|
|
int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen,
|
|
|
|
Format, Value);
|
2011-10-05 06:57:24 -04:00
|
|
|
#else
|
2015-06-10 19:49:09 -04:00
|
|
|
int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen,
|
|
|
|
Format, Value);
|
2011-10-05 06:57:24 -04:00
|
|
|
#endif
|
|
|
|
Stream->StrOutPtr += CCount;
|
2010-06-11 16:47:03 -04:00
|
|
|
Stream->StrOutLen -= CCount;
|
|
|
|
Stream->CharCount += CCount;
|
2015-06-07 00:51:02 -04:00
|
|
|
} else {
|
2010-06-12 08:45:18 -04:00
|
|
|
int CCount = sprintf(Stream->StrOutPtr, Format, Value);
|
|
|
|
Stream->CharCount += CCount;
|
|
|
|
Stream->StrOutPtr += CCount;
|
|
|
|
}
|
2010-06-11 16:47:03 -04:00
|
|
|
}
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* printf-style format of a floating point number */
|
2010-06-11 16:47:03 -04:00
|
|
|
void StdioFprintfFP(StdOutStream *Stream, const char *Format, double Value)
|
|
|
|
{
|
|
|
|
if (Stream->FilePtr != NULL)
|
|
|
|
Stream->CharCount += fprintf(Stream->FilePtr, Format, Value);
|
2015-06-07 00:51:02 -04:00
|
|
|
else if (Stream->StrOutLen >= 0) {
|
2011-10-05 06:57:24 -04:00
|
|
|
#ifndef WIN32
|
2015-06-10 19:49:09 -04:00
|
|
|
int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen,
|
|
|
|
Format, Value);
|
2011-10-05 06:57:24 -04:00
|
|
|
#else
|
2015-06-10 19:49:09 -04:00
|
|
|
int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen,
|
|
|
|
Format, Value);
|
2011-10-05 06:57:24 -04:00
|
|
|
#endif
|
|
|
|
Stream->StrOutPtr += CCount;
|
2010-06-11 16:47:03 -04:00
|
|
|
Stream->StrOutLen -= CCount;
|
|
|
|
Stream->CharCount += CCount;
|
2015-06-07 00:51:02 -04:00
|
|
|
} else {
|
2010-06-12 08:45:18 -04:00
|
|
|
int CCount = sprintf(Stream->StrOutPtr, Format, Value);
|
|
|
|
Stream->CharCount += CCount;
|
|
|
|
Stream->StrOutPtr += CCount;
|
|
|
|
}
|
2010-06-11 16:47:03 -04:00
|
|
|
}
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* printf-style format of a pointer */
|
2010-06-11 16:47:03 -04:00
|
|
|
void StdioFprintfPointer(StdOutStream *Stream, const char *Format, void *Value)
|
|
|
|
{
|
|
|
|
if (Stream->FilePtr != NULL)
|
|
|
|
Stream->CharCount += fprintf(Stream->FilePtr, Format, Value);
|
2015-06-07 00:51:02 -04:00
|
|
|
else if (Stream->StrOutLen >= 0) {
|
2011-10-05 06:57:24 -04:00
|
|
|
#ifndef WIN32
|
2015-06-10 19:49:09 -04:00
|
|
|
int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen,
|
|
|
|
Format, Value);
|
2011-10-05 06:57:24 -04:00
|
|
|
#else
|
2015-06-10 19:49:09 -04:00
|
|
|
int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen,
|
|
|
|
Format, Value);
|
2011-10-05 06:57:24 -04:00
|
|
|
#endif
|
2010-06-11 16:47:03 -04:00
|
|
|
Stream->StrOutPtr += CCount;
|
|
|
|
Stream->StrOutLen -= CCount;
|
|
|
|
Stream->CharCount += CCount;
|
2015-06-07 00:51:02 -04:00
|
|
|
} else {
|
2010-06-12 08:45:18 -04:00
|
|
|
int CCount = sprintf(Stream->StrOutPtr, Format, Value);
|
|
|
|
Stream->CharCount += CCount;
|
|
|
|
Stream->StrOutPtr += CCount;
|
|
|
|
}
|
2010-06-11 16:47:03 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 20:27:30 -04:00
|
|
|
/* internal do-anything v[s][n]printf() formatting system with output
|
|
|
|
to strings or FILE * */
|
2015-06-10 19:49:09 -04:00
|
|
|
int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut,
|
|
|
|
int StrOutLen, char *Format, struct StdVararg *Args)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
2010-06-12 08:45:18 -04:00
|
|
|
struct Value *ThisArg = Args->Param[0];
|
2010-06-11 13:12:49 -04:00
|
|
|
int ArgCount = 0;
|
2012-08-30 06:18:36 -04:00
|
|
|
char *FPos;
|
2010-06-11 13:12:49 -04:00
|
|
|
char OneFormatBuf[MAX_FORMAT+1];
|
|
|
|
int OneFormatCount;
|
|
|
|
struct ValueType *ShowType;
|
2010-06-11 16:47:03 -04:00
|
|
|
StdOutStream SOStream;
|
2012-09-22 01:11:44 -04:00
|
|
|
Picoc *pc = Parser->pc;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2012-08-30 06:18:36 -04:00
|
|
|
if (Format == NULL)
|
|
|
|
Format = "[null format]\n";
|
2015-06-07 00:51:02 -04:00
|
|
|
|
|
|
|
FPos = Format;
|
2010-06-11 16:47:03 -04:00
|
|
|
SOStream.FilePtr = Stream;
|
|
|
|
SOStream.StrOutPtr = StrOut;
|
|
|
|
SOStream.StrOutLen = StrOutLen;
|
|
|
|
SOStream.CharCount = 0;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
|
|
|
while (*FPos != '\0') {
|
|
|
|
if (*FPos == '%') {
|
2010-06-11 13:12:49 -04:00
|
|
|
/* work out what type we're printing */
|
|
|
|
FPos++;
|
|
|
|
ShowType = NULL;
|
2010-06-12 08:45:18 -04:00
|
|
|
OneFormatBuf[0] = '%';
|
2010-06-11 13:12:49 -04:00
|
|
|
OneFormatCount = 1;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
|
|
|
do {
|
|
|
|
switch (*FPos) {
|
2015-06-10 19:49:09 -04:00
|
|
|
case 'd':
|
|
|
|
case 'i':
|
|
|
|
ShowType = &pc->IntType;
|
|
|
|
break; /* integer decimal */
|
|
|
|
case 'o':
|
|
|
|
case 'u':
|
|
|
|
case 'x':
|
|
|
|
case 'X':
|
|
|
|
ShowType = &pc->IntType;
|
|
|
|
break; /* integer base conversions */
|
|
|
|
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 */
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-11 13:12:49 -04:00
|
|
|
/* copy one character of format across to the OneFormatBuf */
|
|
|
|
OneFormatBuf[OneFormatCount] = *FPos;
|
|
|
|
OneFormatCount++;
|
|
|
|
|
|
|
|
/* do special actions depending on the conversion type */
|
2015-06-07 00:51:02 -04:00
|
|
|
if (ShowType == &pc->VoidType) {
|
|
|
|
switch (*FPos) {
|
2015-06-10 19:49:09 -04:00
|
|
|
case 'm':
|
|
|
|
StdioOutPuts(strerror(errno), &SOStream);
|
|
|
|
break;
|
|
|
|
case '%':
|
|
|
|
StdioOutPutc(*FPos, &SOStream);
|
|
|
|
break;
|
|
|
|
case '\0':
|
|
|
|
OneFormatBuf[OneFormatCount] = '\0';
|
|
|
|
StdioOutPutc(*FPos, &SOStream);
|
|
|
|
break;
|
2015-06-07 00:51:02 -04:00
|
|
|
case 'n':
|
2015-06-10 20:27:30 -04:00
|
|
|
ThisArg = (struct Value*)((char*)ThisArg +
|
|
|
|
MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
|
|
|
|
if (ThisArg->Typ->Base == TypeArray &&
|
|
|
|
ThisArg->Typ->FromType->Base == TypeInt)
|
2015-06-07 00:51:02 -04:00
|
|
|
*(int *)ThisArg->Val->Pointer = SOStream.CharCount;
|
|
|
|
break;
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
}
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-11 16:47:03 -04:00
|
|
|
FPos++;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-11 13:12:49 -04:00
|
|
|
} while (ShowType == NULL && OneFormatCount < MAX_FORMAT);
|
2015-06-07 00:51:02 -04:00
|
|
|
|
|
|
|
if (ShowType != &pc->VoidType) {
|
2010-06-11 13:12:49 -04:00
|
|
|
if (ArgCount >= Args->NumArgs)
|
2010-06-11 16:47:03 -04:00
|
|
|
StdioOutPuts("XXX", &SOStream);
|
2015-06-07 00:51:02 -04:00
|
|
|
else {
|
2010-06-11 13:12:49 -04:00
|
|
|
/* null-terminate the buffer */
|
|
|
|
OneFormatBuf[OneFormatCount] = '\0';
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* print this argument */
|
2015-06-10 20:27:30 -04:00
|
|
|
ThisArg = (struct Value*)((char*)ThisArg +
|
|
|
|
MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
|
2015-06-07 00:51:02 -04:00
|
|
|
if (ShowType == &pc->IntType) {
|
2010-06-11 13:12:49 -04:00
|
|
|
/* show a signed integer */
|
2010-06-13 07:58:52 -04:00
|
|
|
if (IS_NUMERIC_COERCIBLE(ThisArg))
|
2015-06-10 19:49:09 -04:00
|
|
|
StdioFprintfWord(&SOStream, OneFormatBuf,
|
|
|
|
ExpressionCoerceUnsignedInteger(ThisArg));
|
2010-06-11 13:12:49 -04:00
|
|
|
else
|
2010-06-11 16:47:03 -04:00
|
|
|
StdioOutPuts("XXX", &SOStream);
|
2015-06-10 14:38:54 -04:00
|
|
|
} else if (ShowType == &pc->FPType) {
|
2010-06-11 13:12:49 -04:00
|
|
|
/* show a floating point number */
|
2010-06-13 07:58:52 -04:00
|
|
|
if (IS_NUMERIC_COERCIBLE(ThisArg))
|
2015-06-10 19:49:09 -04:00
|
|
|
StdioFprintfFP(&SOStream, OneFormatBuf,
|
|
|
|
ExpressionCoerceFP(ThisArg));
|
2010-06-11 13:12:49 -04:00
|
|
|
else
|
2010-06-11 16:47:03 -04:00
|
|
|
StdioOutPuts("XXX", &SOStream);
|
2015-06-10 14:38:54 -04:00
|
|
|
} else if (ShowType == pc->CharPtrType) {
|
2010-06-12 08:45:18 -04:00
|
|
|
if (ThisArg->Typ->Base == TypePointer)
|
2015-06-10 19:49:09 -04:00
|
|
|
StdioFprintfPointer(&SOStream, OneFormatBuf,
|
|
|
|
ThisArg->Val->Pointer);
|
2015-06-10 20:27:30 -04:00
|
|
|
else if (ThisArg->Typ->Base == TypeArray &&
|
|
|
|
ThisArg->Typ->FromType->Base == TypeChar)
|
2015-06-10 19:49:09 -04:00
|
|
|
StdioFprintfPointer(&SOStream, OneFormatBuf,
|
|
|
|
&ThisArg->Val->ArrayMem[0]);
|
2010-06-11 13:12:49 -04:00
|
|
|
else
|
2010-06-11 16:47:03 -04:00
|
|
|
StdioOutPuts("XXX", &SOStream);
|
2015-06-07 00:51:02 -04:00
|
|
|
} else if (ShowType == pc->VoidPtrType) {
|
2010-06-12 08:45:18 -04:00
|
|
|
if (ThisArg->Typ->Base == TypePointer)
|
2015-06-10 19:49:09 -04:00
|
|
|
StdioFprintfPointer(&SOStream, OneFormatBuf,
|
|
|
|
ThisArg->Val->Pointer);
|
2010-06-12 08:45:18 -04:00
|
|
|
else if (ThisArg->Typ->Base == TypeArray)
|
2015-06-10 19:49:09 -04:00
|
|
|
StdioFprintfPointer(&SOStream, OneFormatBuf,
|
|
|
|
&ThisArg->Val->ArrayMem[0]);
|
2010-06-11 13:12:49 -04:00
|
|
|
else
|
2010-06-11 16:47:03 -04:00
|
|
|
StdioOutPuts("XXX", &SOStream);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-11 13:12:49 -04:00
|
|
|
ArgCount++;
|
|
|
|
}
|
|
|
|
}
|
2015-06-07 00:51:02 -04:00
|
|
|
} else {
|
2010-06-11 13:12:49 -04:00
|
|
|
/* just output a normal character */
|
2010-06-11 16:47:03 -04:00
|
|
|
StdioOutPutc(*FPos, &SOStream);
|
|
|
|
FPos++;
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
}
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-11 16:47:03 -04:00
|
|
|
/* null-terminate */
|
|
|
|
if (SOStream.StrOutPtr != NULL && SOStream.StrOutLen > 0)
|
2015-06-07 00:51:02 -04:00
|
|
|
*SOStream.StrOutPtr = '\0';
|
|
|
|
|
2010-06-11 16:47:03 -04:00
|
|
|
return SOStream.CharCount;
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
2010-06-06 13:31:12 -04:00
|
|
|
|
2015-06-10 20:27:30 -04:00
|
|
|
/* internal do-anything v[s][n]scanf() formatting system with input
|
|
|
|
from strings or FILE * */
|
2015-06-10 19:49:09 -04:00
|
|
|
int StdioBaseScanf(struct ParseState *Parser, FILE *Stream, char *StrIn,
|
|
|
|
char *Format, struct StdVararg *Args)
|
2010-06-13 05:17:42 -04:00
|
|
|
{
|
|
|
|
struct Value *ThisArg = Args->Param[0];
|
|
|
|
int ArgCount = 0;
|
2010-06-13 06:40:39 -04:00
|
|
|
void *ScanfArg[MAX_SCANF_ARGS];
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-13 06:40:39 -04:00
|
|
|
if (Args->NumArgs > MAX_SCANF_ARGS)
|
2015-06-10 19:49:09 -04:00
|
|
|
ProgramFail(Parser, "too many arguments to scanf() - %d max",
|
|
|
|
MAX_SCANF_ARGS);
|
2015-06-07 00:51:02 -04:00
|
|
|
|
|
|
|
for (ArgCount = 0; ArgCount < Args->NumArgs; ArgCount++) {
|
2015-06-10 20:27:30 -04:00
|
|
|
ThisArg = (struct Value*)((char*)ThisArg +
|
|
|
|
MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
|
2015-06-07 00:51:02 -04:00
|
|
|
|
|
|
|
if (ThisArg->Typ->Base == TypePointer)
|
2010-06-13 10:41:03 -04:00
|
|
|
ScanfArg[ArgCount] = ThisArg->Val->Pointer;
|
2010-06-13 06:40:39 -04:00
|
|
|
else if (ThisArg->Typ->Base == TypeArray)
|
|
|
|
ScanfArg[ArgCount] = &ThisArg->Val->ArrayMem[0];
|
2010-06-13 05:17:42 -04:00
|
|
|
else
|
2015-06-10 19:49:09 -04:00
|
|
|
ProgramFail(Parser,
|
|
|
|
"non-pointer argument to scanf() - argument %d after format",
|
|
|
|
ArgCount+1);
|
2010-06-13 05:17:42 -04:00
|
|
|
}
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-13 06:40:39 -04:00
|
|
|
if (Stream != NULL)
|
2015-06-10 19:49:09 -04:00
|
|
|
return fscanf(Stream, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2],
|
|
|
|
ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7],
|
|
|
|
ScanfArg[8], ScanfArg[9]);
|
2010-06-13 06:40:39 -04:00
|
|
|
else
|
2015-06-10 19:49:09 -04:00
|
|
|
return sscanf(StrIn, Format, ScanfArg[0], ScanfArg[1], ScanfArg[2],
|
|
|
|
ScanfArg[3], ScanfArg[4], ScanfArg[5], ScanfArg[6], ScanfArg[7],
|
|
|
|
ScanfArg[8], ScanfArg[9]);
|
2010-06-13 05:17:42 -04:00
|
|
|
}
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* stdio calls */
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFopen(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-05 15:00:46 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Pointer = fopen(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-05 15:00:46 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFreopen(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Pointer = freopen(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Pointer, Param[2]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFclose(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-05 15:00:46 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Integer = fclose(Param[0]->Val->Pointer);
|
2010-06-05 15:00:46 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFread(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-05 15:00:46 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = fread(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer);
|
2010-06-05 15:00:46 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFwrite(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-05 15:00:46 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = fwrite(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Integer, Param[2]->Val->Integer, Param[3]->Val->Pointer);
|
2010-06-05 15:00:46 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFgetc(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-05 15:00:46 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Integer = fgetc(Param[0]->Val->Pointer);
|
2010-06-05 15:00:46 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFgets(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-05 15:00:46 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Integer, Param[2]->Val->Pointer);
|
2010-06-05 15:00:46 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioRemove(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Integer = remove(Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioRename(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = rename(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioRewind(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
rewind(Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioTmpfile(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Pointer = tmpfile();
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioClearerr(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-29 06:28:13 -04:00
|
|
|
clearerr((FILE *)Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFeof(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-29 06:28:13 -04:00
|
|
|
ReturnValue->Val->Integer = feof((FILE *)Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFerror(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-29 06:28:13 -04:00
|
|
|
ReturnValue->Val->Integer = ferror((FILE *)Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFileno(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2011-10-05 06:57:24 -04:00
|
|
|
#ifndef WIN32
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Integer = fileno(Param[0]->Val->Pointer);
|
2011-10-05 06:57:24 -04:00
|
|
|
#else
|
|
|
|
ReturnValue->Val->Integer = _fileno(Param[0]->Val->Pointer);
|
|
|
|
#endif
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFflush(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Integer = fflush(Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFgetpos(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 20:27:30 -04:00
|
|
|
ReturnValue->Val->Integer = fgetpos(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFsetpos(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 20:27:30 -04:00
|
|
|
ReturnValue->Val->Integer = fsetpos(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFputc(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 20:27:30 -04:00
|
|
|
ReturnValue->Val->Integer = fputc(Param[0]->Val->Integer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFputs(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 20:27:30 -04:00
|
|
|
ReturnValue->Val->Integer = fputs(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFtell(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Integer = ftell(Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFseek(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = fseek(Param[0]->Val->Pointer,
|
|
|
|
Param[1]->Val->Integer, Param[2]->Val->Integer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioPerror(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
perror(Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioPutc(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = putc(Param[0]->Val->Integer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioPutchar(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
|
|
|
ReturnValue->Val->Integer = putchar(Param[0]->Val->Integer);
|
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioSetbuf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
setbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioSetvbuf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
setvbuf(Param[0]->Val->Pointer, Param[1]->Val->Pointer,
|
|
|
|
Param[2]->Val->Integer, Param[3]->Val->Integer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioUngetc(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = ungetc(Param[0]->Val->Integer,
|
|
|
|
Param[1]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioPuts(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-08 13:12:20 -04:00
|
|
|
{
|
2010-06-13 10:41:03 -04:00
|
|
|
ReturnValue->Val->Integer = puts(Param[0]->Val->Pointer);
|
2010-06-08 13:12:20 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioGets(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Pointer = fgets(Param[0]->Val->Pointer,
|
|
|
|
GETS_MAXValue, stdin);
|
2015-06-07 00:51:02 -04:00
|
|
|
if (ReturnValue->Val->Pointer != NULL) {
|
2011-02-11 21:42:17 -05:00
|
|
|
char *EOLPos = strchr(Param[0]->Val->Pointer, '\n');
|
|
|
|
if (EOLPos != NULL)
|
|
|
|
*EOLPos = '\0';
|
|
|
|
}
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioGetchar(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
|
|
|
ReturnValue->Val->Integer = getchar();
|
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioPrintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
|
|
|
struct StdVararg PrintfArgs;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
PrintfArgs.Param = Param;
|
|
|
|
PrintfArgs.NumArgs = NumArgs-1;
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0,
|
|
|
|
Param[0]->Val->Pointer, &PrintfArgs);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioVprintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, stdout, NULL, 0,
|
|
|
|
Param[0]->Val->Pointer, Param[1]->Val->Pointer);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFprintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
|
|
|
struct StdVararg PrintfArgs;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
PrintfArgs.Param = Param + 1;
|
|
|
|
PrintfArgs.NumArgs = NumArgs-2;
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer,
|
|
|
|
NULL, 0, Param[1]->Val->Pointer, &PrintfArgs);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioVfprintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, Param[0]->Val->Pointer,
|
|
|
|
NULL, 0, Param[1]->Val->Pointer, Param[2]->Val->Pointer);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioSprintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
|
|
|
struct StdVararg PrintfArgs;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
PrintfArgs.Param = Param + 1;
|
|
|
|
PrintfArgs.NumArgs = NumArgs-2;
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
|
|
|
|
Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer, &PrintfArgs);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioSnprintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
|
|
|
struct StdVararg PrintfArgs;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-13 06:40:39 -04:00
|
|
|
PrintfArgs.Param = Param+2;
|
2010-06-12 08:45:18 -04:00
|
|
|
PrintfArgs.NumArgs = NumArgs-3;
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
|
2015-06-10 20:27:30 -04:00
|
|
|
Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer,
|
|
|
|
&PrintfArgs);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioScanf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-13 05:17:42 -04:00
|
|
|
{
|
|
|
|
struct StdVararg ScanfArgs;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-13 06:40:39 -04:00
|
|
|
ScanfArgs.Param = Param;
|
|
|
|
ScanfArgs.NumArgs = NumArgs-1;
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL,
|
|
|
|
Param[0]->Val->Pointer, &ScanfArgs);
|
2010-06-13 06:40:39 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioFscanf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-13 06:40:39 -04:00
|
|
|
{
|
|
|
|
struct StdVararg ScanfArgs;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-13 06:40:39 -04:00
|
|
|
ScanfArgs.Param = Param+1;
|
|
|
|
ScanfArgs.NumArgs = NumArgs-2;
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer,
|
|
|
|
NULL, Param[1]->Val->Pointer, &ScanfArgs);
|
2010-06-13 06:40:39 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioSscanf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-13 06:40:39 -04:00
|
|
|
{
|
|
|
|
struct StdVararg ScanfArgs;
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-13 06:40:39 -04:00
|
|
|
ScanfArgs.Param = Param+1;
|
|
|
|
ScanfArgs.NumArgs = NumArgs-2;
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL,
|
|
|
|
Param[0]->Val->Pointer, Param[1]->Val->Pointer, &ScanfArgs);
|
2010-06-13 05:17:42 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioVsprintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
|
2015-06-10 20:27:30 -04:00
|
|
|
Param[0]->Val->Pointer, -1, Param[1]->Val->Pointer,
|
|
|
|
Param[2]->Val->Pointer);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioVsnprintf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-11 13:12:49 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBasePrintf(Parser, NULL,
|
2015-06-10 20:27:30 -04:00
|
|
|
Param[0]->Val->Pointer, Param[1]->Val->Integer, Param[2]->Val->Pointer,
|
|
|
|
Param[3]->Val->Pointer);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioVscanf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-13 06:40:39 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBaseScanf(Parser, stdin, NULL,
|
|
|
|
Param[0]->Val->Pointer, Param[1]->Val->Pointer);
|
2010-06-13 06:40:39 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioVfscanf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-13 06:40:39 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBaseScanf(Parser, Param[0]->Val->Pointer,
|
|
|
|
NULL, Param[1]->Val->Pointer, Param[2]->Val->Pointer);
|
2010-06-13 06:40:39 -04:00
|
|
|
}
|
|
|
|
|
2015-06-10 19:49:09 -04:00
|
|
|
void StdioVsscanf(struct ParseState *Parser, struct Value *ReturnValue,
|
|
|
|
struct Value **Param, int NumArgs)
|
2010-06-13 06:40:39 -04:00
|
|
|
{
|
2015-06-10 19:49:09 -04:00
|
|
|
ReturnValue->Val->Integer = StdioBaseScanf(Parser, NULL,
|
|
|
|
Param[0]->Val->Pointer, Param[1]->Val->Pointer, Param[2]->Val->Pointer);
|
2010-06-13 06:40:39 -04:00
|
|
|
}
|
2010-06-08 13:12:20 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* handy structure definitions */
|
2010-06-05 15:00:46 -04:00
|
|
|
const char StdioDefs[] = "\
|
2010-06-11 13:12:49 -04:00
|
|
|
typedef struct __va_listStruct va_list; \
|
2010-06-12 08:45:18 -04:00
|
|
|
typedef struct __FILEStruct FILE;\
|
2010-06-05 15:00:46 -04:00
|
|
|
";
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* all stdio functions */
|
2010-06-05 15:00:46 -04:00
|
|
|
struct LibraryFunction StdioFunctions[] =
|
|
|
|
{
|
2015-06-09 03:45:00 -04:00
|
|
|
{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}
|
2010-06-05 15:00:46 -04:00
|
|
|
};
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* creates various system-dependent definitions */
|
2012-09-22 01:11:44 -04:00
|
|
|
void StdioSetupFunc(Picoc *pc)
|
2010-06-05 15:00:46 -04:00
|
|
|
{
|
2010-06-12 08:45:18 -04:00
|
|
|
struct ValueType *StructFileType;
|
|
|
|
struct ValueType *FilePtrType;
|
|
|
|
|
2015-06-10 20:27:30 -04:00
|
|
|
/* make a "struct __FILEStruct" which is the same size as a
|
|
|
|
native FILE structure */
|
2015-06-10 19:49:09 -04:00
|
|
|
StructFileType = TypeCreateOpaqueStruct(pc, NULL,
|
|
|
|
TableStrRegister(pc, "__FILEStruct"), sizeof(FILE));
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* get a FILE * type */
|
2015-06-10 19:49:09 -04:00
|
|
|
FilePtrType = TypeGetMatching(pc, NULL, StructFileType, TypePointer, 0,
|
|
|
|
pc->StrEmpty, true);
|
2010-06-11 13:12:49 -04:00
|
|
|
|
2015-06-10 20:27:30 -04:00
|
|
|
/* make a "struct __va_listStruct" which is the same size as
|
|
|
|
our struct StdVararg */
|
2015-06-10 19:49:09 -04:00
|
|
|
TypeCreateOpaqueStruct(pc, NULL, TableStrRegister(pc, "__va_listStruct"),
|
|
|
|
sizeof(FILE));
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-06 13:31:12 -04:00
|
|
|
/* define EOF equal to the system EOF */
|
2015-06-10 19:49:09 -04:00
|
|
|
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);
|
2015-06-07 00:51:02 -04:00
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* define stdin, stdout and stderr */
|
2015-06-10 19:49:09 -04:00
|
|
|
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);
|
2010-06-13 07:58:52 -04:00
|
|
|
|
2015-06-10 15:24:53 -04:00
|
|
|
/* define NULL, true and false */
|
2012-09-22 01:11:44 -04:00
|
|
|
if (!VariableDefined(pc, TableStrRegister(pc, "NULL")))
|
2015-06-10 19:49:09 -04:00
|
|
|
VariableDefinePlatformVar(pc, NULL, "NULL", &pc->IntType,
|
|
|
|
(union AnyValue*)&Stdio_ZeroValue, false);
|
2010-06-11 13:12:49 -04:00
|
|
|
}
|
|
|
|
|
2010-06-12 08:45:18 -04:00
|
|
|
/* portability-related I/O calls */
|
2010-06-11 13:12:49 -04:00
|
|
|
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);
|
2010-06-05 15:00:46 -04:00
|
|
|
}
|
|
|
|
|