tools

various tools
git clone git://deadbeef.fr/tools.git
Log | Files | Refs | README | LICENSE

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:
Mbtl/src/utils.cpp | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbtl/src/utils.hpp | 10++++++++++
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