package org.erlide.backend.debug.events; import org.erlide.util.ErlLogger; import org.erlide.util.erlang.OtpBindings; import org.erlide.util.erlang.OtpErlang; import org.erlide.util.erlang.OtpParserException; import com.ericsson.otp.erlang.OtpErlangAtom; import com.ericsson.otp.erlang.OtpErlangException; import com.ericsson.otp.erlang.OtpErlangList; import com.ericsson.otp.erlang.OtpErlangObject; import com.ericsson.otp.erlang.OtpErlangPid; public class DebuggerEventFactory { public static DebuggerEvent parse(final OtpErlangObject message) { // TODO More events from dbg_mon... try { OtpBindings b = OtpErlang.match("{started, Pid:p}", message); if (b != null) { return buildStartedEvent(b); } b = OtpErlang.match("{terminated, Pid:p}", message); if (b != null) { return buildTerminatedEvent(b); } b = OtpErlang.match("{int, Cmd}", message); if (b != null) { return buildIntEvent(b); } b = OtpErlang.match("{attached, Pid:p}", message); if (b != null) { return buildAttachedEvent(b); } b = OtpErlang.match("{Other:a, Cmd}", message); if (b != null) { return buildUnknownEvent(message); } b = OtpErlang.match("{Meta:p, Event}", message); if (b != null) { return buildMetaEvent(b); } } catch (final OtpParserException e) { ErlLogger.error(e); } catch (final OtpErlangException e) { ErlLogger.error(e); } return new UnknownEvent(message); } private static DebuggerEvent buildMetaEvent(final OtpBindings b) throws OtpErlangException { return parseMeta(b.getPid("Meta"), b.get("Event")); } private static MetaEvent parseMeta(final OtpErlangPid pid, final OtpErlangObject event) { try { OtpBindings b = OtpErlang.match("{break_at, Mod:a, Line:i, Crt}", event); if (b != null) { return new BreakAtEvent(pid, b.getAtom("Mod"), b.getInt("Line"), b.get("Crt")); } b = OtpErlang.match("{exit_at, Pos, Reason, Le, OrigPid:p}", event); if (b != null) { return new ExitAtEvent(pid, b.get("Pos"), b.get("Reason"), b.get("Le"), b.getPid("OrigPid")); } b = OtpErlang.match("{exit_at, Pos, Reason, Le, OrigPid:p, Stack:l, Binds:l}", event); if (b != null) { return new ExitAtEvent(pid, b.get("Pos"), b.get("Reason"), b.get("Le"), b.getPid("OrigPid"), (OtpErlangList) b.get("Stack"), (OtpErlangList) b.get("Binds")); } b = OtpErlang.match("{wait_at, Mod:a, Line:i, Crt}", event); if (b != null) { return new WaitAtEvent(pid, b.getAtom("Mod"), b.getInt("Line"), b.get("Crt")); } } catch (final Exception e) { } // this is a default event that does nothing return new MetaEvent(pid, event); } private static DebuggerEvent buildUnknownEvent(final OtpErlangObject message) { return new UnknownEvent(message); } private static DebuggerEvent buildAttachedEvent(final OtpBindings b) throws OtpErlangException { return new AttachedEvent(b.getPid("Pid")); } private static DebuggerEvent buildIntEvent(final OtpBindings b) { try { final OtpErlangObject[] cmds = b.getTuple("Cmd"); final String cmd = ((OtpErlangAtom) cmds[0]).atomValue(); if (cmd.equals("new_break")) { return new NewBreakEvent(cmds); } else if (cmd.equals("new_status")) { return new NewStatusEvent(cmds); } else if (cmd.equals("new_process")) { return new NewProcessEvent(cmds); } else if (cmd.equals("interpret")) { return new InterpretEvent(cmds); } else if (cmd.equals("no_interpret")) { return new NoInterpretEvent(cmds); } else { return new IntEvent(cmds); } } catch (final Exception e) { return new IntEvent(new OtpErlangObject[] { new OtpErlangAtom("nop") }); } } private static DebuggerEvent buildTerminatedEvent(final OtpBindings b) throws OtpErlangException { return new TerminatedEvent(b.getPid("Pid")); } private static DebuggerEvent buildStartedEvent(final OtpBindings b) throws OtpErlangException { return new StartedEvent(b.getPid("Pid")); } }