tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/header/TraceHeaderWriter.java
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
child 62 1c2bb2fc7c87
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). 
hgs
parents:
diff changeset
     3
 * All rights reserved.
hgs
parents:
diff changeset
     4
 * This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
 * under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
 * which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
 *
hgs
parents:
diff changeset
     9
 * Initial Contributors:
hgs
parents:
diff changeset
    10
 * Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
 *
hgs
parents:
diff changeset
    12
 * Contributors:
hgs
parents:
diff changeset
    13
 *
hgs
parents:
diff changeset
    14
 * Description:
hgs
parents:
diff changeset
    15
 *
hgs
parents:
diff changeset
    16
 * Writes the TraceHeader to a file
hgs
parents:
diff changeset
    17
 *
hgs
parents:
diff changeset
    18
 */
hgs
parents:
diff changeset
    19
package com.nokia.tracecompiler.engine.header;
hgs
parents:
diff changeset
    20
hgs
parents:
diff changeset
    21
import java.io.File;
hgs
parents:
diff changeset
    22
import java.io.IOException;
hgs
parents:
diff changeset
    23
import java.io.OutputStream;
hgs
parents:
diff changeset
    24
import java.util.ArrayList;
hgs
parents:
diff changeset
    25
import java.util.Iterator;
hgs
parents:
diff changeset
    26
import java.util.List;
hgs
parents:
diff changeset
    27
import java.util.regex.Matcher;
hgs
parents:
diff changeset
    28
import java.util.regex.Pattern;
hgs
parents:
diff changeset
    29
hgs
parents:
diff changeset
    30
import com.nokia.tracecompiler.TraceCompilerLogger;
hgs
parents:
diff changeset
    31
import com.nokia.tracecompiler.engine.LocationListBase;
hgs
parents:
diff changeset
    32
import com.nokia.tracecompiler.engine.LocationProperties;
hgs
parents:
diff changeset
    33
import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals;
hgs
parents:
diff changeset
    34
import com.nokia.tracecompiler.engine.TraceLocation;
hgs
parents:
diff changeset
    35
import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode;
hgs
parents:
diff changeset
    36
import com.nokia.tracecompiler.engine.source.SourceFormatter;
hgs
parents:
diff changeset
    37
import com.nokia.tracecompiler.engine.source.TraceFormattingRule;
hgs
parents:
diff changeset
    38
import com.nokia.tracecompiler.engine.source.TraceParameterFormattingRule;
hgs
parents:
diff changeset
    39
import com.nokia.tracecompiler.file.FileCompareOutputStream;
hgs
parents:
diff changeset
    40
import com.nokia.tracecompiler.file.FileUtils;
hgs
parents:
diff changeset
    41
import com.nokia.tracecompiler.model.Trace;
hgs
parents:
diff changeset
    42
import com.nokia.tracecompiler.model.TraceCompilerException;
hgs
parents:
diff changeset
    43
import com.nokia.tracecompiler.model.TraceGroup;
hgs
parents:
diff changeset
    44
import com.nokia.tracecompiler.model.TraceModel;
hgs
parents:
diff changeset
    45
import com.nokia.tracecompiler.model.TraceParameter;
hgs
parents:
diff changeset
    46
import com.nokia.tracecompiler.plugin.TraceFormatConstants;
hgs
parents:
diff changeset
    47
import com.nokia.tracecompiler.plugin.TraceHeaderContribution;
hgs
parents:
diff changeset
    48
import com.nokia.tracecompiler.plugin.TraceAPIFormatter.TraceFormatType;
hgs
parents:
diff changeset
    49
import com.nokia.tracecompiler.plugin.TraceHeaderContribution.TraceHeaderContributionType;
hgs
parents:
diff changeset
    50
import com.nokia.tracecompiler.rules.FillerParameterRule;
hgs
parents:
diff changeset
    51
import com.nokia.tracecompiler.source.SourceConstants;
hgs
parents:
diff changeset
    52
import com.nokia.tracecompiler.source.SourceExcludedArea;
hgs
parents:
diff changeset
    53
import com.nokia.tracecompiler.source.SourceParser;
hgs
parents:
diff changeset
    54
import com.nokia.tracecompiler.source.SourceUtils;
hgs
parents:
diff changeset
    55
import com.nokia.tracecompiler.source.SymbianConstants;
hgs
parents:
diff changeset
    56
import com.nokia.tracecompiler.utils.TraceCompilerVersion;
hgs
parents:
diff changeset
    57
hgs
parents:
diff changeset
    58
/**
hgs
parents:
diff changeset
    59
 * Writes the TraceHeader to a file
hgs
parents:
diff changeset
    60
 * 
hgs
parents:
diff changeset
    61
 */
hgs
parents:
diff changeset
    62
