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

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

unix.superglobalmegacorp.com

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