#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <epp_pal.h>
#include "swi-internals.h"

int pl_vcall(const char *predicate, const char *params_spec, va_list args) {
    unsigned int arity = params_spec ? strlen(params_spec) : 0;
    predicate_t	p;
    fid_t f;
    term_t a;
    qid_t q;
    int retval;
    
    if (!(pl_is_engine_attached() && pl_is_engine_idle()))
	return(PL_ERROR_PAL);
    
    if (!(f = PL_open_foreign_frame()))
	return(PL_ERROR_PAL);

    p = PL_predicate(predicate, arity, NULL);

    if (arity) {
	a = PL_new_term_refs(arity);
	
	if (!__swi_put_params(params_spec, a, args) || !a) {
	    q = PL_open_query(NULL, PL_Q_NORMAL, p, a);
	    retval = PL_next_solution(q);
	
	    if (PL_exception(q))
		retval = PL_ERROR_PROLOG;
	
	    PL_cut_query(q);
	    __swi_get_params(params_spec, a, args);
	} else {
	    retval = PL_ERROR_PAL;
	}
    } else {
	q = PL_open_query(NULL, PL_Q_NORMAL, p, 0);
	retval = PL_next_solution(q);
	
	if (PL_exception(q))
	    retval = PL_ERROR_PROLOG;
	
	PL_cut_query(q);
    }
    
    PL_close_foreign_frame(f);
    return(retval);

}

int pl_call(const char *predicate, const char *params_spec, ...) {
    int retval;
    va_list vl;

    va_start(vl, params_spec);
    retval = pl_vcall(predicate, params_spec, vl);
    va_end(vl);

    return(retval);
}