final class TraceHeaderWriter {
hgs
parents:
diff changeset
    63
hgs
parents:
diff changeset
    64
	/**
hgs
parents:
diff changeset
    65
	 * return type text of a generated OstTraceGenx function.
hgs
parents:
diff changeset
    66
	 */
hgs
parents:
diff changeset
    67
	private static final String INLINE_TBOOL = "inline TBool";
hgs
parents:
diff changeset
    68
hgs
parents:
diff changeset
    69
	/**
hgs
parents:
diff changeset
    70
	 * open bracket in a type cast
hgs
parents:
diff changeset
    71
	 */
hgs
parents:
diff changeset
    72
	private static final String BEGINCAST = "OBR"; //$NON-NLS-1$
hgs
parents:
diff changeset
    73
	
hgs
parents:
diff changeset
    74
	/**
hgs
parents:
diff changeset
    75
	 * closing bracket in a type cast
hgs
parents:
diff changeset
    76
	 */
hgs
parents:
diff changeset
    77
	private static final String ENDCAST = "CBR"; //$NON-NLS-1$
hgs
parents:
diff changeset
    78
hgs
parents:
diff changeset
    79
	/**
hgs
parents:
diff changeset
    80
	 * REF replaces & in a function guard
hgs
parents:
diff changeset
    81
	 */
hgs
parents:
diff changeset
    82
	private static final String REF = "REF"; //$NON-NLS-1$
hgs
parents:
diff changeset
    83
hgs
parents:
diff changeset
    84
	/**
hgs
parents:
diff changeset
    85
	 * & character
hgs
parents:
diff changeset
    86
	 */
hgs
parents:
diff changeset
    87
	private static final String AMPERSANT = "&"; //$NON-NLS-1$
hgs
parents:
diff changeset
    88
hgs
parents:
diff changeset
    89
	/**
hgs
parents:
diff changeset
    90
	 * closing bracket
hgs
parents:
diff changeset
    91
	 */
hgs
parents:
diff changeset
    92
	private static final String CLOSING_BRACKET = ")"; //$NON-NLS-1$
hgs
parents:
diff changeset
    93
hgs
parents:
diff changeset
    94
	/**
hgs
parents:
diff changeset
    95
	 * open bracket
hgs
parents:
diff changeset
    96
	 */
hgs
parents:
diff changeset
    97
	private static final String OPEN_BRACKET = "("; //$NON-NLS-1$
hgs
parents:
diff changeset
    98
hgs
parents:
diff changeset
    99
	/**
hgs
parents:
diff changeset
   100
	 * TUint32 definition
hgs
parents:
diff changeset
   101
	 */
hgs
parents:
diff changeset
   102
	private static final String TUINT32_DEF = "TUint32 "; //$NON-NLS-1$
hgs
parents:
diff changeset
   103
hgs
parents:
diff changeset
   104
	/**
hgs
parents:
diff changeset
   105
	 * TInt32 definition
hgs
parents:
diff changeset
   106
	 */
hgs
parents:
diff changeset
   107
	private static final String TINT32_DEF = "TInt32 "; //$NON-NLS-1$
hgs
parents:
diff changeset
   108
hgs
parents:
diff changeset
   109
	/**
hgs
parents:
diff changeset
   110
	 * TUint definition
hgs
parents:
diff changeset
   111
	 */
hgs
parents:
diff changeset
   112
	private static final String TUINT_DEF = "TUint "; //$NON-NLS-1$
hgs
parents:
diff changeset
   113
hgs
parents:
diff changeset
   114
	/**
hgs
parents:
diff changeset
   115
	 * TInt definition
hgs
parents:
diff changeset
   116
	 */
hgs
parents:
diff changeset
   117
	private static final String TINT_DEF = "TInt "; //$NON-NLS-1$
hgs
parents:
diff changeset
   118
hgs
parents:
diff changeset
   119
	/**
hgs
parents:
diff changeset
   120
	 * Length variable defined flag
hgs
parents:
diff changeset
   121
	 */
hgs
parents:
diff changeset
   122
	private boolean lenghtVariableDefined = false;
hgs
parents:
diff changeset
   123
	
hgs
parents:
diff changeset
   124
	
hgs
parents:
diff changeset
   125
	/**
hgs
parents:
diff changeset
   126
	 * List of dynamic elements that can be used from the templates
hgs
parents:
diff changeset
   127
	 * 
hgs
parents:
diff changeset
   128
	 */
hgs
parents:
diff changeset
   129
	enum HeaderTemplateElementType {
hgs
parents:
diff changeset
   130
hgs
parents:
diff changeset
   131
		/**
hgs
parents:
diff changeset
   132
		 * Licence text
hgs
parents:
diff changeset
   133
		 */
hgs
parents:
diff changeset
   134
		LICENCE_TEXT,
hgs
parents:
diff changeset
   135
		
hgs
parents:
diff changeset
   136
		/**
hgs
parents:
diff changeset
   137
		 * TraceCompiler version number
hgs
parents:
diff changeset
   138
		 */
hgs
parents:
diff changeset
   139
		TRACE_COMPILER_VERSION,
hgs
parents:
diff changeset
   140
hgs
parents:
diff changeset
   141
		/**
hgs
parents:
diff changeset
   142
		 * Header guard based on file name
hgs
parents:
diff changeset
   143
		 */
hgs
parents:
diff changeset
   144
		HEADER_GUARD,
hgs
parents:
diff changeset
   145
hgs
parents:
diff changeset
   146
		/**
hgs
parents:
diff changeset
   147
		 * Opening brace
hgs
parents:
diff changeset
   148
		 */
hgs
parents:
diff changeset
   149
		OPEN_BRACE,
hgs
parents:
diff changeset
   150
hgs
parents:
diff changeset
   151
		/**
hgs
parents:
diff changeset
   152
		 * Closing brace
hgs
parents:
diff changeset
   153
		 */
hgs
parents:
diff changeset
   154
		CLOSE_BRACE,
hgs
parents:
diff changeset
   155
hgs
parents:
diff changeset
   156
		/**
hgs
parents:
diff changeset
   157
		 * New line and indent based on open brace count
hgs
parents:
diff changeset
   158
		 */
hgs
parents:
diff changeset
   159
		NEW_LINE,
hgs
parents:
diff changeset
   160
hgs
parents:
diff changeset
   161
		/**
hgs
parents:
diff changeset
   162
		 * Writes currentTraceFormatted
hgs
parents:
diff changeset
   163
		 */
hgs
parents:
diff changeset
   164
		FORMATTED_TRACE,
hgs
parents:
diff changeset
   165
hgs
parents:
diff changeset
   166
		/**
hgs
parents:
diff changeset
   167
		 * Adds all closing braces except the one that closes the function
hgs
parents:
diff changeset
   168
		 */
hgs
parents:
diff changeset
   169
		CLOSE_EXTRA_BRACES,
hgs
parents:
diff changeset
   170
hgs
parents:
diff changeset
   171
		/**
hgs
parents:
diff changeset
   172
		 * Type of current parameter
hgs
parents:
diff changeset
   173
		 */
hgs
parents:
diff changeset
   174
		PARAMETER_TYPE,
hgs
parents:
diff changeset
   175
hgs
parents:
diff changeset
   176
		/**
hgs
parents:
diff changeset
   177
		 * Name of current parameter
hgs
parents:
diff changeset
   178
		 */
hgs
parents:
diff changeset
   179
		PARAMETER_NAME,
hgs
parents:
diff changeset
   180
hgs
parents:
diff changeset
   181
		/**
hgs
parents:
diff changeset
   182
		 * Name of current trace
hgs
parents:
diff changeset
   183
		 */
hgs
parents:
diff changeset
   184
		TRACE_NAME,
hgs
parents:
diff changeset
   185
hgs
parents:
diff changeset
   186
		/**
hgs
parents:
diff changeset
   187
		 * ID of current trace
hgs
parents:
diff changeset
   188
		 */
hgs
parents:
diff changeset
   189
		TRACE_ID_HEX,
hgs
parents:
diff changeset
   190
hgs
parents:
diff changeset
   191
		/**
hgs
parents:
diff changeset
   192
		 * Calls a function to add the trace buffer initialization code
hgs
parents:
diff changeset
   193
		 */
hgs
parents:
diff changeset
   194
		BUILD_TRACE_BUFFER_CHECK,
hgs
parents:
diff changeset
   195
hgs
parents:
diff changeset
   196
		/**
hgs
parents:
diff changeset
   197
		 * Calls a function to add the function body
hgs
parents:
diff changeset
   198
		 */
hgs
parents:
diff changeset
   199
		TRACE_FUNCTION_BODY,
hgs
parents:
diff changeset
   200
hgs
parents:
diff changeset
   201
		/**
hgs
parents:
diff changeset
   202
		 * Calls a function to add function parameters
hgs
parents:
diff changeset
   203
		 */
hgs
parents:
diff changeset
   204
		TRACE_FUNCTION_PARAMETERS,
hgs
parents:
diff changeset
   205
hgs
parents:
diff changeset
   206
		/**
hgs
parents:
diff changeset
   207
		 * Writes the fixedBufferSize member variable
hgs
parents:
diff changeset
   208
		 */
hgs
parents:
diff changeset
   209
		FIXED_BUFFER_SIZE,
hgs
parents:
diff changeset
   210
hgs
parents:
diff changeset
   211
		/**
hgs
parents:
diff changeset
   212
		 * Writes the dynamicBufferSize member variable
hgs
parents:
diff changeset
   213
		 */
hgs
parents:
diff changeset
   214
		DYNAMIC_BUFFER_SIZE,
hgs
parents:
diff changeset
   215
hgs
parents:
diff changeset
   216
		/**
hgs
parents:
diff changeset
   217
		 * Index of the parameter being processed
hgs
parents:
diff changeset
   218
		 */
hgs
parents:
diff changeset
   219
		PARAMETER_INDEX
hgs
parents:
diff changeset
   220
	}
hgs
parents:
diff changeset
   221
hgs
parents:
diff changeset
   222
	/**
hgs
parents:
diff changeset
   223
	 * Group ID shift bits
hgs
parents:
diff changeset
   224
	 */
hgs
parents:
diff changeset
   225
	private static final int GROUP_SHIFT = 16; // CodForChk_Dis_Magic
hgs
parents:
diff changeset
   226
hgs
parents:
diff changeset
   227
	/**
hgs
parents:
diff changeset
   228
	 * Number of bytes in parameter
hgs
parents:
diff changeset
   229
	 */
hgs
parents:
diff changeset
   230
	private static final int BYTES_IN_PARAMETER = 4; // CodForChk_Dis_Magic
hgs
parents:
diff changeset
   231
hgs
parents:
diff changeset
   232
	/**
hgs
parents:
diff changeset
   233
	 * Indent
hgs
parents:
diff changeset
   234
	 */
hgs
parents:
diff changeset
   235
	private static final String INDENT = "    "; //$NON-NLS-1$
hgs
parents:
diff changeset
   236
hgs
parents:
diff changeset
   237
	/**
hgs
parents:
diff changeset
   238
	 * The header file to be updated
hgs
parents:
diff changeset
   239
	 */
hgs
parents:
diff changeset
   240
	private TraceHeader header;
hgs
parents:
diff changeset
   241
hgs
parents:
diff changeset
   242
	/**
hgs
parents:
diff changeset
   243
	 * Output stream for the header
hgs
parents:
diff changeset
   244
	 */
hgs
parents:
diff changeset
   245
	private OutputStream headerOutput;
hgs
parents:
diff changeset
   246
hgs
parents:
diff changeset
   247
	/**
hgs
parents:
diff changeset
   248
	 * Temporary flag that specifies if a trace requires a trace buffer or it
hgs
parents:
diff changeset
   249
	 * can be represented by the default trace macros
hgs
parents:
diff changeset
   250
	 */
hgs
parents:
diff changeset
   251
	private boolean buildTraceBuffer;
hgs
parents:
diff changeset
   252
hgs
parents:
diff changeset
   253
	/**
hgs
parents:
diff changeset
   254
	 * Temporary variable for fixed size
hgs
parents:
diff changeset
   255
	 */
hgs
parents:
diff changeset
   256
	private int fixedBufferSize;
hgs
parents:
diff changeset
   257
hgs
parents:
diff changeset
   258
	/**
hgs
parents:
diff changeset
   259
	 * Dynamic size flag
hgs
parents:
diff changeset
   260
	 */
hgs
parents:
diff changeset
   261
	private boolean dynamicBufferSizeFlag;
hgs
parents:
diff changeset
   262
hgs
parents:
diff changeset
   263
	/**
hgs
parents:
diff changeset
   264
	 * Flag which is set it trace needs #endif for __KERNEL_MODE__
hgs
parents:
diff changeset
   265
	 */
hgs
parents:
diff changeset
   266
	private boolean needsKernelEndif;
hgs
parents:
diff changeset
   267
hgs
parents:
diff changeset
   268
	/**
hgs
parents:
diff changeset
   269
	 * Used via HeaderTemplateElementType.FORMATTED_TRACE
hgs
parents:
diff changeset
   270
	 */
hgs
parents:
diff changeset
   271
	private String currentTraceFormatted;
hgs
parents:
diff changeset
   272
hgs
parents:
diff changeset
   273
	/**
hgs
parents:
diff changeset
   274
	 * Type of current parameter
hgs
parents:
diff changeset
   275
	 */
hgs
parents:
diff changeset
   276
	private String currentParameterType;
hgs
parents:
diff changeset
   277
hgs
parents:
diff changeset
   278
	/**
hgs
parents:
diff changeset
   279
	 * Name of current parameter
hgs
parents:
diff changeset
   280
	 */
hgs
parents:
diff changeset
   281
	private String currentParameterName;
hgs
parents:
diff changeset
   282
hgs
parents:
diff changeset
   283
	/**
hgs
parents:
diff changeset
   284
	 * Index of current parameter
hgs
parents:
diff changeset
   285
	 */
hgs
parents:
diff changeset
   286
	private int currentParameterIndex;
hgs
parents:
diff changeset
   287
hgs
parents:
diff changeset
   288
	/**
hgs
parents:
diff changeset
   289
	 * Number of opened brackets
hgs
parents:
diff changeset
   290
	 */
hgs
parents:
diff changeset
   291
	private int openBraceCount;
hgs
parents:
diff changeset
   292
hgs
parents:
diff changeset
   293
	/**
hgs
parents:
diff changeset
   294
	 * Trace being processed
hgs
parents:
diff changeset
   295
	 */
hgs
parents:
diff changeset
   296
	private Trace currentTrace;
hgs
parents:
diff changeset
   297
hgs
parents:
diff changeset
   298
	/**
hgs
parents:
diff changeset
   299
	 * Parameter being processed
hgs
parents:
diff changeset
   300
	 */
hgs
parents:
diff changeset
   301
	private TraceParameter currentParameter;
hgs
parents:
diff changeset
   302
hgs
parents:
diff changeset
   303
	/**
hgs
parents:
diff changeset
   304
	 * List of trace functions already in the header
hgs
parents:
diff changeset
   305
	 */
hgs
parents:
diff changeset
   306
	private ArrayList<String> traceDeclarations = new ArrayList<String>();
hgs
parents:
diff changeset
   307
hgs
parents:
diff changeset
   308
	/**
hgs
parents:
diff changeset
   309
	 * Number of sequential new lines
hgs
parents:
diff changeset
   310
	 */
hgs
parents:
diff changeset
   311
	private int newLineCount;
hgs
parents:
diff changeset
   312
hgs
parents:
diff changeset
   313
	/**
hgs
parents:
diff changeset
   314
	 * Number of allowed sequential new lines
hgs
parents:
diff changeset
   315
	 */
hgs
parents:
diff changeset
   316
	private int maxNewLines;
hgs
parents:
diff changeset
   317
hgs
parents:
diff changeset
   318
	/**
hgs
parents:
diff changeset
   319
	 * Indicates that writing a function to the header file is going
hgs
parents:
diff changeset
   320
	 */
hgs
parents:
diff changeset
   321
	private boolean firstOpenBraceFound;
hgs
parents:
diff changeset
   322
	
hgs
parents:
diff changeset
   323
	/**
hgs
parents:
diff changeset
   324
	 * boolean indication that we are buffering a function text
hgs
parents:
diff changeset
   325
	 */
hgs
parents:
diff changeset
   326
	private boolean bufferingFunction;
hgs
parents:
diff changeset
   327
hgs
parents:
diff changeset
   328
	/**
hgs
parents:
diff changeset
   329
	 * While writing a function to the header file, it's gathered to this
hgs
parents:
diff changeset
   330
	 * member. The member is then checked if the function parameters contain
hgs
parents:
diff changeset
   331
	 * TInt or TUint values. If so, the function is replicated so that TInt is
hgs
parents:
diff changeset
   332
	 * replaced by TInt32 and TUint with TUint32.
hgs
parents:
diff changeset
   333
	 */
hgs
parents:
diff changeset
   334
	private StringBuilder functionText = new StringBuilder();
hgs
parents:
diff changeset
   335
hgs
parents:
diff changeset
   336
	/**
hgs
parents:
diff changeset
   337
	 * Number of brackets seen when writing a function. When it gets to 0, the
hgs
parents:
diff changeset
   338
	 * function in previousFunction variable is complete and can be written.
hgs
parents:
diff changeset
   339
	 */
hgs
parents:
diff changeset
   340
	private int numberOfBrackets;
hgs
parents:
diff changeset
   341
		
hgs
parents:
diff changeset
   342
	/**
hgs
parents:
diff changeset
   343
	 * string to hold the function guard
hgs
parents:
diff changeset
   344
	 */
hgs
parents:
diff changeset
   345
	private String ostTraceGenxFunGuard;
hgs
parents:
diff changeset
   346
hgs
parents:
diff changeset
   347
	/**
hgs
parents:
diff changeset
   348
	 * Creates a new header writer
hgs
parents:
diff changeset
   349
	 * 
hgs
parents:
diff changeset
   350
	 * @param header
hgs
parents:
diff changeset
   351
	 *            the header to be written
hgs
parents:
diff changeset
   352
	 */
hgs
parents:
diff changeset
   353
	TraceHeaderWriter(TraceHeader header) {
hgs
parents:
diff changeset
   354
		this.header = header;
hgs
parents:
diff changeset
   355
	}
hgs
parents:
diff changeset
   356
hgs
parents:
diff changeset
   357
	/**
hgs
parents:
diff changeset
   358
	 * Writes the header
hgs
parents:
diff changeset
   359
	 * 
hgs
parents:
diff changeset
   360
	 * @return true if header was written, false if it matched the existing
hgs
parents:
diff changeset
   361
	 *         header
hgs
parents:
diff changeset
   362
	 * @throws TraceCompilerException
hgs
parents:
diff changeset
   363
	 *             if writing fails
hgs
parents:
diff changeset
   364
	 */
hgs
parents:
diff changeset
   365
	boolean write() throws TraceCompilerException {
hgs
parents:
diff changeset
   366
		boolean headerWritten = false;
hgs
parents:
diff changeset
   367
		try {
hgs
parents:
diff changeset
   368
			openBraceCount = 0;
hgs
parents:
diff changeset
   369
			createHeader();
hgs
parents:
diff changeset
   370
			writeTemplate(HeaderTemplate.HEADER_TEMPLATE);
hgs
parents:
diff changeset
   371
			headerWritten = closeHeader();
hgs
parents:
diff changeset
   372
		} catch (IOException e) {
hgs
parents:
diff changeset
   373
			e.printStackTrace();
hgs
parents:
diff changeset
   374
			throw new TraceCompilerException(
hgs
parents:
diff changeset
   375
					TraceCompilerErrorCode.CANNOT_WRITE_PROJECT_FILE, e);
hgs
parents:
diff changeset
   376
		} finally {
hgs
parents:
diff changeset
   377
			traceDeclarations.clear();
hgs
parents:
diff changeset
   378
			if (headerOutput != null) {
hgs
parents:
diff changeset
   379
				try {
hgs
parents:
diff changeset
   380
					headerOutput.close();
hgs
parents:
diff changeset
   381
				} catch (IOException e) {
hgs
parents:
diff changeset
   382
				}
hgs
parents:
diff changeset
   383
			}
hgs
parents:
diff changeset
   384
			headerOutput = null;
hgs
parents:
diff changeset
   385
		}
hgs
parents:
diff changeset
   386
		return headerWritten;
hgs
parents:
diff changeset
   387
	}
hgs
parents:
diff changeset
   388
hgs
parents:
diff changeset
   389
	/**
hgs
parents:
diff changeset
   390
	 * Creates the header file
hgs
parents:
diff changeset
   391
	 * 
hgs
parents:
diff changeset
   392
	 * @throws IOException
hgs
parents:
diff changeset
   393
	 *             if creation fails
hgs
parents:
diff changeset
   394
	 */
hgs
parents:
diff changeset
   395
	private void createHeader() throws IOException {
hgs
parents:
diff changeset
   396
		File file = new File(header.getAbsolutePath());
hgs
parents:
diff changeset
   397
		if (file.exists()) {
hgs
parents:
diff changeset
   398
			// If header exists, data is written to a byte array and compared
hgs
parents:
diff changeset
   399
			// with existing file. If they are the same, the file is not
hgs
parents:
diff changeset
   400
			// updated.
hgs
parents:
diff changeset
   401
			headerOutput = new FileCompareOutputStream(file);
hgs
parents:
diff changeset
   402
		} else {
hgs
parents:
diff changeset
   403
			// If header does not exist, the data is written directly to file
hgs
parents:
diff changeset
   404
			headerOutput = FileUtils.createOutputStream(file);
hgs
parents:
diff changeset
   405
		}
hgs
parents:
diff changeset
   406
	}
hgs
parents:
diff changeset
   407
hgs
parents:
diff changeset
   408
	/**
hgs
parents:
diff changeset
   409
	 * Closes the header file. If data was written to a byte buffer this
hgs
parents:
diff changeset
   410
	 * compares the contents of the buffer with the existing file and re-writes
hgs
parents:
diff changeset
   411
	 * the file if contents do not match.
hgs
parents:
diff changeset
   412
	 * 
hgs
parents:
diff changeset
   413
	 * @return true if header was written, false if it matched the existing
hgs
parents:
diff changeset
   414
	 *         header
hgs
parents:
diff changeset
   415
	 * @throws IOException
hgs
parents:
diff changeset
   416
	 *             if closing fails
hgs
parents:
diff changeset
   417
	 */
hgs
parents:
diff changeset
   418
	private boolean closeHeader() throws IOException {
hgs
parents:
diff changeset
   419
		boolean headerWritten = true;
hgs
parents:
diff changeset
   420
		if (headerOutput instanceof FileCompareOutputStream) {
hgs
parents:
diff changeset
   421
			headerWritten = ((FileCompareOutputStream) headerOutput)
hgs
parents:
diff changeset
   422
					.writeFile();
hgs
parents:
diff changeset
   423
		}
hgs
parents:
diff changeset
   424
		headerOutput.close();
hgs
parents:
diff changeset
   425
		headerOutput = null;
hgs
parents:
diff changeset
   426
		return headerWritten;
hgs
parents:
diff changeset
   427
	}
hgs
parents:
diff changeset
   428
hgs
parents:
diff changeset
   429
	/**
hgs
parents:
diff changeset
   430
	 * Writes a template to the stream
hgs
parents:
diff changeset
   431
	 * 
hgs
parents:
diff changeset
   432
	 * @param template
hgs
parents:
diff changeset
   433
	 *            the template
hgs
parents:
diff changeset
   434
	 * @throws IOException
hgs
parents:
diff changeset
   435
	 *             if writing fails
hgs
parents:
diff changeset
   436
	 */
hgs
parents:
diff changeset
   437
	void writeTemplate(Object[] template) throws IOException {
hgs
parents:
diff changeset
   438
		for (Object o : template) {
hgs
parents:
diff changeset
   439
			if (o instanceof String) {
hgs
parents:
diff changeset
   440
				write((String) o);
hgs
parents:
diff changeset
   441
			} else if (o instanceof TraceHeaderContributionType) {
hgs
parents:
diff changeset
   442
				writeHeaderContributions((TraceHeaderContributionType) o);
hgs
parents:
diff changeset
   443
			} else if (o instanceof HeaderTemplateElementType) {
hgs
parents:
diff changeset
   444
				writeTemplateElement((HeaderTemplateElementType) o);
hgs
parents:
diff changeset
   445
			} else if (o instanceof Object[]) {
hgs
parents:
diff changeset
   446
				// Template within template
hgs
parents:
diff changeset
   447
				writeTemplate((Object[]) o);
hgs
parents:
diff changeset
   448
			} else if (o instanceof TemplateChoice) {
hgs
parents:
diff changeset
   449
				TemplateChoice choice = (TemplateChoice) o;
hgs
parents:
diff changeset
   450
				// Gets the array index from template
hgs
parents:
diff changeset
   451
				Class<? extends TemplateCheckBase> c = choice.getChoiceClass();
hgs
parents:
diff changeset
   452
				try {
hgs
parents:
diff changeset
   453
					// Creates a switch-case object based on array index
hgs
parents:
diff changeset
   454
					TemplateCheckBase check = c.newInstance();
hgs
parents:
diff changeset
   455
					check.setWriter(this);
hgs
parents:
diff changeset
   456
					// Gets the case from the switch-case object and uses it to
hgs
parents:
diff changeset
   457
					// get the correct template
hgs
parents:
diff changeset
   458
					if (check.check()) {
hgs
parents:
diff changeset
   459
						writeTemplate(choice.getTrueTemplate());
hgs
parents:
diff changeset
   460
					} else {
hgs
parents:
diff changeset
   461
						writeTemplate(choice.getFalseTemplate());
hgs
parents:
diff changeset
   462
					}
hgs
parents:
diff changeset
   463
				} catch (InstantiationException e) {
hgs
parents:
diff changeset
   464
				} catch (IllegalAccessException e) {
hgs
parents:
diff changeset
   465
				}
hgs
parents:
diff changeset
   466
			} else if (o instanceof TemplateIterator) {
hgs
parents:
diff changeset
   467
				Class<? extends TemplateIteratorEntry> c = ((TemplateIterator) o)
hgs
parents:
diff changeset
   468
						.getIteratorClass();
hgs
parents:
diff changeset
   469
				try {
hgs
parents:
diff changeset
   470
					// Creates an iterator object based on array index
hgs
parents:
diff changeset
   471
					TemplateIteratorEntry itr = c.newInstance();
hgs
parents:
diff changeset
   472
					itr.setWriter(this);
hgs
parents:
diff changeset
   473
					itr.iterate(((TemplateIterator) o).getTemplate());
hgs
parents:
diff changeset
   474
				} catch (InstantiationException e) {
hgs
parents:
diff changeset
   475
				} catch (IllegalAccessException e) {
hgs
parents:
diff changeset
   476
				}
hgs
parents:
diff changeset
   477
			} else if (o instanceof SetNewLineCount) {
hgs
parents:
diff changeset
   478
				maxNewLines = ((SetNewLineCount) o).getLineCount();
hgs
parents:
diff changeset
   479
			} else if (o instanceof TraceFormatType) {
hgs
parents:
diff changeset
   480
				// Stores the formatted trace, but does not write anything
hgs
parents:
diff changeset
   481
				// HeaderTemplateElementType.FORMATTED_TRACE writes the trace
hgs
parents:
diff changeset
   482
				currentTraceFormatted = SourceFormatter.formatTrace(
hgs
parents:
diff changeset
   483
						currentTrace, (TraceFormatType) o);
hgs
parents:
diff changeset
   484
			}
hgs
parents:
diff changeset
   485
		}
hgs
parents:
diff changeset
   486
	}
hgs
parents:
diff changeset
   487
hgs
parents:
diff changeset
   488
	/**
hgs
parents:
diff changeset
   489
	 * Writes an element from the HeaderTemplateElementType enumeration
hgs
parents:
diff changeset
   490
	 * 
hgs
parents:
diff changeset
   491
	 * @param type
hgs
parents:
diff changeset
   492
	 *            the element type
hgs
parents:
diff changeset
   493
	 * @throws IOException
hgs
parents:
diff changeset
   494
	 *             if writing fails
hgs
parents:
diff changeset
   495
	 */
hgs
parents:
diff changeset
   496
	private void writeTemplateElement(HeaderTemplateElementType type)
hgs
parents:
diff changeset
   497
			throws IOException { // CodForChk_Dis_ComplexFunc
hgs
parents:
diff changeset
   498
		switch (type) {
hgs
parents:
diff changeset
   499
		case NEW_LINE:
hgs
parents:
diff changeset
   500
			writeNewLine();
hgs
parents:
diff changeset
   501
			break;
hgs
parents:
diff changeset
   502
		case OPEN_BRACE:
hgs
parents:
diff changeset
   503
			writeOpenBrace();
hgs
parents:
diff changeset
   504
			break;
hgs
parents:
diff changeset
   505
		case CLOSE_BRACE:
hgs
parents:
diff changeset
   506
			writeCloseBrace();
hgs
parents:
diff changeset
   507
			break;
hgs
parents:
diff changeset
   508
		case PARAMETER_INDEX:
hgs
parents:
diff changeset
   509
			write(String.valueOf(currentParameterIndex));
hgs
parents:
diff changeset
   510
			break;
hgs
parents:
diff changeset
   511
		case PARAMETER_TYPE:
hgs
parents:
diff changeset
   512
			write(currentParameterType);
hgs
parents:
diff changeset
   513
			break;
hgs
parents:
diff changeset
   514
		case PARAMETER_NAME:
hgs
parents:
diff changeset
   515
			write(currentParameterName);
hgs
parents:
diff changeset
   516
			break;
hgs
parents:
diff changeset
   517
		case FORMATTED_TRACE:
hgs
parents:
diff changeset
   518
			writeFormattedTrace(currentTraceFormatted);
hgs
parents:
diff changeset
   519
			break;
hgs
parents:
diff changeset
   520
		case TRACE_NAME:
hgs
parents:
diff changeset
   521
			write(currentTrace.getName());
hgs
parents:
diff changeset
   522
			break;
hgs
parents:
diff changeset
   523
		case TRACE_ID_HEX:
hgs
parents:
diff changeset
   524
			writeTraceID();
hgs
parents:
diff changeset
   525
			break;
hgs
parents:
diff changeset
   526
		case FIXED_BUFFER_SIZE:
hgs
parents:
diff changeset
   527
			write(String.valueOf(fixedBufferSize));
hgs
parents:
diff changeset
   528
			break;
hgs
parents:
diff changeset
   529
		case TRACE_FUNCTION_BODY:
hgs
parents:
diff changeset
   530
			writeFunctionBody(currentTrace);
hgs
parents:
diff changeset
   531
			break;
hgs
parents:
diff changeset
   532
		case TRACE_FUNCTION_PARAMETERS:
hgs
parents:
diff changeset
   533
			writeParameter(currentParameter);
hgs
parents:
diff changeset
   534
			break;
hgs
parents:
diff changeset
   535
		case BUILD_TRACE_BUFFER_CHECK:
hgs
parents:
diff changeset
   536
			buildTraceBuffer = traceNeedsBuffer(currentTrace);
hgs
parents:
diff changeset
   537
			break;
hgs
parents:
diff changeset
   538
		case HEADER_GUARD:
hgs
parents:
diff changeset
   539
			write(SourceUtils.createHeaderGuard(header.getFileName()));
hgs
parents:
diff changeset
   540
			break;
hgs
parents:
diff changeset
   541
		case TRACE_COMPILER_VERSION:
hgs
parents:
diff changeset
   542
			write(TraceCompilerVersion.getVersion());
hgs
parents:
diff changeset
   543
			break;
hgs
parents:
diff changeset
   544
		case CLOSE_EXTRA_BRACES:
hgs
parents:
diff changeset
   545
			while (openBraceCount > 1) {
hgs
parents:
diff changeset
   546
				writeCloseBrace();
hgs
parents:
diff changeset
   547
			}
hgs
parents:
diff changeset
   548
			break;
hgs
parents:
diff changeset
   549
		case LICENCE_TEXT:
hgs
parents:
diff changeset
   550
		    writeLicence();
hgs
parents:
diff changeset
   551
		    break;
hgs
parents:
diff changeset
   552
		}
hgs
parents:
diff changeset
   553
	}
hgs
parents:
diff changeset
   554
hgs
parents:
diff changeset
   555
	/**
hgs
parents:
diff changeset
   556
	 * Writes the trace ID to header
hgs
parents:
diff changeset
   557
	 * 
hgs
parents:
diff changeset
   558
	 * @throws IOException
hgs
parents:
diff changeset
   559
	 *             if writing fails
hgs
parents:
diff changeset
   560
	 */
hgs
parents:
diff changeset
   561
	private void writeTraceID() throws IOException {
hgs
parents:
diff changeset
   562
		int gid = currentTrace.getGroup().getID() << GROUP_SHIFT;
hgs
parents:
diff changeset
   563
		write(Integer.toHexString(gid | currentTrace.getID()));
hgs
parents:
diff changeset
   564
		ComplexHeaderRule rule = currentTrace
hgs
parents:
diff changeset
   565
				.getExtension(ComplexHeaderRule.class);
hgs
parents:
diff changeset
   566
		if (rule != null) {
hgs
parents:
diff changeset
   567
			String ext = rule.getTraceIDDefineExtension();
hgs
parents:
diff changeset
   568
			if (ext != null) {
hgs
parents:
diff changeset
   569
				write(ext);
hgs
parents:
diff changeset
   570
			}
hgs
parents:
diff changeset
   571
		}
hgs
parents:
diff changeset
   572
	}
hgs
parents:
diff changeset
   573
hgs
parents:
diff changeset
   574
	/**
hgs
parents:
diff changeset
   575
	 * Writes the header contributions from plug-in's
hgs
parents:
diff changeset
   576
	 * 
hgs
parents:
diff changeset
   577
	 * @param type
hgs
parents:
diff changeset
   578
	 *            the contribution type
hgs
parents:
diff changeset
   579
	 * @throws IOException
hgs
parents:
diff changeset
   580
	 *             if writing fails
hgs
parents:
diff changeset
   581
	 */
hgs
parents:
diff changeset
   582
	private void writeHeaderContributions(TraceHeaderContributionType type)
hgs
parents:
diff changeset
   583
			throws IOException {
hgs
parents:
diff changeset
   584
		Iterator<String> contributions = getContributions(type);
hgs
parents:
diff changeset
   585
		boolean written = false;
hgs
parents:
diff changeset
   586
		while (contributions.hasNext()) {
hgs
parents:
diff changeset
   587
			writeContribution(contributions.next(), type);
hgs
parents:
diff changeset
   588
			written = true;
hgs
parents:
diff changeset
   589
		}
hgs
parents:
diff changeset
   590
		if (written) {
hgs
parents:
diff changeset
   591
			writeNewLine();
hgs
parents:
diff changeset
   592
		}
hgs
parents:
diff changeset
   593
	}
hgs
parents:
diff changeset
   594
hgs
parents:
diff changeset
   595
	/**
hgs
parents:
diff changeset
   596
	 * Gets a list of contributions from plug-in's
hgs
parents:
diff changeset
   597
	 * 
hgs
parents:
diff changeset
   598
	 * @param type
hgs
parents:
diff changeset
   599
	 *            the contribution type
hgs
parents:
diff changeset
   600
	 * @return the contributions
hgs
parents:
diff changeset
   601
	 */
hgs
parents:
diff changeset
   602
	private Iterator<String> getContributions(TraceHeaderContributionType type) {
hgs
parents:
diff changeset
   603
		Iterator<TraceHeaderContribution> contributions = header.getOwner()
hgs
parents:
diff changeset
   604
				.getExtensions(TraceHeaderContribution.class);
hgs
parents:
diff changeset
   605
		ArrayList<String> list = new ArrayList<String>();
hgs
parents:
diff changeset
   606
		while (contributions.hasNext()) {
hgs
parents:
diff changeset
   607
			String[] s = contributions.next().getContribution(type);
hgs
parents:
diff changeset
   608
			if (s != null) {
hgs
parents:
diff changeset
   609
				for (String element : s) {
hgs
parents:
diff changeset
   610
					list.add(element);
hgs
parents:
diff changeset
   611
				}
hgs
parents:
diff changeset
   612
			}
hgs
parents:
diff changeset
   613
		}
hgs
parents:
diff changeset
   614
		return list.iterator();
hgs
parents:
diff changeset
   615
	}
hgs
parents:
diff changeset
   616
hgs
parents:
diff changeset
   617
	/**
hgs
parents:
diff changeset
   618
	 * Writes a contribution to the stream
hgs
parents:
diff changeset
   619
	 * 
hgs
parents:
diff changeset
   620
	 * @param contribution
hgs
parents:
diff changeset
   621
	 *            the contribution
hgs
parents:
diff changeset
   622
	 * @param type
hgs
parents:
diff changeset
   623
	 *            the contribution type
hgs
parents:
diff changeset
   624
	 * @throws IOException
hgs
parents:
diff changeset
   625
	 *             if writing fails
hgs
parents:
diff changeset
   626
	 */
hgs
parents:
diff changeset
   627
	private void writeContribution(String contribution,
hgs
parents:
diff changeset
   628
			TraceHeaderContributionType type) throws IOException {
hgs
parents:
diff changeset
   629
		switch (type) {
hgs
parents:
diff changeset
   630
		case GLOBAL_DEFINES:
hgs
parents:
diff changeset
   631
			writeDefine(contribution);
hgs
parents:
diff changeset
   632
			break;
hgs
parents:
diff changeset
   633
		case GLOBAL_INCLUDES:
hgs
parents:
diff changeset
   634
			writeSystemInclude(contribution);
hgs
parents:
diff changeset
   635
			break;
hgs
parents:
diff changeset
   636
		case MAIN_HEADER_CONTENT:
hgs
parents:
diff changeset
   637
			// Handled by HeaderEngine
hgs
parents:
diff changeset
   638
			break;
hgs
parents:
diff changeset
   639
		}
hgs
parents:
diff changeset
   640
	}
hgs
parents:
diff changeset
   641
	
hgs
parents:
diff changeset
   642
	/**
hgs
parents:
diff changeset
   643
	 * write start of function guard
hgs
parents:
diff changeset
   644
	 * @throws IOException
hgs
parents:
diff changeset
   645
	 */
hgs
parents:
diff changeset
   646
	private void writeStartFunctionGuard() throws IOException {
hgs
parents:
diff changeset
   647
		Pattern p = Pattern.compile("inline\\s+TBool\\s+([^\\(]+)\\s*\\((.*)\\)\\s*\\{"); //$NON-NLS-1$
hgs
parents:
diff changeset
   648
		String guard = null;
hgs
parents:
diff changeset
   649
		String functionName = null;
hgs
parents:
diff changeset
   650
		
hgs
parents:
diff changeset
   651
		// Get the function definition line
hgs
parents:
diff changeset
   652
		int startIndex = functionText.indexOf(SourceConstants.OPENING_BRACE) + 1;
hgs
parents:
diff changeset
   653
		String funcDef = functionText.substring(0, startIndex);
hgs
parents:
diff changeset
   654
		
hgs
parents:
diff changeset
   655
		Matcher m = p.matcher(funcDef);
hgs
parents:
diff changeset
   656
		if (m.matches()) {
hgs
parents:
diff changeset
   657
			//get function name
hgs
parents:
diff changeset
   658
			functionName = m.group(1);
hgs
parents:
diff changeset
   659
			if (functionName == null || functionName.length() == 0) {
hgs
parents:
diff changeset
   660
				throw new IOException(Messages.getString("TraceHeader.internalError1")); //$NON-NLS-1$
hgs
parents:
diff changeset
   661
			}
hgs
parents:
diff changeset
   662
			//get raw parameters
hgs
parents:
diff changeset
   663
			String parameters = m.group(2);
hgs
parents:
diff changeset
   664
			if (parameters == null || parameters.length() == 0) {//there must be at least TraceID
hgs
parents:
diff changeset
   665
				throw new IOException(Messages.getString("TraceHeader.internalError2")); //$NON-NLS-1$
hgs
parents:
diff changeset
   666
			}
hgs
parents:
diff changeset
   667
			
hgs
parents:
diff changeset
   668
			functionName = functionName.trim();
hgs
parents:
diff changeset
   669
			parameters = parameters.trim();
hgs
parents:
diff changeset
   670
			//remove parameters names
hgs
parents:
diff changeset
   671
			guard = parameters.replaceAll("(\\S+,)|(\\S+\\s*$)", ""); //$NON-NLS-1$ //$NON-NLS-2$
hgs
parents:
diff changeset
   672
			//replace repeated spaces by one space
hgs
parents:
diff changeset
   673
			guard = guard.replaceAll("\\s+", SourceConstants.SPACE).trim(); //$NON-NLS-1$
hgs
parents:
diff changeset
   674
			//replace space by underscore
hgs
parents:
diff changeset
   675
			guard = guard.replace(SourceConstants.SPACE, SourceConstants.UNDERSCORE);
hgs
parents:
diff changeset
   676
			//replace ampersant by REF
hgs
parents:
diff changeset
   677
			guard = guard.replace(AMPERSANT, REF);
hgs
parents:
diff changeset
   678
			//replace ( by OBR
hgs
parents:
diff changeset
   679
			guard = guard.replace(OPEN_BRACKET, BEGINCAST);
hgs
parents:
diff changeset
   680
			//replace ) by CBR
hgs
parents:
diff changeset
   681
			guard = guard.replace(CLOSING_BRACKET, ENDCAST);
hgs
parents:
diff changeset
   682
		} else {
hgs
parents:
diff changeset
   683
			throw new IOException(Messages.getString("TraceHeader.internalError3")); //$NON-NLS-1$
hgs
parents:
diff changeset
   684
		}
hgs
parents:
diff changeset
   685
		
hgs
parents:
diff changeset
   686
		guard = SourceConstants.DOUBLE_UNDERSCORE 
hgs
parents:
diff changeset
   687
				+ functionName.toUpperCase()
hgs
parents:
diff changeset
   688
				+ SourceConstants.UNDERSCORE
hgs
parents:
diff changeset
   689
				+ guard.toUpperCase()
hgs
parents:
diff changeset
   690
				+ SourceConstants.DOUBLE_UNDERSCORE;
hgs
parents:
diff changeset
   691
		
hgs
parents:
diff changeset
   692
		ostTraceGenxFunGuard = guard;
hgs
parents:
diff changeset
   693
		write( SourceConstants.IFNDEF + SourceConstants.SPACE_CHAR + ostTraceGenxFunGuard);
hgs
parents:
diff changeset
   694
		write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
   695
		write( SourceConstants.DEFINE +SourceConstants.SPACE_CHAR + ostTraceGenxFunGuard);
hgs
parents:
diff changeset
   696
		write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
   697
		write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
   698
	}
hgs
parents:
diff changeset
   699
hgs
parents:
diff changeset
   700
	/**
hgs
parents:
diff changeset
   701
	 * write end of function guard
hgs
parents:
diff changeset
   702
	 * @throws IOException
hgs
parents:
diff changeset
   703
	 */
hgs
parents:
diff changeset
   704
	private void writeEndFunctionGuard() throws IOException {
hgs
parents:
diff changeset
   705
		if (ostTraceGenxFunGuard != null) {
hgs
parents:
diff changeset
   706
			write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
   707
			write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
   708
			write(SourceConstants.ENDIF 
hgs
parents:
diff changeset
   709
					+ SourceConstants.SPACE_CHAR
hgs
parents:
diff changeset
   710
					+ SourceConstants.FORWARD_SLASH_CHAR
hgs
parents:
diff changeset
   711
					+ SourceConstants.FORWARD_SLASH_CHAR
hgs
parents:
diff changeset
   712
					+ SourceConstants.SPACE_CHAR
hgs
parents:
diff changeset
   713
					+ ostTraceGenxFunGuard);
hgs
parents:
diff changeset
   714
			write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
   715
		}
hgs
parents:
diff changeset
   716
	}
hgs
parents:
diff changeset
   717
	/**
hgs
parents:
diff changeset
   718
	 * Writes the function body to the stream
hgs
parents:
diff changeset
   719
	 * 
hgs
parents:
diff changeset
   720
	 * @param trace
hgs
parents:
diff changeset
   721
	 *            the trace to be written
hgs
parents:
diff changeset
   722
	 * @throws IOException
hgs
parents:
diff changeset
   723
	 *             if writing fails
hgs
parents:
diff changeset
   724
	 */
hgs
parents:
diff changeset
   725
	private void writeFunctionBody(Trace trace) throws IOException {
hgs
parents:
diff changeset
   726
		writeTraceBufferAllocation(trace);
hgs
parents:
diff changeset
   727
		writeTemplate(HeaderTemplate.PARAMETERS_TEMPLATE);
hgs
parents:
diff changeset
   728
		// If buffer is not used (single descriptor parameter), trace line is
hgs
parents:
diff changeset
   729
		// already written in template
hgs
parents:
diff changeset
   730
		if (isTraceBufferBuilt()) {
hgs
parents:
diff changeset
   731
			writeTraceLine(trace);
hgs
parents:
diff changeset
   732
		}
hgs
parents:
diff changeset
   733
	}
hgs
parents:
diff changeset
   734
hgs
parents:
diff changeset
   735
	/**
hgs
parents:
diff changeset
   736
	 * Writes trace buffer allocation code to the function
hgs
parents:
diff changeset
   737
	 * 
hgs
parents:
diff changeset
   738
	 * @param trace
hgs
parents:
diff changeset
   739
	 *            the trace to be written
hgs
parents:
diff changeset
   740
	 * @throws IOException
hgs
parents:
diff changeset
   741
	 *             if writing fails
hgs
parents:
diff changeset
   742
	 */
hgs
parents:
diff changeset
   743
	private void writeTraceBufferAllocation(Trace trace) throws IOException {
hgs
parents:
diff changeset
   744
		// If buffer is not used (single descriptor parameter), this function
hgs
parents:
diff changeset
   745
		// does nothing
hgs
parents:
diff changeset
   746
		if (isTraceBufferBuilt()) {
hgs
parents:
diff changeset
   747
			Iterator<TraceParameter> parameters = trace.getParameters();
hgs
parents:
diff changeset
   748
			lenghtVariableDefined = false;
hgs
parents:
diff changeset
   749
			int fixedSizeParametersTotalSize = 0;
hgs
parents:
diff changeset
   750
			while (parameters.hasNext()) {
hgs
parents:
diff changeset
   751
				TraceParameter parameter = parameters.next();
hgs
parents:
diff changeset
   752
				TraceParameterFormattingRule sourceRule = parameter
hgs
parents:
diff changeset
   753
						.getExtension(TraceParameterFormattingRule.class);
hgs
parents:
diff changeset
   754
				if (sourceRule == null || sourceRule.isShownInSource()
hgs
parents:
diff changeset
   755
						|| sourceRule instanceof FillerParameterRule) {
hgs
parents:
diff changeset
   756
					// Fillers do not increment parameter index
hgs
parents:
diff changeset
   757
					if (!(sourceRule instanceof FillerParameterRule)) {
hgs
parents:
diff changeset
   758
						currentParameterIndex++;
hgs
parents:
diff changeset
   759
					}
hgs
parents:
diff changeset
   760
					int paramSize = SourceUtils
hgs
parents:
diff changeset
   761
							.mapParameterTypeToSize(parameter);
hgs
parents:
diff changeset
   762
					// calculateParameterSize returns 0 for dynamic parameters,
hgs
parents:
diff changeset
   763
					// but 4 extra bytes need to be reserved for the length
hgs
parents:
diff changeset
   764
					if (paramSize == 0) {
hgs
parents:
diff changeset
   765
						paramSize = BYTES_IN_PARAMETER;
hgs
parents:
diff changeset
   766
					}
hgs
parents:
diff changeset
   767
					fixedBufferSize += paramSize;
hgs
parents:
diff changeset
   768
					fixedSizeParametersTotalSize += paramSize;
hgs
parents:
diff changeset
   769
					if (SourceUtils.isParameterSizeDynamic(parameter)) {
hgs
parents:
diff changeset
   770
hgs
parents:
diff changeset
   771
						// Define length variable only once
hgs
parents:
diff changeset
   772
						if (lenghtVariableDefined == false) {
hgs
parents:
diff changeset
   773
							writeTemplate(HeaderTemplate.LENGTH_VARIABLE_DEFINITION_TEMPLATE);
hgs
parents:
diff changeset
   774
							lenghtVariableDefined = true;
hgs
parents:
diff changeset
   775
						}
hgs
parents:
diff changeset
   776
hgs
parents:
diff changeset
   777
						// Increase length variable if needed
hgs
parents:
diff changeset
   778
						// This is needed in case that there has been fixed size
hgs
parents:
diff changeset
   779
						// parameter
hgs
parents:
diff changeset
   780
						// before dynamic parameter
hgs
parents:
diff changeset
   781
						if (fixedSizeParametersTotalSize - paramSize > 0) {
hgs
parents:
diff changeset
   782
							fixedSizeParametersTotalSize -= paramSize;
hgs
parents:
diff changeset
   783
							writeTemplate(HeaderTemplate.LENGTH_VARIABLE_INCREASE_TEMPLATE_BEGIN);
hgs
parents:
diff changeset
   784
							write(String.valueOf(fixedSizeParametersTotalSize));
hgs
parents:
diff changeset
   785
							writeTemplate(HeaderTemplate.LENGTH_VARIABLE_INCREASE_TEMPLATE_END);
hgs
parents:
diff changeset
   786
						}
hgs
parents:
diff changeset
   787
hgs
parents:
diff changeset
   788
						fixedSizeParametersTotalSize = 0;
hgs
parents:
diff changeset
   789
hgs
parents:
diff changeset
   790
						writeTemplate(HeaderTemplate.DYNAMIC_PARAMETER_LENGTH_TEMPLATE);
hgs
parents:
diff changeset
   791
						dynamicBufferSizeFlag = true;
hgs
parents:
diff changeset
   792
					}
hgs
parents:
diff changeset
   793
				}
hgs
parents:
diff changeset
   794
			}
hgs
parents:
diff changeset
   795
			writeTemplate(HeaderTemplate.BUFFER_ALLOCATION_TEMPLATE);
hgs
parents:
diff changeset
   796
			currentParameterIndex = 0;
hgs
parents:
diff changeset
   797
		}
hgs
parents:
diff changeset
   798
	}
hgs
parents:
diff changeset
   799
hgs
parents:
diff changeset
   800
	/**
hgs
parents:
diff changeset
   801
	 * Writes the given parameter to the header
hgs
parents:
diff changeset
   802
	 * 
hgs
parents:
diff changeset
   803
	 * @param parameter
hgs
parents:
diff changeset
   804
	 *            the parameter
hgs
parents:
diff changeset
   805
	 * @throws IOException
hgs
parents:
diff changeset
   806
	 *             if writing fails
hgs
parents:
diff changeset
   807
	 */
hgs
parents:
diff changeset
   808
	void writeParameter(TraceParameter parameter) throws IOException {
hgs
parents:
diff changeset
   809
		TraceParameterFormattingRule sourceRule = parameter
hgs
parents:
diff changeset
   810
				.getExtension(TraceParameterFormattingRule.class);
hgs
parents:
diff changeset
   811
		if (sourceRule == null || sourceRule.isShownInSource()
hgs
parents:
diff changeset
   812
				|| sourceRule instanceof FillerParameterRule) {
hgs
parents:
diff changeset
   813
			String paramType = SourceUtils
hgs
parents:
diff changeset
   814
					.mapParameterTypeToSymbianType(parameter);
hgs
parents:
diff changeset
   815
			if (SourceUtils.isParameterSizeDynamic(parameter)) {
hgs
parents:
diff changeset
   816
				currentParameterIndex++;
hgs
parents:
diff changeset
   817
				currentParameterName = SymbianConstants.PARAMETER_DECLARATION_PREFIX
hgs
parents:
diff changeset
   818
						+ currentParameterIndex;
hgs
parents:
diff changeset
   819
				writeTemplate(HeaderTemplate.DYNAMIC_PARAMETER_TEMPLATE);
hgs
parents:
diff changeset
   820
			} else {
hgs
parents:
diff changeset
   821
				currentParameterType = paramType;
hgs
parents:
diff changeset
   822
				if (sourceRule instanceof FillerParameterRule) {
hgs
parents:
diff changeset
   823
					currentParameterName = "0"; //$NON-NLS-1$
hgs
parents:
diff changeset
   824
					writeTemplate(HeaderTemplate.FIXED_PARAMETER_TEMPLATE);
hgs
parents:
diff changeset
   825
				} else {
hgs
parents:
diff changeset
   826
					currentParameterIndex++;
hgs
parents:
diff changeset
   827
					currentParameterName = SymbianConstants.PARAMETER_DECLARATION_PREFIX
hgs
parents:
diff changeset
   828
							+ currentParameterIndex;
hgs
parents:
diff changeset
   829
					if (lenghtVariableDefined == true) {
hgs
parents:
diff changeset
   830
						writeTemplate(HeaderTemplate.FIXED_PARAMETER_TEMPLATE_WITH_LENGTH_CHECK);
hgs
parents:
diff changeset
   831
					} else {
hgs
parents:
diff changeset
   832
						writeTemplate(HeaderTemplate.FIXED_PARAMETER_TEMPLATE);
hgs
parents:
diff changeset
   833
					}
hgs
parents:
diff changeset
   834
				}
hgs
parents:
diff changeset
   835
			}
hgs
parents:
diff changeset
   836
		}
hgs
parents:
diff changeset
   837
	}
hgs
parents:
diff changeset
   838
hgs
parents:
diff changeset
   839
	/**
hgs
parents:
diff changeset
   840
	 * Writes the trace line to the function
hgs
parents:
diff changeset
   841
	 * 
hgs
parents:
diff changeset
   842
	 * @param trace
hgs
parents:
diff changeset
   843
	 *            the trace to be written
hgs
parents:
diff changeset
   844
	 * @throws IOException
hgs
parents:
diff changeset
   845
	 *             if writing fails
hgs
parents:
diff changeset
   846
	 */
hgs
parents:
diff changeset
   847
	private void writeTraceLine(Trace trace) throws IOException {
hgs
parents:
diff changeset
   848
		StringBuffer sb;
hgs
parents:
diff changeset
   849
		StringBuffer bufferData = new StringBuffer();
hgs
parents:
diff changeset
   850
		StringBuffer lengthData = new StringBuffer();
hgs
parents:
diff changeset
   851
		if (isBufferSizeDynamic()) {
hgs
parents:
diff changeset
   852
			sb = writeBufferedTraceLine(trace, bufferData, lengthData);
hgs
parents:
diff changeset
   853
		} else {
hgs
parents:
diff changeset
   854
			// If buffer size is 4, the buffer can be traced using the
hgs
parents:
diff changeset
   855
			// the 32-bit parameter trace macro instead of data macro
hgs
parents:
diff changeset
   856
			if (fixedBufferSize / BYTES_IN_PARAMETER == 1) {
hgs
parents:
diff changeset
   857
				sb = writePackedTraceLine(trace, bufferData);
hgs
parents:
diff changeset
   858
			} else {
hgs
parents:
diff changeset
   859
				sb = writeBufferedTraceLine(trace, bufferData, lengthData);
hgs
parents:
diff changeset
   860
			}
hgs
parents:
diff changeset
   861
		}
hgs
parents:
diff changeset
   862
		int index = sb.indexOf(TraceFormatConstants.DATA_BUFFER_FORMAT);
hgs
parents:
diff changeset
   863
		if (index >= 0) {
hgs
parents:
diff changeset
   864
			sb.replace(index, index
hgs
parents:
diff changeset
   865
					+ TraceFormatConstants.DATA_BUFFER_FORMAT.length(),
hgs
parents:
diff changeset
   866
					bufferData.toString());
hgs
parents:
diff changeset
   867
		}
hgs
parents:
diff changeset
   868
		index = sb.indexOf(TraceFormatConstants.DATA_LENGTH_FORMAT);
hgs
parents:
diff changeset
   869
		if (index >= 0) {
hgs
parents:
diff changeset
   870
			sb.replace(index, index
hgs
parents:
diff changeset
   871
					+ TraceFormatConstants.DATA_LENGTH_FORMAT.length(),
hgs
parents:
diff changeset
   872
					lengthData.toString());
hgs
parents:
diff changeset
   873
		}
hgs
parents:
diff changeset
   874
		String s = sb.toString();
hgs
parents:
diff changeset
   875
		write("retval = "); //$NON-NLS-1$
hgs
parents:
diff changeset
   876
		writeFormattedTrace(s);
hgs
parents:
diff changeset
   877
		writeNewLine();
hgs
parents:
diff changeset
   878
	}
hgs
parents:
diff changeset
   879
hgs
parents:
diff changeset
   880
	/**
hgs
parents:
diff changeset
   881
	 * Writes a trace line when the parameters can be fitted into a direct API
hgs
parents:
diff changeset
   882
	 * call
hgs
parents:
diff changeset
   883
	 * 
hgs
parents:
diff changeset
   884
	 * @param trace
hgs
parents:
diff changeset
   885
	 *            the trace
hgs
parents:
diff changeset
   886
	 * @param bufferData
hgs
parents:
diff changeset
   887
	 *            the buffer
hgs
parents:
diff changeset
   888
	 * @return formatted trace
hgs
parents:
diff changeset
   889
	 */
hgs
parents:
diff changeset
   890
	private StringBuffer writePackedTraceLine(Trace trace,
hgs
parents:
diff changeset
   891
			StringBuffer bufferData) {
hgs
parents:
diff changeset
   892
		StringBuffer sb;
hgs
parents:
diff changeset
   893
		// The formatting rule is used to get the API macro
hgs
parents:
diff changeset
   894
		sb = new StringBuffer(SourceFormatter.formatTrace(trace,
hgs
parents:
diff changeset
   895
				TraceFormatType.TRACE_PACKED));
hgs
parents:
diff changeset
   896
		TraceFormattingRule rule = trace
hgs
parents:
diff changeset
   897
				.getExtension(TraceFormattingRule.class);
hgs
parents:
diff changeset
   898
		if (rule == null) {
hgs
parents:
diff changeset
   899
			rule = trace.getModel().getExtension(TraceFormattingRule.class);
hgs
parents:
diff changeset
   900
		}
hgs
parents:
diff changeset
   901
		int index = sb.indexOf(TraceFormatConstants.PARAM_COUNT_FORMAT);
hgs
parents:
diff changeset
   902
		if (index >= 0) {
hgs
parents:
diff changeset
   903
			// Single parameter is supported
hgs
parents:
diff changeset
   904
			sb.replace(index, index
hgs
parents:
diff changeset
   905
					+ TraceFormatConstants.PARAM_COUNT_FORMAT.length(), rule
hgs
parents:
diff changeset
   906
					.mapParameterCountToSource(trace, 1));
hgs
parents:
diff changeset
   907
		}
hgs
parents:
diff changeset
   908
		bufferData.append("*( ( TUint32* )ptr )"); //$NON-NLS-1$
hgs
parents:
diff changeset
   909
		return sb;
hgs
parents:
diff changeset
   910
	}
hgs
parents:
diff changeset
   911
hgs
parents:
diff changeset
   912
	/**
hgs
parents:
diff changeset
   913
	 * Writes a trace line when the trace contains more data that the API
hgs
parents:
diff changeset
   914
	 * supports
hgs
parents:
diff changeset
   915
	 * 
hgs
parents:
diff changeset
   916
	 * @param trace
hgs
parents:
diff changeset
   917
	 *            the trace
hgs
parents:
diff changeset
   918
	 * @param bufferData
hgs
parents:
diff changeset
   919
	 *            the trace buffer
hgs
parents:
diff changeset
   920
	 * @param lengthData
hgs
parents:
diff changeset
   921
	 *            the trace length buffer
hgs
parents:
diff changeset
   922
	 * @return the formatted trace
hgs
parents:
diff changeset
   923
	 */
hgs
parents:
diff changeset
   924
	private StringBuffer writeBufferedTraceLine(Trace trace,
hgs
parents:
diff changeset
   925
			StringBuffer bufferData, StringBuffer lengthData) {
hgs
parents:
diff changeset
   926
		StringBuffer sb;
hgs
parents:
diff changeset
   927
		// Buffer parameter
hgs
parents:
diff changeset
   928
		// *( ( TUint32* )ptr ), *( ( TUint32* )( ptr + 4 ) ), ..., ptr + x
hgs
parents:
diff changeset
   929
		sb = new StringBuffer(SourceFormatter.formatTrace(trace,
hgs
parents:
diff changeset
   930
				TraceFormatType.TRACE_BUFFER));
hgs
parents:
diff changeset
   931
		if (isTraceBufferBuilt()) {
hgs
parents:
diff changeset
   932
			bufferData.append("ptr"); //$NON-NLS-1$
hgs
parents:
diff changeset
   933
			if (isBufferSizeDynamic()) {
hgs
parents:
diff changeset
   934
				// In case of dynamic buffer, the length has been calculated
hgs
parents:
diff changeset
   935
				// into length variable
hgs
parents:
diff changeset
   936
				lengthData.append("length"); //$NON-NLS-1$
hgs
parents:
diff changeset
   937
			} else {
hgs
parents:
diff changeset
   938
				// Fixed size case
hgs
parents:
diff changeset
   939
				lengthData.append(String.valueOf(fixedBufferSize));
hgs
parents:
diff changeset
   940
			}
hgs
parents:
diff changeset
   941
		} else {
hgs
parents:
diff changeset
   942
			// In case of no-buffer, the size variable contain the data size
hgs
parents:
diff changeset
   943
			bufferData.append("ptr"); //$NON-NLS-1$
hgs
parents:
diff changeset
   944
			lengthData.append("size"); //$NON-NLS-1$
hgs
parents:
diff changeset
   945
		}
hgs
parents:
diff changeset
   946
		return sb;
hgs
parents:
diff changeset
   947
	}
hgs
parents:
diff changeset
   948
hgs
parents:
diff changeset
   949
	/**
hgs
parents:
diff changeset
   950
	 * Writes a formatted trace to the stream. This removes the newline from the
hgs
parents:
diff changeset
   951
	 * trace if it exists
hgs
parents:
diff changeset
   952
	 * 
hgs
parents:
diff changeset
   953
	 * @param trace
hgs
parents:
diff changeset
   954
	 *            the trace
hgs
parents:
diff changeset
   955
	 * @throws IOException
hgs
parents:
diff changeset
   956
	 *             if writing fails
hgs
parents:
diff changeset
   957
	 */
hgs
parents:
diff changeset
   958
	private void writeFormattedTrace(String trace) throws IOException {
hgs
parents:
diff changeset
   959
		if (trace.endsWith(SourceConstants.LINE_FEED)) {
hgs
parents:
diff changeset
   960
			write(trace.substring(0, trace.length()
hgs
parents:
diff changeset
   961
					- SourceConstants.LINE_FEED.length()));
hgs
parents:
diff changeset
   962
		} else {
hgs
parents:
diff changeset
   963
			write(trace);
hgs
parents:
diff changeset
   964
		}
hgs
parents:
diff changeset
   965
	}
hgs
parents:
diff changeset
   966
hgs
parents:
diff changeset
   967
	/**
hgs
parents:
diff changeset
   968
	 * Increases indent and writes a new line, brace, new line combination
hgs
parents:
diff changeset
   969
	 * 
hgs
parents:
diff changeset
   970
	 * @throws IOException
hgs
parents:
diff changeset
   971
	 *             if writing fails
hgs
parents:
diff changeset
   972
	 */
hgs
parents:
diff changeset
   973
	private void writeOpenBrace() throws IOException {
hgs
parents:
diff changeset
   974
		openBraceCount++;
hgs
parents:
diff changeset
   975
		writeNewLine();
hgs
parents:
diff changeset
   976
		write(SourceConstants.OPENING_BRACE);
hgs
parents:
diff changeset
   977
		writeNewLine();
hgs
parents:
diff changeset
   978
	}
hgs
parents:
diff changeset
   979
hgs
parents:
diff changeset
   980
	/**
hgs
parents:
diff changeset
   981
	 * Write brace, decreases indent and writes a new line
hgs
parents:
diff changeset
   982
	 * 
hgs
parents:
diff changeset
   983
	 * @throws IOException
hgs
parents:
diff changeset
   984
	 *             if writing fails
hgs
parents:
diff changeset
   985
	 */
hgs
parents:
diff changeset
   986
	private void writeCloseBrace() throws IOException {
hgs
parents:
diff changeset
   987
		write(SourceConstants.CLOSING_BRACE);
hgs
parents:
diff changeset
   988
		openBraceCount--;
hgs
parents:
diff changeset
   989
		writeNewLine();
hgs
parents:
diff changeset
   990
	}
hgs
parents:
diff changeset
   991
	
hgs
parents:
diff changeset
   992
	/**
hgs
parents:
diff changeset
   993
	 * write licence Text
hgs
parents:
diff changeset
   994
	 * @throws IOException if write fails
hgs
parents:
diff changeset
   995
	 */
hgs
parents:
diff changeset
   996
	private void writeLicence() throws IOException {
hgs
parents:
diff changeset
   997
		String licence = null;
hgs
parents:
diff changeset
   998
		SourceParser parser = null;
hgs
parents:
diff changeset
   999
		//first get any of the traces belonging to this header
hgs
parents:
diff changeset
  1000
		TraceModel model = header.getOwner().getModel();
hgs
parents:
diff changeset
  1001
		for (TraceGroup group : model) {
hgs
parents:
diff changeset
  1002
			for (Trace trace : group) {
hgs
parents:
diff changeset
  1003
				Iterator<LocationListBase> itr = trace.getExtensions(LocationListBase.class);
hgs
parents:
diff changeset
  1004
				// The trace must have at least one location that belong to this header
hgs
parents:
diff changeset
  1005
				while (itr.hasNext() && parser == null) {
hgs
parents:
diff changeset
  1006
					LocationListBase list = itr.next();
hgs
parents:
diff changeset
  1007
					for (LocationProperties loc : list) {
hgs
parents:
diff changeset
  1008
						if (isValidTraceForHeader(loc.getFileName())) {
hgs
parents:
diff changeset
  1009
								parser = ((TraceLocation)loc).getParser();
hgs
parents:
diff changeset
  1010
								break;
hgs
parents:
diff changeset
  1011
						}
hgs
parents:
diff changeset
  1012
					}
hgs
parents:
diff changeset
  1013
				}
hgs
parents:
diff changeset
  1014
				if (parser!= null)  {
hgs
parents:
diff changeset
  1015
					break;
hgs
parents:
diff changeset
  1016
				}
hgs
parents:
diff changeset
  1017
			}
hgs
parents:
diff changeset
  1018
			if (parser != null) {
hgs
parents:
diff changeset
  1019
				break;
hgs
parents:
diff changeset
  1020
			}
hgs
parents:
diff changeset
  1021
		}
hgs
parents:
diff changeset
  1022
		
hgs
parents:
diff changeset
  1023
		if (parser!= null) {
hgs
parents:
diff changeset
  1024
		List<SourceExcludedArea> excludedAreas = parser.getExcludedAreas();
hgs
parents:
diff changeset
  1025
		//try to find licence from the source
hgs
parents:
diff changeset
  1026
		if (!excludedAreas.isEmpty()) {
hgs
parents:
diff changeset
  1027
			SourceExcludedArea sourceExcludedArea = excludedAreas.get(0);
hgs
parents:
diff changeset
  1028
			int offset = sourceExcludedArea.getOffset();
hgs
parents:
diff changeset
  1029
			int type = sourceExcludedArea.getType();
hgs
parents:
diff changeset
  1030
			int length = sourceExcludedArea.getLength();
hgs
parents:
diff changeset
  1031
			if (offset == 0 && type == SourceExcludedArea.MULTILINE_COMMENT) {
hgs
parents:
diff changeset
  1032
				String data = sourceExcludedArea.getParser().getData(offset, length);
hgs
parents:
diff changeset
  1033
				if (data.contains("Copyright")) { //$NON-NLS-1$
hgs
parents:
diff changeset
  1034
					// licence found write it
hgs
parents:
diff changeset
  1035
					TraceCompilerLogger.printInfo("Add Licence text from: " + sourceExcludedArea.getFileName() + " to : " + header.getAbsolutePath()); //$NON-NLS-1$
hgs
parents:
diff changeset
  1036
					licence = data;
hgs
parents:
diff changeset
  1037
					write(licence);
hgs
parents:
diff changeset
  1038
				}
hgs
parents:
diff changeset
  1039
			}	
hgs
parents:
diff changeset
  1040
		}
hgs
parents:
diff changeset
  1041
		}
hgs
parents:
diff changeset
  1042
		
hgs
parents:
diff changeset
  1043
		if (licence == null) {
hgs
parents:
diff changeset
  1044
			//get default licence from the licence file
hgs
parents:
diff changeset
  1045
			licence = TraceCompilerEngineGlobals.getDefaultLicence(true);
hgs
parents:
diff changeset
  1046
			
hgs
parents:
diff changeset
  1047
			if(licence != null) {
hgs
parents:
diff changeset
  1048
				TraceCompilerLogger.printInfo("Add default EPL Licence to : " + header.getAbsolutePath()); //$NON-NLS-1$
hgs
parents:
diff changeset
  1049
				write(licence);
hgs
parents:
diff changeset
  1050
			}
hgs
parents:
diff changeset
  1051
		}
hgs
parents:
diff changeset
  1052
	}
hgs
parents:
diff changeset
  1053
hgs
parents:
diff changeset
  1054
	/**
hgs
parents:
diff changeset
  1055
	 * Writes a new line and indent to the stream
hgs
parents:
diff changeset
  1056
	 * 
hgs
parents:
diff changeset
  1057
	 * @throws IOException
hgs
parents:
diff changeset
  1058
	 *             if writing fails
hgs
parents:
diff changeset
  1059
	 */
hgs
parents:
diff changeset
  1060
	private void writeNewLine() throws IOException {
hgs
parents:
diff changeset
  1061
		int newLines = newLineCount;
hgs
parents:
diff changeset
  1062
		while (newLines < maxNewLines) {
hgs
parents:
diff changeset
  1063
			write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
  1064
			for (int i = 0; i < openBraceCount; i++) {
hgs
parents:
diff changeset
  1065
				write(INDENT);
hgs
parents:
diff changeset
  1066
			}
hgs
parents:
diff changeset
  1067
			newLines++;
hgs
parents:
diff changeset
  1068
		}
hgs
parents:
diff changeset
  1069
		newLineCount = maxNewLines;
hgs
parents:
diff changeset
  1070
	}
hgs
parents:
diff changeset
  1071
hgs
parents:
diff changeset
  1072
	/**
hgs
parents:
diff changeset
  1073
	 * Writes a define to stream
hgs
parents:
diff changeset
  1074
	 * 
hgs
parents:
diff changeset
  1075
	 * @param name
hgs
parents:
diff changeset
  1076
	 *            the name for the define
hgs
parents:
diff changeset
  1077
	 * @throws IOException
hgs
parents:
diff changeset
  1078
	 *             if writing fails
hgs
parents:
diff changeset
  1079
	 */
hgs
parents:
diff changeset
  1080
	private void writeDefine(String name) throws IOException {
hgs
parents:
diff changeset
  1081
		write(SourceConstants.DEFINE);
hgs
parents:
diff changeset
  1082
		write(SourceConstants.SPACE);
hgs
parents:
diff changeset
  1083
		write(name);
hgs
parents:
diff changeset
  1084
		writeNewLine();
hgs
parents:
diff changeset
  1085
	}
hgs
parents:
diff changeset
  1086
hgs
parents:
diff changeset
  1087
	/**
hgs
parents:
diff changeset
  1088
	 * Writes include to header
hgs
parents:
diff changeset
  1089
	 * 
hgs
parents:
diff changeset
  1090
	 * @param name
hgs
parents:
diff changeset
  1091
	 *            the header name
hgs
parents:
diff changeset
  1092
	 * @throws IOException
hgs
parents:
diff changeset
  1093
	 *             if writing fails
hgs
parents:
diff changeset
  1094
	 */
hgs
parents:
diff changeset
  1095
	private void writeSystemInclude(String name) throws IOException {
hgs
parents:
diff changeset
  1096
		write(SourceConstants.INCLUDE);
hgs
parents:
diff changeset
  1097
		write(SourceConstants.SPACE);
hgs
parents:
diff changeset
  1098
		write("<"); //$NON-NLS-1$
hgs
parents:
diff changeset
  1099
		write(name);
hgs
parents:
diff changeset
  1100
		write(">"); //$NON-NLS-1$
hgs
parents:
diff changeset
  1101
		writeNewLine();
hgs
parents:
diff changeset
  1102
	}
hgs
parents:
diff changeset
  1103
hgs
parents:
diff changeset
  1104
	/**
hgs
parents:
diff changeset
  1105
	 * Writes data to a stream
hgs
parents:
diff changeset
  1106
	 * 
hgs
parents:
diff changeset
  1107
	 * @param data
hgs
parents:
diff changeset
  1108
	 *            the string of data
hgs
parents:
diff changeset
  1109
	 * @throws IOException
hgs
parents:
diff changeset
  1110
	 *             if writing fails
hgs
parents:
diff changeset
  1111
	 */
hgs
parents:
diff changeset
  1112
	private void write(String data) throws IOException {
hgs
parents:
diff changeset
  1113
		// Check if function starts
hgs
parents:
diff changeset
  1114
		if (data.contains(INLINE_TBOOL) || bufferingFunction) {
hgs
parents:
diff changeset
  1115
			bufferingFunction = true;
hgs
parents:
diff changeset
  1116
			functionText.append(data);
hgs
parents:
diff changeset
  1117
		} else {
hgs
parents:
diff changeset
  1118
			headerOutput.write(data.getBytes());
hgs
parents:
diff changeset
  1119
		}
hgs
parents:
diff changeset
  1120
			newLineCount = 0;
hgs
parents:
diff changeset
  1121
hgs
parents:
diff changeset
  1122
		//try to duplicate function if the current function processing is complete and duplicate is needed.
hgs
parents:
diff changeset
  1123
		writeAndDuplicateFunction(data);
hgs
parents:
diff changeset
  1124
	}
hgs
parents:
diff changeset
  1125
hgs
parents:
diff changeset
  1126
	/**
hgs
parents:
diff changeset
  1127
	 * Duplicates the function if needed
hgs
parents:
diff changeset
  1128
	 * 
hgs
parents:
diff changeset
  1129
	 * @param data
hgs
parents:
diff changeset
  1130
	 *            data String
hgs
parents:
diff changeset
  1131
	 * @throws IOException
hgs
parents:
diff changeset
  1132
	 *             if writing fails
hgs
parents:
diff changeset
  1133
	 */
hgs
parents:
diff changeset
  1134
	private void writeAndDuplicateFunction(String data) throws IOException {
hgs
parents:
diff changeset
  1135
			// This assumes there is only one start or end bracket in one line!
hgs
parents:
diff changeset
  1136
			if (data.contains(SourceConstants.OPENING_BRACE)) {
hgs
parents:
diff changeset
  1137
				firstOpenBraceFound = true;
hgs
parents:
diff changeset
  1138
				numberOfBrackets++;
hgs
parents:
diff changeset
  1139
			} else if (data.contains(SourceConstants.CLOSING_BRACE)) {
hgs
parents:
diff changeset
  1140
				numberOfBrackets--;
hgs
parents:
diff changeset
  1141
hgs
parents:
diff changeset
  1142
				// Function ends
hgs
parents:
diff changeset
  1143
				if (numberOfBrackets == 0 && firstOpenBraceFound) {
hgs
parents:
diff changeset
  1144
					firstOpenBraceFound = false;
hgs
parents:
diff changeset
  1145
					bufferingFunction = false;
hgs
parents:
diff changeset
  1146
					//write start function guard
hgs
parents:
diff changeset
  1147
					writeStartFunctionGuard();
hgs
parents:
diff changeset
  1148
					//write the function
hgs
parents:
diff changeset
  1149
					headerOutput.write(functionText.toString().getBytes());
hgs
parents:
diff changeset
  1150
					//write end function guard
hgs
parents:
diff changeset
  1151
					writeEndFunctionGuard();
hgs
parents:
diff changeset
  1152
hgs
parents:
diff changeset
  1153
					//process duplicate if needed
hgs
parents:
diff changeset
  1154
					// Get the function definition line
hgs
parents:
diff changeset
  1155
					int startIndex = functionText.indexOf(SourceConstants.OPENING_BRACE);
hgs
parents:
diff changeset
  1156
					String funcDef = functionText.substring(0, startIndex);
hgs
parents:
diff changeset
  1157
hgs
parents:
diff changeset
  1158
					// Replace TInt with TInt32 and TUint with TUint32 from the
hgs
parents:
diff changeset
  1159
					// header and write the function back again
hgs
parents:
diff changeset
  1160
					if (funcDef.contains(TINT_DEF)
hgs
parents:
diff changeset
  1161
							|| funcDef.contains(TUINT_DEF)) {
hgs
parents:
diff changeset
  1162
						//replace and duplicate
hgs
parents:
diff changeset
  1163
						funcDef = funcDef.replace(TINT_DEF, TINT32_DEF);
hgs
parents:
diff changeset
  1164
						funcDef = funcDef.replace(TUINT_DEF, TUINT32_DEF);
hgs
parents:
diff changeset
  1165
						functionText.replace(0, startIndex, funcDef);
hgs
parents:
diff changeset
  1166
						
hgs
parents:
diff changeset
  1167
						//write start function guard for duplicate
hgs
parents:
diff changeset
  1168
						write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
  1169
						write(SourceConstants.LINE_FEED);
hgs
parents:
diff changeset
  1170
						writeStartFunctionGuard();
hgs
parents:
diff changeset
  1171
						
hgs
parents:
diff changeset
  1172
						//write duplicate function
hgs
parents:
diff changeset
  1173
						headerOutput.write(functionText.toString().getBytes());
hgs
parents:
diff changeset
  1174
						
hgs
parents:
diff changeset
  1175
						//write end function guard for duplicate
hgs
parents:
diff changeset
  1176
						writeEndFunctionGuard();
hgs
parents:
diff changeset
  1177
					}
hgs
parents:
diff changeset
  1178
hgs
parents:
diff changeset
  1179
					functionText.setLength(0);
hgs
parents:
diff changeset
  1180
				}
hgs
parents:
diff changeset
  1181
			}
hgs
parents:
diff changeset
  1182
	}
hgs
parents:
diff changeset
  1183
hgs
parents:
diff changeset
  1184
	/**
hgs
parents:
diff changeset
  1185
	 * Checks if a trace needs a buffer or it can be represented with regular
hgs
parents:
diff changeset
  1186
	 * trace macros.
hgs
parents:
diff changeset
  1187
	 * 
hgs
parents:
diff changeset
  1188
	 * @param trace
hgs
parents:
diff changeset
  1189
	 *            the trace
hgs
parents:
diff changeset
  1190
	 * @return true if trace needs a buffer
hgs
parents:
diff changeset
  1191
	 */
hgs
parents:
diff changeset
  1192
	private boolean traceNeedsBuffer(Trace trace) {
hgs
parents:
diff changeset
  1193
		// A single dynamic parameter can be passed through the regular
hgs
parents:
diff changeset
  1194
		// API macros. In that case the parameter length is determined
hgs
parents:
diff changeset
  1195
		// by the trace message length
hgs
parents:
diff changeset
  1196
		Iterator<TraceParameter> parameters = trace.getParameters();
hgs
parents:
diff changeset
  1197
		boolean needsBuffer = false;
hgs
parents:
diff changeset
  1198
		boolean dynamicFound = false;
hgs
parents:
diff changeset
  1199
		while (parameters.hasNext() && !needsBuffer) {
hgs
parents:
diff changeset
  1200
			TraceParameter parameter = parameters.next();
hgs
parents:
diff changeset
  1201
			if (isParameterVisible(parameter)) {
hgs
parents:
diff changeset
  1202
				if (SourceUtils.isParameterSizeDynamic(parameter)) {
hgs
parents:
diff changeset
  1203
					if (dynamicFound) {
hgs
parents:
diff changeset
  1204
						needsBuffer = true;
hgs
parents:
diff changeset
  1205
					} else {
hgs
parents:
diff changeset
  1206
						dynamicFound = true;
hgs
parents:
diff changeset
  1207
					}
hgs
parents:
diff changeset
  1208
				} else {
hgs
parents:
diff changeset
  1209
					needsBuffer = true;
hgs
parents:
diff changeset
  1210
				}
hgs
parents:
diff changeset
  1211
			}
hgs
parents:
diff changeset
  1212
		}
hgs
parents:
diff changeset
  1213
		return needsBuffer;
hgs
parents:
diff changeset
  1214
	}
hgs
parents:
diff changeset
  1215
hgs
parents:
diff changeset
  1216
	/**
hgs
parents:
diff changeset
  1217
	 * Checks if a parameter is visible
hgs
parents:
diff changeset
  1218
	 * 
hgs
parents:
diff changeset
  1219
	 * @param parameter
hgs
parents:
diff changeset
  1220
	 *            the parameter to be checked
hgs
parents:
diff changeset
  1221
	 * @return true if visible, false if not
hgs
parents:
diff changeset
  1222
	 */
hgs
parents:
diff changeset
  1223
	private boolean isParameterVisible(TraceParameter parameter) {
hgs
parents:
diff changeset
  1224
		boolean retval;
hgs
parents:
diff changeset
  1225
		TraceParameterFormattingRule sourceRule = parameter
hgs
parents:
diff changeset
  1226
				.getExtension(TraceParameterFormattingRule.class);
hgs
parents:
diff changeset
  1227
		if (sourceRule == null || sourceRule.isShownInSource()) {
hgs
parents:
diff changeset
  1228
			retval = true;
hgs
parents:
diff changeset
  1229
		} else {
hgs
parents:
diff changeset
  1230
			retval = false;
hgs
parents:
diff changeset
  1231
		}
hgs
parents:
diff changeset
  1232
		return retval;
hgs
parents:
diff changeset
  1233
	}
hgs
parents:
diff changeset
  1234
hgs
parents:
diff changeset
  1235
	/**
hgs
parents:
diff changeset
  1236
	 * Gets the formatted trace
hgs
parents:
diff changeset
  1237
	 * 
hgs
parents:
diff changeset
  1238
	 * @return the trace
hgs
parents:
diff changeset
  1239
	 */
hgs
parents:
diff changeset
  1240
	String getCurrentTraceFormatted() {
hgs
parents:
diff changeset
  1241
		return currentTraceFormatted;
hgs
parents:
diff changeset
  1242
	}
hgs
parents:
diff changeset
  1243
hgs
parents:
diff changeset
  1244
	/**
hgs
parents:
diff changeset
  1245
	 * Checks if trace is already formatted to header
hgs
parents:
diff changeset
  1246
	 * 
hgs
parents:
diff changeset
  1247
	 * @return true if formatted
hgs
parents:
diff changeset
  1248
	 */
hgs
parents:
diff changeset
  1249
	boolean isTraceFormatDuplicate() {
hgs
parents:
diff changeset
  1250
		boolean retval;
hgs
parents:
diff changeset
  1251
		if (traceDeclarations.contains(currentTraceFormatted)) {
hgs
parents:
diff changeset
  1252
			retval = true;
hgs
parents:
diff changeset
  1253
		} else {
hgs
parents:
diff changeset
  1254
			traceDeclarations.add(currentTraceFormatted);
hgs
parents:
diff changeset
  1255
			retval = false;
hgs
parents:
diff changeset
  1256
		}
hgs
parents:
diff changeset
  1257
		return retval;
hgs
parents:
diff changeset
  1258
	}
hgs
parents:
diff changeset
  1259
hgs
parents:
diff changeset
  1260
	/**
hgs
parents:
diff changeset
  1261
	 * Checks if the buffer size for current trace is fixed
hgs
parents:
diff changeset
  1262
	 * 
hgs
parents:
diff changeset
  1263
	 * @return the flag
hgs
parents:
diff changeset
  1264
	 */
hgs
parents:
diff changeset
  1265
	boolean isTraceBufferFixed() {
hgs
parents:
diff changeset
  1266
		return fixedBufferSize != 0;
hgs
parents:
diff changeset
  1267
	}
hgs
parents:
diff changeset
  1268
hgs
parents:
diff changeset
  1269
	/**
hgs
parents:
diff changeset
  1270
	 * Checks if the buffer is built
hgs
parents:
diff changeset
  1271
	 * 
hgs
parents:
diff changeset
  1272
	 * @return the flag
hgs
parents:
diff changeset
  1273
	 */
hgs
parents:
diff changeset
  1274
	boolean isTraceBufferBuilt() {
hgs
parents:
diff changeset
  1275
		return buildTraceBuffer;
hgs
parents:
diff changeset
  1276
	}
hgs
parents:
diff changeset
  1277
hgs
parents:
diff changeset
  1278
	/**
hgs
parents:
diff changeset
  1279
	 * Gets the current trace
hgs
parents:
diff changeset
  1280
	 * 
hgs
parents:
diff changeset
  1281
	 * @return the trace
hgs
parents:
diff changeset
  1282
	 */
hgs
parents:
diff changeset
  1283
	Trace getCurrentTrace() {
hgs
parents:
diff changeset
  1284
		return currentTrace;
hgs
parents:
diff changeset
  1285
	}
hgs
parents:
diff changeset
  1286
hgs
parents:
diff changeset
  1287
	/**
hgs
parents:
diff changeset
  1288
	 * Gets the header
hgs
parents:
diff changeset
  1289
	 * 
hgs
parents:
diff changeset
  1290
	 * @return the header
hgs
parents:
diff changeset
  1291
	 */
hgs
parents:
diff changeset
  1292
	TraceHeader getHeader() {
hgs
parents:
diff changeset
  1293
		return header;
hgs
parents:
diff changeset
  1294
	}
hgs
parents:
diff changeset
  1295
hgs
parents:
diff changeset
  1296
	/**
hgs
parents:
diff changeset
  1297
	 * Starts writing a trace
hgs
parents:
diff changeset
  1298
	 * 
hgs
parents:
diff changeset
  1299
	 * @param trace
hgs
parents:
diff changeset
  1300
	 *            the trace
hgs
parents:
diff changeset
  1301
	 * @return true if trace can be written, false if not
hgs
parents:
diff changeset
  1302
	 */
hgs
parents:
diff changeset
  1303
	boolean startTrace(Trace trace) {
hgs
parents:
diff changeset
  1304
		boolean validTrace = false;
hgs
parents:
diff changeset
  1305
		Iterator<LocationListBase> itr = trace
hgs
parents:
diff changeset
  1306
				.getExtensions(LocationListBase.class);
hgs
parents:
diff changeset
  1307
		// The trace must have at least one location that belong to this header
hgs
parents:
diff changeset
  1308
		while (itr.hasNext() && !validTrace) {
hgs
parents:
diff changeset
  1309
			LocationListBase list = itr.next();
hgs
parents:
diff changeset
  1310
			for (LocationProperties loc : list) {
hgs
parents:
diff changeset
  1311
				validTrace = isValidTraceForHeader(loc.getFileName());
hgs
parents:
diff changeset
  1312
				if (validTrace) {
hgs
parents:
diff changeset
  1313
					break;
hgs
parents:
diff changeset
  1314
				}
hgs
parents:
diff changeset
  1315
			}
hgs
parents:
diff changeset
  1316
		}
hgs
parents:
diff changeset
  1317
		if (validTrace) {
hgs
parents:
diff changeset
  1318
			currentTrace = trace;
hgs
parents:
diff changeset
  1319
			fixedBufferSize = 0;
hgs
parents:
diff changeset
  1320
			dynamicBufferSizeFlag = false;
hgs
parents:
diff changeset
  1321
			buildTraceBuffer = false;
hgs
parents:
diff changeset
  1322
			currentTraceFormatted = null;
hgs
parents:
diff changeset
  1323
			currentParameterName = null;
hgs
parents:
diff changeset
  1324
			currentParameterType = null;
hgs
parents:
diff changeset
  1325
			currentParameterIndex = 0;
hgs
parents:
diff changeset
  1326
		}
hgs
parents:
diff changeset
  1327
		return validTrace;
hgs
parents:
diff changeset
  1328
	}
hgs
parents:
diff changeset
  1329
hgs
parents:
diff changeset
  1330
	/**
hgs
parents:
diff changeset
  1331
	 * Checks if the location belongs to this header
hgs
parents:
diff changeset
  1332
	 * 
hgs
parents:
diff changeset
  1333
	 * @param locFileName
hgs
parents:
diff changeset
  1334
	 *            the location
hgs
parents:
diff changeset
  1335
	 * @return true if location belongs here
hgs
parents:
diff changeset
  1336
	 */
hgs
parents:
diff changeset
  1337
	private boolean isValidTraceForHeader(String locFileName) {
hgs
parents:
diff changeset
  1338
		boolean valid = false;
hgs
parents:
diff changeset
  1339
		if (locFileName != null) {
hgs
parents:
diff changeset
  1340
			int index = locFileName.lastIndexOf('.');
hgs
parents:
diff changeset
  1341
			if (index >= 0) {
hgs
parents:
diff changeset
  1342
				locFileName = locFileName.substring(0, index);
hgs
parents:
diff changeset
  1343
			}
hgs
parents:
diff changeset
  1344
			if (locFileName.equals(header.getProjectName())) {
hgs
parents:
diff changeset
  1345
				valid = true;
hgs
parents:
diff changeset
  1346
			}
hgs
parents:
diff changeset
  1347
		}
hgs
parents:
diff changeset
  1348
		return valid;
hgs
parents:
diff changeset
  1349
	}
hgs
parents:
diff changeset
  1350
hgs
parents:
diff changeset
  1351
	/**
hgs
parents:
diff changeset
  1352
	 * Starts writing a parameter
hgs
parents:
diff changeset
  1353
	 * 
hgs
parents:
diff changeset
  1354
	 * @param parameter
hgs
parents:
diff changeset
  1355
	 *            the parameter
hgs
parents:
diff changeset
  1356
	 */
hgs
parents:
diff changeset
  1357
	void startParameter(TraceParameter parameter) {
hgs
parents:
diff changeset
  1358
		currentParameterName = null;
hgs
parents:
diff changeset
  1359
		currentParameterType = null;
hgs
parents:
diff changeset
  1360
		currentParameter = parameter;
hgs
parents:
diff changeset
  1361
	}
hgs
parents:
diff changeset
  1362
hgs
parents:
diff changeset
  1363
	/**
hgs
parents:
diff changeset
  1364
	 * Sets the kernel mode #endif needed flag
hgs
parents:
diff changeset
  1365
	 * 
hgs
parents:
diff changeset
  1366
	 * @param flag
hgs
parents:
diff changeset
  1367
	 *            the flag
hgs
parents:
diff changeset
  1368
	 */
hgs
parents:
diff changeset
  1369
	void setKernelModeEndifNeeded(boolean flag) {
hgs
parents:
diff changeset
  1370
		needsKernelEndif = flag;
hgs
parents:
diff changeset
  1371
	}
hgs
parents:
diff changeset
  1372
hgs
parents:
diff changeset
  1373
	/**
hgs
parents:
diff changeset
  1374
	 * Gets the kernel mode endif needed flag
hgs
parents:
diff changeset
  1375
	 * 
hgs
parents:
diff changeset
  1376
	 * @return the flag
hgs
parents:
diff changeset
  1377
	 */
hgs
parents:
diff changeset
  1378
	boolean isKernelModeEndifNeeded() {
hgs
parents:
diff changeset
  1379
		return needsKernelEndif;
hgs
parents:
diff changeset
  1380
	}
hgs
parents:
diff changeset
  1381
hgs
parents:
diff changeset
  1382
	/**
hgs
parents:
diff changeset
  1383
	 * Returns the dynamic buffer size flag
hgs
parents:
diff changeset
  1384
	 * 
hgs
parents:
diff changeset
  1385
	 * @return true if buffer size is dynamic
hgs
parents:
diff changeset
  1386
	 */
hgs
parents:
diff changeset
  1387
	boolean isBufferSizeDynamic() {
hgs
parents:
diff changeset
  1388
		return dynamicBufferSizeFlag;
hgs
parents:
diff changeset
  1389
	}
hgs
parents:
diff changeset
  1390
hgs
parents:
diff changeset
  1391
	/**
hgs
parents:
diff changeset
  1392
	 * Checks if current parameter needs alignment
hgs
parents:
diff changeset
  1393
	 * 
hgs
parents:
diff changeset
  1394
	 * @return true if needed
hgs
parents:
diff changeset
  1395
	 */
hgs
parents:
diff changeset
  1396
	boolean isParameterAlignmentNeeded() {
hgs
parents:
diff changeset
  1397
		return SourceUtils.isParameterAlignementNeeded(currentParameter
hgs
parents:
diff changeset
  1398
				.getType());
hgs
parents:
diff changeset
  1399
	}
hgs
parents:
diff changeset
  1400
hgs
parents:
diff changeset
  1401
}