mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 12:00:04 +02:00
Fix #1680 by adding a comment field in the enum editor
This commit is contained in:
parent
156ce7ef80
commit
7398d26e84
10 changed files with 175 additions and 36 deletions
|
@ -2506,7 +2506,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
long enumID = record.getKey();
|
||||
String[] enumNames = enumm.getNames();
|
||||
for (String enumName : enumNames) {
|
||||
enumValueAdapter.createRecord(enumID, enumName, enumm.getValue(enumName));
|
||||
enumValueAdapter.createRecord(enumID, enumName, enumm.getValue(enumName), enumm.getComment(enumName));
|
||||
}
|
||||
EnumDB enumDB = new EnumDB(this, dtCache, enumAdapter, enumValueAdapter, record);
|
||||
return enumDB;
|
||||
|
|
|
@ -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.
|
||||
|
@ -44,6 +44,7 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
private EnumValueDBAdapter valueAdapter;
|
||||
private Map<String, Long> nameMap; // name to value
|
||||
private Map<Long, List<String>> valueMap; // value to names
|
||||
private Map<String, String> commentMap; // name to comment
|
||||
private List<BitGroup> bitGroups;
|
||||
|
||||
EnumDB(DataTypeManagerDB dataMgr, DBObjectCache<DataTypeDB> cache, EnumDBAdapter adapter,
|
||||
|
@ -84,6 +85,7 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
bitGroups = null;
|
||||
nameMap = new HashMap<>();
|
||||
valueMap = new HashMap<>();
|
||||
commentMap = new HashMap<>();
|
||||
|
||||
Field[] ids = valueAdapter.getValueIdsInEnum(key);
|
||||
|
||||
|
@ -91,14 +93,16 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
DBRecord rec = valueAdapter.getRecord(id.getLongValue());
|
||||
String valueName = rec.getString(EnumValueDBAdapter.ENUMVAL_NAME_COL);
|
||||
long value = rec.getLongValue(EnumValueDBAdapter.ENUMVAL_VALUE_COL);
|
||||
addToCache(valueName, value);
|
||||
String valueNameComment = rec.getString(EnumValueDBAdapter.ENUMVAL_COMMENT_COL);
|
||||
addToCache(valueName, value, valueNameComment);
|
||||
}
|
||||
}
|
||||
|
||||
private void addToCache(String valueName, long value) {
|
||||
private void addToCache(String valueName, long value, String valueNameComment) {
|
||||
nameMap.put(valueName, value);
|
||||
List<String> list = valueMap.computeIfAbsent(value, v -> new ArrayList<>());
|
||||
list.add(valueName);
|
||||
commentMap.put(valueName, valueNameComment);
|
||||
}
|
||||
|
||||
private boolean removeFromCache(String valueName) {
|
||||
|
@ -117,6 +121,10 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
if (list.isEmpty()) {
|
||||
valueMap.remove(value);
|
||||
}
|
||||
String comment = commentMap.remove(valueName);
|
||||
if (comment == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -159,6 +167,23 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComment(String valueName) throws NoSuchElementException {
|
||||
lock.acquire();
|
||||
try {
|
||||
checkIsValid();
|
||||
initializeIfNeeded();
|
||||
String comment = commentMap.get(valueName);
|
||||
if (comment == null) {
|
||||
comment = "";
|
||||
}
|
||||
return comment;
|
||||
}
|
||||
finally {
|
||||
lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getValues() {
|
||||
lock.acquire();
|
||||
|
@ -189,6 +214,19 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getComments() {
|
||||
lock.acquire();
|
||||
try {
|
||||
checkIsValid();
|
||||
initializeIfNeeded();
|
||||
return commentMap.keySet().toArray(new String[commentMap.size()]);
|
||||
}
|
||||
finally {
|
||||
lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
lock.acquire();
|
||||
|
@ -204,6 +242,12 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
|
||||
@Override
|
||||
public void add(String valueName, long value) {
|
||||
String valueNameComment = "";
|
||||
add(valueName, value, valueNameComment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(String valueName, long value, String valueNameComment) {
|
||||
lock.acquire();
|
||||
try {
|
||||
checkDeleted();
|
||||
|
@ -213,11 +257,10 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
throw new IllegalArgumentException(valueName + " already exists in this enum");
|
||||
}
|
||||
bitGroups = null;
|
||||
valueAdapter.createRecord(key, valueName, value);
|
||||
valueAdapter.createRecord(key, valueName, value, valueNameComment);
|
||||
adapter.updateRecord(record, true);
|
||||
addToCache(valueName, value);
|
||||
addToCache(valueName, value, valueNameComment);
|
||||
dataMgr.dataTypeChanged(this, false);
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
dataMgr.dbError(e);
|
||||
|
@ -286,6 +329,7 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
bitGroups = null;
|
||||
nameMap = new HashMap<>();
|
||||
valueMap = new HashMap<>();
|
||||
commentMap = new HashMap<>();
|
||||
|
||||
Field[] ids = valueAdapter.getValueIdsInEnum(key);
|
||||
for (Field id : ids) {
|
||||
|
@ -303,9 +347,10 @@ class EnumDB extends DataTypeDB implements Enum {
|
|||
String[] names = enumm.getNames();
|
||||
for (String name2 : names) {
|
||||
long value = enumm.getValue(name2);
|
||||
valueAdapter.createRecord(key, name2, value);
|
||||
String comment = enumm.getComment(name2);
|
||||
valueAdapter.createRecord(key, name2, value, comment);
|
||||
adapter.updateRecord(record, true);
|
||||
addToCache(name2, value);
|
||||
addToCache(name2, value, comment);
|
||||
}
|
||||
|
||||
if (oldLength != newLength) {
|
||||
|
|
|
@ -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.
|
||||
|
@ -38,9 +38,10 @@ abstract class EnumValueDBAdapter {
|
|||
static final int ENUMVAL_NAME_COL = EnumValueDBAdapterV0.V0_ENUMVAL_NAME_COL;
|
||||
static final int ENUMVAL_VALUE_COL = EnumValueDBAdapterV0.V0_ENUMVAL_VALUE_COL;
|
||||
static final int ENUMVAL_ID_COL = EnumValueDBAdapterV0.V0_ENUMVAL_ID_COL;
|
||||
static final int ENUMVAL_COMMENT_COL = EnumValueDBAdapterV0.V0_ENUMVAL_COMMENT_COL;
|
||||
|
||||
/**
|
||||
* Gets an adapter for working with the enumeration data type values database table. The adapter is based
|
||||
* Gets an adapter for working with the enumeration data type values database table. The adapter is based
|
||||
* on the version of the database associated with the specified database handle and the openMode.
|
||||
* @param handle handle to the database to be accessed.
|
||||
* @param openMode the mode this adapter is to be opened for (CREATE, UPDATE, READ_ONLY, UPGRADE).
|
||||
|
@ -87,10 +88,12 @@ abstract class EnumValueDBAdapter {
|
|||
* Create new enum value record corresponding to specified enum datatype ID
|
||||
* @param enumID enum datatype ID
|
||||
* @param name value name
|
||||
* @param value numeric value
|
||||
* @param value numeric value
|
||||
* @param comment the field comment
|
||||
* @throws IOException if IO error occurs
|
||||
*/
|
||||
abstract void createRecord(long enumID, String name, long value) throws IOException;
|
||||
abstract void createRecord(long enumID, String name, long value, String comment)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Get enum value record which corresponds to specified value record ID
|
||||
|
|
|
@ -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.
|
||||
|
@ -34,7 +34,8 @@ class EnumValueDBAdapterNoTable extends EnumValueDBAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void createRecord(long enumID, String name, long value) throws IOException {
|
||||
public void createRecord(long enumID, String name, long value, String comment)
|
||||
throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
|
@ -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,11 +18,12 @@ package ghidra.program.database.data;
|
|||
import java.io.IOException;
|
||||
|
||||
import db.*;
|
||||
import ghidra.program.model.lang.ConstantPool.Record;
|
||||
import ghidra.util.exception.VersionException;
|
||||
|
||||
/**
|
||||
* Version 0 implementation for the enumeration tables adapter.
|
||||
*
|
||||
*
|
||||
*/
|
||||
class EnumValueDBAdapterV0 extends EnumValueDBAdapter {
|
||||
static final int VERSION = 0;
|
||||
|
@ -31,11 +32,16 @@ class EnumValueDBAdapterV0 extends EnumValueDBAdapter {
|
|||
static final int V0_ENUMVAL_NAME_COL = 0;
|
||||
static final int V0_ENUMVAL_VALUE_COL = 1;
|
||||
static final int V0_ENUMVAL_ID_COL = 2;
|
||||
static final int V0_ENUMVAL_COMMENT_COL = 3;
|
||||
|
||||
static final Schema V0_ENUM_VALUE_SCHEMA = new Schema(0, "Enum Value ID",
|
||||
new Field[] { StringField.INSTANCE, LongField.INSTANCE, LongField.INSTANCE },
|
||||
new String[] { "Name", "Value", "Enum ID" });
|
||||
|
||||
// static final Schema V1_ENUM_VALUE_SCHEMA = new Schema(0, "Enum Value ID",
|
||||
// new Class[] { StringField.class, LongField.class, LongField.class, StringField.class },
|
||||
// new String[] { "Name", "Value", "Enum ID", "Comment" });
|
||||
|
||||
private Table valueTable;
|
||||
|
||||
/**
|
||||
|
@ -71,11 +77,13 @@ class EnumValueDBAdapterV0 extends EnumValueDBAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void createRecord(long enumID, String name, long value) throws IOException {
|
||||
DBRecord record = V0_ENUM_VALUE_SCHEMA.createRecord(valueTable.getKey());
|
||||
public void createRecord(long enumID, String name, long value, String comment)
|
||||
throws IOException {
|
||||
Record record = V0_ENUM_VALUE_SCHEMA.createRecord(valueTable.getKey());
|
||||
record.setLongValue(V0_ENUMVAL_ID_COL, enumID);
|
||||
record.setString(V0_ENUMVAL_NAME_COL, name);
|
||||
record.setLongValue(V0_ENUMVAL_VALUE_COL, value);
|
||||
record.setString(V0_ENUMVAL_COMMENT_COL, comment);
|
||||
valueTable.putRecord(record);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,14 @@ public interface Enum extends DataType {
|
|||
*/
|
||||
public String getName(long value);
|
||||
|
||||
/**
|
||||
* Get the comment for the given name.
|
||||
* @param name name of the entry
|
||||
* @return the comment
|
||||
* @throws NoSuchElementException if the name does not exist in this Enum
|
||||
*/
|
||||
public String getComment(String name) throws NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Get the values of the enum entries.
|
||||
* @return values sorted in ascending order
|
||||
|
@ -48,6 +56,11 @@ public interface Enum extends DataType {
|
|||
*/
|
||||
public String[] getNames();
|
||||
|
||||
/**
|
||||
* Get the comments of the enum entries.
|
||||
*/
|
||||
public String[] getComments();
|
||||
|
||||
/**
|
||||
* Get the number of entries in this Enum.
|
||||
*/
|
||||
|
@ -60,6 +73,14 @@ public interface Enum extends DataType {
|
|||
*/
|
||||
public void add(String name, long value);
|
||||
|
||||
/**
|
||||
* Add a enum entry.
|
||||
* @param name name of the new entry
|
||||
* @param value value of the new entry
|
||||
* @param comment comment of the new entry
|
||||
*/
|
||||
public void add(String name, long value, String comment);
|
||||
|
||||
/**
|
||||
* Remove the enum entry with the given name.
|
||||
* @param name name of entry to remove.
|
||||
|
|
|
@ -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.
|
||||
|
@ -33,6 +33,7 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
|
||||
private Map<String, Long> nameMap; // name to value
|
||||
private Map<Long, List<String>> valueMap; // value to names
|
||||
private Map<String, String> commentMap; // name to comment
|
||||
private int length;
|
||||
private String description;
|
||||
private List<BitGroup> bitGroups;
|
||||
|
@ -52,6 +53,7 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
}
|
||||
nameMap = new HashMap<>();
|
||||
valueMap = new HashMap<>();
|
||||
commentMap = new HashMap<>();
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
|
@ -65,6 +67,7 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
}
|
||||
nameMap = new HashMap<>();
|
||||
valueMap = new HashMap<>();
|
||||
commentMap = new HashMap<>();
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
|
@ -91,6 +94,15 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
return list.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComment(String valueName) throws NoSuchElementException {
|
||||
String valueNameComment = commentMap.get(valueName);
|
||||
if (valueNameComment == null) {
|
||||
valueNameComment = "";
|
||||
}
|
||||
return valueNameComment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getValues() {
|
||||
long[] values = valueMap.keySet().stream().mapToLong(Long::longValue).toArray();
|
||||
|
@ -105,6 +117,11 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getComments() {
|
||||
return commentMap.values().toArray(new String[commentMap.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return nameMap.size();
|
||||
|
@ -112,6 +129,12 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
|
||||
@Override
|
||||
public void add(String valueName, long value) {
|
||||
String valueNameComment = "";
|
||||
add(valueName, value, valueNameComment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(String valueName, long value, String valueNameComment) {
|
||||
bitGroups = null;
|
||||
checkValue(value);
|
||||
if (nameMap.containsKey(valueName)) {
|
||||
|
@ -124,6 +147,10 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
valueMap.put(value, list);
|
||||
}
|
||||
list.add(valueName);
|
||||
if (valueNameComment == null) {
|
||||
valueNameComment = "";
|
||||
}
|
||||
commentMap.put(valueName, valueNameComment);
|
||||
}
|
||||
|
||||
private void checkValue(long value) {
|
||||
|
@ -166,6 +193,7 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
if (list.isEmpty()) {
|
||||
valueMap.remove(value);
|
||||
}
|
||||
commentMap.remove(valueName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,7 +384,10 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
for (int i = 0; i < names.length; i++) {
|
||||
long value = getValue(names[i]);
|
||||
long otherValue = enumm.getValue(names[i]);
|
||||
if (!names[i].equals(otherNames[i]) || value != otherValue) {
|
||||
String comment = getComment(names[i]);
|
||||
String otherComment = enumm.getComment(names[i]);
|
||||
if (!names[i].equals(otherNames[i]) || value != otherValue ||
|
||||
!comment.equals(otherComment)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -376,10 +407,11 @@ public class EnumDataType extends GenericDataType implements Enum {
|
|||
Enum enumm = (Enum) dataType;
|
||||
nameMap = new HashMap<>();
|
||||
valueMap = new HashMap<>();
|
||||
commentMap = new HashMap<>();
|
||||
setLength(enumm.getLength());
|
||||
String[] names = enumm.getNames();
|
||||
for (String name2 : names) {
|
||||
add(name2, enumm.getValue(name2));
|
||||
add(name2, enumm.getValue(name2), enumm.getComment(name2));
|
||||
}
|
||||
stateChanged(null);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue