From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Tue, 27 Dec 2022 13:34:03 +0000 (-0700) Subject: move xml tag utilities to xml_tag.cc (#960) X-Git-Tag: archive/raspbian/1.10.0+ds-2+rpi1~1^2~12^2~1^2~152 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a52b81e4ddba30bb2eed3b018b23ebb096511e6b;p=gpsbabel.git move xml tag utilities to xml_tag.cc (#960) * move xml tag utilities to xml_tag.cc they are already declared in src/core/xmltag.h * move xml_tag.cc to src/core, where it's h file is. * move global xml_tag routines into class. * make xml_next non-static. * make xml_findnext non-static. * make xml_findfirst non-static * make xml_attribute non-static * eliminate some shadowing * rename XmlTag class. * retire fs_xml_alloc. * use QStringView with XmlTag. * back off QStringView for xml_attribute for Qt 5. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a2b6fd63..caecf0c76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -189,6 +189,7 @@ set(SUPPORT src/core/usasciicodec.cc src/core/vector3d.cc src/core/xmlstreamwriter.cc + src/core/xmltag.cc strptime.c units.cc util.cc @@ -196,7 +197,6 @@ set(SUPPORT vecs.cc waypt.cc xmlgeneric.cc - xmltag.cc ) if(${QT_VERSION_MAJOR} EQUAL "6") set(SUPPORT ${SUPPORT} src/core/codecdevice.cc) diff --git a/gpx.cc b/gpx.cc index 05e64e66d..f671f42b8 100644 --- a/gpx.cc +++ b/gpx.cc @@ -218,7 +218,7 @@ GpxFormat::start_something_else(QStringView el, const QXmlStreamAttributes& attr return; } - auto* new_tag = new xml_tag; + auto* new_tag = new XmlTag; new_tag->tagname = el.toString(); const QXmlStreamNamespaceDeclarations ns = reader->namespaceDeclarations(); @@ -262,7 +262,7 @@ GpxFormat::start_something_else(QStringView el, const QXmlStreamAttributes& attr cur_tag->sibling = new_tag; new_tag->parent = nullptr; } else { - fs_xml* new_fs_gpx = fs_xml_alloc(kFsGpx); + auto* new_fs_gpx = new fs_xml(kFsGpx); new_fs_gpx->tag = new_tag; fs_ptr->FsChainAdd(new_fs_gpx); new_tag->parent = nullptr; @@ -901,7 +901,7 @@ GpxFormat::gpx_cdata(QStringView s) } if (cur_tag->child) { - xml_tag* tmp_tag = cur_tag->child; + XmlTag* tmp_tag = cur_tag->child; while (tmp_tag->sibling) { tmp_tag = tmp_tag->sibling; } @@ -1138,7 +1138,7 @@ GpxFormat::write_attributes(const QXmlStreamAttributes& attributes) const } void -GpxFormat::fprint_xml_chain(xml_tag* tag, const Waypoint* wpt) const +GpxFormat::fprint_xml_chain(XmlTag* tag, const Waypoint* wpt) const { while (tag) { writer->writeStartElement(tag->tagname); diff --git a/gpx.h b/gpx.h index cc8baa75b..98f68b0e7 100644 --- a/gpx.h +++ b/gpx.h @@ -204,7 +204,7 @@ private: void gpx_end(QStringView unused); void gpx_cdata(QStringView s); void write_attributes(const QXmlStreamAttributes& attributes) const; - void fprint_xml_chain(xml_tag* tag, const Waypoint* wpt) const; + void fprint_xml_chain(XmlTag* tag, const Waypoint* wpt) const; void write_gpx_url(const UrlList& urls) const; void write_gpx_url(const Waypoint* waypointp) const; void write_gpx_url(const route_head* rh) const; @@ -225,7 +225,7 @@ private: void gpx_write_bounds(); QXmlStreamReader* reader{}; - xml_tag* cur_tag{}; + XmlTag* cur_tag{}; QString cdatastr; char* opt_logpoint = nullptr; char* opt_humminbirdext = nullptr; diff --git a/html.cc b/html.cc index 19cebca01..17ea64553 100644 --- a/html.cc +++ b/html.cc @@ -147,25 +147,25 @@ HtmlFormat::html_disp(const Waypoint* wpt) const if (includelogs) { const auto* fs_gpx = reinterpret_cast(wpt->fs.FsChainFind(kFsGpx)); if (fs_gpx && fs_gpx->tag) { - xml_tag* root = fs_gpx->tag; - xml_tag* curlog = xml_findfirst(root, "groundspeak:log"); + XmlTag* root = fs_gpx->tag; + XmlTag* curlog = root->xml_findfirst(u"groundspeak:log"); while (curlog) { time_t logtime = 0; *file_out << "

\n"; - xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type"); + XmlTag* logpart = curlog->xml_findfirst(u"groundspeak:type"); if (logpart) { *file_out << "" << logpart->cdata << " by "; } - logpart = xml_findfirst(curlog, "groundspeak:finder"); + logpart = curlog->xml_findfirst(u"groundspeak:finder"); if (logpart) { *file_out << "" << logpart->cdata.toHtmlEscaped() << " on "; } - logpart = xml_findfirst(curlog, "groundspeak:date"); + logpart = curlog->xml_findfirst(u"groundspeak:date"); if (logpart) { logtime = xml_parse_time(logpart->cdata).toTime_t(); struct tm* logtm = localtime(&logtime); @@ -177,17 +177,17 @@ HtmlFormat::html_disp(const Waypoint* wpt) const } } - logpart = xml_findfirst(curlog, "groundspeak:log_wpt"); + logpart = curlog->xml_findfirst(u"groundspeak:log_wpt"); if (logpart) { - double lat = xml_attribute(logpart->attributes, "lat").toDouble(); - double lon = xml_attribute(logpart->attributes, "lon").toDouble(); + double lat = logpart->xml_attribute("lat").toDouble(); + double lon = logpart->xml_attribute("lon").toDouble(); *file_out << "" << pretty_deg_format(lat, lon, degformat[2], " ", true) << "
\n"; } - logpart = xml_findfirst(curlog, "groundspeak:text"); + logpart = curlog->xml_findfirst(u"groundspeak:text"); if (logpart) { - QString encstr = xml_attribute(logpart->attributes, "encoded"); + QString encstr = logpart->xml_attribute("encoded"); bool encoded = !encstr.startsWith('F', Qt::CaseInsensitive); QString s; @@ -201,7 +201,7 @@ HtmlFormat::html_disp(const Waypoint* wpt) const } *file_out << "

\n"; - curlog = xml_findnext(root, curlog, "groundspeak:log"); + curlog = curlog->xml_findnext(root, u"groundspeak:log"); } } } diff --git a/kml.cc b/kml.cc index 9dbe69c4f..2e9263200 100644 --- a/kml.cc +++ b/kml.cc @@ -1213,22 +1213,22 @@ QString KmlFormat::kml_geocache_get_logs(const Waypoint* wpt) const return r; } - xml_tag* root = fs_gpx->tag; - xml_tag* curlog = xml_findfirst(root, "groundspeak:log"); + XmlTag* root = fs_gpx->tag; + XmlTag* curlog = root->xml_findfirst(u"groundspeak:log"); while (curlog) { // Unless we have a broken GPX input, these logparts // branches will always be taken. - xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type"); + XmlTag* logpart = curlog->xml_findfirst(u"groundspeak:type"); if (logpart) { r = r + "

" + logpart->cdata + ""; } - logpart = xml_findfirst(curlog, "groundspeak:finder"); + logpart = curlog->xml_findfirst(u"groundspeak:finder"); if (logpart) { r = r + " by " + logpart->cdata; } - logpart = xml_findfirst(curlog, "groundspeak:date"); + logpart = curlog->xml_findfirst(u"groundspeak:date"); if (logpart) { gpsbabel::DateTime t = xml_parse_time(logpart->cdata); if (t.isValid()) { @@ -1236,14 +1236,14 @@ QString KmlFormat::kml_geocache_get_logs(const Waypoint* wpt) const } } - logpart = xml_findfirst(curlog, "groundspeak:text"); + logpart = curlog->xml_findfirst(u"groundspeak:text"); if (logpart) { r += "
"; r += logpart->cdata.toHtmlEscaped(); } r += "

"; - curlog = xml_findnext(root, curlog, "groundspeak:log"); + curlog = curlog->xml_findnext(root, u"groundspeak:log"); } return r; } diff --git a/src/core/xmltag.cc b/src/core/xmltag.cc new file mode 100644 index 000000000..2376bce3d --- /dev/null +++ b/src/core/xmltag.cc @@ -0,0 +1,123 @@ +/* + Functions to deal with xml_tags + + Copyright (C) 2005 Ron Parker and Robert Lipe. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 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 General Public License for more details. + + You should have received a copy of the GNU 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. + + */ + +#include // for QString +#include // for QStringView +#include // for CaseInsensitive +#include // for QXmlStreamAttribute +#include // for QXmlStreamAttributes + +#include "src/core/xmltag.h" + + +/* + * xml_tag utilities + */ + +XmlTag* XmlTag::xml_next(const XmlTag* root) +{ + XmlTag* cur = this; + if (cur->child) { + cur = cur->child; + } else if (cur->sibling) { + cur = cur->sibling; + } else { + cur = cur->parent; + if (cur == root) { + cur = nullptr; + } + if (cur) { + cur = cur->sibling; + } + } + return cur; +} + +XmlTag* XmlTag::xml_findnext(const XmlTag* root, QStringView name) +{ + XmlTag* result = this; + do { + result = result->xml_next(root); + } while (result && result->tagname.compare(name, Qt::CaseInsensitive)); + return result; +} + +XmlTag* XmlTag::xml_findfirst(QStringView name) +{ + return xml_findnext(this, name); +} + +QString XmlTag::xml_attribute(const QString& attrname) const +{ + for (const auto& attribute : this->attributes) { + if (attribute.qualifiedName().compare(attrname, Qt::CaseInsensitive) == 0) { + return attribute.value().toString(); + } + } + return QString(); +} + +static void +free_xml_tag(XmlTag* tag) +{ + while (tag) { + if (tag->child) { + free_xml_tag(tag->child); + } + + XmlTag* next = tag->sibling; + delete tag; + tag = next; + } +} + +// FIXME: at some point, this becomes a plain ole copy constructor. +static void +copy_xml_tag(XmlTag** copy, XmlTag* src, XmlTag* parent) +{ + if (!src) { + *copy = nullptr; + return; + } + + auto* res = new XmlTag; + *copy = res; + + res->tagname = (src->tagname); + res->cdata = (src->cdata); + res->parentcdata = (src->parentcdata); + res->attributes = src->attributes; + res->parent = parent; + copy_xml_tag(&(res->sibling), src->sibling, parent); + copy_xml_tag(&(res->child), src->child, res); +} + +fs_xml::~fs_xml() +{ + free_xml_tag(tag); +} + +fs_xml* fs_xml::clone() const +{ + auto* copy = new fs_xml(*this); + copy_xml_tag(&(copy->tag), tag, nullptr); + return copy; +} diff --git a/src/core/xmltag.h b/src/core/xmltag.h index 6e276a161..4eb6fb963 100644 --- a/src/core/xmltag.h +++ b/src/core/xmltag.h @@ -19,26 +19,39 @@ #ifndef SRC_CORE_XMLTAG_H #define SRC_CORE_XMLTAG_H -#include // for QString -#include // for QXmlStreamAttributes +#include // for QString +#include // for QStringView +#include // for QXmlStreamAttributes -#include "defs.h" +#include "formspec.h" // for FormatSpecificData, FsType -class xml_tag + +class XmlTag { public: + + /* Member Functions */ + + XmlTag* xml_findnext(const XmlTag* root, QStringView name); + XmlTag* xml_findfirst(QStringView name); + QString xml_attribute(const QString& attrname) const; + + /* Data Members */ + QString tagname; QString cdata; QString parentcdata; QXmlStreamAttributes attributes; - xml_tag* parent{nullptr}; - xml_tag* sibling{nullptr}; - xml_tag* child{nullptr}; -}; + XmlTag* parent{nullptr}; + XmlTag* sibling{nullptr}; + XmlTag* child{nullptr}; -xml_tag* xml_findfirst(xml_tag* root, const QString& tagname); -xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const QString& tagname); -QString xml_attribute(const QXmlStreamAttributes& attributes, const QString& attrname); +private: + + /* Member Functions */ + + XmlTag* xml_next(const XmlTag* root); +}; struct fs_xml : FormatSpecificData { explicit fs_xml(FsType type) : FormatSpecificData(type) {} @@ -52,9 +65,6 @@ public: fs_xml* clone() const override; - xml_tag* tag{nullptr}; + XmlTag* tag{nullptr}; }; - -fs_xml* fs_xml_alloc(FsType type); - #endif // SRC_CORE_XMLTAG_H diff --git a/text.cc b/text.cc index 6b8363545..2dd985160 100644 --- a/text.cc +++ b/text.cc @@ -130,23 +130,23 @@ TextFormat::text_disp(const Waypoint* wpt) if (includelogs) { const auto* fs_gpx = reinterpret_cast(wpt->fs.FsChainFind(kFsGpx)); if (fs_gpx && fs_gpx->tag) { - xml_tag* root = fs_gpx->tag; - xml_tag* curlog = xml_findfirst(root, "groundspeak:log"); + XmlTag* root = fs_gpx->tag; + XmlTag* curlog = root->xml_findfirst(u"groundspeak:log"); while (curlog) { time_t logtime = 0; *file_out << "\n"; - xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type"); + XmlTag* logpart = curlog->xml_findfirst(u"groundspeak:type"); if (logpart) { *file_out << logpart->cdata << " by "; } - logpart = xml_findfirst(curlog, "groundspeak:finder"); + logpart = curlog->xml_findfirst(u"groundspeak:finder"); if (logpart) { *file_out << logpart->cdata << " on "; } - logpart = xml_findfirst(curlog, "groundspeak:date"); + logpart = curlog->xml_findfirst(u"groundspeak:date"); if (logpart) { logtime = xml_parse_time(logpart->cdata).toTime_t(); struct tm* logtm = localtime(&logtime); @@ -158,16 +158,16 @@ TextFormat::text_disp(const Waypoint* wpt) } } - logpart = xml_findfirst(curlog, "groundspeak:log_wpt"); + logpart = curlog->xml_findfirst(u"groundspeak:log_wpt"); if (logpart) { - double lat = xml_attribute(logpart->attributes, "lat").toDouble(); - double lon = xml_attribute(logpart->attributes, "lon").toDouble(); + double lat = logpart->xml_attribute("lat").toDouble(); + double lon = logpart->xml_attribute("lon").toDouble(); *file_out << pretty_deg_format(lat, lon, degformat[2], " ", false) << "\n"; } - logpart = xml_findfirst(curlog, "groundspeak:text"); + logpart = curlog->xml_findfirst(u"groundspeak:text"); if (logpart) { - QString encstr = xml_attribute(logpart->attributes, "encoded"); + QString encstr = logpart->xml_attribute("encoded"); bool encoded = !encstr.startsWith('F', Qt::CaseInsensitive); QString s; @@ -181,7 +181,7 @@ TextFormat::text_disp(const Waypoint* wpt) } *file_out << "\n"; - curlog = xml_findnext(root, curlog, "groundspeak:log"); + curlog = curlog->xml_findnext(root, u"groundspeak:log"); } } } diff --git a/util.cc b/util.cc index b343a0dda..5b7ab0ce2 100644 --- a/util.cc +++ b/util.cc @@ -22,6 +22,7 @@ #include // for sort #include // for isspace, isalpha, ispunct, tolower, toupper #include // for errno +#include // for INT_MAX, INT_MIN #include // for fabs, floor #include // for va_list, va_end, va_start, va_copy #include // for size_t, vsnprintf, FILE, fopen, printf, sprintf, stderr, stdin, stdout @@ -32,6 +33,7 @@ #include // for QByteArray #include // for QChar, operator<=, operator>= +#include // for QDate #include // for QDateTime #include // for QFileInfo #include // for QList @@ -40,16 +42,15 @@ #include // for QTextBoundaryFinder, QTextBoundaryFinder::Grapheme #include // for QTextCodec #include // for operator<<, QTextStream, qSetFieldWidth, endl, QTextStream::AlignLeft -#include // for QXmlStreamAttribute -#include // for QXmlStreamAttributes #include // for CaseInsensitive +#include // for QTime #include // for QTimeZone #include // for qAsConst, qEnvironmentVariableIsSet, QAddConst<>::Type, qPrintable #include "defs.h" #include "src/core/datetime.h" // for DateTime #include "src/core/logging.h" // for Warning -#include "src/core/xmltag.h" // for xml_tag, xml_attribute, xml_findfirst, xml_findnext + #if Q_BYTE_ORDER == Q_BIG_ENDIAN # define i_am_little_endian 0 @@ -1344,52 +1345,6 @@ strip_html(const utf_string* in) #endif } -/* - * xml_tag utilities - */ - -xml_tag* xml_next(xml_tag* root, xml_tag* cur) -{ - if (cur->child) { - cur = cur->child; - } else if (cur->sibling) { - cur = cur->sibling; - } else { - cur = cur->parent; - if (cur == root) { - cur = nullptr; - } - if (cur) { - cur = cur->sibling; - } - } - return cur; -} - -xml_tag* xml_findnext(xml_tag* root, xml_tag* cur, const QString& tagname) -{ - xml_tag* result = cur; - do { - result = xml_next(root, result); - } while (result && result->tagname.compare(tagname, Qt::CaseInsensitive)); - return result; -} - -xml_tag* xml_findfirst(xml_tag* root, const QString& tagname) -{ - return xml_findnext(root, root, tagname); -} - -QString xml_attribute(const QXmlStreamAttributes& attributes, const QString& attrname) -{ - for (const auto& attribute : attributes) { - if (attribute.qualifiedName().compare(attrname, Qt::CaseInsensitive) == 0) { - return attribute.value().toString(); - } - } - return QString(); -} - QString get_filename(const QString& fname) { return QFileInfo(fname).fileName(); diff --git a/xmltag.cc b/xmltag.cc deleted file mode 100644 index d01594d56..000000000 --- a/xmltag.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* - Functions to deal with xml_tags - - Copyright (C) 2005 Ron Parker and Robert Lipe. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 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 General Public License for more details. - - You should have received a copy of the GNU 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. - - */ - -#include // for QString -#include // for QXmlStreamAttributes - -#include "defs.h" -#include "src/core/xmltag.h" - -static void -free_xml_tag(xml_tag* tag) -{ - while (tag) { - if (tag->child) { - free_xml_tag(tag->child); - } - - xml_tag* next = tag->sibling; - delete tag; - tag = next; - } -} - -// FIXME: at some point, this becomes a plain ole copy constructor. -static void -copy_xml_tag(xml_tag** copy, xml_tag* src, xml_tag* parent) -{ - if (!src) { - *copy = nullptr; - return; - } - - auto* res = new xml_tag; - *copy = res; - - res->tagname = (src->tagname); - res->cdata = (src->cdata); - res->parentcdata = (src->parentcdata); - res->attributes = src->attributes; - res->parent = parent; - copy_xml_tag(&(res->sibling), src->sibling, parent); - copy_xml_tag(&(res->child), src->child, res); -} - -fs_xml::~fs_xml() -{ - free_xml_tag(tag); -} - -fs_xml* fs_xml::clone() const -{ - auto* copy = new fs_xml(*this); - copy_xml_tag(&(copy->tag), tag, nullptr); - return copy; -} - -fs_xml* fs_xml_alloc(FsType type) -{ - auto* result = new fs_xml(type); - return result; -}