Skip to content

Commit

Permalink
Factor out argv parser.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sarah Mount committed Jul 26, 2016
1 parent 99eec16 commit 82480bb
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 112 deletions.
103 changes: 103 additions & 0 deletions revelation/argument_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
USAGE_TEXT = """Pydgin %s Instruction Set Simulator
Usage: %s [OPTIONS] [ELFFILE]
Simulate the execution of ELFFILE.
The following OPTIONS are supported:
--help, -h Show this message and exit
--rows, -r ROWS Number of rows (default: 1)
--cols, -c COLS Number of columns (default: 1)
--first-core, -f COREID Coreid, in hex, of North West core (default: 0x808)
--ext-base, -b COREID Base address of external RAM (default: 0x8e000000)
--ext-size, -s SIZE Size of external RAM in MB (default: 32)
--env, -e ENVIRONMENT Either USER or OPERATING (ignored)
--max-insts NUM Halt after executing NUM instructions
--switch N Switch cores every N instructions (ignored)
--time, -t Print approximate timing information
--jit FLAGS Set flags to tune the JIT (see
rpython.rlib.jit.PARAMETER_DOCS)
--debug,-d FLAGS Enable debug flags in a comma-separated form. The
following flags are supported:
trace pc, decoded instructions
rf register file accesses
mem memory accesses
flags update to CPU flags
syscalls system call information
EXAMPLES:
$ %s -r 1 -c 2 -f 0x808 program.elf
$ %s -r 1 -c 2 --max-insts 20000 program.elf
$ %s --time program.elf
$ %s --debug trace,rf.mem,flags program.elf
"""


def cli_parser(argv, simulator, debug_enabled):
filename_index = 0
debug_flags = []
jit = ''
prev_token = ''
tokens_with_args = [ '-b', '--ext-base',
'-c', '--cols',
'-d', '--debug',
'-e', '--env',
'-f', '--first-core',
'--jit',
'--max-insts',
'-r', '--rows',
'-s', '--ext-size',
'--switch',
]
for index, token in enumerate(argv[1:]):
if prev_token == '':
if token == '--help' or token == '-h':
print (USAGE_TEXT % (simulator.arch_name, argv[0], argv[0],
argv[0], argv[0], argv[0]))
raise SystemExit
elif token == '--time' or token == '-t':
simulator.collect_times = True
elif token == '--debug' or token == '-d':
prev_token = token
if not debug_enabled:
print ('WARNING: debugs are not enabled for this '
'translation. To allow debugs, translate '
'with --debug option.')
elif token in tokens_with_args:
prev_token = token
elif token[:1] == '-':
print 'Unknown argument %s' % token
raise SystemExit
else:
filename_index = index + 1
break
else:
if prev_token == '--debug' or prev_token == '-d':
debug_flags = token.split(',')
elif prev_token == '--env' or prev_token == '-e':
if token =='OPERATING':
simulator.user_environment = False
elif token == 'USER':
simulator.user_environment = True
else:
print ('--env can be OPERATING or USER.')
raise SystemExit
elif prev_token == '--ext-base' or prev_token == '-b':
simulator.ext_base =int(token, 16)
elif prev_token == '--cols' or prev_token == '-c':
simulator.cols = int(token)
elif prev_token == '--first-core' or prev_token == '-f':
simulator.first_core = int(token, 16)
elif prev_token == '--jit': # pragma: no cover
jit = token
elif prev_token == '--max-insts':
simulator.max_insts = int(token)
elif prev_token == '--rows' or prev_token == '-r':
simulator.rows = int(token)
elif prev_token == '--ext-size' or prev_token == '-s':
simulator.ext_size = int(token)
elif prev_token == '--switch':
simulator.switch_interval = int(token)
prev_token = ''
if filename_index == 0:
print 'You must supply a file name'
raise SystemExit
return argv[filename_index], jit, debug_flags
114 changes: 9 additions & 105 deletions revelation/sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pydgin.misc import FatalError
from pydgin.sim import Sim, init_sim

from revelation.argument_parser import cli_parser
from revelation.elf_loader import load_program
from revelation.instruction import Instruction
from revelation.isa import decode, reg_map
Expand Down Expand Up @@ -63,37 +64,6 @@ def __init__(self):
8 : 0x20, # Wired AND-signal interrupt.
9 : 0x24, # Software-generate user interrupt.
}
Sim.help_message = """Pydgin %s Instruction Set Simulator
Usage: %s [OPTIONS] [ELFFILE]
Simulate the execution of ELFFILE.
The following OPTIONS are supported:
--help, -h Show this message and exit
--rows, -r ROWS Number of rows (default: 1)
--cols, -c COLS Number of columns (default: 1)
--first-core, -f COREID Coreid, in hex, of North West core (default: 0x808)
--ext-base, -b COREID Base address of external RAM (default: 0x8e000000)
--ext-size, -s SIZE Size of external RAM in MB (default: 32)
--env, -e ENVIRONMENT Either USER or OPERATING (ignored)
--max-insts NUM Halt after executing NUM instructions
--switch N Switch cores every N instructions (ignored)
--time, -t Print approximate timing information
--jit FLAGS Set flags to tune the JIT (see
rpython.rlib.jit.PARAMETER_DOCS)
--debug,-d FLAGS Enable debug flags in a comma-separated form. The
following flags are supported:
trace pc, decoded instructions
rf register file accesses
mem memory accesses
flags update to CPU flags
syscalls system call information
EXAMPLES:
$ %s -r 1 -c 2 -f 0x808 program.elf
$ %s -r 1 -c 2 --max-insts 20000 program.elf
$ %s --time program.elf
$ %s --debug trace,rf.mem,flags program.elf
"""

