aboutsummaryrefslogtreecommitdiff
path: root/c/pl.c
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-06-02 02:27:43 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-06-02 02:27:43 +0200
commit7f37c580c4e55468ffedba910d01abffe26154f4 (patch)
tree3e50de469d1d871aa77ea23427d6d72d93c3b5cd /c/pl.c
parent5b004563a06dd41e5ba474b82088b5ca516bda85 (diff)
downloadEpisodeBrowser-7f37c580c4e55468ffedba910d01abffe26154f4.tar.gz
Simplify C interface to Prolog.
Diffstat (limited to 'c/pl.c')
-rw-r--r--c/pl.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/c/pl.c b/c/pl.c
new file mode 100644
index 0000000..6f7a07d
--- /dev/null
+++ b/c/pl.c
@@ -0,0 +1,76 @@
+#include <stdarg.h>
+#include <string.h>
+#include <SWI-Prolog.h>
+
+int
+Pl(char *szMod, char *szPred, char *szFmt, ...)
+{
+ int i, iArity;
+ term_t t;
+ va_list vl;
+
+ va_start(vl, szFmt);
+ iArity = strlen(szFmt);
+ t = PL_new_term_refs(iArity);
+
+ for (i = 0; szFmt[i]; i++) {
+ switch (szFmt[i]) {
+ case 'I':
+ {
+ int x;
+ x = va_arg(vl, int);
+ if (!PL_put_integer(t+i, x)) return 0;
+ break;
+ }
+ case 'A':
+ {
+ atom_t x;
+ x = va_arg(vl, atom_t);
+ if (!PL_put_atom(t+i, x)) return 0;
+ break;
+ }
+ case 'S':
+ {
+ atom_t a;
+ char *x;
+ x = va_arg(vl, char *);
+ a = PL_new_atom(x);
+ if (!PL_put_atom(t+i, a)) return 0;
+ break;
+ }
+ }
+ }
+
+ if (!PL_call_predicate(NULL, PL_Q_NORMAL,
+ PL_predicate(szPred, iArity, szMod), t))
+ return 0;
+
+ for (i = 0; szFmt[i]; i++) {
+ switch (szFmt[i]) {
+ case 'i':
+ {
+ int *lp;
+ lp = va_arg(vl, int *);
+ if (!PL_get_integer(t+i, lp)) return 0;
+ break;
+ }
+ case 'a':
+ {
+ atom_t *lp;
+ lp = va_arg(vl, atom_t *);
+ if (!PL_get_atom(t+i, lp)) return 0;
+ break;
+ }
+ case 's':
+ {
+ char **lp;
+ lp = va_arg(vl, char **);
+ if (!PL_get_atom_chars(t+i, lp)) return 0;
+ break;
+ }
+ }
+ }
+
+ va_end(vl);
+ return 1;
+}