home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume3 / libc_term / get_float.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  4.4 KB  |  233 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <curses.h>
  4. #include "c_term.h"
  5.  
  6. float get_float(Default, field_width, places)
  7. float Default;
  8. int field_width, places;
  9.  
  10. /*
  11.  ---------------------------------------------------------------------------
  12.  
  13.    Last revision - 
  14.     6 January 1985 - GWS
  15.     Make it use curses
  16.  
  17.     16 November 1984 - GWS
  18.     Ignore XON, XOFF
  19.  
  20.      11 April 1984 - GWS
  21.  
  22.  
  23.    NAME
  24.      get_float - "crash-proof" float from keyboard routine
  25.  
  26.    SYNOPSIS
  27.     float get_float(Default, field_width, places)
  28.     float Default;
  29.     int field_width, places;
  30.  
  31.    DESCRIPTION
  32.     On a good day this routine will get a real value from the
  33.     keyboard and return it safely.  The terminal is placed in raw
  34.     mode and most non-digit values are beeped at and discarded.  Entry
  35.     is terminated by filling the field or by CR.  CR as first character
  36.     assumes Default.  ^X restarts.
  37.  
  38.    SEE ALSO
  39.  
  40.  
  41.    DIAGNOSTICS
  42.     none - cannot fail :-) 
  43.  
  44.    BUGS
  45.     Doesn't check for silly things like Default too big to fit in
  46.     field_width, etc.  Watch out for that minus sign!!
  47.     
  48.     Exponential notation is not supported.
  49.  
  50.     This version does not let you erase over the decimal point if
  51.     the integer part of the field is already full.  This is not a
  52.     terrible hardship because you are free to ^X and start over,
  53.     but it really should be fixed.
  54.  
  55.    AUTHOR
  56.      George W. Sherouse
  57.      9 April 1984
  58.  
  59.  ---------------------------------------------------------------------------
  60. */
  61.  
  62. {
  63.     int c;
  64.     float val;
  65.     int loop;
  66.     char line_buff[20];
  67.     char Format[80];
  68.     char pad;
  69.     int point, frac_count;
  70.     int count;
  71.     int int_part;
  72.     int    where_x,
  73.         where_y,
  74.         x,
  75.         y;
  76.  
  77.     void f_clean_up();
  78.  
  79.     pad = ' ';
  80.     point = 0;
  81.     frac_count = 0 ;
  82.  
  83.     getyx(stdscr, where_y, where_x);
  84.     standout();
  85.  
  86.     for (loop = 0; loop < field_width; loop++)
  87.         printw(" ");
  88.  
  89.     move(where_y, where_x);
  90.     refresh();
  91.  
  92.     sprintf(Format, "%%%d.%df", field_width, places);
  93.     printw(Format, Default);
  94.     move(where_y, where_x);
  95.     refresh();
  96.     for (loop = 0; loop <= field_width; loop++)
  97.         line_buff[loop] = 0;
  98.  
  99.     count = 0;
  100.     int_part = field_width - places - 1;
  101.     while (1)
  102.     {
  103.         if (!point && count == int_part)
  104.         {
  105.         printw(".");
  106.         line_buff[count++] = '.';
  107.         point++;
  108.         continue;
  109.         }
  110.         refresh();
  111.  
  112.         c = (getch() & 0x7f);
  113.         switch(c)
  114.         {
  115. #ifdef ABORT_CHAR
  116.         case ABORT_CHAR:
  117.         clear();
  118.         standend();
  119.         mvprintw(0, 0, "Program aborted at your request...");
  120.         move(LINES -1 , 0);
  121.         refresh();
  122.         endwin();
  123.         exit(1);
  124.         break;
  125. #endif ABORT_CHAR
  126.  
  127.         case '\r':
  128.         if (count && line_buff[count - 1] != '-')
  129.         {
  130.             sscanf(line_buff, "%f", &val);
  131.             f_clean_up(where_y, where_x, Format, val);
  132.             return(val);
  133.         }
  134.         else
  135.         {
  136.             f_clean_up(where_y, where_x, Format, Default);
  137.             return(Default);
  138.         }
  139.         break;
  140.         case '\030':
  141.         move(where_y, where_x);
  142.         for (loop = 0; loop < field_width; loop++)
  143.             line_buff[loop] = 0;
  144.         count = frac_count = point = 0;
  145.         printw(Format, Default);
  146.         move(where_y, where_x);
  147.         break;
  148.         case '.':
  149.         if (!point)
  150.         {
  151.             if (!count)
  152.             {
  153.             for (loop = 0; loop < field_width; loop++)
  154.                 printw("%c", pad);
  155.             move(where_y, where_x);
  156.             for (loop = 0; loop < field_width; loop++)
  157.                 line_buff[loop] = 0;
  158.             }
  159.             printw(".");
  160.             line_buff[count++] = '.';
  161.             point++;
  162.             break;
  163.         }
  164.         case '\021':
  165.         case '\023':
  166.         break;
  167.         default:
  168.         if (c == erase_char && count)
  169.         {
  170.             getyx(stdscr, y, x);
  171.             move(y, x - 1);
  172.             printw("%c", pad);
  173.             move(y, x - 1);
  174.             if (point)
  175.             {
  176.             if (frac_count)
  177.                 frac_count--;
  178.             else
  179.                 point--;
  180.             }
  181.             line_buff[--count] = 0;
  182.             break;
  183.         }
  184.  
  185.         if (!count && c == '-')
  186.         {
  187.             for (loop = 0; loop < field_width; loop++)
  188.             printw("%c", pad);
  189.             move(where_y, where_x);
  190.             for (loop = 0; loop < field_width; loop++)
  191.                 line_buff[loop] = 0;
  192.  
  193.             line_buff[count++] = (char) c;
  194.             printw("-");
  195.             break;
  196.         }
  197.  
  198.         if (isdigit(c) && count < field_width && frac_count < places)
  199.         {
  200.             if (!count)
  201.             {
  202.             for (loop = 0; loop < field_width; loop++)
  203.                 printw("%c", pad);
  204.             move(where_y, where_x);
  205.             for (loop = 0; loop < field_width; loop++)
  206.                 line_buff[loop] = 0;
  207.             }
  208.             printw("%c", c);
  209.             line_buff[count++] = (char) c;
  210.             if (point)
  211.             frac_count++;
  212.         }
  213.         else
  214.             fprintf(stderr, "%c", '\007');
  215.         }
  216.     }
  217. }
  218.  
  219. void f_clean_up(where_y, where_x, Format, val)
  220. int where_y, where_x;
  221. char *Format;
  222. float val;
  223.  
  224. {
  225.     int loop;
  226.  
  227.     standend();
  228.     move(where_y, where_x);
  229.     printw(Format, val);
  230.  
  231.     refresh();
  232. }
  233.