Annotation of pmsdk/samples/calc/calcmath.c, revision 1.1.1.2

1.1.1.2 ! root        1: /****************************** Module Header *********************************/
        !             2: /*                                                                           */
        !             3: /* Module Name:  calcmath.c - Calc application                               */
        !             4: /*                                                                           */
        !             5: /* OS/2 Presentation Manager version of Calc, ported from Windows version     */
        !             6: /*                                                                           */
        !             7: /* Created by Microsoft Corporation, 1987                                    */
        !             8: /*                                                                           */
        !             9: /******************************************************************************/
1.1       root       10: 
1.1.1.2 ! root       11: #define INCL_WINCLIPBOARD
1.1       root       12: #include <os2.h>
                     13: #include <string.h>
                     14: #include <stdio.h>
                     15: #include <stdlib.h>
                     16: #include <math.h>
                     17: 
                     18: extern BOOL fValueInMemory;
1.1.1.2 ! root       19: extern CHAR chLastKey;
        !            20: extern CHAR szreg1[20], szreg2[20], szmem[20];
1.1       root       21: extern HWND hwndCalc;
1.1.1.2 ! root       22: extern CHAR szregx[];
        !            23: extern HAB  hab;
        !            24: BOOL   fReadNumber;
        !            25: CHAR   PendingOperation;
1.1       root       26: BOOL   fFirstOperand, fError;
1.1.1.2 ! root       27: CHAR   szresult[20];
        !            28: SEL    sel;
1.1       root       29: 
                     30: #define tolower(x)   (((x) >= 'A') && ((x)<='Z')) ? (x) - 'A' + 'a' : (x)
                     31: #define MAXINT (double)999999999
                     32: #define MININT (double)-999999999
                     33: #define ABS(x)         (((x) >= (double)0) ? (x) : (-(x)))
                     34: 
1.1.1.2 ! root       35: 
        !            36: /******************************************************************************/
1.1       root       37: extern VOID UpdateDisplay( VOID);
                     38: extern BOOL InterpretChar( CHAR);
                     39: 
                     40: VOID AppendNumber( BYTE);
                     41: VOID BinaryOperator( CHAR);
                     42: VOID Clear( VOID);
                     43: VOID DataXCopy( VOID);
                     44: VOID DataXPaste( VOID);
                     45: VOID Equilibrate( VOID);
                     46: VOID Evaluate( BYTE);
1.1.1.2 ! root       47: VOID FarStrcpy( PSZ, PSZ);
1.1       root       48: NPCH ftoa( double);
                     49: VOID InitCalc( VOID);
                     50: VOID MClear( VOID);
                     51: VOID MMinus( VOID);
                     52: VOID MPlus( VOID);
                     53: VOID Negate( VOID);
                     54: VOID Number( CHAR);
                     55: VOID Percent( VOID);
                     56: VOID reverse( NPCH);
                     57: VOID Simplify( VOID);
                     58: VOID SquareRoot( VOID);
                     59: 
                     60: 
1.1.1.2 ! root       61: /******************************************************************************/
        !            62: VOID FarStrcpy( pszDest, pszSrc)
        !            63: PSZ  pszDest, pszSrc;
        !            64: {
        !            65:     while( *pszDest++ = *pszSrc++);
        !            66: }
        !            67: 
        !            68: /******************************************************************************/
        !            69: VOID
        !            70: reverse( s)
        !            71: 
1.1       root       72: NPCH s;
                     73: {
1.1.1.2 ! root       74:     CHAR ch;
        !            75:     register INT iHead, iTail;
1.1       root       76: 
1.1.1.2 ! root       77:     for (iHead = 0, iTail = strlen(s) - 1; iHead<iTail; iHead++, iTail-- ) {
        !            78:        ch = s[iHead];
        !            79:        s[iHead] = s[iTail];
        !            80:        s[iTail] = ch;
1.1       root       81:     }
                     82: }
                     83: 
