From ad5a6e055285ad0eda6a2e43d99159427c75c65c Mon Sep 17 00:00:00 2001 From: axel Date: Thu, 5 Oct 2006 09:33:12 +1000 Subject: [PATCH] Move the code keeping track of file descriptor modification from reader.c to screen.c darcs-hash:20061004233312-ac50b-9a10ff758375885ae78a5e5c04279c1976a037ea.gz --- input_common.c | 2 +- reader.c | 107 +------------------------------------------------ screen.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- screen.h | 6 +++ 4 files changed, 106 insertions(+), 109 deletions(-) diff --git a/input_common.c b/input_common.c index c06ac4277..03af3a407 100644 --- a/input_common.c +++ b/input_common.c @@ -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; diff --git a/reader.c b/reader.c index b9155f6c2..765470073 100644 --- a/reader.c +++ b/reader.c @@ -70,7 +70,6 @@ commence. #include #include #include -#include #include #include @@ -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 ); diff --git a/screen.c b/screen.c index 222872614..deedb2efc 100644 --- a/screen.c +++ b/screen.c @@ -39,6 +39,7 @@ #endif #include +#include #include @@ -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 ) diff --git a/screen.h b/screen.h index d732fd405..03e89e5ab 100644 --- a/screen.h +++ b/screen.h @@ -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;