How to source a new function written in python on GDB? - python

I have written new convenience function(greet.py) in python in order to use it on GDB.
class Greet (gdb.Function):
"""Return string to greet someone.
Takes a name as argument."""
def __init__ (self):
super (Greet, self).__init__ ("greet")
def invoke (self, name):
return "Hello, %s!" % name.string ()
Greet ()
Now I would like to use it on GDB as convenience function. What are the procedures I should do in order to use it while debugging a program on GDB?

As you discovered there's no built in user directory from which scripts are auto-loaded.
Usually a user would source individual scripts from their ~/.gdbinit file, like this:
source /home/user/gdb/scripts/my-script.py
If a user really wants scripts to be auto-sourced from a directory without having to add them to their ~/.gdbinit then this is easily done by adding the following into ~/.gdbinit:
python
import os
directory = '/home/user/gdb/scripts/'
if os.path.isdir (directory):
for filename in sorted (os.listdir(directory)):
if filename.endswith (".py") or filename.endswith (".gdb"):
path = os.path.join(directory, filename)
gdb.execute ("source {}".format (path))
end
This will load all *.py and *.gdb scripts from /home/user/gdb/scripts/.

In order to write new convenience function in GDB :
write the function and place it under "~/gdb/python/lib/gdb/function"
import gdb
class Salam(gdb.Function):
"""Return string to greet someone.
Takes a name as argument."""
def __init__(self):
super(Salam, self).__init__("salam")
def invoke(self, name):
return "Salam, jenap %s!" % name.string ()
Salam()
Edit "~/gdb/data-directory/Makefile.in" and under "PYTHON_FILE_LIST" add "gdb/function/salam.py"
./configure
make
make install
Now, after #gdb
try typing : "print salam("Aman")"
In order the convenience function to work, it must have python support under GDB.

Related

Running a class in CMD

I am very new to python so please try keep answers very simple, as I struggle to understand the answers on similar questions. I have the file Employee.py
class Person:
def __init__(self,name,job):
self.name = name
self.job =job
def getEmployeeDescription(self):
return self.name + " is a " + self.job
This is stored on my desktop. I want to import this into cmd so I can do for example
p = Person("James","Builder")
p.name
Python works on cmd, I just dont know exactly what needs to be typed in to allow me to access this class. I tried cd Desktop > python employee.py, but this just runs the file whereas I want to be able to use the class
Open a Python REPL by typing python into the command line
Import the appropriate class that you want to use
Use the class as needed
Here's an example:
$python3
>>> from employee.py import Person
>>> person = Person('name', 'job')

Sublime plugin for executing a command

I been writing markdown files lately, and have been using the awesome table of content generator (github-markdown-toc) tool/script on a daily basis, but I'd like it to be regenerated automatically each time I press Ctrl+s, right before saving the md file in my sublime3 environment.
What I have done till now was to generate it from the shell manually, using:
gh-md-toc --insert my_file.md
So I wrote a simple plugin, but for some reason I can't see the result I wanted.
I see my print but the toc is not generated.
Does anybody has any suggestions? what's wrong?
import sublime, sublime_plugin
import subprocess
class AutoRunTOCOnSave(sublime_plugin.EventListener):
""" A class to listen for events triggered by ST. """
def on_post_save_async(self, view):
"""
This is called after a view has been saved. It runs in a separate thread
and does not block the application.
"""
file_path = view.file_name()
if not file_path:
return
NOT_FOUND = -1
pos_dot = file_path.rfind(".")
if pos_dot == NOT_FOUND:
return
file_extension = file_path[pos_dot:]
if file_extension.lower() == ".md": #
print("Markdown TOC was invoked: handling with *.md file")
subprocess.Popen(["gh-md-toc", "--insert ", file_path])
Here's a slightly modified version of your plugin:
import sublime
import sublime_plugin
import subprocess
class AutoRunTOCOnSaveListener(sublime_plugin.EventListener):
""" A class to listen for events triggered by ST. """
def on_post_save_async(self, view):
"""
This is called after a view has been saved. It runs in a separate thread
and does not block the application.
"""
file_path = view.file_name()
if not file_path:
return
if file_path.split(".")[-1].lower() == "md":
print("Markdown TOC was invoked: handling with *.md file")
subprocess.Popen(["/full/path/to/gh-md-toc", "--insert ", file_path])
I changed a couple things, along with the name of the class. First, I simplified your test for determining if the current file is a Markdown document (fewer operations means less room for error). Second, you should include the full path to the gh-md-toc command, as it's possible subprocess.Popen can't find it on the default path.
I figured out, since gh-md-toc is a bash script, I replaced the following line:
subprocess.Popen(["gh-md-toc", "--insert ", file_path])
with:
subprocess.check_call("gh-md-toc --insert %s" % file_path, shell=True)
So now it works well, on each save.