@staticmethod
def get_location(pc, core_id):
Expand All @@ -113,82 +83,16 @@ def get_entry_point(self):
def entry_point(argv):
if self.jit_enabled:
set_param(self.jitdriver, 'trace_limit', self.default_trace_limit)
filename_index = 0
debug_flags = []
prev_token = ''
tokens_with_args = [ '-b', '--ext-base',
'-c', '--cols',
'-d', '--debug',
'-e', '--env',
'-f', '--first-core',
'--jit',
'--max-insts',
'-r', '--rows',
'-s', '--ext-size',
'--switch',
]
for index, token in enumerate(argv[1:]):
if prev_token == '':
if token == '--help' or token == '-h':
print (self.help_message %
(self.arch_name, argv[0], argv[0], argv[0],
argv[0], argv[0]))
return 0
elif token == '--time' or token == '-t':
self.collect_times = True
elif token == '--debug' or token == '-d':
prev_token = token
if not Debug.global_enabled:
print ('WARNING: debugs are not enabled for this '
'translation. To allow debugs, translate '
'with --debug option.')
elif token in tokens_with_args:
prev_token = token
elif token[:1] == '-':
print 'Unknown argument %s' % token
return 1
else:
filename_index = index + 1
break
else:
if prev_token == '--debug' or prev_token == '-d':
debug_flags = token.split(',')
elif prev_token == '--env' or prev_token == '-e':
if token =='OPERATING':
self.user_environment = False
elif token == 'USER':
self.user_environment = True
else:
print ('--env can be OPERATING or USER.')
return 1
elif prev_token == '--ext-base' or prev_token == '-b':
self.ext_base = int(token, 16)
elif prev_token == '--cols' or prev_token == '-c':
self.cols = int(token)
elif prev_token == '--first-core' or prev_token == '-f':
self.first_core = int(token, 16)
elif prev_token == '--jit': # pragma: no cover
set_user_param(self.jitdriver, token)
elif prev_token == '--max-insts':
self.max_insts = int(token)
elif prev_token == '--rows' or prev_token == '-r':
self.rows = int(token)
elif prev_token == '--ext-size' or prev_token == '-s':
self.ext_size = int(token)
elif prev_token == '--switch':
self.switch_interval = int(token)
prev_token = ''
if filename_index == 0:
print 'You must supply a filename'
return 1
self.debug = Debug(debug_flags, 0)
filename = argv[filename_index]
fname, jit, flags = cli_parser(argv, self, Debug.global_enabled)
if jit: # pragma: no cover
set_user_param(self.jitdriver, jit)
self.debug = Debug(flags, 0)
try:
elf_file = open(filename, 'rb')
elf_file = open(fname, 'rb')
except IOError:
print 'Could not open file %s' % filename
return 1
self.init_state(elf_file, filename, False)
print 'Could not open file %s' % fname
raise SystemExit
self.init_state(elf_file, fname, False)
for state in self.states: # FIXME: Interleaved log.
self.debug.set_state(state)
elf_file.close()
Expand Down
15 changes: 8 additions & 7 deletions revelation/test/test_argument_parser.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from revelation.argument_parser import USAGE_TEXT
from revelation.sim import Revelation

import os.path
Expand Down Expand Up @@ -80,16 +81,16 @@ def test_argv_flags_with_no_args(argv, capfd):

@pytest.mark.parametrize('argv,expected',
[(('sim.py', '-r', '1', 'dummy.elf'), 'Could not open file dummy.elf\n'),
(('sim.py', '-t'), 'You must supply a filename\n'),
(('sim.py', '-t'), 'You must supply a file name\n'),
(('sim.py', '--flibble', 'dummy.elf'), 'Unknown argument --flibble\n'),
(('sim.py', '--env', '@', 'dummy.elf'), '--env can be OPERATING or USER.\n'),
(('sim.py', '-e', '@', 'dummy.elf'), '--env can be OPERATING or USER.\n'),
])
def test_argv_with_errors(argv, expected, capfd):
revelation = Revelation()
entry_point = revelation.get_entry_point()
retval = entry_point(argv)
assert retval == 1 # Exit failure.
with pytest.raises(SystemExit):
entry_point(argv)
out, err = capfd.readouterr()
assert err == ''
assert out == expected
Expand All @@ -98,11 +99,11 @@ def test_argv_with_errors(argv, expected, capfd):
@pytest.mark.parametrize('argv', [('sim.py', '--help'), ('sim.py', '-h')])
def test_argv_help(argv, capfd):
revelation = Revelation()
expected = (revelation.help_message % ('revelation', 'sim.py', 'sim.py',
'sim.py', 'sim.py', 'sim.py') + '\n')
expected = (USAGE_TEXT % ('revelation', 'sim.py', 'sim.py', 'sim.py',
'sim.py', 'sim.py') + '\n')
entry_point = revelation.get_entry_point()
retval = entry_point(argv)
assert retval == 0 # Exit success.
with pytest.raises(SystemExit):
entry_point(argv)
out, err = capfd.readouterr()
assert err == ''
assert out == expected

0 comments on commit 82480bb

Please sign in to comment.