<commit_before>/* ###
 * IP: GHIDRA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ghidra.pcodeCPort.slghpatexpress;

import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.context.Token;
import ghidra.pcodeCPort.slghpattern.*;
import ghidra.sleigh.grammar.Location;

public class TokenPattern {
	public final Location location;

	private Pattern pattern;
	private VectorSTL<Token> toklist = new VectorSTL<Token>();
	private boolean leftell;
	private boolean rightell;

	private TokenPattern(Location location, Pattern pat) {
		this.location = location;
		pattern = pat;
		setLeftEllipsis(false);
		setRightEllipsis(false);
	}

	public void dispose() {
		pattern.dispose();
	}

	public void setLeftEllipsis(boolean val) {
		leftell = val;
	}

	public void setRightEllipsis(boolean val) {
		rightell = val;
	}

	public boolean getLeftEllipsis() {
		return leftell;
	}

	public boolean getRightEllipsis() {
		return rightell;
	}

	public Pattern getPattern() {
		return pattern;
	}

	public boolean alwaysTrue() {
		return pattern.alwaysTrue();
	}

	public boolean alwaysFalse() {
		return pattern.alwaysFalse();
	}

	public boolean alwaysInstructionTrue() {
		return pattern.alwaysInstructionTrue();
	}

	// Use the token lists to decide how the two patterns
	// should be aligned relative to each other
	// return how much -tok2- needs to be shifted
	// and set the resulting tokenlist and ellipses
	private static int calls = 0;

	private int resolveTokens(TokenPattern tok1, TokenPattern tok2) {
		calls++;
		boolean reversedirection = false;
		setLeftEllipsis(false);
		setRightEllipsis(false);
		int ressa = 0;
		int minsize =
			tok1.toklist.size() < tok2.toklist.size() ? tok1.toklist.size() : tok2.toklist.size();
		if (minsize == 0) {
			// Check if pattern doesn't care about tokens
			if ((tok1.toklist.size() == 0) && (tok1.getLeftEllipsis() == false) &&
				(tok1.getRightEllipsis() == false)) {
				toklist = tok2.toklist.copy();
				setLeftEllipsis(tok2.getLeftEllipsis());
				setRightEllipsis(tok2.getRightEllipsis());
				return 0;
			}
			else if ((tok2.toklist.size() == 0) && (tok2.getLeftEllipsis() == false) &&
				(tok2.getRightEllipsis() == false)) {
				toklist = tok1.toklist.copy();
				setLeftEllipsis(tok1.getLeftEllipsis());
				setRightEllipsis(tok1.getRightEllipsis());
				return 0;
			}
			// If one of the ellipses is true then the pattern
			// still cares about tokens even though none are
			// specified
		}

		if (tok1.getLeftEllipsis()) {
			reversedirection = true;
			if (tok2.getRightEllipsis()) {
				throw new SleighError("Right/left ellipsis", location);
			}
			else if (tok2.getLeftEllipsis()) {
				setLeftEllipsis(true);
			}
			else if (tok1.toklist.size() != minsize) {
				throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
					tok1.toklist.size(), minsize), location);
			}
			else if (tok1.toklist.size() == tok2.toklist.size()) {
				throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
			}
		}
		else if (tok1.getRightEllipsis()) {
			if (tok2.getLeftEllipsis()) {
				throw new SleighError("Left/right ellipsis", location);
			}
			else if (tok2.getRightEllipsis()) {
				setRightEllipsis(true);
			}
			else if (tok1.toklist.size() != minsize) {
				throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
					tok1.toklist.size(), minsize), location);
			}
			else if (tok1.toklist.size() == tok2.toklist.size()) {
				throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
			}
		}
		else {
			if (tok2.getLeftEllipsis()) {
				reversedirection = true;
				if (tok2.toklist.size() != minsize) {
					throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
						tok2.toklist.size(), minsize), location);
				}
				else if (tok1.toklist.size() == tok2.toklist.size()) {
					throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
				}
			}
			else if (tok2.getRightEllipsis()) {
				if (tok2.toklist.size() != minsize) {
					throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
						tok1.toklist.size(), minsize), location);
				}
				else if (tok1.toklist.size() == tok2.toklist.size()) {
					throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
				}
			}
			else {
				if (tok2.toklist.size() != tok1.toklist.size()) {
					throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
						tok2.toklist.size(), tok1.toklist.size()), location);
				}
			}
		}
		if (reversedirection) {
			for (int i = 0; i < minsize; ++i) {
				if (tok1.toklist.get(tok1.toklist.size() - 1 - i) != tok2.toklist.get(tok2.toklist.size() -
					1 - i)) {
					throw new SleighError("Mismatched tokens when combining patterns", location);
				}
			}
			if (tok1.toklist.size() <= tok2.toklist.size()) {
				for (int i = minsize; i < tok2.toklist.size(); ++i) {
					ressa += tok2.toklist.get(tok2.toklist.size() - 1 - i).getSize();
				}
			}
			else {
				for (int i = minsize; i < tok1.toklist.size(); ++i) {
					ressa += tok1.toklist.get(tok1.toklist.size() - 1 - i).getSize();
				}<commit_msg>GP-0: Fixing typo in sleigh error print (Closes #4597)<commit_after>/* ###
 * IP: GHIDRA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ghidra.pcodeCPort.slghpatexpress;

import generic.stl.IteratorSTL;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.pcodeCPort.context.Token;
import ghidra.pcodeCPort.slghpattern.*;
import ghidra.sleigh.grammar.Location;

public class TokenPattern {
	public final Location location;

	private Pattern pattern;
	private VectorSTL<Token> toklist = new VectorSTL<Token>();
	private boolean leftell;
	private boolean rightell;

	private TokenPattern(Location location, Pattern pat) {
		this.location = location;
		pattern = pat;
		setLeftEllipsis(false);
		setRightEllipsis(false);
	}

	public void dispose() {
		pattern.dispose();
	}

	public void setLeftEllipsis(boolean val) {
		leftell = val;
	}

	public void setRightEllipsis(boolean val) {
		rightell = val;
	}

	public boolean getLeftEllipsis() {
		return leftell;
	}

	public boolean getRightEllipsis() {
		return rightell;
	}

	public Pattern getPattern() {
		return pattern;
	}

	public boolean alwaysTrue() {
		return pattern.alwaysTrue();
	}

	public boolean alwaysFalse() {
		return pattern.alwaysFalse();
	}

	public boolean alwaysInstructionTrue() {
		return pattern.alwaysInstructionTrue();
	}

	// Use the token lists to decide how the two patterns
	// should be aligned relative to each other
	// return how much -tok2- needs to be shifted
	// and set the resulting tokenlist and ellipses
	private static int calls = 0;

	private int resolveTokens(TokenPattern tok1, TokenPattern tok2) {
		calls++;
		boolean reversedirection = false;
		setLeftEllipsis(false);
		setRightEllipsis(false);
		int ressa = 0;
		int minsize =
			tok1.toklist.size() < tok2.toklist.size() ? tok1.toklist.size() : tok2.toklist.size();
		if (minsize == 0) {
			// Check if pattern doesn't care about tokens
			if ((tok1.toklist.size() == 0) && (tok1.getLeftEllipsis() == false) &&
				(tok1.getRightEllipsis() == false)) {
				toklist = tok2.toklist.copy();
				setLeftEllipsis(tok2.getLeftEllipsis());
				setRightEllipsis(tok2.getRightEllipsis());
				return 0;
			}
			else if ((tok2.toklist.size() == 0) && (tok2.getLeftEllipsis() == false) &&
				(tok2.getRightEllipsis() == false)) {
				toklist = tok1.toklist.copy();
				setLeftEllipsis(tok1.getLeftEllipsis());
				setRightEllipsis(tok1.getRightEllipsis());
				return 0;
			}
			// If one of the ellipses is true then the pattern
			// still cares about tokens even though none are
			// specified
		}

		if (tok1.getLeftEllipsis()) {
			reversedirection = true;
			if (tok2.getRightEllipsis()) {
				throw new SleighError("Right/left ellipsis", location);
			}
			else if (tok2.getLeftEllipsis()) {
				setLeftEllipsis(true);
			}
			else if (tok1.toklist.size() != minsize) {
				throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
					tok1.toklist.size(), minsize), location);
			}
			else if (tok1.toklist.size() == tok2.toklist.size()) {
				throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
			}
		}
		else if (tok1.getRightEllipsis()) {
			if (tok2.getLeftEllipsis()) {
				throw new SleighError("Left/right ellipsis", location);
			}
			else if (tok2.getRightEllipsis()) {
				setRightEllipsis(true);
			}
			else if (tok1.toklist.size() != minsize) {
				throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
					tok1.toklist.size(), minsize), location);
			}
			else if (tok1.toklist.size() == tok2.toklist.size()) {
				throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
			}
		}
		else {
			if (tok2.getLeftEllipsis()) {
				reversedirection = true;
				if (tok2.toklist.size() != minsize) {
					throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
						tok2.toklist.size(), minsize), location);
				}
				else if (tok1.toklist.size() == tok2.toklist.size()) {
					throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
				}
			}
			else if (tok2.getRightEllipsis()) {
				if (tok2.toklist.size() != minsize) {
					throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
						tok2.toklist.size(), minsize), location);
				}
				else if (tok1.toklist.size() == tok2.toklist.size()) {
					throw new SleighError("Pattern size cannot vary (missing ... ?)", location);
				}
			}
			else {
				if (tok2.toklist.size() != tok1.toklist.size()) {
					throw new SleighError(String.format("Mismatched pattern sizes -- %d vs %d",
						tok2.toklist.size(), tok1.toklist.size()), location);
				}
			}
		}
		if (reversedirection) {
			for (int i = 0; i < minsize; ++i) {
				if (tok1.toklist.get(tok1.toklist.size() - 1 - i) != tok2.toklist.get(tok2.toklist.size() -
					1 - i)) {
					throw new SleighError("Mismatched tokens when combining patterns", location);
				}
			}
			if (tok1.toklist.size() <= tok2.toklist.size()) {
				for (int i = minsize; i < tok2.toklist.size(); ++i) {
					ressa += tok2.toklist.get(tok2.toklist.size() - 1 - i).getSize();
				}
			}
			else {
				for (int i = minsize; i < tok1.toklist.size(); ++i) {
					ressa += tok1.toklist.get(tok1.toklist.size() - 1 - i).getSize();
				}
{'fraction_non_alphanumeric': 0.1366906474820144, 'fraction_numerical': 0.013435035104446564, 'mean_word_length': 3.420689655172414, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3233889', 'n_tokens_mistral': 4548, 'n_tokens_neox': 3839, 'n_words': 1006}