patternpythonMinor
DuckyScript precompiler for Arduino Leonardo
Viewed 0 times
arduinoleonardoduckyscriptprecompilerfor
Problem
I've made a python program to convert DuckyScript code to Arduino code for Leonardo boards. Below you can find both the project files and a sample script.
```
#!/usr/bin/env python3
"""
Usage: {}
should be a DuckieScript file and will be an Arduino sketch
"""
import os
import sys
import fileinput
import textwrap
from data import keycodes
from data import code
delay = 0
cmdtype = 0
commands = ""
includes = ""
defines = ""
loop = ""
def info(type, msg, **kwargs):
lineno = fileinput.lineno()
path = os.path.basename(input_file)
exit = kwargs.get('exit', None)
types = ['error', 'warning', 'info', 'screw up risk']
message = '{}:{}: {}: {}'.format(path, lineno, types[type], msg)
print(message)
if exit:
print('{}: compilation aborted.'.format(path))
sys.exit(exit)
def getkey(keys):
global commands
keys = keys.split()
normalkey = list()
modifiers = 0
for key in keys:
if not key.isupper():
key = key.upper()
if len(key) is not 1:
info(1, 'you should type all the special keys in uppercase')
try:
key = [keycodes.get(code) for code in keycodes if key in code][0]
except IndexError:
info(0, 'unrecognized key: {}'.format(key), exit=127)
if key[1]:
modifiers |= key[0]
else:
normalkey.append(key[0])
if len(normalkey) > 6:
info(0, 'you can\'t press more than 6 keys at the same time', exit=126)
arguments = [0] * 7
arguments[6] = modifiers
for number, argument in enumerate(normalkey):
arguments[number] = argument
arguments = [format(byte, '#04x') for byte in arguments]
commands += 'sendKey({},{},{},{},{},{},{});'.format(*arguments)
commands += '\n'
return True
if len(sys.argv) is not 3:
print(__doc__.format(sys.argv[0]))
sys.exit(1)
elif not os.path.isfile(sys.argv[1]):
print()
print('
compiler.py (the program base):```
#!/usr/bin/env python3
"""
Usage: {}
should be a DuckieScript file and will be an Arduino sketch
"""
import os
import sys
import fileinput
import textwrap
from data import keycodes
from data import code
delay = 0
cmdtype = 0
commands = ""
includes = ""
defines = ""
loop = ""
def info(type, msg, **kwargs):
lineno = fileinput.lineno()
path = os.path.basename(input_file)
exit = kwargs.get('exit', None)
types = ['error', 'warning', 'info', 'screw up risk']
message = '{}:{}: {}: {}'.format(path, lineno, types[type], msg)
print(message)
if exit:
print('{}: compilation aborted.'.format(path))
sys.exit(exit)
def getkey(keys):
global commands
keys = keys.split()
normalkey = list()
modifiers = 0
for key in keys:
if not key.isupper():
key = key.upper()
if len(key) is not 1:
info(1, 'you should type all the special keys in uppercase')
try:
key = [keycodes.get(code) for code in keycodes if key in code][0]
except IndexError:
info(0, 'unrecognized key: {}'.format(key), exit=127)
if key[1]:
modifiers |= key[0]
else:
normalkey.append(key[0])
if len(normalkey) > 6:
info(0, 'you can\'t press more than 6 keys at the same time', exit=126)
arguments = [0] * 7
arguments[6] = modifiers
for number, argument in enumerate(normalkey):
arguments[number] = argument
arguments = [format(byte, '#04x') for byte in arguments]
commands += 'sendKey({},{},{},{},{},{},{});'.format(*arguments)
commands += '\n'
return True
if len(sys.argv) is not 3:
print(__doc__.format(sys.argv[0]))
sys.exit(1)
elif not os.path.isfile(sys.argv[1]):
print()
print('
Solution
Globals...
You freely modify
from anywhere, this can get real hard to keep track of, pass things as arguments and
Use multiline strings
Becomes:
The benefit in readability is clear.
You freely modify
delay = 0
cmdtype = 0
commands = ""
includes = ""
defines = ""
loop = ""from anywhere, this can get real hard to keep track of, pass things as arguments and
return instead.Use multiline strings
commands += 'int i=0;'
commands += '\n'
commands += 'for(i; i<={}; i++) {{'.format(options)
commands += '\n'
commands += ' {}'.format(last_command)
commands += '\n'
commands += ' delay({});'.format(delay)
commands += '\n'
commands += '}'
commands += '\n'Becomes:
commands = """\
int i = 0
for(i; ...
...
""".format(options, last_command, delay)The benefit in readability is clear.
Code Snippets
delay = 0
cmdtype = 0
commands = ""
includes = ""
defines = ""
loop = ""commands += 'int i=0;'
commands += '\n'
commands += 'for(i; i<={}; i++) {{'.format(options)
commands += '\n'
commands += ' {}'.format(last_command)
commands += '\n'
commands += ' delay({});'.format(delay)
commands += '\n'
commands += '}'
commands += '\n'commands = """\
int i = 0
for(i; ...
...
""".format(options, last_command, delay)Context
StackExchange Code Review Q#108174, answer score: 2
Revisions (0)
No revisions yet.