From 8b392c5baba9379c1f8eab0e56f73925f68edc22 Mon Sep 17 00:00:00 2001 From: Jeremy Baxter Date: Tue, 13 Feb 2024 09:40:44 +1300 Subject: [PATCH] use @safe everywhere with a little bit of evil @trusted magic... --- esv.d | 9 ++++++++- esvapi.d | 36 ++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/esv.d b/esv.d index a03c586..fc8c3b1 100644 --- a/esv.d +++ b/esv.d @@ -29,7 +29,7 @@ import std.getopt : getoptConfig = config; import std.path : baseName, dirName, expandTilde, isValidPath; import std.process : environment, executeShell; import std.regex : regex, matchFirst, replaceAll, replaceFirst; -import std.stdio : writef, writeln, writefln, stderr; +import std.stdio : writef, writeln, writefln, File; import std.string : splitLines; import initial; @@ -37,6 +37,8 @@ import initial; import config; import esvapi; +@safe: + enum VERSION = "0.2.0"; bool aFlag; /* audio */ @@ -49,6 +51,8 @@ bool rFlag, RFlag; /* passage references */ string sFlag; /* search passages */ bool VFlag; /* show version */ +File stderr; + version (OpenBSD) { immutable(char) *promises; } @@ -58,6 +62,9 @@ main(string[] args) { bool success; + /* @safe way of opening stderr on Unix */ + stderr = File("/dev/stderr", "w"); + version (OpenBSD) { import core.sys.openbsd.unistd : pledge; import std.string : toStringz; diff --git a/esvapi.d b/esvapi.d index 79e70f5..2178258 100644 --- a/esvapi.d +++ b/esvapi.d @@ -30,6 +30,8 @@ import std.stdio : File; import std.string : capitalize, tr, wrap; import std.net.curl : HTTP; +@safe: + /** Indentation style to use when formatting passages. */ enum ESVIndent { @@ -141,7 +143,7 @@ const string[] ESVAPI_PARAMETERS = [ * Otherwise, returns false. */ bool -bookValid(in char[] book) nothrow @safe +bookValid(in char[] book) nothrow { foreach (string b; BIBLE_BOOKS) { if (book.capitalize() == b.capitalize()) @@ -154,7 +156,7 @@ bookValid(in char[] book) nothrow @safe * Otherwise, returns false. */ bool -verseValid(in char[] verse) @safe +verseValid(in char[] verse) { foreach (string re; [ "^\\d{1,3}$", @@ -193,7 +195,7 @@ class ESVApi /** * Constructs an ESVApi object using the given authentication key. */ - this(string key, string tmpName = "esv") @safe + this(string key, string tmpName = "esv") { _key = key; _tmp = tempDir() ~ tmpName; @@ -212,7 +214,7 @@ class ESVApi * was constructed. This authentication key cannot be changed. */ final @property string - key() const nothrow pure @nogc @safe + key() const nothrow pure @nogc { return _key; } @@ -220,7 +222,7 @@ class ESVApi * Returns the subdirectory used to store temporary audio passages. */ final @property string - tmpDir() const nothrow pure @nogc @safe + tmpDir() const nothrow pure @nogc { return _tmp; } @@ -228,7 +230,7 @@ class ESVApi * Returns the API URL currently in use. */ final @property string - url() const nothrow pure @nogc @safe + url() const nothrow pure @nogc { return _url; } @@ -236,7 +238,7 @@ class ESVApi * Sets the API URL currently in use to the given url argument. */ final @property void - url(immutable(string) url) @safe + url(immutable(string) url) in (!url.matchAll(`^https?://.+\\..+(/.+)?`).empty, "Invalid URL format") { _url = url; @@ -348,19 +350,21 @@ class ESVApi lineLength = lineLength == 0 ? 80 : lineLength; - foreach (JSONValue item; resp["results"].array) { - layout ~= format!fmt( - item["reference"].str, - item["content"].str - .wrap(lineLength) - ); - } + () @trusted { + foreach (JSONValue item; resp["results"].array) { + layout ~= format!fmt( + item["reference"].str, + item["content"].str + .wrap(lineLength) + ); + } + }(); return layout; } protected char[] - makeRequest(in char[] query) + makeRequest(in char[] query) @trusted { char[] response; HTTP request; @@ -394,7 +398,7 @@ struct ESVApiOptions * If initialise is true, initialise an ESVApiOptions * structure with the default values. */ - this(bool initialise) nothrow @safe + this(bool initialise) nothrow { if (!initialise) return;