📄 cover_web.erl
字号:
"<P>Select or enter node names to add or remove here.\n", "</TD></TR>\n", "<TR><TD COLSPAN=2><BR><BR></TD></TR>\n", "<FORM ACTION=\"./add_node\" NAME=add_node>\n", "<TR><TD VALIGN=top>Add node:</TD>\n", "<TD><INPUT TYPE=text NAME=\"node\" SIZE=40 >", "<INPUT TYPE=submit\n", " onClick=\"if(!node.value){node.value=selected_node.value};\" VALUE=Add>" "<BR><SELECT NAME=selected_node TITLE=\"Select node\">\n", AllNodes ++ "</SELECT>\n", "</TD></TR>\n" "</FORM>\n", "<TR><TD COLSPAN=2><BR><BR></TD></TR>\n", "<FORM ACTION=\"./remove_node\" NAME=remove_node>\n", "<TR><TD>Remove node:</TD>\n", "<TD><SELECT NAME=node TITLE=\"Select node\">\n", CoverNodes ++ "</SELECT>\n", "<INPUT TYPE=submit VALUE=Remove>" "</TD></TR>\n", "</FORM>", "</TABLE>"]. do_add_node(Input) -> NodeStr = get_input_data(Input, "node"), Node = list_to_atom(NodeStr), case net_adm:ping(Node) of pong -> cover:start(Node), nodes_frame1(); pang -> nodes_frame1("Node \\\'" ++ NodeStr ++ "\\\' is not alive") end.do_remove_node(Input) -> Node = list_to_atom(get_input_data(Input, "node")), cover:stop(Node), nodes_frame1().%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% The functions that is used when the user wants to compile something %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%compile_body(Dir,Err) -> Erls = filelib:wildcard(filename:join(Dir,"*.erl")), Beams = filelib:wildcard(filename:join(Dir,"*.beam")), [reload_menu_script(Err), "<H1 ALIGN=center>Compile</H1>\n", "<TABLE WIDTH=600 ALIGN=center BORDER=0>\n", "<TR><TD COLSPAN=3 BGCOLOR=",?INFO_BG_COLOR,">\n", "Each module which shall be part of the cover analysis must be prepared\n", "or 'cover compiled'. On this page you can select .erl files and/or\n", ".beam files to include in the analysis. If you select a .erl file it\n", "will first be compiled with the Erlang compiler and then prepared for\n", "coverage analysis. If you select a .beam file it will be prepared for\n", "coverage analysis directly.\n", "</TD></TR>\n", "<FORM ACTION=\"./list_dir\" NAME=list_dir>\n", "<TR><TD WIDTH=30% BGCOLOR=",?INFO_BG_COLOR," ROWSPAN=2>\n", "To list a different directory, enter the directory name here.\n", "</TD>\n", "<TH COLSPAN=2><BR>List directory:<BR></TH>\n", "</TR>\n", "<TR><TD ALIGN=center COLSPAN=2>\n", "<INPUT TYPE=text NAME=\"path\" SIZE=40 VALUE=",Dir,">", "<INPUT TYPE=submit VALUE=Ok>", "<BR><BR></TD></TR>\n", "</FORM>\n", "<FORM ACTION=\"./compile\" NAME=compile_selection>\n", "<TR><TD BGCOLOR=",?INFO_BG_COLOR," ROWSPAN=2>\n", "<P>Select one or more .erl or .beam files to prepare for coverage\n" "analysis, and click the \"Compile\" button.\n", "<P>To reload the original file after coverage analysis is complete,\n" "select one or more files and click the \"Uncompile\" button, or\n", "simply click the \"Uncompile all\" button to reload all originals.\n" "</TD>\n", "<TH>.erl files</TH><TH>.beam files</TH></TR>\n", "<TR><TD ALIGN=center VALIGN=top>\n", "<SELECT NAME=erl TITLE=\"Select .erl files to compile\" MULTIPLE=true", " SIZE=15>\n", list_modules(Erls) ++ "</SELECT></TD>\n", "<TD ALIGN=center VALIGN=top>\n", "<SELECT NAME=beam TITLE=\"Select .beam files to compile\"MULTIPLE=true", " SIZE=15>\n", list_modules(Beams) ++ "</SELECT></TD></TR>\n" "<TR><TD BGCOLOR=",?INFO_BG_COLOR," ROWSPAN=2>\n", "Compile options are only needed for .erl files. The options must be\n" "given e.g. like this: \n" "<FONT SIZE=-1>[{i,\"/my/path/include\"},{i,\"/other/path/\"}]</FONT>\n" "</TD>\n", "<TH COLSPAN=2><BR>Compile options:<BR></TH>\n", "</TR>\n", "<TR><TD COLSPAN=2 ALIGN=center>\n", "<INPUT TYPE=text NAME=\"options\" SIZE=40>\n", "<INPUT TYPE=hidden NAME=\"action\"></TD></TR>\n", "<TR><TD></TD><TD ALIGN=center COLSPAN=2>\n", "<INPUT TYPE=submit onClick=\"action.value=\'compile\';\"VALUE=Compile>", "<INPUT TYPE=submit onClick=\"action.value=\'uncompile\';\" ", "VALUE=Uncompile>", "<INPUT TYPE=submit onClick=\"action.value=\'uncompile_all\';\" ", "VALUE=\"Uncompile all\">", "<BR><INPUT TYPE=reset VALUE=\"Reset form\"></TD></TR>\n", "</FORM>\n", "</TABLE>\n"].list_modules([File|Files]) -> Mod = filename:basename(File), ["<OPTION VALUE=",File," onDblClick=\"action.value=\'compile\';submit();\">", Mod,"</OPTION>\n" | list_modules(Files)];list_modules([]) -> [].do_compile(Input,Dir) -> {Erls,Beams,Opts,Action} = get_compile_input(parse(Input),[],[]), Errs = case Action of "compile" -> do_compile(Erls,Beams,Opts,[]); "uncompile" -> do_uncompile(Erls++Beams); "uncompile_all" -> do_uncompile(cover:modules()) end, compile_frame1(Dir,Errs).get_compile_input([{"erl",File}|Input],Erl,Beam) -> get_compile_input(Input,[File|Erl],Beam);get_compile_input([{"beam",File}|Input],Erl,Beam) -> get_compile_input(Input,Erl,[File|Beam]);get_compile_input([{"options",Opts0},{"action",Action}],Erl,Beam) -> Opts = parse_options(Opts0), {Erl,Beam,Opts,Action}.do_compile([Erl|Erls],Beams,Opts,Errs) -> case cover:compile_module(Erl,Opts) of {ok,_} -> do_compile(Erls,Beams,Opts,Errs); {error,File} -> do_compile(Erls,Beams,Opts,["\\n"++File|Errs]) end;do_compile([],[Beam|Beams],Opts,Errs) -> case cover:compile_beam(Beam) of {ok,_} -> do_compile([],Beams,Opts,Errs); {error,{no_abstract_code,File}} -> do_compile([],Beams,Opts,["\\n"++File++" (no_abstract_code)"|Errs]) end;do_compile([],[],_,[]) -> [];do_compile([],[],_,Errs) -> "Compilation failed for the following files:" ++ Errs.parse_options(Options)-> case erl_scan:string(Options ++".") of {ok,Tokens,_Line} -> case erl_parse:parse_exprs(Tokens) of {ok,X}-> case lists:map(fun erl_parse:normalise/1, X) of [List] when is_list(List) -> List; List -> List end; _ -> [] end; _ -> [] end. do_uncompile(Files) -> lists:foreach( fun(File) -> Module = if is_atom(File) -> File; true -> ModStr = filename:basename(filename:rootname(File)), list_to_atom(ModStr) end, case code:which(Module) of cover_compiled -> code:purge(Module), case code:load_file(Module) of {module, Module} -> ok; {error, _Reason2} -> code:delete(Module) end; _ -> ok end end, Files), [].%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% The functions that builds the body of the page for coverage analysis%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%result_body(Err) -> [reload_menu_script(Err), "<H1 ALIGN=center>Result</H1>\n", "<TABLE BORDER=0 WIDTH=600 ALIGN=center>\n", "<TR><TD BGCOLOR=",?INFO_BG_COLOR,">\n", "<P>After executing all your tests you can view the result of the\n", "coverage analysis here. For each module you can\n", "<DL>\n", "<DT><B>Analyse to file</B></DT>\n", "<DD>The source code of the module is shown with the number of calls\n", "to each line stated in the left margin. Lines which are never called\n", "are colored red.</DD>\n", "<DT><B>Analyse coverage</B></DT>\n", "<DD>Show the number of covered and uncovered lines in the module.</DD>\n", "<DT><B>Analyse calls</B></DT>\n", "<DD>Show the number of calls in the module.</DD>\n", "<DT><B>Reset module</B></DT>\n", "<DD>Delete all coverage data for the module.</DD>\n", "<DT><B>Export module</B></DT>\n", "<DD>Write all coverage data for the module to a file. The data can\n", "later be imported from the \"Import\" page.</DD>\n", "</DL>\n", "<P>You can also reset or export data for all modules with the\n", "<B>Reset all</B> and <B>Export all</B> actions respectively. For these\n", "two actions there is no need to select a module.\n", "<P>Select module and action from the drop down menus below, and click\n", "the \"Execute\" button.\n", "</TD></TR>\n", "<TR><TD><BR><BR>\n", result_selections(), "</TD></TR></TABLE>"].result_selections() -> ModList = filter_modlist(cover:modules()++cover:imported_modules(),[]), ["<FORM ACTION=\"./result\" NAME=result_selection>\n", "<TABLE WIDTH=\"300\" BORDER=0 ALIGN=center>\n", "<TR><TD ALIGN=left>\n", "Module:\n", "<BR><SELECT NAME=module TITLE=\"Select module\">\n", ModList ++ "</SELECT>\n", "</TD>\n", "<TD ALIGN=left>\n", "Action:\n", "<BR><SELECT NAME=action TITLE=\"Select action\">\n", "<OPTION VALUE=\"analyse_to_file\">Analyse to file</OPTION>\n" "<OPTION VALUE=\"coverage\">Analyse coverage</OPTION>\n" "<OPTION VALUE=\"calls\">Analyse calls</OPTION>\n" "<OPTION VALUE=\"reset\">Reset module</OPTION>\n" "<OPTION VALUE=\"reset_all\">Reset all</OPTION>\n" "<OPTION VALUE=\"export\">Export module</OPTION>\n" "<OPTION VALUE=\"export_all\">Export all</OPTION>\n" "</SELECT>\n", "</TD>\n", "<TD ALIGN=center VALIGN=bottom><INPUT TYPE=submit VALUE=Execute>\n" "</TD></TR>\n" "</TABLE>\n", "</FORM>\n"].filter_modlist([M|Ms],Already) -> case lists:member(M,Already) of true -> filter_modlist(Ms,Already); false -> MStr = atom_to_list(M), ["<OPTION VALUE=",MStr,">",MStr,"</OPTION>\n" | filter_modlist(Ms,[M|Already])] end;filter_modlist([],_Already) -> []. handle_result(Input) -> case parse(Input) of [{"module",M},{"action",A}] -> case A of "analyse_to_file" -> case cover:analyse_to_file(list_to_atom(M),[html]) of {ok,File} -> case file:read_file(File) of {ok,HTML}-> file:delete(File), [header(), reload_menu_script(""), binary_to_list(HTML)]; _ -> result_frame1("Can not read file" ++ File) end; {error,no_source_code_found} -> result_frame1("No source code found for \\\'" ++ M ++ "\\\'") end; "calls" -> call_page(Input); "coverage" -> coverage_page(Input); "reset" -> cover:reset(list_to_atom(M)), result_frame1("Coverage data for \\\'" ++ M ++ "\\\' is now reset"); "reset_all" -> cover:reset(), result_frame1("All coverage data is now reset"); "export" -> ExportFile = generate_filename(M), cover:export(ExportFile,list_to_atom(M)), result_frame1("Coverage data for \\\'" ++ M ++ "\\\' is now exported to file \\\"" ++ ExportFile ++ "\\\""); "export_all" -> ExportFile = generate_filename("COVER"), cover:export(ExportFile), result_frame1( "All coverage data is now exported to file \\\"" ++ ExportFile ++ "\\\"") end; [{"action",_A}] -> result_frame1("No module is selected") end.generate_filename(Prefix) -> {ok,Cwd} = file:get_cwd(), filename:join(Cwd,Prefix ++ "_" ++ ts() ++ ".coverdata"). ts() -> {{Y,M,D},{H,Min,S}} = calendar:now_to_local_time(now()), io_lib:format("~4.4.0w~2.2.0w~2.2.0w-~2.2.0w~2.2.0w~2.2.0w", [Y,M,D,H,Min,S]).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% The functions that builds the body of the page that shows the calls %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%call_result(Input)-> Mod = list_to_atom(get_input_data(Input, "module")), case cover:analyse(Mod,calls) of {error,_}-> error_body(); {ok,_} -> call_result2(Mod,Input) end.call_result2(Mod,Input)-> Result = case get_input_data(Input,"what") of "mod" -> call_result(mod,Mod); "func" -> call_result(func,Mod); "clause" -> call_result(clause,Mod); _-> call_result(all,Mod) end, result_choice("calls",Mod) ++ Result.result_choice(Level,Mod)-> ModStr=atom_to_list(Mod), [reload_menu_script(""), "<TABLE WIDTH=100%><TR>\n", "<TD><A HREF=./",Level,"?module=",ModStr,"&what=all>All Data</A></TD>\n", "<TD><A HREF=./",Level,"?module=",ModStr,"&what=mod>Module</A></TD>\n", "<TD><A HREF=./",Level,"?module=",ModStr,"&what=func>Function</A></TD>\n", "<TD><A HREF=./",Level,"?module=",ModStr,"&what=clause>Clause</A></TD>\n", "</TR></TABLE><BR>\n"].call_result(Mode,Module)-> Content = case Mode of mod-> format_cover_call(cover:analyse(Module,calls,module),mod); func-> format_cover_call(cover:analyse(Module,calls,function),func); clause-> format_cover_call(cover:analyse(Module,calls,clause),clause); _-> format_cover_call(cover:analyse(Module,calls,module),mod) ++ format_cover_call(cover:analyse(Module,calls,function),func)++ format_cover_call(cover:analyse(Module,calls,clause),clause) end, getModDate(Module,date())++"<BR>"++ "<TABLE WIDTH=\"100%\" BORDER=1>"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -