+.config/yt-dlp.conf
[nethome.git] / src / stringf.h
1 #ifndef LIB_STRINGF_H
2 #define LIB_STRINGF_H
3
4 #include "streamfer.h"
5
6 // template<class... Args>: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security]
7
8 static inline PRINTF(2,0) string vstringf_const(size_t sizemax,const char *fmt,va_list ap) {
9   string str(sizemax+1,0);
10   const int got=vsnprintf(&str[0],str.length(),fmt,ap);
11   if (got!=ssize_t(sizemax))
12     fatal("stringf*(): expected=%zu got=%d fmt=\"%s\" str=\"%s\"",sizemax,got,fmt,str.c_str());
13   str.resize(sizemax);
14   return str;
15 }
16
17 static inline PRINTF(2,3) string stringf_const(size_t sizemax,const char *fmt,...) {
18   va_list ap;
19   va_start(ap,fmt);
20   const string str(vstringf_const(sizemax,fmt,ap));
21   va_end(ap);
22   return str;
23 }
24
25 static inline PRINTF(1,2) string stringf(const char *fmt,...) {
26   // 189: for i in activetick.data/;do find $i -name "*.xz";done|xargs xz -dc|perl -lne 'BEGIN{$m=0;}if (length($_)>$m){$m=length $_;print $m;}'
27   static const int sizetry(192-1/*+1->malloc()*/);
28   string str(sizetry,0);
29   va_list ap;
30   va_start(ap,fmt);
31   const int got(vsnprintf(&str[0],sizetry,fmt,ap));
32   va_end(ap);
33   assert(got>=0);
34   if (got>=sizetry) {
35     str.resize(got+1);
36     va_start(ap,fmt);
37     const int got2(vsnprintf(&str[0],str.length(),fmt,ap));
38     va_end(ap);
39     assert(got2==got);
40   }
41   str.resize(got);
42   return str;
43 }
44
45 #endif /* LIB_STRINGF_H */