-- love.run: main entrypoint function for LÖVE -- -- Most apps can just use the default shown in https://love2d.org/wiki/love.run, -- but we need to override it to: -- * recover from errors (by switching to the source editor) -- * run all tests (functions starting with 'test_') on startup, and -- * save some state that makes it possible to switch between the main app -- and a source editor, while giving each the illusion of complete -- control. function love.run() Version, Major_version = App.love_version() App.snapshot_love() -- Tests always run at the start. App.run_tests_and_initialize() --? print('==') love.timer.step() local dt = 0 return function() if love.event then love.event.pump() for name, a,b,c,d,e,f in love.event.poll() do if name == "quit" then if not love.quit or not love.quit() then return a or 0 end end xpcall(function() love.handlers[name](a,b,c,d,e,f) end, handle_error) end end dt = love.timer.step() xpcall(function() App.update(dt) end, handle_error) love.graphics.origin() love.graphics.clear(love.graphics.getBackgroundColor()) xpcall(App.draw, handle_error) love.graphics.present() love.timer.sleep(0.001) end end function handle_error(err) local callstack = debug.traceback('', --[[stack frame]]2) Error_message = 'Error: ' .. tostring(err)..'\n'..cleaned_up_callstack(callstack) print(Error_message) if Current_app == 'run' then Settings.current_app = 'source' love.filesystem.write('config', json.encode(Settings)) load_file_from_source_or_save_directory('main.lua') App.undo_initialize() App.run_tests_and_initialize() else -- abort without running love.quit handler Disable_all_quit_handlers = true love.event.quit() end end -- I tend to read code from files myself (say using love.filesystem calls) -- rather than offload that to load(). -- Functions compiled in this manner have ugly filenames of the form [string "filename"] -- This function cleans out this cruft from error callstacks. function cleaned_up_callstack(callstack) local frames = {} for frame in string.gmatch(callstack, '[^\n]+\n*') do local line = frame:gsub('^%s*(.-)\n?$', '%1') local filename, rest = line:match('([^:]*):(.*)') local core_filename = filename:match('^%[string "(.*)"%]$') -- pass through frames that don't match this format -- this includes the initial line "stack traceback:" local new_frame = (core_filename or filename)..':'..rest table.insert(frames, new_frame) end -- the initial "stack traceback:" line was unindented and remains so return table.concat(frames, '\n\t') end -- The rest of this file wraps around various LÖVE primitives to support -- automated tests. Often tests will run with a fake version of a primitive -- that redirects to the real love.* version once we're done with tests. -- -- Not everything is so wrapped yet. Sometimes you still have to use love.* -- primitives directly. App = {} function App.love_version() local major_version, minor_version = love.getVersion() local version = major_version..'.'..minor_version return version, major_version end -- save/restore various framework globals we care about -- only on very first load function App.snapshot_love() if Love_snapshot then return end Love_snapshot = {} -- save the entire initial font; it doesn't seem reliably recreated using newFont Love_snapshot.initial_font = love.graphics.getFont() end function App.undo_initialize() love.graphics.setFont(Love_snapshot.initial_font) end function App.run_tests_and_initialize() App.load() Test_errors = {} App.run_tests() if #Test_errors > 0 then local error_message = '' if Warning_before_tests then error_message = Warning_before_tests..'\n\n' end error_message = error_message .. ('There were %d test failures:\n%s'):format(#Test_errors, table.concat(Test_errors)) error(error_message) end App.disable_tests() App.initialize_globals() App.initialize(love.arg.parseGameArguments(arg), arg) end function App.run_tests() local sorted_names = {} for name,binding in pairs(_G) do if name:find('test_') == 1 then table.insert(sorted_names, name) end end table.sort(sorted_names) --? App.initialize_for_test() -- debug: run a single test at a time like these 2 lines --? test_click_below_all_lines() for _,name in ipairs(sorted_names) do App.initialize_for_test() --? print('=== '..name) --? _G[name]() xpcall(_G[name], function(err) prepend_debug_info_to_test_failure(name, err) end) end -- clean up all test methods for _,name in ipairs(sorted_names) do _G[name] = nil end end function App.initialize_for_test() App.screen.init{width=100, height=50} App.screen.co
# dwm - dynamic window manager
# © 2006-2007 Anselm R. Garbe, Sander van Dijk
include config.mk
SRC += dwm.c
OBJ = ${SRC:.c=.o}
all: options dwm
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk
config.h:
echo creating $@ from config.def.h
cp config.def.h $@
dwm: ${OBJ}
@echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
clean:
@echo cleaning
@rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean
@echo creating dist tarball
@mkdir -p dwm-${VERSION}
@cp -R LICENSE Makefile README config.def.h config.mk \
dwm.1 ${SRC} dwm-${VERSION}
@tar -cf dwm-${VERSION}.tar dwm-${VERSION}
@gzip dwm-${VERSION}.tar
@rm -rf dwm-${VERSION}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f dwm ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
@echo installing manual page to ${DESTDIR}${MANPREFIX