home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / p2demo21.exe / PEL / VDIFF.PEL < prev    next >
Text File  |  1995-04-11  |  31KB  |  1,101 lines

  1. # $Header:   P:\source\wmacros\vdiff.pev   1.56   11 Apr 1995 11:43:18   WALKER  $
  2.  
  3. ##############################################################################
  4. #
  5. #       Compuware Corporation
  6. #         31440 Northwestern Highway
  7. #           Farmington Hills, Michigan 48334-2564
  8. #
  9. #   This source code listing contains information that is
  10. #   proprietary to Compuware Corporation and may not be copied
  11. #   duplicated, translated, transmitted, stored, retrieved
  12. #   or in any manner or by any method conveyed or disclosed
  13. #   to a third party or parties without express written
  14. #   permission from Compuware Corporation.
  15. #
  16. #  
  17. ##############################################################################
  18.  
  19. #### $Workfile:   vdiff.pel  $: vdiff comparison support
  20.  
  21. ## $Tabs:5 9$
  22.  
  23.  
  24.  
  25. #--------------------------------------------------------------------------
  26. #
  27. #  PVCS vdiff dialog box and processing
  28. #
  29. #--------------------------------------------------------------------------
  30.  
  31. global dhVdiff          = 0
  32.  
  33. local pvcs_vdiff_arr[]
  34. local pvcs_dlg_arr[]
  35.  
  36. local vdiff_changes[]
  37. local vdiff_prev_status[]
  38. local vdiff_wins[]
  39. local vdiff_bufs[]
  40.  
  41. local PVCS_VDIFF                = 1573
  42. local ID_REFVERSION             = 1574
  43. local ID_REFFILE                = 1575
  44. local ID_TARGETVERSION          = 1576
  45. local ID_TARGETFILE             = 1577
  46. local ID_COMPARISON             = 1578
  47. local ID_VDIFF                  = 1579
  48. local ID_VERTICAL               = 1580
  49. local ID_HORIZONTAL             = 1581
  50. local ID_IGNORE_WHITE           = 1582
  51. local IDG_ORIENTATION           = 1583
  52.                              
  53.  
  54. local IDM_FIRST_ITEM     = 3709
  55. local IDM_NEXT           = 3709
  56. local IDM_PREV           = 3710
  57. local IDM_EXIT_VDIFF     = 3711
  58. local IDM_MVDIFF         = 3712
  59. local IDM_LAST_ITEM      = 3712
  60.  
  61. local kmp                = 0
  62. local cw                 = current_window
  63.  
  64. local vdiff_ok           = TRUE
  65. local in_vdiff           = FALSE
  66. local vdiff_ignore_white = TRUE
  67. local old_menu           = 0
  68. local old_window         = 0
  69. local old_wflags         = 0
  70. local old_current_buffer = 0
  71.  
  72. global default_vdiff_command = "vdiff "
  73. global vdiff_command         = default_vdiff_command
  74.  
  75. local vdiff_win_num
  76.  
  77. global function pvcs_vdiff()
  78. {
  79.    local cmd = ""
  80.    local outputFile  = ""
  81.    local errorFile   = ""
  82.    local options     = ""
  83.    local ret_code    = 0
  84.    local inputError  = 0
  85.    local i           = 0
  86.    local winName[]
  87.    local name[]
  88.  
  89.    # this is the first time through
  90.    if (dhVdiff)
  91.       delete_dialog(dhVdiff)
  92.       
  93.    dhVdiff = create_dialog( function_id( "vdiff_callback" ), 0, PVCS_VDIFF, resource_dll );
  94.  
  95.    set_dialog_item(dhVdiff, ID_TARGETFILE, DAC_SET_TEXT_LEN, 256)
  96.    set_dialog_item(dhVdiff, ID_REFFILE, DAC_SET_TEXT_LEN, 256)
  97.  
  98.    optional_function( "load_user_vdiff_ref_syntax" )
  99.    optional_function( "load_user_vdiff_target_syntax" )
  100.    
  101.    if ( !pvcs_vdiff_arr )
  102.    {
  103.       pvcs_vdiff_arr[ 5 ] = "1"
  104.       pvcs_vdiff_arr[ 6 ] = "0"
  105.       pvcs_vdiff_arr[ 7 ] = "1"
  106.       pvcs_vdiff_arr[ 8 ] = "0"
  107.    }
  108.  
  109.    # always specified :
  110.    pvcs_vdiff_arr[ 1 ] = "*"              # reference ver
  111.    pvcs_vdiff_arr[ 2 ] = buffer_filename  # reference name
  112.    pvcs_vdiff_arr[ 3 ] = ""               # target ver
  113.    pvcs_vdiff_arr[ 4 ] = PVCS_CUR_BUF     # target name
  114.  
  115.    begin_dialog( dhVdiff )
  116.    delete_dialog(dhVdiff)
  117.    dhVdiff = 0
  118.  
  119.    if ( vdiff_ok )
  120.    {  
  121.       # assemble disk filenames or logfile revisions
  122.       name[0] = pvcs_make_name( pvcs_vdiff_arr[1], pvcs_vdiff_arr[2] )
  123.       name[1] = pvcs_make_name( pvcs_vdiff_arr[3], pvcs_vdiff_arr[4] )
  124.       
  125.       # check for existence of files
  126.       #
  127.       for ( i = 0; i <= 1; i++ )
  128.       {
  129.          if ( !name[i] )
  130.          {
  131.             notify( "vdiff:Insufficient parameters passed to vdiff." )
  132.             inputError++
  133.             break
  134.          } 
  135.          else if ( substr( name[i], 1, 1 ) == "-" )
  136.             winName[i] = name[i]      # logfile
  137.          else
  138.          {                            # disk file
  139.             ret_code = filemode( name[i] )
  140.  
  141.             if ( (!and( ret_code,_READ_ONLY+_HIDDEN+_SYSTEM+_ARCHIVE) || ( ret_code < 0 )) &&
  142.                   (ret_code != 0) )
  143.             {
  144.                warning( "vdiff:  Can't open file \"%s\".", name[i] )
  145.                inputError++
  146.             }
  147.  
  148.             # check for name of temp file representing current buffer
  149.             winName[i] = ( pvcs_vdiff_arr[ i ? 4 : 2 ] == PVCS_CUR_BUF ) \
  150.                                                          ? buffer_name " " PVCS_CUR_BUF \
  151.                                                          : name[i]
  152.          }
  153.       }
  154.  
  155.       if ( name[0] == name[1] )
  156.       {
  157.          notify( "vdiff:\"%s\" specified twice.", name[0] )
  158.          inputError++
  159.       }
  160.       
  161.       if ( inputError )
  162.       {
  163.          pvcs_cleanup_temp_files()
  164.          return
  165.       }
  166.       
  167.       if ( pvcs_vdiff_arr[ 5 ] == "1" )
  168.          options = "-e0 -l32000 -n"   # retain tabs, infinite context, omit #s
  169.       else 
  170.          options = "-e0"         # retain tabs
  171.  
  172.       # add ignore whitespace option if set      
  173.       if ( vdiff_ignore_white )
  174.          options = options " -B"
  175.  
  176.       outputFile = pvcs_create_temp_file()
  177.       errorFile  = pvcs_create_temp_file()
  178.       
  179.       message( "Issuing PVCS VDIFF command..." )
  180.       cmd = vdiff_command " -XO" outputFile " -XE" errorFile " " options " " name[0] " " name[1] 
  181.       ret_code = system( cmd, 0, 0, 0, SYS_NOEXPOSE )
  182.  
  183.       if ( filesize(errorFile) ) 
  184.          pvcs_system_output( "VDIFF output", errorFile )
  185.          
  186.       if ( !filesize(outputFile) )
  187.          ret_code = 1
  188.  
  189.       # vdiff option
  190.       if ( ret_code == 0 && pvcs_vdiff_arr[ 5 ] == "1" )
  191.       { 
  192.          in_vdiff = TRUE
  193.          
  194.          # display vdiff output
  195.          vdiff( outputFile, winName[0], winName[1], (pvcs_vdiff_arr[7] == "1") ? "vert" : "horz" )
  196.       } 
  197.       else 
  198.       {
  199.          # comparison option or error
  200.          pvcs_system_output( "VDIFF output", outputFile, ret_code )
  201.          pvcs_cleanup_temp_files()
  202.          delete( pvcs_dlg_arr )
  203.       }
  204.    }
  205. }
  206.  
  207. global function vdiff_callback()
  208. {
  209.    local temp_val = ""
  210.  
  211.    if ( callback_msg == DM_INIT )
  212.       {
  213.  
  214.       # preselect radioboxes
  215.       set_dialog_item(dhVdiff, ID_COMPARISON, pvcs_vdiff_arr[ 5 ] == "1" ? DAC_CHECK : DAC_UNCHECK )
  216.       set_dialog_item(dhVdiff, ID_VDIFF,      pvcs_vdiff_arr[ 6 ] == "1" ? DAC_CHECK : DAC_UNCHECK )
  217.  
  218.       set_dialog_item(dhVdiff, ID_VERTICAL,   pvcs_vdiff_arr[ 7 ] == "1" ? DAC_CHECK : DAC_UNCHECK )
  219.       set_dialog_item(dhVdiff, ID_HORIZONTAL, pvcs_vdiff_arr[ 8 ] == "1" ? DAC_CHECK : DAC_UNCHECK )
  220.  
  221.       set_dialog_item(dhVdiff, ID_IGNORE_WHITE, DAC_CHECK)
  222.  
  223.       set_dialog_item(dhVdiff, ID_REFVERSION, DAC_EDIT_TEXT, "*" )
  224.       set_dialog_item(dhVdiff, ID_REFFILE, DAC_EDIT_TEXT, buffer_filename )
  225.  
  226.       set_dialog_item(dhVdiff, ID_TARGETFILE, DAC_EDIT_TEXT, PVCS_CUR_BUF )
  227.       set_dialog_item(dhVdiff, ID_TARGETVERSION, DAC_EDIT_TEXT, " " )
  228.  
  229.       set_dialog_item(dhVdiff, ID_REFVERSION, DAC_SETFOCUS)
  230.       
  231.       attach_help(editor_helpfile, dhVdiff)
  232.  
  233.       vdiff_ok = TRUE
  234.  
  235.       }
  236.    else if ((callback_msg == DM_CLOSE) || 
  237.             (callback_msg == DM_CANCEL) || 
  238.             ( (callback_msg == DM_CLICK) && (callback_index == DI_CANCEL) ) )
  239.       {
  240.       vdiff_ok = FALSE
  241.       return DRC_EXIT
  242.       }
  243.    else if ( ( callback_msg == DM_CLICK && callback_index == DI_HELP ) ||
  244.              ( callback_msg == DM_HELPREQUESTED ) ) 
  245.    {
  246.       if(isWindows())
  247.          display_help("VCS", dhVdiff);
  248.       else
  249.          display_help("tmpvcs", dhVdiff);
  250.       return DRC_MSG_PROCESSED
  251.    }
  252.    else if ( callback_msg == DM_CLICK )
  253.       {
  254.       if ( callback_index == ID_IGNORE_WHITE )
  255.          {
  256.          vdiff_ignore_white = query_dialog_item(dhVdiff, ID_IGNORE_WHITE, DAC_CHECK)
  257.          }
  258.       else if ( callback_index == ID_COMPARISON )
  259.          {
  260.          set_dialog_item(dhVdiff, ID_COMPARISON, DAC_CHECK)
  261.          pvcs_vdiff_arr[ 5 ] = "1"
  262.  
  263.          set_dialog_item(dhVdiff, ID_VDIFF, DAC_UNCHECK)
  264.          pvcs_vdiff_arr[ 6 ] = "0"
  265.  
  266.          set_dialog_item(dhVdiff, ID_VERTICAL, DAC_ENABLE)
  267.          set_dialog_item(dhVdiff, ID_HORIZONTAL, DAC_ENABLE)
  268.          set_dialog_item(dhVdiff, IDG_ORIENTATION, DAC_ENABLE)
  269.          }
  270.       else if ( callback_index == ID_VDIFF )
  271.          {
  272.          set_dialog_item(dhVdiff, ID_VDIFF, DAC_CHECK)
  273.          pvcs_vdiff_arr[ 6 ] = "1"
  274.  
  275.          set_dialog_item(dhVdiff, ID_COMPARISON, DAC_UNCHECK)
  276.          pvcs_vdiff_arr[ 5 ] = "0"
  277.  
  278.          set_dialog_item(dhVdiff, ID_VERTICAL, DAC_DISABLE)
  279.          set_dialog_item(dhVdiff, ID_HORIZONTAL, DAC_DISABLE)
  280.          set_dialog_item(dhVdiff, IDG_ORIENTATION, DAC_DISABLE)
  281.          }
  282.       else if ( callback_index == ID_VERTICAL )
  283.          {
  284.          set_dialog_item(dhVdiff, ID_VERTICAL, DAC_CHECK)
  285.          pvcs_vdiff_arr[ 7 ] = "1"
  286.  
  287.          set_dialog_item(dhVdiff, ID_HORIZONTAL, DAC_UNCHECK)
  288.          pvcs_vdiff_arr[ 8 ] = "0"
  289.          }
  290.       else if ( callback_index == ID_HORIZONTAL )
  291.          {
  292.          set_dialog_item(dhVdiff, ID_HORIZONTAL, DAC_CHECK)
  293.          pvcs_vdiff_arr[ 8 ] = "1"
  294.  
  295.          set_dialog_item(dhVdiff, ID_VERTICAL, DAC_UNCHECK)
  296.          pvcs_vdiff_arr[ 7 ] = "0"
  297.          }
  298.  
  299.       return DRC_MSG_PROCESSED 
  300.       }
  301.    else if ( callback_msg == DM_KILL_FOCUS )
  302.       {
  303.       temp_val = query_dialog_item(callback_dialog_handle, callback_index, DAC_TEXT)
  304.       if ( !temp_val )
  305.          temp_val = ""
  306.  
  307.       if ( callback_index == ID_REFVERSION )
  308.          {
  309.          pvcs_vdiff_arr[ 1 ] = temp_val
  310.          }
  311.       else if ( callback_index == ID_REFFILE )
  312.          {
  313.          pvcs_vdiff_arr[ 2 ] = temp_val
  314.          }
  315.       else if ( callback_index == ID_TARGETVERSION )
  316.          {
  317.          pvcs_vdiff_arr[ 3 ] = temp_val
  318.          }
  319.       else if ( callback_index == ID_TARGETFILE )
  320.          {
  321.          pvcs_vdiff_arr[ 4 ] = temp_val
  322.          }
  323.       }
  324.  
  325.    return DRC_CONTINUE
  326.  
  327. }
  328.  
  329.  
  330. ## vdiff()
  331. #
  332. #  Compare two files and display the files with changes side by side.
  333. #
  334. #  Arguments:
  335. #
  336. #  vdiffOutput : name of file containing vdiff output
  337. #  refWinName  : name appearing in title bar of reference window
  338. #  tgtWinName  : name appearing in title bar of target window
  339. #  shape    : "horz" - display files one on top of the other
  340. #           : "vert" - display files side by side (default)
  341. #
  342. #  The reference and target buffers are constructed entirely from the vdiff
  343. #  output file.  The function vdiff_build_buffer() performs this action.
  344. #  Blank lines are inserted whereever necessary in order to maintain the
  345. #  line number equivalence between unchanged lines in the two buffers.
  346. #  In addition to the buffers, an array 'vdiff_changes[]' is produced,
  347. #  containing a list of all changed lines, and a code indicating the nature
  348. #  of the change (insert, delete, move from, move to).  The code determines
  349. #  which color to use when the line is displayed.
  350. #
  351. #
  352. local remote_win
  353.  
  354. local function vdiff( vdiffOutput, refWinName, tgtWinName, shape )
  355. {
  356.    local delta
  357.    local titleb1, titleb2
  358.    local called_again
  359.    local errors
  360.  
  361.    cw                 = current_window
  362.    old_wflags         = window_flags
  363.    old_window         = current_window
  364.    called_again       = (argcount() != 4)
  365.    old_current_buffer = current_buffer
  366.  
  367.    if ( !called_again )
  368.    {
  369.       delete( vdiff_changes )
  370.  
  371.       vdiff_prev_status[ "refname" ]   = refWinName
  372.       vdiff_prev_status[ "tgtname" ]   = tgtWinName
  373.       vdiff_prev_status[ "shape"   ]   = shape
  374.  
  375.       message( "Constructing differences..." )
  376.    } 
  377.    else 
  378.    {
  379.       if ( !vdiff_prev_status || !vdiff_changes )
  380.       {
  381.          notify( "VDIFF must be run first with the `comparison' option." )
  382.          return 0
  383.       }
  384.       refWinName  = vdiff_prev_status[ "refname" ]
  385.       tgtWinName  = vdiff_prev_status[ "tgtname" ]
  386.       shape       = vdiff_prev_status[ "shape"   ]
  387.    }
  388.  
  389.    # create windows for reference and target files
  390.    #
  391.  
  392.    remote_win = create_remote_window( "PVCS Vdiff" )
  393.    mdi_mode = 1
  394.  
  395.    status_bar_flags = STB_MESSAGES + STB_LINE_COLUMN
  396.  
  397.    vdiff_menu() 
  398.    old_menu = change_menu(menu, remote_win)
  399.  
  400.    vdiff_wins[0] = create_factory_window( 0, 0, 0, 0, 0x10113 + 0x8, remote_win )
  401.    vdiff_wins[1] = create_factory_window( 0, 0, 0, 0, 0x10113 + 0x8, remote_win )
  402.  
  403.    # create buffers for reference and target files
  404.    #
  405.    if ( !called_again )
  406.    {
  407.       if ( vdiff_bufs )
  408.       {
  409.          delete_buffer( vdiff_bufs[0] )
  410.          delete_buffer( vdiff_bufs[1] )
  411.       }
  412.  
  413.       vdiff_bufs[0] = create_buffer( "VDIFF Reference", "", BUFFER_SYSTEM + BUFFER_NO_UNDO )
  414.       vdiff_bufs[1] = create_buffer( "VDIFF Target", "", BUFFER_SYSTEM + BUFFER_NO_UNDO )
  415.    }
  416.    attach_window_buffer( vdiff_wins[0], vdiff_bufs[0] )
  417.    attach_window_buffer( vdiff_wins[1], vdiff_bufs[1] )
  418.  
  419.    # assemble reference and target buffers
  420.    #
  421.    if ( !called_again )
  422.    {
  423.       current_window = vdiff_wins[0]
  424.       errors = vdiff_build_buffer( vdiffOutput, 0 )      # reference
  425.       if ( !errors )
  426.       {
  427.          current_window = vdiff_wins[1]
  428.          errors = vdiff_build_buffer( vdiffOutput, 1 )   # target
  429.       }
  430.    }
  431.  
  432.    if ( errors )
  433.    {
  434.       delete( vdiff_changes )
  435.       delete( vdiff_prev_status )
  436.       if ( errors == 1 )
  437.       {
  438.          # display error messages in current window
  439.          assign_current_window( cw )
  440. #        pvcs_system_output( "VDIFF output", vdiffOutput, 1 )
  441.       } 
  442.       else 
  443.          warning( "Unable to process vdiff output / wrong vdiff version" )
  444.    } 
  445.    else 
  446.    {
  447.       set_cursor( 0 )      # set block cursor
  448.  
  449.       current_window = vdiff_wins[1]
  450.       current_buffer = vdiff_bufs[1]
  451.       goto_buffer_top()
  452.       update_current_view()
  453.       buffer_name = tgtWinName
  454.  
  455.       if ( filemode(pvcs_vdiff_arr["4"]) != -1 )
  456.       {
  457.          if ( !pvcs_vdiff_arr["3"] )
  458.             buffer_filename = pvcs_vdiff_arr["4"]
  459.       }
  460.  
  461.       current_window = vdiff_wins[0]
  462.       current_buffer = vdiff_bufs[0]
  463.       goto_buffer_top()
  464.       update_current_view()
  465.       buffer_name = refWinName
  466.  
  467.       if ( filemode(pvcs_vdiff_arr["2"]) != -1 )
  468.       {
  469.          if ( !pvcs_vdiff_arr["1"] )
  470.             buffer_filename = pvcs_vdiff_arr["2"]
  471.       }
  472.  
  473.       vdiff_win_num = 0    # current vdiff window
  474.  
  475.       if ( shape == "horz" )  # tiled, one above the other
  476.       {          
  477.          delta = display_height / 2
  478.    
  479.          frame_window( 0, 0, display_width, delta, vdiff_wins[0] )
  480.    
  481.          frame_window( 0, delta, display_width, ((display_height+1)/2)-1, vdiff_wins[1] )
  482.          current_window = vdiff_wins[0]
  483.       }
  484.       else     # tiled, side by side
  485.       {
  486.          delta = display_width / 2
  487.  
  488.          frame_window( 0, 0, delta, display_height - 1, vdiff_wins[0] )
  489.    
  490.          frame_window( delta, 0, delta, display_height - 1, vdiff_wins[1] )
  491.          current_window = vdiff_wins[0]
  492.       }
  493.  
  494.       restore_window(vdiff_wins[1])
  495.       restore_window(vdiff_wins[0])
  496.  
  497.       vdiff_pageup()
  498.  
  499.       message( " n=Next change  p=Prev change  <Esc> to exit" )
  500.       attach_event_handler( EVENT.NEW_CURNT_EDITWIN,  function_id("editwin_changed") )
  501.       setup_vdiff()
  502.  
  503.       return
  504.    }
  505.  
  506.    delete_window( vdiff_wins[0] )
  507.    delete_window( vdiff_wins[1] )
  508.    delete_remote_window( remote_win )
  509.  
  510.    current_buffer = old_current_buffer
  511. }
  512.  
  513. local function setup_vdiff()
  514. {
  515.    # create a keymap for use in the vdiff windows
  516.    #
  517.    kmp = create_keymap( empty_keymap )
  518.    push_keymap( kmp )
  519.  
  520.    delete_event(EVENT.LMOUSE_DRAG,      function_id("lmouse_drag"    )  )
  521.    delete_event(EVENT.MOUSE_LEFT_DOWN,  function_id("mouse_left_down")  )
  522.    delete_event(EVENT.MOUSE_LEFT_UP,    function_id("mouse_left_up"  )  )
  523.    delete_event(EVENT.RESIZE_EDITWIN,   function_id("resize_editwin" )  )
  524.  
  525.    attach_event_handler( EVENT.MOUSE_LEFT_DOWN,    function_id("beep") )
  526.    attach_event_handler( EVENT.MOUSE_RIGHT_DOWN,   function_id("beep") )
  527.    attach_event_handler( EVENT.RESIZE_EDITWIN,     function_id("vdiff_resize") )
  528.  
  529.    assign_key( "<Up>",              "vdiff_up" )
  530.    assign_key( "<Down>",            "vdiff_down" )
  531.    assign_key( "<Left>",            "vdiff_left" )
  532.    assign_key( "<Right>",           "vdiff_right" )
  533.    assign_key( "<Home>",            "vdiff_home" )
  534.    assign_key( "<End>",             "vdiff_end" )
  535.    assign_key( "<PageUp>",          "vdiff_pageup" )
  536.    assign_key( "<PageDown>",        "vdiff_pagedn" )
  537.    assign_key( "<Ctrl-PageUp>",     "vdiff_top" )
  538.    assign_key( "<Ctrl-PageDown>",   "vdiff_bottom" )
  539.    assign_key( "n",                 "vdiff_next" )
  540.    assign_key( "N",                 "vdiff_next" )
  541.    assign_key( "p",                 "vdiff_prev" )
  542.    assign_key( "P",                 "vdiff_prev" )
  543.    assign_key( "<Esc>",             "exit_vdiff" )
  544.  
  545.    attach_event_handler( EVENT.CLOSING_REMOTE_WINDOW, function_id("close_vdiff") )
  546. }
  547.  
  548. global function editwin_changed()
  549. {
  550.    if ( current_editor == remote_win )
  551.    {
  552.       if ( in_vdiff == FALSE )
  553.       {
  554.          setup_vdiff()
  555.          in_vdiff = TRUE
  556.       }
  557.    }
  558.    else
  559.    {
  560.       if ( in_vdiff == TRUE )
  561.       {
  562.          cleanup_vdiff()   
  563.          in_vdiff = FALSE
  564.       }
  565.    }
  566. }
  567.  
  568. local function cleanup_vdiff()
  569. {
  570.    attach_event_handler(EVENT.LMOUSE_DRAG,      function_id("lmouse_drag"     )  )
  571.    attach_event_handler(EVENT.MOUSE_LEFT_DOWN,  function_id("mouse_left_down" )  )
  572.    attach_event_handler(EVENT.MOUSE_LEFT_UP,    function_id("mouse_left_up"   )  )
  573.    attach_event_handler(EVENT.RESIZE_EDITWIN,   function_id("resize_editwin"  )  )
  574.  
  575.    delete_event( EVENT.MOUSE_LEFT_DOWN,    function_id("beep") )
  576.    delete_event( EVENT.MOUSE_RIGHT_DOWN,   function_id("beep") )
  577.    delete_event( EVENT.RESIZE_EDITWIN,     function_id("vdiff_resize") )
  578.  
  579.    pop_keymap()
  580.    delete_keymap( kmp )
  581.    
  582.    message( "" )
  583.    set_cursor( 1 )      # restore cursor
  584. }
  585.  
  586. # this function is called when the user double clicks on
  587. # the system icon.  We don't need to delete any windows or
  588. # the remote editor window because that will be done for 
  589. # us in this case.
  590. global function close_vdiff()
  591. {
  592.    local i
  593.  
  594.    delete_event( EVENT.NEW_CURNT_EDITWIN,  function_id("editwin_changed") )
  595.    delete_event( EVENT.CLOSING_REMOTE_WINDOW, function_id("close_vdiff") )
  596.  
  597.    cleanup_vdiff()
  598.  
  599.    # delete our local list that maps function id's to menu item
  600.    # id's.  This list was created during the append_menuitem calls.   
  601.    for ( i = IDM_FIRST_ITEM; i <= IDM_LAST_ITEM; i++ )
  602.       if ( i in menu_functions )
  603.          delete menu_functions[i]
  604.  
  605.    pvcs_cleanup_temp_files()
  606.    delete( pvcs_dlg_arr )
  607.    in_vdiff = FALSE
  608. }
  609.  
  610. global function exit_vdiff( no_delete )
  611. {
  612.    local i
  613.    local old_create_new_bufwin = create_new_bufwin
  614.  
  615.    if ( in_vdiff )
  616.    {
  617.       delete_event( EVENT.NEW_CURNT_EDITWIN,  function_id("editwin_changed") )
  618.       delete_event( EVENT.CLOSING_REMOTE_WINDOW, function_id("close_vdiff") )
  619.  
  620.       cleanup_vdiff()
  621.  
  622.       create_new_bufwin = 0
  623.  
  624.       delete_window( vdiff_wins[0] )
  625.       delete_window( vdiff_wins[1] )
  626.  
  627.       delete_menu( submenu, remote_win )
  628.       delete_menu( menu, remote_win )
  629.  
  630.       delete_remote_window( remote_win )
  631.  
  632.       create_new_bufwin = old_create_new_bufwin
  633.  
  634.       # delete our local list that maps function id's to menu item
  635.       # id's.  This list was created during the append_menuitem calls.   
  636.       for ( i = IDM_FIRST_ITEM; i <= IDM_LAST_ITEM; i++ )
  637.          if ( i in menu_functions )
  638.             delete menu_functions[i]
  639.  
  640.       pvcs_cleanup_temp_files()
  641.       delete( pvcs_dlg_arr )
  642.       in_vdiff = FALSE
  643.  
  644.       current_window = cw
  645.  
  646.       display_redraw()
  647.    }
  648. }
  649.  
  650. global function prev_vdiff()
  651. {
  652.    in_vdiff = TRUE
  653.          
  654.    # display vdiff output
  655.    vdiff()
  656. }
  657.  
  658.  
  659. #  The following routines perform the actions for each key
  660. #  assigned.
  661. #
  662. #  vdiff_left_press()    -  scroll while mouse left down
  663. #  vdiff_left_release()  -  handle mouse left release
  664. #  vdiff_home()          -  goto beginning of line
  665. #  vdiff_end()           -  goto end of line
  666. #  vdiff_top()           -  goto top of buffer
  667. #  vdiff_bottom()        -  goto end of buffer
  668. #  vdiff_pageup()        -  scroll one page up
  669. #  vdiff_pagedn()        -  scroll one page down
  670. #  vdiff_right()         -  scroll one character right
  671. #  vdiff_left()          -  scroll one character left
  672. #  vdiff_next()          -  goto next difference
  673. #  vdiff_prev()          -  goto previous difference
  674. #  vdiff_goto()          -  goto specific line
  675. #
  676.  
  677. global function vdiff_resize()
  678. {
  679.    local width, height
  680.    if ( pvcs_vdiff_arr[7] == "1" )
  681.       {
  682.       frame_window( 0,                 0, display_width / 2, display_height, vdiff_wins[0] )
  683.       frame_window( display_width / 2,    0, display_width / 2, display_height, vdiff_wins[1] )
  684.       }
  685.    else
  686.       {
  687.       frame_window( 0, 0,                 display_width, display_height / 2, vdiff_wins[0] )
  688.       frame_window( 0, display_height / 2, display_width, display_height / 2, vdiff_wins[1] )
  689.       }
  690. }
  691.  
  692. function vdiff_up()
  693. {
  694.    flush_keyboard()
  695.  
  696.    execute_on_window( "scroll_vertical -1", vdiff_wins[0] )
  697.  
  698.    execute_on_window( "scroll_vertical -1", vdiff_wins[1] )
  699.  
  700. #   current_window = vdiff_wins[ 0 ]
  701. #   scroll_vertical( -1 )
  702. #   update_current_view()
  703. #
  704. #   current_window = vdiff_wins[ 1 ]
  705. #   scroll_vertical( -1 )
  706. #   update_current_view()
  707. }
  708.  
  709. function vdiff_down()
  710. {
  711.    flush_keyboard()
  712.  
  713.    execute_on_window( "scroll_vertical 1", vdiff_wins[0] )
  714.  
  715.    execute_on_window( "scroll_vertical 1", vdiff_wins[1] )
  716.  
  717. }
  718.  
  719. function vdiff_left()
  720. {
  721.    flush_keyboard()
  722.  
  723.    execute_on_window( "scroll_horizontal -1", vdiff_wins[0] )
  724.  
  725.    execute_on_window( "scroll_horizontal -1", vdiff_wins[1] )
  726.  
  727. }
  728.  
  729. function vdiff_right()
  730. {
  731.    flush_keyboard()
  732.  
  733.    execute_on_window( "scroll_horizontal 1", vdiff_wins[0] )
  734.  
  735.    execute_on_window( "scroll_horizontal 1", vdiff_wins[1] )
  736.  
  737. }
  738.  
  739. function vdiff_home()
  740. {
  741.    flush_keyboard()
  742.  
  743.    execute_on_window( "goto_bol", vdiff_wins[0] )
  744.  
  745.    execute_on_window( "goto_bol", vdiff_wins[1] )
  746.  
  747. }
  748.  
  749. function vdiff_end()
  750. {
  751.    flush_keyboard()
  752.  
  753.    execute_on_window( "goto_eol", vdiff_wins[0] )
  754.  
  755.    execute_on_window( "goto_eol", vdiff_wins[1] )
  756.  
  757. }
  758.  
  759. function vdiff_pageup()
  760. {
  761.    flush_keyboard()
  762.  
  763.    execute_on_window( "page_up 1", vdiff_wins[0] )
  764.  
  765.    execute_on_window( "page_up 1", vdiff_wins[1] )
  766.  
  767. }
  768.  
  769. function vdiff_pagedn()
  770. {
  771.    flush_keyboard()
  772.  
  773.    execute_on_window( "page_down 1", vdiff_wins[0] )
  774.  
  775.    execute_on_window( "page_down 1", vdiff_wins[1] )
  776.  
  777. }
  778.  
  779. function vdiff_top()
  780. {
  781.    vdiff_goto( 1 )
  782. }
  783.  
  784. function vdiff_bottom()
  785. {
  786.    vdiff_goto( buffer_last_line - window_text_height )
  787. }
  788.  
  789. function vdiff_next()
  790. {
  791.    local cl = current_line
  792.    local action
  793.    local line
  794.  
  795.    # find the end of the current block of changes
  796.    if ( cl in vdiff_changes ){
  797.       action = vdiff_changes[ cl ]
  798.       while (( ++cl in vdiff_changes) \
  799.             && ( vdiff_changes[ cl ] == action )){
  800.       }
  801.    }
  802.  
  803.    # find the start of the next block of changes
  804.    for ( line in vdiff_changes ){
  805.       if ( line+0 >= cl ){
  806.          vdiff_goto( line )
  807.          return
  808.       }
  809.    }
  810.    beep()
  811. }
  812.  
  813. function vdiff_prev()
  814. {
  815.    local cl = current_line
  816.    local action
  817.    local line
  818.    local prev
  819.  
  820.    # find the start of the current block of changes
  821.    if ( cl in vdiff_changes ){
  822.       action = vdiff_changes[ cl ]
  823.       while (( --cl in vdiff_changes) \
  824.             && ( vdiff_changes[ cl ] == action )){
  825.       }
  826.    }
  827.  
  828.    # find the end of the previous block of changes
  829.    for ( line in vdiff_changes ){
  830.       if ( line+0 >= cl ){
  831.          break
  832.       }
  833.       prev = line
  834.    }
  835.  
  836.    # find the start of the block just found
  837.    if ( prev ){
  838.       line = prev--
  839.       action = vdiff_changes[ line ]
  840.       while (( prev in vdiff_changes) \
  841.             && ( vdiff_changes[ prev ] == action )){
  842.          line = prev--
  843.       }
  844.       vdiff_goto( line )
  845.       return
  846.    }
  847.    beep()
  848. }
  849.  
  850. local function vdiff_goto( ln, col )
  851. {
  852.    if ( argcount() == 0 )
  853.       {
  854.       ln = current_line
  855.       col = current_column
  856.       }
  857.    else if ( argcount() == 1 )
  858.  
  859.       col = current_column
  860.  
  861.    execute_on_window( "goto_pos " ln " " col,   vdiff_wins[0] )
  862.    execute_on_window( "scroll_window_top",      vdiff_wins[0] )
  863.  
  864.    execute_on_window( "goto_pos " ln " " col,   vdiff_wins[1] )
  865.    execute_on_window( "scroll_window_top",      vdiff_wins[1] )
  866.  
  867. }
  868.  
  869. #---------------------------------------------------------------------
  870.  
  871. ## build a complete target or reference file from vdiff output
  872. #
  873. # arguments:
  874. #  vdiffOutput - name of vdiff output file
  875. #  win_num     - 0 = build target (new) file
  876. #          1 = build reference (old) file
  877. #
  878. # return code:
  879. #  0 if successful ; non-zero otherwise
  880. #
  881. # returned by side effect:
  882. #  The output is written into the current buffer.
  883. #  The array 'vdiff_changes[]' contains a list of the changed lines.
  884. #  Both of the above will be incomplete or empty in the event of failure.
  885. #
  886. local function vdiff_build_buffer( vdiffOutput, win_num )
  887. {
  888.    local vdiff_prefix[]
  889.    local bufname
  890.    local action
  891.    local blank_lines
  892.    local c
  893.  
  894.    vdiff_prefix[ " " ] = 0    # context
  895.    vdiff_prefix[ "=" ] = 9    # eof
  896.  
  897.    # read vdiff output into the current buffer
  898.    read_file( vdiffOutput )
  899.  
  900.    if ( win_num == 0 )     # reference buffer
  901.    { 
  902.       vdiff_prefix[ "+" ] = 1    # delete
  903.       vdiff_prefix[ "-" ] = 2    # retain
  904.       vdiff_prefix[ ">" ] = 1    # moved from
  905.       vdiff_prefix[ "<" ] = 2    # moved to
  906.  
  907.       if ( Syntax("vdiff_ref") )
  908.       {
  909.          languages_id = "vdiff_ref"
  910.          syntax_highlight = 1
  911.       }
  912.    } 
  913.    else                    # target buffer
  914.    {          
  915.       vdiff_prefix[ "+" ] = 2    # retain
  916.       vdiff_prefix[ "-" ] = 1    # delete
  917.       vdiff_prefix[ ">" ] = 2    # moved to
  918.       vdiff_prefix[ "<" ] = 1    # moved from
  919.  
  920.       if ( Syntax("vdiff_target") )
  921.       {
  922.          languages_id = "vdiff_target"
  923.          syntax_highlight = 1
  924.       }
  925.    }
  926.  
  927.    # strip off vdiff header lines
  928.    goto_buffer_top()
  929.  
  930.    do {
  931.       if ( !delete_line() )
  932.          return 1 # not a valid vdiff file
  933.  
  934.       } 
  935.    while ( read_buffer(1) != "=" )
  936.  
  937.    delete_line()
  938.  
  939.    if ( pvcs_vdiff_arr[ 5 ] == "0" )
  940.       {
  941.       # remove unwanted line number info
  942.       goto_pos( buffer_last_line, 18 )
  943.       drop_anchor( COLUMN_SELECTION )
  944.       goto_pos( 1, 2 )
  945.       delete_chars()
  946.       current_column = 1
  947.       }
  948.    
  949.    # process each line depending on the first character
  950.    while ( 1 )
  951.       {
  952.       # define an action to perform on this line
  953.       c = read_buffer(1)
  954.  
  955.       if ( !(c in vdiff_prefix ) )
  956.          break
  957.  
  958.       action = vdiff_prefix[ c ]
  959.  
  960.       # process the line
  961.       if ( action == 0 )      # context
  962.          {     
  963.          if ( blank_lines )
  964.             {
  965.             while ( blank_lines-- > 0 )
  966.             {
  967.                insert_string("^")
  968.                insert_newline()
  969.             }
  970.  
  971.             blank_lines = 0
  972.             }
  973.  
  974.          if ( !search( "^[^ ]", SEARCH_FWD_REGEX_ADV ) )
  975.             break
  976.  
  977.          continue # don't increment line count
  978.  
  979.          } 
  980.       else if ( action == 1 )    # delete
  981.          { 
  982.          delete_line()
  983.          blank_lines++
  984.          continue # don't increment line count
  985.          } 
  986.       else if ( action == 2 )    # retain
  987.          { 
  988.          vdiff_changes[ current_line ] += 1 + win_num
  989.          blank_lines--
  990.          } 
  991.       else if ( action == 9 )    # eof
  992.          { 
  993.          delete_line()
  994.  
  995.          # check for unexpected "=" prefix
  996.          if ( current_line != buffer_last_line )
  997.             return 2
  998.  
  999.          goto_buffer_top()
  1000.          toggle_buffer_flags( BUFFER_MODIFIED, 0 )
  1001.          return 0 # successful
  1002.          }
  1003.  
  1004.       if ( !down() )
  1005.          break
  1006.    }
  1007.  
  1008.    return 1 # invalid vdiff prefix or premature end of file
  1009. }
  1010.  
  1011.  
  1012. # Save the current status of the cursor and reset to invisible
  1013. #   OR
  1014. # restore the previous saved status depending on the value of "on"
  1015. #
  1016. local cursors[]
  1017.  
  1018. local function set_cursor( on ){
  1019.    if ( on ){
  1020.       cursor_normal           = cursors[1]
  1021.       cursor_virtual          = cursors[2]
  1022.       cursor_overtype         = cursors[3]
  1023.       cursor_virtual_overtype = cursors[4]
  1024.    } else {
  1025.       cursors[1] = cursor_normal
  1026.       cursors[2] = cursor_virtual
  1027.       cursors[3] = cursor_overtype
  1028.       cursors[4] = cursor_virtual_overtype
  1029.       cursor_normal   = \
  1030.       cursor_virtual  = \
  1031.       cursor_overtype = \
  1032.       cursor_virtual_overtype = 0xFFFF
  1033.    }
  1034. }
  1035.  
  1036. local   menu      = 0
  1037. local   submenu   = 0
  1038.  
  1039. local function vdiff_menu()
  1040. {
  1041.       menu = create_menu()
  1042.       submenu = create_menu()
  1043.  
  1044.       append_menuitem( submenu, IDM_PREV,        0x0408, "~Previous Change", "vdiff_prev" )
  1045.       append_menuitem( submenu, IDM_NEXT,        0x0408, "~Next Change", "vdiff_next" )
  1046.  
  1047.       append_menuitem( submenu, 0, 0x0100)
  1048.  
  1049.       append_menuitem( submenu, IDM_EXIT_VDIFF,  0x0408, "~Exit Vdiff", "exit_vdiff" )
  1050.       append_menuitem( menu,    IDM_MVDIFF,      0x0208, "~Vdiff", submenu )
  1051.  
  1052.       return menu
  1053. }
  1054.  
  1055. global function load_factory_vdiff_ref_syntax()
  1056. {
  1057.    local type = "vdiff_ref";
  1058.  
  1059.    add_syntax_category(type, 0, "All", COLOR_WHITE, COLOR_DARK_BLUE);
  1060.    #  set_factory_categories( type );
  1061.  
  1062.    add_syntax_item(type, LINE, "+", 0x01020000 + VDIFF_MINUS)
  1063.    add_syntax_item(type, LINE, "^", 0x01020000 + VDIFF_BLANK)
  1064.    add_syntax_item(type, LINE, ">", 0x01020000 + VDIFF_MINUS)
  1065.    add_syntax_item(type, LINE, "-", 0x01020000 + VDIFF_PLUS)
  1066.    add_syntax_item(type, LINE, "<", 0x01020000 + VDIFF_PLUS)
  1067.    add_syntax_item(type, LINE, "=", 0x01020000 + VDIFF_PLUS)
  1068.  
  1069.    set_style_delimiters(type, "");
  1070.    set_escape_character(type, "");
  1071. }
  1072.  
  1073. global function add_vdiff_target_type()
  1074. {
  1075.    add_type("vdiff_target", "", "text", "4 7", "1 77", "", "\\",
  1076.             default_buffer_flags, 0, 1, "()[];:,='", 1);
  1077. }
  1078.  
  1079. global function add_vdiff_ref_type()
  1080. {
  1081.    add_type("vdiff_ref", "", "text", "4 7", "1 77", "", "\\",
  1082.             default_buffer_flags, 0, 1, "()[];:,='", 1);
  1083. }
  1084.  
  1085. global function load_factory_vdiff_target_syntax()
  1086. {
  1087.    local type = "vdiff_target";
  1088.  
  1089.    add_syntax_category(type, 0, "All", COLOR_WHITE, COLOR_BROWN);
  1090.  
  1091.    add_syntax_item(type, LINE, "+", 0x01020000 + VDIFF_PLUS)
  1092.    add_syntax_item(type, LINE, "^", 0x01020000 + VDIFF_BLANK)
  1093.    add_syntax_item(type, LINE, ">", 0x01020000 + VDIFF_PLUS)
  1094.    add_syntax_item(type, LINE, "-", 0x01020000 + VDIFF_MINUS)
  1095.    add_syntax_item(type, LINE, "<", 0x01020000 + VDIFF_MINUS)
  1096.    add_syntax_item(type, LINE, "=", 0x01020000 + VDIFF_MINUS)
  1097.  
  1098.    set_style_delimiters(type, "");
  1099.    set_escape_character(type, "");
  1100. }
  1101.