📄 block.c
字号:
if (len < ec + 1) {
/*
* does block start past eol? - fill with pad
*/
assert( ec + 1 - bc >= 0 );
memset( block_buff, filler, (ec + 1) - bc );
if (len >= bc) {
/*
* block ends past eol - fill with pad
*/
avlen = len - bc;
s += bc;
for (i=avlen; i>0; i--)
*bb++ = *s++;
}
} else {
/*
* block is within line - copy block to buffer
*/
avlen = (ec + 1) - bc;
s = s + bc;
for (i=avlen; i>0; i--)
*bb++ = *s++;
}
}
/*
* Name: copy_buff_2file
* Class: helper function
* Purpose: copy the contents of block buffer to destination file
* Date: June 5, 1991
* Passed: window: pointer to current window
* block_buff: local buffer for moves
* dest: pointer to destination line in destination file
* rcol: if in BOX mode, destination column in destination file
* block_len: if in BOX mode, width of block to copy
* action: type of block action
* Notes: In BOX mode, the destination line has already been prepared.
* Just copy the BOX buffer to the destination line.
*/
int copy_buff_2file( WINDOW *window, char *block_buff, line_list_ptr dest,
int rcol, int block_len, int action )
{
char *s;
char *d;
int len;
int pad;
int add;
copy_line( dest );
if (mode.inflate_tabs)
detab_linebuff( );
len = g_status.line_buff_len;
assert( len >= 0 );
assert( len < MAX_LINE_LENGTH );
assert( rcol >= 0 );
assert( rcol < MAX_LINE_LENGTH );
assert( block_len >= 0 );
assert( block_len < BUFF_SIZE );
if (rcol > len) {
pad = rcol - len;
assert( pad >= 0 );
assert( pad < MAX_LINE_LENGTH );
memset( g_status.line_buff + len, ' ', pad );
len += pad;
}
s = g_status.line_buff + rcol;
/*
* s is pointing to location to perform BOX operation. If we do a
* FILL or OVERLAY, we do not necessarily add any extra space. If the
* line does not extend all the thru the BOX then we add.
* we always add space when we COPY, KOPY, or MOVE
*/
if (action == FILL || action == OVERLAY || action == NUMBER || action == SWAP) {
add = len - rcol;
if (add < block_len) {
pad = block_len - add;
assert( pad >= 0 );
assert( pad < MAX_LINE_LENGTH );
memset( g_status.line_buff + len, ' ', pad );
len += pad;
}
} else {
d = s + block_len;
add = len - rcol;
assert( add >= 0 );
assert( add < MAX_LINE_LENGTH );
memmove( d, s, add );
len += block_len;
}
assert( rcol + block_len <= len );
assert( len >= 0 );
assert( len < MAX_LINE_LENGTH );
memmove( s, block_buff, block_len );
g_status.line_buff_len = len;
if (mode.inflate_tabs)
entab_linebuff( );
return( un_copy_line( dest, window, TRUE ) );
}
/*
* Name: block_fill
* Class: helper function
* Purpose: fill the block buffer with character
* Date: June 5, 1991
* Passed: block_buff: local buffer for moves
* fill_char: fill character
* block_len: number of columns in block
* Notes: Fill block_buffer for block_len characters using fill_char. This
* function is used only for BOX blocks.
*/
void block_fill( char *block_buff, int fill_char, int block_len )
{
assert( block_len >= 0 );
assert( block_len < BUFF_SIZE );
assert( block_buff != NULL );
memset( block_buff, fill_char, block_len );
}
/*
* Name: number_block_buff
* Class: helper function
* Purpose: put a number into the block buffer
* Date: June 5, 1991
* Passed: block_buff: local buffer for moves
* block_len: number of columns in block
* block_num: long number to fill block
* just: LEFT or RIGHT justified?
* Notes: Fill block_buffer for block_len characters with number.
* This function is used only for BOX blocks.
*/
void number_block_buff( char *block_buff, int block_len, long block_num,
int just )
{
int len; /* length of number buffer */
int i;
char temp[MAX_COLS]; /* buffer for long number to ascii conversion */
assert( block_len >= 0 );
assert( block_len < BUFF_SIZE );
block_fill( block_buff, ' ', block_len );
len = strlen( ltoa( block_num, temp, 10 ) );
if (just == RIGHT) {
block_len--;
len--;
for (;block_len >= 0 && len >= 0; block_len--, len--)
block_buff[block_len] = temp[len];
} else {
for (i=0; block_len > 0 && i < len; block_len--, i++)
block_buff[i] = temp[i];
}
}
/*
* Name: restore_cursors
* Class: helper function
* Purpose: a file has been modified - must restore all cursor pointers
* Date: June 5, 1991
* Passed: file: pointer to file with changes
* Notes: Go through the window list and adjust the cursor pointers
* as needed.
*/
void restore_cursors( file_infos *file )
{
register WINDOW *window;
line_list_ptr ll;
long n;
assert( file != NULL );
window = g_status.window_list;
while (window != NULL) {
if (window->file_info == file) {
window->bin_offset = 0;
if (window->rline < 1L)
window->rline = 1L;
if (window->rline > file->length)
window->rline = file->length;
ll = file->line_list;
n = 1L;
for (; n < window->rline; n++) {
window->bin_offset += ll->len;
ll = ll->next;
}
window->ll = ll;
if (window->rline < (window->cline - (window->top_line+window->ruler-1)))
window->cline = (int)window->rline + window->top_line+window->ruler-1;
if (window->cline < window->top_line + window->ruler)
window->cline = window->top_line + window->ruler;
if (window->visible)
show_size( window );
}
window = window->next;
}
}
/*
* Name: delete_box_block
* Class: helper function
* Purpose: delete the marked text
* Date: June 5, 1991
* Passed: s_w: source window
* source: pointer to line with block to delete
* bc: beginning column of block - BOX mode only
* add: number of characters in block to delete
* Notes: Used only for BOX blocks. Delete the block.
*/
int delete_box_block( WINDOW *s_w, line_list_ptr source, int bc, int add )
{
char *s;
int number;
assert( s_w != NULL );
assert( source != NULL );
assert( bc >= 0 );
assert( bc < MAX_LINE_LENGTH );
assert( add >= 0 );
assert( add < MAX_LINE_LENGTH );
copy_line( source );
detab_linebuff( );
number = g_status.line_buff_len - bc;
s = g_status.line_buff + bc + add;
assert( number >= 0 );
assert( number < MAX_LINE_LENGTH );
assert( bc + add >= 0 );
assert( bc + add < MAX_LINE_LENGTH );
assert( add <= g_status.line_buff_len );
memmove( s - add, s, number );
g_status.line_buff_len -= add;
entab_linebuff( );
return( un_copy_line( source, s_w, TRUE ) );
}
/*
* Name: check_block
* Class: helper function
* Purpose: To check that the block is still valid.
* Date: June 5, 1991
* Notes: After some editing, the marked block may not be valid. For example,
* deleting all the lines in a block in another window. We don't
* need to keep up with the block text pointers while doing normal
* editing; however, we need to refresh them before doing block stuff.
*/
void check_block( void )
{
register file_infos *file;
WINDOW filler;
file = g_status.marked_file;
if (file == NULL || file->block_br > file->length)
unmark_block( &filler );
else {
if (file->block_er > file->length)
file->block_er = file->length;
find_begblock( file );
find_endblock( file );
}
}
/*
* Name: find_begblock
* Class: helper editor function
* Purpose: find the beginning line in file with marked block
* Date: June 5, 1991
* Passed: file: file containing marked block
* Notes: file->block_start contains starting line of marked block.
*/
void find_begblock( file_infos *file )
{
line_list_ptr ll;
long li; /* line counter (long i) */
assert( file != NULL );
assert( file->line_list != NULL );
ll = file->line_list;
for (li=1; li<file->block_br && ll->next != NULL; li++)
ll = ll->next;
file->block_start = ll;
}
/*
* Name: find_endblock
* Class: helper function
* Purpose: find the ending line in file with marked block
* Date: June 5, 1991
* Passed: file: file containing marked block
* Notes: If in LINE mode, file->block_end is set to end of line of last
* line in block. If in BOX mode, file->block_end is set to
* beginning of last line in marked block. If the search for the
* ending line of the marked block goes past the eof, set the
* ending line of the block to the last line in the file.
*/
void find_endblock( file_infos *file )
{
line_list_ptr ll; /* start from beginning of file and go to end */
long i; /* line counter */
register file_infos *fp;
assert( file != NULL );
assert( file->block_start != NULL );
fp = file;
ll = fp->block_start;
if (ll != NULL) {
for (i=fp->block_br; i < fp->block_er && ll->next != NULL; i++)
ll = ll->next;
if (ll != NULL)
fp->block_end = ll;
else {
/*
* last line in marked block is NULL. if LINE block, set end to
* last character in the file. if STREAM or BOX block, set end to
* start of last line in file. ending row, or er, is then set to
* file length.
*/
fp->block_end = fp->line_list_end->prev;
fp->block_er = fp->length;
}
}
}
/*
* Name: block_write
* Class: primary editor function
* Purpose: To write the currently marked block to a disk file.
* Date: June 5, 1991
* Passed: window: pointer to current window
* Notes: If the file already exists, the user gets to choose whether
* to overwrite or append.
*/
int block_write( WINDOW *window )
{
int prompt_line;
int rc;
char buff[MAX_COLS+2]; /* buffer for char and attribute */
char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */
file_infos *file;
int block_type;
int fattr;
/*
* make sure block is marked OK
*/
entab_linebuff( );
rc = un_copy_line( window->ll, window, TRUE );
check_block( );
if (rc == OK && g_status.marked == TRUE) {
prompt_line = window->bottom_line;
file = g_status.marked_file;
assert( file != NULL );
block_type = file->block_type;
/*
* find out which file to write to
*/
save_screen_line( 0, prompt_line, line_buff );
*g_status.rw_name = '\0';
if (get_name( block6, prompt_line, g_s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -