⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xref_utils.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 2 页
字号:
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 2000, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id $%%-module(xref_utils).-export([xset/2]).-export([is_directory/1, file_info/1, fa_to_mfa/2]).-export([is_string/2, is_path/1]).-export([module_filename/2, application_filename/1, application_filename/2]).-export([release_directory/3, select_application_directories/2, 	 filename_to_application/1, select_last_application_version/1,	 split_filename/2, scan_directory/4, list_path/2]).-export([predefined_functions/0, is_funfun/3, is_builtin/3]).-export([is_static_function/2]).-export([closure/1, components/1, condensation/1, path/2, use/2, call/2]).-export([regexpr/2]).-export([relation_to_graph/1]).-export([find_beam/1]).-export([options/2]).-export([subprocess/2]).-export([format_error/1]).-import(lists, [append/1, delete/2, filter/2, foldl/3, foreach/2, 		keydelete/3, keysearch/3, keysort/2, last/1, map/2, 		member/2, reverse/1, sort/1]).-import(sofs, 	[difference/2, domain/1, family/1,	 family_to_relation/1, from_external/2, from_term/2, 	 intersection/2, partition/2, relation/1, relation_to_family/1, 	 restriction/2, set/1, to_external/1, type/1]).-include_lib("kernel/include/file.hrl").%%%%  Exported functions%%xset(L, T) when is_list(L) ->    from_external(lists:usort(L), T);xset(S, T) ->    from_external(S, T).%% -> true | false | {error, ?MODULE, Reason}%is_directory(F) ->%    filelib:is_dir(F);is_directory(F) ->    case file:read_file_info(F) of	{ok, Info} -> 	    Info#file_info.type =:= directory;	{error, Error} -> 	    file_error(F, Error)    end.%% file_info(FileName) -> {ok, FileInfo} | {error, ?MODULE, Reason}%%   FileInfo = {FileName, DirOrFile, Readable, ModificationTime}%%   DirOrFile = directory | file%%   Readable = readable | unreadable%%   ModificationTime = {{Year, Month, Day}, {Hour, Minute, Second}}%%%% DirOrFile is equal to 'directory' ('file') if FileName is a%% directory (regular file).%% Readable is equal 'readable' ('unreadable') if FileName is readable%% (unreadable).%% ModificationTime is copied from file_info.mtime.%%file_info(F) ->    case file:read_file_info(F) of	{ok, Info} -> 	    Readable = case Info#file_info.access of			   Access when Access =:= read;                                        Access =:= read_write ->			       readable;			   _ ->			       unreadable		       end,	    Type = case Info#file_info.type of		       directory -> directory;		       regular -> file;		       _ -> error		   end,	    case Type of 		error -> error({unrecognized_file, F});		_ -> {ok, {F, Type, Readable, Info#file_info.mtime}}	    end;	{error, Error} -> 	    file_error(F, Error)    end.    fa_to_mfa(FAs, Mod) ->    fa_to_mfa(FAs, Mod, []).fa_to_mfa([{F,A} | MFs], Mod, L) ->    fa_to_mfa(MFs, Mod, [{Mod,F,A} | L]);fa_to_mfa([], _Mod, L) ->    reverse(L).module_filename(Dir, Module) ->    filename:join(Dir, to_list(Module) ++ code:objfile_extension()).application_filename(AppName) ->    to_list(AppName) ++ ".app".application_filename(Dir, AppName) ->    filename:join(to_list(Dir), application_filename(AppName)).%% -> bool()is_string([], _) ->    false;is_string(Term, C) ->    is_string1(Term, C).is_string1([H | T], C) when H > C, H < 127 ->     is_string1(T, C);is_string1([], _) ->     true;is_string1(_, _) ->     false.    %% -> bool()is_path([S | Ss]) ->    case is_string(S, 31) of	true -> 	    is_path(Ss);	false ->	    false    end;is_path([]) ->     true;is_path(_) ->     false.%====================================% Release and application functions.%====================================%%% ApplDir = {ApplicationName,NumericApplicationVersion,ApplicationDirectory}%%% ApplicationName = atom()%%% ApplicationDirectory = string()%%% NumericApplicationVersion = [integer()] ("3.1.7" becomes [3,1,7]).%%% [] means that the application has no version...%%%%%% ModuleName = ModuleFileName = string()%%% ReleaseName = atom()%% release_directory(Directory, CheckLib, SubDirectory) -> %%     {ok, ReleaseName, AppDir, [ApplDir]} | {error, ?MODULE, Reason}%%   CheckLib = bool()%%   AppDir = string()%%   SubDirectory = string()%%%% Returns all sub directories of a given directory, assuming all sub%% directories are application directories. If a sub directory has a%% sub directory SubDirectory, that one is chosen as application%% directory. If Directory has a sub directory 'lib' and CheckLib is%% equal to 'true', applications are looked for on that%% directory. ApplDir is the directory where applications reside. In%% any case, the returned ReleaseName is the basename of the given%% directory.%%release_directory(Dir, UseLib, SubDir) ->    SDir = subdir(Dir, "lib", UseLib),    case file:list_dir(SDir) of	{ok, FileNames} ->            Files = [filename:join(SDir, File) || File <- FileNames],	    case select_application_directories(Files, SubDir) of		{ok, ApplDirs} ->		    {ok, list_to_atom(filename:basename(Dir)), SDir, ApplDirs};		Error ->		    Error	    end;	{error, Error} ->	    file_error(SDir, Error)    end.%% select_application_directories([FileName], SubDirectory) -> %%               {ok, [ApplDir]} | {error, ?MODULE, Error}%%   SubDirectory = string()%%%% For each filename that is a directory, the filename is split into%% an application name and an application version, if possible, using%% '-' as separator. If not possible, the empty version - [] - is%% used. If a directory has a sub directory called SubDirectory, that%% one is returned as application directory rather than the directory%% itself.%%  select_application_directories(FileNames, Dir) ->    select_application_directories(FileNames, Dir, Dir =/= [], []).%% filename_to_application(FileName) -> %%          {ApplicationName,NumbericApplicationVersion}%%%% Interprets a filename as an application name and an application%% version. If the filename (the basename actually) cannot be split%% into two components using '-' as separator, the whole basename is%% used as application name, and the version returned is [].%%filename_to_application(FileName) ->    Basename = filename:basename(FileName),    case catch filename2appl(Basename) of	{'EXIT',_} ->	    {list_to_atom(Basename),[]};	Split ->	    Split    end.    %% select_last_application_version([ApplDir]) -> [ApplDir]%%%% For each application that occurs with more than one version in the%% input list, only the one with the last version is kept.%%select_last_application_version(AppVs) ->    TL = to_external(partition(1, relation(AppVs))),    [last(keysort(2, L)) || L <- TL].%% scan_directory(Directory, Recurse, Collect, Watch) -> %%     {Collected, Errors, Seen, Unreadable}%%%%   Watch = Collect = [string()]%%   Directory = string() | atom()%%   Recurse = bool()%%   Collected = [{Dir,Basename}]%%   Dir = Basename = Seen = Unreadable = [string()]%% %% Collected (Seen) contains those regular files with extension%% occurring in Collect (Watch). Watch is tried only if a filename%% does not match Collect. Only readable files occur in Collected, the%% unreadable files (with extension matching Collect) go into%% Unreadable.%%scan_directory(File, Recurse, Collect, Watch) ->    Init = [[] | {[],[],[]}],    [L | {E,J,U}] = find_files_dir(File, Recurse, Collect, Watch, Init),    {reverse(L), reverse(E), reverse(J), reverse(U)}.%% {Dir, Basename} | falsesplit_filename(File, Extension) ->    case catch begin 		   Dir = filename:dirname(File),		   Basename = filename:basename(File, Extension),		   {Dir, Basename++Extension}	       end of	{'EXIT', _} ->	    false;	R ->	    R    end.%% list_path(Path, Extensions) -> %%    {[{Module, {integer(), Directory, Basename}}], [error()]}%%%%    Path = [Directory]%%    Extensions = [string()]%%    Module = atom()%%    Directory = Basename = string()%%%% Files with any of the given extensions are searched for among%% the given directories (Path). Directories "below" some of the given%% directories are not searched (unless enumerated in Path). If some%% file is found on more than one directory, the first one found is%% returned (Path is searched from the beginning).%%list_path(P, Extensions) ->    list_dirs(P, 1, Extensions, [], []).list_dirs([D | Ds], I, Exts, CL, E) ->    Fun = fun(X, A) -> 		  File = filename:join(D, X),		  case is_directory(File) of		      false ->			  Ext = filename:extension(X),			  case member(Ext, Exts) of			      true ->				  M = list_to_atom(filename:basename(X, Ext)),				  [{M, {I,D,X}} | A];			      false ->				  A			  end;		      true ->			  A;		      _Else ->			  A		  end	   end,    {NCL, NE} = case file:list_dir(D) of		    {ok, C0} ->			{foldl(Fun, CL, C0), E};		    {error, Error} ->			{CL, [file_error(D, Error) | E]}		end,    list_dirs(Ds, I+1, Exts, NCL, NE);list_dirs([], _I, _Exts, C, E) ->     {C, E}.%% Returns functions that are present in all modules.predefined_functions() ->    [{module_info,0}, {module_info,1}].%% Returns true if an MFA takes functional arguments.is_funfun(erlang, apply, 2) -> true;is_funfun(erlang, apply, 3) -> true;is_funfun(erlang, spawn, 1) -> true;is_funfun(erlang, spawn, 2) -> true;is_funfun(erlang, spawn, 3) -> true;is_funfun(erlang, spawn, 4) -> true;is_funfun(erlang, spawn_link, 1) -> true;is_funfun(erlang, spawn_link, 2) -> true;is_funfun(erlang, spawn_link, 3) -> true;is_funfun(erlang, spawn_link, 4) -> true;is_funfun(erlang, spawn_opt, 2) -> true;is_funfun(erlang, spawn_opt, 3) -> true;is_funfun(erlang, spawn_opt, 4) -> true;is_funfun(erlang, spawn_opt, 5) -> true;is_funfun(erts_debug, apply, 4) -> true;is_funfun(_, _, _) -> false.is_builtin(erts_debug, apply, 4) -> true;is_builtin(M, F, A) ->    erlang:is_builtin(M, F, A).%% A "static function" is a function in an abstract module that may be%% called directly.is_static_function(module_info, 0) ->    true;is_static_function(module_info, 1) ->    true;is_static_function(new, _) ->    true;is_static_function(_F, _A) ->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -