diff --git a/libopenage/renderer/resources/parser/common.cpp b/libopenage/renderer/resources/parser/common.cpp index 483c2cb0dd..c270ebf891 100644 --- a/libopenage/renderer/resources/parser/common.cpp +++ b/libopenage/renderer/resources/parser/common.cpp @@ -20,13 +20,7 @@ TextureData parse_texture(const std::vector &args) { texture.texture_id = std::stoul(args[1]); // Call substr() to get rid of the quotes - // If the line ends in a carriage return, remove it as well - if (args[2][args[2].size() - 1] == '\r') { - texture.path = args[2].substr(1, args[2].size() - 3); - } - else { - texture.path = args[2].substr(1, args[2].size() - 2); - } + texture.path = args[2].substr(1, args[2].size() - 2); return texture; } diff --git a/libopenage/renderer/resources/parser/parse_blendmask.cpp b/libopenage/renderer/resources/parser/parse_blendmask.cpp index d7f6e4aa74..b5b9338b72 100644 --- a/libopenage/renderer/resources/parser/parse_blendmask.cpp +++ b/libopenage/renderer/resources/parser/parse_blendmask.cpp @@ -1,4 +1,4 @@ -// Copyright 2023-2023 the openage authors. See copying.md for legal info. +// Copyright 2023-2024 the openage authors. See copying.md for legal info. #include "parse_blendmask.h" @@ -40,7 +40,7 @@ blending_mask parse_mask(const std::vector &args) { if (args[0].starts_with("0b")) { // discard prefix because std::stoul doesn't understand binary prefixes std::string strip = args[0].substr(2, args[2].size() - 1); - dir = std::stoul(args[0], nullptr, 2); + dir = std::stoul(strip, nullptr, 2); } else { dir = std::stoul(args[0]); @@ -58,16 +58,16 @@ blending_mask parse_mask(const std::vector &args) { return mask; } -BlendPatternInfo parse_blendmask_file(const util::Path &file, +BlendPatternInfo parse_blendmask_file(const util::Path &path, const std::shared_ptr &cache) { - if (not file.is_file()) [[unlikely]] { + if (not path.is_file()) [[unlikely]] { throw Error(MSG(err) << "Reading .blmask file '" - << file.get_name() + << path.get_name() << "' failed. Reason: File not found"); } - auto content = file.open(); - auto lines = content.get_lines(); + auto file = path.open(); + auto lines = file.get_lines(); float scalefactor = 1.0; std::vector textures; @@ -79,7 +79,7 @@ BlendPatternInfo parse_blendmask_file(const util::Path &file, if (version_no != 2) { throw Error(MSG(err) << "Reading .blmask file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Version " << version_no << " not supported"); } @@ -104,7 +104,7 @@ BlendPatternInfo parse_blendmask_file(const util::Path &file, // TODO: Avoid double lookup with keywordfuncs.find(args[0]) if (not keywordfuncs.contains(args[0])) [[unlikely]] { throw Error(MSG(err) << "Reading .blmask file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Keyword " << args[0] << " is not defined"); } @@ -128,7 +128,7 @@ BlendPatternInfo parse_blendmask_file(const util::Path &file, // Parse textures std::vector> texture_infos; for (auto texture : textures) { - util::Path texturepath = (file.get_parent() / texture.path); + util::Path texturepath = (path.get_parent() / texture.path); if (cache && cache->check_texture_cache(texturepath)) { // already loaded diff --git a/libopenage/renderer/resources/parser/parse_blendtable.cpp b/libopenage/renderer/resources/parser/parse_blendtable.cpp index c37579ce36..e564085820 100644 --- a/libopenage/renderer/resources/parser/parse_blendtable.cpp +++ b/libopenage/renderer/resources/parser/parse_blendtable.cpp @@ -1,4 +1,4 @@ -// Copyright 2023-2023 the openage authors. See copying.md for legal info. +// Copyright 2023-2024 the openage authors. See copying.md for legal info. #include "parse_blendtable.h" @@ -67,16 +67,16 @@ PatternData parse_pattern(const std::vector &args) { return pattern; } -BlendTableInfo parse_blendtable_file(const util::Path &file, +BlendTableInfo parse_blendtable_file(const util::Path &path, const std::shared_ptr &cache) { - if (not file.is_file()) [[unlikely]] { + if (not path.is_file()) [[unlikely]] { throw Error(MSG(err) << "Reading .bltable file '" - << file.get_name() + << path.get_name() << "' failed. Reason: File not found"); } - auto content = file.open(); - auto lines = content.get_lines(); + auto file = path.open(); + auto lines = file.get_lines(); std::vector blendtable; std::vector patterns; @@ -87,7 +87,7 @@ BlendTableInfo parse_blendtable_file(const util::Path &file, if (version_no != 1) { throw Error(MSG(err) << "Reading .bltable file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Version " << version_no << " not supported"); } @@ -110,7 +110,7 @@ BlendTableInfo parse_blendtable_file(const util::Path &file, // TODO: Avoid double lookup with keywordfuncs.find(args[0]) if (not keywordfuncs.contains(args[0])) [[unlikely]] { throw Error(MSG(err) << "Reading .bltable file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Keyword " << args[0] << " is not defined"); } @@ -125,7 +125,7 @@ BlendTableInfo parse_blendtable_file(const util::Path &file, i += 1; if (i >= lines.size()) { throw Error(MSG(err) << "Reading .bltable file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Matrix for keyword " << args[0] << " is malformed"); } @@ -142,7 +142,7 @@ BlendTableInfo parse_blendtable_file(const util::Path &file, std::vector> pattern_infos; for (auto pattern : patterns) { - util::Path maskpath = (file.get_parent() / pattern.path); + util::Path maskpath = (path.get_parent() / pattern.path); if (cache && cache->check_blpattern_cache(maskpath)) { // already loaded diff --git a/libopenage/renderer/resources/parser/parse_palette.cpp b/libopenage/renderer/resources/parser/parse_palette.cpp index 344466dd86..abea683f6a 100644 --- a/libopenage/renderer/resources/parser/parse_palette.cpp +++ b/libopenage/renderer/resources/parser/parse_palette.cpp @@ -1,4 +1,4 @@ -// Copyright 2023-2023 the openage authors. See copying.md for legal info. +// Copyright 2023-2024 the openage authors. See copying.md for legal info. #include "parse_palette.h" @@ -63,15 +63,15 @@ std::vector parse_colours(const std::vector &lines) { return entries; } -PaletteInfo parse_palette_file(const util::Path &file) { - if (not file.is_file()) [[unlikely]] { +PaletteInfo parse_palette_file(const util::Path &path) { + if (not path.is_file()) [[unlikely]] { throw Error(MSG(err) << "Reading .opal file '" - << file.get_name() + << path.get_name() << "' failed. Reason: File not found"); } - auto content = file.open(); - auto lines = content.get_lines(); + auto file = path.open(); + auto lines = file.get_lines(); size_t entries = 0; std::vector colours; @@ -82,7 +82,7 @@ PaletteInfo parse_palette_file(const util::Path &file) { if (version_no != 1) { throw Error(MSG(err) << "Reading .opal file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Version " << version_no << " not supported"); } @@ -105,7 +105,7 @@ PaletteInfo parse_palette_file(const util::Path &file) { // TODO: Avoid double lookup with keywordfuncs.find(args[0]) if (not keywordfuncs.contains(args[0])) [[unlikely]] { throw Error(MSG(err) << "Reading .opal file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Keyword " << args[0] << " is not defined"); } @@ -120,7 +120,7 @@ PaletteInfo parse_palette_file(const util::Path &file) { i += 1; if (i >= lines.size()) { throw Error(MSG(err) << "Reading .opal file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Matrix for keyword " << args[0] << " is malformed"); } diff --git a/libopenage/renderer/resources/parser/parse_sprite.cpp b/libopenage/renderer/resources/parser/parse_sprite.cpp index 0974f98342..01534ad755 100644 --- a/libopenage/renderer/resources/parser/parse_sprite.cpp +++ b/libopenage/renderer/resources/parser/parse_sprite.cpp @@ -134,16 +134,16 @@ FrameData parse_frame(const std::vector &args) { return frame; } -Animation2dInfo parse_sprite_file(const util::Path &file, +Animation2dInfo parse_sprite_file(const util::Path &path, const std::shared_ptr &cache) { - if (not file.is_file()) [[unlikely]] { + if (not path.is_file()) [[unlikely]] { throw Error(MSG(err) << "Reading .sprite file '" - << file.get_name() + << path.get_name() << "' failed. Reason: File not found"); } - auto content = file.open(); - auto lines = content.get_lines(); + auto file = path.open(); + auto lines = file.get_lines(); float scalefactor = 1.0; std::vector textures; @@ -162,7 +162,7 @@ Animation2dInfo parse_sprite_file(const util::Path &file, if (version_no != 2) { throw Error(MSG(err) << "Reading .sprite file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Version " << version_no << " not supported"); } @@ -195,8 +195,8 @@ Animation2dInfo parse_sprite_file(const util::Path &file, })}; for (auto line : lines) { - // Skip empty lines, lines with carriage returns, and comments - if (line.empty() || line.substr(0, 1) == "#" || line[0] == '\r') { + // Skip empty lines and comments + if (line.empty() || line.substr(0, 1) == "#") { continue; } std::vector args{util::split(line, ' ')}; @@ -204,7 +204,7 @@ Animation2dInfo parse_sprite_file(const util::Path &file, // TODO: Avoid double lookup with keywordfuncs.find(args[0]) if (not keywordfuncs.contains(args[0])) [[unlikely]] { throw Error(MSG(err) << "Reading .sprite file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Keyword " << args[0] << " is not defined"); } @@ -317,7 +317,7 @@ Animation2dInfo parse_sprite_file(const util::Path &file, // Parse textures std::vector> texture_infos; for (auto texture : textures) { - util::Path texturepath = (file.get_parent() / texture.path); + util::Path texturepath = (path.get_parent() / texture.path); if (cache && cache->check_texture_cache(texturepath)) { // already loaded diff --git a/libopenage/renderer/resources/parser/parse_terrain.cpp b/libopenage/renderer/resources/parser/parse_terrain.cpp index 26dc77f10b..9b17f4608e 100644 --- a/libopenage/renderer/resources/parser/parse_terrain.cpp +++ b/libopenage/renderer/resources/parser/parse_terrain.cpp @@ -139,16 +139,16 @@ TerrainFrameData parse_terrain_frame(const std::vector &args) { return frame; } -TerrainInfo parse_terrain_file(const util::Path &file, +TerrainInfo parse_terrain_file(const util::Path &path, const std::shared_ptr &cache) { - if (not file.is_file()) [[unlikely]] { + if (not path.is_file()) [[unlikely]] { throw Error(MSG(err) << "Reading .terrain file '" - << file.get_name() + << path.get_name() << "' failed. Reason: File not found"); } - auto content = file.open(); - auto lines = content.get_lines(); + auto file = path.open(); + auto lines = file.get_lines(); float scalefactor = 1.0; std::vector textures; @@ -167,7 +167,7 @@ TerrainInfo parse_terrain_file(const util::Path &file, if (version_no != 2) { throw Error(MSG(err) << "Reading .terrain file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Version " << version_no << " not supported"); } @@ -200,8 +200,8 @@ TerrainInfo parse_terrain_file(const util::Path &file, })}; for (auto line : lines) { - // Skip empty lines, lines with carriage returns, and comments - if (line.empty() || line.substr(0, 1) == "#" || line[0] == '\r') { + // Skip empty lines and comments + if (line.empty() || line.substr(0, 1) == "#") { continue; } std::vector args{util::split(line, ' ')}; @@ -209,7 +209,7 @@ TerrainInfo parse_terrain_file(const util::Path &file, // TODO: Avoid double lookup with keywordfuncs.find(args[0]) if (not keywordfuncs.contains(args[0])) [[unlikely]] { throw Error(MSG(err) << "Reading .terrain file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Keyword " << args[0] << " is not defined"); } @@ -269,7 +269,7 @@ TerrainInfo parse_terrain_file(const util::Path &file, // Parse textures std::vector> texture_infos; for (auto texture : textures) { - util::Path texturepath = (file.get_parent() / texture.path); + util::Path texturepath = (path.get_parent() / texture.path); if (cache && cache->check_texture_cache(texturepath)) { // already loaded @@ -287,7 +287,7 @@ TerrainInfo parse_terrain_file(const util::Path &file, std::shared_ptr blendtable_info; if (blendtable) { - util::Path tablepath = (file.get_parent() / blendtable.value().path); + util::Path tablepath = (path.get_parent() / blendtable.value().path); if (cache && cache->check_bltable_cache(tablepath)) { // already loaded diff --git a/libopenage/renderer/resources/parser/parse_texture.cpp b/libopenage/renderer/resources/parser/parse_texture.cpp index c3d90fa30a..6f1ee622d3 100644 --- a/libopenage/renderer/resources/parser/parse_texture.cpp +++ b/libopenage/renderer/resources/parser/parse_texture.cpp @@ -56,11 +56,6 @@ std::string parse_imagefile(const std::vector &args) { // it should result in an error if wrongly used here. // Call substr() to get rid of the quotes - // If the line ends in a carriage return, remove it as well - if (args[1][args[1].size() - 1] == '\r') { - return args[1].substr(1, args[1].size() - 3); - } - return args[1].substr(1, args[1].size() - 2); } @@ -144,15 +139,15 @@ SubtextureData parse_subtex(const std::vector &args) { return subtex; } -Texture2dInfo parse_texture_file(const util::Path &file) { - if (not file.is_file()) [[unlikely]] { +Texture2dInfo parse_texture_file(const util::Path &path) { + if (not path.is_file()) [[unlikely]] { throw Error(MSG(err) << "Reading .texture file '" - << file.get_name() + << path.get_name() << "' failed. Reason: File not found"); } - auto content = file.open(); - auto lines = content.get_lines(); + auto file = path.open(); + auto lines = file.get_lines(); std::string imagefile; SizeData size; @@ -165,7 +160,7 @@ Texture2dInfo parse_texture_file(const util::Path &file) { if (version_no != 1) { throw Error(MSG(err) << "Reading .texture file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Version " << version_no << " not supported"); } @@ -184,8 +179,8 @@ Texture2dInfo parse_texture_file(const util::Path &file) { })}; for (auto line : lines) { - // Skip empty lines, lines with carriage returns, and comments - if (line.empty() || line.substr(0, 1) == "#" || line[0] == '\r') { + // Skip empty lines and comments + if (line.empty() || line.substr(0, 1) == "#") { continue; } std::vector args{util::split(line, ' ')}; @@ -193,7 +188,7 @@ Texture2dInfo parse_texture_file(const util::Path &file) { // TODO: Avoid double lookup with keywordfuncs.find(args[0]) if (not keywordfuncs.contains(args[0])) [[unlikely]] { throw Error(MSG(err) << "Reading .texture file '" - << file.get_name() + << path.get_name() << "' failed. Reason: Keyword " << args[0] << " is not defined"); } @@ -213,7 +208,7 @@ Texture2dInfo parse_texture_file(const util::Path &file) { size.height); } - auto imagepath = file.get_parent() / imagefile; + auto imagepath = path.get_parent() / imagefile; auto align = guess_row_alignment(size.width); return Texture2dInfo(size.width, size.height, pxformat.format, imagepath, align, std::move(subinfos)); diff --git a/libopenage/util/file.cpp b/libopenage/util/file.cpp index 0acea80695..5aa630d4cc 100644 --- a/libopenage/util/file.cpp +++ b/libopenage/util/file.cpp @@ -1,4 +1,4 @@ -// Copyright 2013-2019 the openage authors. See copying.md for legal info. +// Copyright 2013-2024 the openage authors. See copying.md for legal info. #include "file.h" @@ -9,11 +9,13 @@ #include #include -#include "path.h" -#include "filelike/native.h" -#include "filelike/python.h" -#include "../error/error.h" -#include "../log/log.h" +#include "error/error.h" +#include "log/log.h" + +#include "util/filelike/native.h" +#include "util/filelike/python.h" +#include "util/path.h" +#include "util/strings.h" namespace openage::util { @@ -23,8 +25,7 @@ File::File() = default; // yes. i'm sorry. but cython can't enum class yet. -File::File(const std::string &path, int mode) - : +File::File(const std::string &path, int mode) : File{path, static_cast(mode)} {} @@ -33,8 +34,7 @@ File::File(const std::string &path, mode_t mode) { } -File::File(std::shared_ptr filelike) - : +File::File(std::shared_ptr filelike) : filelike{filelike} {} @@ -102,13 +102,7 @@ std::vector File::get_lines() { // TODO: relay the get_lines to the underlaying filelike // which may do a better job in getting the lines. // instead, we read everything and then split up into lines. - std::string line; - std::vector result{}; - std::istringstream content{this->read()}; - - while (std::getline(content, line)) { - result.push_back(line); - } + std::vector result = util::split_newline(this->read()); return result; } @@ -119,7 +113,7 @@ std::shared_ptr File::get_fileobj() const { } -std::ostream &operator <<(std::ostream &stream, const File &file) { +std::ostream &operator<<(std::ostream &stream, const File &file) { stream << "File("; file.filelike->repr(stream); stream << ")"; @@ -128,4 +122,4 @@ std::ostream &operator <<(std::ostream &stream, const File &file) { } -} // openage::util +} // namespace openage::util diff --git a/libopenage/util/strings.cpp b/libopenage/util/strings.cpp index 4a9ce1436e..9243992db5 100644 --- a/libopenage/util/strings.cpp +++ b/libopenage/util/strings.cpp @@ -1,17 +1,17 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. +// Copyright 2013-2024 the openage authors. See copying.md for legal info. #include "strings.h" -#include #include +#include #include #include #include #include -#include "config.h" #include "../error/error.h" #include "compiler.h" +#include "config.h" namespace openage::util { @@ -72,12 +72,10 @@ size_t rstrip(char *s) { size_t strippedlen = strlen(s); while (strippedlen > 0) { - if (s[strippedlen - 1] == '\n' || - s[strippedlen - 1] == ' ' || - s[strippedlen - 1] == '\t') { - + if (s[strippedlen - 1] == '\n' || s[strippedlen - 1] == ' ' || s[strippedlen - 1] == '\t') { strippedlen -= 1; - } else { + } + else { break; } } @@ -141,7 +139,6 @@ std::vector split(const std::string &txt, char delimiter) { std::vector split_escape(const std::string &txt, char delim, size_t size_hint) { - // output vector std::vector items; if (size_hint) [[likely]] { @@ -161,7 +158,6 @@ std::vector split_escape(const std::string &txt, char delim, size_t // copy characters to buf, and a buf is emitted as a token // when the delimiter or end is reached. while (true) { - // end of input string if (*r == '\0') { items.emplace_back(std::begin(buf), std::end(buf)); @@ -210,4 +206,17 @@ std::vector split_escape(const std::string &txt, char delim, size_t return items; } -} // openage::util +std::vector split_newline(const std::string &txt) { + auto lines = split(txt, '\n'); + + // remove the '\r' from the end of each line + for (auto &line : lines) { + if (not line.empty() and line.back() == '\r') { + line.pop_back(); + } + } + + return lines; +} + +} // namespace openage::util diff --git a/libopenage/util/strings.h b/libopenage/util/strings.h index 4ab90de510..ad04e5267c 100644 --- a/libopenage/util/strings.h +++ b/libopenage/util/strings.h @@ -116,5 +116,10 @@ std::vector split_escape(const std::string &txt, char delim, size_t size_hint = 0); +/** + * Newline splitter that works with both \n and \r\n. + */ +std::vector split_newline(const std::string &txt); + } // namespace util } // namespace openage