File:  [OS/2 SDKs] / pmsdk / samples / calc / calcmath.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:28:19 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: pmsdk-1989, HEAD
Microsoft OS/2 SDK PM 02-24-1989

/****************************** Module Header *********************************/
/*									      */
/* Module Name:  calcmath.c - Calc application				      */
/*									      */
/* OS/2 Presentation Manager version of Calc, ported from Windows version     */
/*									      */
/* Created by Microsoft Corporation, 1987				      */
/*									      */
/******************************************************************************/

#define INCL_WINCLIPBOARD
#include <os2.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

extern BOOL fValueInMemory;
extern CHAR chLastKey;
extern CHAR szreg1[20], szreg2[20], szmem[20];
extern HWND hwndCalc;
extern CHAR szregx[];
extern HAB  hab;
BOOL   fReadNumber;
CHAR   PendingOperation;
BOOL   fFirstOperand, fError;
CHAR   szresult[20];
SEL    sel;

#define tolower(x)   (((x) >= 'A') && ((x)<='Z')) ? (x) - 'A' + 'a' : (x)
#define MAXINT	(double)999999999
#define MININT (double)-999999999
#define ABS(x)		(((x) >= (double)0) ? (x) : (-(x)))


/******************************************************************************/
extern VOID UpdateDisplay( VOID);
extern BOOL InterpretChar( CHAR);

VOID AppendNumber( BYTE);
VOID BinaryOperator( CHAR);
VOID Clear( VOID);
VOID DataXCopy( VOID);
VOID DataXPaste( VOID);
VOID Equilibrate( VOID);
VOID Evaluate( BYTE);
VOID FarStrcpy( PSZ, PSZ);
NPCH ftoa( double);
VOID InitCalc( VOID);
VOID MClear( VOID);
VOID MMinus( VOID);
VOID MPlus( VOID);
VOID Negate( VOID);
VOID Number( CHAR);
VOID Percent( VOID);
VOID reverse( NPCH);
VOID Simplify( VOID);
VOID SquareRoot( VOID);


/******************************************************************************/
VOID FarStrcpy( pszDest, pszSrc)
PSZ  pszDest, pszSrc;
{
    while( *pszDest++ = *pszSrc++);
}

/******************************************************************************/
VOID
reverse( s)

NPCH s;
{
    CHAR ch;
    register INT iHead, iTail;

    for (iHead = 0, iTail = strlen(s) - 1; iHead<iTail; iHead++, iTail-- ) {
	ch = s[iHead];
	s[iHead] = s[iTail];
	s[iTail] = ch;
    }
}

/******************************************************************************/
NPCH
ftoa( dblNum)

double dblNum;
{
    sprintf( szresult, "%.8f", dblNum );
    return (szresult);
}


/******************************************************************************/
VOID
Negate()
{
    CHAR sztemp[ 20 ];

    if (szreg1[0] ==  '-')
	strcpy(szreg1, (&szreg1[1]));		     /* get rid of minus sign */
    else if (szreg1[0] != '0' || (strlen(szreg1) > 2)) { /* can't negate zero */
	     sztemp[0] = '-';
	     strcpy(&sztemp[1], szreg1);
	     strcpy(szreg1, sztemp);
	 }
}

/******************************************************************************/
VOID
Number( ch)

CHAR ch;
{
    register INT iLen, iSize;

    iSize = 9;
    if (szreg1[0] == '-') iSize++;
    if (strchr(szreg1, '.')) iSize++;
    iLen  = strlen(szreg1 );
    if (iLen == iSize) return;
    if (iLen == 1 && szreg1[0] == '0') iLen--;
    szreg1[ iLen ] = ch;
    szreg1[min(iLen + 1, 11)] = 0;
}

/******************************************************************************/
VOID
AppendNumber ( b)

BYTE b;
{
    if (b == '.') {		    /*	if no decimal, add one at end */
        if (!strchr(szreg1, '.'))   
            strcat(szreg1, ".");
    }
    else if ( b == 0xb1 )
	     Negate();
	 else
	     Number(b);
}

