@@ -52,11 +52,15 @@ package body LSP.Ada_Handlers.Alire is
52
52
Error : Integer);
53
53
54
54
procedure Start_Alire
55
- (Listener : in out Process_Listener'Class;
56
- ALR : String;
55
+ (ALR : String;
57
56
Option_1 : String;
58
57
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);
60
64
61
65
-- ------------------
62
66
-- Error_Occurred --
@@ -81,10 +85,6 @@ package body LSP.Ada_Handlers.Alire is
81
85
Environment : in out GPR2.Environment.Object)
82
86
is
83
87
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;
88
88
89
89
ALR : GNAT.OS_Lib.String_Access :=
90
90
GNAT.OS_Lib.Locate_Exec_On_Path (" alr" );
@@ -100,13 +100,7 @@ package body LSP.Ada_Handlers.Alire is
100
100
VSS.Regular_Expressions.To_Regular_Expression
101
101
(" export ([^=]+)="" ([^\n]+)"" " );
102
102
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;
107
103
Lines : VSS.String_Vectors.Virtual_String_Vector;
108
- Text : VSS.Strings.Virtual_String;
109
- Decoder : VSS.Strings.Converters.Decoders.Virtual_String_Decoder;
110
104
begin
111
105
Project.Clear;
112
106
Has_Alire := ALR /= null ;
@@ -116,67 +110,14 @@ package body LSP.Ada_Handlers.Alire is
116
110
return ;
117
111
end if ;
118
112
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);
121
114
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 ;
177
119
178
120
-- Find project file in `alr show` output
179
- Lines := List (1 ).Text.Split_Lines;
180
121
181
122
declare
182
123
First : constant VSS.Strings.Virtual_String := Lines (1 );
@@ -202,8 +143,18 @@ package body LSP.Ada_Handlers.Alire is
202
143
end ;
203
144
end loop ;
204
145
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
+
205
157
-- Find variables in `alr printenv` output
206
- Lines := List (2 ).Text.Split_Lines;
207
158
208
159
for Line of Lines loop
209
160
declare
@@ -219,10 +170,6 @@ package body LSP.Ada_Handlers.Alire is
219
170
end if ;
220
171
end ;
221
172
end loop ;
222
-
223
- if Project.Is_Empty then
224
- Error.Append (" No project file is found by alire" );
225
- end if ;
226
173
end Run_Alire ;
227
174
228
175
-- -------------
@@ -235,33 +182,130 @@ package body LSP.Ada_Handlers.Alire is
235
182
Error : out VSS.Strings.Virtual_String;
236
183
Environment : in out GPR2.Environment.Object)
237
184
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;
239
195
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 ;
242
224
end Run_Alire ;
243
225
244
- -- -----------------
245
- -- Spawn_Process --
246
- -- -----------------
226
+ -- ---------------
227
+ -- Start_Alire --
228
+ -- ---------------
247
229
248
230
procedure Start_Alire
249
- (Listener : in out Process_Listener'Class;
250
- ALR : String;
231
+ (ALR : String;
251
232
Option_1 : String;
252
233
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)
254
237
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;
257
247
begin
258
248
Options.Append (Option_1);
259
249
Options.Append (Option_2);
260
250
Process.Set_Arguments (Options);
261
251
Process.Set_Working_Directory (Root);
262
252
Process.Set_Program (ALR);
263
- Process.Set_Listener (Listener 'Unchecked_Access);
253
+ Process.Set_Listener (Item 'Unchecked_Access);
264
254
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 ;
265
309
end Start_Alire ;
266
310
267
311
-- ----------------------------
0 commit comments