diff --git a/src/utils/log.h b/src/utils/log.h index cc0cacc4..7460623c 100644 --- a/src/utils/log.h +++ b/src/utils/log.h @@ -1,35 +1,18 @@ -/* Copyright (C) 2014 J.F.Dockes - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. +/* Copyright (C) 2014-2019 J.F.Dockes + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* Copyright (C) 2006-2016 J.F.Dockes - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _LOG_H_X_INCLUDED_ #define _LOG_H_X_INCLUDED_ @@ -57,7 +40,7 @@ class Logger { public: /** Initialize logging to file name. Use "stderr" for stderr - output. Creates the singleton logger object */ + output. Creates the singleton logger object */ static Logger *getTheLog(const std::string& fn); bool reopen(const std::string& fn); @@ -97,7 +80,7 @@ private: #define LOGGER_PRT (Logger::getTheLog("")->getstream()) #if LOGGER_THREADSAFE -#define LOGGER_LOCK \ +#define LOGGER_LOCK \ std::unique_lock lock(Logger::getTheLog("")->getmutex()) #else #define LOGGER_LOCK @@ -107,63 +90,63 @@ private: #define LOGGER_LOCAL_LOGINC 0 #endif -#define LOGGER_LEVEL (Logger::getTheLog("")->getloglevel() + \ +#define LOGGER_LEVEL (Logger::getTheLog("")->getloglevel() + \ LOGGER_LOCAL_LOGINC) -#define LOGGER_DOLOG(L,X) LOGGER_PRT << ":" << L << ":" << \ - __FILE__ << ":" << __LINE__ << "::" << X \ +#define LOGGER_DOLOG(L,X) LOGGER_PRT << ":" << L << ":" << \ + __FILE__ << ":" << __LINE__ << "::" << X \ << std::flush #if LOGGER_STATICVERBOSITY >= 7 -#define LOGDEB2(X) { \ - if (LOGGER_LEVEL >= Logger::LLDEB2) { \ - LOGGER_LOCK; \ - LOGGER_DOLOG(Logger::LLDEB2, X); \ - } \ +#define LOGDEB2(X) { \ + if (LOGGER_LEVEL >= Logger::LLDEB2) { \ + LOGGER_LOCK; \ + LOGGER_DOLOG(Logger::LLDEB2, X); \ + } \ } #else #define LOGDEB2(X) #endif #if LOGGER_STATICVERBOSITY >= 6 -#define LOGDEB1(X) { \ - if (LOGGER_LEVEL >= Logger::LLDEB1) { \ - LOGGER_LOCK; \ - LOGGER_DOLOG(Logger::LLDEB1, X); \ - } \ +#define LOGDEB1(X) { \ + if (LOGGER_LEVEL >= Logger::LLDEB1) { \ + LOGGER_LOCK; \ + LOGGER_DOLOG(Logger::LLDEB1, X); \ + } \ } #else #define LOGDEB1(X) #endif #if LOGGER_STATICVERBOSITY >= 5 -#define LOGDEB0(X) { \ - if (LOGGER_LEVEL >= Logger::LLDEB0) { \ - LOGGER_LOCK; \ - LOGGER_DOLOG(Logger::LLDEB0, X); \ - } \ +#define LOGDEB0(X) { \ + if (LOGGER_LEVEL >= Logger::LLDEB0) { \ + LOGGER_LOCK; \ + LOGGER_DOLOG(Logger::LLDEB0, X); \ + } \ } #else #define LOGDEB0(X) #endif #if LOGGER_STATICVERBOSITY >= 4 -#define LOGDEB(X) { \ - if (LOGGER_LEVEL >= Logger::LLDEB) { \ - LOGGER_LOCK; \ - LOGGER_DOLOG(Logger::LLDEB, X); \ - } \ +#define LOGDEB(X) { \ + if (LOGGER_LEVEL >= Logger::LLDEB) { \ + LOGGER_LOCK; \ + LOGGER_DOLOG(Logger::LLDEB, X); \ + } \ } #else #define LOGDEB(X) #endif #if LOGGER_STATICVERBOSITY >= 3 -#define LOGINF(X) { \ - if (LOGGER_LEVEL >= Logger::LLINF) { \ - LOGGER_LOCK; \ - LOGGER_DOLOG(Logger::LLINF, X); \ - } \ +#define LOGINF(X) { \ + if (LOGGER_LEVEL >= Logger::LLINF) { \ + LOGGER_LOCK; \ + LOGGER_DOLOG(Logger::LLINF, X); \ + } \ } #else #define LOGINF(X) @@ -171,22 +154,22 @@ private: #define LOGINFO LOGINF #if LOGGER_STATICVERBOSITY >= 2 -#define LOGERR(X) { \ - if (LOGGER_LEVEL >= Logger::LLERR) { \ - LOGGER_LOCK; \ - LOGGER_DOLOG(Logger::LLERR, X); \ - } \ +#define LOGERR(X) { \ + if (LOGGER_LEVEL >= Logger::LLERR) { \ + LOGGER_LOCK; \ + LOGGER_DOLOG(Logger::LLERR, X); \ + } \ } #else #define LOGERR(X) #endif #if LOGGER_STATICVERBOSITY >= 1 -#define LOGFAT(X) { \ - if (LOGGER_LEVEL >= Logger::LLFAT) { \ - LOGGER_LOCK; \ - LOGGER_DOLOG(Logger::LLFAT, X); \ - } \ +#define LOGFAT(X) { \ + if (LOGGER_LEVEL >= Logger::LLFAT) { \ + LOGGER_LOCK; \ + LOGGER_DOLOG(Logger::LLFAT, X); \ + } \ } #else #define LOGFAT(X) @@ -198,20 +181,18 @@ private: LOGERR(who << ": " << what << "(" << arg << "): errno " << errno << \ ": " << strerror(errno) << std::endl); \ } -#else // !WINDOWS-> -#if (_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE -#define LOGSYSERR(who, what, arg) { \ - char buf[200]; buf[0] = 0; strerror_r(errno, buf, 200); \ - LOGERR(who << ": " << what << "(" << arg << "): errno " << errno << \ - ": " << buf << std::endl); \ - } -#else +#else // not WINDOWS or sun + +inline char *_log_check_strerror_r(int, char *errbuf) {return errbuf;} +inline char *_log_check_strerror_r(char *cp, char *){return cp;} + #define LOGSYSERR(who, what, arg) { \ char buf[200]; buf[0] = 0; \ LOGERR(who << ": " << what << "(" << arg << "): errno " << errno << \ - ": " << strerror_r(errno, buf, 200) << std::endl); \ + ": " << _log_check_strerror_r( \ + strerror_r(errno, buf, 200), buf) << std::endl); \ } -#endif + #endif // not windows #endif /* _LOG_H_X_INCLUDED_ */ diff --git a/src/utils/smallut.cpp b/src/utils/smallut.cpp index 3a1905fb..a4cf0bed 100644 --- a/src/utils/smallut.cpp +++ b/src/utils/smallut.cpp @@ -115,7 +115,7 @@ string stringtoupper(const string& i) extern int stringisuffcmp(const string& s1, const string& s2) { string::const_reverse_iterator r1 = s1.rbegin(), re1 = s1.rend(), - r2 = s2.rbegin(), re2 = s2.rend(); + r2 = s2.rbegin(), re2 = s2.rend(); while (r1 != re1 && r2 != re2) { char c1 = ::toupper(*r1); char c2 = ::toupper(*r2); @@ -326,18 +326,18 @@ template bool stringToStrings(const string& s, T& tokens, } template bool stringToStrings >(const string&, - list&, const string&); + list&, const string&); template bool stringToStrings >(const string&, - vector&, const string&); + vector&, const string&); template bool stringToStrings >(const string&, - set&, const string&); + set&, const string&); template bool stringToStrings > (const string&, std::unordered_set&, const string&); template void stringsToString(const T& tokens, string& s) { for (typename T::const_iterator it = tokens.begin(); - it != tokens.end(); it++) { + it != tokens.end(); it++) { bool hasblanks = false; if (it->find_first_of(" \t\n") != string::npos) { hasblanks = true; @@ -382,10 +382,10 @@ template void stringsToCSV(const T& tokens, string& s, { s.erase(); for (typename T::const_iterator it = tokens.begin(); - it != tokens.end(); it++) { + it != tokens.end(); it++) { bool needquotes = false; if (it->empty() || - it->find_first_of(string(1, sep) + "\"\n") != string::npos) { + it->find_first_of(string(1, sep) + "\"\n") != string::npos) { needquotes = true; } if (it != tokens.begin()) { @@ -409,7 +409,7 @@ template void stringsToCSV(const T& tokens, string& s, } template void stringsToCSV >(const list&, string&, char); template void stringsToCSV >(const vector&, string&, - char); + char); void stringToTokens(const string& str, vector& tokens, const string& delims, bool skipinit) @@ -418,7 +418,7 @@ void stringToTokens(const string& str, vector& tokens, // Skip initial delims, return empty if this eats all. if (skipinit && - (startPos = str.find_first_not_of(delims, 0)) == string::npos) { + (startPos = str.find_first_not_of(delims, 0)) == string::npos) { return; } while (startPos < str.size()) { @@ -569,13 +569,13 @@ string escapeHtml(const string& in) { string out; for (string::size_type pos = 0; pos < in.length(); pos++) { - switch(in.at(pos)) { - case '<': out += "<"; break; - case '>': out += ">"; break; - case '&': out += "&"; break; - case '"': out += """; break; - default: out += in.at(pos); break; - } + switch(in.at(pos)) { + case '<': out += "<"; break; + case '>': out += ">"; break; + case '&': out += "&"; break; + case '"': out += """; break; + default: out += in.at(pos); break; + } } return out; } @@ -850,7 +850,7 @@ static bool parsedate(vector::const_iterator& it, { dip->y1 = dip->m1 = dip->d1 = dip->y2 = dip->m2 = dip->d2 = 0; if (it->length() > 4 || !it->length() || - it->find_first_not_of("0123456789") != string::npos) { + it->find_first_not_of("0123456789") != string::npos) { return false; } if (it == end || sscanf(it++->c_str(), "%d", &dip->y1) != 1) { @@ -864,7 +864,7 @@ static bool parsedate(vector::const_iterator& it, } if (it->length() > 2 || !it->length() || - it->find_first_not_of("0123456789") != string::npos) { + it->find_first_not_of("0123456789") != string::npos) { return false; } if (it == end || sscanf(it++->c_str(), "%d", &dip->m1) != 1) { @@ -878,7 +878,7 @@ static bool parsedate(vector::const_iterator& it, } if (it->length() > 2 || !it->length() || - it->find_first_not_of("0123456789") != string::npos) { + it->find_first_not_of("0123456789") != string::npos) { return false; } if (it == end || sscanf(it++->c_str(), "%d", &dip->d1) != 1) { @@ -1001,7 +1001,7 @@ static bool addperiod(DateInterval *dp, DateInterval *pp) int monthdays(int mon, int year) { switch (mon) { - // We are returning a few too many 29 days februaries, no problem + // We are returning a few too many 29 days februaries, no problem case 2: return (year % 4) == 0 ? 29 : 28; case 1: @@ -1023,7 +1023,7 @@ bool parsedateinterval(const string& s, DateInterval *dip) DateInterval p1, p2, d1, d2; p1 = p2 = d1 = d2 = *dip; bool hasp1 = false, hasp2 = false, hasd1 = false, hasd2 = false, - hasslash = false; + hasslash = false; if (!stringToStrings(s, vs, "PYMDpymd-/")) { return false; @@ -1164,6 +1164,16 @@ secondelt: return true; } +// We'd like these static, but then, as only one is used, this +// triggers a 'defined but not used' warning. +char *_check_strerror_r(int, char *errbuf) +{ + return errbuf; +} +char *_check_strerror_r(char *cp, char *) +{ + return cp; +} void catstrerror(string *reason, const char *what, int _errno) { @@ -1186,8 +1196,6 @@ void catstrerror(string *reason, const char *what, int _errno) // Note: sun strerror is noted mt-safe ?? reason->append(strerror(_errno)); #else -#define ERRBUFSZ 200 - char errbuf[ERRBUFSZ]; // There are 2 versions of strerror_r. // - The GNU one returns a pointer to the message (maybe // static storage or supplied buffer). @@ -1198,13 +1206,15 @@ void catstrerror(string *reason, const char *what, int _errno) // were returned a pointer... // Also couldn't find an easy way to disable the gnu version without // changing the cxxflags globally, so forget it. Recent gnu lib versions - // normally default to the posix version. - // At worse we get no message at all here. + // normally default to the posix version. (not !) + // The feature defines tests are too complicated and seem unreliable. + // In short it's a mess, but thanks to c++ function overloading and smart + // people, we have a solution: + // https://www.zverovich.net/2015/03/13/reliable-detection-of-strerror-variants.html + char errbuf[200]; errbuf[0] = 0; - // We don't use ret, it's there to silence a cc warning - auto ret = strerror_r(_errno, errbuf, ERRBUFSZ); - (void)ret; - reason->append(errbuf); + reason->append(_check_strerror_r( + strerror_r(_errno, errbuf, sizeof(errbuf)), errbuf)); #endif } @@ -1232,7 +1242,7 @@ static std::unordered_map lang_to_code { {"th", "iso-8859-11"}, {"tr", "iso-8859-9"}, {"uk", "koi8-u"}, -}; + }; static const string cstr_cp1252("CP1252"); string langtocode(const string& lang) @@ -1252,7 +1262,7 @@ string localelang() const char *lang = getenv("LANG"); if (lang == 0 || *lang == 0 || !strcmp(lang, "C") || - !strcmp(lang, "POSIX")) { + !strcmp(lang, "POSIX")) { return "en"; } string locale(lang);