home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 147_01 / rbbscio.c < prev    next >
Text File  |  1985-03-10  |  14KB  |  704 lines

  1. /****************************************************************
  2. * RBBSCIO.C                            *
  3.  
  4. Release 5: RBBS 4.1 Edit 00  27 Feb 84
  5. Release 2: RBBS 4.0 Edit 19  30 Jan 84
  6. Release 1: RBBS 4.0 Edit 18  29 Jan 84
  7.  
  8. * This file contains the functions:
  9.  
  10. * outstr    calls bputs after checking for pause/abort.  Has
  11.                 a variety of CRLF options
  12.  
  13. * instr        calls getinp after checking for pending typeahead
  14.  
  15. * getinp    line editor input
  16.  
  17. * backrub    bputs BS-SP-BS
  18.  
  19. * backspace    outputs n backspaces
  20.  
  21. * space        outputs n spaces
  22.  
  23. * bputs        outputs string via bios with tab expansion and
  24.                 maintains character count
  25.  
  26. * putic        outputs mask character string.  called by getinp
  27.  
  28. * hlplined    help text, called by ^V from getinp
  29.  
  30. * linedisp    outputs string of real or mask characters -
  31.                 called internally by getinp
  32.  
  33. * subdel    internal getinp function for BS and DEL
  34.  
  35. * crlf        displays n CRLFs
  36.  
  37. * upstr        UPPERcases string, removing leading and trailing blanks
  38.  
  39. * capstr    Capitalizes string, removing leading and trailing blanks
  40.  
  41. * getyn        prompts with string, gets a Y or N or CR reply
  42.  
  43. ****************************************************************/
  44. #include    <bdscio.h>
  45. #include    "rbbs4.h"
  46. /****************************************************************/
  47. /* Some assumed globals (in order of appearance):
  48.  
  49. char    pp[SECSIZ];    /* Previous Prompt string        */
  50. int    ocnt;        /* Output character count        */
  51. int    colcnt;        /* Horizontal cursor position        */
  52. int    belflg;        /* BELL Flag                */
  53. int    cflg;        /* Character Flag:
  54.                 1 = don't allow typeahead
  55.                 2 = use Mask Characters
  56.                 3 = output CRLF after input    */
  57. char    sav[SECSIZ];    /* Typeahead buffer            */
  58. int    icnt;        /* Input character count        */
  59.  
  60. ****************************************************************/
  61. /****************************************************************/
  62. outstr(output,flag)
  63. char    *output;
  64. int    flag;        /* 0 = no special action
  65.                1 = CRLF after output only
  66.                2 = CRLF before and after output
  67.                3 = CRLF before output
  68.                4 = CRLF after output and put into pp
  69.                5 = put into pp only - no CRLFs    */
  70. {
  71.     char    b1;
  72.  
  73.     if (bios(2))
  74.     {
  75.         b1 = toupper(bios(3));
  76.         if ((b1 == 0x0B) || (b1 == 'K'))
  77.             return TRUE;
  78.         if ((b1 == 0x13) || (b1 == 'S'))
  79.             b1 = bios(3);
  80.     }
  81.     if ( (flag >= 2) && (flag <= 4 ) )
  82.         crlf(1);
  83.     bputs(output);        /* Print the string already        */
  84.     if ( (flag == 1) || (flag == 2) )
  85.         crlf(1);
  86.     if ( (flag >= 4) )
  87.         strcpy(pp,output);/* Save in pp for possible reprompt    */
  88.     ocnt += strlen(output);
  89.     return FALSE;
  90. }
  91. /****************************************************************/
  92. instr(oldline,input,limit)
  93. char    *input;
  94. char    *oldline;
  95. int    limit;
  96. {
  97.     int    cmdflg;
  98.     char    temp[SECSIZ];
  99.  
  100.     if ( (belflg) && !(*sav) )
  101.     {
  102.         bios(4,7);
  103.         ++ocnt;
  104.     }
  105.     cmdflg = TRUE;
  106.     if (!*sav)
  107.     {                /* If no pending input    */
  108.         strcpy(sav,oldline);
  109.         getinp(limit);
  110.         if (cflg == 3)
  111.             crlf(1);
  112.         cmdflg = FALSE;
  113.     }
  114.     if ( (cflg == 1) || (index(sav,";") == ERROR) )
  115.     {
  116.         strcpy(temp,sav);
  117.         setmem(sav,SECSIZ,0);
  118.     }
  119.     else
  120.         if (sscanf(sav,"%s;%s",temp,sav) == 1)
  121.             setmem(sav,SECSIZ,0);
  122.     *(temp+limit) = 0;
  123.     strcpy(input,temp);
  124.     if (cmdflg)
  125.         bputs(input);
  126.     icnt += strlen(input);
  127.     cflg = 0;
  128. }
  129. /****************************************************************/
  130. getinp(limit)            /* This code is not too bad    */
  131. int    limit;
  132. {
  133.     int    chc;        /* Input character count    */
  134.     int    dc;        /* DEL flag            */
  135.     char    ic;        /* Integer Mask Character    */
  136.     char    nch;        /* Input character        */
  137.     int    i;        /* Loop counter            */
  138.     int    j;        /* Loop counter            */
  139.     int    k;
  140.     int    l;
  141.     char    kbuff[SECSIZ];    /* Kill buffer            */
  142.     int    kcnt;        /* kbuff pointer        */
  143.     int    iflg;        /* Insert Mode Flag        */
  144.     int    sf;        /* Semicolon Flag        */
  145.     int    tabcnt;        /* TAB space expansion counter    */
  146.     int    yankcnt;    /* Yank buffer counter        */
  147.  
  148.     iflg = -1;        /* Initialize Insert Mode Flag    */
  149.     ic = 0x31;        /* Initialize Mask Character    */
  150.     kcnt = 0;        /* Initialize kbuff pointer    */
  151.     *kbuff = 0;        /* Initialize kbuff        */
  152.     sf = FALSE;
  153.     tabcnt = 0;        /* Initialize tabexp counter    */
  154.     yankcnt = 0;        /* Initialize yank buffer cntr    */
  155.     colcnt = 0;        /* Initialize column count    */
  156.  
  157.     if ( (chc = strlen(sav)) )    /* Initialize character count    */
  158.     {
  159.         if (cflg != 2)
  160.             bputs(sav);
  161.         else
  162.             ic = putic(0x31,chc);
  163.     }
  164.     dc = FALSE;        /* Initialize DEL Flag        */
  165.  
  166.     while (TRUE)
  167.     {
  168.     if (yankcnt)
  169.     {
  170.         nch = *(kbuff+(--yankcnt));
  171.         kcnt = yankcnt;
  172.     }
  173.     else
  174.         if (!tabcnt)
  175.             nch = bios(3);    /* Get a character from console    */
  176.         else
  177.         {
  178.             nch = ' ';    /* Get a space instead        */
  179.             --tabcnt;
  180.         }
  181.     switch(nch)
  182.     {
  183.         case '\r':        /* CR  Done        */
  184.             return;
  185.  
  186.         case '\t':
  187.             tabcnt = 5 - (colcnt % 5);
  188.             break;
  189.  
  190.         case 0177:        /* DEL    cancel char    */
  191.             if (!chc || !iflg)
  192.                 break;
  193.             if ( cflg != 2)
  194.             {
  195.                 bputs("\b\\\b");
  196.                 dc = TRUE;    /* Set DEL Flag    */
  197.             }
  198.             else
  199.                 backrub(1);
  200.             subdel(&chc,&iflg,&ic);
  201.             if ( (sf) && (chc <= sf) )
  202.                 sf = FALSE;
  203.             break;
  204.  
  205.  
  206.         case '\b':        /* BS  cancel char    */
  207.             if (!chc || !iflg)
  208.                 break;
  209.             backrub(1);
  210.             dc = FALSE;        /* Clear DEL flg*/
  211.             subdel(&chc,&iflg,&ic);
  212.             if ( (sf) && (chc <= sf) )
  213.                 sf = FALSE;
  214.             break;
  215.  
  216.  
  217.         case 0x04:        /* ^D  cancel current char    */
  218.             if (!chc || (iflg == -1) )
  219.                 break;
  220.             dc = FALSE;        /* Clear DEL flg*/
  221.             if ( iflg == sf )
  222.                 sf = FALSE;
  223.             movmem(sav+iflg+1,sav+iflg,chc-iflg);
  224.             --chc;
  225.             bputs(sav+iflg);
  226.             space(1);
  227.             backspace(chc-iflg+1);
  228.             if (chc == iflg)
  229.                 iflg = -1;
  230.             break;        /* last char    */
  231.  
  232.  
  233.         case 0x17:        /* ^W  delete previous word    */
  234.             if ( !chc || !iflg || (cflg == 2) )
  235.                 break;
  236.             dc = FALSE;        /* Clear DEL flg*/
  237.             j = 0;
  238.             if ( iflg == -1)
  239.             {
  240.                 k = chc;
  241.                 while ( (chc) && (*(sav+chc-1) == ' ') )
  242.                 {
  243.                     ++j;
  244.                     --chc;
  245.                 }
  246.                 while ((chc) && (*(sav+chc-1) != ' ') )
  247.                 {
  248.                     ++j;
  249.                     --chc;
  250.                 }
  251.                 backrub(j);
  252.                 while (j--)
  253.                 {
  254.                     *(kbuff+kcnt++) = *(sav+(--k));
  255.                     *(sav+k) = 0;    /* Wipe out    */
  256.                 }            /* last char    */
  257.                 if ( (sf) && (chc <= sf) )
  258.                     sf = FALSE;
  259.             }
  260.             else
  261.             {
  262.                 k = chc;
  263.                 l = iflg;
  264.                 while ( (iflg) && (*(sav+iflg-1) == ' ') )
  265.                 {
  266.                     ++j;
  267.                     --iflg;
  268.                     --chc;
  269.                 }
  270.                 while ( (iflg) && (*(sav+iflg-1) != ' ') )
  271.                 {
  272.                     ++j;
  273.                     --iflg;
  274.                     --chc;
  275.                 }
  276.                 backrub(j);
  277.                 for ( i = l-1; i >= iflg; i--)
  278.                     *(kbuff+kcnt++) = *(sav+i);
  279.                 movmem(sav+l,sav+iflg,k-l+1);
  280.                 bputs(sav+iflg);
  281.                 space(j);
  282.                 backspace(k-iflg);
  283.                 if(sf && (sf >= iflg) && (sf <= k))
  284.                     sf = FALSE;
  285.             }
  286.             break;
  287.  
  288.  
  289.         case 0x19:        /* ^Y  Yank Kill Buffer        */
  290.             if ( (!chc && !kcnt) || (cflg == 2) )
  291.                 break;
  292.             if ( iflg == -1)
  293.             {
  294.                 yankcnt = kcnt;
  295.                 break;
  296.             }
  297.             else
  298.             {
  299.                 k = 0;
  300.                 for ( i = kcnt-1; i >= 0; i--)
  301.                 {
  302.                     j = *(kbuff+i);
  303.                     if ( (j == ';') && (!sf) && (cflg != 1) )
  304.                         sf = chc;
  305.                     if ( (chc == SECSIZ-3) || ((chc == limit) && (!sf)))
  306.                     {
  307.                         bios(4,7);
  308.                         ++ocnt;
  309.                         break;
  310.                     }
  311.                     movmem(sav+iflg,sav+iflg+1,++chc-iflg);
  312.                     *(sav+iflg++) = j;
  313.                     ++k;
  314.                 }
  315.                 bputs(sav+iflg-k);
  316.                 backspace(chc-iflg);
  317.                 kcnt = 0;
  318.                 *kbuff = 0;
  319.                 dc = FALSE;
  320.             }
  321.             break;
  322.  
  323.  
  324.         case '\f':        /* ^L  Redisplay on same line    */
  325.             if (!chc)
  326.                 break;
  327.             i = chc;
  328.             if ( iflg > 0 )
  329.                 i = iflg;
  330.             if ( chc && iflg )
  331.                 backrub(i);
  332.             ic = linedisp(&chc,&iflg);
  333.             dc = FALSE;
  334.             break;
  335.  
  336.  
  337.         case 0x12:        /* ^R  Redisplay on next line    */
  338.             crlf(1);
  339.             bputs(pp);
  340.             ocnt += strlen(pp);
  341.             ic = linedisp(&chc,&iflg);
  342.             dc = FALSE;
  343.             break;
  344.  
  345.  
  346.         case 0x15:        /* ^U  Cancel and redisplay prompt */
  347.             bputs(sav+iflg);
  348.             bputs(" #\r\n");
  349.             bputs(pp);
  350.             if (!kcnt)
  351.                 for ( i = chc-1; i >= 0; i--)
  352.                     *(kbuff+kcnt++) = *(sav+i);
  353.             iflg = -1;
  354.             chc = 0;
  355.             *sav = 0;
  356.             ic = 0x31;
  357.             dc = FALSE;
  358.             sf = FALSE;
  359.             colcnt = 0;
  360.             break;
  361.  
  362.  
  363.         case 0x18:        /* ^X  Cancel line inplace    */
  364.             if (!chc)
  365.                 break;
  366.             if ( iflg >= 0 )
  367.                 bputs(sav+iflg);
  368.             backrub(chc);
  369.             if (!kcnt)
  370.                 for ( i = chc-1; i >= 0; i--)
  371.                     *(kbuff+kcnt++) = *(sav+i);
  372.             iflg = -1;
  373.             chc = 0;
  374.             *sav = 0;
  375.             ic = 0x31;
  376.             dc = FALSE;
  377.             sf = FALSE;
  378.             colcnt = 0;
  379.             break;
  380.  
  381.  
  382.         case 0x0b:        /* ^K  Kill to end of line    */
  383.             if (!chc || (iflg == -1) )
  384.                 break;
  385.             bputs(sav+iflg);
  386.             backrub(chc-iflg);
  387.             for ( i = chc-1; i >= iflg; i--)
  388.                 *(kbuff+kcnt++) = *(sav+(--chc));
  389.             *(sav+chc) = 0;
  390.             if ( (sf) && (chc <= sf) )
  391.                 sf = FALSE;
  392.             iflg = -1;
  393.             break;
  394.  
  395.  
  396.         case 0x02:        /* ^B  Move back inplace    */
  397.             if (!chc || !iflg || (cflg == 2) )
  398.                 break;
  399.             bios(4,'\b');
  400.             ++ocnt;
  401.             --colcnt;
  402.             if ( iflg >= 0 )
  403.                 --iflg;
  404.             else
  405.                 iflg = chc - 1;
  406.             break;
  407.  
  408.  
  409.         case 0x06:        /* ^F  Move forward inplace    */
  410.             if ( iflg == -1 )
  411.                 break;
  412.             bios(4,*(sav+iflg++));
  413.             ++ocnt;
  414.             ++colcnt;
  415.             if (chc == iflg)
  416.                 iflg = -1;
  417.             break;
  418.  
  419.  
  420.         case 0x01:        /* ^A  Move to beginning    */
  421.             if (!chc || !iflg || (cflg == 2) )
  422.                 break;
  423.             i = chc;
  424.             if ( iflg > 0 )
  425.                 i = iflg;
  426.             backspace(i);
  427.             iflg = 0;
  428.             break;
  429.  
  430.  
  431.         case 0x05:        /* ^E  Move to end of line    */
  432.             if ( (!chc) || (iflg == -1) )
  433.                 break;
  434.             else
  435.                 bputs(sav+iflg);
  436.             iflg = -1;
  437.             break;
  438.  
  439.         case 0x16:        /* ^View  Help!            */
  440.             hlplined();
  441.             crlf(1);
  442.             bputs(pp);
  443.             colcnt = 0;
  444.             ic = linedisp(&chc,&iflg);
  445.             dc = FALSE;
  446.             break;
  447.  
  448.         default:
  449.             if (nch < 0x20)
  450.                 break;
  451.             if ( (nch == ';') && (!sf) && (cflg != 1) )
  452.                 sf = chc;
  453.             if ( (chc == SECSIZ-3) || ((chc == limit) && (!sf)))
  454.             {
  455.                 bios(4,7);
  456.                 ++ocnt;
  457.                 break;
  458.             }
  459.             if ( iflg >= 0 )
  460.             {
  461.                 movmem(sav+iflg,sav+iflg+1,++chc-iflg);
  462.                 *(sav+iflg++) = nch;
  463.             }
  464.             else
  465.             {
  466.                 *(sav+chc++) = nch;
  467.                 *(sav+chc) = 0;
  468.             }
  469.             if (dc)
  470.             {
  471.                 bios(4,'\n');
  472.                 ++ocnt;
  473.             }
  474.             if (cflg != 2)
  475.             {
  476.                 bios(4,nch);
  477.                 ++ocnt;
  478.                 ++colcnt;
  479.                 if ( iflg >= 0 )
  480.                 {
  481.                     bputs(sav+iflg);
  482.                     backspace(chc-iflg);
  483.                 }
  484.             }
  485.             else
  486.             {
  487.                 bios(4,ic++);
  488.                 ++ocnt;
  489.                 ++colcnt;
  490.                 if (ic == 0x3a)
  491.                     ic = 0x30;
  492.                 if ( iflg >= 0 )
  493.                 {
  494.                     ic = putic(ic,chc-iflg+1);
  495.                     backspace(chc-iflg+1);
  496.                 }
  497.             }
  498.             dc = FALSE;
  499.     }
  500.     }
  501. }
  502. /****************************************************************/
  503. backrub(i)
  504. int    i;
  505. {
  506.     while (i--) bputs("\b \b");
  507. }
  508. /****************************************************************/
  509. backspace(i)
  510. int    i;
  511. {
  512.     while (i--)
  513.     {
  514.         bios(4,'\b');
  515.         ++ocnt;
  516.         --colcnt;
  517.     }
  518. }
  519. /****************************************************************/
  520. space(i)
  521. int    i;
  522. {
  523.     while (i--)
  524.     {
  525.         bios(4,' ');
  526.         ++ocnt;
  527.         ++colcnt;
  528.     }
  529. }
  530. /****************************************************************/
  531. bputs(s)
  532. char    *s;
  533. {
  534.     int    j;
  535.  
  536.     while (*s)
  537.     {
  538.         if (*s == '\r')
  539.             colcnt = 0;
  540.         if ( (*(s-1) == '\r') && (*s == '\n') )
  541.             colcnt = -1;
  542.         if ( (*(s-1) != '\r') && (*s == '\n') )
  543.             --colcnt;
  544.         if (*s == '\t')
  545.         {
  546.             *s++;
  547.             j = 8 - (colcnt % 8);
  548.             space(j);
  549.         }
  550.         else
  551.         {
  552.             if (*s == '\b')
  553.                 --colcnt;
  554.             else
  555.                 ++colcnt;
  556.             bios(4,*s++);
  557.         }
  558.         ++ocnt;
  559.     }
  560. }
  561. /****************************************************************/
  562. char    *putic(ic,cnt)
  563. char    ic;
  564. int    cnt;
  565. {
  566.     while (cnt--)
  567.         {
  568.             bios(4,ic++);
  569.             ++ocnt;
  570.             ++colcnt;
  571.             if ( ic == 0x3a )
  572.                 ic = 0x30;
  573.         }
  574.     return ic;
  575. }
  576. /****************************************************************/
  577. hlplined()
  578. {
  579.     if (cflg != 2)
  580.         bufinmsg("RCIOHLP0");
  581.     else
  582.         bufinmsg("RCIOHLP2");
  583. }
  584. /****************************************************************/
  585. char    *linedisp(chc,iflg)
  586. int    *chc;
  587. int    *iflg;
  588. {
  589.     char    ic;
  590.  
  591.     if (cflg != 2)
  592.         bputs(sav);
  593.     else
  594.         ic = putic(0x31,*chc);
  595.     if ( *iflg >= 0 )
  596.         backspace(*chc-*iflg);
  597.     return ic;
  598. }
  599. /****************************************************************/
  600. subdel(chc,iflg,ic)
  601. int    *chc;
  602. int    *iflg;
  603. char    *ic;
  604. {
  605.     if (--*ic == 0x2f)
  606.         *ic = 0x39;
  607.     if ( *iflg == -1)
  608.         *(sav+(--*chc)) = 0;
  609.     else
  610.     {
  611.         --*iflg;
  612.         movmem(sav+*iflg+1,sav+*iflg,*chc-*iflg);
  613.         --*chc;
  614.         if ( cflg != 2)
  615.             bputs(sav+*iflg);
  616.         else
  617.             *ic = putic(*ic,*chc-*iflg);
  618.         space(1);
  619.         backspace(*chc-*iflg+1);
  620.     }
  621. }
  622. /****************************************************************/
  623. crlf(i)
  624. int    i;
  625. {
  626.     while(i--) 
  627.         bputs("\r\n");
  628. }
  629. /****************************************************************/
  630. upstr(s)    /* Capitalize (one word) string            */
  631. char    *s;    /* and flush ALL spaces - DS            */
  632. {
  633.      int    i;
  634.     char    *p1,*p2;
  635.  
  636. /* Delete ALL spaces from string */
  637.  
  638.     for ( p1 = p2 = s; *p2; p2++)
  639.     {
  640.         if ( *p2 != ' ')
  641.             *(p1++) = *p2;
  642.     }
  643.     *p1 = 0;    /* Terminate possibly shortened string    */
  644.  
  645. /* Convert first char to upper, remainder of string to lower    */
  646.  
  647.     p1 = s;        /* Re-set pointer to start of string    */
  648.     *p1 = toupper(*(p1++));
  649.     while ( *p1 = tolower(*(p1++)) );
  650.  
  651.     return s;    /* Return original pointer        */
  652. }
  653. /****************************************************************/
  654. capstr(s)    /* Strips leading and trailing spaces        */
  655. char    *s;    /* & raises string to CAPS            */
  656. {
  657.     int    i;
  658.     char    *p;
  659.  
  660.     p = s;
  661.     while (*p == ' ')
  662.         for ( i = 0; *(p+i); i++)
  663.             *(p+i) = *(p+i+1);
  664.     while (*p = toupper(*p)) p++;
  665.     --p;
  666.     while (*p == ' ')
  667.     {
  668.         *p = 0;
  669.         p--;
  670.     }
  671.     return s;
  672. }
  673. /****************************************************************/
  674. getyn (prom)             /* --<PROMPT 4 Y/N ANSWER>-- */
  675. char    *prom;
  676. {
  677.     char    ans;
  678.     char    ans2[2];
  679.     char    prompt[SECSIZ];
  680.  
  681.     sprintf(prompt,"%s? (Y/N)? ",prom);
  682.     outstr(prompt,5);
  683.     do
  684.     {
  685.         instr("",ans2,1);
  686.         ans = toupper(*ans2);
  687.         if (!*ans2)
  688.         {
  689.             ans = 'Y';
  690.             space(1);
  691.         }
  692.     }    while (ans != 'Y' && ans != 'N');
  693.  
  694.     if ( ans == 'Y' )
  695.         outstr("\bYES",1);
  696.     else
  697.         outstr("\bNO",1);
  698.     return (ans == 'Y' ? YES : NO);
  699. }
  700. /***************************************************************/
  701. 
  702.     while ( *p1 = tolower(*(p1++)) );
  703.  
  704.     return s;    /* Return original