meson.build.o7QLX02
[roobuilder] / src / Palete / ValaSource.vala
1
2 // valac TreeBuilder.vala --pkg libvala-0.24 --pkg posix -o /tmp/treebuilder
3
4 /**
5  * 
6  *  This just deals with spawning the compiler and getting the results.
7  * 
8  *  each window should have one of these...
9  * 
10  *  x = new ValaSource();
11  *  x.connect.compiled(... do something with results... );
12  *  
13  
14  THIS IS NOT USED ?? - replaced with valacompilerequest
15  * 
16  */
17
18 namespace Palete {
19         
20         public errordomain ValaSourceError {
21                 INVALID_FORMAT 
22         }
23         
24         //public delegate  void ValaSourceResult(Json.Object res);
25         
26          
27
28         public class ValaSourceOLD : Object {
29  
30                 public Json.Object? last_result = null;
31                 public signal void compiled(Json.Object res);
32                 public signal void compile_output(string str);
33  
34                 
35                 public JsRender.JsRender file;
36                 public int line_offset = 0;
37                  
38                 public Gee.ArrayList<Spawn> children;
39                 Spawn compiler;
40                 
41                 public string tmpfile_path = "";
42                 
43                 
44                 public int terminal_pid = 0;
45                 
46                 public ValaSourceOLD(   ) 
47                 {
48                         base();
49                          
50                         this.compiler = null;
51                         this.children = new Gee.ArrayList<Spawn>();
52                         
53                 }
54                 public void dumpCode(string str) 
55                 {
56                         var ls = str.split("\n");
57                         for (var i=0;i < ls.length; i++) {
58                                 print("%d : %s\n", i+1, ls[i]);
59                         }
60                 }
61                 
62                 //public Gee.HashMap<int,string> checkFile()
63                 //{
64                 //      return this.checkString(JsRender.NodeToVala.mungeFile(this.file));
65                 //}
66
67                 public bool checkFileWithNodePropChange(
68                   
69                                         JsRender.JsRender file,
70                                         JsRender.Node node, 
71                                         JsRender.NodeProp prop,
72                                         string val
73                                  )
74                 {
75                         this.file = file;
76                         
77                         if (this.compiler != null) {
78                                 //this.compiler.tidyup();
79                                 //this.spawnResult(0,"","");
80                                 return false;
81                         }
82                         
83                         
84                         // untill we get a smarter renderer..
85                         // we have some scenarios where changing the value does not work
86                         if (prop.name == "xns" || prop.name == "xtype") {
87                                 return  false;
88                         }
89                                 
90                          
91                         var old = prop.val;
92                         
93
94                         prop.val =  "/*--VALACHECK-START--*/ " + prop.val ;
95                         
96
97                         var tmpstring = JsRender.NodeToVala.mungeFile(file);
98                         prop.val = old;
99                         
100                         //print("%s\n", tmpstring);
101                         var bits = tmpstring.split("/*--VALACHECK-START--*/");
102                         var offset =0;
103                         if (bits.length > 0) {
104                                 offset = bits[0].split("\n").length +1;
105                         }
106                         
107                         this.line_offset = offset;
108                         
109                         //this.dumpCode(tmpstring);
110                         //print("offset %d\n", offset);
111                         return this.checkStringSpawn(tmpstring );
112                         
113                         // modify report
114                         
115                         
116                         
117                 }
118                 
119                  
120                 private bool checkStringSpawn( string contents  )
121                 {
122                         
123                         if (this.compiler != null) {
124                                 this.compiler.isZombie();
125                                 //this.compiler.tidyup();
126                                 //this.spawnResult(-2,"","");
127                                 return false;
128                         }
129                         var pr = (Project.Gtk)(file.project);
130                         
131                         var tmpfilename = pr.path + "/build/tmp-%u.vala".printf( (uint) GLib.get_real_time()) ;
132                         try {
133                                 GLib.FileUtils.set_contents(tmpfilename,contents);
134                         } catch (GLib.FileError e) {
135                                 GLib.debug("Error creating temp build file %s : %s", tmpfilename, e.message);
136                                 return false;
137                         }
138                          
139
140                  
141                         var valafn = "";
142                         try {             
143                            var  regex = new Regex("\\.bjs$");
144                         
145                                 valafn = regex.replace(this.file.path,this.file.path.length , 0 , ".vala");
146                          } catch (GLib.RegexError e) {
147                                  
148                             return false;
149                         }   
150                         
151
152                         
153                         string[] args = {};
154                         args += BuilderApplication._self;
155                         args += "--skip-linking";
156                         args += "--project";
157                         args += this.file.project.path;
158                         args += "--target";
159                         args +=  pr.firstBuildModuleWith(this.file);
160                         args += "--add-file";
161                         args +=  tmpfilename;
162                         args += "--skip-file";
163                         args += valafn;
164                         
165                         this.tmpfile_path = tmpfilename;
166                         try {
167                                 this.compiler = new Spawn(pr.path + "/build", args);
168                         } catch (GLib.Error e) {
169                                 GLib.debug("Spawn failed: %s", e.message);
170                                 return false;
171                         }
172                         this.compiler.complete.connect(spawnResult);
173                 BuilderApplication.showSpinner("spinner", "compiling file");
174                         try {
175                                 this.compiler.run(); 
176                         } catch (GLib.Error e) {
177                                 GLib.debug("Error %s",e.message);
178                         BuilderApplication.showSpinner("face-sad", "compile failed %s".printf(e.message));
179                                 this.compiler = null;
180                                 this.deleteTemp();
181                                 return false;
182
183                         }
184                         return true;
185                          
186                 }
187                 
188                  
189                 
190                 
191                 public bool checkFileSpawn(JsRender.JsRender file )
192                 {
193                         // race condition..
194                         if (this.compiler != null) { 
195                                 this.compiler.isZombie();
196                                 //this.compiler.tidyup();
197                                 //this.spawnResult(-2,"","");
198                                 return false;
199                         }
200                         
201                         this.file = file;
202                         var pr = (Project.Gtk)(file.project);
203                         this.line_offset = 0;
204                           
205                         string[] args = {};
206                         args += BuilderApplication._self;
207                         args += "--skip-linking";
208                         args += "--project";
209                         args += this.file.project.path;
210                         args += "--target";
211                         args += pr.firstBuildModuleWith(this.file);
212                          
213                           
214                          
215                         
216                         
217                         try {
218                             this.compiler = new Spawn(pr.path+"/build", args);
219                             this.compiler.output_line.connect(this.compile_output_line);
220                             this.compiler.complete.connect(spawnResult);
221                         this.spinner(true);
222                             this.compiler.run(); 
223                         
224                          
225                         } catch (GLib.Error e) {
226                             GLib.debug(e.message);
227                         this.spinner(false);
228                             this.compiler = null;
229                             return false;
230                         }
231                         return true;
232                          
233                 }
234                 
235  
236
237                 
238                 
239                 public void spawnExecute(JsRender.JsRender file)
240                 {
241                         // race condition..
242                         if (this.compiler != null) {
243                                 this.compiler.isZombie();
244                                 this.compiler.tidyup();
245                                 this.spawnResult(-2,"","");
246                                 return;
247                         }
248                         if (!(file.project is Project.Gtk)) {
249                             return;
250                 }
251                         var pr = (Project.Gtk)(file.project);
252                         
253                         
254                         this.file = file;
255                         this.line_offset = 0;
256                         
257
258                           
259                         string[] args = {};
260                         args += BuilderApplication._self;
261                         args += "--debug";
262                         args += "all";
263                         
264                         args += "--project";
265                         args += this.file.project.path;
266                         args += "--target";
267                         args += pr.firstBuildModuleWith(this.file); 
268                         
269                         //args += "--output"; -- set up by the module -- defaults to testrun
270                         //args += "/tmp/testrun";
271                         
272                         // assume code is in home...
273                         try {
274                             this.compiler = new Spawn( GLib.Environment.get_home_dir(), args);
275                             this.compiler.output_line.connect(this.compile_output_line);
276                             this.compiler.complete.connect(runResult);
277                         this.spinner(true);
278                             this.compiler.run(); 
279                                 this.children.add(this.compiler); //keep a reference...
280                          
281                         } catch (GLib.Error e) {
282                         this.spinner(false);
283                             GLib.debug(e.message);
284                             this.compiler = null;
285
286                         }
287                         return;
288                          
289                 }
290                 public void compile_output_line(   string str )
291                 {
292                         GLib.debug("%s", str);
293                         this.compile_output(str);
294                 }
295                 /**
296                 * Used to compile a non builder file..
297                 */
298                  
299                  
300                 public bool checkPlainFileSpawn( JsRender.JsRender file, string contents )
301  
302                 {
303                         // race condition..
304                         if (this.compiler != null) { 
305                                 this.compiler.isZombie();
306                                 return false;
307                         }
308                         this.file = file;
309             
310                         var pr = (Project.Gtk)(file.project);
311                         
312                         var m = pr.firstBuildModuleWith(file);
313                         var cg = pr.compilegroups.get(m);
314
315                         if (cg == null) {
316                           return false;
317                         }
318                         var foundit = false;
319                         
320             if (cg.sources == null) {
321                 return false;
322             }
323             for (var i = 0; i < cg.sources.size; i++) {
324                             var path =  pr.path + "/" + cg.sources.get(i);
325                     if (path == file.path) {
326                         foundit = true;
327                         break;
328                                 }
329                         }
330
331                         if (!foundit) {
332                           
333                             this.compiler = null;
334                         
335                             return false; // do not run the compile..
336                         }
337                         // is the file in the module?
338                         
339                         var tmpfilename = pr.path + "/build/tmp-%u.vala".printf( (uint) GLib.get_real_time()) ;
340                         try {
341                                 GLib.FileUtils.set_contents(tmpfilename,contents);
342                         } catch (GLib.FileError e) {
343                                 GLib.debug("Error creating temp build file %s : %s", tmpfilename, e.message);
344                                 return false;
345                         }
346                          
347                         var target = pr.firstBuildModule();
348                         if (target.length < 1) {
349                                 return false;
350                         }
351                         
352                         // this.file = null; << /why
353                         this.line_offset = 0;
354                           
355                         string[] args = {};
356                         args += BuilderApplication._self;
357                         args += "--skip-linking";
358                         args += "--project";
359                         args +=  file.project.path;
360                         args += "--target";
361  
362                         args += pr.firstBuildModuleWith(this.file);
363                         args += "--add-file";
364                         args +=  tmpfilename;
365                         args += "--skip-file";
366                         args += file.path;
367                          
368                         this.tmpfile_path = tmpfilename;
369                         
370                         
371                         try {
372                             this.compiler = new Spawn("/tmp", args);
373                                 this.compiler.output_line.connect(this.compile_output_line);
374                             this.compiler.complete.connect(spawnResult);
375                         this.spinner(true);
376                             this.compiler.run(); 
377                         } catch (GLib.Error e) {
378                         this.spinner(false);
379                             this.compiler = null;
380                             this.deleteTemp();
381                                 
382                             
383                             return false;
384                         }
385                         return true;
386                          
387                 }
388                 
389                 public void deleteTemp()
390                 {
391                          if (this.tmpfile_path == "") {
392                                 return;
393                         }
394                         if (GLib.FileUtils.test(this.tmpfile_path, GLib.FileTest.EXISTS)) {
395                                 GLib.FileUtils.unlink(this.tmpfile_path);
396                         }
397                         var cf = this.tmpfile_path.substring(0, this.tmpfile_path.length-4) + "c";
398                         GLib.debug("try remove %s",cf);
399                         if (GLib.FileUtils.test(cf, GLib.FileTest.EXISTS)) {
400                                 GLib.FileUtils.unlink(cf);
401                         }
402                         var ccf = GLib.Path.get_dirname(cf) + "/build/" + GLib.Path.get_basename(cf);
403                         GLib.debug("try remove %s",ccf);
404                         if (GLib.FileUtils.test(ccf, GLib.FileTest.EXISTS)) {
405                                 GLib.FileUtils.unlink(ccf);
406                         }
407                         this.tmpfile_path = "";
408                 }
409                 // update the compiler results into the lists.
410                 
411                 
412                 // what to do when we have finished running..
413                 // call this.compiled(result) (handled by windowstate?) 
414                 public void spawnResult(int res, string output, string stderr)
415                 {
416                          
417                         if (res == -2) {
418                                 var ret = new Json.Object();
419                                 ret.set_boolean_member("success", false);
420                                 ret.set_string_member("message","killed");
421                                 this.compiled(ret);
422                                 this.compiler.isZombie();
423                                 this.compiler = null;
424                                 this.deleteTemp();
425                             this.spinner(false);
426                             return;
427                         }
428                         try { 
429                                 //GLib.debug("GOT output %s", output);
430                                 
431                                 var pa = new Json.Parser();
432                                 pa.load_from_data(output);
433                                 var node = pa.get_root();
434
435                                 if (node.get_node_type () != Json.NodeType.OBJECT) {
436                                         var ret = new Json.Object();
437                                         ret.set_boolean_member("success", false);
438                                         ret.set_string_member("message", 
439                                                 "Compiler returned Unexpected element type %s".printf( 
440                                                         node.type_name ()
441                                                 )
442                                         );
443                                         this.compiled(ret);
444                                         this.compiler = null;
445                                 }
446                                 var ret = node.get_object ();
447                                 ret.set_int_member("line_offset", this.line_offset);
448                                 this.last_result = ret;
449                                 this.compiled(ret);
450                                 
451                                 
452                         } catch (GLib.Error e) {
453                                 var ret = new Json.Object();
454                                 ret.set_boolean_member("success", false);
455                                 ret.set_string_member("message", e.message);
456                                 this.compiled(ret);
457                         }
458                         this.compiler.isZombie();
459                         this.compiler = null;
460                         this.deleteTemp();
461                 this.spinner(false);                    
462                         //compiler.unref();
463                         //tmpfile.unref();
464                          
465                         
466                         
467                 }
468                 
469                 public void killChildren(int pid)
470                 {
471                         if (pid < 1) {
472                                 return;
473                         }
474                         var cn = "/proc/%d/task/%d/children".printf(pid,pid);
475                         if (!FileUtils.test(cn, GLib.FileTest.EXISTS)) {
476                                 GLib.debug("%s doesnt exist - killing %d", cn, pid);
477                                 Posix.kill(pid, 9);
478                                 return;
479                         }
480                         string cpids = "";
481                         try {
482                                 FileUtils.get_contents(cn, out cpids);
483                         
484
485                                 if (cpids.length > 0) {
486                                         this.killChildren(int.parse(cpids));
487                                 }
488
489                         } catch (GLib.FileError e) {
490                                 // skip
491                         }
492                         GLib.debug("killing %d", pid);  
493                         Posix.kill(pid, 9);
494                 }
495                 
496                 
497                 public void runResult(int res, string output, string stderr)
498                 {
499                         this.compiler = null;
500                         
501                 
502                         GLib.debug("run result last pid = %d", this.terminal_pid );
503                 this.spinner(false);            
504                         this.killChildren(this.terminal_pid);
505                         this.terminal_pid = 0;
506                          
507                         
508                         
509                         
510                         
511                         var mod = "";
512                         var pr = (Project.Gtk)(this.file.project);
513                         
514                         
515                         
516                         if (this.file.build_module.length > 0 ) {
517                     mod =  this.file.build_module;
518                         } else {
519                             mod =  pr.firstBuildModule();
520                         }
521                         if (mod.length < 1) {
522                                 GLib.debug("missing compilegroup module");
523                                 return;
524                         }
525                         var cg =  pr.compilegroups.get(mod);
526                         var exe = pr.path + "/build/" + cg.name;
527                         
528                         
529                         
530                         if (!GLib.FileUtils.test(exe, GLib.FileTest.EXISTS)) {
531                                 print("Missing output file: %s\n",exe);
532                                 return;
533                         }
534                         var gdb_cfg= pr.path + "/build/.gdb-script";
535                         if (!GLib.FileUtils.test(gdb_cfg, GLib.FileTest.EXISTS)) {
536                                 pr.writeFile("build/.gdb-script", "set debuginfod enabled off\nr");
537                         }
538                         
539                         
540                         
541                          string[] args = "/usr/bin/gnome-terminal --disable-factory --wait -- /usr/bin/gdb -x".split(" ");
542                         //string[] args = "/usr/bin/xterm  -e /usr/bin/gdb -x".split(" ");
543                  
544                         args+= gdb_cfg;
545
546                         
547                         // runs gnome-terminal, with gdb .. running the application..
548                         // fixme -- need a system/which
549                         
550                         args += exe;
551                         if (cg.execute_args.length > 0) {
552                                 args+= "--args";
553                                 var aa = cg.execute_args.split(" ");
554                                 for (var i =0; i < aa.length; i++) {
555                                         args += aa[i];
556                                 }
557                         }
558
559                     print("OUT: %s\n\n----\nERR:%s\n", output, stderr);
560                     
561                     // should be home directory...
562                     
563                     
564                     try {
565                     
566                         var exec = new Spawn(pr.path , args);
567                         exec.env = GLib.Environ.get();
568                         /*{ 
569                                 "PATH=" + GLib.Environment.get_variable("PATH"),
570                                 "SHELL=" + GLib.Environment.get_variable("SHELL"),
571                                 "DISPLAY=" + GLib.Environment.get_variable("DISPLAY"),
572                                 "TERM=xterm",
573                                 "USER=" + GLib.Environment.get_variable("USER"),
574                                 "DBUS_SESSION_BUS_ADDRESS="+ GLib.Environment.get_variable("DBUS_SESSION_BUS_ADDRESS"),
575                                 "XDG_SESSION_PATH="+ GLib.Environment.get_variable("XDG_SESSION_PATH"),
576                                         "SESSION_MANAGER="+ GLib.Environment.get_variable("SESSION_MANAGER"),
577                                         "XDG_SESSION_CLASS="+ GLib.Environment.get_variable("XDG_SESSION_CLASS"),
578                                         "XDG_SESSION_DESKTOP="+ GLib.Environment.get_variable("XDG_SESSION_DESKTOP"),
579                                         "XDG_SESSION_TYPE="+ GLib.Environment.get_variable("XDG_SESSION_TYPE")
580                                 };
581                                 */
582                         exec.detach = true;
583                                 exec.run(); 
584
585                                 this.terminal_pid = exec.pid;
586                                 GLib.debug("Child PID = %d", this.terminal_pid);
587                                 
588                     } catch(GLib.Error e) {
589                                 GLib.debug("Failed to spawn: %s", e.message);
590                                 return;
591                         }
592                         
593                 }
594         }
595                  
596 }
597 /*
598 int main (string[] args) {
599
600         var a = new ValaSource(file);
601         a.create_valac_tree();
602         return 0;
603 }
604 */
605
606