module util; import std.stdio : File; public @safe: File stderr; private { string[] mainArgs; version (OpenBSD) { immutable(char) *promises; } } /++ + Common initialisation function shared between esv and esvsearch +/ void sharedInit(string[] args) { mainArgs = args; stderr = File("/dev/stderr", "w"); version (OpenBSD) () @trusted { import core.sys.openbsd.unistd : pledge; import std.string : toStringz; promises = toStringz("stdio rpath wpath cpath inet dns tty proc exec prot_exec"); pledge(promises, null); }(); } void enforceDie(A...)(bool cond, string fmt, A a) { import std.format : format; if (!cond) die(format(fmt, a)); } void handleOptError(in string msg) { import std.algorithm : startsWith; import std.regex : matchFirst; string opt = msg.matchFirst("-.")[0]; enforceDie(!msg.startsWith("Unrecognized option"), "unknown option " ~ opt); enforceDie(!msg.startsWith("Missing value for argument"), "missing argument for option " ~ opt); die(msg); /* catch-all */ } string parseBook(in string book) { import std.string : tr; return book.tr("-_", " "); } @safe unittest { assert(parseBook("1-Corinthians") == "1 Corinthians"); assert(parseBook("1_Corinthians") == "1 Corinthians"); } ushort terminalColumns() @trusted { import core.sys.posix.sys.ioctl; winsize w; ioctl(1, TIOCGWINSZ, &w); return w.ws_col > 72 ? 72 : w.ws_col; } void warn(string mesg) { import std.path : baseName; stderr.writeln(baseName(mainArgs[0]) ~ ": " ~ mesg); } void die(string mesg) @trusted { import core.runtime : Runtime; import core.stdc.stdlib : exit; warn(mesg); Runtime.terminate(); exit(1); }