1.1.1.2 ! root       84: /******************************************************************************/
        !            85: NPCH
        !            86: ftoa( dblNum)
        !            87: 
        !            88: double dblNum;
1.1       root       89: {
1.1.1.2 ! root       90:     sprintf( szresult, "%.8f", dblNum );
1.1       root       91:     return (szresult);
                     92: }
                     93: 
                     94: 
1.1.1.2 ! root       95: /******************************************************************************/
        !            96: VOID
        !            97: Negate()
1.1       root       98: {
1.1.1.2 ! root       99:     CHAR sztemp[ 20 ];
1.1       root      100: 
1.1.1.2 ! root      101:     if (szreg1[0] ==  '-')
        !           102:        strcpy(szreg1, (&szreg1[1]));                /* get rid of minus sign */
        !           103:     else if (szreg1[0] != '0' || (strlen(szreg1) > 2)) { /* can't negate zero */
        !           104:             sztemp[0] = '-';
        !           105:             strcpy(&sztemp[1], szreg1);
        !           106:             strcpy(szreg1, sztemp);
        !           107:         }
1.1       root      108: }
                    109: 
1.1.1.2 ! root      110: /******************************************************************************/
        !           111: VOID
        !           112: Number( ch)
        !           113: 
        !           114: CHAR ch;
1.1       root      115: {
1.1.1.2 ! root      116:     register INT iLen, iSize;
1.1       root      117: 
1.1.1.2 ! root      118:     iSize = 9;
        !           119:     if (szreg1[0] == '-') iSize++;
        !           120:     if (strchr(szreg1, '.')) iSize++;
        !           121:     iLen  = strlen(szreg1 );
        !           122:     if (iLen == iSize) return;
        !           123:     if (iLen == 1 && szreg1[0] == '0') iLen--;
        !           124:     szreg1[ iLen ] = ch;
        !           125:     szreg1[min(iLen + 1, 11)] = 0;
1.1       root      126: }
                    127: 
1.1.1.2 ! root      128: /******************************************************************************/
        !           129: VOID
        !           130: AppendNumber ( b)
        !           131: 
        !           132: BYTE b;
