home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / FUNCS / FNDOUBLE.C < prev    next >
C/C++ Source or Header  |  1990-10-31  |  8KB  |  307 lines

  1. /*
  2.     fndouble.c         10/14/86
  3.  
  4.     % double_funcs
  5.  
  6.     Regular Double funcs.
  7.     The field variable should be a double *.
  8.  
  9.     C-scape 3.2
  10.     Copyright (c) 1986, 1987, 1988 by Oakland Group, Inc.
  11.     ALL RIGHTS RESERVED.
  12.  
  13.     Revision History:
  14.     -----------------
  15.     10/01/87 jmd     added casting
  16.      4/06/88 jmd     added call to sed_DoSpecial
  17.      5/12/88 jmd    added calls to sed_GetScratchPad()
  18.      9/17/88 jmd     added std_ funcs
  19.     10/09/88 jmd     added SED_ABORT support
  20.     10/14/88 jdc    added var_size element to field_funcs_struct
  21.     12/16/88 jmd    added validation
  22.  
  23.      6/01/89 gam    added ocountry stuff
  24.      6/07/89 jmd    added test for mouse code (later removed)
  25.  
  26.     10/02/89 gam    fixed some of the ocountry stuff
  27.     11/04/89 jdc    changed toupper & tolower to otoupper & otolower
  28.      1/31/90 jmd    don't reset baton on MOU_CLICK
  29.      2/21/90 pmcm    fixed toggle mode/baton problem (but not my initials)
  30.      2/22/90 pmcm    clear entire field on space keypress
  31.      2/22/90 pmcm/mla    added BACKSPACE/DEL case for EXPONENT mode
  32.      2/22/90 pcmm/mla    fixed EXPONENT digit entry to act like calculator
  33.      3/14/90 jmd    moved formatting before validation
  34.      3/28/90 jmd    ansi-fied
  35.      4/26/90 mla    made negative toggle EXPONENT mode sensitive
  36.      6/15/90 mla    added RIGHT and LEFT cases
  37.      6/15/90 mla    fixed clear field case
  38.     10/31/90 ted    added a cast to avoid int/char compiler warning.
  39. */
  40.  
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <ctype.h>
  44.  
  45. #include "cscape.h"
  46. #include "fnfunc.h"            /* for field functions */
  47. #include "strdecl.h"        /* for C-scape string functions */
  48. #include "scancode.h"
  49.  
  50. OSTATIC int mantissa_pos(char *record);
  51.  
  52. /* operating modes (stored in sed baton) */
  53.  
  54. #define        MANTISSA        1       /* SED_FIRST is also treated as MANTISSA */
  55. #define        EXPONENT        2
  56.  
  57. OGLOBAL field_funcs_struct double_funcs = {
  58.     double_fenter,
  59.     double_fexit,
  60.     double_fkey,
  61.     double_senter,
  62.     double_sexit,
  63.     sizeof(double)
  64. };
  65.  
  66. void double_fenter(sed_type sed)
  67. {
  68.     /* handle border prompt */
  69.     std_fenter(sed);
  70.  
  71.     sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
  72. }
  73.  
  74. boolean double_fexit(sed_type sed)
  75. {
  76.     double val;
  77.  
  78.     if (sed_GetBaton(sed) != SED_ABORT) {
  79.  
  80.         /* format the field's record */
  81.         std_format(sed);
  82.  
  83.         sscanf(sed_GetCurrRecord(sed), "%le", &val);
  84.  
  85.         /* call standard numeric validation routine (fnstdval.c) */
  86.         if (!std_NumValid(sed, (double) val)) {
  87.             return(FALSE);
  88.         }
  89.     }
  90.  
  91.     return(std_fexit(sed));
  92. }
  93.  
  94. void double_fkey(sed_type sed)
  95. {
  96.     int   scancode, key, mode, expos;
  97.     char  c, *exp_sign_sp, *s;
  98.  
  99.     scancode = kb_Read();
  100.  
  101.     if (sed_DoSpecial(sed, scancode))
  102.         return;
  103.     if (special_key(sed, scancode))
  104.         return;
  105.     if (inter_field(sed, scancode))
  106.         return;
  107.     if (inter_page(sed, scancode))
  108.         return;
  109.  
  110.     mode = (sed_GetBaton(sed) == SED_FIRST) ? MANTISSA : sed_GetBaton(sed);
  111.     if (mode == EXPONENT) {
  112.         sed_GoEnd(sed);
  113.     }
  114.     else {
  115.         sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
  116.     }
  117.  
  118.     key = ascii(scancode);
  119.  
  120.     switch(scancode) {
  121.     case DEL:
  122.     case BACKSPACE:
  123.         if (mode == MANTISSA) {
  124.             sed_PullLeft(sed);
  125.             if (digit_count(sed_GetCurrRecord(sed)) == 0) {
  126.                 sed_Overwrite(sed, '0');
  127.             }
  128.         }
  129.         else {
  130.             expos = mantissa_pos(sed_GetCurrRecord(sed)) + 3;
  131.             sed_GotoChar(sed, expos);
  132.             c = '0';
  133.             while (sed_GetRecordPos(sed) <= sed_GetCurrRecordLen(sed) - 1) {
  134.                 c = sed_Overwrite(sed, c);
  135.                 if (!sed_IncChar(sed)) {
  136.                     break;
  137.                 }
  138.             }
  139.         }
  140.         break;
  141.  
  142.     case RIGHT:
  143.         if (mode == MANTISSA) {
  144.             /*  change to exponent mode  */
  145.             mode = EXPONENT;
  146.             sed_SetBaton(sed, EXPONENT);
  147.             sed_GoEnd(sed);
  148.         }
  149.         break;
  150.     
  151.     case LEFT:
  152.         if (mode == EXPONENT) {
  153.             /*  change to mantissa mode  */
  154.             mode = MANTISSA;
  155.             sed_SetBaton(sed, MANTISSA);
  156.             sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
  157.         }
  158.         break;
  159.  
  160.     default:
  161.         if (isdigit(key) || key == '.' || key == ' ') {
  162.             if (sed_GetBaton(sed) == SED_FIRST || key == ' ') {
  163.  
  164.                 /* Clear entire field if space key is pressed */
  165.                 /* Clear entire field if first key pressed is a digit */
  166.                 sprintf((s = sed_GetScratchPad(sed)), "%.le", 0.0);
  167.                 /*  now clear the field up to the 'e'.  */
  168.                 while (otoupper(*s) != 'E') {
  169.                     *(s++) = ' ';
  170.                 }
  171.                 strright(sed_GetScratchPad(sed), sed_GetCurrRecordLen(sed));
  172.                 sed_SetCurrRecord(sed, sed_GetScratchPad(sed));
  173.                 sed_UpdateCurrField(sed);
  174.                 sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
  175.             }
  176.  
  177.             if (key == ' ') {
  178.                 /* screen space key from further processing */
  179.                 break;
  180.             }
  181.  
  182.             if (mode == EXPONENT) {
  183.                 /* Edit exponent */
  184.  
  185.                 expos = mantissa_pos(sed_GetCurrRecord(sed)) + 3;
  186.                 c = (char) key;
  187.                 while (sed_GetRecordPos(sed) >= expos) {
  188.                     if (sed_GetChar(sed, expos) == '0') {
  189.                         c = sed_Overwrite(sed, c);
  190.                     }                
  191.                     sed_DecChar(sed);
  192.                 }
  193.                 sed_GoEnd(sed);
  194.             }
  195.             else {
  196.                 /* Edit mantissa */
  197.  
  198.                 if (sed_GetChar(sed, 1) == ' ' || sed_GetChar(sed, 1) == '-'){
  199.                     if (sed_GetCurrChar(sed) == '0' &&
  200.                       digit_count(sed_GetCurrRecord(sed)) == 1) {
  201.                         sed_Overwrite(sed, key);
  202.                     }
  203.                     else {
  204.                         sed_PushLeft(sed, key);
  205.                     }
  206.                 }
  207.             }
  208.         }
  209.  
  210.         /* toggle minus sign if appropriate */
  211.         else if (key == '-') {
  212.             strcpy(sed_GetScratchPad(sed), sed_GetCurrRecord(sed));
  213.             if (mode == EXPONENT) {
  214.                 exp_sign_sp = sed_GetScratchPad(sed) + mantissa_pos(sed_GetScratchPad(sed)) + 2; 
  215.                 if (*exp_sign_sp == '-') {
  216.                     *exp_sign_sp = '+';
  217.                 }
  218.                 else {
  219.                     *exp_sign_sp = '-';
  220.                 }
  221.                 sed_SetCurrRecord(sed, sed_GetScratchPad(sed));
  222.                 }
  223.             else {           /*  mode == MANTISSA  */
  224.                 sed_SetCurrRecord(sed, strminus(sed_GetScratchPad(sed)));
  225.             }
  226.         sed_UpdateCurrField(sed);
  227.         }
  228.  
  229.         /* if no decimal point yet, add one */
  230.  
  231.         else if (key == ocountry.dec_char &&
  232.           (sed_GetChar(sed, 1) == ' '|| sed_GetChar(sed, 1) == '-')) {
  233.             if (strchr(sed_GetCurrRecord(sed), ocountry.dec_char) == NULL)  {
  234.                 /* no decimal point */
  235.                   sed_PushLeft(sed, ocountry.dec_char);
  236.             }
  237.         }
  238.         /* toggle EXP mode */
  239.         else if (otoupper(key) == 'E') {
  240.                if (mode == EXPONENT) {
  241.                 mode = MANTISSA;
  242.                 sed_SetBaton(sed, MANTISSA);
  243.                 sed_GotoChar(sed, mantissa_pos(sed_GetCurrRecord(sed)));
  244.             }
  245.             else {
  246.                 mode = EXPONENT;
  247.                    sed_SetBaton(sed, EXPONENT);
  248.                 sed_GoEnd(sed);
  249.             }
  250.         }
  251.         break;
  252.     }
  253.  
  254.     /* reset baton */
  255.     if (scancode != MOU_CLICK) {
  256.         sed_SetBaton(sed, mode);
  257.     }
  258. }
  259.  
  260.  
  261. static int mantissa_pos(char *record)
  262. /*
  263.     returns the record position of the mantissa
  264.     i.e., the position before the 'e'.
  265. */
  266. {
  267.     char *p;
  268.     int pos;
  269.  
  270.     for (p = record, pos= 0; p[pos] != '\0' && p[pos] != 'e' && p[pos] != 'E'; pos++) {
  271.         ;
  272.     }
  273.  
  274.     return((pos > 0) ? (pos - 1) : 0);
  275. }
  276.  
  277. void double_senter(sed_type sed, int fieldno)
  278. /*
  279.     Convert native type to string for record.
  280. */
  281. {
  282.     sprintf(sed_GetScratchPad(sed), "%.le", *((double *) sed_GetVar(sed, fieldno)));
  283.  
  284.     /* My change to change the decimal default from printf to 
  285.         the ocountry decimal character. */
  286.     strtrans(sed_GetScratchPad(sed), '.', ocountry.dec_char);
  287.     strright(sed_GetScratchPad(sed), sed_GetRecordLen(sed, fieldno));
  288.     sed_SetRecord(sed, sed_GetScratchPad(sed), fieldno);
  289.  
  290.     std_senter(sed, fieldno);
  291. }
  292.  
  293. void double_sexit(sed_type sed, int fieldno)
  294. /*
  295.     Converts record back to native type.
  296. */
  297. {
  298.     if (sed_GetBaton(sed) != SED_ABORT) {
  299.         strcpy(sed_GetScratchPad(sed), sed_GetRecord(sed, fieldno));
  300.         strnocomma(sed_GetScratchPad(sed));
  301.         strtrans(sed_GetScratchPad(sed), ocountry.dec_char, '.');
  302.         
  303.         sscanf(sed_GetRecord(sed, fieldno), "%le", (double *) sed_GetVar(sed, fieldno));
  304.     }
  305. }
  306.  
  307.