From 75def2b4808fae0aef52bb5ba165a9d10936dd05 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 10 Nov 2019 20:38:23 -0800 Subject: GLK: ARCHETYPE: Fixes to correctly parse multi-word inputs --- engines/glk/archetype/archetype.cpp | 6 +++--- engines/glk/archetype/parser.cpp | 22 ++++++++++++---------- engines/glk/archetype/string.cpp | 8 ++++++++ engines/glk/archetype/string.h | 5 +++++ 4 files changed, 28 insertions(+), 13 deletions(-) (limited to 'engines') diff --git a/engines/glk/archetype/archetype.cpp b/engines/glk/archetype/archetype.cpp index f10fa06f0b..cf22afc4db 100644 --- a/engines/glk/archetype/archetype.cpp +++ b/engines/glk/archetype/archetype.cpp @@ -274,7 +274,7 @@ void Archetype::lookup(int the_obj, int the_attr, ResultType &result, ContextTyp } } -static int scummvm = 0; +static int messageCtr = 0; bool Archetype::send_message(int transport, int message_sent, int recipient, ResultType &result, ContextType &context) { @@ -292,8 +292,8 @@ bool Archetype::send_message(int transport, int message_sent, int recipient, } if (DebugMan.isDebugChannelEnabled(DEBUG_MSGS)) { - ++scummvm; - //debugN(String::format("%d ", scummvm).c_str()); + ++messageCtr; + //debugN(String::format("%d ", messageCtr).c_str()); r._kind = IDENT; r._data._ident.ident_kind = OBJECT_ID; diff --git a/engines/glk/archetype/parser.cpp b/engines/glk/archetype/parser.cpp index 0d2dcbbda4..49cd8f14be 100644 --- a/engines/glk/archetype/parser.cpp +++ b/engines/glk/archetype/parser.cpp @@ -131,8 +131,8 @@ static void parse_sentence_substitute(int start, ParsePtr pp, int &next_starting // WORKAROUND: Original encoded object number as two bytes. ScummVM strings don't like // 0 bytes in the middle of the string, so we encode it as plain text g_vm->Command = g_vm->Command.left(start) - + String::format("%%%d^", pp->object) - + String(g_vm->Command.c_str() + start + sublen + 1); + + String::format(" %%%d^", pp->object) + + g_vm->Command.mid(start + sublen + 1); next_starting = next_starting - sublen + 4; } @@ -140,7 +140,7 @@ static void parse_sentence_substitute(int start, ParsePtr pp, int &next_starting static bool parse_sentence_next_chunk(int &start_at, String &the_chunk, int &next_starting) { int i; - if (next_starting == 0) { + if (next_starting == -1) { return false; } else { do { @@ -149,14 +149,16 @@ static bool parse_sentence_next_chunk(int &start_at, String &the_chunk, int &nex i = the_chunk.indexOf('%'); if (i == -1) { - next_starting = 0; + next_starting = -1; } else { - the_chunk = the_chunk.left(i - 1); - next_starting = next_starting + i + 3; + next_starting = the_chunk.indexOf("^", i) + 1; + assert(next_starting != 0); + + the_chunk = the_chunk.left(i); } the_chunk.trim(); - } while (!(next_starting == 0 || !the_chunk.empty())); + } while (!(next_starting == -1 || !the_chunk.empty())); return !the_chunk.empty(); } @@ -197,10 +199,10 @@ void parse_sentence() { // Second pass: carefully search for the remaining string chunks; search only the part // of the noun list of the same length; give preference to those in the Proximate list - next_starting = 1; + next_starting = 0; while (parse_sentence_next_chunk(i, s, next_starting)) { - lchunk = s.size() - 1; + lchunk = s.size(); np = find_item(g_vm->object_names, lchunk); if (np != nullptr) { @@ -215,7 +217,7 @@ void parse_sentence() { else far_match = np; } - } while (!(iterate_list(g_vm->object_names, np) && (lchunk == (int)((ParsePtr)np->data)->word->size()))); + } while (iterate_list(g_vm->object_names, np) && (lchunk = (int)((ParsePtr)np->data)->word->size()) != 0); if (near_match != nullptr) parse_sentence_substitute(i, (ParsePtr)near_match->data, next_starting); diff --git a/engines/glk/archetype/string.cpp b/engines/glk/archetype/string.cpp index 9295ced210..d20a1c9487 100644 --- a/engines/glk/archetype/string.cpp +++ b/engines/glk/archetype/string.cpp @@ -36,6 +36,11 @@ int String::indexOf(const String &substr) const { return c ? c - c_str() : -1; } +int String::indexOf(const String &substr, int start) const { + const char *c = strstr(c_str() + start, substr.c_str()); + return c ? c - c_str() : -1; +} + int String::lastIndexOf(char c) const { for (int i = (int)size() - 1; i >= 0; --i) { if (operator[](i) == c) @@ -49,6 +54,9 @@ void String::trim() { while (!empty() && (lastChar() == ' ' || lastChar() == '\t' || lastChar() == '\n' || lastChar() == '\r')) deleteLastChar(); + + while (hasPrefix(" ") || hasPrefix("\t") || hasPrefix("\n")) + deleteChar(0); } String operator+(const String &x, const String &y) { diff --git a/engines/glk/archetype/string.h b/engines/glk/archetype/string.h index f85ed37d1a..5afa4d6037 100644 --- a/engines/glk/archetype/string.h +++ b/engines/glk/archetype/string.h @@ -76,6 +76,11 @@ public: */ int indexOf(const String &substr) const; + /** + * Returns the index of a substring within this string starting at a given index + */ + int indexOf(const String &substr, int start) const; + /** * Returns the last index of a character in a string, or -1 if it isn't present */ -- cgit v1.2.3