diff --git a/examples/instrumented/src/ b/examples/instrumented/src/ new file mode 100644 index 0000000..f5e8d3f --- /dev/null +++ b/examples/instrumented/src/ @@ -0,0 +1,69 @@ +%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% ex: ts=4 sw=4 et +%% ---------------------------------------------------------------------------- +%% +%% Copyright (c) 2008-2011 Tim Watson (watson.timothy@gmail.com) +%% +%% Permission is hereby granted, free of charge, to any person obtaining a copy +%% of this software and associated documentation files (the "Software"), deal +%% in the Software without restriction, including without limitation the rights +%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%% copies of the Software, and to permit persons to whom the Software is +%% furnished to do so, subject to the following conditions: +%% +%% The above copyright notice and this permission notice shall be included in +%% all copies or substantial portions of the Software. +%% +%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +%% IN THE SOFTWARE. +%% ---------------------------------------------------------------------------- +-module(instrumented). + +-compile(export_all). + +%% this function is called by the instrumented block +if_prefix(Events, Prefix) -> + lists:prefix(Prefix, atom_to_list(hd(Events))). + +handle_events(Events) -> + %% @instrumented [cond_throw_signal 'sig.continue' + %% [eval_p instrumented if_prefix ["node1@"]]] + {received, Events}. + +test() -> + SUT = spawn_test(), + SUT ! {events, ['a@foo', 'b@bar', 'c@baz']}, + annotations:instrument(?MODULE), + %% these should slip past the cond_wait and not hit the throw + SUT ! {events, [{a, 1}, {b, 1}, {c, 1}]}, + %% but these will not... + SUT ! {events, ['node1@foobarbaz', 'node2@bonkers']}, + true = erlang:is_process_alive(SUT), + SUT ! {stop, self()}, + receive + {stopped, Captured} -> + io:format("~p~n", [Captured]); + Other -> + throw(Other) + end, + ok. + +spawn_test() -> + spawn(fun() -> + process_flag(trap_exit, true), + loop([]) + end). + +loop(Acc) -> + receive + {events, Events} -> + [catch(handle_events(Events))|Acc]; + {stop, Sender} -> + Sender ! {stopped, Acc} + end. + diff --git a/examples/instrumented/src/instrumented.app.src b/examples/instrumented/src/instrumented.app.src new file mode 100644 index 0000000..4a86616 --- /dev/null +++ b/examples/instrumented/src/instrumented.app.src @@ -0,0 +1,12 @@ +{application, instrumented, + [ + {description, ""}, + {vsn, "1"}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {mod, { instrumented_app, []}}, + {env, []} + ]}. diff --git a/examples/instrumented/src/instrumented_sup.erl b/examples/instrumented/src/instrumented_sup.erl new file mode 100644 index 0000000..bf93220 --- /dev/null +++ b/examples/instrumented/src/instrumented_sup.erl @@ -0,0 +1,28 @@ + +-module(instrumented_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +%% Helper macro for declaring children of supervisor +-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}). + +%% =================================================================== +%% API functions +%% =================================================================== + +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +%% =================================================================== +%% Supervisor callbacks +%% =================================================================== + +init([]) -> + {ok, { {one_for_one, 5, 10}, []} }. + diff --git a/src/annotations_inst_pt.erl b/src/annotations_inst_pt.erl new file mode 100644 index 0000000..ab75764 --- /dev/null +++ b/src/annotations_inst_pt.erl @@ -0,0 +1,54 @@ +%% -*- tab-width: 4;erlang-indent-level: 4;indent-tabs-mode: nil -*- +%% ex: ts=4 sw=4 et +%% ---------------------------------------------------------------------------- +%% +%% Copyright (c) 2008-2011 Tim Watson (watson.timothy@gmail.com) +%% +%% Permission is hereby granted, free of charge, to any person obtaining a copy +%% of this software and associated documentation files (the "Software"), deal +%% in the Software without restriction, including without limitation the rights +%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%% copies of the Software, and to permit persons to whom the Software is +%% furnished to do so, subject to the following conditions: +%% +%% The above copyright notice and this permission notice shall be included in +%% all copies or substantial portions of the Software. +%% +%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +%% IN THE SOFTWARE. +%% ---------------------------------------------------------------------------- +-module(annotations_inst_pt). +-export([parse_transform/2]). + +-include("types.hrl"). + +parse_transform(Forms, Options) -> + parse_trans:top(fun do_transform/2, Forms, Options). + +do_transform(Forms, Context) -> + File = get_file_loc(Forms), + io:format(user, "File = ~p~n", [File]), + {ok, Bin} = file:read_file(File), + Comments = erl_comment_scan:string(binary_to_list(Bin)), + io:format(user, "comments = ~p~n", [Comments]), + Forms2 = erl_recomment:recomment_forms(Forms, Comments), + {Forms3, _Acc2} = + parse_trans:do_transform(fun xform_fun/4, [], + [Forms2], Context), + parse_trans:revert(Forms3). + +% xform_fun(application, Form, Ctx, Conf) -> +xform_fun(_Thing, Form, _Ctx, Conf) -> + io:format("Form: ~p~n", [Form]), + {[], Form, [], true, Conf}. + +get_file_loc(Forms) -> + Mod = element(4, lists:keyfind(module, 3, Forms)), + proplists:get_value(source, + proplists:get_value(compile, Mod:module_info())). +