GP-4659: Renaming "Python" module to "Jython"

This commit is contained in:
Ryan Kurtz 2024-06-03 11:29:56 -04:00
parent 9840eee937
commit fb1f725f5b
46 changed files with 285 additions and 284 deletions

View file

@ -21,7 +21,7 @@ apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
apply from: "$rootProject.projectDir/gradle/javadoc.gradle"
apply plugin: 'eclipse'
eclipse.project.name = 'Features Python'
eclipse.project.name = 'Features Jython'
def JYTHON = "org.python:jython-standalone:2.7.3"
@ -51,15 +51,15 @@ task jythonUnpack(type: Copy) {
destinationDir file("build/data/${JYTHON_DIR}")
}
task pythonSrcCopy(type: Copy) {
description "Copy python-src directory (for Feature Python)"
task jythonSrcCopy(type: Copy) {
description "Copy jython-src directory (for Feature Jython)"
from(file("python-src"))
from(file("jython-src"))
destinationDir file("build/data/python-src")
destinationDir file("build/data/jython-src")
}
// Ensure that Jython is usable in development xx
rootProject.prepDev.dependsOn jythonUnpack
jar.dependsOn jythonUnpack
jar.dependsOn pythonSrcCopy
jar.dependsOn jythonSrcCopy

View file

@ -2,7 +2,7 @@
##MODULE IP: Jython License
##MODULE IP: LGPL 2.1
Module.manifest||GHIDRA||||END|
data/python.theme.properties||GHIDRA||||END|
data/jython.theme.properties||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/topics/Python/interpreter.html||GHIDRA||||END|
src/main/help/help/topics/Jython/interpreter.html||GHIDRA||||END|
src/main/resources/images/python.png||GHIDRA||||END|

View file

@ -0,0 +1,21 @@
[Defaults]
color.fg.plugin.jython.syntax.class = color.palette.blue
color.fg.plugin.jython.syntax.code = color.palette.darkgreen
color.fg.plugin.jython.syntax.function = color.palette.green
color.fg.plugin.jython.syntax.instance = color.palette.purple
color.fg.plugin.jython.syntax.map = color.palette.steelblue
color.fg.plugin.jython.syntax.method = color.palette.teal
color.fg.plugin.jython.syntax.null = color.palette.red
color.fg.plugin.jython.syntax.number = color.palette.darkgray
color.fg.plugin.jython.syntax.package = color.palette.darkred
color.fg.plugin.jython.syntax.sequence = color.palette.saddlebrown
color.fg.plugin.jython.syntax.special = color.palette.darkgreen
icon.plugin.jython = python.png
[Dark Defaults]

View file

@ -16,7 +16,7 @@ import sys
import tokenize
import types
import __main__
from ghidra.python import PythonCodeCompletionFactory
from ghidra.jython import JythonCodeCompletionFactory
import java # needed for java.lang.Class
try:
@ -72,7 +72,7 @@ def getAutoCompleteList(command='', locals=None, includeMagic=1,
pyObj = getattr(object, attribute)
else:
pyObj = locals[attribute]
completion_list.append(PythonCodeCompletionFactory.
completion_list.append(JythonCodeCompletionFactory.
newCodeCompletion(attribute,
attribute,
pyObj,

View file

@ -8,7 +8,7 @@ import string
import __builtin__
import java # needed for java.lang.Class
import org # for org.python.core
import ghidra # for PythonCodeCompletionFactory
import ghidra # for JythonCodeCompletionFactory
__author__ = "Don Coleman <dcoleman@chariotsolutions.com>"

View file

@ -3,7 +3,7 @@
<tocroot>
<tocref id="Ghidra Functionality">
<tocref id="Scripting">
<tocdef id="Python Interpreter" sortgroup="z" text="Python Interpreter" target="help/topics/Python/interpreter.html" />
<tocdef id="Jython Interpreter" sortgroup="z" text="Jython Interpreter" target="help/topics/Jython/interpreter.html" />
</tocref>
</tocref>
</tocroot>

View file

@ -2,15 +2,15 @@
<HTML>
<HEAD>
<TITLE>Python Interpreter</TITLE>
<TITLE>Jython Interpreter</TITLE>
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
</HEAD>
<BODY lang="EN-US">
<H1><A name="Python"></A>Python Interpreter</H1>
<H1><A name="Jython"></A>Jython Interpreter</H1>
<P>
The Ghidra <I>Python Interpreter</I> provides a full general-purpose Python interactive shell
The Ghidra <I>Jython Interpreter</I> provides a full general-purpose Jython interactive shell
and allows you to interact with your current Ghidra session by exposing Ghidra's powerful Java
API through the magic of Jython.
</P>
@ -18,7 +18,7 @@
<H2>Environment</H2>
<BLOCKQUOTE>
<P>
The Ghidra <I>Python Interpreter</I> is configured to run in a similar context as a Ghidra
The Ghidra <I>Jython Interpreter</I> is configured to run in a similar context as a Ghidra
script. Therefore, you immediately have access to variables such as <TT>currentProgram</TT>,
<TT>currentSelection</TT>, <TT>currentAddress</TT>, etc without needing to import them.
These variables exist as Java objects behind the scenes, but Jython allows you to interact with
@ -48,7 +48,7 @@
hierarchy, so nothing has to be explicitly imported before they can be used. However, because
the <TT>DataTypeSelectionDialog</TT> class and <TT>AllowedDataType</TT> enum reside in
different packages, they must be explicitly imported. Failure to do so will result in a
Python <TT><FONT COLOR="RED">NameError</FONT></TT>.
Jython <TT><FONT COLOR="RED">NameError</FONT></TT>.
</P>
</BLOCKQUOTE>
@ -78,7 +78,7 @@
<H2>Keybindings</H2>
<BLOCKQUOTE>
<P>
The Ghidra <I>Python Interpreter</I> supports the following hard-coded keybindings:
The Ghidra <I>Jython Interpreter</I> supports the following hard-coded keybindings:
<UL>
<LI><B>(up):</B>&nbsp;&nbsp;Move backward in command stack</LI>
<LI><B>(down):</B>&nbsp;&nbsp;Move forward in command stack</LI>
@ -100,7 +100,7 @@
<H2>Copy/Paste</H2>
<BLOCKQUOTE>
<P>
Copy and paste from within the Ghidra <I>Python Interpreter</I> should work as expected for
Copy and paste from within the Ghidra <I>Jython Interpreter</I> should work as expected for
your given environment:
<UL>
<LI><B>Windows:</B>&nbsp;&nbsp;CTRL+C / CTRL+V</LI>
@ -113,7 +113,7 @@
<H2>API Documentation</H2>
<BLOCKQUOTE>
<P>
The built-in <TT>help()</TT> Python function has been altered by the Ghidra <I>Python Interpreter</I>
The built-in <TT>help()</TT> Jython function has been altered by the Ghidra <I>Jython Interpreter</I>
to add support for displaying Ghidra's Javadoc (where available) for a given Ghidra class, method,
or variable. For example, to see Ghidra's Javadoc on the <TT>state</TT> variable, simply do:
<PRE>
@ -147,7 +147,7 @@
</P>
<P>
<B>Note:</B> It may be necessary to import a Ghidra class before calling the built-in <TT>help()</TT>
Python function on it. Failure to do so will result in a Python <TT><FONT COLOR="RED">NameError</FONT></TT>.
Jython function on it. Failure to do so will result in a Jython <TT><FONT COLOR="RED">NameError</FONT></TT>.
</P>
</BLOCKQUOTE>
@ -160,7 +160,7 @@
</P>
</BLOCKQUOTE>
<P align="left" class="providedbyplugin">Provided by: <I>PythonPlugin</I></P>
<P align="left" class="providedbyplugin">Provided by: <I>JythonPlugin</I></P>
<P>&nbsp;</P>
<BR>

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.File;
import java.io.IOException;
@ -41,7 +41,7 @@ import util.CollectionUtils;
* There is no longer a way to reset an interpreter...it was too complicated to get right.
* Instead, you should {@link #cleanup()} your old interpreter and make a new one.
*/
public class GhidraPythonInterpreter extends InteractiveInterpreter {
public class GhidraJythonInterpreter extends InteractiveInterpreter {
private static boolean pythonInitialized;
private static List<PyString> defaultPythonPath;
@ -58,23 +58,23 @@ public class GhidraPythonInterpreter extends InteractiveInterpreter {
*
* @return A new GhidraPythonInterpreter. Could be null if it failed to be created.
*/
public static GhidraPythonInterpreter get() {
public static GhidraJythonInterpreter get() {
// Initialize the python environment if necessary. Only needs to happen once.
if (!pythonInitialized) {
try {
// Setup python home directory
PythonUtils.setupPythonHomeDir();
JythonUtils.setupJythonHomeDir();
// Setup python cache directory
PythonUtils.setupPythonCacheDir(TaskMonitor.DUMMY);
JythonUtils.setupJythonCacheDir(TaskMonitor.DUMMY);
// Indicate that we've initialized the python environment, which should
// only happen once.
pythonInitialized = true;
}
catch (Exception e) {
Msg.showError(GhidraPythonInterpreter.class, null, "Python error",
Msg.showError(GhidraJythonInterpreter.class, null, "Python error",
"Problem getting Ghirda Python interpreter", e);
return null;
}
@ -86,7 +86,7 @@ public class GhidraPythonInterpreter extends InteractiveInterpreter {
state.ps2 = new PyString("... ");
// Return a new instance of our interpreter
return new GhidraPythonInterpreter(state);
return new GhidraJythonInterpreter(state);
}
/**
@ -94,7 +94,7 @@ public class GhidraPythonInterpreter extends InteractiveInterpreter {
*
* @param state The initial system state of the interpreter.
*/
private GhidraPythonInterpreter(PySystemState state) {
private GhidraJythonInterpreter(PySystemState state) {
super(null, state);
// Store the default python path in case we need to reset it later.
@ -158,7 +158,7 @@ public class GhidraPythonInterpreter extends InteractiveInterpreter {
* @throws PyException if an unhandled exception occurred while executing the line of python
* @throws IllegalStateException if this interpreter has been cleaned up.
*/
public synchronized boolean push(String line, PythonScript script)
public synchronized boolean push(String line, JythonScript script)
throws PyException, IllegalStateException {
if (cleanedUp) {
@ -198,7 +198,7 @@ public class GhidraPythonInterpreter extends InteractiveInterpreter {
* @param script A PythonScript from which we load state (or null).
* @throws IllegalStateException if this interpreter has been cleaned up.
*/
public synchronized void execFile(ResourceFile file, PythonScript script)
public synchronized void execFile(ResourceFile file, JythonScript script)
throws IllegalStateException {
if (cleanedUp) {
@ -332,7 +332,7 @@ public class GhidraPythonInterpreter extends InteractiveInterpreter {
*
* @param script The script whose class hierarchy is to be used for injection.
*/
void injectScriptHierarchy(PythonScript script) {
void injectScriptHierarchy(JythonScript script) {
if (script == null) {
return;
@ -447,7 +447,7 @@ public class GhidraPythonInterpreter extends InteractiveInterpreter {
* @param includeBuiltins True if we should include python built-ins; otherwise, false.
* @param caretPos The position of the caret in the input string 'cmd'
* @return A list of possible command completions. Could be empty if there aren't any.
* @see PythonPlugin#getCompletions
* @see JythonPlugin#getCompletions
*/
List<CodeCompletion> getCommandCompletions(String cmd, boolean includeBuiltins, int caretPos) {
// At this point the caret is assumed to be positioned right after the value we need to

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.awt.Color;
import java.lang.reflect.Method;
@ -31,12 +31,12 @@ import ghidra.framework.options.Options;
import ghidra.util.Msg;
/**
* Generates CodeCompletions from Python objects.
* Generates CodeCompletions from Jython objects.
*
*
*
*/
public class PythonCodeCompletionFactory {
public class JythonCodeCompletionFactory {
private static List<Class<?>> classes = new ArrayList<>();
private static Map<Class<?>, Color> classToColorMap = new HashMap<>();
/* necessary because we only want to show the user the simple class name
@ -47,7 +47,7 @@ public class PythonCodeCompletionFactory {
private static Map<Class<?>, String> classDescription = new HashMap<>();
public static final String COMPLETION_LABEL = "Code Completion Colors";
/* package-level accessibility so that PythonPlugin can tell this is
/* package-level accessibility so that JythonPlugin can tell this is
* our option
*/
final static String INCLUDE_TYPES_LABEL = "Include type names in code completion popup?";
@ -59,19 +59,19 @@ public class PythonCodeCompletionFactory {
private static boolean includeTypes = INCLUDE_TYPES_DEFAULT;
//@formatter:off
public static final Color NULL_COLOR = new GColor("color.fg.plugin.python.syntax.null");
public static final Color FUNCTION_COLOR = new GColor("color.fg.plugin.python.syntax.function");
public static final Color PACKAGE_COLOR = new GColor("color.fg.plugin.python.syntax.package");
public static final Color CLASS_COLOR = new GColor("color.fg.plugin.python.syntax.class");
public static final Color METHOD_COLOR = new GColor("color.fg.plugin.python.syntax.method");
public static final Color NULL_COLOR = new GColor("color.fg.plugin.jython.syntax.null");
public static final Color FUNCTION_COLOR = new GColor("color.fg.plugin.jython.syntax.function");
public static final Color PACKAGE_COLOR = new GColor("color.fg.plugin.jython.syntax.package");
public static final Color CLASS_COLOR = new GColor("color.fg.plugin.jython.syntax.class");
public static final Color METHOD_COLOR = new GColor("color.fg.plugin.jython.syntax.method");
/* anonymous code chunks */
public static final Color CODE_COLOR = new GColor("color.fg.plugin.python.syntax.code");
public static final Color INSTANCE_COLOR = new GColor("color.fg.plugin.python.syntax.instance");
public static final Color SEQUENCE_COLOR = new GColor("color.fg.plugin.python.syntax.sequence");
public static final Color MAP_COLOR = new GColor("color.fg.plugin.python.syntax.map");
public static final Color NUMBER_COLOR = new GColor("color.fg.plugin.python.syntax.number");
public static final Color CODE_COLOR = new GColor("color.fg.plugin.jython.syntax.code");
public static final Color INSTANCE_COLOR = new GColor("color.fg.plugin.jython.syntax.instance");
public static final Color SEQUENCE_COLOR = new GColor("color.fg.plugin.jython.syntax.sequence");
public static final Color MAP_COLOR = new GColor("color.fg.plugin.jython.syntax.map");
public static final Color NUMBER_COLOR = new GColor("color.fg.plugin.jython.syntax.number");
/* for weird Jython-specific stuff */
public static final Color SPECIAL_COLOR = new GColor("color.fg.plugin.python.syntax.special");
public static final Color SPECIAL_COLOR = new GColor("color.fg.plugin.jython.syntax.special");
//@formatter:on
static {
@ -174,18 +174,18 @@ public class PythonCodeCompletionFactory {
classDescription.put(klass, description);
}
catch (ClassNotFoundException cnfe) {
Msg.debug(PythonCodeCompletionFactory.class, "Unable to find class: " + className,
Msg.debug(JythonCodeCompletionFactory.class, "Unable to find class: " + className,
cnfe);
}
}
/**
* Creates a new CodeCompletion from the given Python objects.
* Creates a new CodeCompletion from the given Jython objects.
*
* @param description description of the new CodeCompletion
* @param insertion what will be inserted to make the code complete
* @param pyObj a Python Object
* @return A new CodeCompletion from the given Python objects.
* @param pyObj a Jython Object
* @return A new CodeCompletion from the given Jython objects.
* @deprecated use {@link #newCodeCompletion(String, String, PyObject, String)} instead,
* it allows creation of substituting code completions
*/
@ -196,15 +196,15 @@ public class PythonCodeCompletionFactory {
}
/**
* Creates a new CodeCompletion from the given Python objects.
* Creates a new CodeCompletion from the given Jython objects.
*
* @param description description of the new CodeCompletion
* @param insertion what will be inserted to make the code complete
* @param pyObj a Python Object
* @param pyObj a Jython Object
* @param userInput a word we want to complete, can be an empty string.
* It's used to determine which part (if any) of the input should be
* removed before the insertion of the completion
* @return A new CodeCompletion from the given Python objects.
* @return A new CodeCompletion from the given Jython objects.
*/
public static CodeCompletion newCodeCompletion(String description, String insertion,
PyObject pyObj, String userInput) {
@ -241,11 +241,11 @@ public class PythonCodeCompletionFactory {
}
/**
* Sets up Python code completion Options.
* @param plugin python plugin as options owner
* Sets up Jython code completion Options.
* @param plugin jython plugin as options owner
* @param options an Options handle
*/
public static void setupOptions(PythonPlugin plugin, Options options) {
public static void setupOptions(JythonPlugin plugin, Options options) {
includeTypes = options.getBoolean(INCLUDE_TYPES_LABEL, INCLUDE_TYPES_DEFAULT);
options.registerOption(INCLUDE_TYPES_LABEL, INCLUDE_TYPES_DEFAULT, null,
INCLUDE_TYPES_DESCRIPTION);
@ -271,20 +271,20 @@ public class PythonCodeCompletionFactory {
includeTypes = ((Boolean) newValue).booleanValue();
}
else {
Msg.error(PythonCodeCompletionFactory.class, "unknown option '" + name + "'");
Msg.error(JythonCodeCompletionFactory.class, "unknown option '" + name + "'");
}
}
/**
* Returns the Java __call__ methods declared for a Python object.
* Returns the Java __call__ methods declared for a Jython object.
*
* Some Python "methods" in the new-style Python objects are actually
* Some Jython "methods" in the new-style Jython objects are actually
* classes in and of themselves, re-implementing __call__ methods to
* tell us how to call them. This returns an array of those Methods
* (for code completion help).
*
* @param obj a PyObject
* @return the Java __call__ methods declared for the Python object
* @return the Java __call__ methods declared for the Jython object
*/
public static Object[] getCallMethods(PyObject obj) {
List<Method> callMethodList = new ArrayList<>();

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.awt.event.KeyEvent;
import java.io.*;
@ -44,44 +44,44 @@ import ghidra.util.task.*;
import resources.Icons;
/**
* This plugin provides the interactive Python interpreter.
* This plugin provides the interactive Jython interpreter.
*/
//@formatter:off
@PluginInfo(
status = PluginStatus.RELEASED,
packageName = CorePluginPackage.NAME,
category = PluginCategoryNames.COMMON,
shortDescription = "Python Interpreter",
description = "Provides an interactive Python Interpreter that is tightly integrated with a loaded Ghidra program.",
shortDescription = "Jython Interpreter",
description = "Provides an interactive Jython Interpreter that is tightly integrated with a loaded Ghidra program.",
servicesRequired = { InterpreterPanelService.class },
isSlowInstallation = true
)
//@formatter:on
public class PythonPlugin extends ProgramPlugin
public class JythonPlugin extends ProgramPlugin
implements InterpreterConnection, OptionsChangeListener {
private InterpreterConsole console;
private GhidraPythonInterpreter interpreter;
private PythonScript interactiveScript;
private GhidraJythonInterpreter interpreter;
private JythonScript interactiveScript;
private TaskMonitor interactiveTaskMonitor;
private PythonPluginInputThread inputThread;
private JythonPluginInputThread inputThread;
// Plugin options
private final static String INCLUDE_BUILTINS_LABEL = "Include \"builtins\" in code completion?";
private final static String INCLUDE_BUILTINS_DESCRIPTION =
"Whether or not to include Python's built-in functions and properties in the pop-up code completion window.";
"Whether or not to include Jython's built-in functions and properties in the pop-up code completion window.";
private final static boolean INCLUDE_BUILTINS_DEFAULT = true;
private static final Icon ICON = new GIcon("icon.plugin.python");
private static final Icon ICON = new GIcon("icon.plugin.jython");
private boolean includeBuiltins = INCLUDE_BUILTINS_DEFAULT;
/**
* Creates a new PythonPlugin object.
* Creates a new {@link JythonPlugin} object.
*
* @param tool The tool associated with this plugin.
*/
public PythonPlugin(PluginTool tool) {
public JythonPlugin(PluginTool tool) {
super(tool);
}
@ -95,11 +95,11 @@ public class PythonPlugin extends ProgramPlugin
}
/**
* Gets the plugin's Python interpreter.
* Gets the plugin's Jython interpreter.
*
* @return The plugin's Python interpreter. May be null.
* @return The plugin's Jython interpreter. May be null.
*/
GhidraPythonInterpreter getInterpreter() {
GhidraJythonInterpreter getInterpreter() {
return interpreter;
}
@ -108,7 +108,7 @@ public class PythonPlugin extends ProgramPlugin
*
* @return The plugin's interactive script.
*/
PythonScript getInteractiveScript() {
JythonScript getInteractiveScript() {
return interactiveScript;
}
@ -172,7 +172,7 @@ public class PythonPlugin extends ProgramPlugin
/**
* Resets the interpreter to a new starting state. This is used when the plugin is first
* initialized, as well as when an existing interpreter receives a Python exit command.
* initialized, as well as when an existing interpreter receives a Jython exit command.
* We used to try to reset the same interpreter, but it was really hard to do that correctly
* so we now just create a brand new one.
* <p>
@ -181,7 +181,7 @@ public class PythonPlugin extends ProgramPlugin
*/
private void resetInterpreter() {
TaskLauncher.launchModal("Resetting Python...", () -> {
TaskLauncher.launchModal("Resetting Jython...", () -> {
resetInterpreterInBackground();
});
}
@ -193,23 +193,23 @@ public class PythonPlugin extends ProgramPlugin
if (interpreter == null) {
// Setup options
ToolOptions options = tool.getOptions("Python");
ToolOptions options = tool.getOptions("Jython");
includeBuiltins = options.getBoolean(INCLUDE_BUILTINS_LABEL, INCLUDE_BUILTINS_DEFAULT);
options.registerOption(INCLUDE_BUILTINS_LABEL, INCLUDE_BUILTINS_DEFAULT, null,
INCLUDE_BUILTINS_DESCRIPTION);
options.addOptionsChangeListener(this);
interpreter = GhidraPythonInterpreter.get();
interpreter = GhidraJythonInterpreter.get();
// Setup code completion. This currently has to be done after the interpreter
// is created. Otherwise an exception will occur.
PythonCodeCompletionFactory.setupOptions(this, options);
JythonCodeCompletionFactory.setupOptions(this, options);
}
else {
inputThread.shutdown();
inputThread = null;
interpreter.cleanup();
interpreter = GhidraPythonInterpreter.get();
interpreter = GhidraJythonInterpreter.get();
}
// Reset the console.
@ -224,20 +224,20 @@ public class PythonPlugin extends ProgramPlugin
// Print a welcome message.
welcome();
// Setup the PythonScript describing the state of the interactive prompt.
// Setup the JythonScript describing the state of the interactive prompt.
// This allows things like currentProgram and currentAddress to dynamically reflect
// what's happening in the listing. Injecting the script hierarchy early here allows
// code completion to work before commands are entered.
interactiveScript = new PythonScript();
interactiveScript = new JythonScript();
interactiveScript.set(
new GhidraState(tool, tool.getProject(), getCurrentProgram(), getProgramLocation(),
getProgramSelection(), getProgramHighlight()),
interactiveTaskMonitor, new PrintWriter(getConsole().getStdOut()));
interpreter.injectScriptHierarchy(interactiveScript);
interactiveTaskMonitor = new PythonInteractiveTaskMonitor(console.getStdOut());
interactiveTaskMonitor = new JythonInteractiveTaskMonitor(console.getStdOut());
// Start the input thread that receives python commands to execute.
inputThread = new PythonPluginInputThread(this);
// Start the input thread that receives jython commands to execute.
inputThread = new JythonPluginInputThread(this);
inputThread.start();
}
@ -252,11 +252,11 @@ public class PythonPlugin extends ProgramPlugin
@Override
public void optionsChanged(ToolOptions options, String optionName, Object oldValue,
Object newValue) {
if (optionName.startsWith(PythonCodeCompletionFactory.COMPLETION_LABEL)) {
PythonCodeCompletionFactory.changeOptions(options, optionName, oldValue, newValue);
if (optionName.startsWith(JythonCodeCompletionFactory.COMPLETION_LABEL)) {
JythonCodeCompletionFactory.changeOptions(options, optionName, oldValue, newValue);
}
else if (optionName.equals(PythonCodeCompletionFactory.INCLUDE_TYPES_LABEL)) {
PythonCodeCompletionFactory.changeOptions(options, optionName, oldValue, newValue);
else if (optionName.equals(JythonCodeCompletionFactory.INCLUDE_TYPES_LABEL)) {
JythonCodeCompletionFactory.changeOptions(options, optionName, oldValue, newValue);
}
else if (optionName.equals(INCLUDE_BUILTINS_LABEL)) {
includeBuiltins = ((Boolean) newValue).booleanValue();
@ -284,7 +284,7 @@ public class PythonPlugin extends ProgramPlugin
@Override
public List<CodeCompletion> getCompletions(String cmd, int caretPos) {
// Refresh the environment
interactiveScript.setSourceFile(new ResourceFile(new File("python")));
interactiveScript.setSourceFile(new ResourceFile(new File("jython")));
interactiveScript.set(
new GhidraState(tool, tool.getProject(), currentProgram, currentLocation,
currentSelection, currentHighlight),
@ -327,7 +327,7 @@ public class PythonPlugin extends ProgramPlugin
if (interpreter == null) {
return;
}
interpreter.interrupt(inputThread.getPythonPluginExecutionThread());
interpreter.interrupt(inputThread.getJythonPluginExecutionThread());
console.setPrompt(interpreter.getPrimaryPrompt());
}
@ -344,7 +344,7 @@ public class PythonPlugin extends ProgramPlugin
@Override
public String getTitle() {
return "Python";
return "Jython";
}
@Override
@ -361,7 +361,7 @@ public class PythonPlugin extends ProgramPlugin
* Prints a welcome message to the console.
*/
private void welcome() {
console.getOutWriter().println("Python Interpreter for Ghidra");
console.getOutWriter().println("Jython Interpreter for Ghidra");
console.getOutWriter().println("Based on Jython version " + PySystemState.version);
console.getOutWriter().println("Press 'F1' for usage instructions");
}
@ -369,20 +369,20 @@ public class PythonPlugin extends ProgramPlugin
/**
* Support for cancelling execution using a TaskMonitor.
*/
class PythonInteractiveTaskMonitor extends TaskMonitorAdapter {
class JythonInteractiveTaskMonitor extends TaskMonitorAdapter {
private PrintWriter output = null;
public PythonInteractiveTaskMonitor(PrintWriter stdOut) {
public JythonInteractiveTaskMonitor(PrintWriter stdOut) {
output = stdOut;
}
public PythonInteractiveTaskMonitor(OutputStream stdout) {
public JythonInteractiveTaskMonitor(OutputStream stdout) {
this(new PrintWriter(stdout));
}
@Override
public void setMessage(String message) {
output.println("<python-interactive>: " + message);
output.println("<jython-interactive>: " + message);
}
}
}

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.File;
import java.io.PrintWriter;
@ -29,23 +29,24 @@ import ghidra.program.model.listing.Program;
import ghidra.util.task.TaskMonitor;
/**
* Thread responsible for executing a python command for the plugin.
* Thread responsible for executing a jython command for the plugin.
*/
class PythonPluginExecutionThread extends Thread {
class JythonPluginExecutionThread extends Thread {
private PythonPlugin plugin;
private JythonPlugin plugin;
private String cmd;
private AtomicBoolean moreInputWanted;
/**
* Creates a new python plugin execution thread that executes the given command for the given plugin.
* Creates a new jython plugin execution thread that executes the given command for the given
* plugin.
*
* @param plugin The python plugin to execute the command for.
* @param cmd The python command to execute.
* @param plugin The jython plugin to execute the command for.
* @param cmd The jython command to execute.
* @param moreInputWanted Gets set to indicate that the executed command expects more input.
*/
PythonPluginExecutionThread(PythonPlugin plugin, String cmd, AtomicBoolean moreInputWanted) {
super("Python plugin execution thread");
JythonPluginExecutionThread(JythonPlugin plugin, String cmd, AtomicBoolean moreInputWanted) {
super("Jython plugin execution thread");
this.plugin = plugin;
this.cmd = cmd;
@ -56,14 +57,14 @@ class PythonPluginExecutionThread extends Thread {
public void run() {
TaskMonitor interactiveTaskMonitor = plugin.getInteractiveTaskMonitor();
PythonScript interactiveScript = plugin.getInteractiveScript();
JythonScript interactiveScript = plugin.getInteractiveScript();
Program program = plugin.getCurrentProgram();
// Setup transaction for the execution.
try (Transaction tx = program != null ? program.openTransaction("Python command") : null) {
try (Transaction tx = program != null ? program.openTransaction("Jython command") : null) {
// Setup Ghidra state to be passed into interpreter
interactiveTaskMonitor.clearCancelled();
interactiveScript.setSourceFile(new ResourceFile(new File("python")));
interactiveScript.setSourceFile(new ResourceFile(new File("jython")));
PluginTool tool = plugin.getTool();
interactiveScript.set(
new GhidraState(tool, tool.getProject(), program, plugin.getProgramLocation(),

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.*;
import java.util.concurrent.atomic.AtomicBoolean;
@ -21,37 +21,37 @@ import java.util.concurrent.atomic.AtomicBoolean;
import ghidra.util.Msg;
/**
* Thread responsible for getting interactive lines of python from the plugin.
* This class also kicks off the execution of that line in a new {@link PythonPluginExecutionThread}.
* Thread responsible for getting interactive lines of jython from the plugin.
* This class also kicks off the execution of that line in a new {@link JythonPluginExecutionThread}.
*/
class PythonPluginInputThread extends Thread {
class JythonPluginInputThread extends Thread {
private static int generationCount = 0;
private final PythonPlugin plugin;
private final JythonPlugin plugin;
private final AtomicBoolean moreInputWanted = new AtomicBoolean(false);
private final AtomicBoolean shutdownRequested = new AtomicBoolean(false);
private final InputStream consoleStdin;
private PythonPluginExecutionThread pythonExecutionThread;
private JythonPluginExecutionThread jythonExecutionThread;
/**
* Creates a new python input thread that gets a line of python input from the given plugin.
* Creates a new jython input thread that gets a line of jython input from the given plugin.
*
* @param plugin The python plugin to get input from.
* @param plugin The jython plugin to get input from.
*/
PythonPluginInputThread(PythonPlugin plugin) {
super("Python plugin input thread (generation " + ++generationCount + ")");
JythonPluginInputThread(JythonPlugin plugin) {
super("Jython plugin input thread (generation " + ++generationCount + ")");
this.plugin = plugin;
this.consoleStdin = plugin.getConsole().getStdin();
}
/**
* Gets the last python plugin execution thread that ran.
* Gets the last jython plugin execution thread that ran.
*
* @return The last python plugin execution thread that ran. Could be null if one never ran.
* @return The last jython plugin execution thread that ran. Could be null if one never ran.
*/
PythonPluginExecutionThread getPythonPluginExecutionThread() {
return pythonExecutionThread;
JythonPluginExecutionThread getJythonPluginExecutionThread() {
return jythonExecutionThread;
}
@Override
@ -61,13 +61,13 @@ class PythonPluginInputThread extends Thread {
while (!shutdownRequested.get() && (line = reader.readLine()) != null) {
// Execute the line in a new thread
pythonExecutionThread =
new PythonPluginExecutionThread(plugin, line, moreInputWanted);
pythonExecutionThread.start();
jythonExecutionThread =
new JythonPluginExecutionThread(plugin, line, moreInputWanted);
jythonExecutionThread.start();
try {
// Wait for the execution to finish
pythonExecutionThread.join();
jythonExecutionThread.join();
}
catch (InterruptedException ie) {
// Hey we're back... a little earlier than expected, but there must be a reason.
@ -82,7 +82,7 @@ class PythonPluginInputThread extends Thread {
}
}
catch (IOException e) {
Msg.error(PythonPluginInputThread.class,
Msg.error(JythonPluginInputThread.class,
"Internal error reading commands from interpreter console. Please reset the interpreter.",
e);
}

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.IOException;
@ -28,7 +28,7 @@ import ghidra.util.exception.CancelledException;
/**
* Launcher entry point for running Ghidra from within Jython.
*/
public class PythonRun implements GhidraLaunchable {
public class JythonRun implements GhidraLaunchable {
@Override
public void launch(GhidraApplicationLayout layout, String[] args) {
@ -37,25 +37,25 @@ public class PythonRun implements GhidraLaunchable {
ApplicationConfiguration configuration = new HeadlessGhidraApplicationConfiguration();
Application.initializeApplication(layout, configuration);
// Setup python home directory
// Setup jython home directory
try {
PythonUtils.setupPythonHomeDir();
JythonUtils.setupJythonHomeDir();
}
catch (IOException e) {
Msg.showError(PythonRun.class, null, "Python home directory", e.getMessage());
Msg.showError(JythonRun.class, null, "Jython home directory", e.getMessage());
System.exit(1);
}
// Setup python cache directory
// Setup jython cache directory
try {
PythonUtils.setupPythonCacheDir(configuration.getTaskMonitor());
JythonUtils.setupJythonCacheDir(configuration.getTaskMonitor());
}
catch (IOException e) {
Msg.showError(PythonRun.class, null, "Python cache directory", e.getMessage());
Msg.showError(JythonRun.class, null, "Jython cache directory", e.getMessage());
System.exit(1);
}
catch (CancelledException e) {
Msg.showError(PythonRun.class, null, "Operation cancelled", e.getMessage());
Msg.showError(JythonRun.class, null, "Operation cancelled", e.getMessage());
System.exit(1);
}

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicBoolean;
@ -25,11 +25,11 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.util.exception.AssertException;
/**
* A Python version of a {@link GhidraScript}.
* A Jython version of a {@link GhidraScript}.
*/
public class PythonScript extends GhidraScript {
public class JythonScript extends GhidraScript {
static final String PYTHON_INTERPRETER = "ghidra.python.interpreter";
static final String JYTHON_INTERPRETER = "ghidra.jython.interpreter";
private AtomicBoolean interpreterRunning = new AtomicBoolean();
@ -37,10 +37,10 @@ public class PythonScript extends GhidraScript {
public void run() {
// Try to get the interpreter from an existing script state.
GhidraPythonInterpreter interpreter =
(GhidraPythonInterpreter) state.getEnvironmentVar(PYTHON_INTERPRETER);
GhidraJythonInterpreter interpreter =
(GhidraJythonInterpreter) state.getEnvironmentVar(JYTHON_INTERPRETER);
// Are we being called from an already running PythonScript with existing state?
// Are we being called from an already running JythonScript with existing state?
if (interpreter != null) {
runInExistingEnvironment(interpreter);
}
@ -51,12 +51,12 @@ public class PythonScript extends GhidraScript {
@Override
public void runScript(String scriptName, GhidraState scriptState) throws Exception {
GhidraPythonInterpreter interpreter =
(GhidraPythonInterpreter) state.getEnvironmentVar(PYTHON_INTERPRETER);
GhidraJythonInterpreter interpreter =
(GhidraJythonInterpreter) state.getEnvironmentVar(JYTHON_INTERPRETER);
if (interpreter == null) {
interpreter = GhidraPythonInterpreter.get();
interpreter = GhidraJythonInterpreter.get();
if (interpreter == null) {
throw new AssertException("Could not get Ghidra Python interpreter!");
throw new AssertException("Could not get Ghidra Jython interpreter!");
}
}
ResourceFile scriptSource = GhidraScriptUtil.findScriptByName(scriptName);
@ -71,10 +71,10 @@ public class PythonScript extends GhidraScript {
updateStateFromVariables();
}
if (ghidraScript instanceof PythonScript) {
if (ghidraScript instanceof JythonScript) {
ghidraScript.set(scriptState, monitor, writer);
PythonScript pythonScript = (PythonScript) ghidraScript;
interpreter.execFile(pythonScript.getSourceFile(), pythonScript);
JythonScript jythonScript = (JythonScript) ghidraScript;
interpreter.execFile(jythonScript.getSourceFile(), jythonScript);
}
else {
ghidraScript.execute(scriptState, monitor, writer);
@ -93,7 +93,7 @@ public class PythonScript extends GhidraScript {
*
* @param interpreter The existing interpreter to execute from.
*/
private void runInExistingEnvironment(GhidraPythonInterpreter interpreter) {
private void runInExistingEnvironment(GhidraJythonInterpreter interpreter) {
interpreter.execFile(sourceFile, this);
}
@ -104,7 +104,7 @@ public class PythonScript extends GhidraScript {
private void runInNewEnvironment() {
// Create new interpreter and stick it in the script's state.
final GhidraPythonInterpreter interpreter = GhidraPythonInterpreter.get();
final GhidraJythonInterpreter interpreter = GhidraJythonInterpreter.get();
final PrintWriter stdout = getStdOut();
final PrintWriter stderr = getStdErr();
interpreter.setOut(stdout);
@ -114,11 +114,11 @@ public class PythonScript extends GhidraScript {
// script will use the same interpreter. It is questionable whether or not we should do
// this (the new script will get all of the old script's variables), but changing it now
// could break people's scripts if they expect this behavior.
state.addEnvironmentVar(PYTHON_INTERPRETER, interpreter);
state.addEnvironmentVar(JYTHON_INTERPRETER, interpreter);
// Execute the script in a new thread.
PythonScriptExecutionThread executionThread =
new PythonScriptExecutionThread(this, interpreter, interpreterRunning);
JythonScriptExecutionThread executionThread =
new JythonScriptExecutionThread(this, interpreter, interpreterRunning);
interpreterRunning.set(true);
executionThread.start();
@ -139,7 +139,7 @@ public class PythonScript extends GhidraScript {
// Cleanup the interpreter, and remove it from the state (once it's cleaned it cannot be
// reused)
interpreter.cleanup();
state.removeEnvironmentVar(PYTHON_INTERPRETER);
state.removeEnvironmentVar(JYTHON_INTERPRETER);
}
private PrintWriter getStdOut() {
@ -175,6 +175,6 @@ public class PythonScript extends GhidraScript {
@Override
public String getCategory() {
return "Python";
return "Jython";
}
}

View file

@ -13,31 +13,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.util.concurrent.atomic.AtomicBoolean;
import org.python.core.PyException;
/**
* Thread responsible for executing a python script from a file.
* Thread responsible for executing a jython script from a file.
*/
class PythonScriptExecutionThread extends Thread {
class JythonScriptExecutionThread extends Thread {
private PythonScript script;
private GhidraPythonInterpreter interpreter;
private JythonScript script;
private GhidraJythonInterpreter interpreter;
private AtomicBoolean interpreterRunning;
/**
* Creates a new python script execution thread that executes the given python script.
* Creates a new jython script execution thread that executes the given jython script.
*
* @param script The python script to execute.
* @param interpreter The python interpreter to use for execution.
* @param script The jython script to execute.
* @param interpreter The jython interpreter to use for execution.
* @param interpreterRunning Gets set to indicate whether or not the interpreter is still running the script.
*/
PythonScriptExecutionThread(PythonScript script, GhidraPythonInterpreter interpreter,
JythonScriptExecutionThread(JythonScript script, GhidraJythonInterpreter interpreter,
AtomicBoolean interpreterRunning) {
super("Python script execution thread");
super("Jython script execution thread");
this.script = script;
this.interpreter = interpreter;

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.*;
import java.util.regex.Pattern;
@ -21,7 +21,7 @@ import java.util.regex.Pattern;
import generic.jar.ResourceFile;
import ghidra.app.script.*;
public class PythonScriptProvider extends GhidraScriptProvider {
public class JythonScriptProvider extends GhidraScriptProvider {
private static final Pattern BLOCK_COMMENT = Pattern.compile("'''");
@ -39,9 +39,9 @@ public class PythonScriptProvider extends GhidraScriptProvider {
* {@inheritDoc}
*
* <p>
* In Python this is a triple single quote sequence, "'''".
* In Jython this is a triple single quote sequence, "'''".
*
* @return the Pattern for Python block comment openings
* @return the Pattern for Jython block comment openings
*/
@Override
public Pattern getBlockCommentStart() {
@ -52,9 +52,9 @@ public class PythonScriptProvider extends GhidraScriptProvider {
* {@inheritDoc}
*
* <p>
* In Python this is a triple single quote sequence, "'''".
* In Jython this is a triple single quote sequence, "'''".
*
* @return the Pattern for Python block comment openings
* @return the Pattern for Jython block comment openings
*/
@Override
public Pattern getBlockCommentEnd() {
@ -83,7 +83,7 @@ public class PythonScriptProvider extends GhidraScriptProvider {
@Override
public String getDescription() {
return "Python";
return "Jython";
}
@Override
@ -96,7 +96,7 @@ public class PythonScriptProvider extends GhidraScriptProvider {
throws GhidraScriptLoadException {
try {
Class<?> clazz = Class.forName(PythonScript.class.getName());
Class<?> clazz = Class.forName(JythonScript.class.getName());
GhidraScript script = (GhidraScript) clazz.getConstructor().newInstance();
script.setSourceFile(sourceFile);
return script;

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.*;
@ -25,83 +25,83 @@ import utilities.util.FileUtilities;
/**
* Python utility method class.
*/
public class PythonUtils {
public class JythonUtils {
public static final String PYTHON_NAME = "jython-2.7.3";
public static final String PYTHON_CACHEDIR = "jython_cachedir";
public static final String PYTHON_SRC = "python-src";
public static final String JYTHON_NAME = "jython-2.7.3";
public static final String JYTHON_CACHEDIR = "jython_cachedir";
public static final String JYTHON_SRC = "jython-src";
/**
* Sets up the python home directory. This is the directory that has the "Lib" directory in it.
* Sets up the jython home directory. This is the directory that has the "Lib" directory in it.
*
* @return The python home directory.
* @return The jython home directory.
* @throws IOException If there was a disk-related problem setting up the home directory.
*/
public static File setupPythonHomeDir() throws IOException {
public static File setupJythonHomeDir() throws IOException {
File pythonModuleDir = Application.getMyModuleRootDirectory().getFile(false);
File pythonHomeDir =
Application.getModuleDataSubDirectory(pythonModuleDir.getName(), PYTHON_NAME).getFile(
false);
File jythonModuleDir = Application.getMyModuleRootDirectory().getFile(false);
File jythonHomeDir =
Application.getModuleDataSubDirectory(jythonModuleDir.getName(), JYTHON_NAME)
.getFile(false);
if (!pythonHomeDir.exists()) {
throw new IOException("Failed to find the python home directory at: " + pythonHomeDir);
if (!jythonHomeDir.exists()) {
throw new IOException("Failed to find the jython home directory at: " + jythonHomeDir);
}
System.setProperty("python.home", pythonHomeDir.getAbsolutePath());
System.setProperty("jython.home", jythonHomeDir.getAbsolutePath());
return pythonHomeDir;
return jythonHomeDir;
}
/**
* Sets up the python cache directory. This is a temporary space that python source files
* Sets up the jython cache directory. This is a temporary space that jython source files
* get compiled to and cached. It should NOT be in the Ghidra installation directory, because
* some installations will not have the appropriate directory permissions to create new files in.
*
* @param monitor A monitor to use during the cache directory setup.
* @return The python cache directory.
* @return The jython cache directory.
* @throws IOException If there was a disk-related problem setting up the cache directory.
* @throws CancelledException If the user cancelled the setup.
*/
public static File setupPythonCacheDir(TaskMonitor monitor)
public static File setupJythonCacheDir(TaskMonitor monitor)
throws CancelledException, IOException {
File devDir = new File(Application.getUserSettingsDirectory(), "dev");
File cacheDir = new File(devDir, PYTHON_CACHEDIR);
File cacheDir = new File(devDir, JYTHON_CACHEDIR);
if (!FileUtilities.mkdirs(cacheDir)) {
throw new IOException("Failed to create the python cache directory at: " + cacheDir);
throw new IOException("Failed to create the jython cache directory at: " + cacheDir);
}
File pythonSrcDestDir = new File(cacheDir, PYTHON_SRC);
if (!FileUtilities.createDir(pythonSrcDestDir)) {
File jythonSrcDestDir = new File(cacheDir, JYTHON_SRC);
if (!FileUtilities.createDir(jythonSrcDestDir)) {
throw new IOException(
"Failed to create the " + PYTHON_SRC + " directory at: " + pythonSrcDestDir);
"Failed to create the " + JYTHON_SRC + " directory at: " + jythonSrcDestDir);
}
File pythonModuleDir = Application.getMyModuleRootDirectory().getFile(false);
File pythonSrcDir = new File(pythonModuleDir, PYTHON_SRC);
if (!pythonSrcDir.exists()) {
File jythonModuleDir = Application.getMyModuleRootDirectory().getFile(false);
File jythonSrcDir = new File(jythonModuleDir, JYTHON_SRC);
if (!jythonSrcDir.exists()) {
try {
pythonSrcDir = Application.getModuleDataSubDirectory(pythonModuleDir.getName(),
PYTHON_SRC).getFile(false);
jythonSrcDir = Application.getModuleDataSubDirectory(jythonModuleDir.getName(),
JYTHON_SRC).getFile(false);
}
catch (FileNotFoundException e) {
throw new IOException("Failed to find the module's " + PYTHON_SRC + " directory");
throw new IOException("Failed to find the module's " + JYTHON_SRC + " directory");
}
}
try {
FileUtilities.copyDir(pythonSrcDir, pythonSrcDestDir, f -> f.getName().endsWith(".py"),
FileUtilities.copyDir(jythonSrcDir, jythonSrcDestDir, f -> f.getName().endsWith(".py"),
monitor);
}
catch (IOException e) {
throw new IOException(
"Failed to copy " + PYTHON_SRC + " files to: " + pythonSrcDestDir);
"Failed to copy " + JYTHON_SRC + " files to: " + jythonSrcDestDir);
}
System.setProperty("python.cachedir.skip", "false");
System.setProperty("python.cachedir", cacheDir.getAbsolutePath());
System.setProperty("python.path", pythonSrcDestDir.getAbsolutePath());
System.setProperty("python.path", jythonSrcDestDir.getAbsolutePath());
return cacheDir;
}

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import java.io.File;

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import static org.junit.Assert.*;
@ -36,7 +36,7 @@ import ghidra.test.AbstractGhidraHeadedIntegrationTest;
/**
* Tests for the Ghidra Python Interpreter's code completion functionality.
*/
public class PythonCodeCompletionTest extends AbstractGhidraHeadedIntegrationTest {
public class JythonCodeCompletionTest extends AbstractGhidraHeadedIntegrationTest {
private String simpleTestProgram = """
my_int = 32
@ -68,13 +68,13 @@ public class PythonCodeCompletionTest extends AbstractGhidraHeadedIntegrationTes
@Rule
public TemporaryFolder tempScriptFolder = new TemporaryFolder();
private GhidraPythonInterpreter interpreter;
private GhidraJythonInterpreter interpreter;
@Before
public void setUp() throws Exception {
GhidraScriptUtil.initialize(new BundleHost(), null);
interpreter = GhidraPythonInterpreter.get();
executePythonProgram(simpleTestProgram);
interpreter = GhidraJythonInterpreter.get();
executeJythonProgram(simpleTestProgram);
}
@After
@ -160,7 +160,7 @@ public class PythonCodeCompletionTest extends AbstractGhidraHeadedIntegrationTes
return interpreter.getCommandCompletions(command, false, caretPos);
}
private void executePythonProgram(String code) {
private void executeJythonProgram(String code) {
try {
File tempFile = tempScriptFolder.newFile();
FileUtils.writeStringToFile(tempFile, code, Charset.defaultCharset());

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import static org.junit.Assert.*;
@ -29,16 +29,16 @@ import ghidra.test.AbstractGhidraHeadedIntegrationTest;
/**
* Tests the Ghidra python interpreter's functionality.
*/
public class PythonInterpreterTest extends AbstractGhidraHeadedIntegrationTest {
public class JythonInterpreterTest extends AbstractGhidraHeadedIntegrationTest {
private ByteArrayOutputStream out;
private GhidraPythonInterpreter interpreter;
private GhidraJythonInterpreter interpreter;
@Before
public void setUp() throws Exception {
out = new ByteArrayOutputStream();
GhidraScriptUtil.initialize(new BundleHost(), null);
interpreter = GhidraPythonInterpreter.get();
interpreter = GhidraJythonInterpreter.get();
interpreter.setOut(out);
interpreter.setErr(out);
}
@ -54,7 +54,7 @@ public class PythonInterpreterTest extends AbstractGhidraHeadedIntegrationTest {
* Tests that the interpreter's "push" method is working by executing a simple line of python.
*/
@Test
public void testPythonPush() {
public void testJythonPush() {
final String str = "hi";
interpreter.push("print \"" + str + "\"", null);
assertEquals(out.toString().trim(), str);
@ -64,7 +64,7 @@ public class PythonInterpreterTest extends AbstractGhidraHeadedIntegrationTest {
* Tests that the interpreter's "execFile" method is working by executing a simple file of python.
*/
@Test
public void testPythonExecFile() {
public void testJythonExecFile() {
interpreter.execFile(new ResourceFile("ghidra_scripts/python_basics.py"), null);
assertTrue(out.toString().contains("Snoopy"));
}
@ -74,7 +74,7 @@ public class PythonInterpreterTest extends AbstractGhidraHeadedIntegrationTest {
* that we install from there.
*/
@Test
public void testPythonSiteCustomize() {
public void testJythonSiteCustomize() {
interpreter.push("help", null);
assertTrue(out.toString().contains("Press 'F1'"));
}
@ -83,7 +83,7 @@ public class PythonInterpreterTest extends AbstractGhidraHeadedIntegrationTest {
* Tests that cleaning the interpreter invalidates it.
*/
@Test
public void testPythonCleanupInvalidation() {
public void testJythonCleanupInvalidation() {
interpreter.cleanup();
try {

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import static org.junit.Assert.*;
@ -28,19 +28,19 @@ import ghidra.test.TestEnv;
/**
* Tests the Python Plugin functionality.
*/
public class PythonPluginTest extends AbstractGhidraHeadedIntegrationTest {
public class JythonPluginTest extends AbstractGhidraHeadedIntegrationTest {
private TestEnv env;
private PluginTool tool;
private PythonPlugin plugin;
private JythonPlugin plugin;
@Before
public void setUp() throws Exception {
env = new TestEnv();
tool = env.getTool();
GhidraScriptUtil.initialize(new BundleHost(), null);
tool.addPlugin(PythonPlugin.class.getName());
plugin = env.getPlugin(PythonPlugin.class);
tool.addPlugin(JythonPlugin.class.getName());
plugin = env.getPlugin(JythonPlugin.class);
}
@After
@ -53,10 +53,10 @@ public class PythonPluginTest extends AbstractGhidraHeadedIntegrationTest {
* Tests that issuing a reset from the plugin resets the interpreter.
*/
@Test
public void testPythonPluginReset() {
GhidraPythonInterpreter origInterpreter = plugin.getInterpreter();
public void testJythonPluginReset() {
GhidraJythonInterpreter origInterpreter = plugin.getInterpreter();
plugin.reset();
GhidraPythonInterpreter newInterpreter = plugin.getInterpreter();
GhidraJythonInterpreter newInterpreter = plugin.getInterpreter();
assertNotSame(origInterpreter, newInterpreter);
}
}

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import static org.junit.Assert.*;
@ -31,7 +31,7 @@ import ghidra.app.script.GhidraScriptUtil;
import ghidra.app.script.ScriptInfo;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
public class PythonScriptInfoTest extends AbstractGhidraHeadedIntegrationTest {
public class JythonScriptInfoTest extends AbstractGhidraHeadedIntegrationTest {
@Before
public void setUp() throws Exception {
@ -48,7 +48,7 @@ public class PythonScriptInfoTest extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testDetailedPythonScript() {
public void testDetailedJythonScript() {
String descLine1 = "This script exists to check that the info on";
String descLine2 = "a script that has extensive documentation is";
String descLine3 = "properly parsed and represented.";
@ -99,7 +99,7 @@ public class PythonScriptInfoTest extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testPythonScriptWithBlockComment() {
public void testJythonScriptWithBlockComment() {
String description = "Script with a block comment at the top.";
String category = "Test";
ResourceFile scriptFile = null;
@ -129,7 +129,7 @@ public class PythonScriptInfoTest extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testPythonScriptWithBlockCommentAndCertifyHeader() {
public void testJythonScriptWithBlockCommentAndCertifyHeader() {
String description = "Script with a block comment at the top.";
String category = "Test";
ResourceFile scriptFile = null;
@ -168,7 +168,7 @@ public class PythonScriptInfoTest extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testPythonScriptWithoutBlockComment() {
public void testJythonScriptWithoutBlockComment() {
String description = "Script without a block comment at the top.";
String category = "Test";
ResourceFile scriptFile = null;
@ -194,7 +194,7 @@ public class PythonScriptInfoTest extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testPythonScriptWithSingleLineBlockComment() {
public void testJythonScriptWithSingleLineBlockComment() {
String description = "Script with a block comment at the top.";
String category = "Test";
ResourceFile scriptFile = null;

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.python;
package ghidra.jython;
import static org.junit.Assert.*;
@ -37,7 +37,7 @@ import ghidra.util.task.TaskMonitor;
/**
* Tests the Python script functionality.
*/
public class PythonScriptTest extends AbstractGhidraHeadedIntegrationTest {
public class JythonScriptTest extends AbstractGhidraHeadedIntegrationTest {
private TestEnv env;
private PluginTool tool;
@ -59,19 +59,19 @@ public class PythonScriptTest extends AbstractGhidraHeadedIntegrationTest {
}
/**
* Tests that Python scripts are running correctly.
* Tests that Jython scripts are running correctly.
*
* @throws Exception If an exception occurred while trying to run the script.
*/
@Test
public void testPythonScript() throws Exception {
public void testJythonScript() throws Exception {
String script = "ghidra_scripts/python_basics.py";
try {
String output = runPythonScript(Application.getModuleFile("Python", script));
String output = runPythonScript(Application.getModuleFile("Jython", script));
assertTrue(output.contains("Snoopy"));
}
catch (FileNotFoundException e) {
fail("Could not find python script: " + script);
fail("Could not find jython script: " + script);
}
catch (Exception e) {
fail("Exception occurred trying to run script: " + e.getMessage());
@ -79,18 +79,18 @@ public class PythonScriptTest extends AbstractGhidraHeadedIntegrationTest {
}
/**
* Tests that Python scripts are running correctly.
* Tests that Jython scripts are running correctly.
*
* @throws Exception If an exception occurred while trying to run the script.
*/
@Test
public void testPythonInterpreterGoneFromState() throws Exception {
public void testJythonInterpreterGoneFromState() throws Exception {
String script = "ghidra_scripts/python_basics.py";
try {
GhidraState state =
new GhidraState(env.getTool(), env.getProject(), null, null, null, null);
runPythonScript(Application.getModuleFile("Python", script), state);
assertTrue(state.getEnvironmentVar(PythonScript.PYTHON_INTERPRETER) == null);
runPythonScript(Application.getModuleFile("Jython", script), state);
assertTrue(state.getEnvironmentVar(JythonScript.JYTHON_INTERPRETER) == null);
}
catch (FileNotFoundException e) {
fail("Could not find python script: " + script);
@ -125,9 +125,9 @@ public class PythonScriptTest extends AbstractGhidraHeadedIntegrationTest {
runSwing(() -> console.clearMessages());
PythonScriptProvider scriptProvider = new PythonScriptProvider();
JythonScriptProvider scriptProvider = new JythonScriptProvider();
PrintWriter writer = new PrintWriter(new ByteArrayOutputStream());
PythonScript script = (PythonScript) scriptProvider.getScriptInstance(scriptFile, writer);
JythonScript script = (JythonScript) scriptProvider.getScriptInstance(scriptFile, writer);
script.set(state, TaskMonitor.DUMMY, writer);
script.run();

View file

@ -1,21 +0,0 @@
[Defaults]
color.fg.plugin.python.syntax.class = color.palette.blue
color.fg.plugin.python.syntax.code = color.palette.darkgreen
color.fg.plugin.python.syntax.function = color.palette.green
color.fg.plugin.python.syntax.instance = color.palette.purple
color.fg.plugin.python.syntax.map = color.palette.steelblue
color.fg.plugin.python.syntax.method = color.palette.teal
color.fg.plugin.python.syntax.null = color.palette.red
color.fg.plugin.python.syntax.number = color.palette.darkgray
color.fg.plugin.python.syntax.package = color.palette.darkred
color.fg.plugin.python.syntax.sequence = color.palette.saddlebrown
color.fg.plugin.python.syntax.special = color.palette.darkgreen
icon.plugin.python = python.png
[Dark Defaults]

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
#----------------------------------------
# Ghidra Python launch
# Ghidra Jython launch
#----------------------------------------
# Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of
@ -31,6 +31,6 @@ VMARG_LIST+="-Djava.awt.headless=true "
SCRIPT_FILE="$(readlink -f "$0" 2>/dev/null || readlink "$0" 2>/dev/null || echo "$0")"
SCRIPT_DIR="${SCRIPT_FILE%/*}"
# Launch Ghidra Python
# Launch Ghidra Jython
# DEBUG_ADDRESS set via environment for launch.sh
DEBUG_ADDRESS=${DEBUG_ADDRESS} "${SCRIPT_DIR}"/launch.sh "${LAUNCH_MODE}" jdk "Ghidra-Python" "${MAXMEM}" "${VMARG_LIST}" ghidra.python.PythonRun "$@"
DEBUG_ADDRESS=${DEBUG_ADDRESS} "${SCRIPT_DIR}"/launch.sh "${LAUNCH_MODE}" jdk "Ghidra-Jython" "${MAXMEM}" "${VMARG_LIST}" ghidra.jython.JythonRun "$@"

View file

@ -1,4 +1,4 @@
:: Ghidra python launch
:: Ghidra jython launch
@echo off
setlocal
@ -24,4 +24,4 @@ set DEBUG_ADDRESS=127.0.0.1:13002
set VMARG_LIST=-XX:ParallelGCThreads=2
set VMARG_LIST=%VMARG_LIST% -XX:CICompilerCount=2
call "%~dp0launch.bat" %LAUNCH_MODE% jdk Ghidra-Python "%MAXMEM%" "%VMARG_LIST%" ghidra.python.PythonRun %*
call "%~dp0launch.bat" %LAUNCH_MODE% jdk Ghidra-Jython "%MAXMEM%" "%VMARG_LIST%" ghidra.jython.JythonRun %*

View file

@ -36,7 +36,7 @@ import ghidra.app.plugin.core.osgi.BundleStatusComponentProvider;
import ghidra.app.plugin.core.script.*;
import ghidra.app.script.*;
import ghidra.app.services.ConsoleService;
import ghidra.python.PythonScriptProvider;
import ghidra.jython.JythonScriptProvider;
import ghidra.util.HelpLocation;
public class GhidraScriptMgrPluginScreenShots extends GhidraScreenShotGenerator {
@ -223,7 +223,7 @@ public class GhidraScriptMgrPluginScreenShots extends GhidraScreenShotGenerator
List<GhidraScriptProvider> items = new ArrayList<>();
JavaScriptProvider javaScriptProvider = new JavaScriptProvider();
items.add(javaScriptProvider);
items.add(new PythonScriptProvider());
items.add(new JythonScriptProvider());
final PickProviderDialog pickDialog = new PickProviderDialog(items, javaScriptProvider);
runSwing(() -> tool.showDialog(pickDialog), false);