home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 024 / diff.c < prev    next >
C/C++ Source or Header  |  1993-06-04  |  24KB  |  733 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.  * Date:             June 5, 1993, version 3.0
  23.  *
  24.  * This code is released into the public domain, Frank Davis.
  25.  * You may distribute it freely.
  26.  */
  27.  
  28. #include "tdestr.h"
  29. #include "common.h"
  30. #include "define.h"
  31. #include "tdefunc.h"
  32.  
  33.  
  34. /*
  35.  * Name:    define_diff
  36.  * Purpose: get info needed to initialize diff
  37.  * Date:    October 31, 1992
  38.  * Passed:  window:  pointer to current window
  39.  * Notes:   allow the user to start the diff at the beginning of the
  40.  *            file or at the current cursor location.  once the diff
  41.  *            has been defined, the user may press one key to diff again.
  42.  *          user may diff any two visible windows on the screen.
  43.  */
  44. int  define_diff( WINDOW *window )
  45. {
  46. int  rc;
  47. char temp[MAX_COLS];
  48. int  num1;
  49. int  let1;
  50. int  num2;
  51. int  let2;
  52. int  start;
  53. char line_buff[(MAX_COLS+1)*2];  /* buffer for char and attribute  */
  54. char buff[MAX_COLS*2];           /* buffer for char and attribute  */
  55.  
  56.    /*
  57.     * get window number and letter of the first diff window.  then,
  58.     *   verify that window - does it exit? is it visible?
  59.     */
  60.    *temp = '\0';
  61.    rc = get_name( diff_prompt1, window->bottom_line, temp,
  62.                   g_display.message_color );
  63.    if (rc == OK) {
  64.       rc = verify_number( temp, &num1 );
  65.       if (rc == OK)
  66.          rc = verify_letter( temp, &let1, &diff.w1 );
  67.    } else
  68.       return( ERROR );
  69.    if (rc == ERROR) {
  70.       combine_strings( buff, diff_prompt6a, temp, diff_prompt6b );
  71.       error( WARNING, window->bottom_line, buff );
  72.       return( ERROR );
  73.    }
  74.  
  75.    /*
  76.     * get and verify the next window number and letter to diff.
  77.     */
  78.    *temp = '\0';
  79.    rc = get_name( diff_prompt2, window->bottom_line, temp,
  80.                   g_display.message_color );
  81.    if (rc == OK) {
  82.       rc = verify_number( temp, &num2 );
  83.       if (rc == OK)
  84.          rc = verify_letter( temp, &let2, &diff.w2 );
  85.    } else
  86.       return( ERROR );
  87.    if (rc == ERROR) {
  88.       combine_strings( buff, diff_prompt6a, temp, diff_prompt6b );
  89.       error( WARNING, window->bottom_line, buff );
  90.       return( ERROR );
  91.    }
  92.  
  93.    /*
  94.     * are leading spaces significant?
  95.     */
  96.    save_screen_line( 0, window->bottom_line, line_buff );
  97.    set_prompt( diff_prompt7a, window->bottom_line );
  98.    start = get_yn( );
  99.    restore_screen_line( 0, window->bottom_line, line_buff );
  100.    if (start != ERROR)
  101.       diff.leading =  start == A_YES ?  TRUE  :  FALSE;
  102.    else
  103.       return( ERROR );
  104.  
  105.    /*
  106.     * are all spaces significant?
  107.     */
  108.    save_screen_line( 0, window->bottom_line, line_buff );
  109.    set_prompt( diff_prompt7b, window->bottom_line );
  110.    start = get_yn( );
  111.    restore_screen_line( 0, window->bottom_line, line_buff );
  112.    if (start != ERROR) {
  113.       if (start == A_YES)
  114.          diff.leading = diff.all_space = TRUE;
  115.       else
  116.          diff.all_space = FALSE;
  117.    } else
  118.       return( ERROR );
  119.  
  120.    /*
  121.     * are blank lines significant?
  122.     */
  123.    save_screen_line( 0, window->bottom_line, line_buff );
  124.    set_prompt( diff_prompt7c, window->bottom_line );
  125.    start = get_yn( );
  126.    restore_screen_line( 0, window->bottom_line, line_buff );
  127.    if (start != ERROR)
  128.       diff.blank_lines =  start == A_YES  ?  TRUE : FALSE;
  129.    else
  130.       return( ERROR );
  131.  
  132.    /*
  133.     * is end of line significant?
  134.     */
  135.    save_screen_line( 0, window->bottom_line, line_buff );
  136.    set_prompt( diff_prompt7d, window->bottom_line );
  137.    start = get_yn( );
  138.    restore_screen_line( 0, window->bottom_line, line_buff );
  139.    if (start != ERROR)
  140.       diff.ignore_eol =  start == A_YES  ?  TRUE : FALSE;
  141.    else
  142.       return( ERROR );
  143.  
  144.    /*
  145.     * now, find out were to start the diff -- beginning of file or
  146.     *   current cursor location.
  147.     */
  148.    save_screen_line( 0, window->bottom_line, line_buff );
  149.    set_prompt( diff_prompt3, window->bottom_line );
  150.    start = get_bc( );
  151.    restore_screen_line( 0, window->bottom_line, line_buff );
  152.  
  153.    if (start != ERROR) {
  154.       entab_linebuff( );
  155.       if (un_copy_line( window->ll, window, TRUE ) == ERROR)
  156.          return( ERROR );
  157.  
  158.       /*
  159.        * if everything is everything, initialize the diff pointers.
  160.        */
  161.       diff.defined = TRUE;
  162.       if (start == BEGINNING) {
  163.          diff.d1 = diff.w1->file_info->line_list;
  164.          diff.d2 = diff.w2->file_info->line_list;
  165.          diff.rline1 = 1L;
  166.          diff.rline2 = 1L;
  167.          diff.bin_offset1 = 0;
  168.          diff.bin_offset2 = 0;
  169.          rc = differ( 0, 0, window->bottom_line );
  170.       } else {
  171.          diff.d1 = diff.w1->ll;
  172.          diff.d2 = diff.w2->ll;
  173.          diff.rline1 = diff.w1->rline;
  174.          diff.rline2 = diff.w2->rline;
  175.          diff.bin_offset1 = diff.w1->bin_offset;
  176.          diff.bin_offset2 = diff.w2->bin_offset;
  177.          rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
  178.       }
  179.    }
  180.    return( rc );
  181. }
  182.  
  183.  
  184. /*
  185.  * Name:    repeat_diff
  186.  * Purpose: compare two cursor positions
  187.  * Date:    October 31, 1992
  188.  * Passed:  window:  pointer to current window
  189.  * Notes:   user may press this key at any time once the diff has been
  190.  *            defined.
  191.  */
  192. int  repeat_diff( WINDOW *window )
  193. {
  194. register int rc = ERROR;
  195.  
  196.    if (diff.defined) {
  197.       entab_linebuff( );
  198.       if (un_copy_line( window->ll, window, TRUE ) == ERROR)
  199.          return( ERROR );
  200.  
  201.       /*
  202.        * initialize the diff pointers.
  203.        */
  204.       diff.d1 = diff.w1->ll;
  205.       diff.d2 = diff.w2->ll;
  206.       diff.rline1 = diff.w1->rline;
  207.       diff.rline2 = diff.w2->rline;
  208.       diff.bin_offset1 = diff.w1->bin_offset;
  209.       diff.bin_offset2 = diff.w2->bin_offset;
  210.       rc = differ( diff.w1->rcol, diff.w2->rcol, window->bottom_line );
  211.    } else
  212.       error( WARNING, window->bottom_line, diff_prompt5 );
  213.    return( rc );
  214. }
  215.  
  216.  
  217. /*
  218.  * Name:    differ
  219.  * Purpose: diff text pointers
  220.  * Date:    October 31, 1992
  221.  * Passed:  initial_rcol1:  beginning column to begin diff in window1
  222.  *          initial_rcol2:  beginning column to begin diff in window2
  223.  *          bottom:         line to display diagnostics
  224.  * Notes:   a straight diff on text pointers is simple; however, diffing
  225.  *            with leading spaces and tabs is kinda messy.  let's do the
  226.  *            messy diff.
  227.  */
  228. int  differ( int initial_rcol1, int initial_rcol2, int bottom )
  229. {
  230. int  rcol1;             /* virtual real column on diff window 1 */
  231. int  rcol2;             /* virtual real column on diff window 2 */
  232. int  r1;                /* real real column rcol1 - needed for tabs */
  233. int  r2;                /* real real column rcol2 - needed for tabs */
  234. char c1;                /* character under r1 */
  235. char c2;                /* character under r2 */
  236. int  leading1;          /* adjustment for leading space in window 1 */
  237. int  leading2;          /* adjustment for leading space in window 2 */
  238. int  len1;              /* length of diff1 line */
  239. int  len2;              /* length of diff2 line */
  240. line_list_ptr node1;    /* scratch node in window 1 */
  241. line_list_ptr node2;    /* scratch node in window 2 */
  242. text_ptr diff1;         /* scratch text ptr in wind