diff -r a151135b0cf9 -r aa2539c91954 tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/source/SourceUtils.java --- /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: + * + * 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. + * + * 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: + * + * Flags can be zero or more (in any order) of: + * + * + */ + private final static String FLAGS_PATTERN = "([-+# 0])"; //$NON-NLS-1$ + + /** + * Optional width pattern. Quoted from Wikipedia: + * + * Width can be omitted or be any of: + * + * + * + * '*' 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: + * + * 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: + * + * + */ + private final static String LENGTH_PATTERN = "([lh]?[hHlLZjt])"; //$NON-NLS-1$ + + /** + * Type pattern. Quoted from Wikipedia: + * + * type can be any of: + * + * + * + * 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; + } + +}