📄 utils.c
字号:
#include "tdestr.h"
#include "common.h"
#include "define.h"
#include "tdefunc.h"
/*
* Name: myiswhitespc
* Purpose: To determine whether or not a character is *NOT* part of a "word".
* Date: July 4, 1992
* Passed: c: the character to be tested
* Returns: TRUE if c is in the character set *NOT* part of a word
* Notes: The characters in the set not part of a word will not change as
* as much as the characters that are part of a word. In most
* languages, human and computer, the delimiters are much more
* common than the tokens that make up a word. For example,
* the set of punction characters don't change as much across
* languages, human and computer, as the characters that make
* up the alphabet, usually. In other words, the delimiters
* are fairly constant across languages.
*/
int myiswhitespc( int c )
{
return( c == ' ' || (ispunct( c ) && c != '_') || iscntrl( c ) );
}
/*
* Name: check_virtual_col
* Purpose: ensure integrity of rcol, ccol, and bcol
* Date: June 5, 1991
* Passed: window: pointer to current window
* rcol: real column of cursor
* ccol: current or logical column of cursor
*/
void check_virtual_col( WINDOW *window, int rcol, int ccol )
{
register int bcol;
int start_col;
int end_col;
file_infos *file;
file = window->file_info;
bcol = window->bcol;
start_col = window->start_col;
end_col = window->end_col;
/*
* is logical column past end of screen?
*/
if (ccol > end_col) {
/* ccol = start_col + (end_col + 1 - start_col) / 2; */
ccol = end_col;
bcol = rcol - (ccol - start_col);
file->dirty = LOCAL;
}
/*
* is logical column behind start of screen?
*/
if (ccol < start_col) {
if (bcol >= (start_col - ccol))
bcol -= (start_col - ccol);
ccol = start_col;
file->dirty = LOCAL;
}
/*
* is real column < base column?
*/
if (rcol < bcol) {
ccol = rcol + start_col;
bcol = 0;
if (ccol > end_col) {
bcol = rcol;
ccol = start_col;
}
file->dirty = LOCAL;
}
/*
* current column + base column MUST equal real column
*/
if ((ccol - start_col) + bcol != rcol) {
if (bcol < 0 || bcol > rcol) {
bcol = rcol;
file->dirty = LOCAL;
}
ccol = rcol - bcol + start_col;
if (ccol > end_col) {
bcol = rcol;
ccol = start_col;
file->dirty = LOCAL;
}
}
/*
* rcol CANNOT be negative
*/
if (rcol < 0) {
rcol = bcol = 0;
ccol = start_col;
file->dirty = LOCAL;
}
if (rcol >= MAX_LINE_LENGTH) {
rcol = MAX_LINE_LENGTH - 1;
bcol = rcol - (ccol - start_col);
}
assert( rcol >= 0 );
assert( rcol < MAX_LINE_LENGTH );
assert( bcol >= 0 );
assert( bcol < MAX_LINE_LENGTH );
assert( ccol >= start_col );
assert( ccol <= end_col );
window->bcol = bcol;
window->ccol = ccol;
window->rcol = rcol;
}
/*
* Name: copy_line
* Purpose: To copy the cursor line, if necessary, into the current line
* buffer, so that changes can be made efficiently.
* Date: June 5, 1991
* Passed: text_line: line to be copied to line buffer
* line: line to display error message
* Notes: See un_copy_line, the reverse operation.
* DO NOT use the C library string functions on text in
* g_status.line_buff, because Null characters are allowed as
* normal text in the file.
*/
void copy_line( line_list_ptr ll )
{
register unsigned int len;
text_ptr text_line;
if (g_status.copied == FALSE && ll->len != EOF) {
assert( ll != NULL );
len = ll->len;
text_line = ll->line;
g_status.buff_node = ll;
assert( len < MAX_LINE_LENGTH );
if (text_line != NULL)
_fmemcpy( g_status.line_buff, text_line, len );
g_status.line_buff_len = len;
g_status.copied = TRUE;
}
}
/*
* Name: un_copy_line
* Purpose: To copy the cursor line, if necessary, from the current line
* buffer, shifting the main text to make the right amount of
* room.
* Date: June 5, 1991
* Passed: test_line: location in file to copy line buffer
* window: pointer to current window
* del_trailing: delete the trailing blanks at eol? TRUE or FALSE
* Notes: For some functions, trailing spaces should not be removed when
* returning the line buffer to the main text. The JoinLine function
* is a good example. We need to leave trailing space so when we
* join lines - the current line will extend at least up to
* the column of the cursor. We need to leave trailing space
* during BOX block operations.
* See copy_line, the reverse operation.
*/
int un_copy_line( line_list_ptr ll, WINDOW *window, int del_trailing )
{
text_ptr p;
size_t len; /* length of line buffer text */
size_t ll_len; /* length of ll->line */
int net_change;
int rc;
char c;
file_infos *file;
WINDOW *wp;
rc = OK;
if (mode.do_backups == TRUE)
rc = backup_file( window );
if (g_status.copied == TRUE && ll->len != EOF) {
file = window->file_info;
/*
* if we are deleting the entire line, don't worry about the
* deleting the trailing space, since we're deleting entire line.
*/
if (g_status.command == DeleteLine)
del_trailing = FALSE;
if (del_trailing && mode.trailing && file->crlf != BINARY) {
len = g_status.line_buff_len;
for (p=(text_ptr)(g_status.line_buff+len); len > 0; len--, p--) {
c = *(p - 1);
if (c != ' ' && c != '\t')
break;
if (!mode.inflate_tabs && c == '\t')
break;
}
g_status.line_buff_len = len;
file->dirty = GLOBAL;
if (window->visible == TRUE)
show_changed_line( window );
}
len = g_status.line_buff_len;
ll_len = (ll->line == NULL) ? 0 : ll->len;
assert( len < MAX_LINE_LENGTH );
assert( ll_len < MAX_LINE_LENGTH );
net_change = len - ll_len;
if (ll_len != len || ll->line == NULL) {
/*
* let malloc space for the new line before we free the old line.
*/
p = my_malloc( len, &rc );
if (rc == ERROR)
error( WARNING, window->bottom_line, main4 );
/*
* free the space taken up by current line in far heap.
*/
if (rc != ERROR && ll->line != NULL)
my_free( ll->line );
} else
p = ll->line;
if (rc != ERROR) {
if (len > 0)
_fmemcpy( p, g_status.line_buff, len );
ll->line = p;
ll->len = len;
if (net_change != 0) {
for (wp=g_status.window_list; wp != NULL; wp=wp->next) {
if (wp->file_info == file && wp != window)
if (wp->rline > window->rline)
wp->bin_offset += net_change;
}
}
file->modified = TRUE;
show_avail_mem( );
}
}
g_status.copied = FALSE;
return( rc );
}
/*
* Name: un_copy_tab_buffer
* Purpose: To copy the tab buffer line the main text buffer
* Date: October 31, 1992
* Passed: line_number: line number to copy line tab out buffer
* window: pointer to current window
*/
int un_copy_tab_buffer( line_list_ptr ll, WINDOW *window )
{
text_ptr p;
int len; /* length of current line buffer text */
int net_change;
int rc;
file_infos *file;
WINDOW *wp;
rc = OK;
file = window->file_info;
/*
* file has changed. lets create the back_up if needed
*/
if (mode.do_backups == TRUE) {
window->file_info->modified = TRUE;
rc = backup_file( window );
}
len = g_status.tabout_buff_len;
assert( len >= 0 );
assert( len < MAX_LINE_LENGTH );
assert( ll->len >= 0 );
assert( ll->len < MAX_LINE_LENGTH );
/*
* if the far heap has run out of space, then only part of the
* current line can be moved back into the far heap. Warn the user
* that some of the current line has been lost.
*/
p = my_malloc( len, &rc );
if (rc == ERROR)
error( WARNING, window->bottom_line, main4 );
if (rc == OK) {
net_change = len - ll->len;
if (ll->line != NULL)
my_free( ll->line );
if (len > 0)
_fmemcpy( p, g_status.line_buff, len );
ll->line = p;
ll->len = len;
if (net_change != 0) {
for (wp=g_status.window_list; wp != NULL; wp=wp->next) {
if (wp->file_info == file && wp != window)
if (wp->rline > window->rline)
wp->bin_offset += net_change;
}
}
file->modified = TRUE;
}
return( rc );
}
/*
* Name: load_undo_buffer
* Purpose: To copy the cursor line to the undo buffer.
* Date: September 26, 1991
* Passed: file: pointer to file
* line_to_undo: pointer to line in file to save
* Notes: save the last mode.undo_max lines in a stack. when we overflow
* the stack, dump the oldest line.
*/
void load_undo_buffer( file_infos *file, text_ptr line_to_undo, int len )
{
int rc;
text_ptr l;
line_list_ptr temp_ll;
rc = OK;
if (file->undo_count >= mode.undo_max) {
--file->undo_count;
temp_ll = file->undo_bot->prev;
temp_ll->prev->next = file->undo_bot;
file->undo_bot->prev = temp_ll->prev;
if (temp_ll->line != NULL)
my_free( temp_ll->line );
} else
temp_ll = (line_list_ptr)my_malloc( sizeof(line_list_struc), &rc );
assert( len >= 0 );
assert( len < MAX_LINE_LENGTH );
l = my_malloc( len, &rc );
if (rc == ERROR) {
if (l != NULL)
my_free( l );
if (temp_ll != NULL)
my_free( temp_ll );
} else {
if (len > 0)
_fmemcpy( l, line_to_undo, len );
temp_ll->line = l;
temp_ll->len = len;
temp_ll->dirty = TRUE;
temp_ll->prev = NULL;
temp_ll->next = file->undo_top;
file->undo_top->prev = temp_ll;
file->undo_top = temp_ll;
++file->undo_count;
}
}
/*
* Name: set_prompt
* Purpose: To display a prompt, highlighted, at the bottom of the screen.
* Date: October 1, 1989
* Passed: prompt: prompt to be displayed
* line: line to display prompt
*/
void set_prompt( char *prompt, int line )
{
register int prompt_col;
/*
* work out where the answer should go
*/
prompt_col = strlen( prompt );
assert( prompt_col <= MAX_COLS );
/*
* output the prompt
*/
s_output( prompt, line, 0, g_display.message_color );
eol_clear( prompt_col, line, g_display.message_color );
/*
* put cursor at end of prompt
*/
xygoto( prompt_col, line );
}
/*
* Name: get_name
* Purpose: To prompt the user and read the string entered in response.
* Date: June 5, 1992
* Passed: prompt: prompt to offer the user
* line: line to display prompt
* name: default answer
* color: color to display prompt
* Returns: name: user's answer
* OK if user entered something
* ERROR if user aborted the command
* Notes: with the addition of macros in tde, this function became a little
* more complicated. we have to deal with both executing macros
* and macros that are the user uses when entering normal text
* at the prompt. i call these local and global macros. a global
* macro is when this function is called from a running macro.
* the running macro can enter text and return from this function
* w/o any action from the user. a local macro is when the user
* presses a key inside this function, which happens quite often
* when keys are assigned to ASCII and Extended ASCII characters.
*/
int get_name( char *prompt, int line, char *name, int color )
{
int col; /* cursor column for answer */
int c; /* character user just typed */
char *cp; /* cursor position in answer */
char *answer; /* user's answer */
int first = TRUE; /* first character typed */
register int len; /* length of answer */
int plen; /* length of prompt */
int func; /* function of key pressed */
int stop; /* flag to stop getting characters */
char *p; /* for copying text in answer */
char buffer[MAX_COLS+2];/* line on which name is being entered */
char line_buff[(MAX_COLS+1)*2]; /* buffer for char and attribute */
int normal;
int local_macro = FALSE;
int next;
int regx_help_on;
char **pp;
int i;
/*
* set up prompt and default
*/
assert( strlen( prompt ) < MAX_COLS );
assert( strlen( name ) < MAX_COLS );
strcpy( buffer, prompt );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -