home *** CD-ROM | disk | FTP | other *** search
/ Phoenix Heaven Sunny 2 / APPARE2.BIN / oh_towns / dic / src / his.c < prev    next >
C/C++ Source or Header  |  1995-06-20  |  9KB  |  437 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <string.h>
  4. #include    <ctype.h>
  5. #include    <jctype.h>
  6. #include    <dos.h>
  7.  
  8. #define    TRUE    1
  9. #define    FALSE    0
  10. #define    ERR    (-1)
  11.  
  12. #define BUF_MAX 1024            /* 256,512,1024,2048... */
  13. #define BUF_MSK (BUF_MAX-1)
  14. #define LIN_MAX (128-2)
  15.  
  16. static  int     his_pos=0;
  17. static  int     his_top=0;
  18. static  int     his_old=0;
  19. static  int     his_blk=0;
  20. static  char    *his_lin;
  21. static  char    his_buf[BUF_MAX];
  22. static  int     his_len[2]={ 0,0 };
  23. static  char    his_tmp[2][LIN_MAX+2];
  24.  
  25. static    int    ungetbuf=ERR;
  26.  
  27. #define    PUTC    putch
  28.  
  29. static    void    BEEP()
  30. {
  31.     PUTC(0x07);
  32. }
  33. static    int    GETCH()
  34. {
  35.     int     ch;
  36.  
  37.     if ( (ch = ungetbuf) != ERR ) {
  38.     ungetbuf = ERR;
  39.     return ch;
  40.     }
  41.     return getch();
  42. }
  43. static    void    UNGETCH(int ch)
  44. {
  45.     ungetbuf = ch;
  46. }
  47. static    void    FLUSH()
  48. {
  49. }
  50. static    void    REPCHR(ch,n)
  51. int     ch,n;
  52. {
  53.     while ( n-- > 0 )
  54.         PUTC(ch);
  55. }
  56. static    void    BAKSPC(n)
  57. int     n;
  58. {
  59.     while ( n-- > 0 )
  60.         PUTC(0x08);
  61. }
  62. static    void    PUTS(str,n)
  63. char    *str;
  64. int    n;
  65. {
  66.     while ( n-- > 0 )
  67.     PUTC(*(str++));
  68. }
  69. static    int     iskan(p)
  70. char    *p;
  71. {
  72.     if ( iskanji(*p) && iskanji2(*(p+1)) )
  73.         return TRUE;
  74.     else
  75.         return FALSE;
  76. }
  77. static    int     kan_pos(p,len)
  78. register char *p;
  79. int     len;
  80. {
  81.     int     i,n;
  82.  
  83.     for ( i = 0 ; *p != '\0' && i < len ; ) {
  84.         n = (iskan(p) ? 2:1);
  85.         if ( (i + n) > len )
  86.             break;
  87.         i += n;
  88.         p += n;
  89.     }
  90.     return i;
  91. }
  92. static  void    his_set(str,len)
  93. char    *str;
  94. int     len;
  95. {
  96.     int     c;
  97.  
  98.     while ( len-- > 0 && *str != '\0' ) {
  99.         his_buf[his_pos++] = *(str++);
  100.         his_pos &= BUF_MSK;
  101.         if ( his_pos == his_top ) {
  102.             do {
  103.                 c = his_buf[his_top++];
  104.                 his_top &= BUF_MSK;
  105.             } while ( his_top != his_pos && c != '\n' );
  106.         }
  107.     }
  108. }
  109. static  int     his_next(pos)
  110. int     pos;
  111. {
  112.     int     c;
  113.  
  114.     while ( pos != his_pos ) {
  115.         c = his_buf[pos++];
  116.         pos &= BUF_MSK;
  117.         if ( c == '\n' )
  118.             break;
  119.     }
  120.     return pos;
  121. }
  122. static  int     his_back(pos)
  123. int     pos;
  124. {
  125.     if ( pos == his_top )
  126.         return pos;
  127.  
  128.     pos = (pos - 1) & BUF_MSK;
  129.     while ( pos != his_top ) {
  130.         pos = (pos - 1) & BUF_MSK;
  131.         if ( his_buf[pos] == '\n' ) {
  132.             pos = (pos + 1) & BUF_MSK;
  133.             break;
  134.         }
  135.     }
  136.     return pos;
  137. }
  138. static  int     his_get(str,pos,off,max)
  139. char    *str;
  140. int     pos;
  141. int     off;
  142. int     max;
  143. {
  144.     int     i,n;
  145.  
  146.     i = 0;
  147.     while ( i < max && pos != his_pos ) {
  148.         if ( his_buf[pos] == '\n' )
  149.             break;
  150.         else if ( iskanji(his_buf[pos]) &&
  151.                   iskanji2(his_buf[(pos+1)&BUF_MSK]) )
  152.             n = 2;
  153.         else
  154.             n = 1;
  155.  
  156.         if ( (i + n) > max )
  157.             break;
  158.  
  159.         if ( i >= off ) {
  160.             i += n;
  161.             while ( n-- > 0 ) {
  162.                 *(str++) = his_buf[pos++];
  163.                 pos &= BUF_MSK;
  164.             }
  165.         } else {
  166.             pos = (pos + n) & BUF_MSK;
  167.             while ( n-- > 0 ) {
  168.                 if ( ++i > off )
  169.                     *(str++) = ' ';
  170.                 else
  171.                     str++;
  172.             }
  173.         }
  174.     }
  175.     return (i > off ? i:off);
  176. }
  177. static  int     his_cmp(pos,str,len)
  178. int     pos;
  179. char    *str;
  180. int     len;
  181. {
  182.     while ( len > 0 && *str != '\0' ) {
  183.         if ( pos == his_pos || his_buf[pos++] != *(str++) )
  184.             return FALSE;
  185.         pos &= BUF_MSK;
  186.         len--;
  187.     }
  188.     return TRUE;
  189. }
  190. char    *input(buf, max)
  191. char    *buf;
  192. int    max;
  193. {
  194.     int     ch,och,n,i;
  195.     int     pos,len,his,cps;
  196.     char    *p;
  197.  
  198.     och = ch = 0;
  199.     pos = len = cps = 0;
  200.     his = his_pos;
  201.     his_lin = his_tmp[his_blk];
  202.  
  203.     if ( max > LIN_MAX )
  204.     max = LIN_MAX;
  205.  
  206.     if ( --max < 0 ) {
  207.     his_lin[0] = '\n';
  208.     len = 1;
  209.     goto ENDOF;
  210.     }
  211.  
  212.     for ( ; ; ) {
  213.     och = ch;
  214.  
  215.         if ( (ch = GETCH()) == 0x1B )
  216.         ch = (ch << 8) | GETCH();
  217.  
  218.         switch(ch) {
  219.         case 0x08:
  220.             if ( pos > 0 ) {
  221.                 pos = kan_pos(his_lin,pos - 1);
  222.                 p = &(his_lin[pos]);
  223.                 n = (iskan(p) ? 2:1);
  224.                 memcpy(p,p + n,len - pos - n);
  225.                 len -= n;
  226.  
  227.                 BAKSPC(n);
  228.                 PUTS(p,len - pos);
  229.                 REPCHR(' ',n);
  230.                 BAKSPC(len - pos + n);
  231.             }
  232.             break;
  233.  
  234.         case 0x1B56:
  235.             if ( pos < len ) {
  236.                 p = &(his_lin[pos]);
  237.                 n = (iskan(p) ? 2:1);
  238.                 memcpy(p,p + n,len - pos - n);
  239.                 len -= n;
  240.  
  241.                 PUTS(p,len - pos);
  242.                 REPCHR(' ',n);
  243.                 BAKSPC(len - pos + n);
  244.             }
  245.             break;
  246.  
  247.         case 0x1C:
  248.             if ( pos < len ) {
  249.                 p = &(his_lin[pos]);
  250.                 n = (iskan(p) ? 2:1);
  251.                 pos += n;
  252.  
  253.                 while ( n-- > 0 )
  254.                     PUTC(*(p++));
  255.             }
  256.             break;
  257.  
  258.         case 0x1D:
  259.             if ( pos > 0 ) {
  260.                 pos = kan_pos(his_lin,pos - 1);
  261.                 p = &(his_lin[pos]);
  262.                 n = (iskan(p) ? 2:1);
  263.  
  264.                 BAKSPC(n);
  265.             }
  266.             break;
  267.  
  268.     case 0x1E:
  269.         for ( ; ; ) {
  270.         if ( his == his_top ) {
  271.             BEEP();
  272.             break;
  273.         }
  274.  
  275.         his = his_back(his);
  276.         cps = ((och == 0x1F || och == 0x1E) ? cps:pos);
  277.         if ( !his_cmp(his,his_lin,cps) )
  278.             continue;
  279.  
  280.         BAKSPC(pos);
  281.                 REPCHR(' ',len);
  282.                 BAKSPC(len);
  283.  
  284.                 pos = len = his_get(his_lin,his,0,max);
  285.  
  286.                 PUTS(his_lin,len);
  287.                 BAKSPC(len - pos);
  288.         break;
  289.             }
  290.             break;
  291.  
  292.         case 0x1F:
  293.         for ( ; ; ) {
  294.         if ( his == his_pos ) {
  295.             BEEP();
  296.             break;
  297.         }
  298.  
  299.         his = his_next(his);
  300.         cps = ((och == 0x1F || och == 0x1E) ? cps:pos);
  301.         if ( !his_cmp(his,his_lin,cps) )
  302.             continue;
  303.  
  304.                 BAKSPC(pos);
  305.                 REPCHR(' ',len);
  306.                 BAKSPC(len);
  307.  
  308.                 pos = len = his_get(his_lin,his,0,max);
  309.  
  310.                 PUTS(his_lin,len);
  311.                 BAKSPC(len - pos);
  312.         break;
  313.             }
  314.             break;
  315.  
  316.     case 0x16:
  317.         case 'R'-'@':
  318.             if ( his != his_top ) {
  319.                 his = his_back(his);
  320.  
  321.                 REPCHR(' ',len - pos);
  322.                 BAKSPC(len - pos);
  323.  
  324.                 len = his_get(his_lin,his,pos,max);
  325.  
  326.                 PUTS(&(his_lin[pos]),len - pos);
  327.                 BAKSPC(len - pos);
  328.             } else
  329.         BEEP();
  330.             break;
  331.  
  332.     case 0x17:
  333.         case 'E'-'@':
  334.             if ( his != his_pos ) {
  335.                 his = his_next(his);
  336.  
  337.                 REPCHR(' ',len - pos);
  338.                 BAKSPC(len - pos);
  339.  
  340.                 len = his_get(his_lin,his,pos,max);
  341.  
  342.                 PUTS(&(his_lin[pos]),len - pos);
  343.                 BAKSPC(len - pos);
  344.             } else
  345.         BEEP();
  346.             break;
  347.  
  348.     case 0x1B55:
  349.         case 'A'-'@':
  350.             p = &(his_lin[len]);
  351.             while ( len < max && *p != '\n' && *p != '\0' ) {
  352.                 len++;
  353.                 p++;
  354.             }
  355.             PUTS(&(his_lin[pos]),len - pos);
  356.             pos = len;
  357.             break;
  358.  
  359.         case 0x0D:
  360.             his_lin[len++] = '\n';
  361.             if ( len > 1 && !his_cmp(his_old,his_lin,len) ) {
  362.         his_old = his_pos;
  363.                 his_set(his_lin,len);
  364.         }
  365.  
  366.             PUTS(&(his_lin[pos]),len - pos);
  367.         PUTC('\r');
  368.             goto ENDOF;
  369.  
  370.         case 'X'-'@':
  371.             BAKSPC(pos);
  372.             REPCHR(' ',len);
  373.             BAKSPC(len);
  374.             pos = len = 0;
  375.             break;
  376.  
  377.     case 0x0B:
  378.         case 'D'-'@':
  379.             BAKSPC(pos);
  380.             REPCHR(' ',len);
  381.             BAKSPC(len);
  382.  
  383.             his_len[his_blk] = len;
  384.             his_blk ^= 1;
  385.             his_lin = his_tmp[his_blk];
  386.             pos = len = his_len[his_blk];
  387.  
  388.             PUTS(his_lin,len);
  389.             break;
  390.  
  391.         default:
  392.             if ( iskanji(ch) ) {
  393.                 n = GETCH();
  394.                 if ( !iskanji2(n) ) {
  395.                     UNGETCH(n);
  396.                     n = 1;
  397.                 } else {
  398.                     ch = (ch << 8) | n;
  399.                     n = 2;
  400.                 }
  401.             } else
  402.                 n = 1;
  403.  
  404.             if ( (len + n ) >= max ) {
  405.                 BEEP();
  406.                 break;
  407.             }
  408.  
  409.             if ( pos < len ) {
  410.                 p = &(his_lin[len + (n - 1)]);
  411.                 for ( i = len - pos ; i > 0 ; i--,p-- )
  412.                     *p = *(p - n);
  413.             }
  414.  
  415.             p = &(his_lin[pos]);
  416.             if ( n == 1 ) {
  417.                 his_lin[pos++] = ch;
  418.             } else {
  419.                 his_lin[pos++] = ch >> 8;
  420.                 his_lin[pos++] = ch;
  421.             }
  422.             len += n;
  423.  
  424.             PUTS(p,len - pos + n);
  425.             BAKSPC(len - pos);
  426.             break;
  427.         }
  428.         FLUSH();
  429.     }
  430.  
  431. ENDOF:
  432.     his_len[his_blk] = len;
  433.     his_lin[len] = '\0';
  434.     strcpy(buf, his_lin);
  435.     return buf;
  436. }
  437.