type sandbox { data: (handle gap-buffer) value: (handle stream byte) trace: (handle trace) screen-var: (handle cell) keyboard-var: (handle cell) cursor-in-data?: boolean cursor-in-trace?: boolean cursor-in-keyboard?: boolean } fn initialize-sandbox _self: (addr sandbox), fake-screen-width: int, fake-screen-height: int { var self/esi: (addr sandbox) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, data allocate data-ah var data/eax: (addr gap-buffer) <- lookup *data-ah initialize-gap-buffer data, 0x40000/default-gap-buffer-size=256KB # var value-ah/eax: (addr handle stream byte) <- get self, value populate-stream value-ah, 0x1000/4KB # { compare fake-screen-width, 0 break-if-= var screen-ah/eax: (addr handle cell) <- get self, screen-var new-fake-screen screen-ah, fake-screen-width, fake-screen-height, 1/enable-pixel-graphics var keyboard-ah/eax: (addr handle cell) <- get self, keyboard-var new-fake-keyboard keyboard-ah, 0x10/keyboard-capacity } # var trace-ah/eax: (addr handle trace) <- get self, trace allocate trace-ah var trace/eax: (addr trace) <- lookup *trace-ah initialize-trace trace, 4/max-depth, 0x8000/lines, 0x80/visible var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? copy-to *cursor-in-data?, 1/true } ## some helpers for tests fn initialize-sandbox-with _self: (addr sandbox), s: (addr array byte) { var self/esi: (addr sandbox) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, data allocate data-ah var data/eax: (addr gap-buffer) <- lookup *data-ah initialize-gap-buffer-with data, s var value-ah/eax: (addr handle stream byte) <- get self, value populate-stream value-ah, 0x1000/4KB var trace-ah/eax: (addr handle trace) <- get self, trace allocate trace-ah var trace/eax: (addr trace) <- lookup *trace-ah initialize-trace trace, 3/max-depth, 0x8000/lines, 0x80/visible var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? copy-to *cursor-in-data?, 1/true } fn allocate-sandbox-with _out: (addr handle sandbox), s: (addr array byte) { var out/eax: (addr handle sandbox) <- copy _out allocate out var out-addr/eax: (addr sandbox) <- lookup *out initialize-sandbox-with out-addr, s } fn write-sandbox out: (addr stream byte), _self: (addr sandbox) { var self/eax: (addr sandbox) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, data var data/eax: (addr gap-buffer) <- lookup *data-ah { var len/eax: int <- gap-buffer-length data compare len, 0 break-if-!= return } write out, " (sandbox . [" append-gap-buffer data, out write out, "])\n" } ## fn render-sandbox screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int, show-cursor?: boolean { clear-rect screen, xmin, ymin, xmax, ymax, 0xc5/bg=blue-bg add-to xmin, 1/padding-left add-to ymin, 1/padding-top subtract-from xmax, 1/padding-right var self/esi: (addr sandbox) <- copy _self # data var data-ah/eax: (addr handle gap-buffer) <- get self, data var _data/eax: (addr gap-buffer) <- lookup *data-ah var data/edx: (addr gap-buffer) <- copy _data var x/eax: int <- copy xmin var y/ecx: int <- copy ymin y <- maybe-render-empty-screen screen, self, xmin, y y <- maybe-render-keyboard screen, self, xmin, y var cursor-in-editor?/ebx: boolean <- copy show-cursor? { compare cursor-in-editor?, 0/false break-if-= var cursor-in-data-a/eax: (addr boolean) <- get self, cursor-in-data? cursor-in-editor? <- copy *cursor-in-data-a } x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, cursor-in-editor?, 7/fg, 0xc5/bg=blue-bg y <- increment # trace var trace-ah/eax: (addr handle trace) <- get self, trace var _trace/eax: (addr trace) <- lookup *trace-ah var trace/edx: (addr trace) <- copy _trace var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? y <- render-trace screen, trace, xmin, y, xmax, ymax, *cursor-in-trace? # value $render-sandbox:value: { compare y, ymax break-if->= var value-ah/eax: (addr handle stream byte) <- get self, value var _value/eax: (addr stream byte) <- lookup *value-ah var value/esi: (addr stream byte) <- copy _value rewind-stream value var done?/eax: boolean <- stream-empty? value compare done?, 0/false break-if-!= var x/eax: int <- copy 0 x, y <- draw-text-wrapping-right-then-down screen, "=> ", xmin, y, xmax, ymax, xmin, y, 7/fg, 0xc5/bg=blue-bg var x2/edx: int <- copy x var dummy/eax: int <- draw-stream-rightward screen, value, x2, xmax, y, 7/fg=grey, 0xc5/bg=blue-bg } y <- add 2 # padding maybe-render-screen screen, self, xmin, y } fn render-sandbox-menu screen: (addr screen), _self: (addr sandbox) { var self/esi: (addr sandbox) <- copy _self var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data? compare *cursor-in-data?, 0/false { break-if-= render-sandbox-edit-menu screen, self return } var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace? compare *cursor-in-trace?, 0/false { break-if-= render-trace-menu screen return } var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard? compare *cursor-in-keyboard?, 0/false { break-if-= render-keyboard-menu screen return } } fn clear-sandbox-output screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int { # render just enough of the sandbox to figure out what to erase var self/esi: (addr sandbox) <- copy _self var data-ah/eax: (addr handle gap-buffer) <- get self, data var _data/eax: (addr gap-buffer) <- lookup *data-ah var data/edx: (addr gap-buffer) <- copy _data var x/eax: int <- copy xmin var y/ecx: int <- copy ymin y <- maybe-render-empty-screen screen, self, xmin, y y <- maybe-render-keyboard screen, self, xmin, y var cursor-in-sandbox?/ebx: (addr boolean) <- get self, cursor-in-data? x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, *cursor-in-sandbox?, 3/fg, 0xc5/bg=blue-bg y <- increment clear-rect screen, xmin, y, xmax, ymax, 0xc5/bg=blue-bg } fn maybe-render-empty-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int { var self/esi: (addr sandbox) <- copy _self var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah compare screen-obj-cell, 0 { break-if-!= return ymin } var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type compare *screen-obj-cell-type, 5/screen { break-if-= return ymin # silently give up on rendering the screen } var y/ecx: int <- copy ymin var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah var screen-obj/edx: (addr screen) <- copy _screen-obj var x/eax: int <- draw-text-rightward screen, "screen: ", xmin, 0x99/xmax, y, 0x17/fg, 0xc5/bg=blue-bg x <- copy xmin x <- add 2 y <- increment y <- render-empty-screen screen, screen-obj, x, y return y } fn maybe-render-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int { var self/esi: (addr sandbox) <- copy _self var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah compare screen-obj-cell, 0 { break-if-!= return } var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type compare *screen-obj-cell-type, 5/screen { break-if-= return # silently give up on rendering the screen } var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah var screen-obj/edx: (addr screen) <- copy _screen-obj { var screen-empty?/eax: boolean <- fake-screen-empty? screen-obj compare screen-empty?, 0/false break-if-= return } var x/eax: int <- draw-text-rightward screen, "screen: ", xmin, 0x99/xmax, ymin, 0x17/fg, 0xc5/bg=blue-bg x <- copy xmin x <- add 2 var y/ecx: int <- copy ymin y <- increment render-screen screen, screen-obj, x, y } fn render-empty-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int -> _/ecx: int { var target-screen/esi: (addr screen) <- copy _target-screen var screen-y/edi: int <- copy ymin # screen var height/edx: (addr int) <- get target-screen, height var y/ecx: int <- copy 0 { compare y, *height break-if->= set-cursor-position screen, xmin, screen-y var width/edx: (addr int) <- get target-screen, width var x/ebx: int <- copy 0 { compare x, *width break-if->= draw-code-point-at-cursor screen, 0x20/space, 0x18/fg, 0/bg move-cursor-right screen x <- increment loop } y <- increment screen-y <- increment loop } return screen-y } fn render-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int { var target-screen/esi: (addr screen) <- copy _target-screen convert-graphemes-to-pixels target-screen # might overwrite existing pixel data with graphemes # overlapping the two is not supported # pixel data { # screen top left pixels x y width height var tmp/eax: int <- copy xmin tmp <- shift-left 3/log2-font-width var left: int copy-to left, tmp tmp <- copy ymin tmp <- shift-left 4/log2-font-height var top: int copy-to top, tmp var pixels-ah/eax: (addr handle array b
#!/usr/bin/python
# Copyright (C) 2009, 2010 Roman Zimbelmann <romanz@lavabit.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Run all the tests inside the test/ directory as a test suite."""
if __name__ == '__main__':
from re import compile
from test import *
from time import time
from types import FunctionType as function
from sys import argv
bms = []
try:
n = int(argv[1])
except IndexError:
n = 10
if len(argv) > 2:
args = [compile(re) for re in argv[2:]]
def allow(name):
for re in args:
if re.search(name):
return True
else:
return False
else:
allow = lambda name: True
for key, val in vars().copy().items():
if key.startswith('bm_'):
bms.extend(v for k,v in vars(val).items() if type(v) == type)
for bmclass in bms:
for attrname in vars(bmclass):
if not attrname.startswith('bm_'):
continue
bmobj = bmclass()
t1 = time()
method = getattr(bmobj, attrname)
methodname = "{0}.{1}".format(bmobj.__class__.__name__, method.__name__)
if allow(methodname):
try:
method(n)
except:
print("{0} failed!".format(methodname))
raise
else:
t2 = time()
print("{0:60}: {1:10}s".format(methodname, t2 - t1))