Cupt
format2.hpp
1 /**************************************************************************
2 * Copyright (C) 2011-2012 by Eugene V. Lyubimkin *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License *
6 * (version 3 or above) as published by the Free Software Foundation. *
7 * *
8 * This program is distributed in the hope that it will be useful, *
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11 * GNU General Public License for more details. *
12 * *
13 * You should have received a copy of the GNU GPL *
14 * along with this program; if not, write to the *
15 * Free Software Foundation, Inc., *
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA *
17 **************************************************************************/
18 
19 // only for internal inclusion
21 
22 #include <cstdio>
23 #include <cstring>
24 
25 #include <string>
26 
27 namespace cupt {
28 
29 using std::string;
30 
31 namespace internal {
32 namespace format2impl {
33 
34 template < typename... All >
35 struct Tuple;
36 
37 template < typename Head, typename... Tail >
38 struct Tuple< Head, Tail... >
39 {
40  const Head& head;
41  Tuple< Tail... > tail;
42 
43  Tuple< Head, Tail...>(const Head& head_, const Tail&... tail_)
44  : head(head_), tail(tail_...)
45  {}
46 };
47 
48 template <>
49 struct Tuple<>
50 {};
51 
52 template < typename... Args >
53 string tupleformat(Tuple<>, Args... args)
54 {
55  char formattedBuffer[4096];
56 
57  auto bytesWritten = snprintf(formattedBuffer, sizeof(formattedBuffer), args...);
58 
59  if ((size_t)bytesWritten < sizeof(formattedBuffer))
60  {
61  return string(formattedBuffer);
62  }
63  else
64  {
65  // we need a bigger buffer, allocate it dynamically
66  auto size = bytesWritten+1;
67  char* dynamicBuffer = new char[size];
68  snprintf(dynamicBuffer, size, args...);
69  string result(dynamicBuffer);
70  delete [] dynamicBuffer;
71  return result;
72  }
73 }
74 
75 template< typename TupleT, typename... Args >
76 string tupleformat(TupleT&& tuple, Args... args)
77 {
78  return tupleformat(tuple.tail, args..., tuple.head);
79 }
80 
81 template < typename... TupleTailT, typename... Args >
82 string tupleformat(Tuple< string, TupleTailT... > tuple, Args... args)
83 {
84  return tupleformat(tuple.tail, args..., tuple.head.c_str());
85 }
86 
87 }
88 }
89 
90 // now public parts
91 
92 template < typename... Args >
93 string format2(const char* format, const Args&... args)
94 {
95  return internal::format2impl::tupleformat(
96  internal::format2impl::Tuple< const char*, Args... >(format, args...));
97 }
98 
99 template < typename... Args >
100 string format2(const string& format, const Args&... args)
101 {
102  return format2(format.c_str(), args...);
103 }
104 
105 template < typename... Args >
106 string format2e(const char* format, const Args&... args)
107 {
108  char errorBuffer[255] = "?";
109  // error message may not go to errorBuffer, see man strerror_r (GNU version)
110  auto errorString = strerror_r(errno, errorBuffer, sizeof(errorBuffer));
111 
112  return format2(format, args...) + ": " + errorString;
113 }
114 
115 template < typename... Args >
116 string format2e(const string& format, const Args&... args)
117 {
118  return format2e(format.c_str(), args...);
119 }
120 
121 CUPT_API void __mwrite_line(const char*, const string&);
122 
123 template < typename... Args >
124 __attribute ((noreturn)) void fatal2(const string& format, const Args&... args)
125 {
126  auto errorString = format2(format, args...);
127  __mwrite_line("E: ", errorString);
128  throw Exception(errorString);
129 }
130 
131 template < typename... Args >
132 void fatal2i(const char* format, const Args&... args)
133 {
134  fatal2((string("internal error: ") + format), args...);
135 }
136 
137 template < typename... Args >
138 void fatal2e(const string& format, const Args&... args)
139 {
140  auto errorString = format2e(format, args...);
141  __mwrite_line("E: ", errorString);
142  throw Exception(errorString);
143 }
144 
145 template < typename... Args >
146 void warn2(const string& format, const Args&... args)
147 {
148  __mwrite_line("W: ", format2(format, args...));
149 }
150 
151 template < typename... Args >
152 void warn2e(const string& format, const Args&... args)
153 {
154  __mwrite_line("W: ", format2e(format, args...));
155 }
156 
157 template < typename... Args >
158 void debug2(const char* format, const Args&... args)
159 {
160  __mwrite_line("D: ", format2(format, args...));
161 }
162 
163 template < typename... Args >
164 void simulate2(const char* format, const Args&... args)
165 {
166  __mwrite_line("S: ", format2(format, args...));
167 }
168 
169 }
170 
172 
Definition: binarypackage.hpp:26