Do a maven build in a python script

I am checking out a source for a given url using a python script and I want to go to the downloadedFoler/src directory and perform a mvn clean install. I want to do it in the same script. Thank in advance.
You can do the following:
import os
import subprocess
# Context Manager to change current directory.
# I looked at this implementation on stackoverflow but unfortunately do not have the link
# to credit the user who wrote this part of the code.
class changeDir:
def __init__(self, newPath):
self.newPath = os.path.expanduser(newPath)
# Change directory with the new path
def __enter__(self):
self.savedPath = os.getcwd()
os.chdir(self.newPath)
# Return back to previous directory
def __exit__(self, etype, value, traceback):
os.chdir(self.savedPath)
# folderPath = path of the folder you want to run mvn clean install on
with changeDir(folderPath):
# ****** NOTE ******: using shell=True is strongly discouraged since it possesses security risks
subprocess.call(["mvn", "clean", "install"], shell=True)

Aliases for commands with Python cmd module

How can I create an alias for a command in a line-oriented command interpreter implemented using the cmd module?
To create a command, I must implement the do_cmd method. But I have commands with long names (like constraint) and I want to provide aliases (in fact, shortcuts) for these commands (like co). How can I do that?
One possibility that came to my mind is to implement the do_alias (like do_co) method and just calling do_cmd (do_constraint) in this method. But this brings me new commands in the help of the CLI.
Is there any other way to achieve this? Or may be is there a way to hide commands from the help output?
The following solution makes aliased commands share a single help message. It lets you keep all of your aliases in a single easy to edit place, while making documentation much easier. It checks user input against an alias dictionary with function values and overrides both the default() (See sloth & brian) and do_help() methods.
Here I've made aliases 'c' and 'con' execute do_constraint(), 'q' invoke do_quit(), and 'h' invoke do_help(). The bonus of this solution is that 'h q' and 'help quit' print the same message. Documentation for several aliased commands can maintained in a single docstring.
import cmd
class prompt(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
self.aliases = { 'c' : self.do_constraint ,
'con' : self.do_constraint ,
'q' : self.do_quit ,
'h' : self.do_help }
def do_constraint(self, arg):
'''Constrain things.'''
print('Constraint complete.')
def do_quit(self, arg):
'''Exit the program.'''
return True
def do_help(self, arg):
'''List available commands.'''
if arg in self.aliases:
arg = self.aliases[arg].__name__[3:]
cmd.Cmd.do_help(self, arg)
def default(self, line):
cmd, arg, line = self.parseline(line)
if cmd in self.aliases:
self.aliases[cmd](arg)
else:
print("*** Unknown syntax: %s" % line)
You can overwrite the default method and search for a suitable command handler (as already suggested by Brian):
import cmd
class WithAliasCmd(cmd.Cmd):
def default(self, line):
cmd, arg, line = self.parseline(line)
func = [getattr(self, n) for n in self.get_names() if n.startswith('do_' + cmd)]
if func: # maybe check if exactly one or more elements, and tell the user
func[0](arg)
The docs mention a default method, which you can override to handle any unknown command. Code it to prefix scan a list of commands and invoke them as you suggest for do_alias.

Grep-ing classes / functions from projects

Is there a way in grep (or vim) to print out a named function/class?
i.e. From:
class InternalTimer(Sim.Process):
def __init__(self, fsm):
Sim.Process.__init__(self, name="Timer")
random.seed()
self.fsm = fsm
def Lifecycle(self, Request):
while True:
yield Sim.waitevent, self, Request
yield Sim.hold, self, Request.signalparam[0]
if(self.interrupted()):
self.interruptReset()
else:
self.fsm.process(Request.signalparam[1])
Calling $my-func-grep '__init__(self,fsm)' filename.py would produce
def __init__(self, fsm):
Sim.Process.__init__(self, name="Timer")
random.seed()
self.fsm = fsm
You could create a vim extension which effectively performs the following:
import inspect
print inspect.getsource(name_of_function)
This prints the function signature and the body of the function. If Vim has been compiled with Python support, you can write extensions in Python itself.

Categories

Resources