package org.eclipse.linuxtools.ctf.core.event.types;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
/**
* A CTF enum declaration.
*
- * The definition of a enum point basic data type. It will take the data
- * from a trace and store it (and make it fit) as an integer and a string.
+ * The definition of a enum point basic data type. It will take the data from a
+ * trace and store it (and make it fit) as an integer and a string.
*
* @version 1.0
* @author Matthew Khouzam
// Attributes
// ------------------------------------------------------------------------
- private final EnumTable table = new EnumTable();
- private IntegerDeclaration containerType = null;
+ private final EnumTable fTable = new EnumTable();
+ private final IntegerDeclaration fContainerType;
+ private final Set<String> fLabels = new HashSet<String>();
// ------------------------------------------------------------------------
// Constructors
* you are wasting space.
*/
public EnumDeclaration(IntegerDeclaration containerType) {
- this.containerType = containerType;
+ fContainerType = containerType;
}
// ------------------------------------------------------------------------
* @return The container type
*/
public IntegerDeclaration getContainerType() {
- return containerType;
+ return fContainerType;
}
@Override
}
/**
- * Add a value. Do not overlap, this is <i><u><b>not</i></u></b> an interval tree.
- * @param low lowest value that this int can be to have label as a return string
- * @param high highest value that this int can be to have label as a return string
- * @param label the name of the value.
+ * Add a value. Do not overlap, this is <i><u><b>not</i></u></b> an interval
+ * tree.
+ *
+ * @param low
+ * lowest value that this int can be to have label as a return
+ * string
+ * @param high
+ * highest value that this int can be to have label as a return
+ * string
+ * @param label
+ * the name of the value.
* @return was the value be added? true == success
*/
public boolean add(long low, long high, String label) {
- return table.add(low, high, label);
+ fLabels.add(label);
+ return fTable.add(low, high, label);
}
/**
- * Check if the label for a value (enum a{day=0,night=1} would return "day" for query(0)
- * @param value the value to lookup
+ * Check if the label for a value (enum a{day=0,night=1} would return "day"
+ * for query(0)
+ *
+ * @param value
+ * the value to lookup
* @return the label of that value, can be null
*/
public String query(long value) {
- return table.query(value);
+ return fTable.query(value);
+ }
+
+ /**
+ * Gets a set of labels of the enum
+ *
+ * @return A set of labels of the enum, can be empty but not null
+ */
+ public Set<String> getLabels() {
+ return Collections.unmodifiableSet(fLabels);
}
/*
* Maps integer range -> string. A simple list for now, but feel free to
* optimize it. Babeltrace suggests an interval tree.
*/
- private static class EnumTable {
+ private class EnumTable {
- private List<Range> ranges = new LinkedList<Range>();
+ private final List<LabelAndRange> ranges = new LinkedList<LabelAndRange>();
public EnumTable() {
}
public boolean add(long low, long high, String label) {
- Range newRange = new Range(low, high, label);
+ LabelAndRange newRange = new LabelAndRange(low, high, label);
- for (Range r : ranges) {
+ for (LabelAndRange r : ranges) {
if (r.intersects(newRange)) {
return false;
}
/**
* Return the first label that matches a value
- * @param value the value to query
+ *
+ * @param value
+ * the value to query
* @return the label corresponding to that value
*/
public String query(long value) {
- for (Range r : ranges) {
+ for (LabelAndRange r : ranges) {
if (r.intersects(value)) {
- return r.str;
+ return r.fLabel;
}
}
return null;
}
- private static class Range {
+ }
- private long low, high;
- private String str;
+ private class LabelAndRange {
- public Range(long low, long high, String str) {
- this.low = low;
- this.high = high;
- this.str = str;
- }
+ private final long low, high;
+ private final String fLabel;
- public boolean intersects(long i) {
- return (i >= this.low) && (i <= this.high);
- }
+ public LabelAndRange(long low, long high, String str) {
+ this.low = low;
+ this.high = high;
+ this.fLabel = str;
+ }
- public boolean intersects(Range other) {
- return this.intersects(other.low)
- || this.intersects(other.high);
- }
+ public boolean intersects(long i) {
+ return (i >= this.low) && (i <= this.high);
+ }
+
+ public boolean intersects(LabelAndRange other) {
+ return this.intersects(other.low)
+ || this.intersects(other.high);
}
}
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
import java.util.UUID;
import org.antlr.runtime.tree.CommonTree;
if (hasTag) {
variantDeclaration.setTag(variantTag);
+
+ IDeclaration decl = getCurrentScope().lookupIdentifierRecursive(variantTag);
+ if (decl == null) {
+ throw new ParseException("Variant tag not found: " + variantTag); //$NON-NLS-1$
+ }
+ if (!(decl instanceof EnumDeclaration)) {
+ throw new ParseException("Variant tag must be an enum: " + variantTag); //$NON-NLS-1$
+ }
+ EnumDeclaration tagDecl = (EnumDeclaration) decl;
+ Set<String> intersection = new HashSet<String>(tagDecl.getLabels());
+ intersection.retainAll(variantDeclaration.getFields().keySet());
+ if (intersection.isEmpty()) {
+ throw new ParseException("Variant contains no values of the tag, impossible to use: " + variantName); //$NON-NLS-1$
+ }
}
return variantDeclaration;
* @param unaryInteger
* An unary integer node.
* @return The integer value.
- * @throws CTFReaderException
+ * @throws ParseException on an invalid integer format ("bob" for example)
*/
private static long parseUnaryInteger(CommonTree unaryInteger) throws ParseException {