esvsearch: split esv search code into separate program

Requires rewiring the build system to accommodate for two executables.

Fixes: https://todo.sr.ht/~jeremy/esv/4
This commit is contained in:
Jeremy Baxter 2024-06-26 12:55:41 +12:00
parent de71043ef1
commit ec8be68b49
6 changed files with 122 additions and 32 deletions

1
.gitignore vendored
View file

@ -2,6 +2,7 @@
*.so
*.a
esv
esvsearch
result
config.mk

View file

@ -6,12 +6,14 @@ DC = ${_DC}
CFLAGS = ${_CFLAGS}
OBJS = ${_OBJS}
all: esv
all: esv esvsearch
include config.mk
esv: ${OBJS}
${DC} ${_LDFLAGS} -of=$@ ${OBJS}
esv: esv.o ${OBJS}
${DC} ${_LDFLAGS} -of=$@ esv.o ${OBJS}
esvsearch: esvsearch.o ${OBJS}
${DC} ${_LDFLAGS} -of=$@ esvsearch.o ${OBJS}
.SUFFIXES: .d .o
@ -19,10 +21,11 @@ esv: ${OBJS}
${DC} ${CFLAGS} -c $<
clean:
rm -f esv ${OBJS} ${INIOBJS}
rm -f esv esvsearch esv.o esvsearch.o ${OBJS}
install: esv
install: esv esvsearch
install -Dm755 esv ${DESTDIR}${PREFIX}/bin/esv
install -Dm755 esvsearch ${DESTDIR}${PREFIX}/bin/esvsearch
install -Dm644 esv.1 ${DESTDIR}${MANPREFIX}/man1/esv.1
install -Dm644 esv.conf.5 ${DESTDIR}${MANPREFIX}/man5/esv.conf.5

4
configure vendored
View file

@ -5,8 +5,8 @@
set -e
mkf=config.mk
objs='esv.o esvapi.o util.o initial.o'
srcs='esv.d esvapi.d util.d initial.d'
objs='esvapi.o util.o initial.o'
srcs='esvapi.d util.d initial.d'
# utility functions

5
esv.1
View file

@ -10,7 +10,6 @@
.Op Fl aFfHhNnRrV
.Op Fl c Ar config
.Op Fl l Ar length
.Op Fl s Ar query
.Ar book verses
.Ek
.Sh DESCRIPTION
@ -96,10 +95,6 @@ Include verse numbers (the default).
Exclude passage references.
.It Fl r
Include passage references (the default).
.It Fl s Ar query
Rather than displaying a passage or playing an audio track,
search the Bible for instances of
.Ar query .
.It Fl V
Print the version number and exit.
.El

21
esv.d
View file

@ -45,7 +45,6 @@ int lFlag; /* line length */
bool lFlagSpecified;
bool nFlag, NFlag; /* verse numbers */
bool rFlag, RFlag; /* passage references */
string sFlag; /* search passages */
bool VFlag; /* show version */
int
@ -73,7 +72,6 @@ main(string[] args)
"l", &onLineLength,
"N", &NFlag, "n", &nFlag,
"R", &RFlag, "r", &rFlag,
"s", &sFlag,
"V", &VFlag,
);
} catch (GetOptException e) {
@ -85,14 +83,9 @@ main(string[] args)
return 0;
}
if (sFlag != "") {
/* skip argument validation */
goto config;
}
if (args.length < 3) {
stderr.writefln(
"usage: %s [-aFfHhNnRrV] [-c config] [-l length] [-s query] book verses",
"usage: %s [-aFfHhNnRrV] [-c config] [-l length] book verses",
baseName(args[0]));
return 1;
}
@ -134,8 +127,6 @@ key = %s
die(e.msg);
}
enforceDie(!(aFlag && sFlag), "cannot specify both -a and -s flags");
apiKey = ini["api"].key("key");
enforceDie(apiKey != null,
"API key not present in configuration file; cannot proceed");
@ -168,16 +159,6 @@ key = %s
return 0;
}
if (sFlag) {
try
writeln(esv.searchFormat(sFlag));
catch (ESVException)
die("no results for search");
catch (CurlException e)
die(e.msg);
return 0;
}
esv.extraParameters = ini["api"].key("parameters", "");
/* Get [passage] keys */

110
esvsearch.d Normal file
View file

@ -0,0 +1,110 @@
/*
* esvsearch: search the Bible from your terminal
*
* The GPLv2 License (GPLv2)
* Copyright (c) 2023-2024 Jeremy Baxter
*
* esv is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* esv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with esv. If not, see <http://www.gnu.org/licenses/>.
*/
module esvsearch;
import std.file : FileException;
import std.getopt : getopt, GetOptException;
import std.path : baseName, expandTilde;
import std.process : environment;
import std.stdio : writeln, writefln;
import esvapi;
import initial;
import util;
import cf = config;
@safe:
string cFlag; /* config path */
bool VFlag; /* show version */
int
main(string[] args)
{
string apiKey;
string configPath;
INIUnit ini;
ESVApi esv;
sharedInit(args);
cFlag = null;
/* Parse command-line options */
try {
import std.getopt : config;
getopt(args,
config.bundling,
config.caseSensitive,
"c", &cFlag,
"V", &VFlag,
);
} catch (GetOptException e) {
handleOptError(e.msg);
}
if (VFlag) {
writeln("esvsearch " ~ cf.esvVersion);
return 0;
}
if (args.length < 2) {
stderr.writefln("usage: %s [-l length] query",
baseName(args[0]));
return 1;
}
/* determine configuration file: options take first priority,
* then environment variables, and then the default path */
configPath = environment.get(cf.configEnv, cf.configPath)
.expandTilde();
try {
if (cFlag)
configPath = cFlag.expandTilde();
readINIFile(ini, configPath);
} catch (FileException e) {
/* filesystem syscall errors */
import core.stdc.errno : ENOENT;
if (e.errno != ENOENT)
die(e.msg);
warn(configPath ~ ": no such file or directory");
warn("Invoke esv to create an initial configuration file.");
}
apiKey = ini["api"].key("key");
enforceDie(apiKey != null,
"API key not present in configuration file; cannot proceed");
esv = new ESVApi(apiKey);
try
writeln(esv.searchFormat(args[1]));
catch (ESVException)
die("no results");
catch (CurlException e)
die(e.msg);
return 0;
}