aboutsummaryrefslogtreecommitdiff
path: root/c/pl.c
diff options
context:
space:
mode:
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;
+}