Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/****************************Module*Header***********************************\
* Module Name: INPUT.C * * Module Descripton: Decimal floating point input * * Warnings: * * Created: * * Author: \****************************************************************************/
#include "scicalc.h"
#include "unifunc.h"
#include "input.h"
extern BOOL gbRecord; extern TCHAR szDec[5]; // The decimal point we use
extern INT gcIntDigits;
TCHAR const szZeroInit[] = TEXT("0");
#define CH_BASE_10_EXP TEXT('e')
#define CH_BASE_X_EXP TEXT('^')
/****************************************************************************/ void CIO_vClearNSec( PCALCNUMSEC pcns ) { pcns->fEmpty = TRUE; pcns->fNeg = FALSE; lstrcpy( pcns->szVal, szZeroInit ); pcns->cchVal = lstrlen(pcns->szVal); }
void CIO_vClear(PCALCINPUTOBJ pcio) { CIO_vClearNSec( &(pcio->cnsNum) ); CIO_vClearNSec( &(pcio->cnsExp) ); pcio->fExp = FALSE; pcio->iDecPt = -1; }
/****************************************************************************/
void CIO_vConvertToNumObj(PHNUMOBJ phnoNum, PCALCINPUTOBJ pcio) { HNUMOBJ hnoValue; LPTSTR pszExp = NULL;
// ZTerm the strings
pcio->cnsNum.szVal[pcio->cnsNum.cchVal] = TEXT('\0');
if (pcio->fExp ) { pszExp = pcio->cnsExp.szVal; pszExp[pcio->cnsExp.cchVal] = TEXT('\0'); }
hnoValue = NumObjMakeNumber( pcio->cnsNum.fNeg, pcio->cnsNum.szVal, pcio->cnsExp.fNeg, pszExp ); NumObjAssign( phnoNum, hnoValue );
return; }
/****************************************************************************/
void CIO_vConvertToString(LPTSTR *ppszOut, PCALCINPUTOBJ pcio, int nRadix) { //In theory both the base and exponent could be C_NUM_MAX_DIGITS long.
TCHAR szTemp[C_NUM_MAX_DIGITS*2+4]; LPTSTR psz; int i;
// ZTerm the strings
pcio->cnsNum.szVal[pcio->cnsNum.cchVal] = TEXT('\0');
if ( pcio->fExp ) pcio->cnsExp.szVal[pcio->cnsExp.cchVal] = TEXT('\0');
i = 0; if (pcio->cnsNum.fNeg) szTemp[i++] = TEXT('-');
lstrcpy( &szTemp[i], pcio->cnsNum.szVal ); i += pcio->cnsNum.cchVal;
// Add a '.' if it is not already there
if (pcio->iDecPt == -1 ) szTemp[i++] = szDec[0];
if (pcio->fExp) { szTemp[i++] = nRadix == 10 ? CH_BASE_10_EXP : CH_BASE_X_EXP;
if (pcio->cnsExp.fNeg) szTemp[i++] = TEXT('-'); else szTemp[i++] = TEXT('+');
lstrcpy( &szTemp[i], pcio->cnsExp.szVal ); i += pcio->cnsExp.cchVal; }
psz = (LPTSTR)NumObjAllocMem( (lstrlen( szTemp )+1) * sizeof(TCHAR) ); if (psz) { if (*ppszOut != NULL) { NumObjFreeMem( *ppszOut ); } *ppszOut = psz; }
// Don't show '.' if in int math
if (F_INTMATH() && szTemp[i-1] == szDec[0]) i--;
szTemp[i] = TEXT('\0');
lstrcpy( *ppszOut, szTemp );
return; }
/****************************************************************************/
BOOL CIO_bAddDigit(PCALCINPUTOBJ pcio, int iValue) { PCALCNUMSEC pcns; TCHAR chDigit; int cchMaxDigits;
// convert from an integer into a character
chDigit = (iValue < 10)?(TEXT('0')+iValue):(TEXT('A')+iValue-10);
if (pcio->fExp) { pcns = &(pcio->cnsExp); cchMaxDigits = C_EXP_MAX_DIGITS; } else { pcns = &(pcio->cnsNum); ASSERT( gcIntDigits <= C_NUM_MAX_DIGITS ); cchMaxDigits = gcIntDigits; }
// Ignore leading zeros
if ( pcns->fEmpty && (iValue == 0) ) { return TRUE; }
if ( pcns->cchVal < cchMaxDigits ) { if (pcns->fEmpty) { pcns->cchVal = 0; // Clobber the default zero
pcns->fEmpty = FALSE; }
pcns->szVal[pcns->cchVal++] = chDigit; return TRUE; }
// if we are in base 8 entering a mantica and we're on the last digit then
// there are special cases where we can actually add one more digit.
if ( nRadix == 8 && pcns->cchVal == cchMaxDigits && !pcio->fExp ) { BOOL bAllowExtraDigit = FALSE;
switch ( dwWordBitWidth % 3 ) { case 1: // in 16bit word size, if the first digit is a 1 we can enter 6 digits
if ( pcns->szVal[0] == TEXT('1') ) bAllowExtraDigit = TRUE; break;
case 2: // in 8 or 32bit word size we get an extra digit if the first digit is 3 or less
if ( pcns->szVal[0] <= TEXT('3') ) bAllowExtraDigit = TRUE; break; }
if ( bAllowExtraDigit ) { pcns->szVal[pcns->cchVal++] = chDigit; return TRUE; } }
return FALSE; }
/****************************************************************************/
void CIO_vToggleSign(PCALCINPUTOBJ pcio) {
// Zero is always positive
if (pcio->cnsNum.fEmpty) { pcio->cnsNum.fNeg = FALSE; pcio->cnsExp.fNeg = FALSE; } else if (pcio->fExp) { pcio->cnsExp.fNeg = !pcio->cnsExp.fNeg; } else { pcio->cnsNum.fNeg = !pcio->cnsNum.fNeg; } }
/****************************************************************************/
BOOL CIO_bAddDecimalPt(PCALCINPUTOBJ pcio) { ASSERT(gbRecord == TRUE);
if (pcio->iDecPt != -1) // Already have a decimal pt
return FALSE;
if (pcio->fExp) // Entering exponent
return FALSE;
pcio->cnsNum.fEmpty = FALSE; // Zeros become significant
pcio->iDecPt = pcio->cnsNum.cchVal++; pcio->cnsNum.szVal[pcio->iDecPt] = szDec[0];
return TRUE; }
/****************************************************************************/
BOOL CIO_bExponent(PCALCINPUTOBJ pcio) { ASSERT(gbRecord == TRUE);
// For compatability, add a trailing dec pnt to base num if it doesn't have one
CIO_bAddDecimalPt( pcio );
if (pcio->fExp) // Already entering exponent
return FALSE;
pcio->fExp = TRUE; // Entering exponent
return TRUE; }
/****************************************************************************/
BOOL CIO_bBackspace(PCALCINPUTOBJ pcio) { ASSERT(gbRecord == TRUE);
if (pcio->fExp) { if ( !(pcio->cnsExp.fEmpty) ) { pcio->cnsExp.cchVal--;
if (pcio->cnsExp.cchVal == 0) { CIO_vClearNSec( &(pcio->cnsExp) ); } } else { pcio->fExp = FALSE; } } else { if ( !(pcio->cnsNum.fEmpty) ) { pcio->cnsNum.cchVal--; }
if ( pcio->cnsNum.cchVal <= pcio->iDecPt ) //Backed up over decimal point
pcio->iDecPt = -1;
if ((pcio->cnsNum.cchVal == 0) || ((pcio->cnsNum.cchVal == 1) && (pcio->cnsNum.szVal[0] == TEXT('0')))) CIO_vClearNSec( &(pcio->cnsNum) ); }
return TRUE; }
/****************************************************************************/
void CIO_vUpdateDecimalSymbol(PCALCINPUTOBJ pcio, TCHAR chLastDP) { int iDP;
ASSERT(pcio);
iDP = pcio->iDecPt; // Find the DP index
if (iDP == -1) return;
ASSERT(pcio->cnsNum.szVal[iDP] == chLastDP);
pcio->cnsNum.szVal[iDP] = szDec[0]; // Change to new decimal pt
}
/****************************************************************************/
|