aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMartin Kiewitz2010-05-19 13:32:27 +0000
committerMartin Kiewitz2010-05-19 13:32:27 +0000
commitbb10dabe904605505ab1dfb2cb46ed61e4d2d67e (patch)
tree90aec271d0c0e2e129a5e3a23d7f8815fd834145 /engines
parent15c533d2c2b1464f2d55d3f6c48a9e21c85a2e7f (diff)
downloadscummvm-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.cpp180
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;
}
}