diff options
Diffstat (limited to 'lib/vio_lines.h')
-rw-r--r-- | lib/vio_lines.h | 121 |
1 files changed, 105 insertions, 16 deletions
diff --git a/lib/vio_lines.h b/lib/vio_lines.h index dd5545cc..6a3d13e9 100644 --- a/lib/vio_lines.h +++ b/lib/vio_lines.h @@ -24,6 +24,7 @@ #include "misc.h" #include "qiovec.h" +#include "qstring.h" /*============================================================================== * @@ -32,22 +33,24 @@ /*------------------------------------------------------------------------------ * Line control -- collecting lines of a given width for output. * - * NB: a completely zero structure is a valid, clear vio_line_control. + * NB: need to explicitly initialise line control in order to set the required + * new line, the qiovec vectors and a qstring buffer ! */ struct vio_line_control { - unsigned width ; /* console width -- 0 => HUGE */ - unsigned height ; /* console height -- 0 => indefinite */ + uint width ; /* console width -- 0 => HUGE */ + uint height ; /* console height -- 0 => indefinite */ - unsigned pause ; /* number of lines to next pause - 0 => indefinite */ - bool paused ; /* true <=> last append stopped on pause */ + int counter ; /* number of lines to next pause + <= 0 => paused. */ - unsigned col ; /* current column position */ - unsigned line ; /* line number of last complete line */ + bool incomplete ; /* fragments in hand are an incomplete line */ + qiovec fragments ; + qstring here ; /* any fragments after write */ - struct qiovec qiov ; /* iovec control */ - bool writing ; /* write started, but not completed */ + qiovec qiov ; /* output screen lines */ + + qiov_item_t newline ; /* the required sequence */ } ; typedef struct vio_line_control* vio_line_control ; @@ -55,32 +58,118 @@ typedef struct vio_line_control vio_line_control_t[1] ; enum { - VIO_LINE_CONTROL_INIT_ALL_ZEROS = true + VIO_LINE_CONTROL_INIT_ALL_ZEROS = false } ; /*============================================================================== * Functions */ extern vio_line_control vio_lc_init_new(vio_line_control lc, int width, - int height) ; + int height, + const char* newline) ; +Inline vio_line_control vio_lc_new(int width, int height, + const char* newline) ; extern vio_line_control vio_lc_reset(vio_line_control lc, free_keep_b free_structure) ; +Inline vio_line_control vio_lc_free(vio_line_control lc) ; -Inline bool vio_lc_empty(vio_line_control lc) ; extern void vio_lc_clear(vio_line_control lc) ; extern void vio_lc_set_window(vio_line_control lc, int width, int height) ; -extern void vio_lc_set_pause(vio_line_control lc) ; +Inline void vio_lc_counter_reset(vio_line_control lc) ; +Inline void vio_lc_clear_pause(vio_line_control lc) ; + +Inline bool vio_lc_counter_is_exhausted(vio_line_control lc) ; +Inline bool vio_lc_have_complete_line_in_hand(vio_line_control lc) ; +Inline bool vio_lc_is_empty(vio_line_control lc) ; + extern size_t vio_lc_append(vio_line_control lc, const void* buf, size_t len) ; +extern bool vio_lc_flush(vio_line_control lc) ; extern int vio_lc_write_nb(int fd, vio_line_control lc) ; /*------------------------------------------------------------------------------ + * Create new line control. + * + * Returns: address of new line control. + */ +Inline vio_line_control +vio_lc_new(int width, int height, const char* newline) +{ + return vio_lc_init_new(NULL, width, height, newline) ; +} ; + +/*------------------------------------------------------------------------------ + * Free given line control (if any). + * + * It is the caller's responsibility to free anything that the line control may + * point to. + * + * Returns: NULL + */ +Inline vio_line_control +vio_lc_free(vio_line_control lc) +{ + return vio_lc_reset(lc, free_it) ; +} ; + +/*------------------------------------------------------------------------------ + * Counter reset. + */ +Inline void +vio_lc_counter_reset(vio_line_control lc) +{ + lc->counter = (lc->height > 0) ? lc->height : 100 ; +} ; + +/*------------------------------------------------------------------------------ + * If no height is set, set counter to large number -- to do a tranche of + * output. + * + * Otherwise, if the line control is paused (or would pause as soon as any + * output is sent), reset the counter. + */ +Inline void +vio_lc_clear_pause(vio_line_control lc) +{ + if ((lc->counter <= 0) || (lc->height == 0)) + vio_lc_counter_reset(lc) ; +} ; + +/*------------------------------------------------------------------------------ + * Is the given line control counter exhausted ? + * + * Any attempt to output more stuff will be prevented -- except for + * vio_lc_flush() which will succeed if height is indefinite. + */ +Inline bool +vio_lc_counter_is_exhausted(vio_line_control lc) +{ + return (lc->counter <= 0) ; +} ; + +/*------------------------------------------------------------------------------ + * Do we have a complete line "in hand" ? + * + * This will only be the case if have a definite height, and the line counter + * has expired. + */ +Inline bool +vio_lc_have_complete_line_in_hand(vio_line_control lc) +{ + return !lc->incomplete && !qiovec_empty(lc->fragments) ; +} ; + +/*------------------------------------------------------------------------------ * Is given line control empty ? + * + * Is empty if the qiov is empty and there is nothing in hand. + * + * NB: if there is something in hand, it may be complete or incomplete. */ Inline bool -vio_lc_empty(vio_line_control lc) +vio_lc_is_empty(vio_line_control lc) { - return qiovec_empty(&lc->qiov) ; + return qiovec_empty(lc->qiov) && qiovec_empty(lc->fragments) ; } ; #endif /* _ZEBRA_VIO_LINES_H */ |