move map_source_location to parser as parser_source_location since the locations actually come from there rather than from the map; now the parser keeps track of the location, so it's a bit easier to follow
This commit is contained in:
parent
c6fabb290d
commit
335db1c0e4
|
|
@ -463,6 +463,7 @@ settings::common_settings bsputil_options;
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
bspdata_t bspdata;
|
||||
// FIXME: doesn't this get overwritten by ConvertBSPFormat below?
|
||||
mbsp_t &bsp = bspdata.bsp.emplace<mbsp_t>();
|
||||
|
||||
fmt::print("---- bsputil / ericw-tools {} ----\n", ERICWTOOLS_VERSION);
|
||||
|
|
|
|||
|
|
@ -1000,7 +1000,7 @@ static void DecompileEntity(
|
|||
continue;
|
||||
} else if (modelNum > 0 && keyValue.first == "origin") {
|
||||
auto &value = keyValue.second;
|
||||
parser_t parser(value);
|
||||
parser_t parser(value, { });
|
||||
qvec3d vec;
|
||||
parser.parse_token();
|
||||
vec[0] = stof(parser.token);
|
||||
|
|
@ -1182,7 +1182,8 @@ static void DecompileEntity(
|
|||
|
||||
void DecompileBSP(const mbsp_t *bsp, const decomp_options &options, std::ofstream &file)
|
||||
{
|
||||
auto entdicts = EntData_Parse(bsp->dentdata);
|
||||
parser_t parser{bsp->dentdata, { bsp->file.string() }};
|
||||
auto entdicts = EntData_Parse(parser);
|
||||
|
||||
for (size_t i = 0; i < entdicts.size(); ++i) {
|
||||
// entity 0 is implicitly worldspawn (model 0)
|
||||
|
|
|
|||
|
|
@ -1953,6 +1953,8 @@ bool ConvertBSPFormat(bspdata_t *bspdata, const bspversion_t *to_version)
|
|||
// Conversions to bspver_generic
|
||||
mbsp_t mbsp{};
|
||||
|
||||
mbsp.file = bspdata->file;
|
||||
|
||||
if (std::holds_alternative<bsp29_t>(bspdata->bsp)) {
|
||||
ConvertQ1BSPToGeneric(std::get<bsp29_t>(bspdata->bsp), mbsp);
|
||||
} else if (std::holds_alternative<q2bsp_t>(bspdata->bsp)) {
|
||||
|
|
@ -2167,6 +2169,8 @@ void LoadBSPFile(fs::path &filename, bspdata_t *bspdata)
|
|||
|
||||
logging::funcprint("'{}'\n", filename);
|
||||
|
||||
bspdata->file = filename;
|
||||
|
||||
/* load the file header */
|
||||
fs::data file_data = fs::load(filename);
|
||||
|
||||
|
|
|
|||
|
|
@ -182,10 +182,8 @@ void entdict_t::parse(parser_base_t &parser)
|
|||
}
|
||||
}
|
||||
|
||||
void EntData_ParseInto(const std::string &entdata, std::vector<entdict_t> &vector)
|
||||
void EntData_ParseInto(parser_t &parser, std::vector<entdict_t> &vector)
|
||||
{
|
||||
parser_t parser(entdata);
|
||||
|
||||
/* go through all the entities */
|
||||
while (1) {
|
||||
/* parse the opening brace */
|
||||
|
|
@ -197,20 +195,6 @@ void EntData_ParseInto(const std::string &entdata, std::vector<entdict_t> &vecto
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ==================
|
||||
* EntData_Parse
|
||||
* ==================
|
||||
*/
|
||||
std::vector<entdict_t> EntData_Parse(const std::string &entdata)
|
||||
{
|
||||
std::vector<entdict_t> result;
|
||||
|
||||
EntData_ParseInto(entdata, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ================
|
||||
* EntData_Write
|
||||
|
|
|
|||
|
|
@ -43,15 +43,15 @@ skipspace:
|
|||
if (flags & PARSE_OPTIONAL)
|
||||
return false;
|
||||
if (flags & PARSE_SAMELINE)
|
||||
FError("line {}: Line is incomplete", linenum);
|
||||
FError("{}: Line is incomplete", location);
|
||||
return false;
|
||||
}
|
||||
if (*pos == '\n') {
|
||||
if (flags & PARSE_OPTIONAL)
|
||||
return false;
|
||||
if (flags & PARSE_SAMELINE)
|
||||
FError("line {}: Line is incomplete", linenum);
|
||||
linenum++;
|
||||
FError("{}: Line is incomplete", location);
|
||||
location.line_number.value()++;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
|
@ -67,15 +67,15 @@ skipspace:
|
|||
if (flags & PARSE_OPTIONAL)
|
||||
return false;
|
||||
if (flags & PARSE_SAMELINE)
|
||||
FError("line {}: Line is incomplete", linenum);
|
||||
FError("{}: Line is incomplete", location);
|
||||
while (*pos++ != '\n') {
|
||||
if (!*pos) {
|
||||
if (flags & PARSE_SAMELINE)
|
||||
FError("line {}: Line is incomplete", linenum);
|
||||
FError("{}: Line is incomplete", location);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
linenum++; // count the \n the preceding while() loop just consumed
|
||||
location.line_number.value()++; // count the \n the preceding while() loop just consumed
|
||||
goto skipspace;
|
||||
}
|
||||
if (flags & PARSE_COMMENT)
|
||||
|
|
@ -88,7 +88,7 @@ skipspace:
|
|||
pos++;
|
||||
while (*pos != '"') {
|
||||
if (!*pos)
|
||||
FError("line {}: EOF inside quoted token", linenum);
|
||||
FError("{}: EOF inside quoted token", location);
|
||||
if (*pos == '\\') {
|
||||
// small note. the vanilla quake engine just parses the "foo" stuff then goes and looks for \n
|
||||
// explicitly within strings. this means ONLY \n works, and double-quotes cannot be used either in maps
|
||||
|
|
@ -118,13 +118,13 @@ skipspace:
|
|||
break;
|
||||
case '\"':
|
||||
if (pos[2] == '\r' || pos[2] == '\n') {
|
||||
logging::print("WARNING: line {}: escaped double-quote at end of string\n", linenum);
|
||||
logging::print("WARNING: {}: escaped double-quote at end of string\n", location);
|
||||
} else {
|
||||
*token_p++ = *pos++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logging::print("WARNING: line {}: Unrecognised string escape - \\{}\n", linenum, pos[1]);
|
||||
logging::print("WARNING: {}: Unrecognised string escape - \\{}\n", location, pos[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,12 +34,6 @@ setting_base::setting_base(
|
|||
}
|
||||
}
|
||||
|
||||
bool setting_base::parseString(const std::string &string, source source)
|
||||
{
|
||||
parser_t p{string};
|
||||
return parse("", p, source);
|
||||
}
|
||||
|
||||
setting_group performance_group{"Performance", 10};
|
||||
setting_group logging_group{"Logging", 5};
|
||||
setting_group game_group{"Game", 15};
|
||||
|
|
|
|||
|
|
@ -432,6 +432,9 @@ struct bspdata_t
|
|||
{
|
||||
const bspversion_t *version, *loadversion;
|
||||
|
||||
// the file path that this BSP was loaded from
|
||||
fs::path file;
|
||||
|
||||
// Stay in monostate until a BSP type is requested.
|
||||
std::variant<std::monostate, mbsp_t, bsp29_t, bsp2rmq_t, bsp2_t, q2bsp_t, q2bsp_qbism_t> bsp;
|
||||
|
||||
|
|
|
|||
|
|
@ -436,6 +436,9 @@ struct mbsp_t
|
|||
// the BSP version that we came from, if any
|
||||
const bspversion_t *loadversion;
|
||||
|
||||
// the BSP we were converted from, if any
|
||||
fs::path file;
|
||||
|
||||
std::vector<dmodelh2_t> dmodels;
|
||||
mvis_t dvis;
|
||||
std::vector<uint8_t> dlightdata;
|
||||
|
|
|
|||
|
|
@ -26,12 +26,11 @@
|
|||
#include <vector>
|
||||
#include <string_view>
|
||||
#include "qvec.hh"
|
||||
#include "parser.hh"
|
||||
|
||||
using keyvalue_t = std::pair<std::string, std::string>;
|
||||
using keyvalues_t = std::vector<keyvalue_t>;
|
||||
|
||||
struct parser_base_t;
|
||||
|
||||
class entdict_t
|
||||
{
|
||||
keyvalues_t keyvalues;
|
||||
|
|
@ -69,6 +68,20 @@ public:
|
|||
void parse(parser_base_t &parser);
|
||||
};
|
||||
|
||||
void EntData_ParseInto(const std::string &entdata, std::vector<entdict_t> &vector);
|
||||
std::vector<entdict_t> EntData_Parse(const std::string &entdata);
|
||||
void EntData_ParseInto(parser_t &parser, std::vector<entdict_t> &vector);
|
||||
|
||||
/*
|
||||
* ==================
|
||||
* EntData_Parse
|
||||
* ==================
|
||||
*/
|
||||
inline std::vector<entdict_t> EntData_Parse(parser_t &parser)
|
||||
{
|
||||
std::vector<entdict_t> result;
|
||||
|
||||
EntData_ParseInto(parser, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string EntData_Write(const std::vector<entdict_t> &ents);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,81 @@ enum : int32_t
|
|||
|
||||
using parseflags = int32_t;
|
||||
|
||||
// kind of a parallel to std::source_location in C++20
|
||||
// but this represents a location in a parser.
|
||||
struct parser_source_location
|
||||
{
|
||||
// the source name of this location; may be a .map file path,
|
||||
// or some other string that describes where this location came
|
||||
// to be. note that because the locations only live for the lifetime
|
||||
// of the object it is belonging to, whatever this string
|
||||
// points to must out-live the object.
|
||||
std::shared_ptr<std::string> source_name = nullptr;
|
||||
|
||||
// the line number that this location is associated to, if any. Synthetic
|
||||
// locations may not necessarily have an associated line number.
|
||||
std::optional<size_t> line_number = std::nullopt;
|
||||
|
||||
// reference to a location of the object that derived us. this is mainly
|
||||
// for synthetic locations; ie a bspbrush_t's sides aren't themselves generated
|
||||
// by a source or line, but they are derived from a mapbrush_t which does have
|
||||
// a location. The object it points to must outlive this object. this is mainly
|
||||
// for debugging.
|
||||
std::optional<std::reference_wrapper<const parser_source_location>> derivative = std::nullopt;
|
||||
|
||||
parser_source_location() = default;
|
||||
inline parser_source_location(const std::string &source) : source_name(std::make_unique<std::string>(source)) { }
|
||||
inline parser_source_location(const char *source) : source_name(std::make_unique<std::string>(source)) { }
|
||||
inline parser_source_location(const std::string &source, size_t line) : source_name(std::make_unique<std::string>(source)), line_number(line) { }
|
||||
inline parser_source_location(const char *source, size_t line) : source_name(std::make_unique<std::string>(source)), line_number(line) { }
|
||||
|
||||
// check if this source location is valid
|
||||
explicit operator bool() const { return source_name != nullptr; }
|
||||
|
||||
// return a modified source location with only the line changed
|
||||
inline parser_source_location on_line(size_t new_line) const
|
||||
{
|
||||
parser_source_location loc(*this);
|
||||
loc.line_number = new_line;
|
||||
return loc;
|
||||
}
|
||||
|
||||
// return a new, constructed source location derived from this one
|
||||
template<typename ... Args>
|
||||
inline parser_source_location derive(Args&&... args)
|
||||
{
|
||||
parser_source_location loc(std::forward<Args>(args)...);
|
||||
loc.derivative = *this;
|
||||
return loc;
|
||||
}
|
||||
|
||||
// if we update to C++20 we could use this to track where location objects come from:
|
||||
// std::source_location created_location;
|
||||
};
|
||||
|
||||
// FMT support
|
||||
template<>
|
||||
struct fmt::formatter<parser_source_location>
|
||||
{
|
||||
constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { return ctx.end(); }
|
||||
|
||||
template<typename FormatContext>
|
||||
auto format(const parser_source_location &v, FormatContext &ctx) -> decltype(ctx.out())
|
||||
{
|
||||
if (v.source_name) {
|
||||
format_to(ctx.out(), "{}", *v.source_name.get());
|
||||
} else {
|
||||
format_to(ctx.out(), "unknown/unset location");
|
||||
}
|
||||
|
||||
if (v.line_number.has_value()) {
|
||||
format_to(ctx.out(), "[line {}]", v.line_number.value());
|
||||
}
|
||||
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
constexpr auto untie(const std::tuple<T...> &tuple)
|
||||
{
|
||||
|
|
@ -47,8 +122,14 @@ using untied_t = decltype(untie(std::declval<T>()));
|
|||
|
||||
struct parser_base_t
|
||||
{
|
||||
std::string token;
|
||||
std::string token; // the last token parsed by parse_token
|
||||
bool was_quoted = false; // whether the current token was from a quoted string or not
|
||||
parser_source_location location; // parse location, if any
|
||||
|
||||
inline parser_base_t(parser_source_location base_location) :
|
||||
location(base_location)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool parse_token(parseflags flags = PARSE_NORMAL) = 0;
|
||||
|
||||
|
|
@ -66,30 +147,30 @@ struct parser_t : parser_base_t
|
|||
{
|
||||
const char *pos;
|
||||
const char *end;
|
||||
uint32_t linenum = 1;
|
||||
|
||||
// base constructor; accept raw start & length
|
||||
inline parser_t(const void *start, size_t length)
|
||||
: pos(reinterpret_cast<const char *>(start)), end(reinterpret_cast<const char *>(start) + length)
|
||||
inline parser_t(const void *start, size_t length, parser_source_location base_location)
|
||||
: parser_base_t(base_location.on_line(1)),
|
||||
pos(reinterpret_cast<const char *>(start)), end(reinterpret_cast<const char *>(start) + length)
|
||||
{
|
||||
}
|
||||
|
||||
// pull from string_view; note that the string view must live for the entire
|
||||
// duration of the parser's life time
|
||||
inline parser_t(const std::string_view &view) : parser_t(&view.front(), view.size()) { }
|
||||
inline parser_t(const std::string_view &view, parser_source_location base_location) : parser_t(&view.front(), view.size(), base_location) { }
|
||||
|
||||
// pull from fs::data; note that the data must live for the entire
|
||||
// duration of the parser's life time, and must has_value()
|
||||
inline parser_t(const fs::data &data) : parser_t(data.value().data(), data.value().size()) { }
|
||||
inline parser_t(const fs::data &data, parser_source_location base_location) : parser_t(data.value().data(), data.value().size(), base_location) { }
|
||||
|
||||
// pull from C string; made explicit because this is error-prone
|
||||
explicit parser_t(const char *str) : parser_t(str, strlen(str)) { }
|
||||
explicit parser_t(const char *str, parser_source_location base_location) : parser_t(str, strlen(str), base_location) { }
|
||||
|
||||
bool parse_token(parseflags flags = PARSE_NORMAL) override;
|
||||
|
||||
using state_type = decltype(std::tie(pos, linenum));
|
||||
using state_type = decltype(std::tie(pos, location));
|
||||
|
||||
constexpr state_type state() { return state_type(pos, linenum); }
|
||||
constexpr state_type state() { return state_type(pos, location); }
|
||||
|
||||
bool at_end() const override { return pos >= end; }
|
||||
|
||||
|
|
@ -112,7 +193,7 @@ struct token_parser_t : parser_base_t
|
|||
std::vector<std::string_view> tokens;
|
||||
size_t cur = 0;
|
||||
|
||||
inline token_parser_t(int argc, const char **args) : tokens(args, args + argc) { }
|
||||
inline token_parser_t(int argc, const char **args, parser_source_location base_location) : parser_base_t(base_location), tokens(args, args + argc) { }
|
||||
|
||||
using state_type = decltype(std::tie(cur));
|
||||
|
||||
|
|
|
|||
|
|
@ -139,9 +139,6 @@ public:
|
|||
// copies value and source
|
||||
virtual bool copyFrom(const setting_base &other) = 0;
|
||||
|
||||
// convenience form of parse() that constructs a temporary parser_t
|
||||
bool parseString(const std::string &string, source source);
|
||||
|
||||
// resets value to default, and source to source::DEFAULT
|
||||
virtual void reset() = 0;
|
||||
virtual bool parse(const std::string &settingName, parser_base_t &parser, source source) = 0;
|
||||
|
|
@ -769,7 +766,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
parser_t p{value};
|
||||
parser_t p{value, { }};
|
||||
setting->parse(name, p, source);
|
||||
}
|
||||
|
||||
|
|
@ -846,7 +843,7 @@ public:
|
|||
// do the actual parsing
|
||||
virtual void initialize(int argc, const char **argv)
|
||||
{
|
||||
token_parser_t p(argc, argv);
|
||||
token_parser_t p(argc, argv, { "command line" });
|
||||
parse(p);
|
||||
}
|
||||
// after parsing has concluded, handle the side effects
|
||||
|
|
|
|||
|
|
@ -38,71 +38,13 @@
|
|||
|
||||
struct bspbrush_t;
|
||||
|
||||
// kind of a parallel to std::source_location in C++20
|
||||
// but this represents a location in a .map file where
|
||||
// something happens.
|
||||
struct map_source_location
|
||||
{
|
||||
// the source name of this location; may be a .map file path,
|
||||
// or some other string that describes where this location came
|
||||
// to be. note that because the locations only live for the lifetime
|
||||
// of the object it is belonging to, whatever this string
|
||||
// points to must out-live the object.
|
||||
std::shared_ptr<std::string> source_name = nullptr;
|
||||
|
||||
// the line number that this location is associated to, if any. Synthetic
|
||||
// locations may not necessarily have an associated line number.
|
||||
std::optional<size_t> line_number = std::nullopt;
|
||||
|
||||
// reference to a location of the object that derived us. this is mainly
|
||||
// for synthetic locations; ie a bspbrush_t's sides aren't themselves generated
|
||||
// by a source or line, but they are derived from a mapbrush_t which does have
|
||||
// a location. The object it points to must outlive this object. this is mainly
|
||||
// for debugging.
|
||||
std::optional<std::reference_wrapper<const map_source_location>> derivative = std::nullopt;
|
||||
|
||||
explicit operator bool() const { return source_name != nullptr; }
|
||||
|
||||
// return a modified source location with only the line changeed
|
||||
inline map_source_location on_line(size_t new_line) const
|
||||
{
|
||||
return { source_name, new_line, derivative };
|
||||
}
|
||||
|
||||
// if we update to C++20 we could use this to track where location objects come from:
|
||||
// std::source_location created_location;
|
||||
};
|
||||
|
||||
// FMT support
|
||||
template<>
|
||||
struct fmt::formatter<map_source_location>
|
||||
{
|
||||
constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { return ctx.end(); }
|
||||
|
||||
template<typename FormatContext>
|
||||
auto format(const map_source_location &v, FormatContext &ctx) -> decltype(ctx.out())
|
||||
{
|
||||
if (v.source_name) {
|
||||
format_to(ctx.out(), "{}", *v.source_name.get());
|
||||
} else {
|
||||
format_to(ctx.out(), "unknown/unset location");
|
||||
}
|
||||
|
||||
if (v.line_number.has_value()) {
|
||||
format_to(ctx.out(), "[line {}]", v.line_number.value());
|
||||
}
|
||||
|
||||
return ctx.out();
|
||||
}
|
||||
};
|
||||
|
||||
struct mapface_t
|
||||
{
|
||||
size_t planenum;
|
||||
std::array<qvec3d, 3> planepts{};
|
||||
std::string texname{};
|
||||
int texinfo = 0;
|
||||
map_source_location line;
|
||||
parser_source_location line;
|
||||
bool bevel = false;
|
||||
bool visible = false;
|
||||
winding_t winding; // winding used to calculate bevels
|
||||
|
|
@ -137,7 +79,7 @@ public:
|
|||
brushformat_t format = brushformat_t::NORMAL;
|
||||
aabb3d bounds {};
|
||||
std::optional<uint32_t> outputnumber; /* only set for original brushes */
|
||||
map_source_location line;
|
||||
parser_source_location line;
|
||||
};
|
||||
|
||||
struct lumpdata
|
||||
|
|
@ -185,6 +127,8 @@ public:
|
|||
|
||||
int32_t areaportalnum = 0;
|
||||
std::array<int32_t, 2> portalareas = {};
|
||||
|
||||
parser_source_location location;
|
||||
};
|
||||
|
||||
struct maptexdata_t
|
||||
|
|
@ -402,7 +346,7 @@ extern mapdata_t map;
|
|||
|
||||
void CalculateWorldExtent(void);
|
||||
|
||||
bool ParseEntity(parser_t &parser, mapentity_t *entity, const map_source_location &map_source);
|
||||
bool ParseEntity(parser_t &parser, mapentity_t *entity);
|
||||
|
||||
void ProcessExternalMapEntity(mapentity_t *entity);
|
||||
void ProcessAreaPortal(mapentity_t *entity);
|
||||
|
|
|
|||
|
|
@ -772,7 +772,10 @@ void LoadEntities(const settings::worldspawn_keys &cfg, const mbsp_t *bsp)
|
|||
{
|
||||
logging::funcheader();
|
||||
|
||||
entdicts = EntData_Parse(bsp->dentdata);
|
||||
{
|
||||
parser_t parser{bsp->dentdata, { bsp->file.string() }};
|
||||
entdicts = EntData_Parse(parser);
|
||||
}
|
||||
|
||||
// Make warnings
|
||||
for (auto &entdict : entdicts) {
|
||||
|
|
@ -1302,12 +1305,11 @@ static void GL_SubdivideSurface(const mface_t *face, const modelinfo_t *face_mod
|
|||
SubdividePolygon(face, face_modelinfo, bsp, face->numedges, verts, light_options.surflight_subdivide.value());
|
||||
}
|
||||
|
||||
static bool ParseEntityLights(std::ifstream &f)
|
||||
static bool ParseEntityLights(std::ifstream &f, const fs::path &fname)
|
||||
{
|
||||
std::string str{std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>()};
|
||||
parser_t p(str);
|
||||
|
||||
EntData_ParseInto(str, radlights);
|
||||
parser_t p(str, { fname.string() });
|
||||
EntData_ParseInto(p, radlights);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1320,14 +1322,14 @@ bool ParseLightsFile(const fs::path &fname)
|
|||
|
||||
// use entity-style format
|
||||
if (fname.extension() == ".ent") {
|
||||
return ParseEntityLights(f);
|
||||
return ParseEntityLights(f, fname);
|
||||
}
|
||||
|
||||
while (!f.eof()) {
|
||||
std::string buf;
|
||||
std::getline(f, buf);
|
||||
|
||||
parser_t parser(buf);
|
||||
parser_t parser(buf, { fname.string() });
|
||||
|
||||
if (!parser.parse_token())
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ setting_group experimental_group{"Experimental options", 60};
|
|||
|
||||
void light_settings::initialize(int argc, const char **argv)
|
||||
{
|
||||
token_parser_t p(argc - 1, argv + 1);
|
||||
token_parser_t p(argc - 1, argv + 1, { "command line" });
|
||||
auto remainder = parse(p);
|
||||
|
||||
if (remainder.size() <= 0 || remainder.size() > 1) {
|
||||
|
|
@ -1074,7 +1074,8 @@ static void LoadTextures(const mbsp_t *bsp)
|
|||
|
||||
// gather textures used by _project_texture.
|
||||
// FIXME: I'm sure we can resolve this so we don't parse entdata twice.
|
||||
auto entdicts = EntData_Parse(bsp->dentdata);
|
||||
parser_t parser{bsp->dentdata, { bsp->file.string() }};
|
||||
auto entdicts = EntData_Parse(parser);
|
||||
for (auto &entdict : entdicts) {
|
||||
if (entdict.get("classname").find("light") == 0) {
|
||||
const auto &tex = entdict.get("_project_texture");
|
||||
|
|
|
|||
|
|
@ -632,10 +632,10 @@ void bspbrush_t::update_bounds()
|
|||
for (size_t i = 0; i < 3; i++) {
|
||||
// todo: map_source_location in bspbrush_t
|
||||
if (this->bounds.mins()[0] <= -qbsp_options.worldextent.value() || this->bounds.maxs()[0] >= qbsp_options.worldextent.value()) {
|
||||
logging::print("WARNING: {}: brush bounds out of range\n", mapbrush ? mapbrush->line : map_source_location());
|
||||
logging::print("WARNING: {}: brush bounds out of range\n", mapbrush ? mapbrush->line : parser_source_location());
|
||||
}
|
||||
if (this->bounds.mins()[0] >= qbsp_options.worldextent.value() || this->bounds.maxs()[0] <= -qbsp_options.worldextent.value()) {
|
||||
logging::print("WARNING: {}: no visible sides on brush\n", mapbrush ? mapbrush->line : map_source_location());
|
||||
logging::print("WARNING: {}: no visible sides on brush\n", mapbrush ? mapbrush->line : parser_source_location());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
49
qbsp/map.cc
49
qbsp/map.cc
|
|
@ -1158,7 +1158,7 @@ static void SetTexinfo_QuArK(
|
|||
*/
|
||||
determinant = a * d - b * c;
|
||||
if (fabs(determinant) < ZERO_EPSILON) {
|
||||
logging::print("WARNING: line {}: Face with degenerate QuArK-style texture axes\n", parser.linenum);
|
||||
logging::print("WARNING: {}: Face with degenerate QuArK-style texture axes\n", parser.location);
|
||||
for (i = 0; i < 3; i++)
|
||||
out->vecs.at(0, i) = out->vecs.at(1, i) = 0;
|
||||
} else {
|
||||
|
|
@ -1317,7 +1317,7 @@ static void ParsePlaneDef(parser_t &parser, std::array<qvec3d, 3> &planepts)
|
|||
return;
|
||||
|
||||
parse_error:
|
||||
FError("line {}: Invalid brush plane format", parser.linenum);
|
||||
FError("{}: Invalid brush plane format", parser.location);
|
||||
}
|
||||
|
||||
static void ParseValve220TX(parser_t &parser, qmat<vec_t, 2, 3> &axis, qvec2d &shift, vec_t &rotate, qvec2d &scale)
|
||||
|
|
@ -1347,7 +1347,7 @@ static void ParseValve220TX(parser_t &parser, qmat<vec_t, 2, 3> &axis, qvec2d &s
|
|||
return;
|
||||
|
||||
parse_error:
|
||||
FError("line {}: couldn't parse Valve220 texture info", parser.linenum);
|
||||
FError("{}: couldn't parse Valve220 texture info", parser.location);
|
||||
}
|
||||
|
||||
static void ParseBrushPrimTX(parser_t &parser, qmat<vec_t, 2, 3> &texMat)
|
||||
|
|
@ -1378,7 +1378,7 @@ static void ParseBrushPrimTX(parser_t &parser, qmat<vec_t, 2, 3> &texMat)
|
|||
return;
|
||||
|
||||
parse_error:
|
||||
FError("line {}: couldn't parse Brush Primitives texture info", parser.linenum);
|
||||
FError("{}: couldn't parse Brush Primitives texture info", parser.location);
|
||||
}
|
||||
|
||||
static void ParseTextureDef(parser_t &parser, mapface_t &mapface, const mapbrush_t &brush, maptexinfo_t *tx,
|
||||
|
|
@ -1603,7 +1603,7 @@ static std::optional<mapface_t> ParseBrushFace(parser_t &parser, const mapbrush_
|
|||
int i, j;
|
||||
mapface_t face;
|
||||
|
||||
face.line = brush.line.on_line(parser.linenum);
|
||||
face.line = parser.location;
|
||||
|
||||
ParsePlaneDef(parser, planepts);
|
||||
|
||||
|
|
@ -1612,7 +1612,7 @@ static std::optional<mapface_t> ParseBrushFace(parser_t &parser, const mapbrush_
|
|||
ParseTextureDef(parser, face, brush, &tx, face.planepts, face.get_plane());
|
||||
|
||||
if (!normal_ok) {
|
||||
logging::print("WARNING: line {}: Brush plane with no normal\n", parser.linenum);
|
||||
logging::print("WARNING: {}: Brush plane with no normal\n", parser.location);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
|
@ -1790,13 +1790,13 @@ inline void AddBrushBevels(mapentity_t &e, mapbrush_t &b)
|
|||
}
|
||||
}
|
||||
|
||||
static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity, const map_source_location &entity_source)
|
||||
static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity)
|
||||
{
|
||||
mapbrush_t brush;
|
||||
|
||||
// ericw -- brush primitives
|
||||
if (!parser.parse_token(PARSE_PEEK))
|
||||
FError("{}: unexpected EOF after { beginning brush", entity_source);
|
||||
FError("{}: unexpected EOF after { beginning brush", parser.location);
|
||||
|
||||
if (parser.token == "(") {
|
||||
brush.format = brushformat_t::NORMAL;
|
||||
|
|
@ -1820,7 +1820,7 @@ static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity, const map_so
|
|||
|
||||
// set linenum after first parsed token
|
||||
if (!brush.line) {
|
||||
brush.line = entity_source.on_line(parser.linenum);
|
||||
brush.line = parser.location;
|
||||
}
|
||||
|
||||
if (parser.token == "}")
|
||||
|
|
@ -1836,13 +1836,13 @@ static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity, const map_so
|
|||
bool discardFace = false;
|
||||
for (auto &check : brush.faces) {
|
||||
if (qv::epsilonEqual(check.get_plane(), face->get_plane())) {
|
||||
logging::print("line {}: Brush with duplicate plane\n", parser.linenum);
|
||||
logging::print("line {}: Brush with duplicate plane\n", parser.location);
|
||||
discardFace = true;
|
||||
continue;
|
||||
}
|
||||
if (qv::epsilonEqual(-check.get_plane(), face->get_plane())) {
|
||||
/* FIXME - this is actually an invalid brush */
|
||||
logging::print("line {}: Brush with duplicate plane\n", parser.linenum);
|
||||
logging::print("line {}: Brush with duplicate plane\n", parser.location);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -1867,15 +1867,15 @@ static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity, const map_so
|
|||
return brush;
|
||||
}
|
||||
|
||||
bool ParseEntity(parser_t &parser, mapentity_t *entity, const map_source_location &map_source)
|
||||
bool ParseEntity(parser_t &parser, mapentity_t *entity)
|
||||
{
|
||||
entity->location = parser.location;
|
||||
|
||||
if (!parser.parse_token())
|
||||
return false;
|
||||
|
||||
map_source_location entity_source = map_source.on_line(parser.linenum);
|
||||
|
||||
if (parser.token != "{") {
|
||||
FError("{}: Invalid entity format, { not found", entity_source);
|
||||
FError("{}: Invalid entity format, { not found", parser.location);
|
||||
}
|
||||
|
||||
entity->mapbrushes.clear();
|
||||
|
|
@ -1889,7 +1889,7 @@ bool ParseEntity(parser_t &parser, mapentity_t *entity, const map_source_locatio
|
|||
// once we run into the first brush, set up textures state.
|
||||
EnsureTexturesLoaded();
|
||||
|
||||
entity->mapbrushes.emplace_back(ParseBrush(parser, *entity, entity_source));
|
||||
entity->mapbrushes.emplace_back(ParseBrush(parser, *entity));
|
||||
} else {
|
||||
ParseEpair(parser, entity);
|
||||
}
|
||||
|
|
@ -2010,11 +2010,10 @@ static mapentity_t LoadExternalMap(const std::string &filename)
|
|||
FError("Couldn't load external map file \"{}\".\n", filename);
|
||||
}
|
||||
|
||||
parser_t parser(file->data(), file->size());
|
||||
map_source_location entity_source { std::make_shared<std::string>(filename), parser.linenum };
|
||||
parser_t parser(file, { filename });
|
||||
|
||||
// parse the worldspawn
|
||||
if (!ParseEntity(parser, &dest, entity_source)) {
|
||||
if (!ParseEntity(parser, &dest)) {
|
||||
FError("'{}': Couldn't parse worldspawn entity\n", filename);
|
||||
}
|
||||
const std::string &classname = dest.epairs.get("classname");
|
||||
|
|
@ -2024,7 +2023,7 @@ static mapentity_t LoadExternalMap(const std::string &filename)
|
|||
|
||||
// parse any subsequent entities, move any brushes to worldspawn
|
||||
mapentity_t dummy{};
|
||||
while (ParseEntity(parser, &dummy, entity_source = entity_source.on_line(parser.linenum))) {
|
||||
while (ParseEntity(parser, &dummy)) {
|
||||
// move the brushes to the worldspawn
|
||||
dest.mapbrushes.insert(dest.mapbrushes.end(), std::make_move_iterator(dummy.mapbrushes.begin()), std::make_move_iterator(dummy.mapbrushes.end()));
|
||||
|
||||
|
|
@ -2355,13 +2354,12 @@ void LoadMapFile(void)
|
|||
return;
|
||||
}
|
||||
|
||||
parser_t parser(file->data(), file->size());
|
||||
map_source_location entity_source { std::make_shared<std::string>(qbsp_options.map_path.string()) };
|
||||
parser_t parser(file, { qbsp_options.map_path.string() });
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
mapentity_t &entity = map.entities.emplace_back();
|
||||
|
||||
if (!ParseEntity(parser, &entity, entity_source.on_line(parser.linenum))) {
|
||||
if (!ParseEntity(parser, &entity)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2381,13 +2379,12 @@ void LoadMapFile(void)
|
|||
return;
|
||||
}
|
||||
|
||||
parser_t parser(file->data(), file->size());
|
||||
map_source_location entity_source { std::make_shared<std::string>(qbsp_options.add.value()) };
|
||||
parser_t parser(file, { qbsp_options.add.value() });
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
mapentity_t &entity = map.entities.emplace_back();
|
||||
|
||||
if (!ParseEntity(parser, &entity, entity_source.on_line(parser.linenum))) {
|
||||
if (!ParseEntity(parser, &entity)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,12 +83,12 @@ void qbsp_settings::initialize(int argc, const char **argv)
|
|||
{
|
||||
if (auto file = fs::load("qbsp.ini")) {
|
||||
logging::print("Loading options from qbsp.ini\n");
|
||||
parser_t p(file->data(), file->size());
|
||||
parser_t p(file, { "qbsp.ini" });
|
||||
parse(p);
|
||||
}
|
||||
|
||||
try {
|
||||
token_parser_t p(argc - 1, argv + 1);
|
||||
token_parser_t p(argc - 1, argv + 1, { "command line" });
|
||||
auto remainder = parse(p);
|
||||
|
||||
if (remainder.size() <= 0 || remainder.size() > 2) {
|
||||
|
|
@ -113,7 +113,7 @@ void qbsp_settings::load_texture_def(const std::string &pathname)
|
|||
}
|
||||
|
||||
fs::data data = fs::load(pathname);
|
||||
parser_t parser(data);
|
||||
parser_t parser(data, { pathname });
|
||||
|
||||
while (true) {
|
||||
if (!parser.parse_token() || parser.at_end()) {
|
||||
|
|
@ -158,7 +158,7 @@ void qbsp_settings::load_entity_def(const std::string &pathname)
|
|||
}
|
||||
|
||||
fs::data data = fs::load(pathname);
|
||||
parser_t parser(data);
|
||||
parser_t parser(data, { pathname });
|
||||
|
||||
while (true) {
|
||||
if (!parser.parse_token() || parser.at_end()) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ TEST_CASE("booleanFlagImplicit", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_bool boolSetting(&settings, "locked", false);
|
||||
const char *arguments[] = {"qbsp.exe", "-locked"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(boolSetting.value() == true);
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ TEST_CASE("booleanFlagExplicit", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_bool boolSetting(&settings, "locked", false);
|
||||
const char *arguments[] = {"qbsp.exe", "-locked", "1"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(boolSetting.value() == true);
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ TEST_CASE("booleanFlagStray", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_bool boolSetting(&settings, "locked", false);
|
||||
const char *arguments[] = {"qbsp.exe", "-locked", "stray"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(boolSetting.value() == true);
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ TEST_CASE("scalarSimple", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_scalar scalarSetting(&settings, "scale", 1.0);
|
||||
const char *arguments[] = {"qbsp.exe", "-scale", "1.25"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(scalarSetting.value() == 1.25);
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ TEST_CASE("scalarNegative", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_scalar scalarSetting(&settings, "scale", 1.0);
|
||||
const char *arguments[] = {"qbsp.exe", "-scale", "-0.25"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(scalarSetting.value() == -0.25);
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ TEST_CASE("scalarInfinity", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_scalar scalarSetting(&settings, "scale", 1.0, 0.0, std::numeric_limits<vec_t>::infinity());
|
||||
const char *arguments[] = {"qbsp.exe", "-scale", "INFINITY"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(scalarSetting.value() == std::numeric_limits<vec_t>::infinity());
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ TEST_CASE("scalarNAN", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_scalar scalarSetting(&settings, "scale", 1.0);
|
||||
const char *arguments[] = {"qbsp.exe", "-scale", "NAN"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(std::isnan(scalarSetting.value()));
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ TEST_CASE("scalarScientific", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_scalar scalarSetting(&settings, "scale", 1.0);
|
||||
const char *arguments[] = {"qbsp.exe", "-scale", "1.54334E-34"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(scalarSetting.value() == 1.54334E-34);
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ TEST_CASE("scalarEOF", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_scalar scalarSetting(&settings, "scale", 1.0);
|
||||
const char *arguments[] = {"qbsp.exe", "-scale"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
REQUIRE_THROWS_AS(settings.parse(p), settings::parse_exception);
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ TEST_CASE("scalarStray", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_scalar scalarSetting(&settings, "scale", 1.0);
|
||||
const char *arguments[] = {"qbsp.exe", "-scale", "stray"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
REQUIRE_THROWS_AS(settings.parse(p), settings::parse_exception);
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ TEST_CASE("vec3Simple", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_vec3 scalarSetting(&settings, "origin", 0, 0, 0);
|
||||
const char *arguments[] = {"qbsp.exe", "-origin", "1", "2", "3"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(scalarSetting.value() == (qvec3d{1, 2, 3}));
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ TEST_CASE("vec3Complex", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_vec3 scalarSetting(&settings, "origin", 0, 0, 0);
|
||||
const char *arguments[] = {"qbsp.exe", "-origin", "-12.5", "-INFINITY", "NAN"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(scalarSetting.value()[0] == -12.5);
|
||||
REQUIRE(scalarSetting.value()[1] == -std::numeric_limits<vec_t>::infinity());
|
||||
|
|
@ -132,7 +132,7 @@ TEST_CASE("vec3Incomplete", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_vec3 scalarSetting(&settings, "origin", 0, 0, 0);
|
||||
const char *arguments[] = {"qbsp.exe", "-origin", "1", "2"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
REQUIRE_THROWS_AS(settings.parse(p), settings::parse_exception);
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ TEST_CASE("vec3Stray", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_vec3 scalarSetting(&settings, "origin", 0, 0, 0);
|
||||
const char *arguments[] = {"qbsp.exe", "-origin", "1", "2", "abc"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
REQUIRE_THROWS_AS(settings.parse(p), settings::parse_exception);
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ TEST_CASE("stringSimple", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_string stringSetting(&settings, "name", "");
|
||||
const char *arguments[] = {"qbsp.exe", "-name", "i am a string with spaces in it"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(stringSetting.value() == arguments[2]);
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ TEST_CASE("remainder", "[settings]")
|
|||
settings::setting_bool flagSetting(&settings, "flag", false);
|
||||
const char *arguments[] = {
|
||||
"qbsp.exe", "-name", "string", "-flag", "remainder one", "remainder two"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
auto remainder = settings.parse(p);
|
||||
REQUIRE(remainder[0] == "remainder one");
|
||||
REQUIRE(remainder[1] == "remainder two");
|
||||
|
|
@ -177,7 +177,7 @@ TEST_CASE("doubleHyphen", "[settings]")
|
|||
settings::setting_bool boolSetting(&settings, "locked", false);
|
||||
settings::setting_string stringSetting(&settings, "name", "");
|
||||
const char *arguments[] = {"qbsp.exe", "--locked", "--name", "my name!"};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1};
|
||||
token_parser_t p{std::size(arguments) - 1, arguments + 1, { }};
|
||||
settings.parse(p);
|
||||
REQUIRE(boolSetting.value() == true);
|
||||
REQUIRE(stringSetting.value() == "my name!");
|
||||
|
|
@ -233,7 +233,7 @@ TEST_CASE("copyMangle", "[settings]")
|
|||
settings::setting_container settings;
|
||||
settings::setting_mangle sunvec{&settings, {"sunlight_mangle"}, 0.0, 0.0, 0.0};
|
||||
|
||||
parser_t p(std::string_view("0.0 -90.0 0.0"));
|
||||
parser_t p(std::string_view("0.0 -90.0 0.0"), { });
|
||||
CHECK(sunvec.parse("", p, settings::source::COMMANDLINE));
|
||||
CHECK(Catch::Approx(0).margin(1e-6) == sunvec.value()[0]);
|
||||
CHECK(Catch::Approx(0).margin(1e-6) == sunvec.value()[1]);
|
||||
|
|
|
|||
|
|
@ -933,14 +933,16 @@ TEST_CASE("delayDefault", "[settings]")
|
|||
TEST_CASE("delayParseInt", "[settings]")
|
||||
{
|
||||
light_t light;
|
||||
CHECK(light.formula.parseString("2", settings::source::MAP));
|
||||
parser_t p("2", { });
|
||||
CHECK(light.formula.parse(light.formula.primaryName(), p, settings::source::MAP));
|
||||
CHECK(LF_INVERSE2 == light.formula.value());
|
||||
}
|
||||
|
||||
TEST_CASE("delayParseIntUnknown", "[settings]")
|
||||
{
|
||||
light_t light;
|
||||
CHECK(light.formula.parseString("500", settings::source::MAP));
|
||||
parser_t p("500", { });
|
||||
CHECK(light.formula.parse(light.formula.primaryName(), p, settings::source::MAP));
|
||||
// not sure if we should be strict and reject parsing this?
|
||||
CHECK(500 == light.formula.value());
|
||||
}
|
||||
|
|
@ -948,13 +950,15 @@ TEST_CASE("delayParseIntUnknown", "[settings]")
|
|||
TEST_CASE("delayParseFloat", "[settings]")
|
||||
{
|
||||
light_t light;
|
||||
CHECK(light.formula.parseString("2.0", settings::source::MAP));
|
||||
parser_t p("2.0", { });
|
||||
CHECK(light.formula.parse(light.formula.primaryName(), p, settings::source::MAP));
|
||||
CHECK(LF_INVERSE2 == light.formula.value());
|
||||
}
|
||||
|
||||
TEST_CASE("delayParseString", "[settings]")
|
||||
{
|
||||
light_t light;
|
||||
CHECK(light.formula.parseString("inverse2", settings::source::MAP));
|
||||
parser_t p("inverse2", { });
|
||||
CHECK(light.formula.parse(light.formula.primaryName(), p, settings::source::MAP));
|
||||
CHECK(LF_INVERSE2 == light.formula.value());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,17 +39,15 @@ static mapentity_t LoadMap(const char *map)
|
|||
|
||||
::map.entities.clear();
|
||||
|
||||
parser_t parser(map);
|
||||
parser_t parser(map, { Catch::getResultCapture().getCurrentTestName() });
|
||||
|
||||
// FIXME: ???
|
||||
mapentity_t &entity = ::map.entities.emplace_back();
|
||||
|
||||
map_source_location entity_source { std::make_shared<std::string>(Catch::getResultCapture().getCurrentTestName()), 0 };
|
||||
|
||||
mapentity_t worldspawn;
|
||||
|
||||
// FIXME: adds the brush to the global map...
|
||||
Q_assert(ParseEntity(parser, &worldspawn, entity_source));
|
||||
Q_assert(ParseEntity(parser, &worldspawn));
|
||||
|
||||
CalculateWorldExtent();
|
||||
|
||||
|
|
@ -1048,7 +1046,8 @@ TEST_CASE("origin", "[testmaps_q1]")
|
|||
REQUIRE(qvec3f(0, 0, 0) == bsp.dmodels[1].origin);
|
||||
|
||||
// check that the origin brush updated the entity lump
|
||||
auto ents = EntData_Parse(bsp.dentdata);
|
||||
parser_t parser(bsp.dentdata, { "qbsp_origin.bsp" });
|
||||
auto ents = EntData_Parse(parser);
|
||||
auto it = std::find_if(ents.begin(), ents.end(),
|
||||
[](const entdict_t &dict) -> bool { return dict.get("classname") == "rotate_object"; });
|
||||
|
||||
|
|
@ -1392,7 +1391,8 @@ TEST_CASE("areaportal", "[testmaps_q2]")
|
|||
CHECK(0 == void_leaf->area); // a solid leaf gets the invalid area
|
||||
|
||||
// check the func_areaportal entity had its "style" set
|
||||
auto ents = EntData_Parse(bsp.dentdata);
|
||||
parser_t parser(bsp.dentdata, { "qbsp_q2_areaportal.bsp" });
|
||||
auto ents = EntData_Parse(parser);
|
||||
auto it = std::find_if(ents.begin(), ents.end(),
|
||||
[](const entdict_t &dict) { return dict.get("classname") == "func_areaportal"; });
|
||||
|
||||
|
|
@ -1779,7 +1779,8 @@ TEST_CASE("q1_merge_maps", "[testmaps_q1]") {
|
|||
REQUIRE(BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], {-5,0,16}, {0, 0, 1}));
|
||||
|
||||
// check that the worldspawn keys from the base map are used
|
||||
auto ents = EntData_Parse(bsp.dentdata);
|
||||
parser_t parser(bsp.dentdata, { "q1_merge_maps_base.bsp" });
|
||||
auto ents = EntData_Parse(parser);
|
||||
REQUIRE(ents.size() == 3); // worldspawn, info_player_start, func_wall
|
||||
|
||||
REQUIRE(ents[0].get("classname") == "worldspawn");
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ setting_group advanced_group{"Advanced", 300};
|
|||
|
||||
void vis_settings::initialize(int argc, const char **argv)
|
||||
{
|
||||
token_parser_t p(argc - 1, argv + 1);
|
||||
token_parser_t p(argc - 1, argv + 1, { "command line" });
|
||||
auto remainder = parse(p);
|
||||
|
||||
if (remainder.size() <= 0 || remainder.size() > 1) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue