home *** CD-ROM | disk | FTP | other *** search
/ Hot Shareware 32 / hot34.iso / ficheros / DTOOL / INTER57E.ZIP / INTSUM16.ZIP / REFFILE.CPP < prev    next >
C/C++ Source or Header  |  1996-10-13  |  16KB  |  499 lines

  1. //********************************************************************
  2. //  REFFILE.CPP - Handle RefFile display, searching, etc.             
  3. //                                                                    
  4. //  Copyright (c) 1996 Daniel D. Miller                               
  5. //                                                                    
  6. //  Last Update:  09-04-95 11:18pm                                    
  7. //                                                                    
  8. //  Compile with makefile                                             
  9. //                                                                    
  10. //********************************************************************
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <dos.h>
  16. #include "intsum.hpp"
  17. #include "err_exit.hpp"
  18. // #include <memcheck.h>
  19.  
  20. //*****************************************************************
  21. void fill_ref_buffers(fpos_t pos)
  22.    {
  23.    //  adjust input-file position
  24.    fsetpos(index, &pos) ;
  25.    ref.hdptr[0] = pos ;
  26.  
  27.    // read data and fill ref_list buffer 0
  28.    ref.lines[0] = fill_ref_bfr(0) ; //  fill forward buffer
  29.  
  30.    // read data and fill ref_list buffer 1
  31.    ref.hdptr[1] = ref.tlptr[0] ;
  32.    ref.lines[1] = fill_ref_bfr(1) ; //  fill aft buffer
  33.    }
  34.  
  35. //*****************************************************************
  36. //  first, search current ref buffer(s) starting at ref.offset.
  37. //*****************************************************************
  38. int search_ref_buffers(char *srchstr)
  39.    {
  40.    unsigned sline = ref.offset + (ivideo.currow - DATA_TOP) + 1 ;
  41.    int srch_done ;
  42.    //  first, search ref.bfr0 if active
  43.    if (ref.cur_bfr == 0) 
  44.       {
  45.       if (sline > ref.lines[0]) 
  46.          {
  47.          sline -= ref.lines[0] ;
  48.          }
  49.       else 
  50.          {
  51.          srch_done = 0 ;
  52.          while (!srch_done) 
  53.             {
  54.             //  If string is found, update buffers and move cursor
  55.             if (strstri(ref.bfr[0][sline].idx.data, srchstr) == 0) 
  56.                {
  57.                ref.offset = sline ;
  58.                //  I _think_ this is the correct position
  59.                search.offset = sline ;
  60.                ref.offset = sline ;
  61.  
  62.                ivideo.currow = DATA_TOP ;
  63.                display_ref_file() ;
  64.                return 0;
  65.                }
  66.             //  string is not yet found; move along in buffer0
  67.             //  if at end of buffer, exit and try buffer 1.
  68.             else if (++sline >= ref.lines[0]) 
  69.                {
  70.                srch_done = 1 ;
  71.                sline = 0 ;
  72.                }
  73.             }  //  while not done searching
  74.          }
  75.       }
  76.  
  77.    //  then, search ref.bfr1 if active, and nothing found in 0
  78.    if (ref.lines[1] > 0) 
  79.       {
  80.       srch_done = 0 ;
  81.       while (!srch_done) 
  82.          {
  83.          //  If string is found, update buffers and move cursor
  84.          if (strstri(ref.bfr[1][sline].idx.data, srchstr) == 0) 
  85.             {
  86.             search.offset = sline ;
  87.             ref.cur_bfr = 1 ;
  88.             ref.offset = sline ;
  89.             ivideo.currow = DATA_TOP ;
  90.             display_ref_file() ;
  91.             return 0;
  92.             }
  93.          //  string is not yet found; move along in buffer1.
  94.          //  if at end of buffer, exit and try other buffers.
  95.          else if (++sline >= ref.lines[1]) 
  96.             {
  97.             srch_done = 1 ;
  98.             sline = 0 ;
  99.             }
  100.          }  //  while not done searching
  101.       }  //  if any lines are in buffer1, search it
  102.  
  103.    return -1 ;
  104.    }
  105.  
  106. //*****************************************************************
  107. //  current buffers have already been searched, with nothing found.
  108. //  Now, search ref file starting at ref.tlptr[1].
  109. //*****************************************************************
  110. void search_ref_file(char *srchstr)
  111.    {
  112.    //  first, save current file pointer so it
  113.    //  can be restored if no match is found.
  114.    fpos_t oldpos ;
  115.    fgetpos(index, &oldpos) ;
  116.  
  117.    //  position file pointer to current cursor position
  118.    search.hdptr = ref.tlptr[1] ;
  119.    fsetpos(index, &search.hdptr) ;
  120.    //  move past it to current line (if possible)
  121.  
  122.    //  fill the readbfr from ref file
  123.    unsigned rlines = fill_search_buffer(index) ;
  124.    if (rlines == 0) 
  125.       {
  126.       message_show("Your search string was not found") ;
  127.       return ;
  128.       }
  129.  
  130.    unsigned sline = 0 ;
  131.    int srch_done = 0 ;
  132.    while (!srch_done) 
  133.       {
  134.       //  If string is found, update buffers and move cursor
  135.       if (strstri(search.bfr[sline].idx.data, srchstr) == 0) 
  136.          {
  137.          // read real data from beginning of current block
  138.          fsetpos(index, &search.hdptr) ;
  139.          ref.hdptr[0] = search.hdptr ;
  140.          fill_ref_buffers(search.hdptr) ;
  141.  
  142.          //  I _think_ this is the correct position
  143.          search.offset = sline ;
  144.          ref.offset = sline ;
  145.          ref.cur_bfr = 0 ;
  146.  
  147.          ivideo.currow = DATA_TOP ;
  148.          display_ref_file() ;
  149.          srch_done = 1 ;
  150.          }
  151.       //  string is not yet found; move along in readbfr.
  152.       //  if at end of buffer, read next buffer or fail.
  153.       else if (++sline >= rlines) 
  154.          {
  155.          search.hdptr = search.tlptr ;
  156.          rlines = fill_search_buffer(index) ;
  157.          if (rlines == 0) 
  158.             {
  159.             //  restore input-file position
  160.             fsetpos(index, &oldpos) ;
  161.             srch_done = -1 ;
  162.             message_show("Your search string was not found") ;
  163.             }
  164.          else 
  165.             {
  166.             sline = 0 ;
  167.             }
  168.          }
  169.       }  //  while not done searching
  170.    }
  171.  
  172. //*****************************************************************
  173. void scroll_page_down(void)
  174.    {
  175.    //  if cursor is NOT at top, move cursor
  176.    if (ivideo.currow > DATA_TOP) 
  177.       {
  178.       ivideo.currow-- ;
  179.       }
  180.  
  181.    //  if cursor IS at top, try to move up in current buffer
  182.    else if (ref.offset > 0)  //  scroll window down
  183.       {
  184.       ref.offset-- ;
  185.       display_ref_file() ;
  186.       }
  187.  
  188.    //  if current buffer is 1, just move back to buffer 0
  189.    else if (ref.cur_bfr == 1)
  190.       {
  191.       ref.cur_bfr = 0 ;
  192.       ref.offset = ref.lines[0] - 1 ;
  193.       display_ref_file() ;
  194.       }
  195.  
  196.    //  if current buffer = 0, see if we're at beginning of file.
  197.    //  if so, do nothing; otherwise, try to read back in buffer,
  198.    //  after copying buffer 0 to buffer 1.
  199.    else if (ref.hdptr[0] > 0) 
  200.       {
  201.       //  copy buffer0 values to buffer1
  202.  
  203.       //  swap the buffer pointers
  204.       sum_conv *b ;
  205.       b          = ref.bfr[0] ;
  206.       ref.bfr[0] = ref.bfr[1] ;
  207.       ref.bfr[1] = b ;
  208.  
  209.       ref.lines[1] = ref.lines[0] ;
  210.       ref.hdptr[1] = ref.hdptr[0] ;
  211.       ref.tlptr[1] = ref.tlptr[0] ;
  212.       //  current buffer remains 0.
  213.       // ref.cur_bfr = 0 ;
  214.  
  215.       //  then compute and read new data into buffer0
  216.       fill_ref_bfr_rev() ; //  fill forward buffer
  217.       ref.offset-- ;
  218.       display_ref_file() ;
  219.       }
  220.    }
  221.  
  222. //*****************************************************************
  223. void scroll_page_up(void)
  224.    {
  225.    // end_line is line number for NEXT line
  226.    unsigned end_line = ref.offset + window_rows ; //  base-0
  227.  
  228.    //  if still onscreen, just move cursor
  229.    if (ivideo.currow+1 < screen_rows) 
  230.       {
  231.       ivideo.currow++ ;
  232.       }
  233.  
  234.    //  end of screen...
  235.    //  see if there's still room in buffer to move cursor
  236.    else if (end_line < ref.lines[ref.cur_bfr])
  237.          //   ^base-0        ^base-1     
  238.       {
  239.       ref.offset++ ;
  240.       display_ref_file() ;
  241.       }
  242.  
  243.    //  we are at end of buffer
  244.  
  245.    //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  246.    //                      BUFFER 0                             
  247.    //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  248.    else if (ref.cur_bfr == 0) 
  249.    //  If we're in buffer0, we should be able to slop over
  250.    //  into buffer1, if there's any data in it.
  251.       {
  252.       //  if we were previously in buffer0, but now (after     
  253.       //  adding one line) we don't fit in buffer0+buffer1,    
  254.       //  there were less than (screen_size) lines in buffer1, 
  255.       //  which means we're at end of file (otherwise, we      
  256.       //  would have read roughly 32Kbytes).                   
  257.       //                                                       
  258.       //  NOTE: we do not currently handle scrolling           
  259.       //        across multiple files.                         
  260.       //                                                       
  261.       if (end_line >= (ref.lines[0] + ref.lines[1])) 
  262.          {
  263.          //  do nothing for now...
  264.          //  Later, we'll add multiple-file support.
  265.          }
  266.       //  If there is room in the two combined files, see if
  267.       //  moving to next line has thrown us COMPLETELY into buffer1.
  268.       else if ((ref.offset+1) == ref.lines[0])
  269.          {
  270.          ref.offset = 0 ;
  271.          ref.cur_bfr = 1 ;
  272.          display_ref_file() ;
  273.          }
  274.       //  otherwise, we're overlapping two files, 
  275.       //  the ref function supports internally.
  276.       else
  277.          {
  278.          ref.offset++ ;
  279.          display_ref_file() ;
  280.          }
  281.       }
  282.  
  283.    //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  284.    //                      BUFFER 1                             
  285.    //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  286.    //  if NOT at end of buffer 1, update array offset and redraw
  287.    else if (end_line < ref.lines[1]) 
  288.       {
  289.       ref.offset++ ;
  290.       display_ref_file() ;
  291.       }
  292.    //  if we reach end of buffer 1, 
  293.    //  copy buffer 1 to buffer 0 and see if
  294.    //  there's more data to scroll into.
  295.    else 
  296.       {
  297.       back_up_buffer1() ;
  298.       if (ref.lines[1] > 0) 
  299.          {
  300.          ref.offset++ ;
  301.          display_ref_file() ;
  302.          }
  303.       }
  304.    }
  305.  
  306. //*****************************************************************
  307. //  copy ref buffer 1 to ref buffer 0,
  308. //  then refill ref buffer 1
  309. //*****************************************************************
  310. void back_up_buffer1(void)
  311.    {
  312.    //  swap the buffer pointers
  313.    sum_conv *b  = ref.bfr[0] ;
  314.    ref.bfr[0]   = ref.bfr[1] ;
  315.    ref.bfr[1]   = b ;
  316.    //  copy buffer1 data to buffer0 struct
  317.    ref.lines[0] = ref.lines[1] ;
  318.    ref.hdptr[0] = ref.hdptr[1] ;
  319.    ref.tlptr[0] = ref.tlptr[1] ;
  320.    ref.cur_bfr  = 0 ;
  321.    ref.hdptr[1] = ref.tlptr[0] ;
  322.  
  323.    //  read new data into buffer1
  324.    ref.lines[1] = fill_ref_bfr(1) ;
  325.    }
  326.  
  327. //*****************************************************************
  328. void display_ref_file(void)
  329.    {
  330.    unsigned new_top, j, buffer_left = ref.lines[ref.cur_bfr] - ref.offset ;
  331.            //     ^base-1            ^base-1             ^base-0
  332.  
  333.    //  if current buffer fits entirely onscreen
  334.    if (window_rows <= buffer_left) 
  335.       {
  336.       for (j=0; j<window_rows; j++) 
  337.          {
  338.          dprints(0, DATA_TOP+j, MAIN_TEXT, 
  339.             ref.bfr[ref.cur_bfr][ref.offset+j].idx.data) ;
  340.          }
  341.       }
  342.  
  343.    //  if we're currently using buffer 0, just lop over into bfr 1.
  344.    //  Fill any unused lines with blank lines.
  345.    else if (ref.cur_bfr == 0)
  346.       {
  347.       if (window_rows > (buffer_left + ref.lines[1])) 
  348.          //  ^base1        ^base1         ^base1
  349.          {
  350.          //  draw remainder of buffer0
  351.          for (j=0; j<buffer_left; j++) 
  352.             {
  353.             dprints(0, DATA_TOP+j, MAIN_TEXT, 
  354.                ref.bfr[0][ref.offset+j].idx.data) ;
  355.             }
  356.          //  draw all of buffer1
  357.          new_top = DATA_TOP + buffer_left ;
  358.          for (j=0; j<ref.lines[1]; j++) 
  359.             {
  360.             dprints(0, new_top++, MAIN_TEXT, ref.bfr[1][j].idx.data) ;
  361.             }
  362.          //  draw blank lines
  363.          spaces[80] = 0 ;
  364.          while (new_top < screen_rows) 
  365.             {
  366.             dprints(0, new_top++, MAIN_TEXT, spaces) ;
  367.             }
  368.          spaces[80] = ' ' ;
  369.          }
  370.       else 
  371.          {
  372.          for (j=0; j<buffer_left; j++) 
  373.             {
  374.             dprints(0, DATA_TOP+j, MAIN_TEXT, 
  375.                ref.bfr[0][ref.offset+j].idx.data) ;
  376.             }
  377.          for (j=0; j<(window_rows-buffer_left); j++) 
  378.             {
  379.             dprints(0, DATA_TOP+buffer_left+j, MAIN_TEXT, 
  380.                ref.bfr[1][j].idx.data) ;
  381.             }
  382.          }
  383.       }
  384.  
  385.    //  we're at end of buffer 1
  386.    else 
  387.       {
  388.       //  copy bfr1 to bfr0, then refill bfr1
  389.       back_up_buffer1() ;
  390.  
  391.       //  recursive call to this routine
  392.       display_ref_file() ;
  393.       }
  394.    }
  395.  
  396. //*****************************************************************
  397. //  parse lines from input file.
  398. //*****************************************************************
  399. unsigned fill_ref_bfr(unsigned bfr_flag)
  400.    {
  401.    int done = 0 ;
  402.    //lint -e740
  403.    unsigned offseti = FP_OFF(readptr) ;   // init value for byte tfr counter
  404.    unsigned offsetf ;
  405.    unsigned count = 0, j ;
  406.  
  407.    //  fill the readbfr from ref file
  408.    unsigned rlines = fill_read_buffer(index) ;
  409.    if (rlines == 0) 
  410.       return 0;
  411.  
  412.    //  now, translate the read buffer into the ref-list buffer
  413.    unsigned lcount = isl_lines ;
  414.    char *sptr = readptr ;
  415.    while (!done) 
  416.       {
  417.       unsigned slen = strlen(sptr) ;
  418.       strcpy(ref.bfr[bfr_flag][count].instr, sptr) ;
  419.  
  420.       //  pad short lines with spaces
  421.       if (slen < sizeof(sum_conv)) 
  422.          {
  423.          for (j=slen; j<last_ref_char; j++) 
  424.             ref.bfr[bfr_flag][count].instr[j] = ' ' ;
  425.          //  now, NULL-terminate the line
  426.          ref.bfr[bfr_flag][count].instr[last_ref_char] = 0 ;
  427.          }
  428.  
  429.       //  point to next string in buffer
  430.       sptr += slen ;
  431.       while (*sptr == 0)  sptr++ ;   //  seek beginning of next line
  432.  
  433.       count++ ;
  434.       //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  435.       //  If this terminates on lcount, rather than rlines, 
  436.       //  the input buffer will have to be adjusted
  437.       //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  438.       if (--lcount == 0  ||  count == rlines) 
  439.          {
  440.          done = 1 ;
  441.          //  set tail-pointer variable in current ref struct
  442.          offsetf = FP_OFF(sptr) ;   //lint !e740
  443.          ref.tlptr[bfr_flag] = ref.hdptr[bfr_flag]
  444.                                  + (offsetf - offseti) ;
  445.          //  adjust input-file position
  446.          fpos_t pos = ref.tlptr[bfr_flag] ;
  447.          fsetpos(index, &pos) ;
  448.          }
  449.       }
  450.  
  451.    return count;
  452.    }
  453.  
  454. //*****************************************************************
  455. //  parse lines from input file, after reading 
  456. //  BACK from current file position.
  457. //  This is always performed on buffer0.
  458. //  It is assumed that buffer0 struct has already
  459. //  been copied to buffer 1.
  460. //*****************************************************************
  461. void fill_ref_bfr_rev(void)
  462.    {
  463.    //  make a copy of current line before overwriting it,
  464.    //  so we can find it again afterwards
  465.    strcpy(oldstr, ref.bfr[1][ref.offset].instr) ;
  466.    if (strlen(oldstr) == 0) 
  467.       error_exit(BAD_FORMAT, NULL) ;
  468.  
  469.    //  figure out how far to back up the read pointer
  470.    fpos_t pos = IFF   (ref.hdptr[0] > REV_SIZE) 
  471.                 THENN (ref.hdptr[0] - REV_SIZE)
  472.                 ELSSE 0 ;
  473.  
  474.    //  adjust input-file position and fill ref buffers
  475.    fsetpos(index, &pos) ;
  476.    int icount = seek_next_line(index) ;
  477.    if (icount < 0)
  478.       error_exit(BAD_SEARCH, NULL) ;
  479.    pos += icount ;
  480.    fill_ref_buffers(pos) ;
  481.  
  482.    //  now that new buffers have been read, 
  483.    //  seek to the current line and update ref.offset
  484.    unsigned count = 0 ;
  485.    int done = 0 ;
  486.    while (!done) 
  487.       {
  488.       if (strncmp(oldstr, ref.bfr[0][count].instr, 9) == 0) 
  489.          {
  490.          ref.offset = count ;
  491.          done = 1 ;
  492.          }
  493.       else if (++count >= ref.lines[0])
  494.          error_exit(BAD_SEARCH, NULL) ; 
  495.       }
  496.    }
  497.  
  498.  
  499.