1.1       root      133: {
1.1.1.2 ! root      134:     if (b == '.') {                /*  if no decimal, add one at end */
1.1       root      135:         if (!strchr(szreg1, '.'))   
                    136:             strcat(szreg1, ".");
1.1.1.2 ! root      137:     }
        !           138:     else if ( b == 0xb1 )
        !           139:             Negate();
        !           140:         else
        !           141:             Number(b);
        !           142: }
        !           143: 
        !           144: /******************************************************************************/
        !           145: VOID
        !           146: Equilibrate()
        !           147: {
        !           148:     double dblResult;
        !           149:     double dblX1, dblX2;
        !           150: 
        !           151:     if (chLastKey == '=') return;
        !           152:     dblResult = (double)atof(szreg1);
        !           153:     dblX1 = (double)atof(szreg1);
        !           154:     dblX2 = (double)atof(szreg2);
1.1       root      155: 
                    156:     switch (PendingOperation) {
                    157:         case '+':
1.1.1.2 ! root      158:            if (dblX2>(double)0) {          /* check for overflow */
        !           159:                if (dblX1>(double)0) {
        !           160:                    if (dblX1 > (MAXINT - dblX2))
1.1       root      161:                         fError = TRUE;
1.1.1.2 ! root      162:                }
        !           163:            }
        !           164:            else if (dblX2 < (double)0) {
        !           165:                     if (dblX1 < (double)0) {
        !           166:                         if ( dblX1 < (MININT - dblX2))
        !           167:                             fError = TRUE;
        !           168:                     }
        !           169:                 }
        !           170:            if (!fError)
        !           171:                dblResult = dblX2 + dblX1;
1.1       root      172:             break;
                    173:         case '-':
1.1.1.2 ! root      174:            if (dblX2 < (double)0) {
        !           175:                if (dblX1 > (double)0) {
        !           176:                    if (dblX1 > (dblX2 - MININT))
1.1       root      177:                         fError = TRUE;
1.1.1.2 ! root      178:                }
        !           179:            }
        !           180:            else if (dblX2 > (double)0) {
        !           181:                    if (dblX1 < (double)0) {
        !           182:                        if (dblX1 < (dblX2 - MAXINT))
1.1       root      183:                             fError = TRUE;
1.1.1.2 ! root      184:                    }
        !           185:                 }
1.1       root      186:             if (!fError) 
1.1.1.2 ! root      187:                dblResult = dblX2 - dblX1;
1.1       root      188:             break;
                    189:         case '/':
1.1.1.2 ! root      190:            if (dblX1 == (double)0.0)
1.1       root      191:                 fError = TRUE;
1.1.1.2 ! root      192:            else if (dblX2 > (double)0) {
        !           193:                     if (dblX1 > (double)0) {
        !           194:                         if (dblX1 < (dblX2 / MAXINT))
        !           195:                             fError = TRUE;
        !           196:                     }
        !           197:                     else {  /* dblX1 < 0 here */
        !           198:                        if (dblX1 > (dblX2 / MININT))
        !           199:                             fError = TRUE;
        !           200:                     }
        !           201:                 }
        !           202:                 else {  /* dblX2 < 0 here */
        !           203:                     if (dblX1 < (double)0) {
        !           204:                         if (dblX1 > (dblX2 / MAXINT))
        !           205:                             fError = TRUE;
        !           206:                     }
        !           207:                     else { /* dblX1 > 0 here */
        !           208:                         if (dblX1 < (dblX2 / MININT))
        !           209:                             fError = TRUE;
        !           210:                     }
        !           211:                 }
        !           212:            if (!fError)
        !           213:                dblResult = dblX2 / dblX1;
1.1       root      214:             break;
                    215:         case '*':
1.1.1.2 ! root      216:            if (dblX1 == (double)0) return;
        !           217:            if (ABS(dblX2) > (double)1) {
        !           218:                if (ABS(dblX1) > (double)1) {
        !           219:                    if (ABS(dblX1) > (MAXINT / ABS(dblX2)))
1.1       root      220:                         fError = TRUE;
                    221:                     } 
                    222:                 }                    
1.1.1.2 ! root      223:            if (!fError) dblResult = dblX2 * dblX1;
1.1       root      224:             break;
                    225:         }
                    226:     if (!fError) {
1.1.1.2 ! root      227:        strcpy(szreg1, ftoa((double)dblResult));
1.1       root      228:         strcpy( szreg2, szreg1 );
                    229:         }
                    230:     Simplify();
                    231: }
                    232: 
1.1.1.2 ! root      233: /******************************************************************************/
        !           234: VOID
        !           235: SquareRoot()
1.1       root      236: {
1.1.1.2 ! root      237:     double dblResult;
1.1       root      238: 
1.1.1.2 ! root      239:     dblResult = (double)atof(szreg1);
        !           240:     if (dblResult < 0.0) {
1.1       root      241:         fError = TRUE;
                    242:         return;
1.1.1.2 ! root      243:     }
        !           244:     if ((dblResult == 0.0) || ((chLastKey == 'q') && (dblResult == 1.0)))
1.1       root      245:         return;
1.1.1.2 ! root      246:     if ((dblResult < (double) 1.00000002) && (dblResult > (double) 1.0))
        !           247:        dblResult = (double)1.0;
1.1       root      248:     else
1.1.1.2 ! root      249:        dblResult = sqrt(dblResult);
        !           250:     strcpy( szreg1, ftoa((double)dblResult));
1.1       root      251:     if (atof( szreg1 ) == 0.0)
                    252:         strcpy(szreg1, "0.");
                    253:     Simplify();
                    254: }
                    255: 
