1 #ifndef SGPSTRINGS_H
2 #define SGPSTRINGS_H
3 
4 #include <string_theory/format>
5 #include <string_theory/string>
6 
7 #include <cwchar>
8 #include <stdexcept>
9 #include <stdio.h>
10 #include <string.h>
11 #include <utility>
12 
13 #include "PlatformStrings.h"
14 
15 
16 #if defined(__linux__) || defined(_WIN32)
17 
18 size_t strlcpy(char* dst, const char* src, size_t size);
19 
20 #endif
21 
22 
23 #ifdef _WIN32
24 #ifndef __MINGW32__
25 
26 #include <stdarg.h>
27 
28 
29 int WINsnprintf(char* s, size_t n, const char* fmt, ...);
30 
31 #define snprintf  WINsnprintf
32 
33 #endif
34 #endif
35 
36 /// Converts `std::printf` formatting to `ST::format` formatting.
37 /// @see https://en.cppreference.com/w/cpp/io/c/fprintf
38 ST::string st_fmt_printf_to_format(const ST::string& fmt_printf);
39 
40 /// Format a string with `std::printf` formatting.
41 template <typename ... T>
st_format_printf(ST::utf_validation_t validation,const ST::string & fmt_printf,T &&...args)42 inline ST::string st_format_printf(ST::utf_validation_t validation, const ST::string& fmt_printf, T&& ... args)
43 {
44 	ST::string fmt = st_fmt_printf_to_format(fmt_printf);
45 	return ST::format(validation, fmt.c_str(), std::forward<T>(args) ...);
46 }
47 
48 /// Format a string with `std::printf` formatting.
49 template <typename ... T>
st_format_printf(const ST::string & fmt_printf,T &&...args)50 inline ST::string st_format_printf(const ST::string& fmt_printf, T&& ... args)
51 {
52 	return st_format_printf(ST_DEFAULT_VALIDATION, fmt_printf, std::forward<T>(args) ...);
53 }
54 
55 ST::string st_buffer_escape(const ST::char_buffer& buf);
56 ST::string st_buffer_escape(const ST::utf16_buffer& buf);
57 ST::string st_buffer_escape(const ST::utf32_buffer& buf);
58 
59 /// Converts a buffer to a string.
60 template<typename T>
st_checked_buffer_to_string(ST::string & err_msg,const ST::buffer<T> & buf)61 ST::string st_checked_buffer_to_string(ST::string& err_msg, const ST::buffer<T>& buf) noexcept
62 {
63 	err_msg = ST::null;
64 	try
65 	{
66 		return buf.c_str();
67 	}
68 	catch (const std::runtime_error& ex)
69 	{
70 		ST::string str = ST::string(buf.c_str(), ST_AUTO_SIZE, ST::substitute_invalid);
71 		err_msg = ST::format(ST::substitute_invalid, "{}: \"{}\" -> '{}'", ex.what(), st_buffer_escape(buf), str);
72 		return str;
73 	}
74 }
75 
76 #endif
77