Move the code keeping track of file descriptor modification from reader.c to screen.c

darcs-hash:20061004233312-ac50b-9a10ff758375885ae78a5e5c04279c1976a037ea.gz
This commit is contained in:
axel 2006-10-05 09:33:12 +10:00
parent 873fd83307
commit ad5a6e0552
4 changed files with 106 additions and 109 deletions

View file

@ -186,7 +186,7 @@ wchar_t input_common_readch( int timed )
int sz;
if( (b == R_NULL) || (b == R_EOF) )
if( (b >= R_NULL) && (b < R_NULL + 1000) )
return b;
bb=b;

107
reader.c
View file

@ -70,7 +70,6 @@ commence.
#include <signal.h>
#include <fcntl.h>
#include <dirent.h>
#include <time.h>
#include <wchar.h>
#include <assert.h>
@ -265,14 +264,6 @@ static int end_loop = 0;
*/
static array_list_t current_filename;
/**
These status buffers are used to check if any output has occurred
other than from fish's main loop, in which case we need to redraw.
*/
static struct stat prev_buff_1, prev_buff_2, post_buff_1, post_buff_2;
/**
List containing strings which make up the prompt
*/
@ -304,8 +295,6 @@ static struct termios old_modes;
*/
static struct termios saved_modes;
static void reader_save_status();
static void reader_check_status();
static void reader_super_highlight_me_plenty( int *color, int pos, array_list_t *error );
/**
@ -372,18 +361,6 @@ static void term_steal()
}
/**
Test if there is space between the time fields of struct stat to
use for sub second information. If so, we assume this space
contains the desired information.
*/
static int room_for_usec(struct stat *st)
{
int res = ((&(st->st_atime) + 2) == &(st->st_mtime) &&
(&(st->st_atime) + 4) == &(st->st_ctime));
return res;
}
int reader_exit_forced()
{
return exit_forced;
@ -655,79 +632,6 @@ void repaint()
s_write( &data->screen, (wchar_t *)data->prompt_buff.buff, data->buff, data->color, data->buff_pos );
reader_save_status();
}
/**
Stat stdout and stderr and save result.
This should be done before calling a function that may cause output.
*/
static void reader_save_status()
{
/*
This futimes call tries to trick the system into using st_mtime
as a tampering flag. This of course only works on systems where
futimes is defined, but it should make the status saving stuff
failsafe.
*/
struct timeval t[]=
{
{
time(0)-1,
0
}
,
{
time(0)-1,
0
}
}
;
/*
Don't check return value on these. We don't care if they fail,
really. This is all just to make the prompt look ok, which is
impossible to do 100% reliably. We try, at least.
*/
futimes( 1, t );
futimes( 2, t );
fstat( 1, &prev_buff_1 );
fstat( 2, &prev_buff_2 );
}
/**
Stat stdout and stderr and compare result to previous result in
reader_save_status. Repaint if modification time has changed.
Unfortunately, for some reason this call seems to give a lot of
false positives, at least under Linux.
*/
static void reader_check_status()
{
fflush( stdout );
fflush( stderr );
fstat( 1, &post_buff_1 );
fstat( 2, &post_buff_2 );
int changed = ( prev_buff_1.st_mtime != post_buff_1.st_mtime ) ||
( prev_buff_2.st_mtime != post_buff_2.st_mtime );
if (room_for_usec( &post_buff_1))
{
changed = changed || ( (&prev_buff_1.st_mtime)[1] != (&post_buff_1.st_mtime)[1] ) ||
( (&prev_buff_2.st_mtime)[1] != (&post_buff_2.st_mtime)[1] );
}
if( changed )
{
repaint();
}
}
/**
@ -2076,11 +1980,6 @@ wchar_t *reader_readline()
while( !finished && !data->end_loop)
{
/*
Save the terminal status so we know if we have to redraw
*/
reader_save_status();
/*
Sometimes strange input sequences seem to generate a zero
@ -2130,8 +2029,6 @@ wchar_t *reader_readline()
break;
}
reader_check_status();
if( (last_char == R_COMPLETE) && (c != R_COMPLETE) && (!comp_empty) )
{
al_foreach( &comp, &free );
@ -2141,7 +2038,7 @@ wchar_t *reader_readline()
if( last_char != R_YANK && last_char != R_YANK_POP )
yank=0;
switch( c )
{
@ -2214,9 +2111,7 @@ wchar_t *reader_readline()
len = data->buff_pos - (begin-data->buff);
buffcpy = wcsndup( begin, len );
reader_save_status();
data->complete_func( buffcpy, &comp );
reader_check_status();
sort_list( &comp );
remove_duplicates( &comp );

100
screen.c
View file

@ -39,6 +39,7 @@
#endif
#include <wchar.h>
#include <time.h>
#include <assert.h>
@ -199,6 +200,90 @@ static int calc_prompt_width( wchar_t *prompt )
return res;
}
/**
Test if there is space between the time fields of struct stat to
use for sub second information. If so, we assume this space
contains the desired information.
*/
static int room_for_usec(struct stat *st)
{
int res = ((&(st->st_atime) + 2) == &(st->st_mtime) &&
(&(st->st_atime) + 4) == &(st->st_ctime));
return res;
}
/**
Stat stdout and stderr and save result.
This should be done before calling a function that may cause output.
*/
static void s_save_status( screen_t *s)
{
/*
This futimes call tries to trick the system into using st_mtime
as a tampering flag. This of course only works on systems where
futimes is defined, but it should make the status saving stuff
failsafe.
*/
struct timeval t[]=
{
{
time(0)-1,
0
}
,
{
time(0)-1,
0
}
}
;
/*
Don't check return value on these. We don't care if they fail,
really. This is all just to make the prompt look ok, which is
impossible to do 100% reliably. We try, at least.
*/
futimes( 1, t );
futimes( 2, t );
fstat( 1, &s->prev_buff_1 );
fstat( 2, &s->prev_buff_2 );
}
/**
Stat stdout and stderr and compare result to previous result in
reader_save_status. Repaint if modification time has changed.
Unfortunately, for some reason this call seems to give a lot of
false positives, at least under Linux.
*/
static void s_check_status( screen_t *s)
{
fflush( stdout );
fflush( stderr );
fstat( 1, &s->post_buff_1 );
fstat( 2, &s->post_buff_2 );
int changed = ( s->prev_buff_1.st_mtime != s->post_buff_1.st_mtime ) ||
( s->prev_buff_2.st_mtime != s->post_buff_2.st_mtime );
if (room_for_usec( &s->post_buff_1))
{
changed = changed || ( (&s->prev_buff_1.st_mtime)[1] != (&s->post_buff_1.st_mtime)[1] ) ||
( (&s->prev_buff_2.st_mtime)[1] != (&s->post_buff_2.st_mtime)[1] );
}
if( changed )
{
s_reset( s );
}
}
/**
Free all memory used by one line_t struct.
*/
@ -491,12 +576,14 @@ static void s_update( screen_t *scr, wchar_t *prompt )
int prompt_width = calc_prompt_width( prompt );
int current_width=0;
int screen_width = common_get_width();
int resize = 0;
buffer_t output;
b_init( &output );
if( scr->actual_width != screen_width )
{
resize = 1;
s_move( scr, &output, 0, 0 );
scr->actual_width = screen_width;
s_reset( scr );
@ -518,6 +605,12 @@ static void s_update( screen_t *scr, wchar_t *prompt )
int start_pos = (i==0?prompt_width:0);
current_width = start_pos;
if( resize )
{
s_move( scr, &output, start_pos, i );
s_write_mbs( &output, clr_eol);
}
if( !s_line )
{
s_line = s_create_line();
@ -528,6 +621,7 @@ static void s_update( screen_t *scr, wchar_t *prompt )
{
wchar_t o = (wchar_t)al_get( &o_line->text, j );
int o_c = (int)al_get( &o_line->color, j );
if( !o )
continue;
@ -601,6 +695,8 @@ void s_write( screen_t *s,
int prompt_width = calc_prompt_width( prompt );
int screen_width = common_get_width();
s_check_status( s );
/*
Ignore huge prompts on small screens
*/
@ -652,7 +748,7 @@ void s_write( screen_t *s,
memcpy( s->desired_cursor, cursor_arr, sizeof(int)*2 );
s_update( s, prompt );
s_save_status( s );
}
void s_reset( screen_t *s )

View file

@ -40,6 +40,12 @@ typedef struct
write.
*/
int actual_width;
/**
These status buffers are used to check if any output has occurred
other than from fish's main loop, in which case we need to redraw.
*/
struct stat prev_buff_1, prev_buff_2, post_buff_1, post_buff_2;
}
screen_t;