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