diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-07-25 19:06:28 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-07-25 19:06:28 +0000 |
| commit | 73e263588ca2ca99ea7cac8bbf274695dcd0bec6 (patch) | |
| tree | 75a0b4cbc426c1c21671ee784c0230b09ffd4fc4 /src/util/units.cpp | |
| parent | Merged from trunk (r12419). (diff) | |
| parent | Remove unnecessary variable from the GMarkup-based unit parser (diff) | |
| download | inkscape-73e263588ca2ca99ea7cac8bbf274695dcd0bec6.tar.gz inkscape-73e263588ca2ca99ea7cac8bbf274695dcd0bec6.zip | |
Merge from trunk (r12439).
(bzr r11608.1.108)
Diffstat (limited to 'src/util/units.cpp')
| -rw-r--r-- | src/util/units.cpp | 211 |
1 files changed, 61 insertions, 150 deletions
diff --git a/src/util/units.cpp b/src/util/units.cpp index d1275b082..f8ebc5c1a 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -5,8 +5,9 @@ #include <cmath> #include <cerrno> #include <glib.h> +#include <glibmm/fileutils.h> +#include <glibmm/markup.h> -#include "io/simple-sax.h" #include "util/units.h" #include "path-prefix.h" #include "streq.h" @@ -47,27 +48,31 @@ std::map<Glib::ustring, Inkscape::Util::UnitType> &getTypeMappings() namespace Inkscape { namespace Util { -class UnitsSAXHandler : public Inkscape::IO::FlatSaxHandler +class UnitParser : public Glib::Markup::Parser { public: - UnitsSAXHandler(UnitTable *table); - virtual ~UnitsSAXHandler() {} + typedef Glib::Markup::Parser::AttributeMap AttrMap; + typedef Glib::Markup::ParseContext Ctx; - virtual void _startElement(xmlChar const *name, xmlChar const **attrs); - virtual void _endElement(xmlChar const *name); + UnitParser(UnitTable *table); + virtual ~UnitParser() {} +protected: + virtual void on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap const &attrs); + virtual void on_end_element(Ctx &ctx, Glib::ustring const &name); + virtual void on_text(Ctx &ctx, Glib::ustring const &text); + +public: UnitTable *tbl; bool primary; bool skip; Unit unit; }; -UnitsSAXHandler::UnitsSAXHandler(UnitTable *table) : - FlatSaxHandler(), +UnitParser::UnitParser(UnitTable *table) : tbl(table), - primary(0), - skip(0), - unit() + primary(false), + skip(false) { } @@ -115,10 +120,8 @@ int Unit::defaultDigits() const { UnitTable::UnitTable() { - // if we swich to the xml file, don't forget to force locale to 'C' - // load("share/ui/units.xml"); // <-- Buggy - gchar *filename = g_build_filename(INKSCAPE_UIDIR, "units.txt", NULL); - loadText(filename); + gchar *filename = g_build_filename(INKSCAPE_UIDIR, "units.xml", NULL); + load(filename); g_free(filename); } @@ -183,165 +186,73 @@ Glib::ustring UnitTable::primary(UnitType type) const return _primary_unit[type]; } -bool UnitTable::loadText(Glib::ustring const &filename) -{ - char buf[BUFSIZE] = {0}; - - // Open file for reading - FILE * f = fopen(filename.c_str(), "r"); - if (f == NULL) { - g_warning("Could not open units file '%s': %s\n", - filename.c_str(), strerror(errno)); - g_warning("* INKSCAPE_DATADIR is: '%s'\n", INKSCAPE_DATADIR); - g_warning("* INKSCAPE_UIDIR is: '%s'\n", INKSCAPE_UIDIR); - return false; - } - - /** @todo fix this to use C++ means and explicit locale to avoid need to change. */ - // bypass current locale in order to make - // sscanf read floats with '.' as a separator - // set locale to 'C' and keep old locale - char *old_locale = g_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale (LC_NUMERIC, "C"); - - while (fgets(buf, BUFSIZE, f) != NULL) { - char name[BUFSIZE] = {0}; - char plural[BUFSIZE] = {0}; - char abbr[BUFSIZE] = {0}; - char type[BUFSIZE] = {0}; - double factor = 0.0; - char primary[BUFSIZE] = {0}; - - int nchars = 0; - // locale is set to C, scanning %lf should work _everywhere_ - /** @todo address %15n, which causes a warning: */ - if (sscanf(buf, "%15s %15s %15s %15s %8lf %1s %15n", - name, plural, abbr, type, &factor, primary, &nchars) != 6) - { - // Skip the line - doesn't appear to be valid - continue; - } - - g_assert(nchars < BUFSIZE); - - char *desc = buf; - desc += nchars; // buf is now only the description +bool UnitTable::load(std::string const &filename) { + UnitParser uparser(this); + Glib::Markup::ParseContext ctx(uparser); - // insert into _unit_map - if (getTypeMappings().find(type) == getTypeMappings().end()) - { - g_warning("Skipping unknown unit type '%s' for %s.\n", type, name); - continue; - } - UnitType utype = getTypeMappings()[type]; - - Unit u(utype, factor, name, plural, abbr, desc); - - // if primary is 'Y', list this unit as a primary - addUnit(u, (primary[0]=='Y' || primary[0]=='y')); - } - - // set back the saved locale - setlocale (LC_NUMERIC, old_locale); - g_free (old_locale); - - // close file - if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", filename.c_str(), strerror(errno)); + try { + Glib::ustring unitfile = Glib::file_get_contents(filename); + ctx.parse(unitfile); + ctx.end_parse(); + } catch (Glib::MarkupError const &e) { + g_warning("Problem loading units file '%s': %s\n", filename.c_str(), e.what().c_str()); return false; } - return true; } -bool UnitTable::load(Glib::ustring const &filename) { - UnitsSAXHandler handler(this); +bool UnitTable::save(std::string const &filename) { - int result = handler.parseFile( filename.c_str() ); - if ( result != 0 ) { - // perhaps - g_warning("Problem loading units file '%s': %d\n", filename.c_str(), result); - return false; - } + g_warning("UnitTable::save(): not implemented"); return true; } -bool UnitTable::save(Glib::ustring const &filename) { - - // open file for writing - FILE *f = fopen(filename.c_str(), "w"); - if (f == NULL) { - g_warning("Could not open units file '%s': %s\n", filename.c_str(), strerror(errno)); - return false; - } - - // write out header - // foreach item in _unit_map, sorted alphabetically by type and then unit name - // sprintf a line - // name - // name_plural - // abbr - // type - // factor - // PRI - if listed in primary unit table, 'Y', else 'N' - // description - // write line to the file - - // close file - if (fclose(f) != 0) { - g_warning("Error closing units file '%s': %s\n", filename.c_str(), strerror(errno)); - return false; - } - - return true; -} - - -void UnitsSAXHandler::_startElement(xmlChar const *name, xmlChar const **attrs) +void UnitParser::on_start_element(Ctx &ctx, Glib::ustring const &name, AttrMap const &attrs) { - if (streq("unit", (char const *)name)) { + if (name == "unit") { // reset for next use unit.clear(); primary = false; skip = false; - for ( int i = 0; attrs[i]; i += 2 ) { - char const *const key = (char const *)attrs[i]; - if (streq("type", key)) { - char const *type = (char const*)attrs[i+1]; - if (getTypeMappings().find(type) != getTypeMappings().end()) - { - unit.type = getTypeMappings()[type]; - } else { - g_warning("Skipping unknown unit type '%s' for %s.\n", type, name); - skip = true; - } - } else if (streq("pri", key)) { - primary = attrs[i+1][0] == 'y' || attrs[i+1][0] == 'Y'; + AttrMap::const_iterator f; + if ((f = attrs.find("type")) != attrs.end()) { + Glib::ustring type = f->second; + if (getTypeMappings().find(type) != getTypeMappings().end()) { + unit.type = getTypeMappings()[type]; + } else { + g_warning("Skipping unknown unit type '%s'.\n", type.c_str()); + skip = true; } } + if ((f = attrs.find("pri")) != attrs.end()) { + primary = (f->second[0] == 'y' || f->second[0] == 'Y'); + } } } -void UnitsSAXHandler::_endElement(xmlChar const *xname) +void UnitParser::on_text(Ctx &ctx, Glib::ustring const &text) { - char const *const name = (char const *) xname; - if (streq("name", name)) { - unit.name = data; - } else if (streq("plural", name)) { - unit.name_plural = data; - } else if (streq("abbr", name)) { - unit.abbr = data; - } else if (streq("factor", name)) { + Glib::ustring element = ctx.get_element(); + if (element == "name") { + unit.name = text; + } else if (element == "plural") { + unit.name_plural = text; + } else if (element == "abbr") { + unit.abbr = text; + } else if (element == "factor") { // TODO make sure we use the right conversion - unit.factor = atol(data.c_str()); - } else if (streq("description", name)) { - unit.description = data; - } else if (streq("unit", name)) { - if (!skip) { - tbl->addUnit(unit, primary); - } + unit.factor = g_ascii_strtod(text.c_str(), NULL); + } else if (element == "description") { + unit.description = text; + } +} + +void UnitParser::on_end_element(Ctx &ctx, Glib::ustring const &name) +{ + if (name == "unit" && !skip) { + tbl->addUnit(unit, primary); } } |
