📄 iofun.c
字号:
returnValue->value = (void *) EnvAddSymbol(theEnv,buffer);
rm(theEnv,buffer,(int) sizeof (char) * line_max);
return;
}
/*************************************************************/
/* FillBuffer: Read characters from a specified logical name */
/* and places them into a buffer until a carriage return */
/* or end-of-file character is read. */
/*************************************************************/
static char *FillBuffer(
void *theEnv,
char *logicalName,
int *currentPosition,
unsigned *maximumSize)
{
int c;
char *buf = NULL;
/*================================*/
/* Read until end of line or eof. */
/*================================*/
c = EnvGetcRouter(theEnv,logicalName);
if (c == EOF)
{ return(NULL); }
/*==================================*/
/* Grab characters until cr or eof. */
/*==================================*/
while ((c != '\n') && (c != '\r') && (c != EOF) &&
(! GetHaltExecution(theEnv)))
{
buf = ExpandStringWithChar(theEnv,c,buf,currentPosition,maximumSize,*maximumSize+80);
c = EnvGetcRouter(theEnv,logicalName);
}
/*==================*/
/* Add closing EOS. */
/*==================*/
buf = ExpandStringWithChar(theEnv,EOS,buf,currentPosition,maximumSize,*maximumSize+80);
return (buf);
}
/*****************************************/
/* SetLocaleFunction: H/L access routine */
/* for the set-locale function. */
/*****************************************/
globle void SetLocaleFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
DATA_OBJECT theResult;
int numArgs;
/*======================================*/
/* Check for valid number of arguments. */
/*======================================*/
if ((numArgs = EnvArgCountCheck(theEnv,"set-locale",NO_MORE_THAN,1)) == -1)
{
returnValue->type = SYMBOL;
returnValue->value = EnvFalseSymbol(theEnv);
return;
}
/*=================================*/
/* If there are no arguments, just */
/* return the current locale. */
/*=================================*/
if (numArgs == 0)
{
returnValue->type = STRING;
returnValue->value = IOFunctionData(theEnv)->locale;
return;
}
/*=================*/
/* Get the locale. */
/*=================*/
if (EnvArgTypeCheck(theEnv,"set-locale",1,STRING,&theResult) == FALSE)
{
returnValue->type = SYMBOL;
returnValue->value = EnvFalseSymbol(theEnv);
return;
}
/*=====================================*/
/* Return the old value of the locale. */
/*=====================================*/
returnValue->type = STRING;
returnValue->value = IOFunctionData(theEnv)->locale;
/*======================================================*/
/* Change the value of the locale to the one specified. */
/*======================================================*/
DecrementSymbolCount(theEnv,(struct symbolHashNode *) IOFunctionData(theEnv)->locale);
IOFunctionData(theEnv)->locale = DOToPointer(theResult);
IncrementSymbolCount(IOFunctionData(theEnv)->locale);
}
/******************************************/
/* ReadNumberFunction: H/L access routine */
/* for the read-number function. */
/******************************************/
globle void ReadNumberFunction(
void *theEnv,
DATA_OBJECT_PTR returnValue)
{
struct token theToken;
int numberOfArguments;
char *logicalName = NULL;
/*===============================================*/
/* Check for an appropriate number of arguments. */
/*===============================================*/
if ((numberOfArguments = EnvArgCountCheck(theEnv,"read",NO_MORE_THAN,1)) == -1)
{
returnValue->type = STRING;
returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
return;
}
/*======================================================*/
/* Determine the logical name from which input is read. */
/*======================================================*/
if (numberOfArguments == 0)
{ logicalName = "stdin"; }
else if (numberOfArguments == 1)
{
logicalName = GetLogicalName(theEnv,1,"stdin");
if (logicalName == NULL)
{
IllegalLogicalNameMessage(theEnv,"read");
SetHaltExecution(theEnv,TRUE);
SetEvaluationError(theEnv,TRUE);
returnValue->type = STRING;
returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
return;
}
}
/*============================================*/
/* Check to see that the logical name exists. */
/*============================================*/
if (QueryRouters(theEnv,logicalName) == FALSE)
{
UnrecognizedRouterMessage(theEnv,logicalName);
SetHaltExecution(theEnv,TRUE);
SetEvaluationError(theEnv,TRUE);
returnValue->type = STRING;
returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
return;
}
/*=======================================*/
/* Collect input into string if the read */
/* source is stdin, else just get token. */
/*=======================================*/
if (strcmp(logicalName,"stdin") == 0)
{ ReadNumber(theEnv,logicalName,&theToken,TRUE); }
else
{ ReadNumber(theEnv,logicalName,&theToken,FALSE); }
RouterData(theEnv)->CommandBufferInputCount = -1;
/*====================================================*/
/* Copy the token to the return value data structure. */
/*====================================================*/
returnValue->type = theToken.type;
if ((theToken.type == FLOAT) || (theToken.type == STRING) ||
#if OBJECT_SYSTEM
(theToken.type == INSTANCE_NAME) ||
#endif
(theToken.type == SYMBOL) || (theToken.type == INTEGER))
{ returnValue->value = theToken.value; }
else if (theToken.type == STOP)
{
returnValue->type = SYMBOL;
returnValue->value = (void *) EnvAddSymbol(theEnv,"EOF");
}
else if (theToken.type == UNKNOWN_VALUE)
{
returnValue->type = STRING;
returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
}
else
{
returnValue->type = STRING;
returnValue->value = (void *) EnvAddSymbol(theEnv,theToken.printForm);
}
return;
}
/********************************************/
/* ReadNumber: Special routine used by the */
/* read-number function to read a number. */
/********************************************/
static void ReadNumber(
void *theEnv,
char *logicalName,
struct token *theToken,
int isStdin)
{
char *inputString;
char *charPtr = NULL;
unsigned inputStringSize;
int inchar;
long theLong;
double theDouble;
void *oldLocale;
theToken->type = STOP;
/*===========================================*/
/* Initialize the variables used for storing */
/* the characters retrieved from stdin. */
/*===========================================*/
inputString = NULL;
RouterData(theEnv)->CommandBufferInputCount = 0;
inputStringSize = 0;
inchar = EnvGetcRouter(theEnv,logicalName);
/*====================================*/
/* Skip whitespace before any number. */
/*====================================*/
while (isspace(inchar) && (inchar != EOF) &&
(! GetHaltExecution(theEnv)))
{ inchar = EnvGetcRouter(theEnv,logicalName); }
/*=============================================================*/
/* Continue reading characters until whitespace is found again */
/* (for anything other than stdin) or a CR/LF (for stdin). */
/*=============================================================*/
while ((((! isStdin) && (! isspace(inchar))) ||
(isStdin && (inchar != '\n') && (inchar != '\r'))) &&
(inchar != EOF) &&
(! GetHaltExecution(theEnv)))
{
inputString = ExpandStringWithChar(theEnv,inchar,inputString,&RouterData(theEnv)->CommandBufferInputCount,
&inputStringSize,inputStringSize + 80);
inchar = EnvGetcRouter(theEnv,logicalName);
}
/*===========================================*/
/* Pressing control-c (or comparable action) */
/* aborts the read-number function. */
/*===========================================*/
if (GetHaltExecution(theEnv))
{
theToken->type = STRING;
theToken->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
return;
}
/*====================================================*/
/* Return the EOF symbol if the end of file for stdin */
/* has been encountered. This typically won't occur, */
/* but is possible (for example by pressing control-d */
/* in the UNIX operating system). */
/*====================================================*/
if (inchar == EOF)
{
theToken->type = SYMBOL;
theToken->value = (void *) EnvAddSymbol(theEnv,"EOF");
if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
return;
}
/*==================================================*/
/* Open a string input source using the characters */
/* retrieved from stdin and extract the first token */
/* contained in the string. */
/*==================================================*/
/*=======================================*/
/* Change the locale so that numbers are */
/* converted using the localized format. */
/*=======================================*/
oldLocale = EnvAddSymbol(theEnv,setlocale(LC_NUMERIC,NULL));
setlocale(LC_NUMERIC,ValueToString(IOFunctionData(theEnv)->locale));
/*========================================*/
/* Try to parse the number as a long. The */
/* terminating character must either be */
/* white space or the string terminator. */
/*========================================*/
theLong = strtol(inputString,&charPtr,10);
if ((charPtr != inputString) &&
(isspace(*charPtr) || (*charPtr == '\0')))
{
theToken->type = INTEGER;
theToken->value = (void *) EnvAddLong(theEnv,theLong);
if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
setlocale(LC_NUMERIC,ValueToString(oldLocale));
return;
}
/*==========================================*/
/* Try to parse the number as a double. The */
/* terminating character must either be */
/* white space or the string terminator. */
/*==========================================*/
theDouble = strtod(inputString,&charPtr);
if ((charPtr != inputString) &&
(isspace(*charPtr) || (*charPtr == '\0')))
{
theToken->type = FLOAT;
theToken->value = (void *) EnvAddDouble(theEnv,theDouble);
if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
setlocale(LC_NUMERIC,ValueToString(oldLocale));
return;
}
/*============================================*/
/* Restore the "C" locale so that any parsing */
/* of numbers uses the C format. */
/*============================================*/
setlocale(LC_NUMERIC,ValueToString(oldLocale));
/*=========================================*/
/* Return "*** READ ERROR ***" to indicate */
/* a number was not successfully parsed. */
/*=========================================*/
theToken->type = STRING;
theToken->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -