GP-4847: Unify Debugger param dialogs. Prefixed integers allowed.

This commit is contained in:
Dan
2024-09-05 12:35:28 -04:00
parent e0bf7b4c53
commit 16ff4c4d08
36 changed files with 2842 additions and 1509 deletions

View File

@@ -33,6 +33,8 @@ public final class NumericUtilities {
private final static String HEX_PREFIX_X = "0X";
private final static String HEX_PREFIX_x = "0x";
private final static String BIN_PREFIX = "0B";
private final static String OCT_PREFIX = "0";
private final static Set<Class<? extends Number>> INTEGER_TYPES = new HashSet<>();
static {
@@ -235,6 +237,49 @@ public final class NumericUtilities {
return new BigInteger(s, 16);
}
private static BigInteger decodeMagnitude(int p, String s) {
// Special case, so it doesn't get chewed by octal parser
if ("0".equals(s)) {
return BigInteger.ZERO;
}
if (s.regionMatches(true, p, HEX_PREFIX_X, 0, HEX_PREFIX_X.length())) {
return new BigInteger(s.substring(p + HEX_PREFIX_X.length()), 16);
}
if (s.regionMatches(true, p, BIN_PREFIX, 0, BIN_PREFIX.length())) {
return new BigInteger(s.substring(p + BIN_PREFIX.length()), 2);
}
// Check last, because prefix is shortest.
if (s.regionMatches(true, p, OCT_PREFIX, 0, OCT_PREFIX.length())) {
return new BigInteger(s.substring(p + OCT_PREFIX.length()), 8);
}
return new BigInteger(s.substring(p), 10);
}
/**
* Decode a big integer in hex, binary, octal, or decimal, based on the prefix 0x, 0b, or 0.
*
* <p>
* This checks for the presence of a case-insensitive prefix. 0x denotes hex, 0b denotes binary,
* 0 denotes octal. If no prefix is given, decimal is assumed. A sign +/- may immediately
* precede the prefix. If no sign is given, a positive value is assumed.
*
* @param s the string to parse
* @return the decoded value
*/
public static BigInteger decodeBigInteger(String s) {
int p = 0;
boolean negative = false;
if (s.startsWith("+")) {
p = 1;
}
else if (s.startsWith("-")) {
p = 1;
negative = true;
}
BigInteger mag = decodeMagnitude(p, s);
return negative ? mag.negate() : mag;
}
/**
* returns the value of the specified long as hexadecimal, prefixing with the
* {@link #HEX_PREFIX_x} string.

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,6 +18,7 @@ package ghidra.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;
@@ -332,4 +333,89 @@ public class NumericUtilitiesTest {
assertEquals(errorMessage, expected[i], actual[i]);
}
}
@Test
public void testDecodeBigInteger() {
// Zero special cases
assertEquals(BigInteger.ZERO, NumericUtilities.decodeBigInteger("0"));
assertEquals(BigInteger.ZERO, NumericUtilities.decodeBigInteger("000"));
// Decimal
assertEquals(BigInteger.valueOf(99), NumericUtilities.decodeBigInteger("99"));
assertEquals(BigInteger.valueOf(99), NumericUtilities.decodeBigInteger("+99"));
assertEquals(BigInteger.valueOf(-99), NumericUtilities.decodeBigInteger("-99"));
// Hex
assertEquals(BigInteger.valueOf(0x99), NumericUtilities.decodeBigInteger("0x99"));
assertEquals(BigInteger.valueOf(0x99), NumericUtilities.decodeBigInteger("+0x99"));
assertEquals(BigInteger.valueOf(-0x99), NumericUtilities.decodeBigInteger("-0x99"));
// Binary
assertEquals(BigInteger.valueOf(0b110), NumericUtilities.decodeBigInteger("0b110"));
assertEquals(BigInteger.valueOf(0b110), NumericUtilities.decodeBigInteger("+0b110"));
assertEquals(BigInteger.valueOf(-0b110), NumericUtilities.decodeBigInteger("-0b110"));
// Octal
assertEquals(BigInteger.valueOf(0755), NumericUtilities.decodeBigInteger("0755"));
assertEquals(BigInteger.valueOf(0755), NumericUtilities.decodeBigInteger("+0755"));
assertEquals(BigInteger.valueOf(-0755), NumericUtilities.decodeBigInteger("-0755"));
// Errors
try {
NumericUtilities.decodeBigInteger("");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("+");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("-");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("0x");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("0b");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("a01");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("081");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("0x9g");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger(" 10");
fail();
}
catch (NumberFormatException e) {
}
try {
NumericUtilities.decodeBigInteger("10 ");
fail();
}
catch (NumberFormatException e) {
}
}
}