<commit_before>%%%----------------------------------------------------------------------
%%% Copyright (c) 2011, <NAME> <<EMAIL>>,
%%%                     <NAME> <<EMAIL>>
%%%                 and <NAME> <<EMAIL>>.
%%% All rights reserved.
%%%
%%% This file is distributed under the Simplified BSD License.
%%% Details can be found in the LICENSE file.
%%%----------------------------------------------------------------------
%%% Authors     : <NAME> <<EMAIL>>
%%%               <NAME> <<EMAIL>>
%%% Description : Instrumenter
%%%----------------------------------------------------------------------

-module(concuerror_instr).
-export([delete_and_purge/1, instrument_and_compile/2, load/1,
         new_module_name/1, check_module_name/3, old_module_name/1,
         delete_temp_files/1]).

-export_type([macros/0]).

-include("gen.hrl").
-include("instr.hrl").

%%%----------------------------------------------------------------------
%%% Debug
%%%----------------------------------------------------------------------

%%-define(PRINT, true).
-ifdef(PRINT).
-define(print(S_), io:put_chars(erl_prettypr:format(S_))).
-else.
-define(print(S_), ok).
-endif.

%%%----------------------------------------------------------------------
%%% Types
%%%----------------------------------------------------------------------

-type mfb() :: {module(), file:filename(), binary()}.

-type macros() :: [{atom(), term()}].

%%%----------------------------------------------------------------------
%%% Instrumentation utilities
%%%----------------------------------------------------------------------

%% ---------------------------
%% Delete and purge all modules.
-spec delete_and_purge(concuerror:options()) -> 'ok'.
delete_and_purge(_Options) ->
    %% Unload and purge modules.
    ModsToPurge =
        [check_module_name(IM, none, 0) || {IM}<-ets:tab2list(?NT_INSTR_MODS)],
    Fun = fun (M) -> code:purge(M), code:delete(M) end,
    lists:foreach(Fun, ModsToPurge),
    %% Delete ?NT_INSTR_MODS, ?NT_INSTR_BIFS,
    %% ?NT_INSTR_IGNORED and ?NT_INSTR tables.
    ets:delete(?NT_INSTR_MODS),
    ets:delete(?NT_INSTR_BIFS),
    ets:delete(?NT_INSTR_IGNORED),
    ets:delete(?NT_INSTR),
    ok.

%% ---------------------------
%% Rename a module for the instrumentation.
%% 1. Don't rename `concuerror_*' modules
%% 2. Don't rename `ignored' modules
%% 3. Don't rename `BIFS'.
%% 4. If module is instrumented rename it.
%% 5. If we are in `fail_uninstrumented' mode rename all modules.
-spec check_module_name(module() | {module(),term()}, atom(), non_neg_integer())
                        -> module() | {module(), term()}.
check_module_name({Module, Term}, Function, Arity) ->
    {check_module_name(Module, Function, Arity), Term};
check_module_name(Module, Function, Arity) ->
    Conc_Module =
        case atom_to_list(Module) of
            ("concuerror_" ++ _Rest) -> true;
            _Other -> false
        end,
    Rename = (not Conc_Module)
        andalso (not ets:member(?NT_INSTR_IGNORED, Module))
        andalso (not ets:member(?NT_INSTR_BIFS, {Module, Function, Arity}))
        andalso (ets:member(?NT_INSTR_MODS, Module)
            orelse ets:lookup_element(?NT_INSTR, ?FAIL_BB, 2)),
    case Rename of
        true  -> new_module_name(Module);
        false -> Module
    end.

-spec new_module_name(atom() | string()) -> atom().
new_module_name(StrModule) when is_list(StrModule) ->
    %% Check that module is not already renamed.<commit_msg>In `check_module_name' catch exceptions from `atom_to_list'<commit_after>%%%----------------------------------------------------------------------
