| 1 | % (c) 2009-2019 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, | |
| 2 | % Heinrich Heine Universitaet Duesseldorf | |
| 3 | % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) | |
| 4 | ||
| 5 | :- module(tools_commands, | |
| 6 | [ edit_file/1,edit_file/2, diff_files_with_editor/2, | |
| 7 | show_errors_with_bb_results/0, show_errors_with_bb_results/1, show_source_locations_with_bb_results/1, | |
| 8 | gen_dot_output/4, gen_dot_output_env/6, | |
| 9 | get_dot_engine_options/2, | |
| 10 | show_ps_file/1, | |
| 11 | show_dot_file/1 ]). | |
| 12 | ||
| 13 | ||
| 14 | :- use_module(preferences). | |
| 15 | :- use_module(debug). | |
| 16 | :- use_module(tools). | |
| 17 | :- use_module(error_manager). | |
| 18 | :- use_module(system_call,[system_call/4]). | |
| 19 | ||
| 20 | ||
| 21 | edit_file(F) :- edit_file(F,none). | |
| 22 | edit_file(FILE,LINE) :- | |
| 23 | get_preference(path_to_text_editor_launch,EDITOR), | |
| 24 | edit_file_with_editor(EDITOR,FILE,LINE). | |
| 25 | ||
| 26 | edit_file_with_editor('',FILE,_LINE) :- !, | |
| 27 | add_error(edit_file_with_editor,'No text editor set (be sure to set the ProB EDITOR preference), cannot edit: ',FILE). | |
| 28 | edit_file_with_editor(EDITOR,FILE,LINE) :- number(LINE), | |
| 29 | tools:get_tail_filename(EDITOR,EdName), | |
| 30 | editor_understands_plus_line(EdName),!, % bbedit/vim can handle +LINE arg | |
| 31 | format('Opening file "~w" at LINE ~w using EDITOR "~w"~n',[FILE,LINE,EDITOR]), | |
| 32 | tools:string_concatenate('+',LINE,LinePosArg), | |
| 33 | system_call(EDITOR,[LinePosArg,FILE],ErrorTextAsCodeList,ExitCode), | |
| 34 | debug_println(9,exit(ExitCode,ErrorTextAsCodeList)). | |
| 35 | edit_file_with_editor(EDITOR,FILE,LINE) :- number(LINE), | |
| 36 | tools:get_tail_filename(EDITOR,atom),!, % atom can handle FILE:LINE | |
| 37 | format('Opening file "~w" at LINE ~w using EDITOR "~w"~n',[FILE,LINE,EDITOR]), | |
| 38 | ajoin([FILE,':',LINE],FILE_LINE), | |
| 39 | system_call(EDITOR,[FILE_LINE],ErrorTextAsCodeList,ExitCode), | |
| 40 | debug_println(9,exit(ExitCode,ErrorTextAsCodeList)). | |
| 41 | edit_file_with_editor(EDITOR,FILE,_) :- | |
| 42 | format('Opening file "~w" using EDITOR "~w"~n',[FILE,EDITOR]), | |
| 43 | system_call(EDITOR,[FILE],ErrorTextAsCodeList,ExitCode), | |
| 44 | debug_println(9,exit(ExitCode,ErrorTextAsCodeList)). | |
| 45 | ||
| 46 | ||
| 47 | editor_understands_plus_line(bbedit). | |
| 48 | editor_understands_plus_line(edit). % Text Wrangler | |
| 49 | editor_understands_plus_line(vim). | |
| 50 | ||
| 51 | ||
| 52 | ||
| 53 | diff_files_with_editor(FILE1,FILE2) :- | |
| 54 | DIFFER = '/usr/local/bin/bbdiff', % TO DO: provide preference | |
| 55 | system_call:system_call(DIFFER,[FILE1,FILE2],ErrorTextAsCodeList,ExitCode), | |
| 56 | debug_println(9,exit(ExitCode,ErrorTextAsCodeList)). | |
| 57 | ||
| 58 | ||
| 59 | :- use_module(library(process)). | |
| 60 | :- use_module(system_call,[system_call_keep_open/7]). | |
| 61 | show_errors_with_bb_results :- show_errors_with_bb_results([]). | |
| 62 | show_errors_with_bb_results(Options) :- | |
| 63 | stored_error(_,_,_,Span,Options), | |
| 64 | extract_file_number_and_name(Span,_,_Filename), | |
| 65 | extract_line_col(Span,_,_,_,_), | |
| 66 | !, | |
| 67 | Command = '/usr/local/bin/bbresults', % TO DO: put in preference | |
| 68 | BBOptions = ['-p', 'flake8'], Env = [], | |
| 69 | on_exception(error(existence_error(_,_),E), | |
| 70 | (system_call_keep_open(Command,BBOptions,Process,STDIn,_STDOut,_STDErr,Env), | |
| 71 | write_errors_for_bbresults(STDIn,Options), | |
| 72 | close(STDIn), | |
| 73 | process_release(Process)), | |
| 74 | add_error(show_errors_with_bb_results,'Cannot start error viewer: ',Command:E)). | |
| 75 | show_errors_with_bb_results(_). % no errors to show | |
| 76 | ||
| 77 | stored_error(Source,S,TContext,Span,Options) :- | |
| 78 | (member(current,Options) -> logged_error(Source,S,TContext,Span) | |
| 79 | ; backed_up_error(Source,S,_TContext,Span)). | |
| 80 | ||
| 81 | % --------------------- | |
| 82 | % write errors in bbresults style (flake8) | |
| 83 | % filename:line:column: W/E1 message | |
| 84 | ||
| 85 | write_errors_for_bbresults(Stream,Options) :- | |
| 86 | stored_error(Source,S,_TContext,Span,Options), | |
| 87 | extract_file_number_and_name(Span,_,Filename), | |
| 88 | extract_line_col(Span,SL,SC,_EL,_EC), | |
| 89 | StartCol is SC+1, | |
| 90 | (Source = warning(_) -> Type='W1' ; Type='E1'), | |
| 91 | format(Stream,'~w:~w:~w: ~w ~w~n',[Filename,SL,StartCol,Type,S]), | |
| 92 | %format(user_output,'~w:~w:~w: ~w ~w~n',[Filename,SL,SC,Type,S]), | |
| 93 | fail. | |
| 94 | write_errors_for_bbresults(_,_). | |
| 95 | ||
| 96 | :- use_module(library(lists)). | |
| 97 | % show a list of source locations | |
| 98 | show_source_locations_with_bb_results(List) :- | |
| 99 | Command = '/usr/local/bin/bbresults', % TO DO: put in preference | |
| 100 | BBOptions = ['-p', 'flake8'], Env = [], | |
| 101 | on_exception(error(existence_error(_,_),E), | |
| 102 | (system_call_keep_open(Command,BBOptions,Process,STDIn,_STDOut,_STDErr,Env), | |
| 103 | maplist(write_src_loc_msg_for_bbresults(STDIn),List), | |
| 104 | close(STDIn), | |
| 105 | process_release(Process)), | |
| 106 | add_error(show_errors_with_bb_results,'Cannot start error viewer: ',Command:E)). | |
| 107 | ||
| 108 | write_src_loc_msg_for_bbresults(Stream,src_loc_msg(S,Filename,SL,StartCol,_EndLine,_EndCol)) :- | |
| 109 | format(Stream,'~w:~w:~w: ~w ~w~n',[Filename,SL,StartCol,'W1',S]). | |
| 110 | ||
| 111 | % ------------------------------ | |
| 112 | ||
| 113 | % show pdf/ps file using Preview/open/gsview/... | |
| 114 | show_ps_file(FILE) :- | |
| 115 | get_preference(path_to_ps_viewer,PSVIEWER), | |
| 116 | system_call:system_call(PSVIEWER,[FILE],ErrorTextAsCodeList,ExitCode), | |
| 117 | (ErrorTextAsCodeList=[] -> true | |
| 118 | ; format('PS/PDF Viewer (~w) Error Result: ~s~nExit code:~w.~n',[PSVIEWER,ErrorTextAsCodeList,ExitCode]), | |
| 119 | fail | |
| 120 | ). | |
| 121 | ||
| 122 | % show dot file using dotty | |
| 123 | show_dot_file(FILE) :- | |
| 124 | get_preference(path_to_dotty,DOTTY), | |
| 125 | system_call:system_call(DOTTY,[FILE],ErrorTextAsCodeList,ExitCode), | |
| 126 | (ErrorTextAsCodeList=[] -> true | |
| 127 | ; format('Dot Viewer(~w) Error Result: ~s~nExit code:~w.~n',[DOTTY,ErrorTextAsCodeList,ExitCode]), | |
| 128 | fail | |
| 129 | ). | |
| 130 | ||
| 131 | % ------------------------------ | |
| 132 | ||
| 133 | % call dot or sfdp to generate a PDF/PNG/SVG file: | |
| 134 | :- use_module(probsrc(system_call),[system_call_env/6]). | |
| 135 | gen_dot_output(DOTFILE,DotType,OutputType,OutputFILE) :- | |
| 136 | gen_dot_output_env(DOTFILE,DotType,OutputType,OutputFILE,[],_JExit). | |
| 137 | % you can use JExit=no_process_wait and ENV = [detached(false)] | |
| 138 | gen_dot_output_env(DOTFILE,DotType,OutputType,OutputFILE,ENV,JExit) :- | |
| 139 | get_preference(path_to_dot,DOTCMD), | |
| 140 | valid_dot_output_parameter(OutputType,Para),!, | |
| 141 | absolute_file_name(OutputFILE,AOutFile), | |
| 142 | format(user_output,'Calling dot: ~w to generate ~w from ~w~n',[DOTCMD,AOutFile,DOTFILE]), | |
| 143 | get_dot_engine_options(DotType,DotOptions), | |
| 144 | append([Para|DotOptions],['-o', AOutFile, DOTFILE],DotArgs), | |
| 145 | system_call_env(DOTCMD, DotArgs,ENV,_TextOut,ErrorTextAsCodeList,JExit), | |
| 146 | (ErrorTextAsCodeList=[] -> true | |
| 147 | ; format('Dot Error Result: ~s~n.',[ErrorTextAsCodeList]), | |
| 148 | fail | |
| 149 | ). | |
| 150 | ||
| 151 | get_dot_engine_options(circo,R) :- !, R=['-Kcirco']. | |
| 152 | get_dot_engine_options(dot,R) :- !, R=['-Kdot']. | |
| 153 | get_dot_engine_options(fdp,R) :- !, R=['-Kfdp']. | |
| 154 | get_dot_engine_options(neato,R) :- !, R=['-Kneato']. | |
| 155 | get_dot_engine_options(sfdp,R) :- !, R=['-Ksfdp']. | |
| 156 | get_dot_engine_options(twopi,R) :- !, R=['-Ktwopi']. | |
| 157 | get_dot_engine_options(default,R) :- get_preference(dot_default_engine,Eng), Eng \= default,!, | |
| 158 | get_dot_engine_options(Eng,R). | |
| 159 | get_dot_engine_options(OTHER,[]) :- add_error(get_dot_engine_options,'Unknown DOT Engine:',OTHER). | |
| 160 | ||
| 161 | valid_dot_output_parameter(pdf,'-Tpdf'). | |
| 162 | valid_dot_output_parameter(png,'-Tpng'). | |
| 163 | valid_dot_output_parameter(svg,'-Tsvg'). | |
| 164 | valid_dot_output_parameter(dot,'-Tdot'). % dot with layout | |
| 165 | valid_dot_output_parameter(canon,'-Tcanon'). % dot without layout | |
| 166 | valid_dot_output_parameter(xdot,'-Txdot'). % dot with layout | |
| 167 | % many more a supported: eps, xdot, canon, ... | |
| 168 | valid_dot_output_parameter(T,_) :- add_internal_error('Illegal dot output type: ',T),fail. | |
| 169 | ||
| 170 | ||
| 171 |