*/
private final long fTimestamp;
+ private final ICompositeDefinition fEventHeaderDefinition;
+
/**
* The event context structure definition.
*/
ICompositeDefinition eventContext,
ICompositeDefinition packetContext,
ICompositeDefinition fields) {
+ this(declaration, streamInputReader, timestamp, null, streamContext,
+ eventContext, packetContext, fields);
+ }
+
+ /**
+ * Constructs an event definition.
+ *
+ * @param declaration
+ * The corresponding event declaration
+ * @param streamInputReader
+ * The SIR from where this EventDef was read
+ * @param timestamp
+ * event timestamp
+ * @param eventHeaderDefinition
+ * the event header definition, can be null
+ * @param eventContext
+ * The event context
+ * @param packetContext
+ * the packet context
+ * @param streamContext
+ * the stream context
+ * @param fields
+ * The event fields
+ * @since 1.1
+ */
+ public EventDefinition(IEventDeclaration declaration,
+ CTFStreamInputReader streamInputReader,
+ long timestamp,
+ ICompositeDefinition eventHeaderDefinition,
+ ICompositeDefinition streamContext,
+ ICompositeDefinition eventContext,
+ ICompositeDefinition packetContext,
+ ICompositeDefinition fields) {
fDeclaration = declaration;
+ fEventHeaderDefinition = eventHeaderDefinition;
fStreamInputReader = streamInputReader;
fTimestamp = timestamp;
fFields = fields;
return fDeclaration;
}
+ /**
+ * Get the event header
+ *
+ * @return the event header
+ * @since 1.1
+ */
+ public ICompositeDefinition getEventHeader() {
+ return fEventHeaderDefinition;
+ }
+
/**
* Gets the fields of a definition
*
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
String fieldName, BitBuffer input) throws CTFException {
alignRead(input);
final Definition[] myFields = new Definition[fFieldMap.size()];
- StructDefinition structDefinition = new StructDefinition(this, definitionScope, fieldName, myFields);
+ StructDefinition structDefinition = null;
+ if (definitionScope == null) {
+ InternalDef localDefinitionScope = new InternalDef(null, null);
+ structDefinition = new StructDefinition(this, localDefinitionScope, fieldName, myFields);
+ localDefinitionScope.setDefinition(structDefinition);
+ } else {
+ structDefinition = new StructDefinition(this, definitionScope, fieldName, myFields);
+ }
fillStruct(input, myFields, structDefinition);
return structDefinition;
}
alignRead(input);
final Definition[] myFields = new Definition[fFieldMap.size()];
- StructDefinition structDefinition = new StructDefinition(this,definitionScope,
+ StructDefinition structDefinition = new StructDefinition(this, definitionScope,
fieldScope, fieldScope.getName(), checkNotNull(fFieldMap.keySet()), myFields);
fillStruct(input, myFields, structDefinition);
return structDefinition;
}
}
+ /**
+ * Special constructor for fields
+ *
+ * @param eventHeaderDef
+ * the event header, used for scopes
+ * @param definitionScope
+ * the definition scope, in this case, the trace
+ * @param fields
+ * event fields
+ * @param input
+ * the input {@link BitBuffer}
+ * @return the fields definition
+ * @throws CTFException
+ * something went wrong
+ * @since 1.1
+ */
+ public StructDefinition createFieldDefinition(ICompositeDefinition eventHeaderDef, IDefinitionScope definitionScope, ILexicalScope fields, @NonNull BitBuffer input) throws CTFException {
+ alignRead(input);
+ final Definition[] myFields = new Definition[fFieldMap.size()];
+ IDefinitionScope merged = definitionScope;
+ if (eventHeaderDef != null) {
+ merged = new InternalDef(definitionScope, eventHeaderDef);
+ }
+ StructDefinition structDefinition = new StructDefinition(this, merged,
+ fields, fields.getName(), checkNotNull(fFieldMap.keySet()), myFields);
+ if (merged instanceof InternalDef) {
+ InternalDef internalDef = (InternalDef) merged;
+ internalDef.setDefinition(structDefinition);
+ }
+ fillStruct(input, myFields, structDefinition);
+ return structDefinition;
+ }
+
+ private static final Pattern EVENT_HEADER = Pattern.compile(ILexicalScope.EVENT_HEADER.getPath().replaceAll("\\.", "\\\\.") + "\\."); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+
+ private class InternalDef implements IDefinitionScope {
+
+ private final ICompositeDefinition fEventHeaderDef;
+ private final IDefinitionScope fTraceDef;
+ private StructDefinition fDefinition;
+
+ public InternalDef(IDefinitionScope definitionScope, ICompositeDefinition eventHeaderDef) {
+ fTraceDef = definitionScope;
+ fEventHeaderDef = eventHeaderDef;
+ }
+
+ @Override
+ public ILexicalScope getScopePath() {
+ return ILexicalScope.EVENT;
+ }
+
+ @Override
+ public IDefinition lookupDefinition(String lookupPath) {
+ IDefinition lookupDefinition = null;
+ if (fTraceDef != null) {
+ lookupDefinition = fTraceDef.lookupDefinition(lookupPath);
+ }
+ if (lookupDefinition == null) {
+ if (fEventHeaderDef != null) {
+ String[] paths = EVENT_HEADER.split(lookupPath);
+ if (paths.length > 1) {
+ String[] childLookup = paths[1].split("\\."); //$NON-NLS-1$
+ return getRecursiveDef(fEventHeaderDef.getDefinition(childLookup[0]), childLookup, 1);
+ }
+ if (fDefinition != null) {
+ return fDefinition.lookupDefinition(lookupPath);
+ }
+ }
+ }
+ return lookupDefinition;
+ }
+
+ private IDefinition getRecursiveDef(Definition definition, String[] childLookup, int i) {
+ if (i == childLookup.length) {
+ return definition;
+ }
+ if (definition instanceof ICompositeDefinition) {
+ ICompositeDefinition compositeDefinition = (ICompositeDefinition) definition;
+ return getRecursiveDef(compositeDefinition.getDefinition(childLookup[i]), childLookup, i + 1);
+ }
+ return null;
+ }
+
+ public void setDefinition(StructDefinition definition) {
+ fDefinition = definition;
+ }
+
+ }
+
@Override
public String toString() {
/* Only used for debugging */
List<IDeclaration> otherDecs = new ArrayList<>();
otherDecs.addAll(other.fFieldMap.values());
- //check fields in order
+ // check fields in order
for (int i = 0; i < fFieldMap.size(); i++) {
if ((!localFieldNames.get(i).equals(otherFieldNames.get(i))) ||
(!otherDecs.get(i).equals(localDecs.get(i)))) {
if (val != -1) {
return fDefinitions[val];
}
- return null;
+ return (Definition) getDefinitionScope().lookupDefinition(lookupPath);
}
@Override
import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition;
import org.eclipse.tracecompass.ctf.core.event.types.VariantDefinition;
import org.eclipse.tracecompass.internal.ctf.core.SafeMappedByteBuffer;
+import org.eclipse.tracecompass.internal.ctf.core.event.EventDeclaration;
import org.eclipse.tracecompass.internal.ctf.core.event.types.composite.EventHeaderDefinition;
/**
private static final int BITS_PER_BYTE = Byte.SIZE;
+ private static final IDefinitionScope EVENT_HEADER_SCOPE = new IDefinitionScope() {
+
+ @Override
+ public IDefinition lookupDefinition(String lookupPath) {
+ return null;
+ }
+
+ @Override
+ public ILexicalScope getScopePath() {
+ return null;
+ }
+ };
+
/** BitBuffer used to read the trace file. */
@Nullable
private BitBuffer fBitBuffer;
/* Read the stream event header. */
if (fStreamEventHeaderDecl != null) {
if (fStreamEventHeaderDecl instanceof IEventHeaderDeclaration) {
- fCurrentStreamEventHeaderDef = (ICompositeDefinition) fStreamEventHeaderDecl.createDefinition(null, "", currentBitBuffer); //$NON-NLS-1$
+ fCurrentStreamEventHeaderDef = (ICompositeDefinition) fStreamEventHeaderDecl.createDefinition(EVENT_HEADER_SCOPE, "", currentBitBuffer); //$NON-NLS-1$
EventHeaderDefinition ehd = (EventHeaderDefinition) fCurrentStreamEventHeaderDef;
eventID = ehd.getId();
timestamp = calculateTimestamp(ehd.getTimestamp(), ehd.getTimestampLength());
} else {
- fCurrentStreamEventHeaderDef = ((StructDeclaration) fStreamEventHeaderDecl).createDefinition(null, ILexicalScope.EVENT_HEADER, currentBitBuffer);
+ fCurrentStreamEventHeaderDef = ((StructDeclaration) fStreamEventHeaderDecl).createDefinition(EVENT_HEADER_SCOPE, ILexicalScope.EVENT_HEADER, currentBitBuffer);
StructDefinition StructEventHeaderDef = (StructDefinition) fCurrentStreamEventHeaderDef;
/* Check for the event id. */
IDefinition idDef = StructEventHeaderDef.lookupDefinition("id"); //$NON-NLS-1$
}
}
/* Get the right event definition using the event id. */
- IEventDeclaration eventDeclaration = fStreamInputReader.getStreamInput().getStream().getEventDeclaration(eventID);
+ EventDeclaration eventDeclaration = (EventDeclaration) fStreamInputReader.getStreamInput().getStream().getEventDeclaration(eventID);
if (eventDeclaration == null) {
throw new CTFIOException("Incorrect event id : " + eventID); //$NON-NLS-1$
}
- EventDefinition eventDef = eventDeclaration.createDefinition(fStreamInputReader, currentBitBuffer, timestamp);
+ EventDefinition eventDef = eventDeclaration.createDefinition(fStreamInputReader, fCurrentStreamEventHeaderDef, currentBitBuffer, timestamp);
/*
* Set the event timestamp using the timestamp calculated by
public EventDeclaration() {
}
+ /**
+ * Creates an instance of EventDefinition corresponding to this declaration.
+ *
+ * @param streamInputReader
+ * The StreamInputReader for which this definition is created.
+ * @param eventHeaderDef
+ * The event header definition
+ * @param input
+ * the bitbuffer input source
+ * @param timestamp
+ * The timestamp when the event was taken
+ * @return A new EventDefinition.
+ * @throws CTFException
+ * As a bitbuffer is used to read, it could have wrapped
+ * IOExceptions.
+ */
+ public EventDefinition createDefinition(CTFStreamInputReader streamInputReader, ICompositeDefinition eventHeaderDef, @NonNull BitBuffer input, long timestamp) throws CTFException {
+ StructDeclaration streamEventContextDecl = streamInputReader.getStreamEventContextDecl();
+ StructDefinition streamEventContext = streamEventContextDecl != null ? streamEventContextDecl.createDefinition(fStream.getTrace(), ILexicalScope.STREAM_EVENT_CONTEXT, input) : null;
+ ICompositeDefinition packetContext = streamInputReader.getPacketReader().getCurrentPacketEventHeader();
+ StructDefinition eventContext = fContext != null ? fContext.createFieldDefinition(eventHeaderDef, fStream.getTrace(), ILexicalScope.CONTEXT, input) : null;
+ StructDefinition eventPayload = fFields != null ? fFields.createFieldDefinition(eventHeaderDef, fStream.getTrace(), ILexicalScope.FIELDS, input) : null;
+
+ // a bit lttng specific
+ // CTF doesn't require a timestamp,
+ // but it's passed to us
+ return new EventDefinition(
+ this,
+ streamInputReader,
+ timestamp,
+ eventHeaderDef,
+ streamEventContext,
+ eventContext,
+ packetContext,
+ eventPayload);
+ }
+
@Override
public EventDefinition createDefinition(CTFStreamInputReader streamInputReader, @NonNull BitBuffer input, long timestamp) throws CTFException {
StructDeclaration streamEventContextDecl = streamInputReader.getStreamEventContextDecl();
throw new ParseException("packet.header expects a type specifier"); //$NON-NLS-1$
}
- IDeclaration packetHeaderDecl = parseTypeSpecifierList(
- typeSpecifier, null);
+ IDeclaration packetHeaderDecl = parseTypeSpecifierList(typeSpecifier);
if (!(packetHeaderDecl instanceof StructDeclaration)) {
throw new ParseException("packet.header expects a struct"); //$NON-NLS-1$
throw new ParseException("event.header expects a type specifier"); //$NON-NLS-1$
}
- IDeclaration eventHeaderDecl = parseTypeSpecifierList(
- typeSpecifier, null);
+ IDeclaration eventHeaderDecl = parseTypeSpecifierList(typeSpecifier);
DeclarationScope scope = getCurrentScope();
DeclarationScope eventHeaderScope = scope.lookupChildRecursive(MetadataStrings.STRUCT);
if (eventHeaderScope == null) {
throw new ParseException("event.context expects a type specifier"); //$NON-NLS-1$
}
- IDeclaration eventContextDecl = parseTypeSpecifierList(
- typeSpecifier, null);
+ IDeclaration eventContextDecl = parseTypeSpecifierList(typeSpecifier);
if (!(eventContextDecl instanceof StructDeclaration)) {
throw new ParseException("event.context expects a struct"); //$NON-NLS-1$
throw new ParseException("packet.context expects a type specifier"); //$NON-NLS-1$
}
- IDeclaration packetContextDecl = parseTypeSpecifierList(
- typeSpecifier, null);
+ IDeclaration packetContextDecl = parseTypeSpecifierList(typeSpecifier);
if (!(packetContextDecl instanceof StructDeclaration)) {
throw new ParseException("packet.context expects a struct"); //$NON-NLS-1$
throw new ParseException("context expects a type specifier"); //$NON-NLS-1$
}
- IDeclaration contextDecl = parseTypeSpecifierList(typeSpecifier,
- null);
+ IDeclaration contextDecl = parseTypeSpecifierList(typeSpecifier);
if (!(contextDecl instanceof StructDeclaration)) {
throw new ParseException("context expects a struct"); //$NON-NLS-1$
}
IDeclaration fieldsDecl;
- fieldsDecl = parseTypeSpecifierList(typeSpecifier, null);
+ fieldsDecl = parseTypeSpecifierList(typeSpecifier);
if (!(fieldsDecl instanceof StructDeclaration)) {
throw new ParseException("fields expects a struct"); //$NON-NLS-1$
parseTypealias(child);
break;
case CTFParser.TYPE_SPECIFIER_LIST:
- parseTypeSpecifierList(child, null);
+ parseTypeSpecifierList(child);
break;
default:
throw childTypeError(child);
* Parse the type specifier list, which is the "base" type. For example,
* it would be int in int a[3][len].
*/
- declaration = parseTypeSpecifierList(typeSpecifierList, pointers);
+ declaration = parseTypeSpecifierList(typeSpecifierList, pointers, identifier);
/*
* Each length subscript means that we must create a nested array or
private void registerType(IDeclaration declaration, String identifier) throws ParseException {
final DeclarationScope currentScope = getCurrentScope();
- if (declaration instanceof StructDeclaration) {
- currentScope.registerStruct(identifier, (StructDeclaration) declaration);
- } else if (declaration instanceof EnumDeclaration) {
+ if (declaration instanceof EnumDeclaration) {
currentScope.registerEnum(identifier, (EnumDeclaration) declaration);
} else if (declaration instanceof VariantDeclaration) {
currentScope.registerVariant(identifier, (VariantDeclaration) declaration);
}
+ private IDeclaration parseTypeSpecifierList(CommonTree typeSpecifierList) throws ParseException {
+ return parseTypeSpecifierList(typeSpecifierList, null, null);
+ }
+
/**
* Parses a type specifier list and returns the corresponding declaration.
*
* creating the declaration.
*/
private IDeclaration parseTypeSpecifierList(CommonTree typeSpecifierList,
- List<CommonTree> pointerList) throws ParseException {
+ List<CommonTree> pointerList, CommonTree identifier) throws ParseException {
IDeclaration declaration = null;
/*
declaration = parseString(firstChild);
break;
case CTFParser.STRUCT:
- declaration = parseStruct(firstChild);
+ declaration = parseStruct(firstChild, identifier);
StructDeclaration structDeclaration = (StructDeclaration) declaration;
IDeclaration idEnumDecl = structDeclaration.getFields().get("id"); //$NON-NLS-1$
if (idEnumDecl instanceof EnumDeclaration) {
* @return The corresponding struct declaration.
* @throws ParseException
*/
- private StructDeclaration parseStruct(CommonTree struct)
+ private StructDeclaration parseStruct(CommonTree struct, CommonTree identifier)
throws ParseException {
List<CommonTree> children = struct.getChildren();
}
}
+ if (!hasName && identifier != null) {
+ structName = identifier.getText();
+ hasName = true;
+ }
+
/*
* If a struct has just a body and no name (just like the song,
* "A Struct With No Name" by America (sorry for that...)), it's a
break;
case CTFParser.TYPEDEF:
parseTypedef(declarationNode);
+ parseStructDeclaration(declarationNode, structDeclaration);
break;
case CTFParser.SV_DECLARATION:
parseStructDeclaration(declarationNode, structDeclaration);
CommonTree typeSpecifierList = (CommonTree) enumContainerType.getChild(0);
/* Parse it and get the corresponding declaration */
- IDeclaration decl = parseTypeSpecifierList(typeSpecifierList, null);
+ IDeclaration decl = parseTypeSpecifierList(typeSpecifierList);
/* If is is an integer, return it, else throw an error */
if (decl instanceof IntegerDeclaration) {