ctf: make dynamic scopes work with definitions [bug 470846]
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Wed, 8 Jul 2015 18:56:34 +0000 (14:56 -0400)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Thu, 9 Jul 2015 23:57:57 +0000 (19:57 -0400)
Change-Id: I0838fb9f17ceab856f3009bdf340185b24e82f28
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/51546
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
Tested-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-by: Hudson CI
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/EventDefinition.java
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDeclaration.java
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/event/types/StructDefinition.java
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/ctf/core/trace/CTFStreamInputPacketReader.java
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/EventDeclaration.java
ctf/org.eclipse.tracecompass.ctf.core/src/org/eclipse/tracecompass/internal/ctf/core/event/metadata/IOStructGen.java

index aa75dd638859f73ab9b00a3056c9f78240cbb73a..2e0a3d35209e9947644edd1ebd69884469b42f1d 100644 (file)
@@ -52,6 +52,8 @@ public final class EventDefinition implements IDefinitionScope {
      */
     private final long fTimestamp;
 
+    private final ICompositeDefinition fEventHeaderDefinition;
+
     /**
      * The event context structure definition.
      */
@@ -101,7 +103,41 @@ public final class EventDefinition implements IDefinitionScope {
             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;
@@ -139,6 +175,16 @@ public final class EventDefinition implements IDefinitionScope {
         return fDeclaration;
     }
 
+    /**
+     * Get the event header
+     *
+     * @return the event header
+     * @since 1.1
+     */
+    public ICompositeDefinition getEventHeader() {
+        return fEventHeaderDefinition;
+    }
+
     /**
      * Gets the fields of a definition
      *
index 90f6efc67e674f55f12d7a2349674e3221baf1a8..f45323d8af910ea22dba383a0a0970905789f3e8 100644 (file)
@@ -20,6 +20,7 @@ import java.util.LinkedHashMap;
 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;
@@ -145,7 +146,14 @@ public class StructDeclaration extends Declaration {
             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;
     }
@@ -171,7 +179,7 @@ public class StructDeclaration extends Declaration {
         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;
@@ -200,6 +208,95 @@ public class StructDeclaration extends Declaration {
         }
     }
 
+    /**
+     * 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 */
@@ -252,7 +349,7 @@ public class StructDeclaration extends Declaration {
         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)))) {
index a3bbd14edaecd4879e93a7f197aa095ce5b0c0df..c70eb474775fcb82e8ae81e1a512acf473360cdd 100644 (file)
@@ -156,7 +156,7 @@ public final class StructDefinition extends ScopedDefinition implements IComposi
         if (val != -1) {
             return fDefinitions[val];
         }
-        return null;
+        return (Definition) getDefinitionScope().lookupDefinition(lookupPath);
     }
 
     @Override
index 4b9fdccf557bf09462cfbaef960cb6c4ae88bdb3..d073d90ce3636afdc743dde5a353b412edab010d 100644 (file)
@@ -40,6 +40,7 @@ import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
 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;
 
 /**
@@ -56,6 +57,19 @@ public class CTFStreamInputPacketReader implements IDefinitionScope, AutoCloseab
 
     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;
@@ -344,12 +358,12 @@ public class CTFStreamInputPacketReader implements IDefinitionScope, AutoCloseab
         /* 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$
@@ -398,11 +412,11 @@ public class CTFStreamInputPacketReader implements IDefinitionScope, AutoCloseab
             }
         }
         /* 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
index 6167586ad399bbd90359957a08d26e9ad5d9e007..9acb2b7d95d490e832f7eeaf08b5d5aca7876e5e 100644 (file)
@@ -79,6 +79,43 @@ public class EventDeclaration implements IEventDeclaration {
     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();
index 957e65c03047b51b5c11f914b54d411d4a220d86..ab2cb4770c20432ae7d7357287974f6094569a20 100644 (file)
@@ -463,8 +463,7 @@ public class IOStructGen {
                 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$
@@ -608,8 +607,7 @@ public class IOStructGen {
                 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) {
@@ -638,8 +636,7 @@ public class IOStructGen {
                 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$
@@ -657,8 +654,7 @@ public class IOStructGen {
                 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$
@@ -796,8 +792,7 @@ public class IOStructGen {
                 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$
@@ -816,7 +811,7 @@ public class IOStructGen {
             }
 
             IDeclaration fieldsDecl;
-            fieldsDecl = parseTypeSpecifierList(typeSpecifier, null);
+            fieldsDecl = parseTypeSpecifierList(typeSpecifier);
 
             if (!(fieldsDecl instanceof StructDeclaration)) {
                 throw new ParseException("fields expects a struct"); //$NON-NLS-1$
@@ -858,7 +853,7 @@ public class IOStructGen {
                 parseTypealias(child);
                 break;
             case CTFParser.TYPE_SPECIFIER_LIST:
-                parseTypeSpecifierList(child, null);
+                parseTypeSpecifierList(child);
                 break;
             default:
                 throw childTypeError(child);
@@ -1121,7 +1116,7 @@ public class IOStructGen {
          * 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
@@ -1212,9 +1207,7 @@ public class IOStructGen {
 
     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);
@@ -1300,6 +1293,10 @@ public class IOStructGen {
 
     }
 
+    private IDeclaration parseTypeSpecifierList(CommonTree typeSpecifierList) throws ParseException {
+        return parseTypeSpecifierList(typeSpecifierList, null, null);
+    }
+
     /**
      * Parses a type specifier list and returns the corresponding declaration.
      *
@@ -1313,7 +1310,7 @@ public class IOStructGen {
      *             creating the declaration.
      */
     private IDeclaration parseTypeSpecifierList(CommonTree typeSpecifierList,
-            List<CommonTree> pointerList) throws ParseException {
+            List<CommonTree> pointerList, CommonTree identifier) throws ParseException {
         IDeclaration declaration = null;
 
         /*
@@ -1333,7 +1330,7 @@ public class IOStructGen {
             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) {
@@ -1627,7 +1624,7 @@ public class IOStructGen {
      * @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();
@@ -1672,6 +1669,11 @@ public class IOStructGen {
             }
         }
 
+        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
@@ -1764,6 +1766,7 @@ public class IOStructGen {
                 break;
             case CTFParser.TYPEDEF:
                 parseTypedef(declarationNode);
+                parseStructDeclaration(declarationNode, structDeclaration);
                 break;
             case CTFParser.SV_DECLARATION:
                 parseStructDeclaration(declarationNode, structDeclaration);
@@ -2061,7 +2064,7 @@ public class IOStructGen {
         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) {
This page took 0.03582 seconds and 5 git commands to generate.