home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 14 / CD_ASCQ_14_0694.iso / maj / 653 / editgets.c < prev    next >
C/C++ Source or Header  |  1994-04-03  |  13KB  |  372 lines

  1. /* editgets.c - line input w/editing                                        */
  2. /* this code is released to the public domain                               */
  3. /* written by Jon Burchmore                                                 */
  4. /* modifications & enhancements by Bob Stout                                */
  5.  
  6. /* This is as close to ANSI compliant C that I could come, but it was made  */
  7. /* on an IBM compatable computer, so I designed it for that platform.       */
  8. /* If you're porting it to another computer type, please note how the IBM   */
  9. /* passes enhanced keys.  First, it sends an ASCIIZ (character 0), then a   */
  10. /* standard character.  Anyway, what the switch() statement does is check   */
  11. /* to see if there WAS a zero sent, and if there wasn't, it just "falls"    */
  12. /* through to the default, which handles normal characters.                 */
  13.  
  14. /* The conio header file provides the getch() function, which returns a     */
  15. /* single character from the KEYBOARD, not stdin, and waits if it must.     */
  16. /* It is be possible to re-write this function for a computer besides an    */
  17. /* IBM PC.                                                                  */
  18.  
  19. /* It would be possible to check the variable insert, and if it's on, make  */
  20. /* the cursor large, and if it's off, make the cursor small, but my primary */
  21. /* goal is portability, not fancy add-ons                                   */
  22.  
  23. /* Pardon the lack of comments.  I'm a coder, not an author.  Besides, if   */
  24. /* you can't understand this, DON'T USE IT! (Words to live by)              */
  25.  
  26. #include <conio.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30.  
  31. #undef min
  32. #define min(x,y) (((x) <= (y)) ? (x) : (y))
  33.  
  34. #define NUL     0x00
  35. #define ESC     0x1B
  36. #define LEFT    0x4B
  37. #define RIGHT   0x4D
  38. #define HOME    0x47
  39. #define END     0x4F
  40. #define INSERT  0x52
  41. #define DELETE  0x53
  42. #define BACKSPC 0x08
  43. #define ENTER   0x0D
  44. #define CTLEND  0x75
  45. #define CTLHOME 0x77
  46. #define CTLRT   0x74
  47. #define CTLLFT  0x73
  48.  
  49. /*
  50. **  Password mode - '*' is echoed for all characters, only ESC, ENTER,
  51. **  BACKSPC, and CTLHOME are active.
  52. */
  53.  
  54. int password_mode = 0;
  55.  
  56. /*
  57. **  Aruments: 1) Buffer to receive string
  58. **            2) Size of buffer
  59. **            3) Default string
  60. */
  61.  
  62. int jgets(char *s, int maxlen, char *string)
  63. {
  64.       char temp[500];
  65.       int insert = 1, done = 0, pos, len, i, j, c, zeroflag;
  66.  
  67.       if (NULL == string)
  68.             string = "";
  69.  
  70.       if (0 != (pos = len = strlen(string)))
  71.             strncpy(temp, string, min(len, maxlen));
  72.  
  73.       for (i = 0; i < maxlen; ++i)
  74.       {
  75.             if (NUL == *string)
  76.                   putchar('_');
  77.             else  putchar(*string++);
  78.       }
  79.       for (i = 0; i < (maxlen - len); ++i)
  80.             putchar(BACKSPC);
  81.  
  82.       while (!done)
  83.       {
  84.             zeroflag = 0;
  85.             if ((c = getch()) == 0)
  86.             {
  87.                   zeroflag = 1;
  88.                   c = getch();
  89.             }
  90.             switch (c)
  91.             {
  92.             case ESC :
  93.                   if (len == 0)
  94.                         break;
  95.                   if (pos != len)
  96.                   {
  97.                         for (i = pos; i < len; i++)
  98.                               putch('_');
  99.                         for (i = len; i >= 0; i--)
  100.                         {
  101.                               putch(BACKSPC);
  102.                               putch('_');
  103.                               putch(BACKSPC);
  104.                         }
  105.                         pos = len = 0;
  106.                         break;
  107.                   }
  108.  
  109.             case LEFT :
  110.                   if (zeroflag)
  111.                   {
  112.                         if (password_mode)
  113.                               break;
  114.                         if (pos == 0)
  115.                               break;
  116.                         pos--;
  117.                         putch(BACKSPC);
  118.                         break;
  119.                   }
  120.  
  121.             case RIGHT :
  122.                   if (zeroflag)
  123.                   {
  124.                         if (password_mode)
  125.                               break;
  126.                         if (pos == len)
  127.                               break;
  128.                         if (pos != maxlen)
  129.                         {
  130.                               putch(temp[pos]);
  131.                               pos++;
  132.                         }
  133.                         break;
  134.                   }
  135.  
  136.             case HOME :
  137.                   if (zeroflag)
  138.                   {
  139.                         if (password_mode)
  140.                               break;
  141.                         while (pos-- > 0)
  142.                               putch(BACKSPC);
  143.                         pos = 0;
  144.                         break;
  145.                   }
  146.  
  147.             case END :
  148.                   if (zeroflag)
  149.                   {
  150.                         if (password_mode)
  151.                               break;
  152.                         while (pos < len)
  153.                               putch(temp[pos++]);
  154.                         break;
  155.                   }
  156.  
  157.             case INSERT :
  158.                   if (zeroflag)
  159.                   {
  160.                         if (password_mode)
  161.                               break;
  162.                         insert = (!(insert));
  163.                         break;
  164.                   }
  165.  
  166.             case DELETE :
  167.                   if (zeroflag)
  168.                   {
  169.                         if (password_mode)
  170.                               break;
  171.                         if (pos == len)
  172.                               break;
  173.                         for (i = pos; i < len; i++)
  174.                               temp[i] = temp[i + 1];
  175.                         len--;
  176.                         for (i = pos; i < len; i++)
  177.                               putch(temp[i]);
  178.                         putch('_');
  179.                         for (i = len + 1; i > pos; i--)
  180.                               putch(BACKSPC);
  181.                         break;
  182.                   }
  183.  
  184.             case BACKSPC :
  185.                   if (c == BACKSPC)
  186.                   {
  187.                         if (pos == 0)
  188.                               break;
  189.                         if (pos != len)
  190.                         {
  191.                               for (i = pos - 1; i < len; i++)
  192.                                     temp[i] = temp[i + 1];
  193.                               pos--;
  194.                               len--;
  195.                               putch(BACKSPC);
  196.                               for (i = pos; i < len; i++)
  197.                                     putch(temp[i]);
  198.                               putch('_');
  199.                               for (i = len; i >= pos; i--)
  200.                                     putch(BACKSPC);
  201.                         }
  202.                         else
  203.                         {
  204.                               putch(BACKSPC);
  205.                               putch('_');
  206.                               putch(BACKSPC);
  207.                               pos = --len;
  208.                         }
  209.                         break;
  210.                   }
  211.  
  212.             case ENTER :
  213.                   if (c == ENTER)
  214.                   {
  215.                         done = 1;
  216.                         break;
  217.                   }
  218.  
  219.             case CTLEND :
  220.                   if (zeroflag)
  221.                   {
  222.                         if (password_mode)
  223.                               break;
  224.                         for (i = pos; i < len; ++i)
  225.                               putch('_');
  226.                         for (i = pos; i < len; ++i)
  227.                               putch(BACKSPC);
  228.                         len = pos;
  229.                         break;
  230.                   }
  231.  
  232.             case CTLHOME :
  233.                   if (zeroflag)
  234.                   {
  235.                         if (pos == 0)
  236.                               break;
  237.                         if (pos != len)
  238.                         {
  239.                               while (0 != pos)
  240.                               {
  241.                                     for (i = pos - 1; i < len; i++)
  242.                                           temp[i] = temp[i + 1];
  243.                                     pos--;
  244.                                     len--;
  245.                                     putch(BACKSPC);
  246.                                     for (i = pos; i < len; i++)
  247.                                           putch(temp[i]);
  248.                                     putch('_');
  249.                                     for (i = len; i >= pos; i--)
  250.                                           putch(BACKSPC);
  251.                               }
  252.                         }
  253.                         else
  254.                         {
  255.                               while (0 != pos)
  256.                               {
  257.                                     putch(BACKSPC);
  258.                                     putch('_');
  259.                                     putch(BACKSPC);
  260.                                     pos = --len;
  261.                               }
  262.                         }
  263.                         break;
  264.                   }
  265.  
  266.             case CTLRT :
  267.                   if (zeroflag)
  268.                   {
  269.                         if (password_mode)
  270.                               break;
  271.                         do
  272.                         {
  273.                               if (pos == len)
  274.                                     break;
  275.                               if (pos != maxlen)
  276.                               {
  277.                                     putch(temp[pos]);
  278.                                     pos++;
  279.                               }
  280.                         } while (isspace(temp[pos]));
  281.                         do
  282.                         {
  283.                               if (pos == len)
  284.                                     break;
  285.                               if (pos != maxlen)
  286.                               {
  287.                                     putch(temp[pos]);
  288.                                     pos++;
  289.                               }
  290.                         } while (!isspace(temp[pos]));
  291.                         break;
  292.                   }
  293.  
  294.             case CTLLFT :
  295.                   if (zeroflag)
  296.                   {
  297.                         if (password_mode)
  298.                               break;
  299.                         do
  300.                         {
  301.                               if (pos == 0)
  302.                                     break;
  303.                               pos--;
  304.                               putch(BACKSPC);
  305.                         } while (isspace(temp[pos]));
  306.                         do
  307.                         {
  308.                               if (pos == 0)
  309.                                     break;
  310.                               pos--;
  311.                               putch(BACKSPC);
  312.                         } while (!isspace(temp[pos]));
  313.                         break;
  314.                   }
  315.  
  316.             default :
  317.                   if (zeroflag)
  318.                         break;
  319.                   if (c == 0 || pos == maxlen)
  320.                         break;
  321.                   if ((!(insert)) || pos == len)
  322.                   {
  323.                         temp[pos++] = (char)c;
  324.                         if (pos > len) len++;
  325.                         if (password_mode)
  326.                               putch('*');
  327.                         else  putch(c);
  328.                   }
  329.                   else
  330.                   {
  331.                         if (len == maxlen)
  332.                               break;
  333.                         for (i = len++; i >= pos; i--)
  334.                               temp[i + 1] = temp[i];
  335.                         temp[pos++] = (char)c;
  336.                         if (password_mode)
  337.                               putch('*');
  338.                         else  putch(c);
  339.                         for (i = pos; i < len; i++)
  340.                               putch(temp[i]);
  341.                         for (i = len; i > pos; i--)
  342.                               putch(BACKSPC);
  343.                   }
  344.             }
  345.       }
  346.       temp[len] = '\0';
  347.       strcpy(s, temp);
  348.       return len;
  349. }
  350.  
  351. #ifdef TEST
  352.  
  353. void main(void)
  354. {
  355.       char mystring[60];
  356.  
  357.       memset(mystring, 0, 60);
  358.       fputs("Enter any string: ", stdout);
  359.       jgets(mystring, 60, "This is a test");
  360.       puts("");
  361.       printf("editgets() returned:\n%s\n", mystring);
  362.  
  363.       password_mode = 1;
  364.       memset(mystring, 0, 60);
  365.       fputs("Enter any password: ", stdout);
  366.       jgets(mystring, 50, NULL);
  367.       puts("");
  368.       printf("editgets() returned:\n%s\n", mystring);
  369. }
  370.  
  371. #endif
  372.