2 // valac TreeBuilder.vala --pkg libvala-0.24 --pkg posix -o /tmp/treebuilder
6 * This just deals with spawning the compiler and getting the results.
8 * each window should have one of these...
10 * x = new ValaSource();
11 * x.connect.compiled(... do something with results... );
18 public errordomain ValaSourceError {
22 //public delegate void ValaSourceResult(Json.Object res);
26 public class ValaSourceOLD : Object {
28 public Json.Object? last_result = null;
29 public signal void compiled(Json.Object res);
30 public signal void compile_output(string str);
33 public JsRender.JsRender file;
34 public int line_offset = 0;
36 public Gee.ArrayList<Spawn> children;
39 public string tmpfile_path = "";
42 public int terminal_pid = 0;
44 public ValaSourceOLD( )
49 this.children = new Gee.ArrayList<Spawn>();
52 public void dumpCode(string str)
54 var ls = str.split("\n");
55 for (var i=0;i < ls.length; i++) {
56 print("%d : %s\n", i+1, ls[i]);
60 //public Gee.HashMap<int,string> checkFile()
62 // return this.checkString(JsRender.NodeToVala.mungeFile(this.file));
65 public bool checkFileWithNodePropChange(
67 JsRender.JsRender file,
69 JsRender.NodeProp prop,
75 if (this.compiler != null) {
76 //this.compiler.tidyup();
77 //this.spawnResult(0,"","");
82 // untill we get a smarter renderer..
83 // we have some scenarios where changing the value does not work
84 if (prop.name == "xns" || prop.name == "xtype") {
92 prop.val = "/*--VALACHECK-START--*/ " + prop.val ;
95 var tmpstring = JsRender.NodeToVala.mungeFile(file);
98 //print("%s\n", tmpstring);
99 var bits = tmpstring.split("/*--VALACHECK-START--*/");
101 if (bits.length > 0) {
102 offset = bits[0].split("\n").length +1;
105 this.line_offset = offset;
107 //this.dumpCode(tmpstring);
108 //print("offset %d\n", offset);
109 return this.checkStringSpawn(tmpstring );
118 private bool checkStringSpawn( string contents )
121 if (this.compiler != null) {
122 this.compiler.isZombie();
123 //this.compiler.tidyup();
124 //this.spawnResult(-2,"","");
127 var pr = (Project.Gtk)(file.project);
129 var tmpfilename = pr.path + "/build/tmp-%u.vala".printf( (uint) GLib.get_real_time()) ;
131 GLib.FileUtils.set_contents(tmpfilename,contents);
132 } catch (GLib.FileError e) {
133 GLib.debug("Error creating temp build file %s : %s", tmpfilename, e.message);
141 var regex = new Regex("\\.bjs$");
143 valafn = regex.replace(this.file.path,this.file.path.length , 0 , ".vala");
144 } catch (GLib.RegexError e) {
152 args += BuilderApplication._self;
153 args += "--skip-linking";
155 args += this.file.project.path;
157 args += pr.firstBuildModuleWith(this.file);
158 args += "--add-file";
160 args += "--skip-file";
163 this.tmpfile_path = tmpfilename;
165 this.compiler = new Spawn(pr.path + "/build", args);
166 } catch (GLib.Error e) {
167 GLib.debug("Spawn failed: %s", e.message);
170 this.compiler.complete.connect(spawnResult);
174 } catch (GLib.Error e) {
175 GLib.debug("Error %s",e.message);
177 this.compiler = null;
186 public void spinner(bool state)
188 foreach (var win in BuilderApplication.windows) {
190 win.statusbar_compile_spinner.start();
192 win.statusbar_compile_spinner.stop();
198 public bool checkFileSpawn(JsRender.JsRender file )
201 if (this.compiler != null) {
202 this.compiler.isZombie();
203 //this.compiler.tidyup();
204 //this.spawnResult(-2,"","");
209 var pr = (Project.Gtk)(file.project);
210 this.line_offset = 0;
213 args += BuilderApplication._self;
214 args += "--skip-linking";
216 args += this.file.project.path;
218 args += pr.firstBuildModuleWith(this.file);
225 this.compiler = new Spawn(pr.path+"/build", args);
226 this.compiler.output_line.connect(this.compile_output_line);
227 this.compiler.complete.connect(spawnResult);
232 } catch (GLib.Error e) {
233 GLib.debug(e.message);
235 this.compiler = null;
246 public void spawnExecute(JsRender.JsRender file)
249 if (this.compiler != null) {
250 this.compiler.isZombie();
251 this.compiler.tidyup();
252 this.spawnResult(-2,"","");
255 if (!(file.project is Project.Gtk)) {
258 var pr = (Project.Gtk)(file.project);
262 this.line_offset = 0;
267 args += BuilderApplication._self;
272 args += this.file.project.path;
274 args += pr.firstBuildModuleWith(this.file);
276 //args += "--output"; -- set up by the module -- defaults to testrun
277 //args += "/tmp/testrun";
279 // assume code is in home...
281 this.compiler = new Spawn( GLib.Environment.get_home_dir(), args);
282 this.compiler.output_line.connect(this.compile_output_line);
283 this.compiler.complete.connect(runResult);
286 this.children.add(this.compiler); //keep a reference...
288 } catch (GLib.Error e) {
290 GLib.debug(e.message);
291 this.compiler = null;
297 public void compile_output_line( string str )
299 GLib.debug("%s", str);
300 this.compile_output(str);
303 * Used to compile a non builder file..
307 public bool checkPlainFileSpawn( JsRender.JsRender file, string contents )
311 if (this.compiler != null) {
312 this.compiler.isZombie();
317 var pr = (Project.Gtk)(file.project);
319 var m = pr.firstBuildModuleWith(file);
320 var cg = pr.compilegroups.get(m);
327 if (cg.sources == null) {
330 for (var i = 0; i < cg.sources.size; i++) {
331 var path = pr.path + "/" + cg.sources.get(i);
332 if (path == file.path) {
340 this.compiler = null;
342 return false; // do not run the compile..
344 // is the file in the module?
346 var tmpfilename = pr.path + "/build/tmp-%u.vala".printf( (uint) GLib.get_real_time()) ;
348 GLib.FileUtils.set_contents(tmpfilename,contents);
349 } catch (GLib.FileError e) {
350 GLib.debug("Error creating temp build file %s : %s", tmpfilename, e.message);
354 var target = pr.firstBuildModule();
355 if (target.length < 1) {
359 // this.file = null; << /why
360 this.line_offset = 0;
363 args += BuilderApplication._self;
364 args += "--skip-linking";
366 args += file.project.path;
369 args += pr.firstBuildModuleWith(this.file);
370 args += "--add-file";
372 args += "--skip-file";
375 this.tmpfile_path = tmpfilename;
379 this.compiler = new Spawn("/tmp", args);
380 this.compiler.output_line.connect(this.compile_output_line);
381 this.compiler.complete.connect(spawnResult);
384 } catch (GLib.Error e) {
386 this.compiler = null;
396 public void deleteTemp()
398 if (this.tmpfile_path == "") {
401 if (GLib.FileUtils.test(this.tmpfile_path, GLib.FileTest.EXISTS)) {
402 GLib.FileUtils.unlink(this.tmpfile_path);
404 var cf = this.tmpfile_path.substring(0, this.tmpfile_path.length-4) + "c";
405 GLib.debug("try remove %s",cf);
406 if (GLib.FileUtils.test(cf, GLib.FileTest.EXISTS)) {
407 GLib.FileUtils.unlink(cf);
409 var ccf = GLib.Path.get_dirname(cf) + "/build/" + GLib.Path.get_basename(cf);
410 GLib.debug("try remove %s",ccf);
411 if (GLib.FileUtils.test(ccf, GLib.FileTest.EXISTS)) {
412 GLib.FileUtils.unlink(ccf);
414 this.tmpfile_path = "";
416 // update the compiler results into the lists.
419 // what to do when we have finished running..
420 // call this.compiled(result) (handled by windowstate?)
421 public void spawnResult(int res, string output, string stderr)
425 var ret = new Json.Object();
426 ret.set_boolean_member("success", false);
427 ret.set_string_member("message","killed");
429 this.compiler.isZombie();
430 this.compiler = null;
436 //GLib.debug("GOT output %s", output);
438 var pa = new Json.Parser();
439 pa.load_from_data(output);
440 var node = pa.get_root();
442 if (node.get_node_type () != Json.NodeType.OBJECT) {
443 var ret = new Json.Object();
444 ret.set_boolean_member("success", false);
445 ret.set_string_member("message",
446 "Compiler returned Unexpected element type %s".printf(
451 this.compiler = null;
453 var ret = node.get_object ();
454 ret.set_int_member("line_offset", this.line_offset);
455 this.last_result = ret;
459 } catch (GLib.Error e) {
460 var ret = new Json.Object();
461 ret.set_boolean_member("success", false);
462 ret.set_string_member("message", e.message);
465 this.compiler.isZombie();
466 this.compiler = null;
476 public void killChildren(int pid)
481 var cn = "/proc/%d/task/%d/children".printf(pid,pid);
482 if (!FileUtils.test(cn, GLib.FileTest.EXISTS)) {
483 GLib.debug("%s doesnt exist - killing %d", cn, pid);
489 FileUtils.get_contents(cn, out cpids);
492 if (cpids.length > 0) {
493 this.killChildren(int.parse(cpids));
496 } catch (GLib.FileError e) {
499 GLib.debug("killing %d", pid);
504 public void runResult(int res, string output, string stderr)
506 this.compiler = null;
509 GLib.debug("run result last pid = %d", this.terminal_pid );
511 this.killChildren(this.terminal_pid);
512 this.terminal_pid = 0;
519 var pr = (Project.Gtk)(this.file.project);
523 if (this.file.build_module.length > 0 ) {
524 mod = this.file.build_module;
526 mod = pr.firstBuildModule();
528 if (mod.length < 1) {
529 GLib.debug("missing compilegroup module");
532 var cg = pr.compilegroups.get(mod);
533 var exe = pr.path + "/build/" + cg.name;
537 if (!GLib.FileUtils.test(exe, GLib.FileTest.EXISTS)) {
538 print("Missing output file: %s\n",exe);
541 var gdb_cfg= pr.path + "/build/.gdb-script";
542 if (!GLib.FileUtils.test(gdb_cfg, GLib.FileTest.EXISTS)) {
543 pr.writeFile("build/.gdb-script", "set debuginfod enabled off\nr");
548 string[] args = "/usr/bin/gnome-terminal --disable-factory --wait -- /usr/bin/gdb -x".split(" ");
549 //string[] args = "/usr/bin/xterm -e /usr/bin/gdb -x".split(" ");
554 // runs gnome-terminal, with gdb .. running the application..
555 // fixme -- need a system/which
558 if (cg.execute_args.length > 0) {
560 var aa = cg.execute_args.split(" ");
561 for (var i =0; i < aa.length; i++) {
566 print("OUT: %s\n\n----\nERR:%s\n", output, stderr);
568 // should be home directory...
573 var exec = new Spawn(pr.path , args);
574 exec.env = GLib.Environ.get();
576 "PATH=" + GLib.Environment.get_variable("PATH"),
577 "SHELL=" + GLib.Environment.get_variable("SHELL"),
578 "DISPLAY=" + GLib.Environment.get_variable("DISPLAY"),
580 "USER=" + GLib.Environment.get_variable("USER"),
581 "DBUS_SESSION_BUS_ADDRESS="+ GLib.Environment.get_variable("DBUS_SESSION_BUS_ADDRESS"),
582 "XDG_SESSION_PATH="+ GLib.Environment.get_variable("XDG_SESSION_PATH"),
583 "SESSION_MANAGER="+ GLib.Environment.get_variable("SESSION_MANAGER"),
584 "XDG_SESSION_CLASS="+ GLib.Environment.get_variable("XDG_SESSION_CLASS"),
585 "XDG_SESSION_DESKTOP="+ GLib.Environment.get_variable("XDG_SESSION_DESKTOP"),
586 "XDG_SESSION_TYPE="+ GLib.Environment.get_variable("XDG_SESSION_TYPE")
592 this.terminal_pid = exec.pid;
593 GLib.debug("Child PID = %d", this.terminal_pid);
595 } catch(GLib.Error e) {
596 GLib.debug("Failed to spawn: %s", e.message);
605 int main (string[] args) {
607 var a = new ValaSource(file);
608 a.create_valac_tree();