diff options
Diffstat (limited to 'lib/vio_lines.h')
-rw-r--r-- | lib/vio_lines.h | 158 |
1 files changed, 127 insertions, 31 deletions
diff --git a/lib/vio_lines.h b/lib/vio_lines.h index ffef94ec..be62f143 100644 --- a/lib/vio_lines.h +++ b/lib/vio_lines.h @@ -22,16 +22,9 @@ #ifndef _ZEBRA_VIO_LINES_H #define _ZEBRA_VIO_LINES_H -#include "zebra.h" - -#include <stddef.h> -#include <stdint.h> - +#include "misc.h" #include "qiovec.h" - -#ifndef Inline -#define Inline static inline -#endif +#include "qstring.h" /*============================================================================== * @@ -40,52 +33,155 @@ /*------------------------------------------------------------------------------ * 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 ! */ - -typedef struct vio_line_control* vio_line_control ; -typedef struct vio_line_control vio_line_control_t ; 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 */ + + int counter ; /* number of lines to next pause + <= 0 => paused. */ + + bool incomplete ; /* fragments in hand are an incomplete line */ + qiovec fragments ; + qstring here ; /* any fragments after write */ + + qiovec qiov ; /* output screen lines */ - unsigned pause ; /* number of lines to next pause - 0 => indefinite */ - bool paused ; /* true <=> last append stopped on pause */ + qiov_item_t newline ; /* the required sequence */ +} ; - unsigned col ; /* current column position */ - unsigned line ; /* line number of last complete line */ +typedef struct vio_line_control* vio_line_control ; +typedef struct vio_line_control vio_line_control_t[1] ; - struct qiovec qiov ; /* iovec control */ - bool writing ; /* write started, but not completed */ +enum +{ + VIO_LINE_CONTROL_INIT_ALL_ZEROS = false } ; /*============================================================================== * Functions */ extern vio_line_control vio_lc_init_new(vio_line_control lc, int width, - int height) ; -extern vio_line_control vio_lc_reset(vio_line_control lc, bool free_structure) ; - -#define vio_lc_reset_keep(lc) vio_lc_reset(lc, 0) -#define vio_lc_reset_free(lc) vio_lc_reset(lc, 1) + 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) ; +Inline bool vio_lc_pending(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_is_empty(vio_line_control lc) +{ + return qiovec_empty(lc->qiov) && qiovec_empty(lc->fragments) ; +} ; + +/*------------------------------------------------------------------------------ + * Is there something pending, still to be written, in the qiov ? + * + * NB: ignoring anything that there may be in hand. */ Inline bool -vio_lc_empty(vio_line_control lc) +vio_lc_pending(vio_line_control lc) { - return qiovec_empty(&lc->qiov) ; + return lc->qiov->writing ; } ; #endif /* _ZEBRA_VIO_LINES_H */ |