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>
1021 lines
27 KiB
Plaintext
1021 lines
27 KiB
Plaintext
/*
|
|
** BRIEF -- Basic Reconfigurable Interactive Editing Facility
|
|
**
|
|
** pwb.cb:
|
|
**
|
|
** This macro package permits BRIEF to interface with the Microsoft
|
|
** Programmers Workbench.
|
|
**
|
|
** It saves and restores the BRIEF state using the PWB State
|
|
** File (current.sts). The state information includes the search and
|
|
** translate global variables, the buffers (and positions therein), and
|
|
** bookmarks. Please refer to the Brief DOS/ OS-2 User's Guide,
|
|
** Chapter 7 "Third-Party Packages", page 215 for additional details
|
|
** on using the pwb macro package.
|
|
**
|
|
*/
|
|
|
|
#define REG_EXIT_ACTION 5
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define SYSTEM 1
|
|
|
|
extern int _reg_exp, // Current regular expression setting.
|
|
_dir, // Current search direction.
|
|
_t_dir, // Current translate direction.
|
|
_block_search, // Current block search setting.
|
|
_check_warnings, // "Check output for warnings" setting.
|
|
_background; // Whether or not to compile in the bg.
|
|
|
|
extern string _s_pat, // Last search pattern.
|
|
_t_pat, // Last translate pattern.
|
|
_r_pat; // Last translate replacement.
|
|
|
|
extern string search_path (string pathvar, string filename);
|
|
|
|
void save_state ();
|
|
int _save_state (int start_buf_id);
|
|
void _save_marks (int start_buf_id);
|
|
void _save_files (int start_buf_id);
|
|
void _save_file_info (int start_buf_id);
|
|
void .sts ();
|
|
void pwb ();
|
|
void _restore_pwb (void);
|
|
_restore (int);
|
|
string _remove_newlines (string trans_str);
|
|
|
|
/*
|
|
** save_state:
|
|
**
|
|
** This macro, when registered as an EXIT_ACTION (type 5)
|
|
** registered macro, saves the state of the search variables
|
|
** as well as the names and positions of the current files.
|
|
**
|
|
** The state file is broken up into several sections. Each section
|
|
** is preceded by a tag that describes the type of information stored in
|
|
** the section.
|
|
*/
|
|
|
|
void save_state ()
|
|
{
|
|
int save_buf_id,
|
|
start_buf_id,
|
|
old_backup;
|
|
|
|
string file_name;
|
|
|
|
|
|
/*
|
|
** If the user hasn't specified a BFILE as yet (if there
|
|
** isn't any BFILE in the environment, (inq_environment) returns
|
|
** the null string), or the given BFILE is invalid in some other
|
|
** way, we can't save the state. We display a message to this
|
|
** effect and exit.
|
|
*/
|
|
|
|
file_name = trim (ltrim (lower (inq_environment ("BFILE"))));
|
|
|
|
if (substr (file_name, strlen (file_name) - 3) != ".sts")
|
|
error ("Invalid BFILE specified, state not saved.");
|
|
else
|
|
{
|
|
/*
|
|
** Here we create a buffer for the state file. It's created
|
|
** as a system buffer to prevent it from appearing in the buffer
|
|
** list (and getting saved along with the other files).
|
|
*/
|
|
|
|
if (!strlen (file_name))
|
|
{
|
|
/*
|
|
** In reality, right here is where we would create a current.sts if
|
|
** we couldn't find one where it belonged.
|
|
*/
|
|
|
|
file_name = "current.sts";
|
|
}
|
|
|
|
if (!(save_buf_id = create_buffer ("State", file_name, SYSTEM)))
|
|
error ("Invalid BFILE specified, state not saved.");
|
|
else
|
|
{
|
|
int screen_lines,
|
|
screen_cols;
|
|
|
|
/*
|
|
** We need to reset the current buffer later, since
|
|
** other macros could run after we do and we don't want
|
|
** to leave BRIEF in an unstable state. We save its
|
|
** buffer id before continuing.
|
|
*/
|
|
|
|
start_buf_id = set_buffer (save_buf_id);
|
|
|
|
/*
|
|
** First, we make sure the PWB state file version is one we
|
|
** support. If it isn't, we bail.
|
|
*/
|
|
|
|
top_of_buffer ();
|
|
|
|
if (!(search_fwd ("<[\t ]@\\[shared-\\]", TRUE, TRUE) &&
|
|
search_fwd ("<[\t ]@version=2", TRUE, TRUE)))
|
|
{
|
|
error ("Unsupported BFILE specified, state not saved.");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
** First, we save the "global" information: [shared-]
|
|
** This includes the bookmarks and the primary mark (current file
|
|
** and position within the current file).
|
|
*/
|
|
|
|
_save_marks (start_buf_id);
|
|
|
|
/*
|
|
** Next, we save the "common tool" information: [edit-]
|
|
** This is only the files we are currently editing.
|
|
*/
|
|
|
|
_save_files (start_buf_id);
|
|
|
|
/*
|
|
** Finally, we save the BRIEF state information: [brief]
|
|
** This includes the screen size, search and translate directions,
|
|
** regular expression setting, block search setting, and search
|
|
** and translate patterns.
|
|
*/
|
|
|
|
top_of_buffer ();
|
|
|
|
if (search_fwd ("<[\t ]@\\[brief\\]", TRUE, TRUE))
|
|
{
|
|
/*
|
|
** Remove any existing BRIEF state information first.
|
|
*/
|
|
|
|
down ();
|
|
drop_anchor ();
|
|
|
|
if (search_fwd ("<[\t ]@\\[", TRUE, TRUE))
|
|
prev_char ();
|
|
else
|
|
end_of_buffer ();
|
|
|
|
delete_block ();
|
|
}
|
|
else
|
|
{
|
|
end_of_buffer ();
|
|
insert ("\n[brief]\n");
|
|
}
|
|
|
|
inq_screen_size (screen_lines, screen_cols);
|
|
|
|
insert ("\tscreen=%d %d\n\ttoggles=%d %d %d %d %d %d\n",
|
|
screen_lines, screen_cols,
|
|
_dir, _reg_exp, _block_search,
|
|
_t_dir, _check_warnings, _background);
|
|
|
|
/*
|
|
** The search and translate patterns could,
|
|
** potentially, have newline characters in them.
|
|
** The _remove_newlines subroutine replaces those
|
|
** newline characters with \n, the regular expression
|
|
** that means "newline".
|
|
*/
|
|
|
|
insert ("\tsrch=" + _remove_newlines (_s_pat));
|
|
insert ("\tsrc=" + _remove_newlines (_t_pat));
|
|
insert ("\trpl=" + _remove_newlines (_r_pat));
|
|
|
|
/*
|
|
** Now we call the _save_state macro to save the
|
|
** remainder of the state information. Note that
|
|
** this macro can be replaced to extend restore's
|
|
** capabilities.
|
|
*/
|
|
|
|
_save_file_info (start_buf_id);
|
|
_save_state (start_buf_id);
|
|
set_buffer (save_buf_id);
|
|
|
|
/*
|
|
** Finally, we write the restore file to disk.
|
|
** Since we don't want backup files created, we
|
|
** turn those off. We put it back the way it was
|
|
** before exiting, since other macros could run
|
|
** once we're through.
|
|
*/
|
|
|
|
old_backup = set_backup (FALSE);
|
|
write_buffer ();
|
|
set_backup (old_backup);
|
|
delete_buffer (save_buf_id);
|
|
set_buffer (start_buf_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** _save_state:
|
|
**
|
|
** This macro is the end of the save_state chain; other macros can
|
|
** replace it to save state information in the state file.
|
|
*/
|
|
|
|
int _save_state (int)
|
|
{
|
|
returns (0);
|
|
}
|
|
|
|
/*
|
|
** _save_marks:
|
|
**
|
|
** This macro saves the the bookmarks and the primary mark in the
|
|
** [shared-] section of the state file.
|
|
*/
|
|
|
|
void _save_marks (int start_buf_id)
|
|
{
|
|
int save_buf_id = inq_buffer (),
|
|
i, curr_buf_id, line, col,
|
|
mark_line1, mark_line2;
|
|
string info;
|
|
|
|
top_of_buffer ();
|
|
search_fwd ("<[\t ]@\\[shared-\\]", TRUE, TRUE);
|
|
down ();
|
|
inq_position (mark_line1);
|
|
|
|
while (search_fwd ("<[\t ]@\\c{\\[}|{mark=edit}|{pmark=}"))
|
|
if (read (1) == "[")
|
|
break;
|
|
else
|
|
{
|
|
if (!mark_line2)
|
|
inq_position (mark_line2);
|
|
|
|
delete_line ();
|
|
beginning_of_line ();
|
|
}
|
|
|
|
/*
|
|
** Finally, we save the bookmarks and the primary mark.
|
|
*/
|
|
|
|
goto_line (mark_line2 ? mark_line2 : mark_line1);
|
|
|
|
for ( ; i < 10 ; i++)
|
|
if (goto_bookmark (i, curr_buf_id, line, col))
|
|
{
|
|
set_buffer (curr_buf_id);
|
|
inq_names (info);
|
|
set_buffer (save_buf_id);
|
|
insert ("\tmark=edit %s %u %u bnumber=%u\n", info, line, col, i);
|
|
}
|
|
set_buffer (start_buf_id);
|
|
inq_position (line, col);
|
|
inq_names (info);
|
|
set_buffer (save_buf_id);
|
|
insert ("\tpmark=\"%s\" %u %u\n", info, line, col);
|
|
}
|
|
|
|
/*
|
|
** _save_files:
|
|
**
|
|
** This macro gets called to save the "common tool" state information.
|
|
*/
|
|
|
|
void _save_files (int start_buf_id)
|
|
{
|
|
int save_buf_id = inq_buffer (),
|
|
curr_buf_id = start_buf_id,
|
|
line,
|
|
col,
|
|
top_line,
|
|
top_col,
|
|
mark_line1, mark_line2;
|
|
|
|
string info;
|
|
|
|
top_of_buffer ();
|
|
search_fwd ("<[\t ]@\\[edit-\\]", TRUE, TRUE);
|
|
down ();
|
|
inq_position (mark_line1);
|
|
|
|
while (search_fwd ("<[\t ]@\\c{\\[}|{file=}"))
|
|
if (read (1) == "[")
|
|
break;
|
|
else
|
|
{
|
|
if (!mark_line2)
|
|
inq_position (mark_line2);
|
|
|
|
delete_line ();
|
|
beginning_of_line ();
|
|
}
|
|
|
|
/*
|
|
** Finally, we save the files.
|
|
*/
|
|
|
|
goto_line (mark_line2 ? mark_line2 : mark_line1);
|
|
|
|
set_buffer (start_buf_id);
|
|
|
|
do
|
|
{
|
|
if (!inq_system ())
|
|
{
|
|
inq_position (line, col);
|
|
inq_top_left (top_line, top_col, NULL, NULL, NULL, curr_buf_id);
|
|
inq_names (info);
|
|
set_buffer (save_buf_id);
|
|
insert ("\tfile=\"%s\" %u %u %u %u\n", info, top_line, top_col, line, col);
|
|
set_buffer (curr_buf_id);
|
|
}
|
|
set_buffer (curr_buf_id = next_buffer (1));
|
|
}
|
|
while (curr_buf_id != start_buf_id);
|
|
|
|
set_buffer (save_buf_id);
|
|
}
|
|
|
|
/*
|
|
** _save_file_info:
|
|
**
|
|
** This macro gets called to save the variable length state information.
|
|
*/
|
|
|
|
void _save_file_info (int start_buf_id)
|
|
{
|
|
int save_buf_id = inq_buffer (),
|
|
curr_buf_id,
|
|
curr_win_id = inq_window (),
|
|
start_win_id = curr_win_id,
|
|
line,
|
|
col,
|
|
top_line,
|
|
top_col,
|
|
cursor_line,
|
|
cursor_col,
|
|
lx,
|
|
by,
|
|
rx,
|
|
ty,
|
|
i;
|
|
|
|
string info;
|
|
|
|
/*
|
|
** Now that the global state information has been saved, we save the
|
|
** information about the buffers and windows in the [brief] section.
|
|
**
|
|
** First, we save all the buffers that are being displayed in tiled
|
|
** windows. These windows are recreated along with the buffers if no
|
|
** filename is specified.
|
|
**
|
|
** Then, we save information about the buffers that aren't being
|
|
** viewed in a window.
|
|
**
|
|
** We skip system buffers manually, rather than with the (next_buffer)
|
|
** parameter, because we could have been entered with a system buffer as
|
|
** the current buffer. If we made use of the (next_buffer) parameter,
|
|
** we'd never come back to the starting buffer and would infinite loop.
|
|
*/
|
|
|
|
do
|
|
{
|
|
/*
|
|
** We don't save the state of overlapping windows. Exit if there's
|
|
** one on the screen.
|
|
*/
|
|
|
|
if (inq_window_info (curr_win_id, curr_buf_id, lx, by, rx, ty))
|
|
break;
|
|
|
|
/*
|
|
** If there's a buffer in the window, save all the appropriate
|
|
** information, including:
|
|
**
|
|
** The fully qualified filename.
|
|
** The line and column of the file in the top left corner
|
|
** of the window.
|
|
** The line and column of the file the cursor's on.
|
|
** The window's coordinates (lx, by, rx, ty).
|
|
** The window's colors.
|
|
*/
|
|
|
|
if (curr_buf_id)
|
|
{
|
|
set_buffer (curr_buf_id);
|
|
inq_names (info);
|
|
inq_top_left (top_line, top_col, curr_win_id, cursor_line, cursor_col);
|
|
set_buffer (save_buf_id);
|
|
insert ("\tfile=%s %u %u %u %u %d %d %d %d c=%d\n", info,
|
|
top_line, top_col, cursor_line, cursor_col,
|
|
lx, by, rx, ty, inq_window_color (curr_win_id));
|
|
}
|
|
curr_win_id = next_window (curr_win_id);
|
|
}
|
|
while (start_win_id != curr_win_id);
|
|
|
|
/*
|
|
** Now we save all the buffers that aren't viewed in windows.
|
|
*/
|
|
|
|
set_buffer (start_buf_id);
|
|
|
|
do
|
|
{
|
|
/*
|
|
** If there was an overlapping window on the screen, we save
|
|
** _all_ the buffers, not just the ones that weren't being viewed.
|
|
*/
|
|
|
|
if (!inq_system () && (!inq_views (curr_buf_id) || inq_window_info ()))
|
|
{
|
|
inq_names (info);
|
|
inq_position (line, col);
|
|
inq_top_left (top_line, top_col, NULL, NULL, NULL, curr_buf_id);
|
|
|
|
set_buffer (save_buf_id);
|
|
insert ("\tfile=%s %u %u %u %u\n", info, top_line, top_col, line, col);
|
|
set_buffer (curr_buf_id);
|
|
}
|
|
set_buffer (curr_buf_id = next_buffer (1));
|
|
}
|
|
while (start_buf_id != curr_buf_id);
|
|
|
|
set_buffer (save_buf_id);
|
|
}
|
|
|
|
/*
|
|
** .sts:
|
|
**
|
|
** This macro is, quite frankly, a mite strange. When the
|
|
** user types "b" with no arguments, BRIEF automatically loads
|
|
** the file specified by the BFILE environment variable. If
|
|
** that file has the extension ".sts", this macro runs.
|
|
**
|
|
** This macro then restores the files that were active
|
|
** during the last editing session. The state file buffer
|
|
** (specified in the BFILE) isn't deleted -- the restore macro,
|
|
** which runs after the file loading sequence, does that after
|
|
** restoring the state of the search and translate variables.
|
|
*/
|
|
|
|
void .sts ()
|
|
{
|
|
string file_name;
|
|
|
|
/*
|
|
** We need the name of the current file for the next test.
|
|
** All we need is the buffer name, which is the last parameter.
|
|
** The NULL placeholder is used to omit the additional information.
|
|
*/
|
|
|
|
inq_names (NULL, NULL, file_name);
|
|
|
|
/*
|
|
** This logic only makes sense the first time this file extension
|
|
** macro is called. If we're running it for the second time, or the file
|
|
** isn't the same as the state file (maintained in the BFILE environment
|
|
** variable), we skip it. Initialization logic for "real" .rst files can
|
|
** be placed in the "true" clause of the if statement (replacing or
|
|
** supplementing the (tabs) statement).
|
|
**
|
|
** We use "index" here because the only thing we really care about is
|
|
** that the file name matches the name of the file specified in BFILE:
|
|
** remember that the path specified could be relative.
|
|
*/
|
|
|
|
if (!(first_time () && index (trim (lower (inq_environment ("BFILE"))) + "\xff", file_name + "\xff")))
|
|
tabs (9);
|
|
else
|
|
{
|
|
int save_buf_id = inq_buffer (),
|
|
curr_buf,
|
|
line,
|
|
col,
|
|
top_line,
|
|
top_col,
|
|
lx,
|
|
by,
|
|
rx,
|
|
ty,
|
|
bg_color,
|
|
loc,
|
|
has_window,
|
|
window_to_select,
|
|
old_msg_level = inq_msg_level ();
|
|
|
|
string file_line;
|
|
|
|
/*
|
|
** BRIEF has already edited the state file (because of normal BFILE
|
|
** processing) and made it the current buffer. We get its buffer id
|
|
** for future use, search for the [brief] string that tells us where
|
|
** the file data starts, and process the file information, which
|
|
** is in the following format:
|
|
**
|
|
** The string "file=".
|
|
** Full, qualified filename.
|
|
** The line displayed at the top of the last/this window.
|
|
** The column at the left hand side of the last/this window.
|
|
** The current line number in this window/in the buffer.
|
|
** The current column number in this window/in the buffer.
|
|
**
|
|
** The rest of the information is optional, and is only there if
|
|
** there were views of the buffer.
|
|
**
|
|
** The coordinates of the window (lx, by, rx, ty).
|
|
** The string "c=".
|
|
** The window color.
|
|
**
|
|
** Note that if the telltale [brief] string isn't found, we can't
|
|
** process the .rst file. In addition, if the screen size specified
|
|
** in the [edit-] section isn't the same as the current screen size,
|
|
** we can't continue.
|
|
*/
|
|
|
|
if (search_fwd ("<[\t ]@\\[brief\\]", TRUE, TRUE) >= 1)
|
|
{
|
|
int curr_win_lines,
|
|
curr_win_cols,
|
|
old_win_lines,
|
|
old_win_cols,
|
|
create_windows;
|
|
|
|
inq_screen_size (curr_win_lines, curr_win_cols);
|
|
search_fwd ("<[\t ]@screen=\\c", TRUE, TRUE);
|
|
// next_char (7);
|
|
old_win_lines = atoi (file_line = trim (ltrim (compress (read ()))));
|
|
old_win_cols = atoi (substr (file_line, index (file_line, " ") + 1));
|
|
|
|
if (search_fwd ("<[\t ]@\\cfile=", TRUE, TRUE))
|
|
{
|
|
lx = 1;
|
|
rx = curr_win_cols - 2;
|
|
ty = 1;
|
|
by = curr_win_lines - 3;
|
|
bg_color = inq_window_color ();
|
|
create_windows = ((curr_win_lines == old_win_lines) && (curr_win_cols == old_win_cols));
|
|
|
|
// down ();
|
|
display_windows (FALSE);
|
|
|
|
/*
|
|
** Here's the loop that processes the file information. We
|
|
** continue restoring files until there's no more information in
|
|
** the file to restore (signaled by EOF or another section).
|
|
*/
|
|
|
|
while (substr (file_line = ltrim (trim (read ())), 1, 5) == "file=")
|
|
{
|
|
/*
|
|
** The string "c=" is only present if this is a window/file
|
|
** declaration.
|
|
*/
|
|
|
|
if (loc = rindex (file_line, " c="))
|
|
{
|
|
has_window = TRUE;
|
|
|
|
if (create_windows)
|
|
{
|
|
bg_color = atoi (substr (file_line, loc + 3));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
ty = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
rx = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
by = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
lx = atoi (substr (file_line, loc + 1));
|
|
file_line = substr (file_line, 1, loc - 1);
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
|
|
for ( ; i < 5 ; i++)
|
|
{
|
|
file_line = substr (file_line, 1, loc - 1);
|
|
loc = rindex (file_line, " ");
|
|
}
|
|
}
|
|
}
|
|
else if (!window_to_select)
|
|
has_window = TRUE;
|
|
|
|
loc = rindex (file_line, " ");
|
|
col = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
line = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
top_col = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
top_line = atoi (substr (file_line, loc + 1));
|
|
|
|
file_name = trim (ltrim (substr (file_line, 6, loc - 6)));
|
|
down ();
|
|
|
|
/*
|
|
** edit_file is used to load the file back in because it
|
|
** deals with all the details of attaching the buffer to the
|
|
** window, calling the proper initialization routines, setting
|
|
** the current buffer, etc.
|
|
**
|
|
** If the call to edit_file fails, we know something has
|
|
** gone wrong. So we ignore this file and continue to the
|
|
** next.
|
|
*/
|
|
|
|
set_msg_level (0);
|
|
|
|
if (curr_buf = inq_buffer (file_name))
|
|
set_buffer (curr_buf);
|
|
|
|
if (curr_buf || edit_file (file_name) > 0)
|
|
{
|
|
if (has_window && (create_windows || !window_to_select))
|
|
{
|
|
int window_id = create_tiled_window (lx, by, rx, ty, inq_buffer ());
|
|
|
|
if (!window_to_select)
|
|
window_to_select = window_id;
|
|
|
|
set_top_left (top_line, top_col, window_id, line, col);
|
|
window_color (bg_color, window_id);
|
|
}
|
|
else
|
|
{
|
|
move_abs (line, col);
|
|
set_top_left (top_line, top_col, NULL, NULL, NULL, inq_buffer ());
|
|
}
|
|
|
|
/*
|
|
** At this point, the restored file has been made the
|
|
** current buffer. We have to make our state file current
|
|
** so the top of the loop works correctly.
|
|
*/
|
|
|
|
set_buffer (save_buf_id);
|
|
}
|
|
else if (has_window && (create_windows || !window_to_select))
|
|
{
|
|
int window_id = create_tiled_window (lx, by, rx, ty, save_buf_id);
|
|
|
|
if (!window_to_select)
|
|
window_to_select = window_id;
|
|
}
|
|
set_msg_level (old_msg_level);
|
|
has_window = FALSE;
|
|
}
|
|
|
|
display_windows (1);
|
|
set_window (window_to_select);
|
|
}
|
|
}
|
|
|
|
curr_buf = set_buffer (save_buf_id);
|
|
top_of_buffer ();
|
|
|
|
if (search_fwd ("<[\t ]@\\[edit-\\]"))
|
|
{
|
|
int buffer_id,
|
|
line, col, top_line, top_col;
|
|
|
|
do
|
|
{
|
|
down ();
|
|
file_line = trim (ltrim (read ()));
|
|
|
|
if (substr (file_line, 1, index (file_line, "=")) == "file=")
|
|
{
|
|
int loc = rindex (file_line, " ");
|
|
string file;
|
|
|
|
file = substr (file_line, index (file_line, "\"") + 1);
|
|
file = substr (file, 1, rindex (file, "\"") - 1);
|
|
|
|
col = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
line = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
top_col = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
top_line = atoi (substr (file_line, loc + 1));
|
|
|
|
if (edit_file (file) > 0)
|
|
{
|
|
move_abs (line, col);
|
|
set_top_left (top_line, top_col, NULL, NULL, NULL, inq_buffer ());
|
|
set_buffer (save_buf_id);
|
|
}
|
|
}
|
|
} while (substr (file_line, 1, 1) != "[" && !inq_position ());
|
|
}
|
|
|
|
attach_buffer (curr_buf);
|
|
|
|
/*
|
|
** Restore the primary mark.
|
|
*/
|
|
|
|
set_buffer (save_buf_id);
|
|
top_of_buffer ();
|
|
|
|
if (search_fwd ("<[\t ]@\\[shared-\\]", TRUE, TRUE) &&
|
|
search_fwd ("<[\t ]@pmark=\"\\c", TRUE, TRUE))
|
|
{
|
|
loc = rindex (file_line = read (), " ");
|
|
col = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
line = atoi (substr (file_line, loc + 1));
|
|
file_line = substr (file_line, 1, rindex (file_line, "\"") - 1);
|
|
|
|
if (edit_file (file_line))
|
|
move_abs (line, col);
|
|
else
|
|
set_buffer (curr_buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** pwb:
|
|
**
|
|
** This macro restores the state of the search and translate
|
|
** global variables, as well as the list of bookmarks for each
|
|
** currently edited file.
|
|
**
|
|
** Note that if the ".sts" macro ran when BRIEF was started,
|
|
** the state file (BFILE) has already been loaded. In this case,
|
|
** (create_buffer) just gives us its buffer ID, and doesn't bother
|
|
** loading the file again.
|
|
*/
|
|
|
|
void pwb ()
|
|
{
|
|
if (first_time ())
|
|
{
|
|
string file_name;
|
|
|
|
/*
|
|
** First, we register the macro that will end up saving the state of
|
|
** the session for the next time around.
|
|
*/
|
|
|
|
register_macro (REG_EXIT_ACTION, "save_state");
|
|
|
|
/*
|
|
** If this macro runs, and no BFILE is specified, we can't restore
|
|
** the state (you can't restore what isn't there). So we put up an
|
|
** error message and exit. If the file doesn't exist, we don't
|
|
** proceed -- once again, there's nothing to restore!
|
|
*/
|
|
|
|
file_name = trim (ltrim (lower (inq_environment ("BFILE"))));
|
|
|
|
if (substr (file_name, strlen (file_name) - 3) != ".sts")
|
|
error ("Invalid BFILE specified, state not restored.");
|
|
else if (exist (file_name))
|
|
{
|
|
/*
|
|
** Before we make the state file buffer current, we have to
|
|
** ensure the old buffer (which is in the main window) is saved
|
|
** away. Before we exit the macro, we have to reset it: otherwise,
|
|
** BRIEF gets very unhappy.
|
|
*/
|
|
|
|
int buffer_id,
|
|
old_buffer = inq_buffer ();
|
|
|
|
string file_line;
|
|
|
|
/*
|
|
** If the buffer creation fails ((create_buffer) returns 0), we
|
|
** tell the user about the problem and stop. Otherwise, we continue
|
|
** with the restore.
|
|
*/
|
|
|
|
if (!(buffer_id = create_buffer ("Restore", file_name)))
|
|
error ("Invalid BFILE specified.");
|
|
else
|
|
{
|
|
/*
|
|
** Here we make the restore buffer current and parse the
|
|
** information in the state file. This includes:
|
|
**
|
|
** The size of the screen.
|
|
** The search direction, regular expression setting,
|
|
** search block setting, translate direction, warnings-only
|
|
** and background compile settings.
|
|
** The search pattern.
|
|
** The translate pattern.
|
|
** The replacement string.
|
|
**
|
|
** No error checking is done on the results of the parse: if
|
|
** the numbers aren't right, the (atoi) call will fail and
|
|
** things will default to 0 (if the strings don't exist, they'll
|
|
** probably be null).
|
|
*/
|
|
|
|
set_buffer (buffer_id);
|
|
top_of_buffer ();
|
|
|
|
if (search_fwd ("<[\t ]@\\[brief\\]", TRUE, TRUE))
|
|
{
|
|
down ();
|
|
|
|
while (substr (file_line = ltrim (read ()), 1, 1) != "[" && !inq_position ())
|
|
{
|
|
switch (substr (file_line, 1, index (file_line, "=")))
|
|
{
|
|
case "toggles=":
|
|
{
|
|
file_line = trim (compress (file_line));
|
|
_dir = atoi (substr (file_line, 9));
|
|
file_line = substr (file_line, index (file_line, " ") + 1);
|
|
_reg_exp = atoi (file_line);
|
|
file_line = substr (file_line, index (file_line, " ") + 1);
|
|
_block_search = atoi (file_line);
|
|
file_line = substr (file_line, index (file_line, " ") + 1);
|
|
_t_dir = atoi (file_line);
|
|
file_line = substr (file_line, index (file_line, " ") + 1);
|
|
_check_warnings = atoi (file_line);
|
|
file_line = substr (file_line, index (file_line, " ") + 1);
|
|
_background = atoi (file_line);
|
|
}
|
|
case "srch=":
|
|
_s_pat = substr (file_line, 6, strlen (file_line) - 6);
|
|
|
|
case "src=":
|
|
_t_pat = substr (file_line, 5, strlen (file_line) - 5);
|
|
|
|
case "rpl=":
|
|
_r_pat = substr (file_line, 5, strlen (file_line) - 5);
|
|
}
|
|
down ();
|
|
}
|
|
/*
|
|
** Now we call the _restore macro to finish up the
|
|
** restoration. Note that this macro can be replaced to
|
|
** extend restore's capabilities.
|
|
*/
|
|
|
|
_restore_pwb ();
|
|
_restore (old_buffer);
|
|
}
|
|
}
|
|
set_buffer (buffer_id);
|
|
|
|
/*
|
|
** Here we make sure the state file buffer isn't the same as
|
|
** the buffer that was current when we entered the macro. This
|
|
** shouldn't happen, but it could.
|
|
*/
|
|
|
|
if (old_buffer != buffer_id && !inq_views (buffer_id))
|
|
{
|
|
set_buffer (old_buffer);
|
|
delete_buffer (buffer_id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** _restore_pwb:
|
|
**
|
|
** This macro restores the "common tool" state information.
|
|
*/
|
|
|
|
void _restore_pwb (void)
|
|
{
|
|
int use_srch, use_rpl;
|
|
string srch, rpl, src, file_line;
|
|
|
|
top_of_buffer ();
|
|
|
|
if (search_fwd ("<[\t ]@\\[edit-\\]"))
|
|
{
|
|
do
|
|
{
|
|
down ();
|
|
file_line = trim (ltrim (read ()));
|
|
|
|
switch (substr (file_line, 1, index (file_line, "=")))
|
|
{
|
|
case "srch=":
|
|
srch = substr (file_line, index (file_line, "=") + 1);
|
|
|
|
case "fSrchRe=":
|
|
use_srch = !atoi (substr (file_line, index (file_line, "=") + 1));
|
|
|
|
case "rpl=":
|
|
rpl = substr (file_line, index (file_line, "=") + 1);
|
|
|
|
case "src=":
|
|
src = substr (file_line, index (file_line, "=") + 1);
|
|
|
|
case "fRplRe=":
|
|
use_rpl = !atoi (substr (file_line, index (file_line, "=") + 1));
|
|
}
|
|
} while (substr (file_line, 1, 1) != "[" && !inq_position ());
|
|
|
|
if (use_srch)
|
|
_s_pat = srch;
|
|
|
|
if (use_rpl)
|
|
{
|
|
_t_pat = src;
|
|
_r_pat = rpl;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** _restore:
|
|
**
|
|
** This macro restores the variable editing information. It can be
|
|
** replaced by the user to extend restore's capabilities.
|
|
*/
|
|
|
|
_restore (int)
|
|
{
|
|
/*
|
|
** Now, we restore the list of bookmarks. We check to see if each
|
|
** buffer in the file list is being edited in this session. If so, its
|
|
** bookmarks are restored.
|
|
*/
|
|
|
|
top_of_buffer ();
|
|
|
|
if (search_fwd ("<[\t ]@\\[shared-\\]", TRUE, TRUE))
|
|
{
|
|
int bookmark_num,
|
|
loc,
|
|
mark_buf,
|
|
line,
|
|
col;
|
|
|
|
string file_line;
|
|
|
|
down ();
|
|
|
|
while (!inq_position () && read (1) != "[")
|
|
{
|
|
file_line = trim (ltrim (compress (read ())));
|
|
|
|
if (substr (file_line, 1, 9) == "mark=edit")
|
|
{
|
|
file_line = substr (file_line, 11);
|
|
|
|
if ((mark_buf = inq_buffer (substr (file_line, 1, index (file_line, " ") - 1)))
|
|
&& (loc = rindex (file_line, " bnumber=")))
|
|
{
|
|
bookmark_num = atoi (substr (file_line, loc + 9));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
col = atoi (substr (file_line, loc + 1));
|
|
loc = rindex (substr (file_line, 1, loc - 1), " ");
|
|
line = atoi (substr (file_line, loc + 1));
|
|
drop_bookmark (bookmark_num, "y", mark_buf, line, col);
|
|
}
|
|
}
|
|
down ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** _remove_newlines:
|
|
**
|
|
** This macro replaces all newline characters with the character sequence
|
|
** "\n". This prevents problems when a search pattern with a newline in it
|
|
** is inserted. Note that a hard carriage return is also inserted at the
|
|
** end of the line as a step saver.
|
|
*/
|
|
|
|
string _remove_newlines (string trans_str)
|
|
{
|
|
int loc;
|
|
|
|
/*
|
|
** This loop checks for newlines in the passed string. If
|
|
** once is found, the string is split into two parts: the part
|
|
** before the newline, and the part after. The two halves are
|
|
** then put back together again, with a newline regular expression
|
|
** ("\n") in between.
|
|
*/
|
|
|
|
while (loc = index (trans_str, "\n"))
|
|
trans_str = substr (trans_str, 1, loc - 1) + "\\n" + substr (trans_str, loc + 1);
|
|
|
|
returns (trans_str + "\n");
|
|
}
|