tools

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

utils.hpp (3793B)


      1 // Copyright (c) 2020 Morel BĂ©renger
      2 // 
      3 // This software is provided 'as-is', without any express or implied
      4 // warranty. In no event will the authors be held liable for any damages
      5 // arising from the use of this software.
      6 // 
      7 // Permission is granted to anyone to use this software for any purpose,
      8 // including commercial applications, and to alter it and redistribute it
      9 // freely, subject to the following restrictions:
     10 // 
     11 // 1. The origin of this software must not be misrepresented; you must not
     12 //    claim that you wrote the original software. If you use this software
     13 //    in a product, an acknowledgment in the product documentation would be
     14 //    appreciated but is not required.
     15 // 2. Altered source versions must be plainly marked as such, and must not be
     16 //    misrepresented as being the original software.
     17 // 3. This notice may not be removed or altered from any source distribution.
     18 
     19 // This files contains various utilities and macros, some
     20 // useful, some useless, some harmful.
     21 
     22 #ifndef UTILS_HPP
     23 #define UTILS_HPP
     24 
     25 //TODO I wish this could be avoided, but FILE* is used there.
     26 #include <stdio.h>
     27 
     28 #define xstr(s) str(s)
     29 #define str(s) #s
     30 #define HEADER_LOG __FILE__ "[" xstr(__LINE__) "]"
     31 
     32 #ifndef NDEBUG
     33 //abort-like macro, but more flexible
     34 #define BUG_CHECK( cond, err )                                     \
     35 	do                                                               \
     36 	{                                                                \
     37 		if( cond )                                                     \
     38 		{                                                              \
     39 			fputs( HEADER_LOG ": " #err " caused by " #cond, stderr ); \
     40 			abort();                                                     \
     41 		}                                                              \
     42 	} while( 0 )
     43 #else
     44 #define BUG_CHECK( cond, err ) if( cond ) return err
     45 #endif
     46 
     47 //display a system error
     48 #define syserr( str )                   \
     49 	do {                                  \
     50 		fputs( HEADER_LOG ": ", stderr );   \
     51 		fputs( strerror( errno ), stderr ); \
     52 		fputs( ": " str "\n", stderr );     \
     53 	} while( 0 )
     54 
     55 // C++ malloc, because casting from malloc is annoying and
     56 // new does not just allocates (it constructs, too).
     57 #define ALLOC( type ) static_cast<type*>( malloc( sizeof( type ) ) )
     58 // tired of looooong lines of code because casting and
     59 // dereferencing? This saves 6 out of 11 characters per use.
     60 #define REDEF( type, dst, src ) type& dst = *static_cast<type*>( src )
     61 
     62 //simply check if an array is nullptr or starts with a value considered invalid
     63 template <typename T, T INVALID=T()>
     64 inline bool empty_array( T* arr )
     65 {
     66 	return !arr || *arr == INVALID;
     67 }
     68 
     69 //like fputs, but when character is blank, prints the C escape instead
     70 //returns 0 on success, INT_MAX on error
     71 int esc_fputs( const char *s, FILE *stream );
     72 
     73 // prints a string into stdin for further reading. Might not
     74 // be null-terminated.
     75 inline size_t ungets( char const* const str, size_t str_sz );
     76 
     77 // search for a specific character, if not preceded by an escape one.
     78 // return the distance, or end - start if not found
     79 inline uint16_t find_unescaped( int ch, int esc_ch, char const* start, char const* end )
     80 {
     81 	uint16_t ret = 0;
     82 	for( ; start != end && *start != ch; ++start, ++ret )
     83 	{
     84 		if( *start == esc_ch )
     85 		{
     86 			++start;
     87 			++ret;
     88 		}
     89 	}
     90 	return ret;
     91 }
     92 
     93 // returns the size in characters of terminal fd in w and h.
     94 // returns true on error.
     95 bool term_ch_size( uint16_t *w, uint16_t *h, int fd );
     96 
     97 // print [txt,end) on target, indenting it level times.
     98 // When a line is wider than max_width, try to break at last isblank(3).
     99 // returns true on error.
    100 // note:
    101 bool indent_txt( char const* txt, char const* end, uint8_t level, uint16_t max_width, uint8_t tab_width, FILE* target );
    102 
    103 #endif