tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/source/SourceParameterTokenizer.java
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
parent 41 tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/source/SourceParameterTokenizer.java@838cdffd57ce
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
41
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 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
* Parameter tokenizer is used to parse function parameters lists
hgs
parents:
diff changeset
    17
*
hgs
parents:
diff changeset
    18
*/
hgs
parents:
diff changeset
    19
package com.nokia.tracecompiler.source;
hgs
parents:
diff changeset
    20
hgs
parents:
diff changeset
    21
import java.util.List;
hgs
parents:
diff changeset
    22
hgs
parents:
diff changeset
    23
/**
hgs
parents:
diff changeset
    24
 * Parameter tokenizer is used to parse function parameters lists
hgs
parents:
diff changeset
    25
 * 
hgs
parents:
diff changeset
    26
 */
hgs
parents:
diff changeset
    27
public class SourceParameterTokenizer {
hgs
parents:
diff changeset
    28
hgs
parents:
diff changeset
    29
	/**
hgs
parents:
diff changeset
    30
	 * The source parser
hgs
parents:
diff changeset
    31
	 */
hgs
parents:
diff changeset
    32
	private SourceParser parser;
hgs
parents:
diff changeset
    33
hgs
parents:
diff changeset
    34
	/**
hgs
parents:
diff changeset
    35
	 * The offset where to start the tokenizer
hgs
parents:
diff changeset
    36
	 */
hgs
parents:
diff changeset
    37
	private int offset;
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
	/**
hgs
parents:
diff changeset
    40
	 * Slip next whitespace
hgs
parents:
diff changeset
    41
	 */
hgs
parents:
diff changeset
    42
	private boolean skipNextWhiteSpace;
hgs
parents:
diff changeset
    43
hgs
parents:
diff changeset
    44
	/**
hgs
parents:
diff changeset
    45
	 * Constructor
hgs
parents:
diff changeset
    46
	 * 
hgs
parents:
diff changeset
    47
	 * @param parser
hgs
parents:
diff changeset
    48
	 *            the source parser
hgs
parents:
diff changeset
    49
	 * @param offset
hgs
parents:
diff changeset
    50
	 *            offset to the start of parameter
hgs
parents:
diff changeset
    51
	 */
hgs
parents:
diff changeset
    52
	public SourceParameterTokenizer(SourceParser parser, int offset) {
hgs
parents:
diff changeset
    53
		this.parser = parser;
hgs
parents:
diff changeset
    54
		this.offset = offset;
hgs
parents:
diff changeset
    55
	}
hgs
parents:
diff changeset
    56
hgs
parents:
diff changeset
    57
	/**
hgs
parents:
diff changeset
    58
	 * Parses a list of parameters (a, b, c) and stores the values into the
hgs
parents:
diff changeset
    59
	 * given list.
hgs
parents:
diff changeset
    60
	 * 
hgs
parents:
diff changeset
    61
	 * @param list
hgs
parents:
diff changeset
    62
	 *            the list of parameters
hgs
parents:
diff changeset
    63
	 * @param findSeparator
hgs
parents:
diff changeset
    64
	 *            if true, the processing stops after ';' or '{' character. If
hgs
parents:
diff changeset
    65
	 *            false, processing stops after ')' at end of parameters
hgs
parents:
diff changeset
    66
	 * @return index at end of parameters
hgs
parents:
diff changeset
    67
	 * @throws SourceParserException
hgs
parents:
diff changeset
    68
	 *             if processing fails
hgs
parents:
diff changeset
    69
	 */
hgs
parents:
diff changeset
    70
	public int tokenize(List<String> list, boolean findSeparator)
hgs
parents:
diff changeset
    71
			throws SourceParserException {
hgs
parents:
diff changeset
    72
		TokenizerSearchData data = new TokenizerSearchData();
hgs
parents:
diff changeset
    73
		data.itr = parser.createIterator(offset, SourceParser.SKIP_WHITE_SPACES
hgs
parents:
diff changeset
    74
				| SourceParser.SKIP_COMMENTS);
hgs
parents:
diff changeset
    75
		boolean bracketsOpened = false;
hgs
parents:
diff changeset
    76
		boolean finished = false;
hgs
parents:
diff changeset
    77
		while (data.itr.hasNext() && !finished) {
hgs
parents:
diff changeset
    78
			data.value = data.itr.next();
hgs
parents:
diff changeset
    79
			if (!data.inQuotes && data.value == '\"') {
hgs
parents:
diff changeset
    80
				data.inQuotes = true;
hgs
parents:
diff changeset
    81
				data.hasData = true;
hgs
parents:
diff changeset
    82
			} else if (data.inQuotes) {
hgs
parents:
diff changeset
    83
				processInQuotesChar(data);
hgs
parents:
diff changeset
    84
			} else if (data.complete) {
hgs
parents:
diff changeset
    85
				processEndOfParametersChar(data);
hgs
parents:
diff changeset
    86
			} else if (data.value == '(') {
hgs
parents:
diff changeset
    87
				bracketsOpened = true;
hgs
parents:
diff changeset
    88
				processOpeningBracket(data);
hgs
parents:
diff changeset
    89
			} else if (data.value == ',' || data.value == ')') {
hgs
parents:
diff changeset
    90
				processCommaOrClosingBracket(list, data);
hgs
parents:
diff changeset
    91
			} else if (data.value == ';' && data.openBracketCount != 0 || data.value == '{'
hgs
parents:
diff changeset
    92
					|| data.value == '}' ) {
hgs
parents:
diff changeset
    93
				throw new SourceParserException(
hgs
parents:
diff changeset
    94
						SourceErrorCodes.UNEXPECTED_PARAMETER_SEPARATOR);
hgs
parents:
diff changeset
    95
			} else {
hgs
parents:
diff changeset
    96
				// Raises a flag that there is some data. processOpeningBracket
hgs
parents:
diff changeset
    97
				// no longer interprets the next bracket as opening bracket
hgs
parents:
diff changeset
    98
				if (data.openBracketCount > 0) {
hgs
parents:
diff changeset
    99
					data.hasData = true;
hgs
parents:
diff changeset
   100
				}
hgs
parents:
diff changeset
   101
			}
hgs
parents:
diff changeset
   102
			finished = ((data.complete && !findSeparator) || (data.endFound && findSeparator));
hgs
parents:
diff changeset
   103
			if (bracketsOpened && data.openBracketCount == 0) {
hgs
parents:
diff changeset
   104
				data.complete = true;
hgs
parents:
diff changeset
   105
				break;
hgs
parents:
diff changeset
   106
			}
hgs
parents:
diff changeset
   107
		}
hgs
parents:
diff changeset
   108
		if (!data.complete) {
hgs
parents:
diff changeset
   109
			throw new SourceParserException(
hgs
parents:
diff changeset
   110
					SourceErrorCodes.UNEXPECTED_END_OF_FILE);
hgs
parents:
diff changeset
   111
		}
hgs
parents:
diff changeset
   112
		if (data.openBracketCount != 0) {
hgs
parents:
diff changeset
   113
			throw new SourceParserException(SourceErrorCodes.BRACKET_MISMATCH);
hgs
parents:
diff changeset
   114
		}
hgs
parents:
diff changeset
   115
		
hgs
parents:
diff changeset
   116
		
hgs
parents:
diff changeset
   117
		return data.itr.currentIndex() + 1;
hgs
parents:
diff changeset
   118
	}
hgs
parents:
diff changeset
   119
hgs
parents:
diff changeset
   120
	/**
hgs
parents:
diff changeset
   121
	 * Parses list of parameters with types (int a, int b, int c) and stores the
hgs
parents:
diff changeset
   122
	 * values into the given list.
hgs
parents:
diff changeset
   123
	 * 
hgs
parents:
diff changeset
   124
	 * @param list
hgs
parents:
diff changeset
   125
	 *            the list of parameters
hgs
parents:
diff changeset
   126
	 * @return index at end of parameters
hgs
parents:
diff changeset
   127
	 * @throws SourceParserException
hgs
parents:
diff changeset
   128
	 *             if processing fails
hgs
parents:
diff changeset
   129
	 */
hgs
parents:
diff changeset
   130
	public int tokenizeTyped(List<SourceParameter> list) 
hgs
parents:
diff changeset
   131
			throws SourceParserException {
hgs
parents:
diff changeset
   132
		TokenizerSearchData data = new TokenizerSearchData();
hgs
parents:
diff changeset
   133
hgs
parents:
diff changeset
   134
		try {
hgs
parents:
diff changeset
   135
			data.itr = parser
hgs
parents:
diff changeset
   136
					.createIterator(offset, SourceParser.SKIP_WHITE_SPACES
hgs
parents:
diff changeset
   137
							| SourceParser.SKIP_COMMENTS);
hgs
parents:
diff changeset
   138
			data.sourceParameter = new SourceParameter();
hgs
parents:
diff changeset
   139
			while (data.itr.hasNext() && !data.complete) {
hgs
parents:
diff changeset
   140
				data.value = data.itr.next();
hgs
parents:
diff changeset
   141
hgs
parents:
diff changeset
   142
				// Check if there was array start or end character and then
hgs
parents:
diff changeset
   143
				// space. It would mean that the parameter continues and more
hgs
parents:
diff changeset
   144
				// should be parsed.
hgs
parents:
diff changeset
   145
				if (skipNextWhiteSpace) {
hgs
parents:
diff changeset
   146
					skipNextWhiteSpace = false;
hgs
parents:
diff changeset
   147
					if (data.itr.hasSkipped()) {
hgs
parents:
diff changeset
   148
						data.value = data.itr.next();
hgs
parents:
diff changeset
   149
					}
hgs
parents:
diff changeset
   150
				}
hgs
parents:
diff changeset
   151
hgs
parents:
diff changeset
   152
				if (data.value == '\"') {
hgs
parents:
diff changeset
   153
					throw new SourceParserException(
hgs
parents:
diff changeset
   154
							SourceErrorCodes.UNEXPECTED_QUOTE_CHARACTER);
hgs
parents:
diff changeset
   155
				} else if (data.value == '(') {
hgs
parents:
diff changeset
   156
					processOpeningBracket(data);
hgs
parents:
diff changeset
   157
				} else if (data.value == ',' || data.value == ')') {
hgs
parents:
diff changeset
   158
					processCommaOrClosingBracket(list, data);
hgs
parents:
diff changeset
   159
				} else if (data.value == ';' || data.value == '{'
hgs
parents:
diff changeset
   160
						|| data.value == '}') {
hgs
parents:
diff changeset
   161
					data.complete = true;
hgs
parents:
diff changeset
   162
					// Array start or end character.
hgs
parents:
diff changeset
   163
				} else if (data.value == '<' || data.value == '>') {
hgs
parents:
diff changeset
   164
					skipNextWhiteSpace = true;
hgs
parents:
diff changeset
   165
				} else if (data.itr.hasSkipped() && data.openBracketCount > 0) {
hgs
parents:
diff changeset
   166
					processNameValueSeparator(data);
hgs
parents:
diff changeset
   167
				}
hgs
parents:
diff changeset
   168
			}
hgs
parents:
diff changeset
   169
			if (!data.complete) {
hgs
parents:
diff changeset
   170
				throw new SourceParserException(
hgs
parents:
diff changeset
   171
						SourceErrorCodes.UNEXPECTED_END_OF_FILE);
hgs
parents:
diff changeset
   172
			}
hgs
parents:
diff changeset
   173
		} catch (SourceParserException e) {
hgs
parents:
diff changeset
   174
			// Resets all source locations if parser fails
hgs
parents:
diff changeset
   175
			for (int i = 0; i < list.size(); i++) {
hgs
parents:
diff changeset
   176
				list.get(i).getSourceLocation().dereference();
hgs
parents:
diff changeset
   177
			}
hgs
parents:
diff changeset
   178
			throw e;
hgs
parents:
diff changeset
   179
		}
hgs
parents:
diff changeset
   180
		return data.itr.currentIndex() + 1;
hgs
parents:
diff changeset
   181
	}
hgs
parents:
diff changeset
   182
hgs
parents:
diff changeset
   183
	/**
hgs
parents:
diff changeset
   184
	 * Processes a separator character and updates the current SourceParameter
hgs
parents:
diff changeset
   185
	 * object in the search data
hgs
parents:
diff changeset
   186
	 * 
hgs
parents:
diff changeset
   187
	 * @param data
hgs
parents:
diff changeset
   188
	 *            the search data
hgs
parents:
diff changeset
   189
	 * @throws SourceParserException
hgs
parents:
diff changeset
   190
	 *             if processing fails
hgs
parents:
diff changeset
   191
	 */
hgs
parents:
diff changeset
   192
	private void processNameValueSeparator(TokenizerSearchData data)
hgs
parents:
diff changeset
   193
			throws SourceParserException {
hgs
parents:
diff changeset
   194
		// If the parameter is empty, the previous index will point
hgs
parents:
diff changeset
   195
		// to index preceeding tagStartIndex
hgs
parents:
diff changeset
   196
		int previous = data.itr.previousIndex();
hgs
parents:
diff changeset
   197
		if (previous >= data.tagStartIndex) {
hgs
parents:
diff changeset
   198
			int endIndex = previous + 1;
hgs
parents:
diff changeset
   199
			if (data.sourceParameter.getType() == null) {
hgs
parents:
diff changeset
   200
				processNameValueSeparatorNoType(data, endIndex);
hgs
parents:
diff changeset
   201
			} else if (data.sourceParameter.getName() == null) {
hgs
parents:
diff changeset
   202
				processNameValueSeparatorNoName(data, endIndex);
hgs
parents:
diff changeset
   203
			}
hgs
parents:
diff changeset
   204
			data.tagStartIndex = data.itr.currentIndex();
hgs
parents:
diff changeset
   205
		}
hgs
parents:
diff changeset
   206
	}
hgs
parents:
diff changeset
   207
hgs
parents:
diff changeset
   208
	/**
hgs
parents:
diff changeset
   209
	 * Processes a name-value separator when there is no name
hgs
parents:
diff changeset
   210
	 * 
hgs
parents:
diff changeset
   211
	 * @param data
hgs
parents:
diff changeset
   212
	 *            the search data
hgs
parents:
diff changeset
   213
	 * @param endIndex
hgs
parents:
diff changeset
   214
	 *            the end index of the parameters
hgs
parents:
diff changeset
   215
	 * @throws SourceParserException
hgs
parents:
diff changeset
   216
	 *             if processing fails
hgs
parents:
diff changeset
   217
	 */
hgs
parents:
diff changeset
   218
	private void processNameValueSeparatorNoName(TokenizerSearchData data,
hgs
parents:
diff changeset
   219
			int endIndex) throws SourceParserException {
hgs
parents:
diff changeset
   220
		String name = parser.getSource().get(data.tagStartIndex,
hgs
parents:
diff changeset
   221
				endIndex - data.tagStartIndex);
hgs
parents:
diff changeset
   222
		boolean startFound = false;
hgs
parents:
diff changeset
   223
		int start = 0;
hgs
parents:
diff changeset
   224
		int end = name.length();
hgs
parents:
diff changeset
   225
		for (int i = 0; i < name.length(); i++) {
hgs
parents:
diff changeset
   226
			char c = name.charAt(i);
hgs
parents:
diff changeset
   227
			if (c == '&' || c == '*') {
hgs
parents:
diff changeset
   228
				if (c == '&') {
hgs
parents:
diff changeset
   229
					data.sourceParameter.setReference();
hgs
parents:
diff changeset
   230
				} else {
hgs
parents:
diff changeset
   231
					data.sourceParameter.addPointer();
hgs
parents:
diff changeset
   232
				}
hgs
parents:
diff changeset
   233
				if (!startFound) {
hgs
parents:
diff changeset
   234
					start++;
hgs
parents:
diff changeset
   235
				} else {
hgs
parents:
diff changeset
   236
					end--;
hgs
parents:
diff changeset
   237
				}
hgs
parents:
diff changeset
   238
			} else {
hgs
parents:
diff changeset
   239
				startFound = true;
hgs
parents:
diff changeset
   240
			}
hgs
parents:
diff changeset
   241
		}
hgs
parents:
diff changeset
   242
		name = name.substring(start, end);
hgs
parents:
diff changeset
   243
		if (name.length() > 0) {
hgs
parents:
diff changeset
   244
			if (isParameterTypeQualifier(name)) {
hgs
parents:
diff changeset
   245
				// Qualifiers between type and name are ignored
hgs
parents:
diff changeset
   246
				// For example TInt const* aValue
hgs
parents:
diff changeset
   247
			} else {
hgs
parents:
diff changeset
   248
				data.sourceParameter.setName(name);
hgs
parents:
diff changeset
   249
			}
hgs
parents:
diff changeset
   250
		}
hgs
parents:
diff changeset
   251
	}
hgs
parents:
diff changeset
   252
hgs
parents:
diff changeset
   253
	/**
hgs
parents:
diff changeset
   254
	 * Processes a name-value separator when there is no value
hgs
parents:
diff changeset
   255
	 * 
hgs
parents:
diff changeset
   256
	 * @param data
hgs
parents:
diff changeset
   257
	 *            the search data
hgs
parents:
diff changeset
   258
	 * @param endIndex
hgs
parents:
diff changeset
   259
	 *            the end index of the parameters
hgs
parents:
diff changeset
   260
	 * @throws SourceParserException
hgs
parents:
diff changeset
   261
	 *             if processing fails
hgs
parents:
diff changeset
   262
	 */
hgs
parents:
diff changeset
   263
	private void processNameValueSeparatorNoType(TokenizerSearchData data,
hgs
parents:
diff changeset
   264
			int endIndex) throws SourceParserException {
hgs
parents:
diff changeset
   265
		String type = parser.getSource().get(data.tagStartIndex,
hgs
parents:
diff changeset
   266
				endIndex - data.tagStartIndex);
hgs
parents:
diff changeset
   267
		if (isParameterTypeQualifier(type)) {
hgs
parents:
diff changeset
   268
			data.sourceParameter.addQualifier(type);
hgs
parents:
diff changeset
   269
		} else {
hgs
parents:
diff changeset
   270
			for (int i = type.length() - 1; i >= 0; i--) {
hgs
parents:
diff changeset
   271
				if (type.charAt(i) == '&') {
hgs
parents:
diff changeset
   272
					data.sourceParameter.setReference();
hgs
parents:
diff changeset
   273
					if (i == 0) {
hgs
parents:
diff changeset
   274
						type = ""; //$NON-NLS-1$
hgs
parents:
diff changeset
   275
					}
hgs
parents:
diff changeset
   276
				} else if (type.charAt(i) == '*') {
hgs
parents:
diff changeset
   277
					data.sourceParameter.addPointer();
hgs
parents:
diff changeset
   278
					if (i == 0) {
hgs
parents:
diff changeset
   279
						type = ""; //$NON-NLS-1$
hgs
parents:
diff changeset
   280
					}
hgs
parents:
diff changeset
   281
				} else {
hgs
parents:
diff changeset
   282
					if (i != type.length() - 1) {
hgs
parents:
diff changeset
   283
						type = type.substring(0, i + 1);
hgs
parents:
diff changeset
   284
					}
hgs
parents:
diff changeset
   285
					i = -1;
hgs
parents:
diff changeset
   286
				}
hgs
parents:
diff changeset
   287
			}
hgs
parents:
diff changeset
   288
			if (type.length() > 0) {
hgs
parents:
diff changeset
   289
				// Remove spaces
hgs
parents:
diff changeset
   290
				type = type.replace(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$
hgs
parents:
diff changeset
   291
				data.sourceParameter.setType(type);
hgs
parents:
diff changeset
   292
			}
hgs
parents:
diff changeset
   293
		}
hgs
parents:
diff changeset
   294
	}
hgs
parents:
diff changeset
   295
hgs
parents:
diff changeset
   296
	/**
hgs
parents:
diff changeset
   297
	 * Checks if parameter type if a qualifier or not
hgs
parents:
diff changeset
   298
	 * 
hgs
parents:
diff changeset
   299
	 * @param type
hgs
parents:
diff changeset
   300
	 *            the type to be checked
hgs
parents:
diff changeset
   301
	 * @return true if qualifier, false if not
hgs
parents:
diff changeset
   302
	 */
hgs
parents:
diff changeset
   303
	private boolean isParameterTypeQualifier(String type) {
hgs
parents:
diff changeset
   304
		boolean retval = false;
hgs
parents:
diff changeset
   305
		for (String element : SourceConstants.PARAMETER_QUALIFIERS) {
hgs
parents:
diff changeset
   306
			if (type.equals(element)) {
hgs
parents:
diff changeset
   307
				retval = true;
hgs
parents:
diff changeset
   308
			}
hgs
parents:
diff changeset
   309
		}
hgs
parents:
diff changeset
   310
		return retval;
hgs
parents:
diff changeset
   311
	}
hgs
parents:
diff changeset
   312
hgs
parents:
diff changeset
   313
	/**
hgs
parents:
diff changeset
   314
	 * Processes a parameter separator or closing bracket
hgs
parents:
diff changeset
   315
	 * 
hgs
parents:
diff changeset
   316
	 * @param list
hgs
parents:
diff changeset
   317
	 *            the list of existing parameters
hgs
parents:
diff changeset
   318
	 * @param data
hgs
parents:
diff changeset
   319
	 *            the search data
hgs
parents:
diff changeset
   320
	 * @throws SourceParserException
hgs
parents:
diff changeset
   321
	 *             if invalid character is encountered
hgs
parents:
diff changeset
   322
	 */
hgs
parents:
diff changeset
   323
	@SuppressWarnings("unchecked")
hgs
parents:
diff changeset
   324
	private void processCommaOrClosingBracket(List list,
hgs
parents:
diff changeset
   325
			TokenizerSearchData data) throws SourceParserException {
hgs
parents:
diff changeset
   326
		// This method is called from both tokenize functions. One uses
hgs
parents:
diff changeset
   327
		// List<String> and other List<SourceParameter>
hgs
parents:
diff changeset
   328
		// Thus this uses List and @SuppressWarnings
hgs
parents:
diff changeset
   329
		if (data.value == ')') {
hgs
parents:
diff changeset
   330
			data.openBracketCount--;
hgs
parents:
diff changeset
   331
		}
hgs
parents:
diff changeset
   332
		
hgs
parents:
diff changeset
   333
		if (data.value == ',') {
hgs
parents:
diff changeset
   334
			//we may have the case of OstTraceDef1( OST_TRACE_CATEGORY_ALL, TRACE_FATAL, TEST_OstTraceDef1, "EOstTraceDef1 - %u" , f(a,b));
hgs
parents:
diff changeset
   335
			//when processing the comma in f(a,b) that should not count as parameter separator
hgs
parents:
diff changeset
   336
			if (data.openBracketCount >1 ) {
hgs
parents:
diff changeset
   337
				return;
hgs
parents:
diff changeset
   338
			}
hgs
parents:
diff changeset
   339
		}
hgs
parents:
diff changeset
   340
		
hgs
parents:
diff changeset
   341
		if (data.value == ',' || data.openBracketCount == 0) {
hgs
parents:
diff changeset
   342
			//we have another parameter
hgs
parents:
diff changeset
   343
			if (data.sourceParameter != null) {
hgs
parents:
diff changeset
   344
				// If processing typed parameter list, the name and type are
hgs
parents:
diff changeset
   345
				// stored into a SourceParameter object, which is then added
hgs
parents:
diff changeset
   346
				// to list
hgs
parents:
diff changeset
   347
				processNameValueSeparator(data);
hgs
parents:
diff changeset
   348
				if (data.sourceParameter.getType() != null) {
hgs
parents:
diff changeset
   349
					SourceLocation location = new SourceLocation(parser,
hgs
parents:
diff changeset
   350
							data.paramStartIndex, data.itr.currentIndex()
hgs
parents:
diff changeset
   351
									- data.paramStartIndex);
hgs
parents:
diff changeset
   352
					data.sourceParameter.setSourceLocation(location);
hgs
parents:
diff changeset
   353
					list.add(data.sourceParameter);
hgs
parents:
diff changeset
   354
					data.sourceParameter = new SourceParameter();
hgs
parents:
diff changeset
   355
				}
hgs
parents:
diff changeset
   356
			} else {
hgs
parents:
diff changeset
   357
				// In this case the list contains strings.
hgs
parents:
diff changeset
   358
				int previous = data.itr.previousIndex();
hgs
parents:
diff changeset
   359
				String tracepoint = ""; //$NON-NLS-1$
hgs
parents:
diff changeset
   360
				if (previous >= data.tagStartIndex) {
hgs
parents:
diff changeset
   361
					int endIndex = data.itr.previousIndex() + 1;
hgs
parents:
diff changeset
   362
					tracepoint = parser.getSource().get(data.tagStartIndex,
hgs
parents:
diff changeset
   363
							endIndex - data.tagStartIndex);
hgs
parents:
diff changeset
   364
					list.add(tracepoint);
hgs
parents:
diff changeset
   365
				} else {
hgs
parents:
diff changeset
   366
					list.add(tracepoint);
hgs
parents:
diff changeset
   367
				}	
hgs
parents:
diff changeset
   368
			}
hgs
parents:
diff changeset
   369
			
hgs
parents:
diff changeset
   370
			// In case like below we have parsed all parameters and data is completed if next character after ')' is ':' 
hgs
parents:
diff changeset
   371
			// and open bracket count is 0:
hgs
parents:
diff changeset
   372
			// 		CNpeSendData::CNpeSendData(RMeDriver* aDriver, TUint16 aMaxMsgLength): CActive(EPriorityStandard),
hgs
parents:
diff changeset
   373
			//				iDriver(aDriver),
hgs
parents:
diff changeset
   374
			//				iMaxMsgLength(aMaxMsgLength)
hgs
parents:
diff changeset
   375
			if (data.itr.hasNext()){
hgs
parents:
diff changeset
   376
				char nextChar = data.itr.peek();
hgs
parents:
diff changeset
   377
				
hgs
parents:
diff changeset
   378
				if (data.value == ')' &&  nextChar == ':' && data.openBracketCount == 0) {
hgs
parents:
diff changeset
   379
					data.complete = true;
hgs
parents:
diff changeset
   380
				}
hgs
parents:
diff changeset
   381
			}
hgs
parents:
diff changeset
   382
			
hgs
parents:
diff changeset
   383
			if (data.value == ',') {
hgs
parents:
diff changeset
   384
				data.tagStartIndex = data.itr.nextIndex();
hgs
parents:
diff changeset
   385
				data.paramStartIndex = data.tagStartIndex;
hgs
parents:
diff changeset
   386
			}
hgs
parents:
diff changeset
   387
		}
hgs
parents:
diff changeset
   388
	}
hgs
parents:
diff changeset
   389
hgs
parents:
diff changeset
   390
	/**
hgs
parents:
diff changeset
   391
	 * Processes an opening bracket
hgs
parents:
diff changeset
   392
	 * 
hgs
parents:
diff changeset
   393
	 * @param data
hgs
parents:
diff changeset
   394
	 *            the search data
hgs
parents:
diff changeset
   395
	 */
hgs
parents:
diff changeset
   396
	private void processOpeningBracket(TokenizerSearchData data) {
hgs
parents:
diff changeset
   397
		data.openBracketCount++;
hgs
parents:
diff changeset
   398
		if (!data.hasData && data.openBracketCount == 1 ) {
hgs
parents:
diff changeset
   399
			// The number of initial '(' characters is stored. The
hgs
parents:
diff changeset
   400
			// parameters are assumed to end when the corresponding ')'
hgs
parents:
diff changeset
   401
			// character is encountered
hgs
parents:
diff changeset
   402
			data.tagStartIndex = data.itr.nextIndex();
hgs
parents:
diff changeset
   403
			data.paramStartIndex = data.tagStartIndex;
hgs
parents:
diff changeset
   404
			data.initialBracketCount = data.openBracketCount;
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
	 * Process a character when in quotes
hgs
parents:
diff changeset
   410
	 * 
hgs
parents:
diff changeset
   411
	 * @param data
hgs
parents:
diff changeset
   412
	 *            the search data
hgs
parents:
diff changeset
   413
	 */
hgs
parents:
diff changeset
   414
	private void processInQuotesChar(TokenizerSearchData data) {
hgs
parents:
diff changeset
   415
		if (data.value == '\"' && data.previousValue != '\\') {
hgs
parents:
diff changeset
   416
			data.inQuotes = false;
hgs
parents:
diff changeset
   417
		}
hgs
parents:
diff changeset
   418
		data.previousValue = data.value;
hgs
parents:
diff changeset
   419
	}
hgs
parents:
diff changeset
   420
hgs
parents:
diff changeset
   421
	/**
hgs
parents:
diff changeset
   422
	 * Processes a character found after the closing bracket
hgs
parents:
diff changeset
   423
	 * 
hgs
parents:
diff changeset
   424
	 * @param data
hgs
parents:
diff changeset
   425
	 *            the data
hgs
parents:
diff changeset
   426
	 * @throws SourceParserException
hgs
parents:
diff changeset
   427
	 *             if invalid characters are found
hgs
parents:
diff changeset
   428
	 */
hgs
parents:
diff changeset
   429
	private void processEndOfParametersChar(TokenizerSearchData data)
hgs
parents:
diff changeset
   430
			throws SourceParserException {
hgs
parents:
diff changeset
   431
		if (data.value == ';' || data.value == '{') {
hgs
parents:
diff changeset
   432
			data.endFound = true;
hgs
parents:
diff changeset
   433
		} else if (data.value == ')') {
hgs
parents:
diff changeset
   434
			data.openBracketCount--;
hgs
parents:
diff changeset
   435
		} else if (!Character.isWhitespace(data.value)) {
hgs
parents:
diff changeset
   436
			throw new SourceParserException(SourceErrorCodes.BRACKET_MISMATCH);
hgs
parents:
diff changeset
   437
		}
hgs
parents:
diff changeset
   438
	}
hgs
parents:
diff changeset
   439
hgs
parents:
diff changeset
   440
}