34
35:- module(build_conan,
36 []). 37:- autoload(library(apply), [foldl/4]). 38:- autoload(library(filesex), [directory_file_path/3]). 39:- autoload(library(lists), [select/4, append/3]). 40:- autoload(library(readutil), [read_line_to_string/2]). 41:- autoload(library(build/tools), [ensure_build_dir/3, run_process/3]). 42:- autoload(library(dcg/basics), [whites/2, remainder/3]). 43
44:- use_module(tools). 45
59
60:- multifile
61 prolog:build_file/2,
62 prolog:build_step/4, 63 prolog:build_config/5. 64
65prolog:build_file('conanfile.txt', conan).
66prolog:build_file('conanfile.py', conan).
67
68prolog:build_step(dependencies, conan, State0, State) :-
69 ensure_build_dir(build, State0, State1),
70 run_process(path(conan), ['install', '-b', missing, State1.src_dir],
71 [ env(State1.env),
72 directory(State1.bin_dir)
73 ]),
74 load_conan_virtualenv(State1, State).
75
76load_conan_virtualenv(State0, State) :-
77 directory_file_path(State0.bin_dir, 'environment.sh.env', ConanEnvFile),
78 ( exists_file(ConanEnvFile)
79 -> import_environment(ConanEnvFile, State0.env, Env),
80 State = State0.put(env,Env)
81 ; State = State0
82 ).
83
84
94
95import_environment(File, Env0, Env) :-
96 setup_call_cleanup(
97 open(File, read, In),
98 join_environment(In, Env0, Env),
99 close(In)).
100
101join_environment(In, Env0, Env) :-
102 read_line_to_string(In, Line),
103 ( Line == end_of_file
104 -> Env = Env0
105 ; join_line(Line, Env0, Env1),
106 join_environment(In, Env1, Env)
107 ).
108
109join_line(Line, Env0, Env) :-
110 string_codes(Line, Codes),
111 phrase(env_assigments(Assignments, Env0), Codes),
112 foldl(env_assign, Assignments, Env0, Env).
113
114env_assign(Var=Value, Env0, Env) :-
115 select(Var=_, Env0, Var=Value, Env),
116 !.
117env_assign(Var=Value, Env, [Var=Value|Env]).
118
119env_assigments([Var=Value|T], Env) -->
120 whites,
121 vname(Var), "=", !,
122 var_value(ValueCodes, Env, -1),
123 { atom_codes(Value, ValueCodes) },
124 env_assigments(T, Env).
125env_assigments([], _) -->
126 whites,
127 ( "#"
128 -> remainder(_)
129 ; []
130 ).
131
132var_value(Codes, Env, EOF) -->
133 "\"",
134 !,
135 dquoted(Codes, Tail, Env),
136 var_value(Tail, Env, EOF).
137var_value(Codes, Env, EOF) -->
138 "\'",
139 !,
140 squoted(Codes, Tail),
141 var_value(Tail, Env, EOF).
142var_value(Codes, Env, EOF) -->
143 "$",
144 !,
145 subst_var(Codes, Tail, Env),
146 var_value(Tail, Env, EOF).
147var_value([H|T], Env0, EOF) -->
148 [H],
149 { \+ ( H == EOF
150 ; H == -1,
151 code_type(H, white)
152 )
153 },
154 !,
155 var_value(T, Env0, EOF).
156var_value([], _, _) -->
157 [].
158
159dquoted(Codes, Tail, _) -->
160 "\"",
161 !,
162 { Tail = Codes }.
163dquoted(Codes, Tail, Env) -->
164 "$",
165 !,
166 subst_var(Codes, Tail0, Env),
167 dquoted(Tail0, Tail, Env).
168dquoted([H|T], Tail, Env) -->
169 [H],
170 dquoted(T, Tail, Env).
171
172squoted(Codes, Tail) -->
173 "'",
174 !,
175 { Tail = Codes }.
176squoted([H|T], Tail) -->
177 [H],
178 squoted(T, Tail).
179
180subst_var(Codes, Tail, Env) -->
181 "{",
182 !, vname(Name),
183 var_default(Name, Env, Codes, Tail),
184 "}".
185subst_var(Codes, Tail, Env) -->
186 vname(Name),
187 { memberchk(Name=Value, Env)
188 -> string_codes(Value, CodesC),
189 append(CodesC, Tail, Codes)
190 ; Tail = Codes
191 }.
192
193vname(Name) -->
194 [C],
195 { code_type(C, csymf) },
196 vname_cont(Cs),
197 { atom_codes(Name, [C|Cs]) }.
198
199vname_cont([H|T]) -->
200 [H],
201 { code_type(H, csym) },
202 !,
203 vname_cont(T).
204vname_cont([]) -->
205 [].
206
207var_default(Name, Env, Codes, Tail) -->
208 var_def_sep(Op, Null),
209 var_value(Default, Env, 0'}),
210 { Op == (-)
211 -> ( memberchk(Name=Value, Env),
212 \+ isnull(Null, Value)
213 -> string_codes(Value, CodesC),
214 append(CodesC, Tail, Codes)
215 ; append(Default, Tail, Codes)
216 )
217 ; Op == (+),
218 ( memberchk(Name=Value, Env),
219 \+ isnull(Null, Value)
220 -> append(Default, Tail, Codes)
221 ; Tail = Codes
222 )
223 }.
224
225var_def_sep(-, false) --> "-".
226var_def_sep(-, true) --> ":-".
227var_def_sep(+, false) --> "+".
228var_def_sep(+, true) --> ":+".
229
230isnull(false, _).
231isnull(true, '').
232isnull(true, "")