Files
TeslaRel410/sda4/BRIEF/MACROS/PVCS.CB
T
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

718 lines
19 KiB
Plaintext

/*
** BRIEF -- Basic Reconfigurable Interactive Editing Facility
**
** Written by Dave Nanian and Michael Strickman.
*/
#include "win_ctrl.h"
/* pvcs.cb:
**
** This macro package makes BRIEF work quite well with PVCS.
*/
#define READ_ONLY 0x01
#define FALSE 0
#define TRUE 1
int _vcs_buf; // Buffer that holds checked out logfile names.
string default_mouse_handler;
int _pvcs_run_cmd (string cmd_line);
string _wp_on (~int margin_val);
void _wp_off ();
/*
** _pvcs_new:
**
** This macro creates a workfile from a PVCS logfile if the file
** does not exist.
*/
string _pvcs_new (~int, ~int checklock)
{
string file_name,
path,
old_msg,
old_path,
old_drive,
just_name;
int deletework,
curr_buf,
old_msg_level;
/*
** First, we retrieve the name of the file we're trying to
** obtain. This name is split into a filename component and
** a path component. We then change to the drive and directory
** of this file, since most version control systems need to be
** run from there to work properly.
**
*/
if (!get_parm (0, deletework))
deletework = TRUE;
deletework = !!deletework;
if (deletework)
{
inq_names (file_name);
path = substr (file_name, 1, rindex (file_name, substr (file_name, 3, 1)));
if (strlen (path) > 3)
path = substr (path, 1, strlen (path) - 1);
just_name = substr (file_name, rindex (file_name, substr (file_name, 3, 1)) + 1);
old_msg_level = inq_msg_level ();
set_msg_level (0);
old_msg = inq_message ();
message ("Retrieving workfile %s...", just_name);
set_msg_level (old_msg_level);
getwd ("", old_drive);
getwd (path, old_path);
cd (path);
cd (substr (path, 1, 2));
/*
** Note that since this file doesn't exist, we can do the get
** without closing the original buffer first.
*/
if (checklock == FALSE && _pvcs_run_cmd ("get (" + just_name + ")") != 0)
message ("%s", old_msg);
else
{
int size,
file_date,
file_time,
attribute;
/*
** If the file has been successfully retrieved, we put its
** name in the _vcs_buf along with its current date, time, size
** and attribute. This information is used later to determine
** whether or not the file should be checked in.
*/
file_pattern (just_name);
if (!find_file (NULL, size, file_date, file_time, attribute))
attribute |= READ_ONLY;
/*
** Note that if the file is read-only at this point, it's
** probably because lock checking is enabled. So, we try to
** check the file out with a lock.
*/
checklock = checklock || (attribute & READ_ONLY);
if (checklock == FALSE || _pvcs_run_cmd ("get -l (" + just_name + ")") == 0)
{
if (!_vcs_buf)
{
_vcs_buf = create_buffer ("PVCS", NULL, 1);
register_macro (5, "_pvcs_exit");
}
curr_buf = set_buffer (_vcs_buf);
insert (file_name + "\n");
if (attribute & READ_ONLY)
{
file_pattern (just_name);
find_file (NULL, size, file_date, file_time, attribute);
insert ("DELETEWORK CHECKLOCK %d %d %d %d\n", size, file_date, file_time, attribute);
}
else
insert ("DELETEWORK NOCHECKLOCK %d %d %d %d\n", size, file_date, file_time, attribute);
delete_buffer (curr_buf);
set_buffer (create_buffer (just_name, file_name));
message ("");
}
else
{
dos ("attrib -r " + just_name + ">&nul");
del (just_name);
message ("%s", old_msg);
}
}
cd (old_path);
cd (substr (old_drive, 1, 2));
}
returns ("");
}
/*
** _pvcs_existing:
**
** This macro creates a workfile from a PVCS logfile if the file
** is read only.
*/
string _pvcs_existing (~int, ~int checklock)
{
string file_name,
path,
old_msg,
old_path,
old_drive,
just_name;
int attribute,
old_msg_level;
/*
** First, we retrieve the name of the file we're trying to
** obtain. This name is split into a filename component and
** a path component. We then change to the drive and directory
** of this file, since most version control systems need to be
** run from there to work properly.
*/
inq_names (file_name);
file_pattern (file_name);
/*
** Note that the file has to exist and be read only before this macro
** does anything. If it doesn't or isn't, we don't have anything to do.
*/
if (find_file (NULL, NULL, NULL, NULL, attribute) != 0 && (attribute & READ_ONLY))
{
path = substr (file_name, 1, rindex (file_name, substr (file_name, 3, 1)));
if (strlen (path) > 3)
path = substr (path, 1, strlen (path) - 1);
just_name = substr (file_name, rindex (file_name, substr (file_name, 3, 1)) + 1);
old_msg_level = inq_msg_level ();
set_msg_level (0);
old_msg = inq_message ();
message ("Retrieving workfile %s...", just_name);
set_msg_level (old_msg_level);
getwd ("", old_drive);
getwd (path, old_path);
cd (path);
cd (substr (path, 1, 2));
/*
** First, we try to get the file without a lock. This won't
** fail due to lock checking; it can only fail because of other
** errors.
**
** Note that since the file exists, we must delete the buffer
** before running get. Otherwise, we might get file sharing
** violations.
*/
delete_buffer (inq_buffer ());
if (checklock == FALSE && _pvcs_run_cmd ("get (" + just_name + ")") != 0)
message ("%s", old_msg);
else
{
int size,
file_date,
file_time;
/*
** If the file has been successfully retrieved, we put its
** name in the _vcs_buf along with its current date, time, size
** and attribute. This information is used later to determine
** whether or not the file should be checked in.
*/
file_pattern (just_name);
find_file (NULL, size, file_date, file_time, attribute);
/*
** Note that if the file is read-only at this point, it's
** probably because lock checking is enabled. So, we try to
** check the file out with a lock.
*/
checklock = checklock || (attribute & READ_ONLY);
if (checklock == FALSE || _pvcs_run_cmd ("get -l (" + just_name + ")") == 0)
{
if (!_vcs_buf)
{
_vcs_buf = create_buffer ("PVCS", NULL, 1);
register_macro (5, "_pvcs_exit");
}
set_buffer (_vcs_buf);
insert (file_name + "\n");
if (attribute & READ_ONLY)
{
file_pattern (just_name);
find_file (NULL, size, file_date, file_time, attribute);
insert ("NODELETEWORK CHECKLOCK %d %d %d %d\n", size, file_date, file_time, attribute);
}
else
insert ("NODELETEWORK NOCHECKLOCK %d %d %d %d\n", size, file_date, file_time, attribute);
message ("");
}
else
message ("%s", old_msg);
}
/*
** Since we deleted this buffer above, we recreate it here, whether
** or not we were able to check it out.
*/
set_buffer (create_buffer (just_name, file_name));
cd (old_path);
cd (substr (old_drive, 1, 2));
}
returns ("");
}
/*
** _pvcs_exit:
**
** This macro registers another macro, which must run LAST! This is
** because it deletes (or can delete) a lot of files that are being
** edited.
*/
void _pvcs_exit ()
{
if (_vcs_buf)
register_macro (5, "__pvcs_exit");
}
__pvcs_exit ()
{
string just_name,
file_name,
path,
old_path,
cmd_line,
reply;
int checklock,
deletework,
curr_buf,
ret_code,
old_msg_level,
file_date,
old_date,
file_time,
old_time,
size,
old_size,
attribute,
old_attribute;
set_buffer (_vcs_buf);
set_buffer (curr_buf = next_buffer (1));
/*
** First, we want to delete all non-system buffers. This ensures
** that they're all closed and available for modification by PVCS.
*/
pause_on_error (1);
while (curr_buf != _vcs_buf)
{
if (!inq_system (curr_buf))
{
delete_buffer (curr_buf);
set_buffer (_vcs_buf);
}
set_buffer (curr_buf = next_buffer(1));
}
top_of_buffer ();
old_msg_level = inq_msg_level ();
set_msg_level (0);
while ((file_name = read ()) != "\n")
{
file_name = substr (file_name, 1, strlen (file_name) - 1);
path = substr (file_name, 1, rindex (file_name, substr (file_name, 3, 1)));
if (strlen (path) > 3)
path = substr (path, 1, strlen (path) - 1);
/*
** We keep around a bunch of information for each file that we
** checked out of PVCS. In addition to the date, time, size and
** attribute value, we also have to "command words" that tell us
** what condition the workfile was in to begin with.
*/
just_name = substr (file_name, rindex (file_name, substr (file_name, 3, 1)) + 1);
down ();
file_name = read ();
deletework = (substr (file_name, 1, index (file_name, " ") - 1) == "DELETEWORK");
file_name = substr (file_name, index (file_name, " ") + 1);
checklock = (substr (file_name, 1, index (file_name, " ") - 1) == "CHECKLOCK");
file_name = substr (file_name, index (file_name, " ") + 1);
old_size = atoi (file_name);
file_name = substr (file_name, index (file_name, " ") + 1);
old_date = atoi (file_name);
file_name = substr (file_name, index (file_name, " ") + 1);
old_time = atoi (file_name);
file_name = substr (file_name, index (file_name, " ") + 1);
old_attribute = atoi (file_name);
down ();
getwd ("", cmd_line);
getwd (path, old_path);
old_path = substr (cmd_line, 1, 1) + substr (old_path, 2);
cd (path);
cd (substr (path, 1, 2));
file_pattern (just_name);
find_file (NULL, size, file_date, file_time, attribute);
if (old_size != size || old_date != file_date || old_time != file_time || old_attribute != attribute)
{
if (reply != "q")
{
message ("Checking workfile \"%s\"...", just_name);
sprintf (cmd_line, "vdiff -q -t -r %s %s >&nul", just_name, just_name);
if ((ret_code = dos (cmd_line)) == 2)
{
if (reply != "g" && !get_parm (NULL, reply, ("Check in " + just_name) + " [yngq]? ", 1))
reply = "q";
if (strlen (reply) && index ("yg", lower (reply)))
{
int num_lines,
num_cols,
comment_buf,
source_keyboard = inq_keyboard (),
old_msg_level;
/*
** Note that this variable is initialized every time the
** macro is called, even though it's global.
*/
global int _pvcs_abort_pressed = FALSE;
string exit_assignment = inq_assignment ("exit", 1),
window_msg;
/*
** At this point, we know we're going to check in the
** PVCS file. So we create a window and center it on the
** screen, and allow the user to enter a check-in comment.
** Once they've completed the comment, we send it along to
** PVCS.
*/
if (exit_assignment == "")
exit_assignment = "<Alt-x>";
else if (index (exit_assignment, "<-"))
exit_assignment = substr (exit_assignment, 1, index (exit_assignment, "<-") - 1);
sprintf (window_msg, "Enter comment, %s when finished, <Esc> to abort.", exit_assignment);
old_msg_level = set_msg_level (3);
set_buffer (comment_buf = create_buffer (just_name, "check_in.vcs"));
set_msg_level (old_msg_level);
tabs (9);
inq_screen_size (num_lines, num_cols);
num_cols /= 2;
num_lines /= 2;
set_ctrl_state( ZOOM_BTN, HIDE_CTRL); // hide the zoom button for this window
create_window (num_cols - 38, num_lines + ((num_lines / 2) - 1),
num_cols + 37, num_lines - (num_lines / 2), window_msg);
set_ctrl_state( ZOOM_BTN, SHOW_CTRL); // show the zoom button
/* save the current mouse event handler */
default_mouse_handler = inq_mouse_action();
/*
** Here, we copy over assignments that are useful inside
** the PVCS check-in window. Note that we copy both the
** assignments to _home and _end and beginning_of_line and
** end_of_line: this is because some people may have kept
** the old-style assignments intact.
*/
keyboard_push ();
keyboard_typeables ();
copy_keyboard (source_keyboard, "up",
"down",
"left",
"right",
"_home",
"_end",
"beginning_of_line",
"end_of_line",
"page_up",
"page_down",
"next_word",
"previous_word",
"search_fwd",
"search_back",
"search_again",
"translate",
"translate_back",
"translate_again",
"top_of_buffer",
"end_of_buffer",
"cut",
"copy",
"paste",
"delete_char",
"delete_line",
"delete_to_eol",
"delete_previous_word",
"delete_next_word",
"read_file",
"quote",
"undo",
"insert_mode",
"mark",
"mark 2",
"mark 3",
"mark 4",
"dos",
"goto_line",
"reform");
assign_to_key (exit_assignment, "exit y");
assign_to_key ("<Esc>", "_pvcs_abort");
/*
** If there aren't already keys assigned to the normal
** PVCS exit keys, we assign them here. Old habits die
** hard, and we're trying to make it easier for the user.
*/
if (inq_assignment ("<Ctrl-d>") == "self_insert")
assign_to_key ("<Ctrl-d>", "exit y");
if (inq_assignment ("<Ctrl-z>") == "self_insert")
assign_to_key ("<Ctrl-z>", "exit y");
if (inq_assignment ("<Ctrl-c>") == "self_insert")
assign_to_key ("<Ctrl-c>", "_pvcs_abort");
attach_buffer (comment_buf);
/* set the mouse handler to the default handler */
set_mouse_action( "mouse_pvcs1" );
_wp_on (70);
refresh ();
process ();
_wp_off ();
delete_window ();
keyboard_pop ();
if (_pvcs_abort_pressed == FALSE)
{
set_msg_level (3);
write_buffer ();
set_msg_level (old_msg_level);
set_buffer (_vcs_buf);
delete_buffer (comment_buf);
message ("Checking in " + just_name + "...");
dos ("put -M (" + just_name + ") <check_in.vcs >&nul");
del ("check_in.vcs");
if (deletework == FALSE && checklock == FALSE)
dos ("attrib +r " + just_name + " >&nul");
message ("");
}
else
set_buffer (_vcs_buf);
}
}
else if (ret_code == 0)
{
if (checklock == TRUE)
{
message ("Unlocking " + just_name + "...");
dos ("put -n (" + just_name + ") >&nul");
message ("");
}
else if (deletework)
del (just_name);
else
dos ("attrib +r " + just_name + " >&nul");
}
}
}
else if (checklock == TRUE)
{
message ("Unlocking " + just_name + "...");
dos ("put -n (" + just_name + ") >&nul");
message ("");
}
else if (deletework)
del (just_name);
else
dos ("attrib +r " + just_name + " >&nul");
cd (substr (old_path, 3));
cd (substr (old_path, 1, 2));
}
delete_buffer (_vcs_buf);
}
/*
** _pvcs_abort:
**
** This little routine just tells the main check-in code that the
** user pressed Esc to abort the comment & check-in.
*/
void _pvcs_abort ()
{
_pvcs_abort_pressed++;
exit ("y");
}
/*
** _pvcs_run_cmd:
**
** This command runs a PVCS get command and checks for common errors.
** If the file isn't a logfile (etc.), no error box is displayed. Otherwise,
** we display an error box and let the user see the "disaster in progress."
*/
int _pvcs_run_cmd (string cmd_line)
{
int ret_code;
if (ret_code = dos (cmd_line + " >&bvcs.tmp"))
{
if (ret_code > 0)
{
int error_buf = create_buffer ("PVCS error", "bvcs.tmp", 1),
old_buf = set_buffer (error_buf);
if (!search_fwd ("{can't locate logfile}|{is not a directory}"))
{
/* save the current mouse event handler */
default_mouse_handler = inq_mouse_action();
keyboard_push ();
assign_to_key ("<PgUp>", "page_up");
assign_to_key ("<PgDn>", "page_down");
assign_to_key ("<Esc>", "exit");
assign_to_key ("<Home>", "top_of_buffer");
assign_to_key ("<End>", "end_of_buffer");
assign_to_key ("<Up Arrow>", "up");
assign_to_key ("<Down>", "down");
/* set the mouse handler to the default handler */
set_mouse_action( "mouse_pvcs2" );
set_ctrl_state( ZOOM_BTN, HIDE_CTRL); // hide the zoom button for this window
create_window (2, 22, 78, 2, "PVCS error window -- Esc to exit");
set_ctrl_state( ZOOM_BTN, SHOW_CTRL); // show the zoom button
attach_buffer (error_buf);
refresh ();
process ();
keyboard_pop ();
delete_window ();
}
delete_buffer (error_buf);
set_buffer (old_buf);
}
}
del ("bvcs.tmp");
returns (ret_code);
}
/*
** mouse_pvcs1
**
** Handle mouse events for the pvcs check in window
**
** Mouse actions
** CLOSE_WIN - abort the check in , same as Esc
** BTN1_CLICK outside of the window - abort the check in
**
** All other events are sent to the previous mouse action handler.
*/
void mouse_pvcs1 (int event, // the event code
int modifier, // modifier keys
int parm2, // line or scroll bar code
int parm3 ) // column or thumb position
{
/* handle the events of interest */
switch ( event ){
case CLOSE_WIN: // abort the check in
_pvcs_abort();
case SET_WIN: // click outside the window aborts check in
if ( parm2 != inq_window() ) _pvcs_abort();
default:
/* let the previous event handler take care of the event */
execute_macro( default_mouse_handler, event, modifier, parm2, parm3 );
}
}
/*
** mouse_pvcs2
**
** Handle mouse events for the pvcs error window
**
** Mouse actions
** CLOSE_WIN - close the window, same as Esc
** BTN1_CLICK outside of the window - close the window
** let the default event handler process all the scrolling events
** ignore all others.
**
** All other events are sent to the previous mouse action handler.
*/
void mouse_pvcs2 (int event, // the event code
int modifier, // modifier keys
int parm2, // line or scroll bar code
int parm3 ) // column or thumb position
{
/* handle the events of interest */
switch ( event ){
case CLOSE_WIN: // abort the check in
exit();
case SET_WIN: // click outside the window aborts check in
if ( parm2 != inq_window() ) exit();
case VSCROLL:
case HSCROLL:
/* let the previous event handler take care of the event */
execute_macro( default_mouse_handler, event, modifier, parm2, parm3 );
}
}