divide labor
This commit is contained in:
parent
4628d3dbf2
commit
98923dbe9f
65
it/buffer.py
Executable file
65
it/buffer.py
Executable file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
import importlib
|
||||
import sys
|
||||
from parse_command import parse_command
|
||||
|
||||
class Buffer: # all the information about the current file
|
||||
def carat(self):
|
||||
return self.index
|
||||
def dollar(self):
|
||||
return self.length() - 1 + self.index
|
||||
|
||||
# Rather than get the content as it's presented in the buffer object
|
||||
# (as one big string), get it as a list.
|
||||
def content_list(self):
|
||||
return self.split(self.delimiter)
|
||||
|
||||
# Build a string with the same format as the buffer.content and set the
|
||||
# buffer.content to that string, from the kind of list output by
|
||||
# buffer.content_list().
|
||||
# buffer.content_set_list(buffer.content_list()) is an expensive nop.
|
||||
def content_set_list(self, content_as_list):
|
||||
content = ""
|
||||
for line in content_as_list:
|
||||
content += line + self.delimiter
|
||||
self.content = content
|
||||
return None
|
||||
|
||||
# this is really bad because any module can call import_module_ just as
|
||||
# easily as any other. so malicious modules that, say, take 'q' and
|
||||
# make it upload a file to some external server before exiting would be
|
||||
# super easy to make.
|
||||
# the solution I see is OS-level permissions but this needs to be
|
||||
# talked about like all the time if this tool gets popular
|
||||
# [why would it?] lest some fool runs a zelda.sh script that changes
|
||||
# ~/src/it/w.py and doesn't realize in time
|
||||
def import_module_(self, name):
|
||||
try:
|
||||
self.modules[name] = importlib.import_module(name)
|
||||
except (ModuleNotFoundError, TypeError) as err:
|
||||
print(err)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def length(self):
|
||||
return self.content.count(self.delimiter)
|
||||
|
||||
def __init__(self):
|
||||
self.content = '' # content of the file
|
||||
self.delimiter = '\n' # line delimiter
|
||||
self.filename = "" # name of where we'll save the file
|
||||
self.index = 0 # indexing of dot
|
||||
self.dot = self.index - 1 # invalid position to start
|
||||
self.modules = {}
|
||||
self.saved = 1 # bool that says whether or not we have saved the file
|
||||
|
||||
def main(buffer, command):
|
||||
if len(command) == 1:
|
||||
command = command + list(vars(buffer))
|
||||
for attrib in command[1:]:
|
||||
if attrib in list(vars(buffer)):
|
||||
print("%s:\t%s" % (attrib, vars(buffer)[attrib]))
|
||||
else:
|
||||
print("No attribute: %s" % attrib)
|
||||
return buffer
|
91
it/it.py
91
it/it.py
@ -1,70 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
# it, a shITtier version of ed
|
||||
import importlib
|
||||
import sys
|
||||
from buffer import Buffer
|
||||
from parse_command import parse_command
|
||||
|
||||
def parsecommand(command):
|
||||
casesensitive = True
|
||||
escapes = {"\\"}
|
||||
quotes = {"'", '"'}
|
||||
spaces = {" ", "\t"}
|
||||
|
||||
command = command.strip()
|
||||
|
||||
inQuotes = 0
|
||||
word = ""
|
||||
parsed_command = []
|
||||
|
||||
# copied from other project. mystery code. works though
|
||||
for i in range(len(command)):
|
||||
if ((command[i] in quotes)
|
||||
and inQuotes == 0
|
||||
and (i == 0
|
||||
or (i > 0 and not(command[i-1] in escapes)))):
|
||||
inQuotes = command[i]
|
||||
|
||||
elif (command[i] == inQuotes
|
||||
and (i > 0 and not(command[i-1] in escapes))):
|
||||
inQuotes = 0
|
||||
|
||||
elif (command[i] in spaces and inQuotes == 0
|
||||
and (i > 0 and not(command[i-1] in escapes))):
|
||||
parsed_command += [word]
|
||||
word = ""
|
||||
|
||||
elif (command[i] != "\\" or (i == len(command) - 1)
|
||||
or not(command[i+1] in spaces + quotes)):
|
||||
word += command[i]
|
||||
|
||||
parsed_command += [word]
|
||||
return [] if parsed_command == [''] else parsed_command
|
||||
|
||||
class Buffer: # all the information about the current file
|
||||
def __init__(self):
|
||||
self.content = [] # content of the file
|
||||
self.dot = 0 # where we are in the file
|
||||
self.filename = "" # name of where we'll save the file
|
||||
self.saved = 1 # bool that says whether or not we have saved the file
|
||||
|
||||
def main():
|
||||
buffer = Buffer()
|
||||
modules = {}
|
||||
while True:
|
||||
def get_command():
|
||||
try:
|
||||
command = parsecommand(input())
|
||||
return parse_command(input())
|
||||
except KeyboardInterrupt: # bastard behavior from ed
|
||||
pass
|
||||
except EOFError:
|
||||
break
|
||||
if command == []:
|
||||
continue
|
||||
try:
|
||||
modules[command[0]] = importlib.import_module(command[0])
|
||||
except ModuleNotFoundError as err:
|
||||
print(err)
|
||||
else:
|
||||
buffer = modules[command[0]].main(buffer, command)
|
||||
return 0
|
||||
|
||||
def main(buffer, supplied_command):
|
||||
if supplied_command != [] and len(supplied_command) > 1:
|
||||
command = supplied_command[1:]
|
||||
else:
|
||||
command = get_command()
|
||||
|
||||
while True:
|
||||
# EOFError in get_command(); ^D
|
||||
if command == 0:
|
||||
break
|
||||
|
||||
if command == []:
|
||||
continue
|
||||
|
||||
if command[0] in buffer.modules.keys() or buffer.import_module_(command[0]):
|
||||
buffer = buffer.modules[command[0]].main(buffer, command)
|
||||
if type(buffer) is int:
|
||||
break
|
||||
|
||||
command = get_command()
|
||||
|
||||
return buffer
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
buffer = main(Buffer(), [])
|
||||
if type(buffer) is int:
|
||||
sys.exit(buffer)
|
||||
else:
|
||||
sys.exit(0)
|
||||
|
65
it/parse_command.py
Executable file
65
it/parse_command.py
Executable file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
def parse_command(command):
|
||||
casesensitive = True
|
||||
escapes = {"\\"}
|
||||
quotes = {"'", '"'}
|
||||
spaces = {" ", "\t"}
|
||||
|
||||
command = command.strip()
|
||||
|
||||
in_quotes = 0
|
||||
word = ""
|
||||
parsed_command = []
|
||||
|
||||
for i in range(len(command)):
|
||||
# if this char is a quote char
|
||||
# , we're in quotes
|
||||
if ((command[i] in quotes)
|
||||
and in_quotes == 0
|
||||
and (i == 0
|
||||
or (i > 0 and not(command[i-1] in escapes)))):
|
||||
in_quotes = command[i]
|
||||
|
||||
# if this char matches the char by which we're in quotes
|
||||
# , we're not in quotes
|
||||
elif (command[i] == in_quotes
|
||||
and (i > 0 and not(command[i-1] in escapes))):
|
||||
in_quotes = 0
|
||||
|
||||
# if this char is an arg delimiter
|
||||
# and we're not in quotes
|
||||
# and the last char isn't an escape
|
||||
# , this word is an argument
|
||||
elif (command[i] in spaces and in_quotes == 0
|
||||
and (i > 0 and not(command[i-1] in escapes))):
|
||||
parsed_command += [word]
|
||||
word = ""
|
||||
|
||||
elif (not(command[i] in escapes) or (i == len(command) - 1)
|
||||
or not(command[i+1] in spaces + quotes)):
|
||||
word += command[i]
|
||||
|
||||
parsed_command += [word]
|
||||
return [] if parsed_command == [''] else parsed_command
|
||||
|
||||
def main(*args):
|
||||
while True:
|
||||
try:
|
||||
command = input()
|
||||
except:
|
||||
break
|
||||
|
||||
if command == ".":
|
||||
break
|
||||
|
||||
command = parse_command(command)
|
||||
|
||||
for i in range(len(command)):
|
||||
print("\t%d:\t%s" % (i, command[i]))
|
||||
|
||||
return 0 if len(args) != 2 else args[0]
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
Loading…
Reference in New Issue
Block a user