commit 63966f207ec9bd8c5b55845e94da9df2750dd653
parent 97f3cef9ce0a984aa3d724c5650ec37b50b56018
Author: Morel BĂ©renger <berengermorel76@gmail.com>
Date: Wed, 12 Aug 2020 20:41:16 +0200
add esc_fputs function
Diffstat:
2 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/btl/src/utils.cpp b/btl/src/utils.cpp
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <iterator>
+#include <algorithm>
+#include "utils.hpp"
+
+//would probably be better without that many ifs
+int esc_fputs( const char *s, FILE *stream )
+{
+ assert( s && stream && "nullpointer provided to esc_fputs" );
+ if( !( s && stream ) )
+ {
+ errno = EINVAL;
+ return EOF;
+ }
+
+ const char *str_end = s + strlen( s );
+ const char *chunk_start = s;
+ const char *chunk_end;
+ char bslash[2] = { '\\', '\\' };
+ char tohex [4] = { '\\', 'x', 0, 0 };
+ char ch;
+ char const* buf;
+ size_t sz;
+
+ do
+ {
+ chunk_end = std::find_if( chunk_start, str_end, []( const char c ){ return c < 0x20 || c == '\\'; } );
+ assert( chunk_end - chunk_start >= 0 );
+ if( !fwrite( chunk_start, static_cast<size_t>( chunk_end - chunk_start ), 1, stream ) )
+ {
+ return INT_MAX;
+ }
+ if( chunk_end != str_end )
+ {
+ ch = *chunk_end;
+ buf = bslash;
+ sz = sizeof( bslash );
+ if( ch != '\\' )
+ {
+ buf = tohex;
+ sz = sizeof( tohex );
+ //quick'n dirty ascii to hex convertion for values < 0x20 (space)
+ tohex[2] = '0' + ( ch >> 4 );
+ ch &= 0x0F;
+ tohex[3] = ch + '0' + ( ch > 9 ? 'A' - ( '9' + 1 ) : 0 );
+ }
+ if( !fwrite( buf, sz, 1, stream ) )
+ {
+ return INT_MAX;
+ }
+ }
+ chunk_start = chunk_end;
+ } while( chunk_start != str_end );
+ return 0;
+}
diff --git a/btl/src/utils.hpp b/btl/src/utils.hpp
@@ -41,4 +41,8 @@ inline bool empty_array( T* arr )
return arr && *arr == INVALID;
}
+//like fputs, but when character is blank, prints the C escape instead
+//returns 0 on success, INT_MAX on error
+int esc_fputs( const char *s, FILE *stream );
+
#endif