commit e6778c95c2a44a183acacb4df20c9db5706352be
parent 02d2827aa257ae919123ef1d046732b388eaa2d2
Author: Morel BĂ©renger <berengermorel76@gmail.com>
Date: Mon, 11 Jan 2021 04:18:43 +0100
btl: new functions: term_ch_size and indent_txt
Diffstat:
2 files changed, 82 insertions(+), 0 deletions(-)
diff --git a/btl/src/utils.cpp b/btl/src/utils.cpp
@@ -24,8 +24,12 @@
#include <iterator>
#include <algorithm>
+
#include "utils.hpp"
+#include <sys/ioctl.h>
+#include <termios.h>
+
//would probably be better without that many ifs
int esc_fputs( const char *s, FILE *stream )
{
@@ -91,3 +95,71 @@ size_t ungets( char const* const str, size_t str_sz )
}
return 0;
}
+
+bool term_ch_size( uint16_t *w, uint16_t *h, int fd )
+{
+ struct winsize wsz;
+ if( -1 == ioctl( fd, TIOCGWINSZ, &wsz ) )
+ {
+ return true;
+ }
+ *w = wsz.ws_col;
+ *h = wsz.ws_row;
+ return false;
+}
+
+bool indent_txt( char const* txt, char const* end, uint8_t level, uint16_t max_width, uint8_t tab_width, FILE* target )
+{
+ uint16_t indent_size = tab_width * level;
+ //bad args
+ if( !txt || !target )
+ {
+ return true;
+ }
+ //overflow
+ if( indent_size < tab_width || indent_size < level )
+ {
+ return true;
+ }
+ //indent wider than screen
+ if( indent_size > max_width )
+ {
+ return true;
+ }
+ max_width -= indent_size;
+ assert( max_width > 0 );
+
+ uint16_t pos = 0;
+ uint16_t last_blank = 0;
+ char const* ptr = txt;
+ for( ; ptr != end; ++ptr, ++pos )
+ {
+ if( isblank( *ptr ) )
+ {
+ last_blank = pos;
+ }
+
+ if( *ptr == '\n' || pos == max_width )
+ {
+ if( *ptr != '\n' && last_blank != 0 )
+ {
+ assert( pos >= last_blank );
+ ptr -= pos - last_blank;
+ pos = last_blank;
+ }
+ for( uint8_t l = 0; l < level; ++l )
+ {
+ fputc( '\t', target );
+ }
+ fprintf( target, "%.*s", pos, txt );
+ last_blank = 0;
+ pos = 0;
+ txt = ptr + 1;
+ if( *ptr != '\n' )
+ {
+ fputc( '\n', target );
+ }
+ }
+ }
+ return false;
+}
diff --git a/btl/src/utils.hpp b/btl/src/utils.hpp
@@ -98,4 +98,14 @@ inline uint16_t find_unescaped( int end, int esc, char ** str )
return find_unescaped( end, esc, str, strlen( *str ) );
}
+// returns the size in characters of terminal fd in w and h.
+// returns true on error.
+bool term_ch_size( uint16_t *w, uint16_t *h, int fd );
+
+// print [txt,end) on target, indenting it level times.
+// When a line is wider than max_width, try to break at last isblank(3).
+// returns true on error.
+// note:
+bool indent_txt( char const* txt, char const* end, uint8_t level, uint16_t max_width, uint8_t tab_width, FILE* target );
+
#endif