Commit 2f406974 authored by Jean-Francois Dockes's avatar Jean-Francois Dockes
Browse files

shared

parent b65773ca
......@@ -107,7 +107,7 @@ protected:
*/
virtual void endElement(const std::string& /* nm */) {}
/** Expatmm compat */
virtual void EndElement(const XML_Char */* nm */) {}
virtual void EndElement(const XML_Char * /* nm */) {}
/**
* Non-tag data handler.
......@@ -186,7 +186,18 @@ private:
for (;;) {
// Current char is '<' and the next char is not '?'
//std::cerr<< "m_pos "<< m_pos<<" char "<< m_in[m_pos] << std::endl;
//std::cerr<< "m_pos "<< m_pos<<" char "<< m_in[m_pos]<<std::endl;
// skipComment also processes
if (!skipComment()) {
return false;
}
if (nomore()) {
if (!m_tagstack.empty()) {
m_reason << "EOF hit inside open element";
return false;
}
return true;
}
m_pos++;
if (nomore()) {
m_reason << "EOF within tag";
......@@ -227,24 +238,29 @@ private:
_startelem(tag, attrs, emptyel);
}
spos = m_pos;
m_pos = m_in.find("<", m_pos);
if (nomore()) {
if (!m_tagstack.empty()) {
m_reason << "EOF hit inside open element";
return false;
}
return true;
}
if (m_pos != spos) {
std::string data{unQuote(m_in.substr(spos, m_pos - spos))};
characterData(data);
CharacterData(data.c_str(), data.size());
if (!_chardata()) {
return false;
}
}
return false;
}
bool nomore() const {
return m_pos == std::string::npos || m_pos == m_in.size();
bool _chardata() {
std::string::size_type spos = m_pos;
m_pos = m_in.find("<", m_pos);
if (nomore()) {
return true;
}
if (m_pos != spos) {
std::string data{unQuote(m_in.substr(spos, m_pos - spos))};
characterData(data);
CharacterData(data.c_str(), data.size());
}
return true;
}
bool nomore(int sz = 0) const {
return m_pos == std::string::npos || m_pos >= m_in.size() - sz;
}
bool skipWS(const std::string& in, std::string::size_type& pos) {
if (pos == std::string::npos)
......@@ -260,10 +276,10 @@ private:
m_pos += str.size();
return m_pos != std::string::npos;
}
int peek() const {
if (nomore())
int peek(int sz = 0) const {
if (nomore(sz))
return -1;
return m_in[m_pos + 1];
return m_in[m_pos + 1 + sz];
}
void trimtag(std::string& tagname) {
std::string::size_type trimpos = tagname.find_last_not_of(" \t\n\r");
......@@ -294,6 +310,27 @@ private:
}
return true;
}
bool skipComment() {
if (nomore()) {
return true;
}
if (m_in[m_pos] != '<') {
m_reason << "Internal error: skipComment called with wrong "
"start: m_pos " <<
m_pos << " char [" << m_in[m_pos] << "]\n";
return false;
}
if (peek() == '!' && peek(1) == '-' && peek(2) == '-') {
if (!skipStr("-->")) {
m_reason << "EOF while looking for end of XML comment";
return false;
}
// Process possible characters until next tag
return _chardata();
}
return true;
}
bool parseattrs(std::string& tag,
std::map<std::string, std::string>& attrs) {
......@@ -327,14 +364,17 @@ private:
}
epos++;
skipWS(tag, epos);
if (tag[epos] != '"' || epos == tag.size() - 1) {
m_reason << "Missing dquote or value at cpos " << m_pos+epos;
char qc{0};
if ((tag[epos] != '"' && tag[epos] != '\'') ||
epos == tag.size() - 1) {
m_reason << "Missing quote or value at cpos " << m_pos+epos;
return false;
}
qc = tag[epos];
spos = epos + 1;
epos = tag.find_first_of(R"(")", spos);
epos = tag.find_first_of(qc, spos);
if (epos == std::string::npos) {
m_reason << "Missing closing dquote at cpos " << m_pos+spos;
m_reason << "Missing closing quote at cpos " << m_pos+spos;
return false;
}
attrs[attrnm] = tag.substr(spos, epos - spos);
......@@ -370,7 +410,7 @@ private:
continue;
}
if (it == s.end()) {
// ??
// Unexpected
break;
}
it++;
......@@ -380,7 +420,7 @@ private:
it++;
}
if (it == s.end()) {
// ??
// Unexpected
break;
}
it++;
......
= Upmpdcli release notes
== 2020-07-20 libnpupnp 4.0.10
- Source cleanup
- Be more tolerant of incorrect UTF-8 data
== 2020-07-04 upplay 1.4.5
- Add prefs to control lower upnp lib logging.
......@@ -12,7 +17,7 @@
actually accessing the library object.
- Use the NetIF interface from libnpupnp instead of duplicating the module.
== 2020-07-04 libnpupnp 4.1.0
== 2020-07-04 libnpupnp 4.0.8
- Improved processing of device errors, better error data returned.
- Optional (configure time) code to fix bad utf-8 in data returned from
......
......@@ -26,11 +26,11 @@
#include "chrono.h"
#include <fcntl.h>
#include <microhttpd.h>
#include <microhttpd.h>
#if MHD_VERSION < 0x00097002
typedef int MHD_Result;
#if MHD_VERSION < 0x00097000
#define MHD_Result int
#endif
#include <mutex>
......
......@@ -756,11 +756,7 @@ string path_absolute(const string& is)
path_slashize(s);
#endif
if (!path_isabsolute(s)) {
char buf[MAXPATHLEN];
if (!getcwd(buf, MAXPATHLEN)) {
return string();
}
s = path_cat(string(buf), s);
s = path_cat(path_cwd(), s);
#ifdef _WIN32
path_slashize(s);
#endif
......@@ -783,16 +779,11 @@ string path_canon(const string& is, const string* cwd)
#endif
if (!path_isabsolute(s)) {
char buf[MAXPATHLEN];
const char *cwdp = buf;
if (cwd) {
cwdp = cwd->c_str();
s = path_cat(*cwd, s);
} else {
if (!getcwd(buf, MAXPATHLEN)) {
return string();
}
s = path_cat(path_cwd(), s);
}
s = path_cat(string(cwdp), s);
}
vector<string> elems;
stringToTokens(s, elems, "/");
......@@ -871,6 +862,27 @@ bool path_chdir(const std::string& path)
return CHDIR(syspath) == 0;
}
std::string path_cwd()
{
#ifdef _WIN32
wchar_t *wd = _wgetcwd(nullptr, 0);
if (nullptr == wd) {
return std::string();
}
string sdname;
wchartoutf8(wd, sdname);
free(wd);
path_slashize(sdname);
return sdname;
#else
char wd[MAXPATHLEN+1];
if (nullptr == getcwd(wd, MAXPATHLEN+1)) {
return string();
}
return wd;
#endif
}
bool path_unlink(const std::string& path)
{
SYSPATH(path, syspath);
......
......@@ -135,6 +135,7 @@ extern bool path_makepath(const std::string& path, int mode);
///
extern bool path_chdir(const std::string& path);
extern std::string path_cwd();
extern bool path_unlink(const std::string& path);
/* Open file, trying to do the right thing with non-ASCII paths on
......
......@@ -15,9 +15,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cinttypes>
#ifdef _WIN32
// needed for localtime_r under mingw?
......@@ -27,11 +28,11 @@
#endif /* _MSC_VER */
#endif /* _WIN32 */
#include <time.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <math.h>
#include <ctime>
#include <cctype>
#include <cerrno>
#include <cstring>
#include <cmath>
// Older compilers don't support stdc++ regex, but Windows does not
// have the Linux one. Have a simple class to solve the simple cases.
......@@ -46,6 +47,7 @@
#include <string>
#include <iostream>
#include <list>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
......@@ -71,18 +73,18 @@ int stringicmp(const string& s1, const string& s2)
++it2;
}
return size1 == size2 ? 0 : -1;
} else {
while (it2 != s2.end()) {
c1 = ::toupper(*it1);
c2 = ::toupper(*it2);
if (c1 != c2) {
return c1 > c2 ? 1 : -1;
}
++it1;
++it2;
}
while (it2 != s2.end()) {
c1 = ::toupper(*it1);
c2 = ::toupper(*it2);
if (c1 != c2) {
return c1 > c2 ? 1 : -1;
}
return size1 == size2 ? 0 : 1;
++it1;
++it2;
}
return size1 == size2 ? 0 : 1;
}
void stringtolower(string& io)
{
......@@ -150,17 +152,17 @@ int stringlowercmp(const string& s1, const string& s2)
++it2;
}
return size1 == size2 ? 0 : -1;
} else {
while (it2 != s2.end()) {
c2 = ::tolower(*it2);
if (*it1 != c2) {
return *it1 > c2 ? 1 : -1;
}
++it1;
++it2;
}
while (it2 != s2.end()) {
c2 = ::tolower(*it2);
if (*it1 != c2) {
return *it1 > c2 ? 1 : -1;
}
return size1 == size2 ? 0 : 1;
++it1;
++it2;
}
return size1 == size2 ? 0 : 1;
}
// s1 is already uppercase
......@@ -181,42 +183,29 @@ int stringuppercmp(const string& s1, const string& s2)
++it2;
}
return size1 == size2 ? 0 : -1;
} else {
while (it2 != s2.end()) {
c2 = ::toupper(*it2);
if (*it1 != c2) {
return *it1 > c2 ? 1 : -1;
}
++it1;
++it2;
}
while (it2 != s2.end()) {
c2 = ::toupper(*it2);
if (*it1 != c2) {
return *it1 > c2 ? 1 : -1;
}
return size1 == size2 ? 0 : 1;
++it1;
++it2;
}
return size1 == size2 ? 0 : 1;
}
bool beginswith(const std::string& big, const std::string& small)
{
if (big.compare(0, small.size(), small)) {
return false;
}
return true;
return big.compare(0, small.size(), small) == 0;
}
// Compare charset names, removing the more common spelling variations
bool samecharset(const string& cs1, const string& cs2)
{
string mcs1, mcs2;
// Remove all - and _, turn to lowecase
for (unsigned int i = 0; i < cs1.length(); i++) {
if (cs1[i] != '_' && cs1[i] != '-') {
mcs1 += ::tolower(cs1[i]);
}
}
for (unsigned int i = 0; i < cs2.length(); i++) {
if (cs2[i] != '_' && cs2[i] != '-') {
mcs2 += ::tolower(cs2[i]);
}
}
auto mcs1 = std::accumulate(cs1.begin(), cs1.end(), "", [](const char* m, char i) { return (i != '_' && i != '-') ? m + ::tolower(i) : m; });
auto mcs2 = std::accumulate(cs2.begin(), cs2.end(), "", [](const char* m, char i) { return (i != '_' && i != '-') ? m + ::tolower(i) : m; });
return mcs1 == mcs2;
}
......@@ -227,8 +216,8 @@ template <class T> bool stringToStrings(const string& s, T& tokens,
tokens.clear();
enum states {SPACE, TOKEN, INQUOTE, ESCAPE};
states state = SPACE;
for (unsigned int i = 0; i < s.length(); i++) {
switch (s[i]) {
for (char i : s) {
switch (i) {
case '"':
switch (state) {
case SPACE:
......@@ -279,13 +268,13 @@ template <class T> bool stringToStrings(const string& s, T& tokens,
continue;
case INQUOTE:
case ESCAPE:
current += s[i];
current += i;
continue;
}
break;
default:
if (!addseps.empty() && addseps.find(s[i]) != string::npos) {
if (!addseps.empty() && addseps.find(i) != string::npos) {
switch (state) {
case ESCAPE:
state = INQUOTE;
......@@ -293,12 +282,12 @@ template <class T> bool stringToStrings(const string& s, T& tokens,
case INQUOTE:
break;
case SPACE:
tokens.insert(tokens.end(), string(1, s[i]));
tokens.insert(tokens.end(), string(1, i));
continue;
case TOKEN:
tokens.insert(tokens.end(), current);
current.erase();
tokens.insert(tokens.end(), string(1, s[i]));
tokens.insert(tokens.end(), string(1, i));
state = SPACE;
continue;
}
......@@ -313,7 +302,7 @@ template <class T> bool stringToStrings(const string& s, T& tokens,
case INQUOTE:
break;
}
current += s[i];
current += i;
}
}
switch (state) {
......@@ -340,7 +329,7 @@ template bool stringToStrings<std::unordered_set<string> >
template <class T> void stringsToString(const T& tokens, string& s)
{
for (typename T::const_iterator it = tokens.begin();
for (auto it = tokens.begin();
it != tokens.end(); it++) {
bool hasblanks = false;
if (it->find_first_of(" \t\n") != string::npos) {
......@@ -385,7 +374,7 @@ template <class T> void stringsToCSV(const T& tokens, string& s,
char sep)
{
s.erase();
for (typename T::const_iterator it = tokens.begin();
for (auto it = tokens.begin();
it != tokens.end(); it++) {
bool needquotes = false;
if (it->empty() ||
......@@ -433,10 +422,11 @@ void stringToTokens(const string& str, vector<string>& tokens,
if (pos == string::npos) {
tokens.push_back(str.substr(startPos));
break;
} else if (pos == startPos) {
}
if (pos == startPos) {
// Dont' push empty tokens after first
if (tokens.empty()) {
tokens.push_back(string());
tokens.emplace_back();
}
startPos = ++pos;
} else {
......@@ -461,9 +451,10 @@ void stringSplitString(const string& str, vector<string>& tokens,
if (pos == string::npos) {
tokens.push_back(str.substr(startPos));
break;
} else if (pos == startPos) {
}
if (pos == startPos) {
// Initial or consecutive separators
tokens.push_back(string());
tokens.emplace_back();
} else {
tokens.push_back(str.substr(startPos, pos - startPos));
}
......@@ -478,12 +469,9 @@ bool stringToBool(const string& s)
}
if (isdigit(s[0])) {
int val = atoi(s.c_str());
return val ? true : false;
return val != 0;
}
if (s.find_first_of("yYtT") == 0) {
return true;
}
return false;
return s.find_first_of("yYtT") == 0;
}
void trimstring(string& s, const char *ws)
......@@ -572,13 +560,13 @@ string truncate_to_word(const string& input, string::size_type maxlen)
string escapeHtml(const string& in)
{
string out;
for (string::size_type pos = 0; pos < in.length(); pos++) {
switch(in.at(pos)) {
for (char pos : in) {
switch(pos) {
case '<': out += "&lt;"; break;
case '>': out += "&gt;"; break;
case '&': out += "&amp;"; break;
case '"': out += "&quot;"; break;
default: out += in.at(pos); break;
default: out += pos; break;
}
}
return out;
......@@ -588,8 +576,8 @@ string escapeShell(const string& in)
{
string out;
out += "\"";
for (string::size_type pos = 0; pos < in.length(); pos++) {
switch (in.at(pos)) {
for (char pos : in) {
switch (pos) {
case '$':
out += "\\$";
break;
......@@ -606,7 +594,7 @@ string escapeShell(const string& in)
out += "\\\\";
break;
default:
out += in.at(pos);
out += pos;
}
}
out += "\"";
......@@ -619,8 +607,8 @@ string makeCString(const string& in)
{
string out;
out += "\"";
for (string::size_type pos = 0; pos < in.length(); pos++) {
switch (in.at(pos)) {
for (char pos : in) {
switch (pos) {
case '"':
out += "\\\"";
break;
......@@ -634,7 +622,7 @@ string makeCString(const string& in)
out += "\\\\";
break;
default:
out += in.at(pos);
out += pos;
}
}
out += "\"";
......@@ -684,13 +672,13 @@ bool pcSubst(const string& in, string& out, const map<string, string>& subs)
out += '%';
continue;
}
string key = "";
string key;
if (in[i] == '(') {
if (++i == in.size()) {
out += string("%(");
break;
}
string::size_type j = in.find_first_of(")", i);
string::size_type j = in.find_first_of(')', i);
if (j == string::npos) {
// ??concatenate remaining part and stop
out += in.substr(i - 2);
......@@ -733,7 +721,6 @@ void ulltodecstr(uint64_t val, string& buf)
} while (val);
buf.assign(&rbuf[idx+1]);
return;
}
void lltodecstr(int64_t val, string& buf)
......@@ -760,7 +747,6 @@ void lltodecstr(int64_t val, string& buf)
rbuf[idx--] = '-';
}
buf.assign(&rbuf[idx+1]);
return;
}
string lltodecstr(int64_t val)
......@@ -809,9 +795,9 @@ string breakIntoLines(const string& in, unsigned int ll,
while (query.length() > 0) {
string ss = query.substr(0, ll);
if (ss.length() == ll) {
string::size_type pos = ss.find_last_of(" ");
string::size_type pos = ss.find_last_of(' ');
if (pos == string::npos) {
pos = query.find_first_of(" ");
pos = query.find_first_of(' ');
if (pos != string::npos) {
ss = query.substr(0, pos + 1);
} else {
......@@ -1080,7 +1066,7 @@ secondelt:
// Empty part means today IF other part is period, else means
// forever (stays at 0)
time_t now = time(0);
time_t now = time(nullptr);
struct tm *tmnow = gmtime(&now);
if ((!hasp1 && !hasd1) && hasp2) {
d1.y1 = 1900 + tmnow->tm_year;
......@@ -1161,7 +1147,7 @@ std::string hexprint(const std::string& in, char separ)
string out;
out.reserve(separ ? (3 *in.size()) : (2 * in.size()));
static const char hex[]="0123456789abcdef";
auto cp = (const unsigned char *)in.c_str();
auto cp = reinterpret_cast<const unsigned char*>(in.c_str());
for (unsigned int i = 0; i < in.size(); i++) {
out.append(1, hex[cp[i] >> 4]);
out.append(1, hex[cp[i] & 0x0f]);
...