scite_require 'debugger.lua' scite_MessageTbl { 'get_debug_output $(MessageLparam)|58|.*', } scite_Command { 'Debug a currently running script...|Debug_Attach_script|Ctrl+Shift+F7', } local ATM_OFFSET = 0x1000 local ATM_GETSTATUS = ATM_OFFSET+6 local ATM_AHKDBG = ATM_OFFSET+7 local ATM_AHKSTR = ATM_OFFSET+8 local savedbk = nil local function ahk_dbg_command( cmd, mode, typ ) mode = mode or 0 typ = typ or 0 local toolbar = scite_GetPropNumber('DirectorHwnd', 0) local ahk_debuger = scite_GetPropNumber('ahk_gdb', 0) if ahk_debuger > 0 then SendMessageStr(ahk_debuger, ATM_AHKDBG, mode, cmd) --[[ if typ > 0 then if typ == 1 then SendMessageStr(toolbar, ATM_AHKSTR, 0, cmd) elseif typ == 2 then PostMessage(toolbar, ATM_AHKDBG, ahk_debuger, mode) end else SendMessageStr(ahk_debuger, ATM_AHKDBG, mode, cmd) --PostMessage(toolbar, ATM_AHKDBG, ahk_debuger, mode) end ]]-- else print('ahk debug err:toolbar=['.. toolbar ..'] ahk_debuger=['.. ahk_debuger ..'] cmd=[' .. cmd ..']') end --print ( 'test command : ' cmd .. '\n' ) end local find = string.find local sub = string.sub local gsub = string.gsub local GTK = scite_GetProp('PLAT_GTK') local p_pattern = '^= ' local function print_process(s, dbg) s = s:sub(3) display(dbg.last_arg..' = '..s) --dbg.last_command = nil end -- special actions for commands which require postprocessing local postprocess_command = { eval = {pattern = p_pattern, action = print_process, single_pattern = true}, } AhkGdb = class(Dbg) -- AhkGdb is now only used for _remote connections_ if Clidebug is also registered! function AhkGdb.discriminator(target) return find(target, ':') == 1 end function AhkGdb:init(root) local dir = scite_GetProp('debug.path.local') if dir then dir = dir:gsub('\\', '/') if not find(dir, "/$")then dir = dir .. "/" end local _, _, res, path = find(dir, '^([^%.\\/]+)(:.*)$') self.local_dir = res:upper()..path print('local_dir:'..self.local_dir) else self.local_dir = nil end dir = scite_GetProp('debug.path.remote') if dir then dir = dir:gsub('\\', '/') if not find(dir, "/$")then dir = dir .. "/" end _, _, res, path = find(dir, '^([^%.\\/]+)(:.*)$') self.remote_dir = res:upper()..path print('remote_dir:'..self.remote_dir) else self.remote_dir = nil end self.type = 1 self.prompt = 'DBG>' self.no_target_ext = false self.cmd_file = root..'/dbg.cmd' self.detect_start = '^%*+ Listening on port %d+ and Addr [%d%.]+ for a debugger connection%.' -- find out where the Lua executable is; you can use the debug.lua property if it isn't the same -- as your lua executable specified in lua.properties. self.lua = scite_GetProp("debug.lua") if not self.lua then self.lua = scite_GetProp('command.go.*.lua'):match('^(%w+)') end -- this is added to the package.path of the Lua program self.remdebug_path = scite_GetProp('AhkGdb.path', extman_Path()..'/AhkGdb') self.no_quit_confirm = true local drive = ''; if not GTK then drive = '[a-zA-Z]:' end self.break_line = '^Paused at file ('..drive..'/[^%s].+[^%s])%s+line%s(%d+)' self.silent_command = {} self.postprocess_command = postprocess_command end local function backslash(path) return path:gsub('\\', '/') end local ahk_dbg_first = 0 local function ahk_dbg_int( mode ) if savedbk then local cmds = '' for i, cmd in ipairs(savedbk) do cmds = cmds .. '\n' .. cmd end cmds = cmds .. '\n' --.. 'run' ahk_dbg_command(cmds , mode ) savedbk = nil else --ahk_dbg_command( 'step_into',1 ) ahk_dbg_command('' , mode ) end end function get_debug_output(addr_msg) local msg = GetMessage(addr_msg) local _, pos, ahk_gdb_hwd = string.find(msg, "^:(%d+):") props['ahk_gdb']=ahk_gdb_hwd local line = msg:sub( pos+1 ) --print('ahkgdb.lua debug_msg:'.. line ) if ahk_dbg_first < 2 then if ahk_dbg_first == 0 then ProcessOutput( line ) local _, _, command, file= string.find(line, "^%S+%s+(Debugging)%s+(.%:.*%S)%n") if command == "Debugging" then scite.Open(file) set_status('active') if AhkGdb.bIsAttach then ahk_dbg_first = 1 ahk_dbg_command( 'breakpoint_list' ) else set_status('running') ahk_dbg_int(3) ahk_dbg_first = 2 end end elseif ahk_dbg_first == 1 then for s in line:gmatch("[^\n]+") do local _, _, file, num= string.find(s, "^%S+%s+(%S.+%S)%s+(%d+)") if file and file ~= 'have' then num = tonumber(num) local brk = breakpoint_from_position(num, file ) if not brk then SetBreakMarker(tonumber(num),file) end end end ahk_dbg_int(2) ahk_dbg_first = 2 end else ProcessOutput( line ) end SendMessage(ahk_gdb_hwd, ATM_GETSTATUS, 5, 0) end function Debug_Attach_script( ) AhkGdb.bIsAttach = true do_run() end local function ahkgdb_command(cmd ,word, mode ) AhkGdb.last_command = cmd AhkGdb.last_arg = word if word then cmd = cmd .. word end print('>' .. cmd ) ahk_dbg_command( cmd, mode ) end function AhkGdb:handle_debug_start() if not self.target:find('^:remote') and not self.bIsAttach and 'ahk' == string.lower(props['FileExt']) then local ahkdir = scite_GetProp('AutoHotkeyDir'):gsub('\\', '/') local addr = scite_GetProp('debug.Addr') local port = scite_GetProp('debug.Port') local file = scite_CurrentFile() ahkgdb_command('start_dbg', ' "' .. ahkdir .. '/AutoHotkey.exe" /Debug=' .. addr ..':' .. port .. ' "' .. file .. '"', 1) end end -- '%s -e "package.path=%s" -l AhkGdb %s' local GTK = scite_GetProp('PLAT_GTK') function AhkGdb:command_line(target) ahk_dbg_first = 0 self.target = target local LocalAHK = scite_GetProp('LocalAHK') local addr = scite_GetProp('debug.Addr') local port = scite_GetProp('debug.Port') local debug_console = scite_GetProp('SciteDefaultHome') .. '/ahk/scite_ahk/tools/dbgp_console.ahk' local rpath = self.remdebug_path -- /Debug=localhost:9002 /Debug=localhost:9001 local cmd = LocalAHK .. ' ' .. debug_console .. ' ' .. scite_GetPropNumber('scitehwnd', 0) .. ' ' .. scite_GetPropNumber('WindowID', 0) .. ' ' .. scite_GetPropNumber('DirectorHwnd', 0) .. ' ' .. addr .. ' ' .. port --.. ' && exit' -- ..self.cmd_file ..' /Debug=localhost:' .. port if self.bIsAttach then cmd = cmd .. ' /attach' end --bIsAttach = false --print(cmd) return cmd end local breakpoint_exit = false function AhkGdb:dump_breakpoints(out) breakpoint_exit = false local tbl={} local i=1 for b in Breakpoints()do local file = b.file:gsub('\\', '/') if self.local_dir and self.local_dir ~= "" and self.remote_dir and self.remote_dir ~= "" then local file_tmp = file file = gsub(file_tmp, self.local_dir, self.remote_dir) scite_debug('set_breakpoint(local to remote):'..file_tmp..'->'..file..' ('..b.line..')') end tbl[i] = 'breakpoint_set -t line -n '.. b.line .. ' -f ' .. file i=i+1 breakpoint_exit = true end if breakpoint_exit then savedbk = tbl end end function AhkGdb:run_program(out, parms) --ahk_dbg_int( ) end function AhkGdb:command(cmd) ahkgdb_command(cmd) end function AhkGdb:step() ahkgdb_command('step_into') --ahk_dbg_command('step_into') end function AhkGdb:step_over() ahkgdb_command('step_over') --ahk_dbg_command('step_over') end function AhkGdb:finish() ahkgdb_command('step_out') end function AhkGdb:continue() ahkgdb_command('run') --ahk_dbg_command('run') end function AhkGdb:quit() ahkgdb_command('stop') --ahk_dbg_command('stop') end function AhkGdb:inspect(word) self.last_command = 'eval' self.last_arg = word ahk_dbg_command('property_get -m 200 -n '..word) end function AhkGdb:set_breakpoint(file, lno) local FileDir = props['FileDir']:gsub('\\', '/') if not find(FileDir, "/$")then FileDir = FileDir .. "/" end if self.local_dir and self.local_dir ~= "" and self.remote_dir and self.remote_dir ~= "" then local file_tmp = FileDir FileDir = gsub(file_tmp, self.local_dir, self.remote_dir) scite_debug('set_breakpoint(local to remote):'..file_tmp..file..'->'..FileDir..file..' ('..lno..')') end ahk_dbg_command('breakpoint_set -t line -n ' .. lno .. ' -f ' .. FileDir..file) print('>' .. 'breakpoint_set -t line -n ' .. lno .. ' -f ' .. FileDir..file ) self.last_command = 'breakpoint_set' end function AhkGdb:clear_breakpoint(file, line, num) if file then -- this function will only pass us the filename part, not the path! local FileDir = props['FileDir']:gsub('\\', '/') if not find(FileDir, "/$")then FileDir = FileDir .. "/" end if self.local_dir and self.local_dir ~= "" and self.remote_dir and self.remote_dir ~= "" then local file_tmp = FileDir FileDir = gsub(file_tmp, self.local_dir, self.remote_dir) scite_debug('clear_breakpoint(local to remote):'..file_tmp..file..'->'..FileDir..file..' ('..line..')') end ahk_dbg_command('breakpoint_remove ' .. FileDir ..file..' '..line) print('>' .. 'breakpoint_remove ' .. FileDir ..file..' '..line ) self.last_command = 'breakpoint_remove' else print('no breakpoint at '..file..':'..line) end end function AhkGdb:backtrace(count) end function AhkGdb:locals() ahk_dbg_command('locals') end function AhkGdb:detect_program_end(line) return find(line, '^%*+%s+Stopped%s+debugging.') end register_debugger('ahkgdb', 'ahk', AhkGdb)