--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/source/SourceUtils.java Fri Oct 08 14:56:39 2010 +0300
@@ -0,0 +1,1146 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+* Static utility functions related to source files
+*
+*/
+package com.nokia.tracecompiler.source;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals;
+import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.StringErrorParameters;
+import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode;
+import com.nokia.tracecompiler.model.TraceCompilerException;
+import com.nokia.tracecompiler.model.TraceConstantTable;
+import com.nokia.tracecompiler.model.TraceParameter;
+import com.nokia.tracecompiler.rules.ArrayParameterRule;
+
+/**
+ * Static utility functions related to source files
+ *
+ */
+public class SourceUtils {
+
+ /**
+ * Tag for array types
+ */
+ private static final String ARRAY_TAG = "[]"; //$NON-NLS-1$
+
+ /**
+ * Start tag for printf format specifier
+ */
+ private static final String START_TAG = "%"; //$NON-NLS-1$
+
+ /**
+ * Regular expression optional element tag
+ */
+ private static final String OPTIONAL_TAG = "?"; //$NON-NLS-1$
+
+ /**
+ * Optional parameter pattern. Quoted from Wikipedia:
+ *
+ * <strong> Parameter can be omitted or can be: 'n$' Where n is the number
+ * of the parameter to display using this format specifier, allowing the
+ * parameters provided to be output multiple times, using varying format
+ * specifiers or in different orders. This is a POSIX extension and not in
+ * C99.</strong>
+ *
+ * This has not been implemented -> Currently format specifier count must
+ * match parameter count
+ */
+ private final static String PARAMETER_PATTERN = "(\\d+\\$)"; //$NON-NLS-1$
+
+ /**
+ * Optional flags pattern. Quoted from Wikipedia:
+ *
+ * <strong> Flags can be zero or more (in any order) of:
+ * <ul>
+ * <li>'+' : Causes printf to always denote the sign '+' or '-' of a number
+ * (the default is to omit the sign for positive numbers). Only applicable
+ * to numeric types.
+ * <li>'-' : Causes printf to left-align the output of this placeholder (the
+ * default is to right-align the output).
+ * <li>'#' : Alternate form. For 'g' and 'G', trailing zeros are not
+ * removed. For 'f', 'F', 'e', 'E', 'g', 'G', the output always contains a
+ * decimal point. For 'o', 'x', and 'X', a 0, 0x, and 0X, respectively, is
+ * prepended to non-zero numbers.
+ * <li>' ' : Causes printf to left-pad the output with spaces until the
+ * required length of output is attained. If combined with '0' (see below),
+ * it will cause the sign to become a space when positive, but the remaining
+ * characters will be zero-padded
+ * <li>'0' : Causes printf to use '0' (instead of spaces) to left fill a
+ * fixed length field. For example (assume i = 3) printf("%2d", i) results
+ * in " 3", while printf("%02d", i) results in "03"
+ * </ul>
+ * </strong>
+ */
+ private final static String FLAGS_PATTERN = "([-+# 0])"; //$NON-NLS-1$
+
+ /**
+ * Optional width pattern. Quoted from Wikipedia:
+ *
+ * <strong>Width can be omitted or be any of:
+ * <ul>
+ * <li>a number : Causes printf to pad the output of this placeholder with
+ * spaces until it is at least number characters wide. If number has a
+ * leading '0', then padding is done with '0' characters.
+ * <li>'*' : Causes printf to pad the output until it is n characters wide,
+ * where n is an integer value stored in the a function argument just
+ * preceding that represented by the modified type. For example
+ * printf("%*d", 5, 10) will result in "10" being printed with a width of
+ * 5.</strong>
+ * </ul>
+ * </strong>
+ *
+ * '*' has not been implemented -> Currently format specifier count must
+ * match parameter count
+ */
+ private final static String WIDTH_PATTERN = "(\\d+|\\*)"; //$NON-NLS-1$
+
+ /**
+ * Optional precision pattern. Quoted from Wikipedia:
+ *
+ * Precision can be omitted or be any of: <strong>
+ * <ul>
+ * <li>a number : For non-integral numeric types, causes the decimal portion
+ * of the output to be expressed in at least number digits. For the string
+ * type, causes the output to be truncated at number characters.
+ * <li>'*' : Same as the above, but uses an integer value in the intaken
+ * argument to determine the number of decimal places or maximum string
+ * length. For example, printf("%.*s", 3, "abcdef") will result in "abc"
+ * being printed.
+ * </ul>
+ * </strong> If the precision is zero, nothing is printed for the
+ * corresponding argument.
+ *
+ * '*' has not been implemented -> Currently format specifier count must
+ * match parameter count
+ */
+ private final static String PRECISION_PATTERN = "(\\.(\\d+|\\*))"; //$NON-NLS-1$
+
+ /**
+ * Optional length pattern. Quoted from Wikipedia:
+ *
+ * Length can be omitted or be any of: <strong>
+ * <ul>
+ * <li>'hh' : For integer types, causes printf to expect an int sized
+ * integer argument which was promoted from a char.
+ * <li>'h' : For integer types, causes printf to expect a int sized integer
+ * argument which was promoted from a short.
+ * <li>'l' : (ell) For integer types, causes printf to expect a long sized
+ * integer argument.
+ * <li>'ll' : (ell ell) For integer types, causes printf to expect a long
+ * long sized integer argument.
+ * <li>'L' : For floating point types, causes printf to expect a long double
+ * argument.
+ * <li>'z' : For integer types, causes printf to expect a size_t sized
+ * integer argument.
+ * <li>'j' : For integer types, causes printf to expect a intmax_t sized
+ * integer argument.
+ * <li>'t' : For integer types, causes printf to expect a ptrdiff_t sized
+ * integer argument.
+ * </ul>
+ * </strong>
+ */
+ private final static String LENGTH_PATTERN = "([lh]?[hHlLZjt])"; //$NON-NLS-1$
+
+ /**
+ * Type pattern. Quoted from Wikipedia:
+ *
+ * <strong> type can be any of:
+ * <ul>
+ * <li>'d', 'i' : Print an int as a signed decimal number. '%d' and '%i' are
+ * synonymous for output, but are different when used with scanf() for
+ * input.
+ * <li>'u' : Print decimal unsigned int.
+ * <li>'f', 'F' : Print a double in normal (fixed-point) notation.
+ * <li>'e', 'E' : Print a double value in standard form ([-]d.ddd
+ * e[+/-]ddd).
+ * <li>'g', 'G' : Print a double in either normal or exponential notation,
+ * whichever is more appropriate for its magnitude. 'g' uses lower-case
+ * letters, 'G' uses upper-case letters. This type differs slightly from
+ * fixed-point notation in that insignificant zeroes to the right of the
+ * decimal point are not included. Also, the decimal point is not included
+ * on whole numbers.
+ * <li>'x', 'X' : Print an unsigned int as a hexadecimal number. 'x' uses
+ * lower-case letters and 'X' uses upper-case.
+ * <li>'o' : Print an unsigned int in octal.
+ * <li>'s' : Print a character string.
+ * <li>'c' : Print a char (character).
+ * <li>'p' : Print a void * (pointer to void) in an implementation-defined
+ * format.
+ * <li>'n' : Write number of characters successfully written so far into an
+ * integer pointer parameter.
+ * <li>'%' : Print a literal '%' character (this type doesn't accept any
+ * flags, width, precision or length).
+ * </ul>
+ * </strong>
+ *
+ * The pattern itself accepts all characters and the validity check is done
+ * in {@link #mapFormatToParameterType mapFormatToType}
+ */
+ private final static String TYPE_PATTERN = "([a-zA-Z%])"; //$NON-NLS-1$
+
+ /**
+ * Regular expression pattern for printf
+ *
+ * %[parameter][flags][width][.precision][length]type
+ */
+ private static final String STANDARD_PRINTF_PATTERN = PARAMETER_PATTERN
+ + OPTIONAL_TAG + FLAGS_PATTERN + OPTIONAL_TAG + WIDTH_PATTERN
+ + OPTIONAL_TAG + PRECISION_PATTERN + OPTIONAL_TAG + LENGTH_PATTERN
+ + OPTIONAL_TAG + TYPE_PATTERN;
+
+ /**
+ * Regular expression pattern for Open System Trace printf extensions
+ * %{Type}, %{Array[]}
+ */
+ private static final String EXTENSION_PRINTF_PATTERN = "\\{[\\w_]+(\\[\\])?\\}"; //$NON-NLS-1$
+
+ /**
+ * Regular expression pattern for printf
+ */
+ public static final String PRINTF_PATTERN = START_TAG + "((" //$NON-NLS-1$
+ + STANDARD_PRINTF_PATTERN + ")|(" //$NON-NLS-1$
+ + EXTENSION_PRINTF_PATTERN + "))"; //$NON-NLS-1$
+
+ /**
+ * The pattern for printf-formatted trace text
+ */
+ public final static Pattern traceTextPattern = Pattern
+ .compile(PRINTF_PATTERN);
+
+ /**
+ * The pattern for parameter length in printf specifier
+ */
+ public final static Pattern lengthPattern = Pattern.compile(LENGTH_PATTERN);
+
+ /**
+ * Hidden constructor
+ */
+ private SourceUtils() {
+ }
+
+ /**
+ * Creates a header guard
+ *
+ * @param fileName
+ * the name of the file
+ * @return the header guard
+ */
+ public static String createHeaderGuard(String fileName) {
+ StringBuffer sb = new StringBuffer();
+ String uname = fileName.replace(SourceConstants.PERIOD_CHAR,
+ SourceConstants.UNDERSCORE_CHAR).toUpperCase();
+ sb.append(SourceConstants.IFNDEF);
+ sb.append(SourceConstants.SPACE);
+ sb.append(SourceConstants.DOUBLE_UNDERSCORE);
+ sb.append(uname);
+ sb.append(SourceConstants.DOUBLE_UNDERSCORE);
+ sb.append(SourceConstants.LINE_FEED);
+ sb.append(SourceConstants.DEFINE);
+ sb.append(SourceConstants.SPACE);
+ sb.append(SourceConstants.DOUBLE_UNDERSCORE);
+ sb.append(uname);
+ sb.append(SourceConstants.DOUBLE_UNDERSCORE);
+ return sb.toString();
+ }
+
+ /**
+ * Checks the validity of name
+ *
+ * @param name
+ * the name
+ * @return true if valid
+ */
+ public static boolean isValidName(String name) {
+ boolean retval;
+ if (name != null && name.length() > 0) {
+ retval = true;
+ if (!isValidNameStartChar(name.charAt(0))) {
+ retval = false;
+ } else {
+ for (int i = 1; i < name.length() && retval; i++) {
+ retval = isValidNameChar(name.charAt(i));
+ }
+ }
+ } else {
+ retval = false;
+ }
+ return retval;
+ }
+
+ /**
+ * Checks the validity of parameter name
+ *
+ * @param name
+ * the name
+ * @return true if valid
+ */
+ public static boolean isValidParameterName(String name) {
+ boolean retval;
+ if (name != null && name.length() > 0) {
+ retval = true;
+ if (!isValidNameStartChar(name.charAt(0))) {
+ retval = false;
+ } else {
+ for (int i = 1; i < name.length() && retval; i++) {
+
+ // Check validity of the character
+ char c = name.charAt(i);
+ retval = (isValidNameChar(c) || isValidSpecialChar(c));
+ }
+ }
+ } else {
+ retval = false;
+ }
+ return retval;
+ }
+
+ /**
+ * Checks special character validity
+ *
+ * @param c
+ * character
+ * @return true if valid
+ */
+ private static boolean isValidSpecialChar(char c) {
+ boolean retval = false;
+ // Check if the character is allowed
+ if (c == '.' || c == '-' || c == '>' || c == '(' || c == ')'
+ || c == '[' || c == ']' || c == ' ' || c == '&' || c == '*') {
+ retval = true;
+ }
+ return retval;
+ }
+
+ /**
+ * Checks start-of-name character validity
+ *
+ * @param c
+ * character
+ * @return true if valid
+ */
+ private static boolean isValidNameStartChar(char c) {
+ // Ascii characters and underscore are allowed
+ return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A) // CodForChk_Dis_Magic
+ || c == 0x5F; // CodForChk_Dis_Magic
+ }
+
+ /**
+ * Checks name character validity
+ *
+ * @param c
+ * character
+ * @return true if valid
+ */
+ private static boolean isValidNameChar(char c) {
+ // Numbers are allowed in addition to start characters
+ return isValidNameStartChar(c) || (c >= 0x30 && c <= 0x39); // CodForChk_Dis_Magic
+ }
+
+ /**
+ * Maps a Symbian type to one of the TraceParameter types
+ *
+ * @param parsedType
+ * the type parsed from source
+ * @return the parameter type
+ */
+ public static TypeMapping mapSymbianTypeToParameterType(
+ ParsedType parsedType) {
+ String type = null;
+ // The type map contains Symbian types
+ for (int i = 0; i < SymbianConstants.PARAMETER_TYPE_MAP.length
+ && type == null; i++) {
+ if (parsedType
+ .typeEquals(SymbianConstants.PARAMETER_TYPE_MAP[i][0])) {
+ type = SymbianConstants.PARAMETER_TYPE_MAP[i][1];
+ }
+ }
+ if (type != null) {
+ if (parsedType.hasQualifier(SourceConstants.UNSIGNED)) {
+ type = convertToUnsigned(type);
+ }
+ }
+ TypeMapping retval = new TypeMapping(type);
+ if (type != null) {
+ // Value or a reference can be added to source as is
+ // Points needs to be cast to HEX32
+ if (parsedType.isPointer()) {
+ retval.type = TraceParameter.HEX32;
+ retval.needsCasting = true;
+ } else {
+ // TUint32 needs to be cast to TUint and TInt32 to TInt.
+ // Otherwise there will be some problems with extension
+ // headers
+ if (parsedType.typeEquals(SymbianConstants.TUINT32)
+ || parsedType.typeEquals(SymbianConstants.TINT32)) {
+ retval.needsCasting = true;
+ }
+ }
+ } else if (parsedType.isPointer()) {
+ // Unrecognized pointer types are cast to Hex32
+ retval.type = TraceParameter.HEX32;
+ retval.needsCasting = true;
+ } else {
+ // Unrecognized value types are passed as pointer and cast to Hex32
+ retval.type = TraceParameter.HEX32;
+ retval.valueToPointer = true;
+ retval.needsCasting = true;
+ }
+ return retval;
+ }
+
+ /**
+ * Maps the type of a parameter to a Symbian type
+ *
+ * @param parameter
+ * the parameter
+ * @return the parameter type as string
+ */
+ public static String mapParameterTypeToSymbianType(TraceParameter parameter) {
+ String retval;
+ ArrayParameterRule rule = parameter
+ .getExtension(ArrayParameterRule.class);
+ String type = parameter.getType();
+ TraceConstantTable table = parameter.getModel()
+ .findConstantTableByName(type);
+ if (table != null) {
+ type = table.getType();
+ }
+ if (rule != null) {
+ retval = mapArrayTypeToSymbianType(type);
+ } else {
+ retval = mapBasicTypeToSymbianType(type);
+ }
+ return retval;
+ }
+
+ /**
+ * Maps a basic parameter type to Symbian type
+ *
+ * @param type
+ * the parameter type
+ * @return the Symbian type
+ */
+ public static String mapBasicTypeToSymbianType(String type) {
+ String retval;
+ // Unsigned and hex both use TUint types
+ // Signed uses TInt types
+ if (type.equals(TraceParameter.POINTER)) {
+ retval = SymbianConstants.CONST_TANY_PTR;
+ } else if (type.equals(TraceParameter.SDEC32)) {
+ retval = SymbianConstants.TINT;
+ } else if (type.equals(TraceParameter.UDEC32)
+ || type.equals(TraceParameter.OCT32)
+ || type.equals(TraceParameter.HEX32)) {
+ retval = SymbianConstants.TUINT;
+ } else if (type.equals(TraceParameter.SDEC16)) {
+ retval = SymbianConstants.TINT16;
+ } else if (type.equals(TraceParameter.UDEC16)
+ || type.equals(TraceParameter.OCT16)
+ || type.equals(TraceParameter.HEX16)) {
+ retval = SymbianConstants.TUINT16;
+ } else if (type.equals(TraceParameter.SDEC8)) {
+ retval = SymbianConstants.TINT8;
+ } else if (type.equals(TraceParameter.UDEC8)
+ || type.equals(TraceParameter.OCT8)
+ || type.equals(TraceParameter.HEX8)) {
+ retval = SymbianConstants.TUINT8;
+ } else if (type.equals(TraceParameter.SDEC64)
+ || type.equals(TraceParameter.TIME)) {
+ retval = SymbianConstants.TINT64;
+ } else if (type.equals(TraceParameter.UDEC64)
+ || type.equals(TraceParameter.OCT64)
+ || type.equals(TraceParameter.HEX64)) {
+ retval = SymbianConstants.TUINT64;
+ } else if (type.equals(TraceParameter.ASCII)) {
+ retval = SymbianConstants.CONST_TDESC8_REF;
+ } else if (type.equals(TraceParameter.UNICODE)) {
+ retval = SymbianConstants.CONST_TDESC16_REF;
+ } else if (type.equals(TraceParameter.FLOAT_EXP)
+ || type.equals(TraceParameter.FLOAT_FIX)
+ || type.equals(TraceParameter.FLOAT_OPT)) {
+ retval = SymbianConstants.TREAL;
+ } else {
+ retval = SymbianConstants.TANY_PTR;
+ }
+ return retval;
+ }
+
+ /**
+ * Maps an array parameter type to Symbian type
+ *
+ * @param type
+ * the parameter type
+ * @return the Symbian type
+ */
+ public static String mapArrayTypeToSymbianType(String type) {
+ String basic = mapBasicTypeToSymbianType(type);
+ String retval = SourceConstants.OST_ARRAY_TYPE_PREFIX + basic
+ + SourceConstants.OST_ARRAY_TYPE_POSTFIX;
+ return retval;
+ }
+
+ /**
+ * Maps a format specifier into parameter type
+ *
+ * @param formatSpecifier
+ * the format specifier
+ * @return the parameter type or null if not recognized. If the type is one
+ * of the supported TraceParameter types, the string contains the
+ * integer value of the type
+ * @throws TraceCompilerException
+ * if format specifier is not valid
+ */
+ public static FormatMapping mapFormatToParameterType(String formatSpecifier)
+ throws TraceCompilerException {
+ String type;
+ boolean array = false;
+ boolean basic = false;
+ boolean extended = false;
+ int len = formatSpecifier.length();
+ // Extension format is checked first: %{x}
+ if (len > 3 && formatSpecifier.charAt(1) == '{' // CodForChk_Dis_Magic
+ && formatSpecifier.charAt(len - 1) == '}') {
+ // Extension format can be an array: %{x[]}
+ // In that case it could also be a basic type
+ if (len > 3 + ARRAY_TAG.length() // CodForChk_Dis_Magic
+ && formatSpecifier.charAt(len - 3) == '[' // CodForChk_Dis_Magic
+ && formatSpecifier.charAt(len - 2) == ']') { // CodForChk_Dis_Magic
+ type = formatSpecifier.substring(2, len - 1 // CodForChk_Dis_Magic
+ - ARRAY_TAG.length());
+ array = true;
+ if (isStringType(type)) {
+ StringErrorParameters param = new StringErrorParameters();
+ param.string = type;
+ throw new TraceCompilerException(
+ TraceCompilerErrorCode.PARAMETER_FORMAT_NOT_SUPPORTED_IN_ARRAY,
+ param, null);
+ }
+ } else {
+ type = formatSpecifier.substring(2, len - 1); // CodForChk_Dis_Magic
+ }
+ extended = !isBasicType(type);
+ } else {
+ basic = true;
+ type = formatSpecifier;
+ }
+
+ if (basic) {
+ type = mapBasicFormatToType(formatSpecifier);
+ }
+ if (type == null) {
+ StringErrorParameters params = new StringErrorParameters();
+ params.string = formatSpecifier;
+ throw new TraceCompilerException(
+ TraceCompilerErrorCode.PARAMETER_FORMAT_NOT_SUPPORTED,
+ params, null);
+ }
+ FormatMapping retval = new FormatMapping(type);
+ retval.isArray = array;
+ if (extended) {
+ // In case of extended types, a constant table can still be
+ // represented with normal trace macros.
+ TraceConstantTable table = TraceCompilerEngineGlobals.getTraceModel()
+ .findConstantTableByName(retval.type);
+ if (table != null) {
+ if (!array && isSimpleType(table.getType())) {
+ retval.isSimple = true;
+ }
+ } else {
+ // Extended type must be found from the property file
+ StringErrorParameters params = new StringErrorParameters();
+ params.string = formatSpecifier;
+ throw new TraceCompilerException(
+ TraceCompilerErrorCode.PARAMETER_FORMAT_NOT_SUPPORTED,
+ params, null);
+ }
+ } else if (!retval.isArray) {
+ retval.isSimple = isSimpleType(type);
+ }
+
+ return retval;
+ }
+
+ /**
+ * Maps basic format specifies to parameter type
+ *
+ * @param formatSpecifier
+ * the format specifies
+ * @return the type
+ * @throws TraceCompilerException
+ * if mapping cannot be done
+ */
+ private static String mapBasicFormatToType(String formatSpecifier)
+ throws TraceCompilerException { // CodForChk_Dis_ComplexFunc
+ String type;
+ int paramLength = SourceUtils
+ .mapFormatToParameterLength(formatSpecifier);
+ char formatChar = formatSpecifier.charAt(formatSpecifier.length() - 1);
+ switch (formatChar) {
+ case 'd':
+ type = SourceUtils.mapSignedToParameterType(paramLength);
+ break;
+ case 'x':
+ case 'X':
+ type = SourceUtils.mapHexToParameterType(paramLength);
+ break;
+ case 'u':
+ type = SourceUtils.mapUnsignedToParameterType(paramLength);
+ break;
+ case 'o':
+ type = SourceUtils.mapOctalToParameterType(paramLength);
+ break;
+ case 's':
+ type = TraceParameter.ASCII;
+ break;
+ case 'S': // Symbian extension
+ type = TraceParameter.UNICODE;
+ break;
+ case 'c':
+ type = TraceParameter.SDEC8;
+ break;
+ case 'p':
+ type = TraceParameter.POINTER;
+ break;
+ case 'f':
+ case 'F':
+ type = TraceParameter.FLOAT_FIX;
+ break;
+ case 'e':
+ case 'E':
+ type = TraceParameter.FLOAT_EXP;
+ break;
+ case 'g':
+ case 'G':
+ type = TraceParameter.FLOAT_OPT;
+ break;
+ default:
+ type = null;
+ }
+
+ return type;
+ }
+
+ /**
+ * Maps a parameter type to format string
+ *
+ * @param parameter
+ * the parameter
+ * @return the format string
+ */
+ public static String mapParameterTypeToFormat(TraceParameter parameter) {
+ String tag;
+ if (parameter.getExtension(ArrayParameterRule.class) != null) {
+ tag = mapArrayTypeToFormat(parameter.getType());
+ } else {
+ tag = mapNormalTypeToFormat(parameter.getType());
+ }
+ return tag;
+ }
+
+ /**
+ * Maps an array type to basic type
+ *
+ * @param arrayType
+ * the array type
+ * @return the basic type or null if original type is not array type
+ */
+ public static String mapArrayTypeToBasicType(String arrayType) {
+ String retval;
+ if (arrayType.endsWith(ARRAY_TAG)) {
+ retval = arrayType.substring(0, arrayType.length()
+ - ARRAY_TAG.length());
+ } else {
+ retval = null;
+ }
+ return retval;
+ }
+
+ /**
+ * Parses a numeric value from source
+ *
+ * @param number
+ * the number as string
+ * @return the value
+ */
+ public static int parseNumberFromSource(String number) {
+ int ret;
+ String low = number.toLowerCase();
+ int radix;
+ if (low.startsWith(SourceConstants.HEX_PREFIX)) {
+ radix = 16; // CodForChk_Dis_Magic
+ low = low.substring(SourceConstants.HEX_PREFIX.length());
+ } else if (low.startsWith(SourceConstants.OCTAL_PREFIX)
+ && low.length() > SourceConstants.OCTAL_PREFIX.length()
+ && Character.isDigit(low.charAt(SourceConstants.OCTAL_PREFIX
+ .length()))) {
+ radix = 8; // CodForChk_Dis_Magic
+ low = low.substring(SourceConstants.OCTAL_PREFIX.length());
+ } else {
+ radix = 10; // CodForChk_Dis_Magic
+ }
+ if (low.endsWith(SourceConstants.I64_POSTFIX)) {
+ low = low.substring(0, low.length()
+ - SourceConstants.I64_POSTFIX.length());
+ }
+ if (low.length() > 0) {
+ // Removes U / L characters from the end of value
+ int index = low.length() - 1;
+ boolean complete = false;
+ do {
+ char c = low.charAt(index);
+ if (c == 'u' || c == 'l') {
+ index--;
+ } else {
+ complete = true;
+ }
+ } while (!complete && index >= 0);
+ if (index < low.length() - 1 && index > 0) {
+ low = low.substring(0, index + 1);
+ }
+ ret = Integer.parseInt(low, radix);
+ } else {
+ ret = 0;
+ }
+ return ret;
+ }
+
+ /**
+ * Calculates the size of parameter
+ *
+ * @param parameter
+ * the parameter
+ * @return the parameter size or 0 if the size is not known at compile time
+ */
+ public static int mapParameterTypeToSize(TraceParameter parameter) {
+ int retval;
+ ArrayParameterRule rule = parameter
+ .getExtension(ArrayParameterRule.class);
+ if (rule != null) {
+ // Array parameters are dynamic
+ retval = 0;
+ } else {
+ String type = parameter.getType();
+ TraceConstantTable table = parameter.getModel()
+ .findConstantTableByName(type);
+ if (table != null) {
+ type = table.getType();
+ }
+ retval = mapParameterTypeToSize(type);
+ }
+ return retval;
+ }
+
+ /**
+ * Calculates the size of parameter type
+ *
+ * @param type
+ * the parameter type
+ * @return the parameter size or 0 if size is not known at compile time
+ */
+ public static int mapParameterTypeToSize(String type) {
+ int retval;
+ if (type.equals(TraceParameter.HEX32)
+ || type.equals(TraceParameter.UDEC32)
+ || type.equals(TraceParameter.SDEC32)
+ || type.equals(TraceParameter.OCT32)
+ || type.equals(TraceParameter.POINTER)) {
+ retval = 4; // CodForChk_Dis_Magic
+ } else if (type.equals(TraceParameter.HEX16)
+ || type.equals(TraceParameter.UDEC16)
+ || type.equals(TraceParameter.SDEC16)
+ || type.equals(TraceParameter.OCT16)) {
+ retval = 2; // CodForChk_Dis_Magic
+ } else if (type.equals(TraceParameter.HEX8)
+ || type.equals(TraceParameter.UDEC8)
+ || type.equals(TraceParameter.SDEC8)
+ || type.equals(TraceParameter.OCT8)) {
+ retval = 1;
+ } else if (type.equals(TraceParameter.HEX64)
+ || type.equals(TraceParameter.UDEC64)
+ || type.equals(TraceParameter.SDEC64)
+ || type.equals(TraceParameter.OCT64)
+ || type.equals(TraceParameter.FLOAT_EXP)
+ || type.equals(TraceParameter.FLOAT_FIX)
+ || type.equals(TraceParameter.FLOAT_OPT)) {
+ retval = 8; // CodForChk_Dis_Magic
+ } else {
+ retval = 0;
+ }
+ return retval;
+ }
+
+ /**
+ * Removes printf formatting from trace text
+ *
+ * @param text
+ * the text to be converted
+ * @return the new text
+ */
+ public static String removePrintfFormatting(String text) {
+ Matcher matcher = traceTextPattern.matcher(text);
+ return matcher.replaceAll(""); //$NON-NLS-1$
+ }
+
+ /**
+ * Converts the given type to unsigned type
+ *
+ * @param type
+ * the type
+ * @return unsigned type
+ */
+ private static String convertToUnsigned(String type) {
+ if (type.equals(TraceParameter.SDEC32)) {
+ type = TraceParameter.UDEC32;
+ } else if (type.equals(TraceParameter.SDEC16)) {
+ type = TraceParameter.UDEC16;
+ } else if (type.equals(TraceParameter.SDEC8)) {
+ type = TraceParameter.UDEC8;
+ } else if (type.equals(TraceParameter.SDEC64)) {
+ type = TraceParameter.UDEC64;
+ }
+ return type;
+ }
+
+ /**
+ * Maps a normal parameter type for format character
+ *
+ * @param type
+ * the parameter type
+ * @return the format character
+ */
+ public static String mapNormalTypeToFormat(String type) { // CodForChk_Dis_ComplexFunc
+ String tag;
+ if (type.equals(TraceParameter.SDEC32)) {
+ tag = "%d"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.POINTER)) {
+ tag = "%p"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.HEX32)) {
+ tag = "%x"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.UDEC32)) {
+ tag = "%u"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.OCT32)) {
+ tag = "%o"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.SDEC16)) {
+ tag = "%hd"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.HEX16)) {
+ tag = "%hx"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.UDEC16)) {
+ tag = "%hu"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.OCT16)) {
+ tag = "%ho"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.SDEC8)) {
+ tag = "%hhd"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.HEX8)) {
+ tag = "%hhx"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.UDEC8)) {
+ tag = "%hhu"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.OCT8)) {
+ tag = "%hho"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.SDEC64)) {
+ tag = "%Ld"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.HEX64)) {
+ tag = "%Lx"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.UDEC64)) {
+ tag = "%Lu"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.OCT64)) {
+ tag = "%Lo"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.ASCII)) {
+ tag = "%s"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.UNICODE)) {
+ tag = "%S"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.FLOAT_FIX)) {
+ tag = "%f"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.FLOAT_EXP)) {
+ tag = "%e"; //$NON-NLS-1$
+ } else if (type.equals(TraceParameter.FLOAT_OPT)) {
+ tag = "%g"; //$NON-NLS-1$
+ } else {
+ tag = "%{" //$NON-NLS-1$
+ + type + "}"; //$NON-NLS-1$
+ }
+ return tag;
+ }
+
+ /**
+ * Maps an array parameter type to format string
+ *
+ * @param type
+ * the parameter type
+ * @return the format string
+ */
+ public static String mapArrayTypeToFormat(String type) {
+ String tag = "%{" //$NON-NLS-1$
+ + type + "[]}"; //$NON-NLS-1$
+ return tag;
+ }
+
+ /**
+ * Maps format specifier to parameter length
+ *
+ * @param formatSpecifier
+ * the specifier
+ * @return the length
+ * @throws TraceCompilerException
+ * if length is not valid
+ */
+ public static int mapFormatToParameterLength(String formatSpecifier)
+ throws TraceCompilerException {
+ Matcher matcher = SourceUtils.lengthPattern.matcher(formatSpecifier);
+ int paramLength = 0;
+ if (matcher.find()) {
+ String length = matcher.group();
+
+ if (length.length() == 2) { // CodForChk_Dis_Magic
+ if (length.charAt(0) == 'h' && length.charAt(1) == 'h') {
+ paramLength = SourceConstants.BYTE_SIZE;
+ } else if (length.charAt(0) == 'l' && length.charAt(1) == 'l') {
+ paramLength = SourceConstants.LONG_SIZE;
+ } else {
+ StringErrorParameters params = new StringErrorParameters();
+ params.string = formatSpecifier;
+ throw new TraceCompilerException(
+ TraceCompilerErrorCode.PARAMETER_FORMAT_NOT_SUPPORTED,
+ params, null);
+ }
+ } else if (length.length() == 1) {
+ switch (length.charAt(0)) {
+ case 'h':
+ paramLength = SourceConstants.SHORT_SIZE;
+ break;
+ case 'l':
+ paramLength = SourceConstants.INT_SIZE;
+ break;
+ case 'L':
+ paramLength = SourceConstants.LONG_SIZE;
+ break;
+ default:
+ StringErrorParameters params = new StringErrorParameters();
+ params.string = formatSpecifier;
+ throw new TraceCompilerException(
+ TraceCompilerErrorCode.PARAMETER_FORMAT_NOT_SUPPORTED,
+ params, null);
+ }
+ } else {
+ throw new TraceCompilerException(
+ TraceCompilerErrorCode.INVALID_TRACE_TEXT_FORMAT, null,
+ formatSpecifier);
+ }
+ }
+
+ return paramLength;
+ }
+
+ /**
+ * Maps signed parameter length to type
+ *
+ * @param paramLength
+ * the length
+ * @return the type
+ */
+ private static String mapSignedToParameterType(int paramLength) {
+ String retval;
+ if (paramLength == SourceConstants.BYTE_SIZE) {
+ retval = TraceParameter.SDEC8;
+ } else if (paramLength == SourceConstants.SHORT_SIZE) {
+ retval = TraceParameter.SDEC16;
+ } else if (paramLength == SourceConstants.LONG_SIZE) {
+ retval = TraceParameter.SDEC64;
+ } else {
+ retval = TraceParameter.SDEC32;
+ }
+ return retval;
+ }
+
+ /**
+ * Maps unsigned parameter length to type
+ *
+ * @param paramLength
+ * the length
+ * @return the type
+ */
+ public static String mapUnsignedToParameterType(int paramLength) {
+ String retval;
+ if (paramLength == SourceConstants.BYTE_SIZE) {
+ retval = TraceParameter.UDEC8;
+ } else if (paramLength == SourceConstants.SHORT_SIZE) {
+ retval = TraceParameter.UDEC16;
+ } else if (paramLength == SourceConstants.LONG_SIZE) {
+ retval = TraceParameter.UDEC64;
+ } else {
+ retval = TraceParameter.UDEC32;
+ }
+ return retval;
+ }
+
+ /**
+ * Maps hex parameter length to type
+ *
+ * @param paramLength
+ * the length
+ * @return the type
+ */
+ public static String mapHexToParameterType(int paramLength) {
+ String retval;
+ if (paramLength == SourceConstants.BYTE_SIZE) {
+ retval = TraceParameter.HEX8;
+ } else if (paramLength == SourceConstants.SHORT_SIZE) {
+ retval = TraceParameter.HEX16;
+ } else if (paramLength == SourceConstants.LONG_SIZE) {
+ retval = TraceParameter.HEX64;
+ } else {
+ retval = TraceParameter.HEX32;
+ }
+ return retval;
+ }
+
+ /**
+ * Maps octal parameter length to type
+ *
+ * @param paramLength
+ * the length
+ * @return the type
+ */
+ public static String mapOctalToParameterType(int paramLength) {
+ String retval;
+ if (paramLength == SourceConstants.BYTE_SIZE) {
+ retval = TraceParameter.OCT8;
+ } else if (paramLength == SourceConstants.SHORT_SIZE) {
+ retval = TraceParameter.OCT16;
+ } else if (paramLength == SourceConstants.LONG_SIZE) {
+ retval = TraceParameter.OCT64;
+ } else {
+ retval = TraceParameter.OCT32;
+ }
+
+ return retval;
+ }
+
+ /**
+ * Checks if the parameter can be represented with default trace macros
+ *
+ * @param parameter
+ * the parameter
+ * @return true if parameter can be represented with default trace macros
+ */
+ public static boolean isSimpleType(TraceParameter parameter) {
+ boolean retval;
+ if (parameter.getExtension(ArrayParameterRule.class) != null) {
+ // Arrays are always complex types
+ retval = false;
+ } else {
+ String type = parameter.getType();
+ TraceConstantTable table = parameter.getModel()
+ .findConstantTableByName(type);
+ if (table != null) {
+ type = table.getType();
+ }
+ retval = isSimpleType(type);
+ }
+ return retval;
+ }
+
+ /**
+ * Simple type is 32-bit integer
+ *
+ * @param type
+ * the type
+ * @return true if simple, false if not
+ */
+ private static boolean isSimpleType(String type) {
+ return type.equals(TraceParameter.SDEC32)
+ || type.equals(TraceParameter.UDEC32)
+ || type.equals(TraceParameter.OCT32)
+ || type.equals(TraceParameter.HEX32);
+ }
+
+ /**
+ * String type is either ascii or unicode
+ *
+ * @param type
+ * the type
+ * @return true if string, false if not
+ */
+ private static boolean isStringType(String type) {
+ return type.equals(TraceParameter.ASCII)
+ || type.equals(TraceParameter.UNICODE);
+ }
+
+ /**
+ * Basic type is any of the built-in TraceParameter types
+ *
+ * @param type
+ * the type
+ * @return true if basic, false if not
+ */
+ private static boolean isBasicType(String type) {
+ return isSimpleType(type) || type.equals(TraceParameter.SDEC8)
+ || type.equals(TraceParameter.SDEC16)
+ || type.equals(TraceParameter.UDEC8)
+ || type.equals(TraceParameter.UDEC16)
+ || type.equals(TraceParameter.OCT16)
+ || type.equals(TraceParameter.HEX8)
+ || type.equals(TraceParameter.HEX16)
+ || type.equals(TraceParameter.SDEC64)
+ || type.equals(TraceParameter.UDEC64)
+ || type.equals(TraceParameter.OCT64)
+ || type.equals(TraceParameter.HEX64)
+ || type.equals(TraceParameter.ASCII)
+ || type.equals(TraceParameter.UNICODE)
+ || type.equals(TraceParameter.FLOAT_EXP)
+ || type.equals(TraceParameter.FLOAT_FIX)
+ || type.equals(TraceParameter.FLOAT_OPT)
+ || type.equals(TraceParameter.POINTER);
+ }
+
+ /**
+ * Checks if parameter size is dynamic
+ *
+ * @param parameter
+ * the parameter to be checked
+ * @return true if dynamic size
+ */
+ public static boolean isParameterSizeDynamic(TraceParameter parameter) {
+ String type = parameter.getType();
+ ArrayParameterRule rule = parameter
+ .getExtension(ArrayParameterRule.class);
+ return rule != null || type.equals(TraceParameter.ASCII)
+ || type.equals(TraceParameter.UNICODE);
+ }
+
+ /**
+ * Checks if alignment is needed
+ *
+ * @param type
+ * the parameter type
+ * @return true if alignment is needed
+ */
+ public static boolean isParameterAlignementNeeded(String type) {
+ int size = SourceUtils.mapParameterTypeToSize(type);
+ boolean retval = false;
+ if (size == 1 || size == 2) { // CodForChk_Dis_Magic
+ // 8 and 16-bit parameters need alignment
+ retval = true;
+ } else if (isStringType(type)) {
+ retval = true;
+ }
+ return retval;
+ }
+
+}