1.1.1.2 ! root      256: /******************************************************************************/
        !           257: VOID
        !           258: BinaryOperator( ch)
        !           259: 
        !           260: CHAR ch;
1.1       root      261: {
                    262:     if (fFirstOperand) {
                    263:         fFirstOperand = FALSE;
                    264:         strcpy(szreg2, szreg1);
1.1.1.2 ! root      265:     }
1.1       root      266:     else {
                    267:         Equilibrate();
1.1.1.2 ! root      268:     }
        !           269:     PendingOperation = ch;
1.1       root      270: }
                    271: 
1.1.1.2 ! root      272: /******************************************************************************/
        !           273: VOID
        !           274: Clear()
1.1       root      275: {
                    276:     fReadNumber = FALSE;
                    277:     fFirstOperand = TRUE;
                    278:     strcpy(szreg1, "0.");
1.1.1.2 ! root      279:     if (fError || chLastKey == 'c'){
1.1       root      280:         strcpy(szreg2, "0.");
                    281:         PendingOperation = NULL;
1.1.1.2 ! root      282:     }
1.1       root      283:     fError = FALSE;
                    284: }
                    285: 
1.1.1.2 ! root      286: /******************************************************************************/
        !           287: /* trash out trailing zeros, if a '.' is in the number                       */
        !           288: /* and leading zeros in all cases.                                           */
        !           289: /******************************************************************************/
        !           290: VOID
        !           291: Simplify()
        !           292: {
        !           293:     register INT iLen, iCount;
        !           294:     CHAR        achLocal[20];
        !           295: 
        !           296:     iCount = 0;
        !           297:     strcpy(achLocal, szreg1);
        !           298:     if (atof(achLocal) != 0.0) {
        !           299:        while (achLocal[iCount++] == '0');
        !           300:        strcpy(szreg1, &achLocal[iCount-1] );
        !           301:     }
1.1       root      302:     if (strchr(szreg1, '.')) {
1.1.1.2 ! root      303:        iLen = strlen(szreg1);
        !           304:        while (szreg1[--iLen] == '0');
        !           305:        szreg1[min( iLen + 1, 11)] = 0; /* null terminate */
        !           306:     }
1.1       root      307: }
                    308: 
                    309: 
1.1.1.2 ! root      310: /******************************************************************************/
        !           311: VOID
        !           312: DataXPaste()
        !           313: {
        !           314:     PSZ          psz;
        !           315:     ULONG        ulText;
        !           316:     register CHAR ch;
1.1       root      317: 
1.1.1.2 ! root      318:     if (WinOpenClipbrd( hab))
1.1       root      319:     {
1.1.1.2 ! root      320:        ulText = WinQueryClipbrdData( hab, CF_TEXT);
        !           321:        if (ulText)
        !           322:        {
        !           323:            psz = MAKEP( (SEL)ulText, 0);
        !           324:            while (*psz)
1.1       root      325:             {
1.1.1.2 ! root      326:                ch = tolower(*psz);
        !           327:                if (ch == 'm')
1.1       root      328:                 {
1.1.1.2 ! root      329:                    psz++;
        !           330:                    switch (tolower(*psz))
1.1       root      331:                     {
1.1.1.2 ! root      332:                        case '-':
        !           333:                            ch = '\271';
        !           334:                            break;
        !           335:                        case '+':
        !           336:                            ch = '\272';
        !           337:                            break;
        !           338:                        case 'r':
        !           339:                            ch = '\273';
        !           340:                            break;
        !           341:                        case 'c':
        !           342:                            ch = '\274';
        !           343:                            break;
        !           344:                        default:
        !           345:                            ch = ' ';
        !           346:                            break;
1.1       root      347:                     }
                    348:                 }
1.1.1.2 ! root      349:                psz++;
        !           350:                InterpretChar(ch);
1.1       root      351:                 UpdateDisplay();
                    352:             }
                    353:         }
                    354:     }
1.1.1.2 ! root      355:     WinCloseClipbrd( hab);
1.1       root      356:     InterpretChar('=');
                    357:     UpdateDisplay();
                    358: }
                    359: 
                    360: 
