@@ -52,11 +52,15 @@ package body LSP.Ada_Handlers.Alire is
5252 Error : Integer);
5353
5454 procedure Start_Alire
55- (Listener : in out Process_Listener'Class;
56- ALR : String;
55+ (ALR : String;
5756 Option_1 : String;
5857 Option_2 : String;
59- Root : String);
58+ Root : String;
59+ Error : out VSS.Strings.Virtual_String;
60+ Lines : out VSS.String_Vectors.Virtual_String_Vector);
61+
62+ Anchored : constant VSS.Regular_Expressions.Match_Options :=
63+ (VSS.Regular_Expressions.Anchored_Match => True);
6064
6165 -- ------------------
6266 -- Error_Occurred --
@@ -81,10 +85,6 @@ package body LSP.Ada_Handlers.Alire is
8185 Environment : in out GPR2.Environment.Object)
8286 is
8387 use type GNAT.OS_Lib.String_Access;
84- use type Spawn.Process_Exit_Code;
85- use type Spawn.Process_Exit_Status;
86- use type Spawn.Process_Status;
87- use all type VSS.Regular_Expressions.Match_Option;
8888
8989 ALR : GNAT.OS_Lib.String_Access :=
9090 GNAT.OS_Lib.Locate_Exec_On_Path (" alr" );
@@ -100,13 +100,7 @@ package body LSP.Ada_Handlers.Alire is
100100 VSS.Regular_Expressions.To_Regular_Expression
101101 (" export ([^=]+)="" ([^\n]+)"" " );
102102
103- Anchored : constant VSS.Regular_Expressions.Match_Options :=
104- (VSS.Regular_Expressions.Anchored_Match => True);
105-
106- List : array (1 .. 2 ) of aliased Process_Listener;
107103 Lines : VSS.String_Vectors.Virtual_String_Vector;
108- Text : VSS.Strings.Virtual_String;
109- Decoder : VSS.Strings.Converters.Decoders.Virtual_String_Decoder;
110104 begin
111105 Project.Clear;
112106 Has_Alire := ALR /= null ;
@@ -116,67 +110,14 @@ package body LSP.Ada_Handlers.Alire is
116110 return ;
117111 end if ;
118112
119- Start_Alire (List (1 ), ALR.all , " --non-interactive" , " show" , Root);
120- Start_Alire (List (2 ), ALR.all , " --non-interactive" , " printenv" , Root);
113+ Start_Alire (ALR.all , " --non-interactive" , " show" , Root, Error, Lines);
121114
122- loop
123- Spawn.Processes.Monitor_Loop (0.1 );
124-
125- exit when
126- (for all Item of List => Item.Process.Status = Spawn.Not_Running);
127- end loop ;
128-
129- Decoder.Initialize (" utf-8" );
130- GNAT.OS_Lib.Free (ALR);
131-
132- -- Decode output and check errors
133- for Item of List loop
134- Decoder.Reset_State;
135- Item.Text := Decoder.Decode (Item.Stdout);
136-
137- if Item.Process.Exit_Status /= Spawn.Normal
138- or else Item.Process.Exit_Code /= 0
139- or else Decoder.Has_Error
140- or else Item.Error /= 0
141- then
142- Error := " 'alr" ;
143-
144- for Arg of Item.Process.Arguments loop
145- Error.Append (" " );
146- Error.Append (VSS.Strings.Conversions.To_Virtual_String (Arg));
147- end loop ;
148-
149- Error.Append (" ' failed:" );
150- Error.Append (VSS.Characters.Latin.Line_Feed);
151-
152- if Decoder.Has_Error then
153- Error.Append (Decoder.Error_Message);
154- else
155- Error.Append (Item.Text);
156- end if ;
157-
158- Error.Append (VSS.Characters.Latin.Line_Feed);
159- Decoder.Reset_State;
160- Text := Decoder.Decode (Item.Stderr);
161-
162- if Decoder.Has_Error then
163- Error.Append (Decoder.Error_Message);
164- else
165- Error.Append (Text);
166- end if ;
167-
168- if Item.Error /= 0 then
169- Error.Append
170- (VSS.Strings.Conversions.To_Virtual_String
171- (GNAT.OS_Lib.Errno_Message (Item.Error)));
172- end if ;
173-
174- return ;
175- end if ;
176- end loop ;
115+ if not Error.Is_Empty then
116+ GNAT.OS_Lib.Free (ALR);
117+ return ;
118+ end if ;
177119
178120 -- Find project file in `alr show` output
179- Lines := List (1 ).Text.Split_Lines;
180121
181122 declare
182123 First : constant VSS.Strings.Virtual_String := Lines (1 );
@@ -202,8 +143,18 @@ package body LSP.Ada_Handlers.Alire is
202143 end ;
203144 end loop ;
204145
146+ if Project.Is_Empty then
147+ Error.Append (" No project file is found by alire" );
148+ end if ;
149+
150+ -- Find variables in `alr printenv` output
151+
152+ Start_Alire
153+ (ALR.all , " --non-interactive" , " printenv" , Root, Error, Lines);
154+
155+ GNAT.OS_Lib.Free (ALR);
156+
205157 -- Find variables in `alr printenv` output
206- Lines := List (2 ).Text.Split_Lines;
207158
208159 for Line of Lines loop
209160 declare
@@ -219,10 +170,6 @@ package body LSP.Ada_Handlers.Alire is
219170 end if ;
220171 end ;
221172 end loop ;
222-
223- if Project.Is_Empty then
224- Error.Append (" No project file is found by alire" );
225- end if ;
226173 end Run_Alire ;
227174
228175 -- -------------
@@ -235,33 +182,130 @@ package body LSP.Ada_Handlers.Alire is
235182 Error : out VSS.Strings.Virtual_String;
236183 Environment : in out GPR2.Environment.Object)
237184 is
238- Ignore : VSS.Strings.Virtual_String;
185+ use type GNAT.OS_Lib.String_Access;
186+
187+ ALR : GNAT.OS_Lib.String_Access :=
188+ GNAT.OS_Lib.Locate_Exec_On_Path (" alr" );
189+
190+ Export_Pattern : constant VSS.Regular_Expressions.Regular_Expression :=
191+ VSS.Regular_Expressions.To_Regular_Expression
192+ (" export ([^=]+)="" ([^\n]+)"" " );
193+
194+ Lines : VSS.String_Vectors.Virtual_String_Vector;
239195 begin
240- -- TODO: optimization: don't run second alire process
241- Run_Alire (Root, Has_Alire, Error, Ignore, Environment);
196+ Has_Alire := ALR /= null ;
197+
198+ if ALR = null then
199+ Error := " No alr in the PATH" ;
200+ return ;
201+ end if ;
202+
203+ Start_Alire
204+ (ALR.all , " --non-interactive" , " printenv" , Root, Error, Lines);
205+
206+ GNAT.OS_Lib.Free (ALR);
207+
208+ -- Find variables in `alr printenv` output
209+
210+ for Line of Lines loop
211+ declare
212+ Match : constant VSS.Regular_Expressions.Regular_Expression_Match
213+ := Export_Pattern.Match (Line, Anchored);
214+ begin
215+ if Match.Has_Match then
216+ Environment.Insert
217+ (Key => VSS.Strings.Conversions.To_UTF_8_String
218+ (Match.Captured (1 )),
219+ Value => VSS.Strings.Conversions.To_UTF_8_String
220+ (Match.Captured (2 )));
221+ end if ;
222+ end ;
223+ end loop ;
242224 end Run_Alire ;
243225
244- -- -----------------
245- -- Spawn_Process --
246- -- -----------------
226+ -- ---------------
227+ -- Start_Alire --
228+ -- ---------------
247229
248230 procedure Start_Alire
249- (Listener : in out Process_Listener'Class;
250- ALR : String;
231+ (ALR : String;
251232 Option_1 : String;
252233 Option_2 : String;
253- Root : String)
234+ Root : String;
235+ Error : out VSS.Strings.Virtual_String;
236+ Lines : out VSS.String_Vectors.Virtual_String_Vector)
254237 is
255- Process : Spawn.Processes.Process renames Listener.Process;
256- Options : Spawn.String_Vectors.UTF_8_String_Vector;
238+ use type Spawn.Process_Exit_Code;
239+ use type Spawn.Process_Exit_Status;
240+ use type Spawn.Process_Status;
241+
242+ Item : aliased Process_Listener;
243+ Process : Spawn.Processes.Process renames Item.Process;
244+ Options : Spawn.String_Vectors.UTF_8_String_Vector;
245+ Decoder : VSS.Strings.Converters.Decoders.Virtual_String_Decoder;
246+ Text : VSS.Strings.Virtual_String;
257247 begin
258248 Options.Append (Option_1);
259249 Options.Append (Option_2);
260250 Process.Set_Arguments (Options);
261251 Process.Set_Working_Directory (Root);
262252 Process.Set_Program (ALR);
263- Process.Set_Listener (Listener 'Unchecked_Access);
253+ Process.Set_Listener (Item 'Unchecked_Access);
264254 Process.Start;
255+
256+ loop
257+ Spawn.Processes.Monitor_Loop (0.1 );
258+
259+ exit when Item.Process.Status = Spawn.Not_Running;
260+ end loop ;
261+
262+ Decoder.Initialize (" utf-8" );
263+
264+ -- Decode output and check errors
265+ Decoder.Reset_State;
266+ Item.Text := Decoder.Decode (Item.Stdout);
267+
268+ if Item.Process.Exit_Status = Spawn.Normal
269+ and then Item.Process.Exit_Code = 0
270+ and then not Decoder.Has_Error
271+ and then Item.Error = 0
272+ then
273+
274+ Lines := Item.Text.Split_Lines;
275+
276+ else
277+ Error := " 'alr" ;
278+
279+ for Arg of Item.Process.Arguments loop
280+ Error.Append (" " );
281+ Error.Append (VSS.Strings.Conversions.To_Virtual_String (Arg));
282+ end loop ;
283+
284+ Error.Append (" ' failed:" );
285+ Error.Append (VSS.Characters.Latin.Line_Feed);
286+
287+ if Decoder.Has_Error then
288+ Error.Append (Decoder.Error_Message);
289+ else
290+ Error.Append (Item.Text);
291+ end if ;
292+
293+ Error.Append (VSS.Characters.Latin.Line_Feed);
294+ Decoder.Reset_State;
295+ Text := Decoder.Decode (Item.Stderr);
296+
297+ if Decoder.Has_Error then
298+ Error.Append (Decoder.Error_Message);
299+ else
300+ Error.Append (Text);
301+ end if ;
302+
303+ if Item.Error /= 0 then
304+ Error.Append
305+ (VSS.Strings.Conversions.To_Virtual_String
306+ (GNAT.OS_Lib.Errno_Message (Item.Error)));
307+ end if ;
308+ end if ;
265309 end Start_Alire ;
266310
267311 -- ----------------------------
0 commit comments