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