Cupt
|
00001 /************************************************************************** 00002 * Copyright (C) 2011-2012 by Eugene V. Lyubimkin * 00003 * * 00004 * This program is free software; you can redistribute it and/or modify * 00005 * it under the terms of the GNU General Public License * 00006 * (version 3 or above) as published by the Free Software Foundation. * 00007 * * 00008 * This program is distributed in the hope that it will be useful, * 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00011 * GNU General Public License for more details. * 00012 * * 00013 * You should have received a copy of the GNU GPL * 00014 * along with this program; if not, write to the * 00015 * Free Software Foundation, Inc., * 00016 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 00017 **************************************************************************/ 00018 00019 // only for internal inclusion 00021 00022 #include <cstdio> 00023 #include <cstring> 00024 00025 #include <string> 00026 00027 namespace cupt { 00028 00029 using std::string; 00030 00031 namespace internal { 00032 namespace format2impl { 00033 00034 template < typename... All > 00035 struct Tuple; 00036 00037 template < typename Head, typename... Tail > 00038 struct Tuple< Head, Tail... > 00039 { 00040 const Head& head; 00041 Tuple< Tail... > tail; 00042 00043 Tuple< Head, Tail...>(const Head& head_, const Tail&... tail_) 00044 : head(head_), tail(tail_...) 00045 {} 00046 }; 00047 00048 template <> 00049 struct Tuple<> 00050 {}; 00051 00052 template < typename... Args > 00053 string tupleformat(Tuple<>, Args... args) 00054 { 00055 char formattedBuffer[4096]; 00056 00057 auto bytesWritten = snprintf(formattedBuffer, sizeof(formattedBuffer), args...); 00058 00059 if ((size_t)bytesWritten < sizeof(formattedBuffer)) 00060 { 00061 return string(formattedBuffer); 00062 } 00063 else 00064 { 00065 // we need a bigger buffer, allocate it dynamically 00066 auto size = bytesWritten+1; 00067 char* dynamicBuffer = new char[size]; 00068 snprintf(dynamicBuffer, size, args...); 00069 string result(dynamicBuffer); 00070 delete [] dynamicBuffer; 00071 return result; 00072 } 00073 } 00074 00075 template< typename TupleT, typename... Args > 00076 string tupleformat(TupleT&& tuple, Args... args) 00077 { 00078 return tupleformat(tuple.tail, args..., tuple.head); 00079 } 00080 00081 template < typename... TupleTailT, typename... Args > 00082 string tupleformat(Tuple< string, TupleTailT... > tuple, Args... args) 00083 { 00084 return tupleformat(tuple.tail, args..., tuple.head.c_str()); 00085 } 00086 00087 } 00088 } 00089 00090 // now public parts 00091 00092 template < typename... Args > 00093 string format2(const char* format, const Args&... args) 00094 { 00095 return internal::format2impl::tupleformat( 00096 internal::format2impl::Tuple< const char*, Args... >(format, args...)); 00097 } 00098 00099 template < typename... Args > 00100 string format2(const string& format, const Args&... args) 00101 { 00102 return format2(format.c_str(), args...); 00103 } 00104 00105 template < typename... Args > 00106 string format2e(const char* format, const Args&... args) 00107 { 00108 char errorBuffer[255] = "?"; 00109 // error message may not go to errorBuffer, see man strerror_r (GNU version) 00110 auto errorString = strerror_r(errno, errorBuffer, sizeof(errorBuffer)); 00111 00112 return format2(format, args...) + ": " + errorString; 00113 } 00114 00115 template < typename... Args > 00116 string format2e(const string& format, const Args&... args) 00117 { 00118 return format2e(format.c_str(), args...); 00119 } 00120 00121 CUPT_API void __mwrite_line(const char*, const string&); 00122 00123 template < typename... Args > 00124 void fatal2(const string& format, const Args&... args) 00125 { 00126 auto errorString = format2(format, args...); 00127 __mwrite_line("E: ", errorString); 00128 throw Exception(errorString); 00129 } 00130 00131 template < typename... Args > 00132 void fatal2i(const char* format, const Args&... args) 00133 { 00134 fatal2((string("internal error: ") + format), args...); 00135 } 00136 00137 template < typename... Args > 00138 void fatal2e(const string& format, const Args&... args) 00139 { 00140 auto errorString = format2e(format, args...); 00141 __mwrite_line("E: ", errorString); 00142 throw Exception(errorString); 00143 } 00144 00145 template < typename... Args > 00146 void warn2(const string& format, const Args&... args) 00147 { 00148 __mwrite_line("W: ", format2(format, args...)); 00149 } 00150 00151 template < typename... Args > 00152 void warn2e(const string& format, const Args&... args) 00153 { 00154 __mwrite_line("W: ", format2e(format, args...)); 00155 } 00156 00157 template < typename... Args > 00158 void debug2(const char* format, const Args&... args) 00159 { 00160 __mwrite_line("D: ", format2(format, args...)); 00161 } 00162 00163 template < typename... Args > 00164 void simulate2(const char* format, const Args&... args) 00165 { 00166 __mwrite_line("S: ", format2(format, args...)); 00167 } 00168 00169 } 00170 00172