/******************************************************************************/
VOID
Equilibrate()
{
    double dblResult;
    double dblX1, dblX2;

    if (chLastKey == '=') return;
    dblResult = (double)atof(szreg1);
    dblX1 = (double)atof(szreg1);
    dblX2 = (double)atof(szreg2);

    switch (PendingOperation) {
        case '+':
	    if (dblX2>(double)0) {	    /* check for overflow */
		if (dblX1>(double)0) {
		    if (dblX1 > (MAXINT - dblX2))
                        fError = TRUE;
		}
	    }
	    else if (dblX2 < (double)0) {
		     if (dblX1 < (double)0) {
			 if ( dblX1 < (MININT - dblX2))
			     fError = TRUE;
		     }
		 }
	    if (!fError)
		dblResult = dblX2 + dblX1;
            break;
        case '-':
	    if (dblX2 < (double)0) {
		if (dblX1 > (double)0) {
		    if (dblX1 > (dblX2 - MININT))
                        fError = TRUE;
		}
	    }
	    else if (dblX2 > (double)0) {
		    if (dblX1 < (double)0) {
			if (dblX1 < (dblX2 - MAXINT))
                            fError = TRUE;
		    }
		 }
            if (!fError) 
		dblResult = dblX2 - dblX1;
            break;
        case '/':
	    if (dblX1 == (double)0.0)
                fError = TRUE;
	    else if (dblX2 > (double)0) {
		     if (dblX1 > (double)0) {
			 if (dblX1 < (dblX2 / MAXINT))
			     fError = TRUE;
		     }
		     else {  /* dblX1 < 0 here */
			if (dblX1 > (dblX2 / MININT))
			     fError = TRUE;
		     }
		 }
		 else {  /* dblX2 < 0 here */
		     if (dblX1 < (double)0) {
			 if (dblX1 > (dblX2 / MAXINT))
			     fError = TRUE;
		     }
		     else { /* dblX1 > 0 here */
			 if (dblX1 < (dblX2 / MININT))
			     fError = TRUE;
		     }
		 }
	    if (!fError)
		dblResult = dblX2 / dblX1;
            break;
        case '*':
	    if (dblX1 == (double)0) return;
	    if (ABS(dblX2) > (double)1) {
		if (ABS(dblX1) > (double)1) {
		    if (ABS(dblX1) > (MAXINT / ABS(dblX2)))
                        fError = TRUE;
                    } 
                }                    
	    if (!fError) dblResult = dblX2 * dblX1;
            break;
        }
    if (!fError) {
	strcpy(szreg1, ftoa((double)dblResult));
        strcpy( szreg2, szreg1 );
        }
    Simplify();
}

/******************************************************************************/
VOID
SquareRoot()
{
    double dblResult;

    dblResult = (double)atof(szreg1);
    if (dblResult < 0.0) {
        fError = TRUE;
        return;
    }
    if ((dblResult == 0.0) || ((chLastKey == 'q') && (dblResult == 1.0)))
        return;
    if ((dblResult < (double) 1.00000002) && (dblResult > (double) 1.0))
	dblResult = (double)1.0;
    else
	dblResult = sqrt(dblResult);
    strcpy( szreg1, ftoa((double)dblResult));
    if (atof( szreg1 ) == 0.0)
        strcpy(szreg1, "0.");
    Simplify();
}

/******************************************************************************/
VOID
BinaryOperator( ch)

CHAR ch;
{
    if (fFirstOperand) {
        fFirstOperand = FALSE;
        strcpy(szreg2, szreg1);
    }
    else {
        Equilibrate();
    }
    PendingOperation = ch;
}

/******************************************************************************/
VOID
Clear()
{
    fReadNumber = FALSE;
    fFirstOperand = TRUE;
    strcpy(szreg1, "0.");
    if (fError || chLastKey == 'c'){
        strcpy(szreg2, "0.");
        PendingOperation = NULL;
    }
    fError = FALSE;
}

/******************************************************************************/
/* trash out trailing zeros, if a '.' is in the number			      */
/* and leading zeros in all cases.					      */
/******************************************************************************/
VOID
Simplify()
{
    register INT iLen, iCount;
    CHAR	 achLocal[20];

    iCount = 0;
    strcpy(achLocal, szreg1);
    if (atof(achLocal) != 0.0) {
	while (achLocal[iCount++] == '0');
	strcpy(szreg1, &achLocal[iCount-1] );
    }
    if (strchr(szreg1, '.')) {
	iLen = strlen(szreg1);
	while (szreg1[--iLen] == '0');
	szreg1[min( iLen + 1, 11)] = 0; /* null terminate */
    }
}


/******************************************************************************/
VOID
DataXPaste()
{
    PSZ 	  psz;
    ULONG	  ulText;
    register CHAR ch;

    if (WinOpenClipbrd( hab))
    {
	ulText = WinQueryClipbrdData( hab, CF_TEXT);
	if (ulText)
	{
	    psz = MAKEP( (SEL)ulText, 0);
	    while (*psz)
            {
		ch = tolower(*psz);
		if (ch == 'm')
                {
		    psz++;
		    switch (tolower(*psz))
                    {
			case '-':
			    ch = '\271';
			    break;
			case '+':
			    ch = '\272';
			    break;
			case 'r':
			    ch = '\273';
			    break;
			case 'c':
			    ch = '\274';
			    break;
			default:
			    ch = ' ';
			    break;
                    }
                }
		psz++;
		InterpretChar(ch);
                UpdateDisplay();
            }
        }
    }
    WinCloseClipbrd( hab);
    InterpretChar('=');
    UpdateDisplay();
}


