home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / tde221.zip / DIFF.C < prev    next >
C/C++ Source or Header  |  1993-04-01  |  24KB  |  732 lines

  1. /*
  2.  * Being that the windows in TDE are numbered and lettered, we can easily
  3.  * prompt for windows to diff.  Might as well do a few standard diff
  4.  * options:  ignore leading space, ignore all space, ignore blank lines,
  5.  * ignore end-of-line, and Ignore/Match case.  Once the diff is defined,
  6.  * just press one key to find the next diff.  Any two visible windows may
  7.  * be diffed, which is really nice for comparing similar functions or
  8.  * data in seperate areas of a file.
  9.  *
  10.  *
  11.  * New editor name:  TDE, the Thomson-Davis Editor.
  12.  * Author:           Frank Davis
  13.  * Date:             June 5, 1991, version 1.0
  14.  * Date:             July 29, 1991, version 1.1
  15.  * Date:             October 5, 1991, version 1.2
  16.  * Date:             January 20, 1992, version 1.3
  17.  * Date:             February 17, 1992, version 1.4
  18.  * Date:             April 1, 1992, version 1.5
  19.  * Date:             June 5, 1992, version 2.0
  20.  * Date:             October 31, 1992, version 2.1
  21.  * Date:             April 1, 1993, version 2.2
  22.  *
  23.  * This code is released into the public domain, Frank Davis.
  24.  * You may distribute it freely.
  25.  */
  26.  
  27. #include "tdestr.h"
  28. #include "common.h"
  29. #include "define.h"
  30. #include "tdefunc.h"
  31.  
  32.  
  33. /*
  34.  * Name:    define_diff
  35.  * Purpose: get info needed to initialize diff
  36.  * Date:    October 31, 1992
  37.  * Passed:  window:  pointer to current window
  38.  * Notes:   allow the user to start the diff at the beginning of the
  39.  *            file or at the current cursor location.  once the diff
  40.  *            has been defined, the user may press one key to diff again.
  41.  *          user may diff any two visible windows on the screen.
  42.  */
  43. int  define_diff( WINDOW *window )
  44. {
  45. int  rc;
  46. char temp[MAX_COLS];
  47. int  num1;
  48. int  let1;
  49. int  num2;
  50. int  let2;
  51. int  start;
  52. char line_buff[(MAX_COLS+1)*2];  /* buffer for char and attribute  */
  53. char buff[MAX_COLS*2];           /* buffer for char and attribute  */
  54.  
  55.    /*
  56.     * get window number and letter of the first diff window.  then,
  57.     *   verify that window - does it exit? is it visible?
  58.     */
  59.    *temp = '\0';
  60.    rc = get_name( diff_prompt1, window->bottom_line, temp,
  61.                   g_display.message_color );
  62.    if (rc == OK) {
  63.       rc = verify_number( temp, &num1 );
  64.       if (rc == OK)
  65.          rc = verify_letter( temp, &let1, &diff.w1 );
  66.    } else
  67.       return( ERROR );
  68.    if (rc == ERROR) {
  69.       combine_strings( buff, diff_prompt6a, temp, diff_prompt6b );
  70.       error( WARNING, window->bottom_line, buff );
  71.       return( ERROR );
  72.    }
  73.  
  74.    /*
  75.     * get and verify the next window number and letter to diff.
  76.     */
  77.    *temp = '\0';
  78.    rc = get_name( diff_prompt2, window->bottom_line, temp,
  79.                   g_display.message_color );
  80.    if (rc == OK) {
  81.       rc = verify_number( temp, &num2 );
  82.       if (rc == OK)
  83.          rc = verify_letter( temp, &let2, &diff.w2 );
  84.    } else
  85.       return( ERROR );
  86.    if (rc == ERROR) {
  87.       combine_strings( buff, diff_prompt6a, temp, diff_prompt6b );
  88.       error( WARNING, window->bottom_line, buff );
  89.       return( ERROR );
  90.    }
  91.  
  92.    /*
  93.     * are leading spaces significant?
  94.     */
  95.    save_screen_line( 0, window->bottom_line, line_buff );
  96.    set_prompt( diff_prompt7a, window->bottom_line );
  97.    start = get_yn( );
  98.    restore_screen_line( 0, window->bottom_line, line_buff );
  99.    if (start != ERROR)
  100.       diff.leading =  start == A_YES ?  TRUE  :  FALSE;
  101.    else
  102.       return( ERROR );
  103.  
  104.    /*
  105.     * are all spaces significant?
  106.     */
  107.    save_screen_line( 0, window->bottom_line, line_buff );
  108.    set_prompt( diff_prompt7b, window->bottom_line );
  109.    start = get_yn( );
  110.    restore_screen_line( 0, window->bottom_line, line_buff );
  111.    if (start != ERROR) {
  112.       if (start == A_YES)
  113.          diff.leading = diff.all_space = TRUE;
  114.       else
  115.          diff.all_space = FALSE;
  116.    } else
  117.       return( ERROR );
  118.  
  119.    /*
  120.     * are blank lines significant?
  121.     */
  122.    save_screen_line( 0, window->bottom_line, line_buff );
  123.    set_prompt( diff_prompt7c, window->bottom_line );
  124.    start = get_yn( );
  125.    restore_screen_line( 0, window->bottom_line, line_buff );
  126.    if (start != ERROR)
  127.       diff.blank_lines =  start == A_YES  ?  TRUE : FALSE;
  128.    else
  129.       return( ERROR );
  130.  
  131.    /*
  132.     * is end of line significant?
  133.     */
  134.    save_screen_line( 0, window->bottom_line, line_buff );
  135.    set_prompt( diff_prompt7d, window->bottom_line );
  136.    start = get_yn( );
  137.    restore_screen_line( 0, window->bottom_line, line_buff );
  138.    if (start != ERROR)
  139.       diff.ignore_eol =  start == A_YES  ?  TRUE : FALSE;
  140.    else
  141.       return( ERROR );
  142.  
  143.    /*
  144.     * now, find out were to start the diff -- beginning of file or
  145.     *   current cursor location.
  146.     */
  147.    save_screen_line( 0, window->bottom_line, line_buff );
  148.    set_prompt( diff_prompt3, window->bottom_line );
  149.    start = get_bc( );
  150.    restore_screen_line( 0, window->bottom_line, line_buff );
  151.  
  152.    if (start != ERROR) {
  153.       entab_linebuff( );
  154.       if (un_copy_line( window->ll, window, TRUE ) == ERROR)
  155.          return( ERROR );
  156.  
  157.       /*
  158.        * if everything is everything, initialize the diff pointers.
  159.        */
  160.       diff.defined = TRUE;
  161.       if (start == BEGINNING) {
  162.          diff.d1 = diff.w1->file_info->line_list;
  163.          diff.d2 = diff.w2->file_info->line_list;
  164.          diff.rline1 = 1L;
  165.          diff.rline2 = 1L;
  166.          diff.bin_offset1 = 0;
  167.          diff.bin_offset2 = 0;
  168.          rc = differ( 0, 0, window->bottom_line );
  169.       } else {
  170.          diff.d1 = diff.w1->ll;
  171.          diff.d2 = diff.w2->ll;
  172.          diff.rline1 = diff.w1->rline;
  173.          diff.rline2 = diff.w2->rline;
  174.          diff.bin_offset1 = diff.w1->bin_offset;
  175.          diff.bin_offset2 = diff.w2->bin_offset;
  176.          rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
  177.       }
  178.    }
  179.    return( rc );
  180. }
  181.  
  182.  
  183. /*
  184.  * Name:    repeat_diff
  185.  * Purpose: compare two cursor positions
  186.  * Date:    October 31, 1992
  187.  * Passed:  window:  pointer to current window
  188.  * Notes:   user may press this key at any time once the diff has been
  189.  *            defined.
  190.  */
  191. int  repeat_diff( WINDOW *window )
  192. {
  193. register int rc = ERROR;
  194.  
  195.    if (diff.defined) {
  196.       entab_linebuff( );
  197.       if (un_copy_line( window->ll, window, TRUE ) == ERROR)
  198.          return( ERROR );
  199.  
  200.       /*
  201.        * initialize the diff pointers.
  202.        */
  203.       diff.d1 = diff.w1->ll;
  204.       diff.d2 = diff.w2->ll;
  205.       diff.rline1 = diff.w1->rline;
  206.       diff.rline2 = diff.w2->rline;
  207.       diff.bin_offset1 = diff.w1->bin_offset;
  208.       diff.bin_offset2 = diff.w2->bin_offset;
  209.       rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
  210.    } else
  211.       error( WARNING, window->bottom_line, diff_prompt5 );
  212.    return( rc );
  213. }
  214.  
  215.  
  216. /*
  217.  * Name:    differ
  218.  * Purpose: diff text pointers
  219.  * Date:    October 31, 1992
  220.  * Passed:  initial_rcol1:  beginning column to begin diff in window1
  221.  *          initial_rcol2:  beginning column to begin diff in window2
  222.  *          bottom:         line to display diagnostics
  223.  * Notes:   a straight diff on text pointers is simple; however, diffing
  224.  *            with leading spaces and tabs is kinda messy.  let's do the
  225.  *            messy diff.
  226.  */
  227. int  differ( int initial_rcol1, int initial_rcol2, int bottom )
  228. {
  229. int  rcol1;             /* virtual real column on diff window 1 */
  230. int  rcol2;             /* virtual real column on diff window 2 */
  231. int  r1;                /* real real column rcol1 - needed for tabs */
  232. int  r2;                /* real real column rcol2 - needed for tabs */
  233. char c1;                /* character under r1 */
  234. char c2;                /* character under r2 */
  235. int  leading1;          /* adjustment for leading space in window 1 */
  236. int  leading2;          /* adjustment for leading space in window 2 */
  237. int  len1;              /* length of diff1 line */
  238. int  len2;              /* length of diff2 line */
  239. line_list_ptr node1;    /* scratch node in window 1 */
  240. line_list_ptr node2;    /* scratch node in window 2 */
  241. text_ptr diff1;         /* scratch text ptr in window 1 */
  242. text_ptr diff2;         /* scratch text ptr in window 2 */
  243. long rline1;            /* real line number of diff pointer 1 */
  244. long rline2;            /* real line number of diff pointer 2 */
  245. long bin_offset1;       /* binary offset of diff pointer 1 */
  246. long bin_offset2;       /* binary offset of diff pointer 2 */
  247. int  len;               /* line length variable */
  248. register int tabs;      /* local variable for mode.inflate_tabs, T or F */
  249. char line_buff[(MAX_COLS+1)*2];  /* buffer for char and attribute  */
  250.  
  251.    /*
  252.     * initialize the text pointers and the initial column.  skip any
  253.     *  initial blank lines.
  254.     */
  255.    rline1 = diff.rline1;
  256.    rline2 = diff.rline2;
  257.    node1 = diff.d1;
  258.    node2 = diff.d2;
  259.    bin_offset1 = diff.bin_offset1;
  260.    bin_offset2 = diff.bin_offset2;
  261.    tabs  = mode.inflate_tabs;
  262.    if (diff.blank_lines) {
  263.       while (node1->len != EOF  && is_line_blank( node1->line, node1->len )) {
  264.          bin_offset1 += node1->len;
  265.          node1 = node1->next;
  266.          ++rline1;
  267.          initial_rcol1 = 0;
  268.       }
  269.       while (node2->len != EOF  && is_line_blank( node2->line , node2->len)) {
  270.          bin_offset2 += node2->len;
  271.          node2 = node2->next;
  272.          ++rline2;
  273.          initial_rcol2 = 0;
  274.       }
  275.    }
  276.  
  277.    /*
  278.     * if everything is everything, initialize the diff variables and diff.
  279.     */
  280.    if (node1->len != EOF  &&  node2->len != EOF) {
  281.       diff1 = node1->line;
  282.       diff2 = node2->line;
  283.       rcol1 = initial_rcol1;
  284.       rcol2 = initial_rcol2;
  285.       len1  = node1->len;
  286.       len2  = node2->len;
  287.  
  288.       assert( rcol1 >= 0 );
  289.       assert( rcol1 < MAX_LINE_LENGTH );
  290.       assert( rcol2 >= 0 );
  291.       assert( rcol2 < MAX_LINE_LENGTH );
  292.       assert( len1 >= 0 );
  293.       assert( len1 < MAX_LINE_LENGTH );
  294.       assert( len2 >= 0 );
  295.       assert( len2 < MAX_LINE_LENGTH );
  296.  
  297.       /*
  298.        * if cursors are past EOL, move them back to EOL.
  299.        */
  300.       len = find_end( diff1, len1 );
  301.       if (rcol1 > len)
  302.          rcol1 = len;
  303.       len = find_end( diff2, len2 );
  304.       if (rcol2 > len)
  305.          rcol2 = len;
  306.  
  307.       /*
  308.        * if skip leading space, make sure our cursors start on first non-space.
  309.        */
  310.       if (diff.leading) {
  311.          leading1 = skip_leading_space( diff1, len1 );
  312.          leading2 = skip_leading_space( diff2, len2 );
  313.          if (tabs) {
  314.             leading1 = detab_adjust_rcol( diff1, leading1 );
  315.             leading2 = detab_adjust_rcol( diff2, leading2 );
  316.          }
  317.          if (rcol1 < leading1)
  318.             rcol1 = leading1;
  319.          if (rcol2 < leading2)
  320.             rcol2 = leading2;
  321.       }
  322.  
  323.       /*
  324.        * we now have a valid rcol for the diff start, we may need to adjust
  325.        *   for tabs, though.
  326.        */
  327.       assert( rcol1 >= 0 );
  328.       assert( rcol1 < MAX_LINE_LENGTH );
  329.       assert( rcol2 >= 0 );
  330.       assert( rcol2 < MAX_LINE_LENGTH );
  331.  
  332.       r1 =  tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
  333.       r2 =  tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
  334.  
  335.       assert( r1 >= 0 );
  336.       assert( r1 <= len1 );
  337.       assert( r2 >= 0 );
  338.       assert( r2 <= len2 );
  339.       assert( r1 <= rcol1 );
  340.       assert( r2 <= rcol2 );
  341.  
  342.       s_output( diff_message, g_display.mode_line, 67, g_display.diag_color );
  343.       while (node1->len != EOF  &&  node2->len != EOF  &&
  344.                          !g_status.control_break) {
  345.  
  346.          /*
  347.           * look at each character in each diff window
  348.           */
  349.          c1 = (char)(r1 < len1 ? *(diff1 + r1)  : 0);
  350.          c2 = (char)(r2 < len2 ? *(diff2 + r2)  : 0);
  351.  
  352.          /*
  353.           *  tabs == space
  354.           */
  355.          if (tabs) {
  356.             if (c1 == '\t')
  357.                c1 = ' ';
  358.             if (c2 == '\t')
  359.                c2 = ' ';
  360.          }
  361.  
  362.          /*
  363.           * skip spaces, if needed
  364.           */
  365.          if (diff.all_space) {
  366.             while (c1 == ' '  &&  r1 < len1) {
  367.                ++rcol1;
  368.                r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
  369.                c1 =  (char)(r1 < len1  ?  *(diff1 + r1) :  0);
  370.                if (c1 == '\t'  &&  tabs)
  371.                   c1 = ' ';
  372.             }
  373.             while (c2 == ' '  &&  r2 < len2) {
  374.                ++rcol2;
  375.                r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
  376.                c2 =  (char)(r2 < len2  ? *(diff2 + r2) : 0);
  377.                if (c2 == '\t'  &&  tabs)
  378.                   c2 = ' ';
  379.             }
  380.          }
  381.  
  382.          /*
  383.           * if one of the node pointers has come to EOL, move to next
  384.           *   diff line.
  385.           */
  386.          if (diff.ignore_eol) {
  387.             if (r1 >= len1) {
  388.                node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 );
  389.                len1  = node1->len;
  390.                if (len1 != EOF) {
  391.                   diff1 = node1->line;
  392.                   c1 =  (char)(r1 < len1  ?  *(diff1 + r1) : 0);
  393.                   if (c1 == '\t'  &&  tabs)
  394.                      c1 = ' ';
  395.                }
  396.             }
  397.             if (r2 >= len2) {
  398.                node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 );
  399.                len2  = node2->len;
  400.                if (len2 != EOF) {
  401.                   diff2 = node2->line;
  402.                   c2 =  (char)(r2 < len2  ? *(diff2 + r2)  :  0);
  403.                   if (c2 == '\t'  &&  tabs)
  404.                      c2 = ' ';
  405.                }
  406.             }
  407.          }
  408.  
  409.          /*
  410.           * convert the characters to lower case, if needed.
  411.           */
  412.          if (mode.search_case == IGNORE) {
  413.             c1 = (char)tolower( c1 );
  414.             c2 = (char)tolower( c2 );
  415.          }
  416.  
  417.          /*
  418.           * diff each character in the diff lines until we reach EOL
  419.           */
  420.          while (r1 < len1  && r2 < len2) {
  421.             if (c1 == c2) {
  422.                if (diff.all_space) {
  423.                   do {
  424.                      ++rcol1;
  425.                      r1 = tabs ? entab_adjust_rcol( diff1,len1,rcol1 ) : rcol1;
  426.                      c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  :  0);
  427.                      if (c1 == '\t'  &&  tabs)
  428.                         c1 = ' ';
  429.                   } while (c1 == ' '  &&  r1 < len1);
  430.                   do {
  431.                      ++rcol2;
  432.                      r2 = tabs ? entab_adjust_rcol( diff2,len2,rcol2 ) : rcol2;
  433.                      c2 =  (char)(r2 < len2  ?  *(diff2 + r2)  :  0);
  434.                      if (c2 == '\t'  &&  tabs)
  435.                         c2 = ' ';
  436.                   } while (c2 == ' '  &&  r2 < len2);
  437.                } else {
  438.                   ++rcol1;
  439.                   ++rcol2;
  440.                   r1 = tabs ? entab_adjust_rcol( diff1, len1, rcol1 ) : rcol1;
  441.                   r2 = tabs ? entab_adjust_rcol( diff2, len2, rcol2 ) : rcol2;
  442.                   c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  :  0);
  443.                   c2 =  (char)(r2 < len2  ?  *(diff2 + r2)  :  0);
  444.                   if (tabs) {
  445.                      if (c1 == '\t')
  446.                         c1 = ' ';
  447.                      if (c2 == '\t')
  448.                         c2 = ' ';
  449.                   }
  450.                }
  451.                if (diff.ignore_eol) {
  452.                   if (r1 >= len1) {
  453.                      node1 = skip_eol(node1, &r1, &rcol1, &rline1,&bin_offset1);
  454.                      len1  = node1->len;
  455.                      if (len1 != EOF) {
  456.                         diff1 = node1->line;
  457.                         c1 =  (char)(r1 < len1  ?  *(diff1 + r1)  : 0);
  458.                         if (c1 == '\t'  &&  tabs)
  459.                            c1 = ' ';
  460.                      }
  461.                   }
  462.                   if (r2 >= len2) {
  463.                      node2 = skip_eol(node2, &r2, &rcol2, &rline2,&bin_offset2);
  464.                      len2  = node2->len;
  465.                      if (len2 != EOF) {
  466.                         diff2 = node2->line;
  467.                         c2 = (char)(r2 < len2  ? *(diff2 + r2)  :  0);
  468.                         if (c2 == '\t'  &&  tabs)
  469.                            c2 = ' ';
  470.                      }
  471.                   }
  472.                }
  473.                if (mode.search_case == IGNORE) {
  474.                   c1 = (char)tolower( c1 );
  475.                   c2 = (char)tolower( c2 );
  476.                }
  477.             } else {
  478.  
  479.                /*
  480.                 * when we show the diff, use rcol1 and rcol2, as
  481.                 *   find_adjust does not adjust rcol for tabs.
  482.                 */
  483.                update_line( diff.w1 );
  484.                diff.w1->bin_offset = bin_offset1;
  485.                find_adjust( diff.w1, node1, rline1, rcol1 );
  486.                check_virtual_col( diff.w1, rcol1, rcol1 );
  487.                show_diff_window( diff.w1 );
  488.                update_line( diff.w2 );
  489.                diff.w2->bin_offset = bin_offset2;
  490.                bin_offset_adjust( diff.w2, rline2 );
  491.                find_adjust( diff.w2, node2, rline2, rcol2 );
  492.                check_virtual_col( diff.w2, rcol2, rcol2 );
  493.                show_diff_window( diff.w2 );
  494.                s_output( diff_blank, g_display.mode_line, 67,
  495.                          g_display.mode_color );
  496.                return( OK );
  497.             }
  498.          }
  499.  
  500.          /*
  501.           * if we haven't come to the end of a file buffer, check the last
  502.           *   characters.  see if pointers are at EOL.
  503.           */
  504.          if (node1->len != EOF && node2->len != EOF) {
  505.             if (rcol1 != len1  &&  rcol2 != len2) {
  506.                update_line( diff.w1 );
  507.                diff.w1->bin_offset = bin_offset1;
  508.                find_adjust( diff.w1, node1, rline1, rcol1 );
  509.                show_diff_window( diff.w1 );
  510.                update_line( diff.w2 );
  511.                diff.w2->bin_offset = bin_offset2;
  512.                find_adjust( diff.w2, node2, rline2, rcol2 );
  513.                show_diff_window( diff.w2 );
  514.                s_output( diff_blank, g_display.mode_line, 67,
  515.                          g_display.mode_color );
  516.                return( OK );
  517.             } else {
  518.                node1 = skip_eol( node1, &r1, &rcol1, &rline1, &bin_offset1 );
  519.                len1  = node1->len;
  520.                diff1 = node1->line;
  521.                node2 = skip_eol( node2, &r2, &rcol2, &rline2, &bin_offset2 );
  522.                len2  = node2->len;
  523.                diff2 = node2->line;
  524.             }
  525.          }
  526.  
  527.          assert( rcol1 >= 0 );
  528.          assert( rcol1 < MAX_LINE_LENGTH );
  529.          assert( rcol2 >= 0 );
  530.          assert( rcol2 < MAX_LINE_LENGTH );
  531.          assert( r1 >= 0 );
  532.          assert( r1 < MAX_LINE_LENGTH );
  533.          assert( r2 >= 0 );
  534.          assert( r2 < MAX_LINE_LENGTH );
  535.          assert( r1 <= rcol1 );
  536.          assert( r2 <= rcol2 );
  537.          if (node1->len == EOF)
  538.             assert( len1 == EOF );
  539.          else {
  540.             assert( len1 >= 0 );
  541.             assert( len1 < MAX_LINE_LENGTH );
  542.          }
  543.          if (node2->len == EOF)
  544.             assert( len2 == EOF );
  545.          else {
  546.             assert( len2 >= 0 );
  547.             assert( len2 < MAX_LINE_LENGTH );
  548.          }
  549.       }
  550.       save_screen_line( 0, bottom, line_buff );
  551.       set_prompt( diff_prompt4, bottom );
  552.       getkey( );
  553.       restore_screen_line( 0, bottom, line_buff );
  554.       s_output( diff_blank, g_display.mode_line, 67, g_display.mode_color );
  555.    }
  556.    return( ERROR );
  557. }
  558.  
  559.  
  560. /*
  561.  * Name:    skip_leading_space
  562.  * Purpose: put the diff on the first non-blank character
  563.  * Date:    October 31, 1992
  564.  * Passed:  s:  the string to search
  565.  *          len: length of string
  566.  * Returns: the first non-blank column
  567.  */
  568. int  skip_leading_space( text_ptr s, int len )
  569. {
  570. register int count = 0;
  571.  
  572.    assert( len >= 0 );
  573.    assert( len < MAX_LINE_LENGTH );
  574.  
  575.    if (s != NULL) {
  576.       if (mode.inflate_tabs) {
  577.          while (len > 0  &&  (*s == ' ' || *s == '\t')) {
  578.             ++count;
  579.             ++s;
  580.             --len;
  581.          }
  582.       } else {
  583.          while (len > 0  &&  *s == ' ') {
  584.            ++count;
  585.            ++s;
  586.            --len;
  587.          }
  588.       }
  589.    }
  590.    if (len == 0)
  591.       count = 0;
  592.    return( count );
  593. }
  594.  
  595.  
  596. /*
  597.  * Name:    skip_eol
  598.  * Purpose: move the diff to the next line
  599.  * Date:    October 31, 1992
  600.  * Passed:  d:           pointer to current node
  601.  *          r:           tab adjusted real col
  602.  *          rcol:        real real col
  603.  *          rline:       current line number
  604.  *          bin_offset:  offset from the beginning of the file
  605.  * Returns: next non-blank node
  606.  */
  607. line_list_ptr skip_eol( line_list_ptr d, int *r, int *rcol, long *rline,
  608.                         long *bin_offset )
  609. {
  610. int  leading;
  611. long rl;
  612. long bo;
  613.  
  614.    *r = *rcol = 0;
  615.    rl = *rline;
  616.    bo = *bin_offset;
  617.    if (d->len != EOF) {
  618.       bo += d->len;
  619.       d = d->next;
  620.       ++rl;
  621.       if (diff.blank_lines) {
  622.          while (d->len != EOF  &&  is_line_blank( d->line, d->len )) {
  623.             bo += d->len;
  624.             d = d->next;
  625.             ++rl;
  626.          }
  627.       }
  628.       if (d->len != EOF) {
  629.          if (diff.leading) {
  630.             leading = skip_leading_space( d->line, d->len );
  631.             if (mode.inflate_tabs)
  632.                leading = detab_adjust_rcol( d->line, leading );
  633.             *rcol = leading;
  634.          } else
  635.             *rcol = 0;
  636.          *r = *rcol;
  637.          if (mode.inflate_tabs)
  638.             *r = entab_adjust_rcol( d->line, d->len, *rcol );
  639.       }
  640.    }
  641.    *rline = rl;
  642.    *bin_offset = bo;
  643.    return( d );
  644. }
  645.  
  646.  
  647. /*
  648.  * Name:    show_diff_window
  649.  * Purpose: update the contents of a diff window
  650.  * Date:    October 31, 1992
  651.  * Passed:  win:  pointer to window
  652.  */
  653. void show_diff_window( WINDOW *win )
  654. {
  655.    if (win->file_info->dirty == LOCAL)
  656.       display_current_window( win );
  657.    else
  658.       show_curl_line( win );
  659.    show_line_col( win );
  660.    make_ruler( win );
  661.    show_ruler( win );
  662.    show_ruler_pointer( win );
  663.    win->file_info->dirty = FALSE;
  664. }
  665.  
  666.  
  667. /*
  668.  * Name:    verify_number
  669.  * Purpose: given a window number, verify the number
  670.  * Date:    October 31, 1992
  671.  * Passed:  temp:  string that contains number
  672.  *          num:   successfully converted number.
  673.  */
  674. int  verify_number( char *temp, int *num )
  675. {
  676. register file_infos *fp;
  677.  
  678.    /*
  679.     * see if string has a number.  if string does have a number, convert it.
  680.     */
  681.    if (*temp == '\0' || !isdigit( *temp ))
  682.       return( ERROR );
  683.    *num = 0;
  684.    while (isdigit( *temp ))
  685.       *num = *num * 10 + *temp++ - '0';
  686.  
  687.    /*
  688.     * now that we have a window number, see if any files have that number
  689.     */
  690.    for (fp=g_status.file_list; fp != NULL; fp=fp->next) {
  691.       if (fp->file_no == *num)
  692.          return( OK );
  693.    }
  694.    return( ERROR );
  695. }
  696.  
  697.  
  698.  
  699. /*
  700.  * Name:    verify_letter
  701.  * Purpose: given a window letter, verify the letter
  702.  * Date:    October 31, 1992
  703.  * Passed:  temp:  string that contains letter
  704.  *          let:   window letter
  705.  *          win:   pointer to window that contains letter and number
  706.  */
  707. int  verify_letter( char *temp, int *let, WINDOW **win )
  708. {
  709. register file_infos *fp;
  710. register WINDOW *wp;
  711. int  num;
  712.  
  713.    if (verify_number( temp, &num ) == OK) {
  714.       while (isdigit( *temp ))
  715.          temp++;
  716.       if (*temp == '\0' || !isalpha( *temp ))
  717.          return( ERROR );
  718.       *let = (int)tolower( *temp );
  719.       for (fp=g_status.file_list; fp != NULL; fp=fp->next) {
  720.          if (fp->file_no == num)
  721.             break;
  722.       }
  723.       for (wp=g_status.window_list; wp != NULL; wp=wp->next) {
  724.          if (wp->file_info == fp  &&  wp->letter == *let  &&  wp->visible) {
  725.             *win = wp;
  726.             return( OK );
  727.          }
  728.       }
  729.    }
  730.    return( ERROR );
  731. }
  732.