1 /** 2 * A sensible main() function. 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <ae@cy.md> 12 */ 13 14 module ae.utils.main; 15 16 /** 17 * Mix in a main function, which should be adequate 18 * for most end-user programs. 19 * 20 * In debug mode (-debug), this is a pass-through. 21 * Otherwise, this will catch uncaught exceptions, 22 * and display only the message (sans stack trace) 23 * to the user - on standard error, or, for Windows 24 * GUI programs, in a message box. 25 */ 26 mixin template main(alias realMain) 27 { 28 int run(string[] args) 29 { 30 static if (is(typeof(realMain()))) 31 static if (is(typeof(realMain()) == void)) 32 { realMain(); return 0; } 33 else 34 return realMain(); 35 else 36 static if (is(typeof(realMain(args)) == void)) 37 { realMain(args); return 0; } 38 else 39 return realMain(args); 40 } 41 42 int runCatchingException(E, string message)(string[] args) 43 { 44 try 45 return run(args); 46 catch (E e) 47 { 48 version (Windows) 49 { 50 import core.sys.windows.windows; 51 auto h = GetStdHandle(STD_ERROR_HANDLE); 52 if (!h || h == INVALID_HANDLE_VALUE) 53 { 54 import ae.sys.windows : messageBox; 55 messageBox(e.msg, message, MB_ICONERROR); 56 return 1; 57 } 58 } 59 60 import std.stdio : stderr; 61 stderr.writefln("%s: %s", message, e.msg); 62 return 1; 63 } 64 } 65 66 int main(string[] args) 67 { 68 debug 69 static if(is(std.getopt.GetOptException)) 70 return runCatchingException!(std.getopt.GetOptException, "Usage error")(args); 71 else 72 return run(args); 73 else 74 return runCatchingException!(Throwable, "Fatal error")(args); 75 } 76 }