/******************************************************************************/
VOID
DataXCopy()
{
    PSZ  pszText;

    if (WinOpenClipbrd( hab))
    {
	WinEmptyClipbrd( hab);
	DosAllocSeg( 20, (SEL FAR *)&sel, SEG_GIVEABLE);
        if (sel == NULL) return;
	pszText = MAKEP(sel, 0);
	FarStrcpy( pszText, (PSZ)szreg1);
	WinSetClipbrdData( hab, (ULONG)sel, CF_TEXT, CFI_SELECTOR);
	WinCloseClipbrd( hab);
    }
}


/******************************************************************************/
VOID
MPlus()
{
    double dblX1, dblX2, dblResult;

    dblX2 = atof(szmem);
    dblX1 = atof(szreg1);

    if (dblX2>(double)0) {	    /* check for overflow */
	if (dblX1>(double)0) {
	    if (dblX1 > (MAXINT - dblX2))
                fError = TRUE;
	}
    }
    else if (dblX2 < (double)0) {
	     if (dblX1 < (double)0) {
		 if ( dblX1 < (MININT - dblX2))
		     fError = TRUE;
	     }
	 }
    if (!fError) {
	dblResult = dblX2 + dblX1;
	strcpy( szmem, ftoa((double)dblResult));
    }
    if (dblResult == (double)0.0)
         fValueInMemory = FALSE; 
    else fValueInMemory = TRUE;
}

/******************************************************************************/
VOID
MClear()
{
     strcpy(szmem, "0.");   
     fValueInMemory = FALSE; 
}


/******************************************************************************/
VOID
MMinus()
{
    double dblX1, dblX2, dblResult;

    dblX2 = atof(szmem);
    dblX1 = atof(szreg1);
    if (dblX2 < (double)0) {
	if (dblX1 > (double)0) {
	    if (dblX1 > (dblX2 - MININT))
                fError = TRUE;
	}
    }
    else if (dblX2 > (double)0) {
	    if (dblX1 < (double)0) {
		if (dblX1 < (dblX2 - MAXINT))
                    fError = TRUE;
	    }
	 }
    if (!fError) {
	dblResult = dblX2 - dblX1;
	strcpy( szmem, ftoa((double)dblResult));
    }
    if (dblResult == (double)0.0)
         fValueInMemory = FALSE; 
    else fValueInMemory = TRUE;
}

/******************************************************************************/
VOID
Evaluate( bCommand)

BYTE bCommand;
{
    switch( bCommand ) {
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9': case '.': case 0xb1:
        case 'n': /* n = 'negate'  from keyboard */
	    if ( fReadNumber )
		AppendNumber( bCommand );
            else {
                      /* if starting a new number */
		if (bCommand != 0xb1)
                    strcpy(szreg1, "0");
		AppendNumber( bCommand );
	    }
	    if (bCommand != 0xb1)
                fReadNumber = TRUE;
            break;
        case '+': case '-': case '/': case '*': case 'p':
	    BinaryOperator(bCommand);
            fReadNumber = FALSE;
            break;
        case '=':
            fReadNumber = FALSE;
            Equilibrate();
            PendingOperation = NULL;
            break;
        case 'q':
            SquareRoot();
            fReadNumber = FALSE;
            break;
        case 0xBB:   /* MR */
            strcpy(szreg1, szmem);
            fReadNumber = FALSE;
            Simplify();
            break;
        case 0xBA: /* M+ */
            MPlus();
            fReadNumber = FALSE;
            Simplify();
            break;
        case 0xB9: /* M- */
            MMinus();
            fReadNumber = FALSE;
            Simplify();
            break;
        case 0xBC:
            MClear(); /* MC */
            break;
        case '%':
            Percent();
            fReadNumber = FALSE;
            break;
        case 'c':
            Clear();
            break;
        }
}

/******************************************************************************/
VOID
Percent()
{
    double dblX1, dblX2, dblResult;

    dblX1 = atof(szreg1) / 100.0;
    dblX2 = atof(szreg2);
    if (ABS(dblX2) > (double)1) {
	if (ABS(dblX1) > (double)1) {
	    if (dblX1 > (MAXINT / dblX2))
                fError = TRUE;
	}
    }
    if (!fError) {
	dblResult = dblX2 * dblX1;
	strcpy( szreg1, ftoa((double)dblResult));
    }
    Simplify();
}

/******************************************************************************/
VOID
InitCalc()
{
    fReadNumber = FALSE;
    fError = FALSE;
    fFirstOperand = TRUE;
    PendingOperation = 0;
    strcpy(szreg1, "0.");
    strcpy(szmem,  "0.");
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.