📄 block.c
字号:
assert( bc >= 0 );
assert( bc <= MAX_LINE_LENGTH );
assert( lens >= 0 );
assert( lens <= MAX_LINE_LENGTH );
assert( rcol >= 0 );
assert( rcol <= MAX_LINE_LENGTH );
_fmemcpy( g_status.line_buff+rcol, block_start->line+bc, lens );
g_status.line_buff_len = lens + rcol;
*rc = un_copy_line( dest, &d_w, TRUE );
dest->dirty = TRUE;
}
if (*rc == OK && ptoul( block_start->next ) != ptoul( block_end )) {
block_start->next->prev = dest;
temp_ll->prev = block_end->prev;
block_end->prev->next = temp_ll;
dest->next = block_start->next;
}
if (*rc == OK) {
copy_line( block_start );
detab_linebuff( );
lend = bc;
lens = block_end->len - (ec + 1);
assert( bc >= 0 );
assert( bc <= MAX_LINE_LENGTH );
assert( lens >= 0 );
assert( lens <= MAX_LINE_LENGTH );
assert( lend >= 0 );
assert( lend <= MAX_LINE_LENGTH );
assert( ec + 1 >= 0 );
assert( ec + 1 <= MAX_LINE_LENGTH );
assert( lens + lend >= 0 );
assert( lens + lend <= MAX_LINE_LENGTH );
_fmemcpy( g_status.line_buff+bc, block_end->line+ec+1, lens );
g_status.line_buff_len = lend + lens;
*rc = un_copy_line( block_start, &s_w, TRUE );
block_start->dirty = TRUE;
block_start->next = block_end->next;
block_end->next->prev = block_start;
if (block_end->line != NULL)
my_free( block_end->line );
my_free( block_end );
}
}
} else if (action == DELETE) {
copy_line( block_start );
lens = block_end->len - (ec + 1);
assert( bc >= 0 );
assert( bc <= MAX_LINE_LENGTH );
assert( lens >= 0 );
assert( lens <= MAX_LINE_LENGTH );
assert( ec + 1 >= 0 );
assert( ec + 1 <= MAX_LINE_LENGTH );
assert( bc + lens >= 0 );
assert( bc + lens <= MAX_LINE_LENGTH );
_fmemcpy( g_status.line_buff+bc, block_end->line + ec+1, lens );
g_status.line_buff_len = bc + lens;
*rc = un_copy_line( block_start, &s_w, TRUE );
block_start->dirty = TRUE;
source = block_start->next;
block_start->next = block_end->next;
block_end->next->prev = block_start;
block_end->next = NULL;
while (source != NULL) {
temp_ll = source;
source = source->next;
if (temp_ll->line != NULL)
my_free( temp_ll->line );
my_free( temp_ll );
}
}
if (*rc == OK) {
diff = er - br;
if (action == COPY || action == KOPY || action == MOVE)
dest_file->length += diff;
if (action == DELETE || action == MOVE)
source_file->length -= diff;
if (action == DELETE && source_window->rline >= br) {
source_window->rline -= diff;
if (source_window->rline < br)
source_window->rline = br;
}
}
/*
* restore all cursors in all windows
*/
restore_cursors( dest_file );
if (dest_file != source_file)
restore_cursors( source_file );
show_avail_mem( );
}
/*
* Name: do_box_block
* Purpose: delete, move, copy, or kopy a BOX block
* Date: June 5, 1991
* Passed: window: pointer to destination window (current window)
* source_window: pointer to source window
* action: block action -- OVERLAY, FILL, etc...
* source_file: pointer to source file structure
* dest_file: pointer to destination file
* source: pointer to source node
* dest: pointer to destination node
* br: beginning line number in marked block
* er: ending line number in marked block
* block_inc: increment used to number a block
* rline: current line number in destination file
* block_num: starting number when numbering a block
* block_just: LEFT or RIGHT justified numbers in block
* fill_char: character to fill a block
* same: are source and destination files same? T or F
* block_len: width of box block
* bc: beginning column of block
* ec: ending column of block
* rcol: current column of cursor
* rc: return code
*/
void do_box_block( WINDOW *window, WINDOW *source_window, int action,
file_infos *source_file, file_infos *dest_file,
line_list_ptr source, line_list_ptr dest, long br,
long er, long block_inc,
long rline, long block_num, int block_just, int fill_char,
int same, int block_len, int bc, int ec, int rcol, int *rc )
{
line_list_ptr p; /* temporary list pointer */
int lens; /* length of source line */
int lend; /* length of destination line */
int add; /* characters being added from another line */
char *block_buff;
char *swap_buff;
int xbc, xec; /* temporary column variables */
long li; /* temporary line variables */
long dest_add; /* number of bytes added to destination file */
WINDOW s_w, d_w; /* a couple of temporary WINDOWs for BOX stuff */
int padded_file;
WINDOW *w;
padded_file = FALSE;
dup_window_info( &s_w, source_window );
dup_window_info( &d_w, window );
s_w.rline = br;
s_w.ll = source;
s_w.visible = FALSE;
d_w.rline = rline;
d_w.ll = dest;
d_w.visible = FALSE;
block_buff = (char *)calloc( BUFF_SIZE + 2, sizeof(char) );
swap_buff = (char *)calloc( BUFF_SIZE + 2, sizeof(char) );
if (block_buff == NULL || swap_buff == NULL) {
error( WARNING, window->bottom_line, block4 );
*rc = ERROR;
}
/*
* special case for block actions. since block actions always
* move forward thru the file, overlapping text in an OVERLAY
* action don't do right. make the operation start at the end
* of the block and work backwards.
*/
if (*rc == OK && (action == OVERLAY || action == SWAP) &&
same && rline > br && rline <= er) {
/*
* see if we need to add padd lines at eof.
*/
dest_add = rline - br;
if (dest_add + er > window->file_info->length) {
dest_add = dest_add - (window->file_info->length - er);
p = dest_file->line_list_end->prev;
for (; dest_add > 0 && *rc == OK; dest_add--)
*rc = pad_dest_line( window, dest_file, p );
padded_file = TRUE;
}
/*
* move source and dest pointers to the end of the OVERLAY
*/
for (li=er-br; li > 0; li--) {
load_undo_buffer( dest_file, dest->line, dest->len );
dest = dest->next;
++d_w.rline;
source = source->next;
++s_w.rline;
}
/*
* work backwards so the overlapped OVERLAY block don't use
* overlayed text to fill the block. same for SWAPPing blocks.
*/
for (li=er; *rc == OK && li >= br && !g_status.control_break;
li--, s_w.rline--, d_w.rline--) {
lens = find_end( source->line, source->len );
lend = find_end( dest->line, dest->len );
if (lens != 0 || lend != 0) {
load_box_buff( block_buff, source, bc, ec, ' ' );
if (action == SWAP)
load_box_buff( swap_buff, dest, rcol, rcol+block_len, ' ' );
*rc = copy_buff_2file( &d_w, block_buff, dest, rcol,
block_len, action );
dest->dirty = TRUE;
if (action == SWAP) {
add = 0;
*rc = copy_buff_2file( &s_w, swap_buff, source, bc,
block_len, action );
source->dirty = TRUE;
}
}
source = source->prev;
dest = dest->prev;
}
} else {
if (action == FILL)
block_fill( block_buff, fill_char, block_len );
for (li=br; *rc == OK && li <= er && !g_status.control_break;
li++, s_w.rline++, d_w.rline++) {
lens = find_end( source->line, source->len );
lend = find_end( dest->line, dest->len );
switch (action) {
case FILL :
case NUMBER :
case DELETE :
case MOVE :
load_undo_buffer( source_file, source->line, source->len );
break;
case COPY :
case KOPY :
case OVERLAY :
load_undo_buffer( dest_file, dest->line, dest->len );
break;
}
/*
* with FILL and NUMBER operations, we're just adding chars
* to the file at the source location. we don't have to
* worry about bookkeeping.
*/
if (action == FILL || action == NUMBER) {
if (action == NUMBER) {
number_block_buff( block_buff, block_len, block_num, block_just );
block_num += block_inc;
}
*rc = copy_buff_2file( &s_w, block_buff, source, rcol,
block_len, action );
source->dirty = TRUE;
/*
* if we are doing a BOX action and both the source and
* destination are 0 then we have nothing to do.
*/
} else if (lens != 0 || lend != 0) {
/*
* do actions that may require adding to file
*/
if (action == MOVE || action == COPY || action == KOPY ||
action == OVERLAY || action == SWAP) {
xbc = bc;
xec = ec;
if (action != OVERLAY && action != SWAP && same) {
if (rcol < bc && rline > br && rline <=er)
if (li >= rline) {
xbc = bc + block_len;
xec = ec + block_len;
}
}
load_box_buff( block_buff, source, xbc, xec, ' ' );
if (action == SWAP)
load_box_buff( swap_buff, dest, rcol, rcol+block_len, ' ' );
*rc = copy_buff_2file( &d_w, block_buff, dest, rcol,
block_len, action );
dest->dirty = TRUE;
if (action == SWAP && *rc == OK) {
*rc = copy_buff_2file( &s_w, swap_buff, source, xbc,
block_len, action );
source->dirty = TRUE;
}
}
/*
* do actions that may require deleting from file
*/
if (action == MOVE || action == DELETE) {
lens = find_end( source->line, source->len );
if (lens >= (bc + 1)) {
source->dirty = TRUE;
add = block_len;
xbc = bc;
if (lens <= (ec + 1))
add = lens - bc;
if (same && action == MOVE) {
if (rcol < bc && rline >= br && rline <=er)
if (li >= rline) {
xbc = bc + block_len;
if (lens <= (ec + block_len + 1))
add = lens - xbc;
}
}
if (add > 0)
*rc = delete_box_block( &s_w, source, xbc, add );
}
}
}
/*
* if we are doing any BOX action we need to move the source pointer
* to the next line.
*/
source = source->next;
/*
* if we are doing any action other than DELETE, we need to move
* the destination to the next line in marked block.
* In BOX mode, we may need to pad the end of the file
* with a blank line before we process the next line.
*/
if (action != DELETE && action != FILL && action != NUMBER) {
p = dest->next;
if (p->len != EOF)
dest = p;
else if (li < er) {
padded_file = TRUE;
pad_dest_line( window, dest_file, p );
dest = dest->next;
}
}
}
}
if (block_buff != NULL)
free( block_buff );
if (swap_buff != NULL)
free( swap_buff );
if (padded_file) {
w = g_status.window_list;
while (w != NULL) {
if (w->file_info == dest_file && w->visible)
show_size( w );
w = w->next;
}
}
show_avail_mem( );
}
/*
* Name: load_box_buff
* Class: helper function
* Purpose: copy the contents of a BOX to a block buffer.
* Date: June 5, 1991
* Passed: block_buff: local buffer for block moves
* ll: node to source line in file to load
* bc: beginning column of BOX. used only in BOX operations.
* ec: ending column of BOX. used only in BOX operations.
* filler: character to fill boxes that end past eol
* Notes: For BOX blocks, there are several things to take care of:
* 1) The BOX begins and ends within a line - just copy the blocked
* characters to the block buff. 2) the BOX begins within a line
* but ends past the eol - copy all the characters within the line
* to the block buff then fill with padding. 3) the BOX begins and
* ends past eol - fill entire block buff with padding (filler).
* the fill character varies with the block operation. for sorting
* a box block, the fill character is '\0'. for adding text to
* the file, the fill character is a space.
*/
void load_box_buff( char *block_buff, line_list_ptr ll, int bc, int ec,
char filler )
{
int len;
int avlen;
register int i;
register char *bb;
text_ptr s;
assert( bc >= 0 );
assert( ec >= bc );
assert( ec < MAX_LINE_LENGTH );
bb = block_buff;
len = ll->len;
s = detab_a_line( ll->line, &len );
/*
* block start may be past eol
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -