/******************************************************************************* * Copyright (c) 2012 Sierra Wireless and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sierra Wireless - initial API and implementation *******************************************************************************/ package org.eclipse.koneki.ldt.ui.internal.editor.text.rules; import org.eclipse.jface.text.rules.ICharacterScanner; import org.eclipse.jface.text.rules.IPredicateRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.Token; import org.eclipse.koneki.ldt.ui.internal.editor.text.LuaPartitionScanner; public class LuaMultLineStringRule implements IPredicateRule { // CHECKSTYLE:OFF protected int readCount; protected IToken returnToken; // CHECKSTYLE:ON private IToken fDefaultToken; public LuaMultLineStringRule(IToken stringToken) { this.fDefaultToken = stringToken; } @Override public IToken getSuccessToken() { return fDefaultToken; } @Override public IToken evaluate(ICharacterScanner scanner) { return evaluate(scanner, false); } @Override public IToken evaluate(ICharacterScanner scanner, boolean resume) { // initialize value readCount = 0; returnToken = fDefaultToken; // evaluate rule IToken result = doEvaluate(scanner); // rewind scanner if no token detected if (result.isUndefined()) { for (; readCount > 0; readCount--) { scanner.unread(); } } return result; } protected IToken doEvaluate(ICharacterScanner scanner) { int equalsNumber = 0; int c = scanner.read(); readCount++; if (c == '[') { // begin parsing what looks like a multiline string/comment c = scanner.read(); readCount++; while (c == '=') { equalsNumber++; c = scanner.read(); readCount++; } // at this point, the current character should be '[' otherwise it means we are not // detecting a multiline string/comment opening after all if (c != '[') { return Token.UNDEFINED; } // now read characters until ']' is detected... IToken content = doEvaluateContent(scanner); if (content.isUndefined()) return content; // now, look for the second ']', which may be located after "equalsNumber" '=' signs. // we should retry as many times as we don't encounter the right pattern, or stop if we // reach the EOF c = scanner.read(); while (c != LuaPartitionScanner.EOF) { boolean missed = false; if (c == ']') { c = scanner.read(); readCount++; for (int i = 0; i < equalsNumber; i++) { if (c != '=') { missed = true; break; } c = scanner.read(); readCount++; } // if we exited the loop because there were not enough '=', we need // to start looking for the first ']' again if (missed) continue; // now should be the second ']' if (c == ']') return returnToken; // else restart looking for the first ']' c = scanner.read(); readCount++; } else { c = scanner.read(); readCount++; } } scanner.unread(); return returnToken; } return Token.UNDEFINED; } protected IToken doEvaluateContent(ICharacterScanner scanner) { int c; do { c = scanner.read(); readCount++; } while (c != ']' && c != LuaPartitionScanner.EOF); scanner.unread(); readCount--; return returnToken; } }