1 // Copyright (c) 2017 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
2 // Boost Software License - Version 1.0
3 // A simple message box for the D programming language
4 // https://github.com/workhorsy/d-message-box
5 
6 
7 module message_box_helpers;
8 
9 import std.process : ProcessPipes;
10 
11 
12 void logProgramOutput(ProcessPipes pipes) {
13 	import std.algorithm : map;
14 	import std.conv : to;
15 	import std.stdio : stderr, stdout;
16 	import std.array : array;
17 	string[] output;
18 
19 	if (! pipes.stderr.eof) {
20 		output = pipes.stderr.byLine.map!(n => n.to!string).array();
21 		stderr.writefln("!!! show stderr: %s", output);
22 		stderr.flush();
23 	}
24 
25 	if (! pipes.stdout.eof) {
26 		output = pipes.stdout.byLine.map!(n => n.to!string).array();
27 		stdout.writefln("!!! show stdout: %s", output);
28 		stdout.flush();
29 	}
30 }
31 
32 bool isExecutable(string path) {
33 	version (Windows) {
34 		return true;
35 	} else {
36 		import std.file : getAttributes;
37 		import core.sys.posix.sys.stat : S_IXUSR;
38 		return (getAttributes(path) & S_IXUSR) > 0;
39 	}
40 }
41 
42 string[] programPaths(string[] program_names) {
43 	import std.process : environment;
44 	import std.path : pathSeparator, buildPath;
45 	import std.file : isDir;
46 	import std..string : split;
47 	import glob : glob;
48 
49 	string[] paths;
50 	string[] exts;
51 	if (environment.get("PATHEXT")) {
52 		exts = environment["PATHEXT"].split(pathSeparator);
53 	}
54 
55 	// Each path
56 	foreach (p ; environment["PATH"].split(pathSeparator)) {
57 		//stdout.writefln("p: %s", p);
58 		// Each program name
59 		foreach (program_name ; program_names) {
60 			string full_name = buildPath(p, program_name);
61 			//stdout.writefln("full_name: %s", full_name);
62 			string[] full_names = glob(full_name);
63 			//stdout.writefln("full_names: %s", full_names);
64 
65 			// Each program name that exists in a path
66 			foreach (name ; full_names) {
67 				// Save the path if it is executable
68 				if (name && isExecutable(name) && ! isDir(name)) {
69 					paths ~= name;
70 				}
71 				// Save the path if we found one with a common extension like .exe
72 				foreach (e; exts) {
73 					string full_name_ext = name ~ e;
74 
75 					if (isExecutable(full_name_ext) && ! isDir(full_name_ext)) {
76 						paths ~= full_name_ext;
77 					}
78 				}
79 			}
80 		}
81 	}
82 
83 	return paths;
84 }