| /******************************************************************************* |
| * Copyright (c) 2006, 2018 Red Hat, Inc. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Red Hat Incorporated - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.linuxtools.internal.changelog.core.editors; |
| |
| 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.IWhitespaceDetector; |
| import org.eclipse.jface.text.rules.IWordDetector; |
| import org.eclipse.jface.text.rules.Token; |
| |
| public class GNUFileEntryRule implements IPredicateRule { |
| /** |
| * The default token to be returned on success and if nothing else has been |
| * specified. |
| */ |
| protected IToken fileToken; |
| |
| protected IWordDetector fDetector = new IWordDetector() { |
| |
| @Override |
| public boolean isWordPart(char c) { |
| return Character.isJavaIdentifierPart(c) || c == '/' || c == '.' || c == '-'; |
| } |
| |
| @Override |
| public boolean isWordStart(char c) { |
| return Character.isJavaIdentifierPart(c) || c == '/' || c == '.'; |
| } |
| |
| }; |
| |
| private boolean started = false; |
| |
| private IWhitespaceDetector fWsDetector = character -> Character.isWhitespace(character); |
| |
| /** Internal setting for the un-initialized column constraint */ |
| protected static final int UNDEFINED = -1; |
| |
| /** Buffer used for pattern detection */ |
| private StringBuilder fBuffer = new StringBuilder(); |
| |
| private String fStartingSequence = "* "; |
| |
| public GNUFileEntryRule(IToken fileToken) { |
| this.fileToken = fileToken; |
| } |
| |
| @Override |
| public IToken evaluate(ICharacterScanner scanner) { |
| return evaluate(scanner, false); |
| } |
| |
| @Override |
| public IToken evaluate(ICharacterScanner scanner, boolean resume) { |
| int c = scanner.read(); |
| fBuffer.setLength(0); |
| if (!started) { |
| for (int i = 0; i < fStartingSequence.length(); i++) { |
| fBuffer.append((char) c); |
| if (fStartingSequence.charAt(i) != c) { |
| unreadBuffer(scanner); |
| return Token.UNDEFINED; |
| } |
| c = scanner.read(); |
| } |
| } else if (c == ',') { // we are continuing after a comma (perhaps we have multiple entries |
| fBuffer.append((char) c); |
| c = scanner.read(); |
| while (c != ICharacterScanner.EOF && fWsDetector.isWhitespace((char)c)) { |
| fBuffer.append((char) c); |
| c = scanner.read(); |
| } |
| scanner.unread(); |
| if (scanner instanceof GNUHyperlinkScanner) { |
| return ((GNUHyperlinkScanner)scanner).getDefaultToken(); |
| } |
| return ((GNUElementScanner)scanner).getDefaultToken(); |
| } |
| |
| boolean haveFilePart = false; |
| |
| while (c != ICharacterScanner.EOF) { |
| if (fDetector.isWordPart((char) c)) { |
| fBuffer.append((char) c); |
| haveFilePart = true; |
| } |
| else if (c == '\\') { |
| fBuffer.append((char) c); |
| c = scanner.read(); |
| if (c == ICharacterScanner.EOF) { |
| unreadBuffer(scanner); |
| return Token.UNDEFINED; |
| } |
| fBuffer.append((char) c); |
| } else { |
| break; |
| } |
| c = scanner.read(); |
| } |
| |
| if (!haveFilePart) { |
| unreadBuffer(scanner); |
| return Token.UNDEFINED; |
| } |
| |
| if (c == ',') |
| started = true; |
| |
| scanner.unread(); |
| return fileToken; |
| } |
| |
| /** |
| * Returns the characters in the buffer to the scanner. |
| * |
| * @param scanner |
| * the scanner to be used |
| */ |
| private void unreadBuffer(ICharacterScanner scanner) { |
| for (int i = fBuffer.length() - 1; i >= 0; i--) { |
| scanner.unread(); |
| } |
| started = false; |
| } |
| |
| @Override |
| public IToken getSuccessToken() { |
| return fileToken; |
| } |
| |
| } |