home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 16 / 16.iso / w / w055 / 4.ddi / SOURCES.LIF / PVCS.PEL < prev    next >
Encoding:
Text File  |  1990-09-27  |  9.2 KB  |  370 lines

  1. # $Header:   P:/source/ppee/macros/pvcs.pev   1.50   26 Sep 1990 17:09:28   skipr  $
  2.  
  3. ##############################################################################
  4. #
  5. #           Sage Software - POLYTRON Division
  6. #             1700 NW 167th Place
  7. #               Beaverton, OR 97006
  8. #
  9. #   Copyright 1990, Sage Software, Inc.
  10. #
  11. #   Permission is hereby granted for licensed users of Sage Professional
  12. #   Editor and PolyAwk to copy and modify this source code for their own
  13. #   personal use.  These derivative works may be distributed only to other
  14. #   licensed Sage Professional Editor and PolyAwk users.  All other usage
  15. #   is prohibited without express written permission from Sage Software.
  16. #
  17. ##############################################################################
  18.  
  19. #### $Workfile:   pvcs.pel  $: PVCS support
  20.  
  21.  
  22. ### global variables
  23.  
  24. global    PVCS_DISABLED          = 0x00
  25. global    PVCS_ENABLE_GETS       = 0x01
  26. global    PVCS_ENABLE_EMPTY_GETS = 0x02
  27.  
  28. ### local variables
  29.  
  30. global    pvcsEnabled
  31. local    pvcsPutEnabled
  32. local    pvcsEmptyEnabled
  33. local    pvcsPutId
  34. local    pvcsGetId
  35. local    pvcsGetEmptyId
  36. local    pvcsBuffersGot
  37. local    pvcsRevision = ""
  38.  
  39.  
  40. ## pvcs() and
  41. ## toggle_pvcs()
  42. #
  43. #  Enable PVCS get and put.  The "on" argument can be set to one of 
  44. #  four values depending on the desired configuration:
  45. #
  46. #     PVCS_DISABLED          = 0 - disable PVCS
  47. #     PVCS_ENABLE_GETS       = 1 - enable get and put via existing file edits
  48. #     PVCS_ENABLE_EMPTY_GETS = 2 - enable get and put via non-existant 
  49. #                                  file reads
  50. #     PVCS_ENABLE_GETS +
  51. #     PVCS_ENABLE_EMPTY_GETS = 3 - enable get and put via existing and
  52. #                                  non-existant files
  53. #
  54. global function pvcs( on ){
  55.     if (argcount())
  56.         toggle_pvcs( on )
  57.     else
  58.         toggle_pvcs()
  59. }
  60.  
  61. global function toggle_pvcs( on ){
  62.  
  63.     if ( !argcount()) {
  64.         on = !pvcsEnabled
  65.         message( "PVCS " (on ? "Enabled." : "Disabled." ))
  66.     } else {
  67.         on = 0+on
  68.     }
  69.  
  70.     #
  71.     # enable puts for all files
  72.     #
  73.     if (on && !pvcsPutEnabled) {
  74.         pvcsPutEnabled = 1
  75.         attach_event_handler( EVENT_EDIT_FILE_SAVE,    \
  76.             pvcsPutId = function_id( "pvcs_put_buffer" ))
  77.     } else if (!on && pvcsPutEnabled) {
  78.         pvcsPutEnabled = 0
  79.         delete_event( EVENT_EDIT_FILE_SAVE, pvcsPutId )
  80.     }
  81.  
  82.     #
  83.     # enable gets for existing files
  84.     #
  85.     if (and( on, PVCS_ENABLE_GETS ) && !pvcsEnabled) {
  86.         pvcsEnabled = 1
  87.         attach_event_handler( EVENT_FIRST_MOD,        \
  88.             pvcsGetId = function_id( "pvcs_get_existing_buffer" ))
  89.     } else if (!and( on, PVCS_ENABLE_GETS ) && pvcsEnabled) {
  90.         pvcsEnabled = 0
  91.         delete_event( EVENT_FIRST_MOD, pvcsGetId )
  92.     }
  93.  
  94.     #
  95.     # enable gets for non-existing files
  96.     #
  97.     if (and( on, PVCS_ENABLE_EMPTY_GETS ) && !pvcsEmptyEnabled) {
  98.         pvcsEmptyEnabled = 1
  99.         attach_event_handler( EVENT_NEW_EDIT_FILE,    \
  100.             pvcsGetEmptyId = function_id( "pvcs_get_empty" ))
  101.     } else if (!and( on, PVCS_ENABLE_EMPTY_GETS ) && (pvcsEmptyEnabled)) {
  102.         pvcsEmptyEnabled = 0
  103.         delete_event( EVENT_NEW_EDIT_FILE, pvcsGetEmptyId )
  104.     }
  105. }
  106.  
  107.  
  108. ###
  109. ### put up a menu of PVCS system commands
  110. ###
  111.  
  112. global function pvcs_menu(){
  113.     local    priorPvcsEnabled
  114.     local    cmd
  115.     local    options = ""
  116.     local    str = " Get\n Put\n Ident\n Regen\n VCS\n Vcompress\n Vdel\n Vdiff\n VJournal\n Vlog\n Vlogin\n Vmrg\n Vname"
  117.  
  118.     cmd = list_vertical( str, 10, display_height - 22, 15, 18 )
  119.     cmd = tolower( ltrim( cmd ))
  120.  
  121.     if (cmd != "") {
  122.  
  123.         # default actions for selected commands
  124.         if (cmd == "get") {
  125.             pvcs_get_existing_buffer( 1 )
  126.             return
  127.         } else if (cmd == "put") {
  128.             pvcs_put_buffer( 1 )
  129.             return
  130.         } else if (cmd == "vdiff") {
  131.             options = "-r " buffer_filename
  132.         }
  133.  
  134.         str = prompt_history( "PVCS" toupper( cmd ),    \
  135.             "PVCS Command:" cmd " ",         \
  136.             options )
  137.  
  138.         if ( str != "" ) {
  139.  
  140.             # write the buffer; prevent conflicts with
  141.             # pvcs "put" events
  142.             priorPvcsEnabled = pvcsEnabled
  143.             pvcsEnabled = 0
  144.             write_buffer_key()
  145.             pvcsEnabled = priorPvcsEnabled
  146.  
  147.             push_dir( path_path( buffer_filename ))
  148.  
  149.             if ( cmd == "vdiff" ||            \
  150.                     cmd == "vjournal" ||    \
  151.                     cmd == "vlog" ) {
  152.                 dos_buffer( cmd " " str )
  153.             } else {
  154.                 system_window_command( cmd " " str )
  155.             }
  156.  
  157.             pop_dir()
  158.  
  159.             return
  160.         }
  161.     }
  162. }
  163.  
  164.  
  165. ###
  166. ### event handlers for PVCS
  167. ###
  168.  
  169. ### event handler invoked when attempting to edit a non-exisiting file
  170.  
  171. global function pvcs_get_empty(){
  172.     if ( pvcsEnabled && filemode( buffer_filename ) < 0) {
  173.         # file doesn't exist
  174.         pvcs_get_existing_buffer( 1 )
  175.     }
  176. }
  177.  
  178.  
  179. ### event handler invoked when attempting to edit a read-only buffer
  180.  
  181. ## pvcs_get_existing_buffer()
  182. #
  183. # forceget instructs not to delete the buffer and reload, just perform
  184. # the PVCS command.
  185. #
  186. global function pvcs_get_existing_buffer( forceget ){
  187.     local    fmode = filemode( buffer_filename )
  188.     local    cmd
  189.  
  190.     # check the file's read-only status
  191.  
  192.     if ( (pvcsEnabled && ((fmode > 0) && and( fmode, _READ_ONLY )))    \
  193.             || forceget ) {
  194.  
  195.         cmd = factory_prompt( \
  196.             "Read-only buffer : enter a PVCS \"get\" command (<Esc> to cancel)",
  197.             "PVCSGET",
  198.             "cmd: ",
  199.             "get -L " pvcsRevision buffer_filename )
  200.  
  201.         if ( cmd ) {
  202.             # perform the GET command
  203.             pvcsSystemCommand( cmd, forceget )
  204.  
  205.             # add this buffer to the list if we have it locked
  206.             if ( !and( buffer_flags, BUFFER_READ_ONLY )) {
  207.                 pvcsBuffersGot[ current_buffer ] = \
  208.                             (cmd ~ /<-[Ll]/)
  209.             }
  210.         }
  211.     }
  212. }
  213.  
  214.  
  215. ### event handler invoked when attempting to write a buffer
  216.  
  217. global function pvcs_put_buffer( forceput ){
  218.     local    priorPvcsEnabled
  219.     local    cmd
  220.  
  221.     # see if the current buffer originated from a PVCS get
  222.  
  223.     if ( (pvcsEnabled &&    \
  224.                 current_buffer in pvcsBuffersGot &&    \
  225.                 pvcsBuffersGot[current_buffer] )    \
  226.             || forceput ) {
  227.  
  228.         cmd = factory_prompt( \
  229.                 "Enter a PVCS \"put\" command (<Esc> to cancel)",
  230.                 "PVCSPUT",
  231.                 "cmd: ",
  232.                 "put " pvcsRevision buffer_filename )
  233.  
  234.         if ( cmd ) {
  235.  
  236.             # write the current buffer to disk if necessary,
  237.             priorPvcsEnabled = pvcsEnabled
  238.             pvcsEnabled = 0        # prevent recursion
  239.             write_buffer_key()
  240.             pvcsEnabled = priorPvcsEnabled
  241.  
  242.             # perform the put command
  243.             pvcsSystemCommand( cmd )
  244.         }
  245.     }
  246. }
  247.  
  248.  
  249. ## support functions for pvcs commands
  250.  
  251. local    bufferSavedState
  252.  
  253. local function pvcsSystemCommand( cmd, forceget ) {
  254.  
  255.     # save the current state of the current buffer
  256.     saveBufferState()
  257.  
  258.     # change to the directory where the file is
  259.     push_dir( path_path( buffer_filename ))
  260.  
  261.     # do the shell-in-a-box command
  262.     system_window_command( cmd )
  263.  
  264.     # restore the prior working directory
  265.     pop_dir()
  266.  
  267.     # re-edit the file and restore the state of the
  268.     # buffer to what it was, depending on the file's
  269.     # new read-write/read-only status, etc.
  270.     if (!forceget)
  271.         rereadNewBuffer()
  272.  
  273.     # if a wildcard GET or PUT was performed, check all buffers
  274.     # for conflicts
  275.     if ( cmd ~ /[*?][^ \t]*$/ ) {
  276.         checkAllFilemodes();
  277.     }
  278. }
  279.  
  280. local function checkAllFilemodes(){
  281.     #
  282.     # PVCS GET and PUT commands can result in changes to the filemodes
  283.     # of one or more files.  This function synchronizes the read-write/
  284.     # read-only status of all buffers currently in the editor with their
  285.     # corresponding disk files.
  286.     #
  287.     local    priorBuffer = current_buffer
  288.     local    sentinel = next_buffer()
  289.     local    fmode
  290.  
  291.     do {
  292.         fmode = filemode( buffer_filename )
  293.         if ( fmode >= 0 ) {
  294.             if ( !and( fmode, _READ_ONLY ) !=    \
  295.                  !and( buffer_flags, BUFFER_READ_ONLY ) ) {
  296.                 # read only status differs:
  297.                 saveBufferState()
  298.                 bufferSavedState[ "filetime" ] = 0
  299.                 rereadNewBuffer()
  300.             }
  301.         }
  302.     } while( next_buffer() != sentinel )
  303.  
  304.     current_buffer = priorBuffer
  305. }
  306.  
  307. local function saveBufferState(){
  308.     #
  309.     # save salient info about the current buffer in an array
  310.     #
  311.     bufferSavedState[ "filename" ]    = buffer_filename
  312.     bufferSavedState[ "filetime" ]    = filetime( buffer_filename )
  313.     bufferSavedState[ "name" ]    = buffer_name
  314.     bufferSavedState[ "flags" ]    = buffer_flags
  315.     bufferSavedState[ "line" ]    = current_line
  316.     bufferSavedState[ "column" ]    = current_column
  317.     bufferSavedState[ "keymap" ]    = buffer_keymap
  318.     bufferSavedState[ "tabs" ]    = buffer_tabs
  319. }
  320.  
  321. local function rereadNewBuffer(){
  322.     local    fmode
  323.  
  324.     #
  325.     # re-read a buffer which has possibly been changed by a system
  326.     # command, using the attributes saved by function saveBufferState()
  327.     #
  328.     if ( bufferSavedState ) {
  329.  
  330.         # has the disk file changed?
  331.         if ( bufferSavedState[ "filetime" ]    \
  332.                 != filetime( buffer_filename )) {
  333.  
  334.             # delete the current buffer without asking
  335.             #
  336.             buffer_flags = and( buffer_flags,    \
  337.                     not( BUFFER_MODIFIED ))
  338.             delete_buffer()
  339.  
  340.             # create a new buffer with the same attributes
  341.             # as before
  342.             #
  343.             current_buffer = create_buffer(            \
  344.                     bufferSavedState[ "name" ],    \
  345.                     bufferSavedState[ "filename" ],    \
  346.                     bufferSavedState[ "flags" ] )
  347.  
  348.             current_line    = bufferSavedState[ "line" ]
  349.             current_column    = bufferSavedState[ "column" ]
  350.             buffer_keymap    = bufferSavedState[ "keymap" ]
  351.             buffer_tabs    = bufferSavedState[ "tabs" ]
  352.  
  353.             center_cursor()
  354.         }
  355.  
  356.         delete bufferSavedState
  357.     }
  358.  
  359.     # update the read-only bit of the buffer to match the disk file
  360.     #
  361.     fmode = filemode( buffer_filename )
  362.     if ( fmode >= 0 ) {
  363.         set_buffer_flag(            \
  364.             BUFFER_READ_ONLY,        \
  365.             and( fmode, _READ_ONLY ) )
  366.     }
  367.  
  368.     return fmode
  369. }
  370.