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

  1. /********************************************
  2.  
  3.     文書デ-タの取得
  4.  
  5. *********************************************/
  6. #include    "defs.h"
  7.  
  8. static    int    cd_stat = 0;
  9. static    int    cd_ank_mode = FALSE;
  10. static    int    cd_left_spc = 0;
  11. static    int    cd_eof_flag = FALSE;
  12. static    int    cd_attr = 0;
  13.  
  14. static    int    cd_bak_char = ERR;
  15. static    int    cd_bak_data = ERR;
  16.  
  17. static    uchar    *cd_mac_str = NULL;
  18.  
  19. static    POINT    sub_pos;
  20.  
  21.     int    menu_max = 0;
  22.     int    betu_max = 0;
  23.  
  24.     MENUPTR *menu_top = NULL;
  25.     MENUPTR    *betu_top = NULL;
  26.  
  27.     MENUPTR    menu_tab[MENU_MAX];
  28.     MENUPTR    betu_tab[BETU_MAX];
  29.  
  30. static    int    cd_getc()
  31. {
  32.     int     ch;
  33.  
  34.     if ( cd_bak_char != ERR ) {
  35.     ch = cd_bak_char;
  36.     cd_bak_char = ERR;
  37.     return ch;
  38.     }
  39.     return IO_getc();
  40. }
  41. static    void    cd_ungetc(int ch)
  42. {
  43.     cd_bak_char = ch;
  44. }
  45. static    int    cd_getw()
  46. {
  47.     int   ch;
  48.  
  49.     ch = cd_getc() << 8;
  50.     ch |= cd_getc();
  51.     return ch;
  52. }
  53. static    ushort    cd_get_short(int len)
  54. {
  55.     int     c;
  56.     ushort  n = 0;
  57.  
  58.     while ( len-- > 0 ) {
  59.     if ( (c = cd_getc()) == EOF )
  60.         break;
  61.     n = n * 10 + (c >> 4);
  62.     n = n * 10 + (c & 0x0F);
  63.     }
  64.     return n;
  65. }
  66. static    ulong    cd_get_long(int len)
  67. {
  68.     int     c;
  69.     ulong   n = 0;
  70.  
  71.     while ( len-- > 0 ) {
  72.     if ( (c = cd_getc()) == EOF )
  73.         break;
  74.     n = n * 10 + (c >> 4);
  75.     n = n * 10 + (c & 0x0F);
  76.     }
  77.     return n;
  78. }
  79. static    int    cd_get_col()
  80. {
  81.     int     c;
  82.     int     n = 0;
  83.  
  84.     while ( (c = cd_getc()) == 0x1E ) {
  85.     if ( (c = cd_getc()) == EOF )
  86.         break;
  87.     n = n * 10 + (c >> 4);
  88.     n = n * 10 + (c & 0x0F);
  89.     }
  90.     cd_ungetc(c);
  91.     return n;
  92. }
  93. int    cd_get_data()
  94. {
  95.     uint   ch;
  96.  
  97.     if ( cd_eof_flag )
  98.     return EOF;
  99.  
  100. RESTART:
  101.     if ( cd_bak_data != ERR ) {
  102.     ch = cd_bak_data;
  103.     cd_bak_data = ERR;
  104.     return ch;
  105.     }
  106.  
  107.     if ( cd_mac_str != NULL ) {
  108.     if ( (ch = *(cd_mac_str++)) != '\0' ) {
  109.         if ( iskanji(ch) && iskanji2(*cd_mac_str) )
  110.         ch = (ch << 8) | (*(cd_mac_str++) & 0xFF);
  111.         return ch;
  112.     }
  113.     cd_mac_str = NULL;
  114.     }
  115.  
  116. NEXT:
  117.     if ( (ch = cd_getw()) == EOF ) {
  118.     ch = EOF;
  119.     goto ENDOF;
  120.     }
  121.  
  122.     if ( ch >= 0x2121 ) {
  123.     if ( cutof_flag == FALSE && cd_stat == 3 ) {
  124.         ch = EOF;
  125.         goto ENDOF;
  126.     }
  127.  
  128.     if ( ch >= 0xA121u ) {    /* 外字文字 */
  129.         ch |= (cd_ank_mode ? 0x0080:0x0000);
  130.         if ( (cd_mac_str = Gaiji_convert(&ch)) != NULL )
  131.         goto RESTART;
  132.     }
  133.  
  134.     ch = jistosjis(ch);
  135.  
  136.     if ( cd_ank_mode )
  137.         ch = zentohan(ch);
  138.  
  139. #ifdef    EUC
  140.     if ( (ch & 0xFF00) != 0 )
  141.         ch = jistoeuc(sjistojis(ch));
  142. #endif    /* EUC */
  143.  
  144.     } else {
  145.         switch(ch) {
  146.         case 0x0000:
  147.         ch = EOF;
  148.         break;
  149.  
  150.         case 0x1F02:        /* 表示開始指定 */
  151.         goto NEXT;
  152.         case 0x1F03:        /* 表示終了指定 */
  153.         ch = EOF;
  154.         break;
  155.  
  156.         case 0x1F04:        /* 半角開始指定 */
  157.         cd_ank_mode = TRUE;
  158.         goto NEXT;
  159.         case 0x1F05:        /* 半角終了指定 */
  160.         cd_ank_mode = FALSE;
  161.         goto NEXT;
  162.  
  163.         case 0x1F06:        /* ルビ開始指定 */
  164.         case 0x1F07:        /* ルビ終了指定 */
  165.         goto NEXT;
  166.  
  167.         case 0x1F09:        /* 字下げ指定 */
  168.         cd_left_spc = (cd_get_short(2) - 1) * 2;
  169.         goto NEXT;
  170.  
  171.         case 0x1F0A:        /* 改行指定 */
  172.         switch(cd_stat) {
  173.         case 0: cd_stat = 1; break;
  174.         case 1: cd_stat = 2; break;
  175.         }
  176.         ch = '\n';
  177.         break;
  178.  
  179.         case 0x1F0E:        /* 添字上開始指定 */
  180.         case 0x1F0F:        /* 添字上終了指定 */
  181.         case 0x1F10:        /* 分割禁止開始指定 */
  182.         case 0x1F11:        /* 分割禁止終了指定 */
  183.         goto NEXT;
  184.         case 0x1F12:        /* 強調開始指定 */
  185.         ch = CH_BOLD_ON;
  186.         break;
  187.         case 0x1F13:        /* 強調終了指定 */
  188.         ch = CH_BOLD_OFF;
  189.         break;
  190.  
  191.         case 0x1F14:        /* 色指定開始指定 */
  192.         cd_get_col();
  193.         case 0x1F15:        /* 色指定終了指定 */
  194.         goto NEXT;
  195.  
  196.         case 0x1FE0:        /* 拡張強調表示開始指定 */
  197.         cd_get_short(2);
  198.         ch = CH_BOLD_ON;
  199.         break;
  200.         case 0x1FE1:        /* 拡張強調表示終了指定 */
  201.         ch = CH_BOLD_OFF;
  202.         break;
  203.  
  204.         case 0x1FE2:        /* 保護開始指定 */
  205.         cd_get_short(2);
  206.         case 0x1FE3:        /* 保護終了指定 */
  207.         goto NEXT;
  208.  
  209.         case 0x1F41:        /* 検索キ-識別子 */
  210.         switch(cd_stat) {
  211.         case 0: cd_stat = 1; break;
  212.         case 2: cd_stat = 3; break;
  213.         }
  214.         cd_getw();
  215.         ch = CH_BOLD_ON;
  216.         break;
  217.         case 0x1F61:        /* 検索キ-終了識別子 */
  218.         ch = CH_BOLD_OFF;
  219.         break;
  220.  
  221.         case 0x1F42:        /* 別項目参照識別子 */
  222.         break;
  223.         case 0x1F62:        /* 別項目参照終了識別子 */
  224.         sub_pos.block  = cd_get_long(4);        /* Block No */
  225.         sub_pos.offset = cd_get_short(2);        /* Offset */
  226.         break;
  227.  
  228.         case 0x1F43:        /* メニュ-識別子 */
  229.         break;
  230.         case 0x1F63:        /* メニュ-終了識別子 */
  231.         sub_pos.block  = cd_get_long(4);
  232.         sub_pos.offset = cd_get_short(2);
  233.         break;
  234.  
  235.         case 0x1F44:        /* 図版デ-タ識別子 */
  236.         cd_get_short(2);        /* 図版再生法識別 */
  237.         cd_get_long(4);        /* 縦ドット数 */
  238.         cd_get_long(4);        /* 横ドット数 */
  239.         goto NEXT;
  240.         case 0x1F64:        /* 図版デ-タ終了識別子 */
  241.         sub_pos.block  = cd_get_long(4);        /* Block No */
  242.         sub_pos.offset = cd_get_short(2);        /* Offset */
  243.         goto NEXT;
  244.  
  245.         case 0x1F45:        /* 図版デ-タ群識別子 */
  246.         case 0x1F65:        /* 図版デ-タ群終了識別子 */
  247.         goto NEXT;
  248.  
  249.         case 0x1F46:        /* 図版メニュ-識別子 */
  250.         goto NEXT;
  251.         case 0x1F66:        /* 図版メニュ-終了識別子 */
  252.         sub_pos.block  = cd_get_long(4);        /* Block No */
  253.         sub_pos.offset = cd_get_short(2);        /* Offset */
  254.         goto NEXT;
  255.  
  256.         case 0x1F47:        /* 色見本メニュ-識別子 */
  257.         goto NEXT;
  258.         case 0x1F67:        /* 色見本メニュ-終了識別子 */
  259.         cd_get_col();
  260.         goto NEXT;
  261.  
  262.         case 0x1F48:        /* 音声デ-タ識別子 */
  263.         cd_get_short(2);        /* トラック番号 */
  264.         cd_get_long(4);        /* 先頭アドレス */
  265.         cd_get_long(4);        /* 容量 */
  266.         goto NEXT;
  267.         case 0x1F68:        /* 音声デ-タ終了識別子 */
  268.         goto NEXT;
  269.  
  270.         default:
  271. #ifdef    DEBUG
  272.     printf("Unkow Code %04x\n", ch);
  273. #endif
  274.         ch = '?';
  275.         break;
  276.         }
  277.     }
  278.  
  279. ENDOF:
  280.     if ( ch == EOF )
  281.     cd_eof_flag = TRUE;
  282.  
  283.     return ch;
  284. }
  285. static    void    cd_unget_data(int ch)
  286. {
  287.     cd_bak_data = ch;
  288. }
  289. char    *cd_gets(char *buf, int max, int line)
  290. {
  291.     int     ch, n;
  292.     int     len = 0;
  293.     int     attr = 0;
  294.  
  295.     while ( len < max ) {
  296.  
  297.     if ( (ch = cd_get_data()) == EOF ) {
  298.         if ( len == 0 )
  299.             return NULL;
  300.         break;
  301.     }
  302.  
  303.     if ( ch == '\n' )
  304.         break;
  305.  
  306.     while ( len < cd_left_spc && len < max )
  307.         buf[len++] = ' ';
  308.  
  309.     n = (ch & 0xFF00) != 0 ? 2:1;
  310.     if ( (len + n) > max ) {
  311.         cd_unget_data(ch);
  312.         break;
  313.     }
  314.  
  315.         if ( ch == 0x1F43 ) {            /* メニュ-識別子 */
  316.         if ( menu_max >= MENU_MAX )
  317.         continue;
  318.         menu_tab[menu_max].sx = len;
  319.         menu_tab[menu_max].sy = line;
  320.         menu_tab[menu_max].next = menu_top;
  321.         menu_top = &(menu_tab[menu_max]);
  322.         menu_max++;
  323.         continue;
  324.  
  325.     } else if ( ch == 0x1F63 ) {        /* メニュ-終了識別子 */
  326.         if ( menu_top == NULL )
  327.         continue;
  328.         menu_top->bx = len;
  329.         menu_top->by = line;
  330.         menu_top->pos.block  = sub_pos.block;
  331.         menu_top->pos.offset = sub_pos.offset;
  332.         if ( menu_top->sx == len &&
  333.          menu_top->sy == line ) {
  334.         menu_top->bx = len + 2;
  335.         ch = 0x819E;        /* ◇ */
  336. #ifdef    EUC
  337.         ch = jistoeuc(sjistojis(ch));
  338. #endif    /* EUC */
  339.         menu_top = menu_top->next;
  340.         } else {
  341.         menu_top = menu_top->next;
  342.             continue;
  343.         }
  344.  
  345.     } else if ( ch == 0x1F42 ) {        /* 別項目参照識別子 */
  346.         if ( betu_max >= BETU_MAX )
  347.         continue;
  348.         betu_tab[betu_max].sx = len;
  349.         betu_tab[betu_max].sy = line;
  350.         betu_tab[betu_max].next = betu_top;
  351.         betu_top = &(betu_tab[betu_max]);
  352.         betu_max++;
  353.         ch = CH_ITALIC_ON;
  354.         n = 1;
  355.  
  356.     } else if ( ch == 0x1F62 ) {        /* 別項目参照終了識別子 */
  357.         if ( betu_top == NULL )
  358.         continue;
  359.         betu_top->bx = len;
  360.         betu_top->by = line;
  361.         betu_top->pos.block  = sub_pos.block;
  362.         betu_top->pos.offset = sub_pos.offset;
  363.         if ( betu_top->sx == len &&
  364.          betu_top->sy == line ) {
  365.         betu_top->bx = len + 2;
  366.         betu_top = betu_top->next;
  367.         ch = ('#' << 8) | CH_ITALIC_OFF;
  368.         n = 2;
  369.  
  370.         } else {
  371.         betu_top = betu_top->next;
  372.         ch = CH_ITALIC_OFF;
  373.             n = 1;
  374.         }
  375.     }
  376.  
  377.     switch(ch) {
  378.     case CH_BOLD_ON:    cd_attr |= 1; break;
  379.     case CH_BOLD_OFF:   cd_attr &= 2; break;
  380.     case CH_ITALIC_ON:  cd_attr |= 2; break;
  381.     case CH_ITALIC_OFF: cd_attr &= 1; break;
  382.     default:
  383.         if ( (cd_attr & 0x01) != (attr & 0x01) )
  384.         buf[len++] = (cd_attr & 1) == 0 ? CH_BOLD_OFF:CH_BOLD_ON;
  385.         if ( (cd_attr & 0x02) != (attr & 0x02) )
  386.         buf[len++] = (cd_attr & 2) == 0 ? CH_ITALIC_OFF:CH_ITALIC_ON;
  387.         attr = cd_attr;
  388.         if ( n == 2 )
  389.             buf[len++] = (char)(ch >> 8);
  390.         buf[len++] = (char)(ch);
  391.         break;
  392.     }
  393.     }
  394.     if ( (attr & 1) != 0 )
  395.     buf[len++] = CH_BOLD_OFF;
  396.     if ( (attr & 2) != 0 )
  397.     buf[len++] = CH_ITALIC_OFF;
  398.     buf[len++] = '\n';
  399.     buf[len] = '\0';
  400.  
  401.     return buf;
  402. }
  403. int    dic_seek(ulong block, ushort offset)
  404. {
  405.     cd_stat = 0;
  406.     cd_ank_mode = FALSE;
  407.     cd_left_spc = 0;
  408.     cd_eof_flag = FALSE;
  409.     cd_attr     = 0;
  410.  
  411.     menu_max = betu_max = 0;
  412.     menu_top = betu_top = NULL;
  413.  
  414.     cd_bak_char = ERR;
  415.     cd_bak_data = ERR;
  416.  
  417.     return IO_seek(block, offset);
  418. }
  419.