summaryrefslogtreecommitdiffstats
path: root/lib/vio_lines.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vio_lines.h')
-rw-r--r--lib/vio_lines.h121
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 */