%%% Copyright (c) 2011, <NAME> <<EMAIL>>,
%%%                     <NAME> <<EMAIL>>
%%%                 and <NAME> <<EMAIL>>.
%%% All rights reserved.
%%%
%%% This file is distributed under the Simplified BSD License.
%%% Details can be found in the LICENSE file.
%%%----------------------------------------------------------------------
%%% Authors     : <NAME> <<EMAIL>>
%%%               <NAME> <<EMAIL>>
%%% Description : Instrumenter
%%%----------------------------------------------------------------------

-module(concuerror_instr).
-export([delete_and_purge/1, instrument_and_compile/2, load/1,
         new_module_name/1, check_module_name/3, old_module_name/1,
         delete_temp_files/1]).

-export_type([macros/0]).

-include("gen.hrl").
-include("instr.hrl").

%%%----------------------------------------------------------------------
%%% Debug
%%%----------------------------------------------------------------------

%%-define(PRINT, true).
-ifdef(PRINT).
-define(print(S_), io:put_chars(erl_prettypr:format(S_))).
-else.
-define(print(S_), ok).
-endif.

%%%----------------------------------------------------------------------
%%% Types
%%%----------------------------------------------------------------------

-type mfb() :: {module(), file:filename(), binary()}.

-type macros() :: [{atom(), term()}].

%%%----------------------------------------------------------------------
%%% Instrumentation utilities
%%%----------------------------------------------------------------------

%% ---------------------------
%% Delete and purge all modules.
-spec delete_and_purge(concuerror:options()) -> 'ok'.
delete_and_purge(_Options) ->
    %% Unload and purge modules.
    ModsToPurge =
        [check_module_name(IM, none, 0) || {IM}<-ets:tab2list(?NT_INSTR_MODS)],
    Fun = fun (M) -> code:purge(M), code:delete(M) end,
    lists:foreach(Fun, ModsToPurge),
    %% Delete ?NT_INSTR_MODS, ?NT_INSTR_BIFS,
    %% ?NT_INSTR_IGNORED and ?NT_INSTR tables.
    ets:delete(?NT_INSTR_MODS),
    ets:delete(?NT_INSTR_BIFS),
    ets:delete(?NT_INSTR_IGNORED),
    ets:delete(?NT_INSTR),
    ok.

%% ---------------------------
%% Rename a module for the instrumentation.
%% 1. Don't rename `concuerror_*' modules
%% 2. Don't rename `ignored' modules
%% 3. Don't rename `BIFS'.
%% 4. If module is instrumented rename it.
%% 5. If we are in `fail_uninstrumented' mode rename all modules.
-spec check_module_name(module() | {module(),term()}, atom(), non_neg_integer())
                        -> module() | {module(), term()}.
check_module_name({Module, Term}, Function, Arity) ->
    {check_module_name(Module, Function, Arity), Term};
check_module_name(Module, Function, Arity) ->
    Conc_Module =
        try atom_to_list(Module) of
            ("concuerror_" ++ _Rest) -> true;
            _Other -> false
        catch   %% In case atom_to_list fail, we don't want to rename the module
            error:badarg -> true
        end,
    Rename = (not Conc_Module)
        andalso (not ets:member(?NT_INSTR_IGNORED, Module))
        andalso (not ets:member(?NT_INSTR_BIFS, {Module, Function, Arity}))
        andalso (ets:member(?NT_INSTR_MODS, Module)
            orelse ets:lookup_element(?NT_INSTR, ?FAIL_BB, 2)),
    case Rename of
        true  -> new_module_name(Module);
        false -> Module
    end.

-spec new_module_name(atom() | string()) -> atom().
new_module_name(StrModule) when is_list(StrModule) ->
    %% Check that module is not already renamed.
{'fraction_non_alphanumeric': 0.3305120609394837, 'fraction_numerical': 0.005642544787699252, 'mean_word_length': 1.656425627575871, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '206029', 'n_tokens_mistral': 2144, 'n_tokens_neox': 2016, 'n_words': 452}