📄 iofun.c
字号:
if (buffer == NULL) { returnValue->value = (void *) EnvAddSymbol(theEnv,"EOF"); returnValue->type = SYMBOL; return; } 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, size_t *currentPosition, size_t *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; size_t inputStringSize; int inchar; long 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. */ /*========================================*/#if IBM_MSC theLong = _strtoi64(inputString,&charPtr,10);#else theLong = strtoll(inputString,&charPtr,10);#endif 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 + -