diff options
author | Martin Kiewitz | 2010-05-19 13:32:27 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-05-19 13:32:27 +0000 |
commit | bb10dabe904605505ab1dfb2cb46ed61e4d2d67e (patch) | |
tree | 90aec271d0c0e2e129a5e3a23d7f8815fd834145 /engines | |
parent | 15c533d2c2b1464f2d55d3f6c48a9e21c85a2e7f (diff) | |
download | scummvm-rg350-bb10dabe904605505ab1dfb2cb46ed61e4d2d67e.tar.gz scummvm-rg350-bb10dabe904605505ab1dfb2cb46ed61e4d2d67e.tar.bz2 scummvm-rg350-bb10dabe904605505ab1dfb2cb46ed61e4d2d67e.zip |
SCI: changing debugger commands to not require "?"-prefix for objects anymore. It's now also possible to use 0x prefix for hexadecimal values e.g. "vo 0x13", "vo 13h", "vo theSound", "vo 12f:34f" is now possible
svn-id: r49097
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/console.cpp | 180 |
1 files changed, 125 insertions, 55 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 7a83d6a261..16bc69115f 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -2769,74 +2769,144 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV // Finally, after the colon comes the offset offsetStr = colon + 1; - } else if (*str == '?') { // Object by name: "?OBJ" or "?OBJ.INDEX" or "?OBJ.INDEX+OFFSET" or "?OBJ.INDEX-OFFSET" - // The (optional) index can be used to distinguish multiple object with the same name. - int index = -1; - // Skip over the leading question mark '?' - str++; - - // Look for an offset. It starts with + or - - relativeOffset = true; - offsetStr = strchr(str, '+'); - if (!offsetStr) // No + found, look for - - offsetStr = strchr(str, '-'); - - // Strip away the offset and the leading '?' - Common::String str_objname; - if (offsetStr) - str_objname = Common::String(str, offsetStr); - else - str_objname = str; + } else { + // Now we either got an object name, or segment:offset or plain value + // segment:offset is recognized by the ":" + // plain value may be "123" or "123h" or "fffh" or "0xfff" + // object name is assumed if nothing else matches or a "?" is used as prefix as override + // object name may contain "+", "-" and "." for relative calculations, those chars are used nowhere else + + // First we cycle through the string counting special chars + const char *strLoop = str; + int charsCount = strlen(str); + int charsCountObject = 0; + int charsCountSegmentOffset = 0; + int charsCountLetter = 0; + int charsCountNumber = 0; + bool charsForceHex = false; + bool charsForceObject = false; + + while (*strLoop) { + switch (*strLoop) { + case '+': + case '-': + case '.': + charsCountObject++; + break; + case '?': + if (strLoop == str) { + charsForceObject = true; + str++; // skip over prefix + } + break; + case ':': + charsCountSegmentOffset++; + break; + case 'h': + if (*(strLoop + 1) == 0) + charsForceHex = true; + else + charsCountObject++; + break; + case '0': + if (*(strLoop + 1) == 'x') { + str += 2; // skip "0x" + strLoop++; // skip "x" + charsForceHex = true; + } + charsCountNumber++; + break; + default: + if ((*strLoop >= '0') && (*strLoop <= '9')) + charsCountNumber++; + if ((*strLoop >= 'a') && (*strLoop <= 'f')) + charsCountLetter++; + if ((*strLoop >= 'A') && (*strLoop <= 'F')) + charsCountLetter++; + if ((*strLoop >= 'i') && (*strLoop <= 'z')) + charsCountObject++; + if ((*strLoop >= 'I') && (*strLoop <= 'Z')) + charsCountObject++; + } + strLoop++; + } + if ((charsCountObject) && (charsCountSegmentOffset)) + return 1; // input doesn't make sense - // Scan for a period, after which (if present) we'll find an index - const char *tmp = Common::find(str_objname.begin(), str_objname.end(), '.'); - if (tmp != str_objname.end()) { - index = strtol(tmp + 1, &endptr, 16); - if (*endptr) - return -1; - // Chop of the index - str_objname = Common::String(str_objname.c_str(), tmp); - } + if (!charsForceObject) { + // input may be values/segment:offset - // Now all values are available; iterate over all objects. + if (charsCountSegmentOffset) { + // ':' found, so must be segment:offset + const char *colon = strchr(str, ':'); - *dest = s->_segMan->findObjectByName(str_objname, index); - if (dest->isNull()) - return 1; + offsetStr = colon + 1; - } else { // Finally, check for "SEGMENT:OFFSET" or just "OFFSET" - const char *colon = strchr(str, ':'); + Common::String segmentStr(str, colon); + dest->segment = strtol(segmentStr.c_str(), &endptr, 16); + if (*endptr) + return 1; + } else { + int val = 0; + dest->segment = 0; - if (!colon) { - // No segment specified - if (mayBeValue) { - // We assume that this is not an offset, but a straight (decimal) value - int val; - int length = strlen(str); - const char *lastchar = str + length - (length ? 1 : 0); - if (*lastchar != 'h') { + if (charsCountNumber == charsCount) { + // Only numbers in input, assume decimal value val = strtol(str, &endptr, 10); if (*endptr) - return 1; + return 1; // strtol failed? + dest->offset = val; + return 0; } else { - val = strtol(str, &endptr, 16); - if (endptr != lastchar) - return 1; + // We also got letters, check if there were only hexadecimal letters and '0x' at the start or 'h' at the end + if ((charsForceHex) && (!charsCountObject)) { + val = strtol(str, &endptr, 16); + if ((*endptr != 'h') && (*endptr != 0)) + return 1; + dest->offset = val; + return 0; + } else { + // Something else was in input, assume object name + charsForceObject = true; + } } - dest->offset = val; - } else { - // We require an address, so interpret it as an offset (hexadecimal) - offsetStr = str; } - dest->segment = 0; - } else { - offsetStr = colon + 1; + } + + if (charsForceObject) { + // We assume now that input is object name + // Object by name: "?OBJ" or "?OBJ.INDEX" or "?OBJ.INDEX+OFFSET" or "?OBJ.INDEX-OFFSET" + // The (optional) index can be used to distinguish multiple object with the same name. + int index = -1; + + // Look for an offset. It starts with + or - + relativeOffset = true; + offsetStr = strchr(str, '+'); + if (!offsetStr) // No + found, look for - + offsetStr = strchr(str, '-'); + + // Strip away the offset and the leading '?' + Common::String str_objname; + if (offsetStr) + str_objname = Common::String(str, offsetStr); + else + str_objname = str; + + // Scan for a period, after which (if present) we'll find an index + const char *tmp = Common::find(str_objname.begin(), str_objname.end(), '.'); + if (tmp != str_objname.end()) { + index = strtol(tmp + 1, &endptr, 16); + if (*endptr) + return -1; + // Chop of the index + str_objname = Common::String(str_objname.c_str(), tmp); + } - Common::String segmentStr(str, colon); - dest->segment = strtol(segmentStr.c_str(), &endptr, 16); - if (*endptr) + // Now all values are available; iterate over all objects. + *dest = s->_segMan->findObjectByName(str_objname, index); + if (dest->isNull()) return 1; } } |