Skip to content

Commit

Permalink
Various improvements to the reference search feature
Browse files Browse the repository at this point in the history
- Implemented missing search for WAV references in BCS resources
- Improved results of music, resource, and string references in script and text resources
  • Loading branch information
Argent77 committed Jan 16, 2025
1 parent 1193487 commit 0bee49d
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 72 deletions.
3 changes: 3 additions & 0 deletions src/org/infinity/resource/bcs/BcsResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ public String getText() {
@Override
public void highlightText(int linenr, String highlightText) {
try {
linenr = Math.max(1, linenr);
int startOfs = sourceText.getLineStartOffset(linenr - 1);
int endOfs = sourceText.getLineEndOffset(linenr - 1);
if (highlightText != null) {
Expand All @@ -560,6 +561,8 @@ public void highlightText(int linenr, String highlightText) {
@Override
public void highlightText(int startOfs, int endOfs) {
try {
startOfs = Math.max(0, startOfs);
endOfs = Math.max(1, endOfs);
sourceText.setCaretPosition(startOfs);
sourceText.moveCaretPosition(endOfs - 1);
sourceText.getCaret().setSelectionVisible(true);
Expand Down
2 changes: 1 addition & 1 deletion src/org/infinity/resource/text/PlainTextResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ public void highlightText(int linenr, String highlightText) {
int endOfs = editor.getLineEndOffset(linenr - 1);
if (highlightText != null) {
String text = editor.getText(startOfs, endOfs - startOfs);
Pattern p = Pattern.compile(highlightText, Pattern.CASE_INSENSITIVE);
Pattern p = Pattern.compile(highlightText, Pattern.CASE_INSENSITIVE | Pattern.LITERAL);
Matcher m = p.matcher(text);
if (m.find()) {
startOfs += m.start();
Expand Down
27 changes: 27 additions & 0 deletions src/org/infinity/search/AbstractReferenceSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.JButton;
Expand Down Expand Up @@ -126,6 +128,31 @@ protected Runnable newWorker(ResourceEntry entry) {
};
}

/**
* Registers all matches of a variable number of regular expression patterns in a string.
*
* @param entry Resource in which match is found.
* @param content Text content of the resource.
* @param patterns A variable number of {@link Pattern} objects that are used to find matches in {@code content}.
*/
void registerTextHits(ResourceEntry entry, String content, Pattern... patterns) {
if (entry == null || content == null || patterns.length == 0) {
return;
}

final String[] lines = content.split("\r?\n");
for (int i = 0; i < lines.length; i++) {
for (final Pattern p : patterns) {
if (p != null) {
final Matcher m = p.matcher(lines[i]);
if (m.find()) {
addHit(entry, lines[i].trim(), i + 1);
}
}
}
}
}

/**
* Registers match hit.
*
Expand Down
75 changes: 30 additions & 45 deletions src/org/infinity/search/ReferenceSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
package org.infinity.search;

import java.awt.Component;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -162,36 +160,34 @@ private void searchScript(ResourceEntry entry, BcsResource bcsfile) {
decompiler.setGenerateComments(false);
decompiler.setGenerateResourcesUsed(true);
try {
String code = decompiler.decompile();
boolean resourceExists = decompiler.getResourcesUsed().contains(targetEntry);
try (final BufferedReader br = new BufferedReader(new StringReader(code))) {
// resref match
Pattern regName = Pattern.compile("\"" + Pattern.quote(targetEntry.getResourceRef()) + "\"",
Pattern.CASE_INSENSITIVE);
// script name match
Pattern regVar = null;
if (creDeathVar != null && !creDeathVar.equalsIgnoreCase(targetEntry.getResourceRef())) {
regVar = Pattern.compile("\"" + Pattern.quote(creDeathVar) + "\"", Pattern.CASE_INSENSITIVE);
}
// symbolic spell name match
Pattern regSymbol = null;
if (targetEntry.getExtension().equalsIgnoreCase("SPL")) {
String symbol = org.infinity.resource.spl.Viewer.getSymbolicName(targetEntry, false);
if (symbol != null && !symbol.isEmpty()) {
regSymbol = Pattern.compile("\\b" + Pattern.quote(symbol) + "\\b");
}
}
final String code = decompiler.decompile();
final boolean resourceExists = decompiler.getResourcesUsed().contains(targetEntry);

String line;
int lineNr = 0;
while ((line = br.readLine()) != null) {
lineNr++;
if (resourceExists && regName.matcher(line).find() || regVar != null && regVar.matcher(line).find()
|| regSymbol != null && regSymbol.matcher(line).find()) {
addHit(entry, line.trim(), lineNr);
}
// resref match
Pattern pattern1 = null;
if (resourceExists) {
pattern1 = Pattern.compile("\"" + Pattern.quote(targetEntry.getResourceRef()) + "\"",
Pattern.CASE_INSENSITIVE);
}

// script name match
Pattern pattern2 = null;
if (creDeathVar != null && !creDeathVar.equalsIgnoreCase(targetEntry.getResourceRef())) {
pattern2 = Pattern.compile("\"" + Pattern.quote(creDeathVar) + "\"", Pattern.CASE_INSENSITIVE);
}

// symbolic spell name match
Pattern pattern3 = null;
if (targetEntry.getExtension().equalsIgnoreCase("SPL")) {
final String symbol = org.infinity.resource.spl.Viewer.getSymbolicName(targetEntry, false);
if (symbol != null && !symbol.isEmpty()) {
pattern3 = Pattern.compile("\\b" + Pattern.quote(symbol) + "\\b");
}
}

if (pattern1 != null || pattern2 != null || pattern3 != null) {
registerTextHits(entry, code, pattern1, pattern2, pattern3);
}
} catch (Exception e) {
Logger.error(e);
}
Expand Down Expand Up @@ -299,23 +295,12 @@ private void searchTis(ResourceEntry entry, TisResource tis) {

private void searchText(ResourceEntry entry, PlainTextResource text) {
String name = getTargetEntry().getResourceRef();
Pattern regName = Pattern.compile("\\b(AP_|GA_)?" + name + "\\b", Pattern.CASE_INSENSITIVE);
Pattern regVar = null;
if (creDeathVar != null && !creDeathVar.equalsIgnoreCase(name)) {
regVar = Pattern.compile("\\b" + creDeathVar + "\\b", Pattern.CASE_INSENSITIVE);
}

try (final BufferedReader br = new BufferedReader(new StringReader(text.getText()))) {
String line;
int lineNr = 0;
while ((line = br.readLine()) != null) {
lineNr++;
if (regName.matcher(line).find() || regVar != null && regVar.matcher(line).find()) {
addHit(entry, line.trim(), lineNr);
}
}
} catch (Exception e) {
Logger.error(e);
final Pattern pattern1 = Pattern.compile("\\b(AP_|GA_)?" + Pattern.quote(name) + "\\b", Pattern.CASE_INSENSITIVE);
Pattern pattern2 = null;
if (creDeathVar != null && !creDeathVar.equalsIgnoreCase(name)) {
pattern2 = Pattern.compile("\\b" + Pattern.quote(creDeathVar) + "\\b", Pattern.CASE_INSENSITIVE);
}
registerTextHits(entry, text.getText(), pattern1, pattern2);
}
}
28 changes: 20 additions & 8 deletions src/org/infinity/search/ScriptReferenceSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
import org.infinity.resource.are.Door;
import org.infinity.resource.are.ITEPoint;
import org.infinity.resource.bcs.BcsResource;
import org.infinity.resource.bcs.Decompiler;
import org.infinity.resource.cre.CreResource;
import org.infinity.resource.dlg.AbstractCode;
import org.infinity.resource.dlg.DlgResource;
import org.infinity.resource.key.ResourceEntry;
import org.infinity.resource.text.PlainTextResource;
import org.tinylog.Logger;

/**
* Performs search usages of the specified script in the {@link AreResource area}, {@link BcsResource script},
Expand All @@ -37,8 +39,7 @@ public ScriptReferenceSearcher(ResourceEntry bcsScript, Component parent) {
@Override
protected void search(ResourceEntry entry, Resource resource) {
if (resource instanceof BcsResource) {
// passing raw bytecode to improve performance
searchScript(entry, ((BcsResource) resource).getCode(), null);
searchScript(entry, (BcsResource) resource);
} else if (resource instanceof PlainTextResource) {
searchText(entry, ((PlainTextResource) resource).getText());
} else if (resource instanceof AbstractStruct) {
Expand Down Expand Up @@ -67,12 +68,8 @@ private void searchStruct(ResourceEntry entry, AbstractStruct struct) {
}

private void searchText(ResourceEntry entry, String text) {
String name = targetEntry.getResourceRef();
final Pattern p = Pattern.compile("\\b" + name + "\\b", Pattern.CASE_INSENSITIVE);
final Matcher m = p.matcher(text);
if (m.find()) {
addHit(entry, entry.getSearchString(), null);
}
final String name = targetEntry.getResourceRef();
registerTextHits(entry, text, Pattern.compile("\\b" + name + "\\b", Pattern.CASE_INSENSITIVE));
}

private void searchScript(ResourceEntry entry, String script, StructEntry ref) {
Expand All @@ -83,4 +80,19 @@ private void searchScript(ResourceEntry entry, String script, StructEntry ref) {
addHit(entry, entry.getSearchString(), ref);
}
}

private void searchScript(ResourceEntry entry, BcsResource bcsFile) {
final Decompiler decompiler = new Decompiler(bcsFile.getCode(), true);
decompiler.setGenerateComments(false);
decompiler.setGenerateResourcesUsed(true);
try {
final String script = decompiler.decompile();
if (decompiler.getResourcesUsed().contains(targetEntry)) {
registerTextHits(entry, script,
Pattern.compile('"' + targetEntry.getResourceRef() + '"', Pattern.CASE_INSENSITIVE));
}
} catch (Exception e) {
Logger.error(e);
}
}
}
2 changes: 1 addition & 1 deletion src/org/infinity/search/SongReferenceSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private void searchBcs(ResourceEntry entry, BcsResource bcs) {
decompiler.setGenerateResourcesUsed(false);
try {
String text = decompiler.decompile();
searchText(entry, null, text);
registerTextHits(entry, text, pattern);
} catch (Exception e) {
Logger.error(e);
}
Expand Down
24 changes: 13 additions & 11 deletions src/org/infinity/search/StringReferenceSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,13 @@ private void searchSave(ResourceEntry entry, SavResource savfile) {
}

private void searchScript(ResourceEntry entry, BcsResource bcsfile) {
Decompiler decompiler = new Decompiler(bcsfile.getCode(), true);
final Decompiler decompiler = new Decompiler(bcsfile.getCode(), true);
decompiler.setGenerateComments(false);
decompiler.setGenerateResourcesUsed(true);
try {
decompiler.decompile();
for (final Integer stringRef : decompiler.getStringRefsUsed()) {
if (stringRef == searchvalue) {
addHit(entry, null, null);
}
final String script = decompiler.decompile();
if (decompiler.getStringRefsUsed().contains(searchvalue)) {
registerTextHits(entry, script, Pattern.compile("\\b" + searchvalue + "\\b"));
}
} catch (Exception e) {
Logger.error(e);
Expand All @@ -163,11 +161,15 @@ private void searchStruct(ResourceEntry entry, AbstractStruct struct) {
}

private void searchText(ResourceEntry entry, PlainTextResource text) {
final Matcher m = NUMBER_PATTERN.matcher(text.getText());
while (m.find()) {
long nr = Long.parseLong(m.group());
if (nr == searchvalue) {
addHit(entry, null, null);
final String[] lines = text.getText().split("\r?\n");
for (int i = 0; i < lines.length; i++) {
final Matcher m = NUMBER_PATTERN.matcher(lines[i]);
while (m.find()) {
long nr = Long.parseLong(m.group());
if (nr == searchvalue) {
addHit(entry, lines[i].trim(), i + 1);
break;
}
}
}
}
Expand Down
27 changes: 21 additions & 6 deletions src/org/infinity/search/WavReferenceSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@
package org.infinity.search;

import java.awt.Component;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.infinity.datatype.ResourceRef;
import org.infinity.datatype.StringRef;
import org.infinity.resource.AbstractStruct;
import org.infinity.resource.Resource;
import org.infinity.resource.StructEntry;
import org.infinity.resource.bcs.BcsResource;
import org.infinity.resource.bcs.Decompiler;
import org.infinity.resource.key.ResourceEntry;
import org.infinity.resource.text.PlainTextResource;
import org.infinity.util.StringTable;
import org.tinylog.Logger;

public final class WavReferenceSearcher extends AbstractReferenceSearcher {
public WavReferenceSearcher(ResourceEntry targetEntry, Component parent) {
Expand All @@ -26,6 +28,8 @@ public WavReferenceSearcher(ResourceEntry targetEntry, Component parent) {
protected void search(ResourceEntry entry, Resource resource) {
if (resource instanceof AbstractStruct) {
searchStruct(entry, (AbstractStruct) resource);
} else if (resource instanceof BcsResource) {
searchScript(entry, (BcsResource) resource);
} else if (resource instanceof PlainTextResource) {
searchText(entry, (PlainTextResource) resource);
}
Expand All @@ -47,11 +51,22 @@ private void searchStruct(ResourceEntry entry, AbstractStruct struct) {
}

private void searchText(ResourceEntry entry, PlainTextResource text) {
String nameBase = getTargetEntry().getResourceRef();
Pattern p = Pattern.compile("\\b" + nameBase + "\\b", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(text.getText());
if (m.find()) {
addHit(entry, null, null);
final String nameBase = getTargetEntry().getResourceRef();
registerTextHits(entry, text.getText(), Pattern.compile("\\b" + nameBase + "\\b", Pattern.CASE_INSENSITIVE));
}

private void searchScript(ResourceEntry entry, BcsResource bcsFile) {
final Decompiler decompiler = new Decompiler(bcsFile.getCode(), true);
decompiler.setGenerateComments(false);
decompiler.setGenerateResourcesUsed(true);
try {
final String script = decompiler.decompile();
if (decompiler.getResourcesUsed().contains(targetEntry)) {
registerTextHits(entry, script,
Pattern.compile('"' + targetEntry.getResourceRef() + '"', Pattern.CASE_INSENSITIVE));
}
} catch (Exception e) {
Logger.error(e);
}
}
}

0 comments on commit 0bee49d

Please sign in to comment.