1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.integer
;
12 import static org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.TsdlUtils
.childTypeError
;
13 import static org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.TsdlUtils
.concatenateUnaryStrings
;
14 import static org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.TsdlUtils
.isAnyUnaryString
;
16 import java
.nio
.ByteOrder
;
17 import java
.util
.List
;
19 import org
.antlr
.runtime
.tree
.CommonTree
;
20 import org
.eclipse
.core
.runtime
.IStatus
;
21 import org
.eclipse
.jdt
.annotation
.NonNull
;
22 import org
.eclipse
.jdt
.annotation
.NonNullByDefault
;
23 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.Encoding
;
24 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IntegerDeclaration
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.trace
.CTFTrace
;
26 import org
.eclipse
.tracecompass
.ctf
.parser
.CTFParser
;
27 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.Activator
;
28 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.ICommonTreeParser
;
29 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.Messages
;
30 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.MetadataStrings
;
31 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.ParseException
;
32 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.AlignmentParser
;
33 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.ByteOrderParser
;
34 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.SizeParser
;
35 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.tsdl
.string
.EncodingParser
;
38 * Signed integers are represented in two-complement. Integer alignment, size,
39 * signedness and byte ordering are defined in the TSDL metadata. Integers
40 * aligned on byte size (8-bit) and with length multiple of byte size (8-bit)
41 * correspond to the C99 standard integers. In addition, integers with alignment
42 * and/or size that are not a multiple of the byte size are permitted; these
43 * correspond to the C99 standard bitfields, with the added specification that
44 * the CTF integer bitfields have a fixed binary representation. Integer size
45 * needs to be a positive integer. Integers of size 0 are forbidden. An
46 * MIT-licensed reference implementation of the CTF portable bitfields is
49 * Binary representation of integers:
51 * <li>On little and big endian: Within a byte, high bits correspond to an
52 * integer high bits, and low bits correspond to low bits</li>
53 * <li>On little endian: Integer across multiple bytes are placed from the less
54 * significant to the most significant Consecutive integers are placed from
55 * lower bits to higher bits (even within a byte)</li>
56 * <li>On big endian: Integer across multiple bytes are placed from the most
57 * significant to the less significant Consecutive integers are placed from
58 * higher bits to lower bits (even within a byte)</li>
61 * This binary representation is derived from the bitfield implementation in GCC
62 * for little and big endian. However, contrary to what GCC does, integers can
63 * cross units boundaries (no padding is required). Padding can be explicitly
64 * added to follow the GCC layout if needed.
66 * @author Matthew Khouzam
67 * @author Efficios - javadoc preamble
70 public final class IntegerDeclarationParser
implements ICommonTreeParser
{
73 * Parameter Object with a trace
75 * @author Matthew Khouzam
78 public static final class Param
implements ICommonTreeParserParameter
{
79 private final CTFTrace fTrace
;
87 public Param(CTFTrace trace
) {
95 public static final IntegerDeclarationParser INSTANCE
= new IntegerDeclarationParser();
97 private static final @NonNull String ENCODING
= "encoding"; //$NON-NLS-1$
98 private static final @NonNull String EMPTY_STRING
= ""; //$NON-NLS-1$
99 private static final int DEFAULT_INT_BASE
= 10;
100 private static final @NonNull String MAP
= "map"; //$NON-NLS-1$
101 private static final @NonNull String BASE
= "base"; //$NON-NLS-1$
102 private static final @NonNull String SIZE
= "size"; //$NON-NLS-1$
103 private static final @NonNull String SIGNED
= "signed"; //$NON-NLS-1$
105 private IntegerDeclarationParser() {
109 * Parses an integer declaration node.
112 * parent trace, for byte orders
114 * @return The corresponding integer declaration.
117 public IntegerDeclaration
parse(CommonTree integer
, ICommonTreeParserParameter parameter
) throws ParseException
{
118 if (!(parameter
instanceof Param
)) {
119 throw new IllegalArgumentException("Param must be a " + Param
.class.getCanonicalName()); //$NON-NLS-1$
121 CTFTrace trace
= ((Param
) parameter
).fTrace
;
122 List
<CommonTree
> children
= integer
.getChildren();
125 * If the integer has no attributes, then it is missing the size
126 * attribute which is required
128 if (children
== null) {
129 throw new ParseException("integer: missing size attribute"); //$NON-NLS-1$
132 /* The return value */
133 IntegerDeclaration integerDeclaration
= null;
134 boolean signed
= false;
135 ByteOrder byteOrder
= trace
.getByteOrder();
138 int base
= DEFAULT_INT_BASE
;
140 String clock
= EMPTY_STRING
;
142 Encoding encoding
= Encoding
.NONE
;
144 /* Iterate on all integer children */
145 for (CommonTree child
: children
) {
146 switch (child
.getType()) {
147 case CTFParser
.CTF_EXPRESSION_VAL
:
149 * An assignment expression must have 2 children, left and right
152 CommonTree leftNode
= (CommonTree
) child
.getChild(0);
153 CommonTree rightNode
= (CommonTree
) child
.getChild(1);
155 List
<CommonTree
> leftStrings
= leftNode
.getChildren();
157 if (!isAnyUnaryString(leftStrings
.get(0))) {
158 throw new ParseException("Left side of ctf expression must be a string"); //$NON-NLS-1$
160 String left
= concatenateUnaryStrings(leftStrings
);
164 signed
= SignedParser
.INSTANCE
.parse(rightNode
, null);
166 case MetadataStrings
.BYTE_ORDER
:
167 byteOrder
= ByteOrderParser
.INSTANCE
.parse(rightNode
, new ByteOrderParser
.Param(trace
));
170 size
= SizeParser
.INSTANCE
.parse(rightNode
, null);
172 case MetadataStrings
.ALIGN
:
173 alignment
= AlignmentParser
.INSTANCE
.parse(rightNode
, null);
176 base
= BaseParser
.INSTANCE
.parse(rightNode
, null);
179 encoding
= EncodingParser
.INSTANCE
.parse(rightNode
, null);
182 clock
= ClockMapParser
.INSTANCE
.parse(rightNode
, null);
185 Activator
.log(IStatus
.WARNING
, Messages
.IOStructGen_UnknownIntegerAttributeWarning
+ " " + left
); //$NON-NLS-1$
191 throw childTypeError(child
);
196 throw new ParseException("Invalid size attribute in Integer: " + size
); //$NON-NLS-1$
199 if (alignment
== 0) {
203 integerDeclaration
= IntegerDeclaration
.createDeclaration((int) size
, signed
, base
,
204 byteOrder
, encoding
, clock
, alignment
);
206 return integerDeclaration
;