mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Reader now warns about invalid UTF-8 files;
Fixed possible hang when reading multiline strings with incorrect indentation; Warnings from reading are shown also in NewSetWindow; Script parse errors get reported with the correct line number; Added support for showing multiple choice fields as a single image; Added 'line_below' to ChoiceField::Choice, for putting a line below menu items. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@420 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <data/game.hpp>
|
||||
#include <data/field/text.hpp>
|
||||
#include <data/field/choice.hpp>
|
||||
#include <data/field/multiple_choice.hpp>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(FieldP);
|
||||
DECLARE_TYPEOF_COLLECTION(TextValue*);
|
||||
@@ -140,7 +141,7 @@ SCRIPT_FUNCTION(primary_choice) {
|
||||
SCRIPT_PARAM(ValueP,input);
|
||||
ChoiceValueP value = dynamic_pointer_cast<ChoiceValue>(input);
|
||||
if (!value) {
|
||||
throw ScriptError(_("Argument to 'primary_choice' should be a choice field"));
|
||||
throw ScriptError(_("Argument to 'primary_choice' should be a choice value"));
|
||||
}
|
||||
// determine choice
|
||||
int id = value->field().choices->choiceId(value->value);
|
||||
@@ -154,10 +155,46 @@ SCRIPT_FUNCTION(primary_choice) {
|
||||
SCRIPT_RETURN(_(""));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Multiple choice values
|
||||
|
||||
// is the given choice active?
|
||||
SCRIPT_FUNCTION(chosen) {
|
||||
SCRIPT_PARAM(String,choice);
|
||||
SCRIPT_PARAM(String,input);
|
||||
for (size_t pos = 0 ; pos < input.size() ; ) {
|
||||
if (input.GetChar(pos) == _(' ')) {
|
||||
++pos; // ingore whitespace
|
||||
} else {
|
||||
// does this choice match the one asked about?
|
||||
size_t end = input.find_first_of(_(','), pos);
|
||||
if (end == String::npos) end = input.size();
|
||||
if (end - pos == choice.size() && is_substr(input, pos, choice)) {
|
||||
SCRIPT_RETURN(true);
|
||||
}
|
||||
pos = end + 1;
|
||||
}
|
||||
}
|
||||
SCRIPT_RETURN(false);
|
||||
}
|
||||
|
||||
// add the given choice if it is not already active
|
||||
SCRIPT_FUNCTION(require_choice) {
|
||||
SCRIPT_PARAM(ValueP,input);
|
||||
MultipleChoiceValueP value = dynamic_pointer_cast<MultipleChoiceValue>(input);
|
||||
if (!value) {
|
||||
throw ScriptError(_("Argument 'input' to 'require_choice' should be a multiple choice value"));
|
||||
}
|
||||
SCRIPT_PARAM(String,choice);
|
||||
// TODO
|
||||
SCRIPT_RETURN(input);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Init
|
||||
|
||||
void init_script_editor_functions(Context& ctx) {
|
||||
ctx.setVariable(_("forward editor"), script_combined_editor); // combatability
|
||||
ctx.setVariable(_("combined editor"), script_combined_editor);
|
||||
ctx.setVariable(_("primary choice"), script_primary_choice);
|
||||
ctx.setVariable(_("chosen"), script_chosen);
|
||||
ctx.setVariable(_("require choice"), script_require_choice);
|
||||
}
|
||||
|
||||
@@ -567,7 +567,7 @@ void parseOper(TokenIterator& input, Script& script, Precedence minPrec, Instruc
|
||||
t = input.peek();
|
||||
}
|
||||
}
|
||||
input.read(); // skip the )
|
||||
expectToken(input, _(")"));
|
||||
// generate instruction
|
||||
script.addInstruction(I_CALL, (unsigned int)arguments.size());
|
||||
FOR_EACH(arg,arguments) {
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
Alignment from_string(const String&);
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(ScriptParseError);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Store
|
||||
|
||||
void store(const ScriptValueP& val, String& var) { var = val->toString(); }
|
||||
@@ -43,10 +45,16 @@ ScriptValueP OptionalScript::invoke(Context& ctx, bool open_scope) const {
|
||||
}
|
||||
|
||||
void OptionalScript::parse(Reader& reader, bool string_mode) {
|
||||
try {
|
||||
script = ::parse(unparsed, string_mode);
|
||||
} catch (const ParseError& e) {
|
||||
reader.warning(e.what());
|
||||
vector<ScriptParseError> errors;
|
||||
script = ::parse(unparsed, string_mode, errors);
|
||||
// show parse errors as warnings
|
||||
FOR_EACH(e, errors) {
|
||||
// find line number
|
||||
int line = 0;
|
||||
for (size_t i = 0 ; i < unparsed.size() && i < e.start ; ++i) {
|
||||
if (unparsed.GetChar(i) == _('\n')) line++;
|
||||
}
|
||||
reader.warning(e.ParseError::what(), line); // use ParseError::what because we don't want e.start in the error message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ void Reader::handle(Scriptable<T>& s) {
|
||||
} else if (s.script.unparsed.find_first_of('{') != String::npos) {
|
||||
s.script.parse(*this, true);
|
||||
} else {
|
||||
unhandle();
|
||||
handle(s.value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user