1.1.1.2 ! root      361: /******************************************************************************/
        !           362: VOID
        !           363: DataXCopy()
1.1       root      364: {
1.1.1.2 ! root      365:     PSZ  pszText;
1.1       root      366: 
1.1.1.2 ! root      367:     if (WinOpenClipbrd( hab))
1.1       root      368:     {
1.1.1.2 ! root      369:        WinEmptyClipbrd( hab);
        !           370:        DosAllocSeg( 20, (SEL FAR *)&sel, SEG_GIVEABLE);
1.1       root      371:         if (sel == NULL) return;
1.1.1.2 ! root      372:        pszText = MAKEP(sel, 0);
        !           373:        FarStrcpy( pszText, (PSZ)szreg1);
        !           374:        WinSetClipbrdData( hab, (ULONG)sel, CF_TEXT, CFI_SELECTOR);
        !           375:        WinCloseClipbrd( hab);
1.1       root      376:     }
                    377: }
                    378: 
                    379: 
1.1.1.2 ! root      380: /******************************************************************************/
        !           381: VOID
        !           382: MPlus()
        !           383: {
        !           384:     double dblX1, dblX2, dblResult;
        !           385: 
        !           386:     dblX2 = atof(szmem);
        !           387:     dblX1 = atof(szreg1);
        !           388: 
        !           389:     if (dblX2>(double)0) {         /* check for overflow */
        !           390:        if (dblX1>(double)0) {
        !           391:            if (dblX1 > (MAXINT - dblX2))
1.1       root      392:                 fError = TRUE;
1.1.1.2 ! root      393:        }
        !           394:     }
        !           395:     else if (dblX2 < (double)0) {
        !           396:             if (dblX1 < (double)0) {
        !           397:                 if ( dblX1 < (MININT - dblX2))
        !           398:                     fError = TRUE;
        !           399:             }
        !           400:         }
1.1       root      401:     if (!fError) {
1.1.1.2 ! root      402:        dblResult = dblX2 + dblX1;
        !           403:        strcpy( szmem, ftoa((double)dblResult));
        !           404:     }
        !           405:     if (dblResult == (double)0.0)
1.1       root      406:          fValueInMemory = FALSE; 
                    407:     else fValueInMemory = TRUE;
                    408: }
                    409: 
1.1.1.2 ! root      410: /******************************************************************************/
        !           411: VOID
        !           412: MClear()
1.1       root      413: {
                    414:      strcpy(szmem, "0.");   
                    415:      fValueInMemory = FALSE; 
                    416: }
                    417: 
                    418: 
1.1.1.2 ! root      419: /******************************************************************************/
        !           420: VOID
        !           421: MMinus()
        !           422: {
        !           423:     double dblX1, dblX2, dblResult;
        !           424: 
        !           425:     dblX2 = atof(szmem);
        !           426:     dblX1 = atof(szreg1);
        !           427:     if (dblX2 < (double)0) {
        !           428:        if (dblX1 > (double)0) {
        !           429:            if (dblX1 > (dblX2 - MININT))
1.1       root      430:                 fError = TRUE;
1.1.1.2 ! root      431:        }
        !           432:     }
        !           433:     else if (dblX2 > (double)0) {
        !           434:            if (dblX1 < (double)0) {
        !           435:                if (dblX1 < (dblX2 - MAXINT))
1.1       root      436:                     fError = TRUE;
1.1.1.2 ! root      437:            }
        !           438:         }
1.1       root      439:     if (!fError) {
1.1.1.2 ! root      440:        dblResult = dblX2 - dblX1;
        !           441:        strcpy( szmem, ftoa((double)dblResult));
        !           442:     }
        !           443:     if (dblResult == (double)0.0)
1.1       root      444:          fValueInMemory = FALSE; 
                    445:     else fValueInMemory = TRUE;
                    446: }
                    447: 
1.1.1.2 ! root      448: /******************************************************************************/
        !           449: VOID
        !           450: Evaluate( bCommand)
        !           451: 
        !           452: BYTE bCommand;
1.1       root      453: {
1.1.1.2 ! root      454:     switch( bCommand ) {
1.1       root      455:         case '0': case '1': case '2': case '3': case '4': case '5':
                    456:         case '6': case '7': case '8': case '9': case '.': case 0xb1:
                    457:         case 'n': /* n = 'negate'  from keyboard */
1.1.1.2 ! root      458:            if ( fReadNumber )
        !           459:                AppendNumber( bCommand );
1.1       root      460:             else {
                    461:                       /* if starting a new number */
1.1.1.2 ! root      462:                if (bCommand != 0xb1)
1.1       root      463:                     strcpy(szreg1, "0");
1.1.1.2 ! root      464:                AppendNumber( bCommand );
        !           465:            }
        !           466:            if (bCommand != 0xb1)
1.1       root      467:                 fReadNumber = TRUE;
                    468:             break;
                    469:         case '+': case '-': case '/': case '*': case 'p':
1.1.1.2 ! root      470:            BinaryOperator(bCommand);
1.1       root      471:             fReadNumber = FALSE;
                    472:             break;
                    473:         case '=':
                    474:             fReadNumber = FALSE;
                    475:             Equilibrate();
                    476:             PendingOperation = NULL;
                    477:             break;
                    478:         case 'q':
                    479:             SquareRoot();
                    480:             fReadNumber = FALSE;
                    481:             break;
                    482:         case 0xBB:   /* MR */
                    483:             strcpy(szreg1, szmem);
                    484:             fReadNumber = FALSE;
                    485:             Simplify();
                    486:             break;
                    487:         case 0xBA: /* M+ */
                    488:             MPlus();
                    489:             fReadNumber = FALSE;
                    490:             Simplify();
                    491:             break;
                    492:         case 0xB9: /* M- */
                    493:             MMinus();
                    494:             fReadNumber = FALSE;
                    495:             Simplify();
                    496:             break;
                    497:         case 0xBC:
                    498:             MClear(); /* MC */
                    499:             break;
                    500:         case '%':
                    501:             Percent();
                    502:             fReadNumber = FALSE;
                    503:             break;
                    504:         case 'c':
                    505:             Clear();
                    506:             break;
                    507:         }
                    508: }
                    509: 
1.1.1.2 ! root      510: /******************************************************************************/
        !           511: VOID
        !           512: Percent()
        !           513: {
        !           514:     double dblX1, dblX2, dblResult;
        !           515: 
        !           516:     dblX1 = atof(szreg1) / 100.0;
        !           517:     dblX2 = atof(szreg2);
        !           518:     if (ABS(dblX2) > (double)1) {
        !           519:        if (ABS(dblX1) > (double)1) {
        !           520:            if (dblX1 > (MAXINT / dblX2))
1.1       root      521:                 fError = TRUE;
1.1.1.2 ! root      522:        }
        !           523:     }
1.1       root      524:     if (!fError) {
1.1.1.2 ! root      525:        dblResult = dblX2 * dblX1;
        !           526:        strcpy( szreg1, ftoa((double)dblResult));
        !           527:     }
1.1       root      528:     Simplify();
                    529: }
                    530: 
1.1.1.2 ! root      531: /******************************************************************************/
        !           532: VOID
        !           533: InitCalc()
1.1       root      534: {
                    535:     fReadNumber = FALSE;
                    536:     fError = FALSE;
                    537:     fFirstOperand = TRUE;
                    538:     PendingOperation = 0;
                    539:     strcpy(szreg1, "0.");
                    540:     strcpy(szmem,  "0.");
                    541: }

unix.superglobalmegacorp.com

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