Beispiel #1
0
static int conj_size(term_t source) {
  if (PL_is_functor(source, FUNCTOR_comma2)) {
    term_t a1 = PL_new_term_ref(), a2 = PL_new_term_ref();
    if (PL_get_arg(1, source, a1) <= 0 || PL_get_arg(2, source, a2) <= 0)
      return -1;
    return conj_size(a1) + conj_size(a2);
  }
  return 1;
}
Beispiel #2
0
static void
call_prolog_goal(prolog_goal *g)
{ fid_t fid;
  static predicate_t pred = NULL;
  int rc;

  if ( !pred )
    pred = PL_predicate("call", 1, "user");

  if ( (fid = PL_open_foreign_frame()) )
  { term_t t = PL_new_term_ref();
    term_t vars;
    rc = PL_recorded(g->goal, t);
    PL_erase(g->goal);
    g->goal = 0;
    g->state = G_RUNNING;
    if ( rc )
    { qid_t qid;
      int flags = PL_Q_NORMAL;

      if ( g->acknowledge )
      { flags |= PL_Q_CATCH_EXCEPTION;
	vars = PL_new_term_ref();
	if ( !PL_get_arg(2, t, vars) ||		/* Goal-Vars */
	     !PL_get_arg(1, t, t) )
	{ PL_warning("ERROR: in_pce_thread: bad goal-vars term");
	}
      } else
      { vars = 0;
      }

      if ( (qid = PL_open_query(g->module, flags, pred, t)) )
      { rc = PL_next_solution(qid);

	if ( rc )
	{ g->state = G_TRUE;
	  if ( vars )
	    g->result = PL_record(vars);
	} else
	{ term_t ex;

	  if ( g->acknowledge && (ex=PL_exception(qid)) )
	  { g->result = PL_record(ex);
	    g->state = G_ERROR;
	  } else
	  { g->state = G_FALSE;
	  }
	}

	PL_cut_query(qid);
      } else
	PL_warning("ERROR: pce: out of global stack");
    }
    PL_discard_foreign_frame(fid);
  } else
    PL_warning("ERROR: pce: out of global stack");
}
Beispiel #3
0
static int python_import(term_t mname, term_t mod) {
  PyObject *pName, *pModule;
  term_t arg = PL_new_term_ref();
  char s0[MAXPATHLEN], *s = s0;

  while (true) {
    size_t len;

    len = (MAXPATHLEN - 1) - (s - s0);
    if (PL_is_pair(mname)) {
      char *sa;
      if (!PL_get_arg(1, mname, arg) || !PL_get_atom_chars(arg, &sa) ||
          !PL_get_arg(2, mname, mname)) {
        return false;
      }
      s = stpcpy(s, sa);
      *s++ = '.';
      s[0] = '\0';
    } else if (!PL_get_nchars(mname, &len, &s,
                              CVT_ALL | CVT_EXCEPTION | REP_UTF8)) {
      {
        return false;
      }
    } else {
      break;
    }
  }
#if PY_MAJOR_VERSION < 3
  pName = PyString_FromString(s0);
#else
  pName = PyUnicode_FromString(s0);
#endif
  if (pName == NULL) {
    {
      return false;
    }
  }
  pModule = PyImport_Import(pName);
  PyErr_Clear();
  Py_DECREF(pName);
  if (pModule == NULL) {
#if EXTRA_MESSSAGES
    if (PyErr_Occurred())
      PyErr_Print();
    PyErr_Clear();
#endif
    {
      return false;
    }
  }
  ActiveModules[active_modules++] = pModule;
  {    foreign_t rc = python_to_ptr(pModule, mod);
    return rc;
  }
}
Beispiel #4
0
static int conj_copy(term_t target, PyObject *e, int pos) {
  if (PL_is_functor(target, FUNCTOR_comma2)) {
    term_t a1 = PL_new_term_ref(), a2 = PL_new_term_ref();
    if (PL_get_arg(1, target, a1) <= 0 || PL_get_arg(2, target, a2) <= 0)
      return -1;
    int p1 = conj_copy(a1, e, pos);
    return conj_copy(a2, e, p1);
  } else {
    assign_python(py_Main, target, PyTuple_GetItem(e, pos));
    return pos + 1;
  }
}
Beispiel #5
0
static int
put_write_options(term_t opts_in, write_options *options)
{ GET_LD
  term_t newlist = PL_new_term_ref();
  term_t precopt = PL_new_term_ref();
  fid_t fid = PL_open_foreign_frame();
  term_t head = PL_new_term_ref();
  term_t tail = PL_copy_term_ref(opts_in);
  term_t newhead = PL_new_term_ref();
  term_t newtail = PL_copy_term_ref(newlist);
  int rc = TRUE;

  while(rc && PL_get_list(tail, head, tail))
  { if ( !PL_is_functor(head, FUNCTOR_priority1) )
      rc = ( PL_unify_list(newtail, newhead, newtail) &&
	     PL_unify(newhead, head) );
  }

  if ( rc )
  { rc = ( PL_unify_list(newtail, head, newtail) &&
	   PL_unify_functor(head, FUNCTOR_priority1) &&
	   PL_get_arg(1, head, precopt) &&
	   PL_unify_nil(newtail) );
  }
  if ( rc )
  { options->write_options = newlist;
    options->prec_opt = precopt;
  }

  PL_close_foreign_frame(fid);
  return rc;
}
Beispiel #6
0
static PyObject *bip_int(term_t t) {
  PyObject *pVal, *o;

  if (!PL_get_arg(1, t, t))
    return NULL;
  pVal = term_to_python(t, true);
#if PY_MAJOR_VERSION < 3
  if (PyLong_Check(pVal)) {
    o = PyInt_FromLong(PyLong_AsLong(pVal));
  } else if (PyInt_Check(pVal)) {
    return pVal;
#else
  if (PyLong_Check(pVal)) {
    return pVal;
#endif
  } else if (PyFloat_Check(pVal)) {
#if PY_MAJOR_VERSION < 3
    o = PyInt_FromLong(PyFloat_AsDouble(pVal));
#else
    o = PyLong_FromDouble(PyFloat_AsDouble(pVal));
#endif
  } else
    return NULL;
  Py_DECREF(pVal);
  return o;
}

static PyObject *bip_long(term_t t) {
  PyObject *pVal, *o;

  if (!PL_get_arg(1, t, t))
    return NULL;
  pVal = term_to_python(t, true);
  if (PyLong_Check(pVal)) {
    return pVal;
#if PY_MAJOR_VERSION < 3
  } else if (PyInt_Check(pVal)) {
    o = PyLong_FromLong(PyInt_AsLong(pVal));
#endif
  } else if (PyFloat_Check(pVal)) {
    o = pVal;
  } else
    return NULL;
  Py_DECREF(pVal);
  return o;
}
Beispiel #7
0
static PyObject *bip_iter(term_t t) {
  PyObject *v;

  if (!PL_get_arg(1, t, t))
    return NULL;
  v = term_to_python(t, true);
  return PyObject_GetIter(v);
}
Beispiel #8
0
static PyObject *bip_bin(term_t t) {
  PyObject *v;

  if (!PL_get_arg(1, t, t))
    return NULL;
  v = term_to_python(t, true);
  return PyNumber_ToBase(v, 2);
}
Beispiel #9
0
static foreign_t
pl_setopt(term_t Socket, term_t opt)
{ int socket;
  atom_t a;
  int arity;

  if ( !tcp_get_socket(Socket, &socket) )
    return FALSE;

  if ( PL_get_name_arity(opt, &a, &arity) )
  { if ( a == ATOM_reuseaddr && arity == 0 )
    { if ( nbio_setopt(socket, TCP_REUSEADDR, TRUE) == 0 )
	return TRUE;

      return FALSE;
    } else if ( a == ATOM_nodelay && arity <= 1 )
    { int enable, rc;

      if ( arity == 0 )
      { enable = TRUE;
      } else /*if ( arity == 1 )*/
      { term_t a = PL_new_term_ref();

	_PL_get_arg(1, opt, a);
	if ( !PL_get_bool(a, &enable) )
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "boolean");
      }

      if ( (rc=nbio_setopt(socket, TCP_NO_DELAY, enable) == 0) )
	return TRUE;
      if ( rc == -2 )
	goto not_implemented;

      return FALSE;
    } else if ( a == ATOM_broadcast && arity == 0 )
    { if ( nbio_setopt(socket, UDP_BROADCAST, TRUE) == 0 )
	return TRUE;

      return FALSE;
    } else if ( a == ATOM_dispatch && arity == 1 )
    { int val;
      term_t a1 = PL_new_term_ref();

      if ( PL_get_arg(1, opt, a1) && PL_get_bool(a1, &val) )
      { if ( nbio_setopt(socket, TCP_DISPATCH, val) == 0 )
	  return TRUE;
	return FALSE;
      }
    } else if ( a == ATOM_nonblock && arity == 0 )
    { if ( nbio_setopt(socket, TCP_NONBLOCK) == 0 )
	return TRUE;
      return FALSE;
    }
  }

not_implemented:
  return pl_error(NULL, 0, NULL, ERR_DOMAIN, opt, "socket_option");
}
Beispiel #10
0
static PyObject *bip_abs(term_t t) {
  PyObject *pVal, *nVal;

  if (!PL_get_arg(1, t, t))
    return NULL;
  pVal = term_to_python(t, true);
  nVal = PyNumber_Absolute(pVal);
  Py_DecRef(pVal);
  return nVal;
}
Beispiel #11
0
// parse a list of Prolog terms and add arguments to an OSC message 
static int add_msg_args(lo_message msg, term_t list)
{
	term_t 	head=PL_new_term_ref();

	// copy term ref so as not to modify original
	list=PL_copy_term_ref(list);

	while (PL_get_list(list,head,list)) {
		atom_t name;
		int	 arity;
		const char  *type;

		if (!PL_get_name_arity(head,&name,&arity)) return type_error(head,"term");
		type=PL_atom_chars(name);
		switch (arity) {
		case 1: {
				term_t a1=PL_new_term_ref();
				PL_get_arg(1,head,a1);

				if (!strcmp(type,"int")) {
					int x;
					if (!PL_get_integer(a1,&x)) return type_error(a1,"integer");
					lo_message_add_int32(msg,x);
				} else if (!strcmp(type,"double")) {
					double x;
					if (!PL_get_float(a1,&x)) return type_error(a1,"float");
					lo_message_add_double(msg,x);
				} else if (!strcmp(type,"string")) {
					char *x;
					if (!PL_get_chars(a1,&x,CVT_ATOM|CVT_STRING)) return type_error(a1,"string");
					lo_message_add_string(msg,x);
				} else if (!strcmp(type,"symbol")) {
					char *x;
					if (!PL_get_chars(a1,&x,CVT_ATOM)) return type_error(a1,"atom");
					lo_message_add_symbol(msg,x);
				} else if (!strcmp(type,"float")) {
					double x;
					if (!PL_get_float(a1,&x)) return type_error(a1,"float");
					lo_message_add_float(msg,(float)x);
				}
				break;
			}
		case 0: {
				if (!strcmp(type,"true")) lo_message_add_true(msg);
				else if (!strcmp(type,"false")) lo_message_add_false(msg);
				else if (!strcmp(type,"nil")) lo_message_add_nil(msg);
				else if (!strcmp(type,"inf")) lo_message_add_infinitum(msg);
				break;
			}
		}
	}
	if (!PL_get_nil(list)) return type_error(list,"nil");
	return TRUE;
}
Beispiel #12
0
/** assign a tuple to something:
*/
static foreign_t python_assign_tuple(term_t t_lhs, term_t t_rhs) {
  PyObject *e;
  Py_ssize_t sz;
  functor_t f;

  e = term_to_python(t_rhs, true);
  if (!e || !PyTuple_Check(e)) {
    return -1;
  }
  sz = PyTuple_Size(e);
  switch (PL_term_type(t_lhs)) {
  case PL_VARIABLE:
    return PL_unify(t_lhs, t_rhs);
  case PL_ATOM:
    return assign_python(py_Main, t_rhs, e);
  case PL_TERM:
    if (PL_get_functor(t_lhs, &f)) {
      term_t targ = PL_new_term_ref();
      // assign a tuple to a tuple
      if (PL_functor_name(f) == ATOM_t && ((sz = PL_functor_arity(f)))) {
        Py_ssize_t i;
        for (i = 0; i < sz; i++) {
          PL_get_arg(i + 1, t_lhs, targ);
          assign_python(py_Main, targ, PyTuple_GetItem(e, i));
        }
      } else if (PL_functor_name(f) == ATOM_comma) {
        int n = conj_size(t_lhs);
        if (n != sz)
          return -1;
        return conj_copy(t_lhs, e, 0);
      } else if (PL_functor_name(f) == ATOM_dot) { // vectors
        size_t len;
        term_t tail = PL_new_term_ref();

        PL_skip_list(t_lhs, tail, &len);
        if (!PL_get_nil(tail))
          return -1;
        term_t arg = tail;
        size_t i;

        for (i = 0; i < len; i++) {
          if (!PL_get_list(t_rhs, arg, t_rhs)) {
            return -1;
          }
          if (assign_python(py_Main, arg, PyTuple_GetItem(e, i)) < 0)
            return -1;
        }
      }
    }
  }
  return -1;
}
Beispiel #13
0
PyObject *term_to_nametuple(const char *s, int arity, term_t t) {
  PyObject *o;
#if PY_MAJOR_VERSION >= 3
  PyTypeObject *typp;
  PyObject *key = PyUnicode_FromString(s);
  if (py_F2P && PyDict_Contains(py_F2P, key)) {
    typp = (PyTypeObject *)PyDict_GetItem(py_F2P, key);
  } else {

    typp = PyMem_Malloc(sizeof(PyTypeObject));
    PyStructSequence_Desc *desc = PyMem_Malloc(sizeof(PyStructSequence_Desc));

    desc->name = PyUnicode_AsUTF8(key);
    desc->doc = "YAPTerm";
    desc->fields = pnull;
    desc->n_in_sequence = 32;
    if (PyStructSequence_InitType2(typp, desc) < 0)
      return NULL;
    typp->tp_str = structseq_str;
    typp->tp_repr = structseq_repr;
    //     typp = PyStructSequence_NewType(desc);
    Py_INCREF(typp);
    //	typp->tp_flags |= Py_TPFLAGS_HEAPTYPE;
    PyModule_AddObject(py_Yapex, s, (PyObject *)typp);
    if (py_F2P)
      PyDict_SetItem(py_F2P, key, (PyObject *)typp);
  }
  o = PyTuple_New(typp);
#else
  o = PyTuple_New(arity);
#endif
  term_t tleft = PL_new_term_ref();
  int i;

  for (i = 0; i < arity; i++) {
    PyObject *pArg;
    if (!PL_get_arg(i + 1, t, tleft))
      return NULL;
    pArg = term_to_python(tleft, false);
    if (pArg == NULL)
      return NULL;
#if PY_MAJOR_VERSION >= 3
    /* pArg reference stolen here: */
    PyStructSequence_SET_ITEM(o, i, pArg);
  }
  ((PyStructSequence *)o)->ob_base.ob_size = arity;
  return o;
#else
    /* pArg reference stolen here: */
    PyTuple_SET_ITEM(o, i, pArg);
  }
Beispiel #14
0
static foreign_t python_field(term_t parent, term_t att, term_t tobj) {
  PyObject *pF;
  atom_t name;
  char *s;
  int arity;

  if (!PL_get_name_arity(att, &name, &arity)) {
    {
      return false;
    }
  } else {
    PyObject *p;

    // got Scope.Exp
    // get Scope ...
    p = term_to_python(parent, true);
    // Exp
    if (!PL_get_name_arity(att, &name, &arity)) {
      {
        return false;
      }
    }
    s = PL_atom_chars(name);
    if (arity == 1 && !strcmp(s, "()")) {
      if (!PL_get_arg(1, att, att)) {
        return false;
      }
      if (!PL_get_name_arity(att, &name, &arity)) {
        {
          return false;
        }
      }
      s = PL_atom_chars(name);
    }
    if (!s || !p) {
      {
        return false;
      }
    } else if ((pF = PyObject_GetAttrString(p, s)) == NULL) {
      PyErr_Clear();
      {
        return false;
      }
    }
  }
  {
    foreign_t rc;
    rc = address_to_term(pF, tobj);
    return rc;
  }
}
Beispiel #15
0
/*
	lookup_ht(HT,Key,Values) :-
		term_hash(Key,Hash),
		HT = ht(Capacity,_,Table),
		Index is (Hash mod Capacity) + 1,
		arg(Index,Table,Bucket),
		nonvar(Bucket),
		( Bucket = K-Vs ->
		    K == Key,	
		    Values = Vs
		;
		    lookup(Bucket,Key,Values)
		).

	lookup([K - V | KVs],Key,Value) :-
		( K = Key ->
			V = Value
		;
			lookup(KVs,Key,Value)
		).
*/
static foreign_t
pl_lookup_ht1(term_t ht, term_t pl_hash, term_t key, term_t values)
{
  int capacity;
  int hash;
  int index;

  term_t pl_capacity = PL_new_term_ref();
  term_t table       = PL_new_term_ref();
  term_t bucket      = PL_new_term_ref();

  /* HT = ht(Capacity,_,Table) */
  PL_get_arg(1, ht, pl_capacity);
  PL_get_integer(pl_capacity, &capacity);
  PL_get_arg(3, ht, table);

  /* Index is (Hash mod Capacity) + 1 */
  PL_get_integer(pl_hash, &hash);
  index = (hash % capacity) + 1;  

  /* arg(Index,Table,Bucket) */
  PL_get_arg(index, table, bucket);

  /* nonvar(Bucket) */ 
  if (PL_is_variable(bucket)) PL_fail;  

  if (PL_is_list(bucket)) {
  	term_t pair	     = PL_new_term_ref();
  	term_t k	     = PL_new_term_ref();
	term_t vs	     = PL_new_term_ref();
	while (PL_get_list(bucket, pair,bucket)) {
  		PL_get_arg(1, pair, k);
		if ( PL_compare(k,key) == 0 ) {
      			/* Values = Vs */
			PL_get_arg(2, pair, vs);
			return PL_unify(values,vs);
		}
	}
	PL_fail;
  } else {
  	term_t k	     = PL_new_term_ref();
	term_t vs	     = PL_new_term_ref();
  	PL_get_arg(1, bucket, k);
        /* K == Key */	
	if ( PL_compare(k,key) == 0 ) {
      		/* Values = Vs */
		PL_get_arg(2, bucket, vs);
		return PL_unify(values,vs);
	} else {
		PL_fail;
	}
  }
}
Beispiel #16
0
static foreign_t
pl_tipc_bind(term_t Socket, term_t Address, term_t opt)
{ struct sockaddr_tipc sockaddr;
  size_t addrlen = sizeof(sockaddr);
  int socket;
  atom_t a;
  int arity;

  memset(&sockaddr, 0, sizeof(sockaddr));

  if ( !tipc_get_socket(Socket, &socket) ||
       !nbio_get_tipc_sockaddr(Address, &sockaddr) )
    return FALSE;

  if ( PL_get_name_arity(opt, &a, &arity) )
  { if ( (a == ATOM_scope || a == ATOM_no_scope) && arity == 1 )
    { atom_t val;
      term_t a1 = PL_new_term_ref();

      if (PL_get_arg(1, opt, a1))
      { signed char ival = 0;

	if ( !PL_get_atom(a1, &val) )
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "atom");

	if ( val == ATOM_zone )
	  ival = TIPC_ZONE_SCOPE;
	else if ( val == ATOM_cluster )
	  ival = TIPC_CLUSTER_SCOPE;
	else if ( val == ATOM_node )
	  ival = TIPC_NODE_SCOPE;
	else if ( val == ATOM_all && a == ATOM_no_scope)
	  addrlen = 0;
	else
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "node, cluster, or zone");

	sockaddr.scope = (a == ATOM_scope) ? ival
                                           : -ival;

	if ( nbio_bind(socket, (struct sockaddr*)&sockaddr, addrlen) < 0 )
	  return FALSE;
      }
    } else
      return pl_error(NULL, 0, NULL, ERR_ARGTYPE, 1, opt, "scoping option");

      return TRUE;
  }

  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "scope/1");
}
Beispiel #17
0
static foreign_t python_export(term_t t, term_t pl) {
  foreign_t rc = false;
  if (PL_is_functor(t, FUNCTOR_pointer1)) {
    void *ptr;
    term_t targ = PL_new_term_ref();

    if (!PL_get_arg(1, t, targ)) {
      return false;
    }
    if (!PL_get_pointer(targ, &ptr)) {
      return false;
    }
    Py_INCREF((PyObject *)ptr);
    /* return __main__,s */
    rc = python_to_term((PyObject *)ptr, pl);
  }
  return rc;
}
Beispiel #18
0
/* todo */
void parse_validate_args(term_t args, EtalisEvent* event)
{
    event->args = malloc(sizeof(int)*event->RootModel->event.arity);
    int arity;
    PL_get_name_arity(args, NULL, &arity);
    term_t arg_terms = PL_new_term_refs(arity);
    /* assuming that all arguments are ints */ /* todo implement for other types */


    size_t arg_iterator;
    for(arg_iterator=0;arg_iterator<event->RootModel->event.arity;arg_iterator++)
    {
        PL_get_arg(arg_iterator+1,args,arg_terms+arg_iterator);
        PL_get_integer(arg_terms+arg_iterator,(int*)event->args+arg_iterator);

    }

}
Beispiel #19
0
static PyObject *bip_float(term_t t, bool eval) {
  PyObject *pVal, *o;

  if (!PL_get_arg(1, t, t))
    return NULL;
  pVal = term_to_python(t, eval);
  if (PyLong_Check(pVal)) {
    o = PyFloat_FromDouble(PyLong_AsLong(pVal));
#if PY_MAJOR_VERSION < 3
  } else if (PyInt_Check(pVal)) {
    o = PyFloat_FromDouble(PyInt_AsLong(pVal));
#endif
  } else if (PyFloat_Check(pVal)) {
    return pVal;
  } else
    return NULL;
  Py_DECREF(pVal);
  return o;
}
Beispiel #20
0
static PyObject *bip_ord(term_t t) {
  PyObject *pVal;
  Py_ssize_t size;

  if (!PL_get_arg(1, t, t))
    return NULL;
  pVal = term_to_python(t, true);
  if (PyUnicode_Check(pVal)) {
#if PY_MAJOR_VERSION < 3
    size = PyUnicode_GET_SIZE(pVal);
#else
    size = PyUnicode_GetLength(pVal);
#endif
    if (size == 1) {
#if PY_MAJOR_VERSION < 3
      long ord = (long)*PyUnicode_AS_UNICODE(pVal);
      return PyInt_FromLong(ord);
#else
      Py_UCS4 ord = PyUnicode_ReadChar(pVal, 0);
      return PyLong_FromLong(ord);
#endif
    }
    return NULL;
  } else if (PyByteArray_Check(pVal)) {
    char *s = PyByteArray_AsString(pVal);

    if (s[1])
      return NULL;
#if PY_MAJOR_VERSION < 3
    return PyInt_FromLong(s[0]);
  } else if (PyString_Check(pVal)) {
    char *s = PyString_AsString(pVal);

    if (s[1])
      return NULL;
    return PyInt_FromLong(s[0]);
#else
    return PyLong_FromLong(s[0]);
#endif
  } else
    return NULL;
}
Beispiel #21
0
/**
* Python all
*
* @param t Prolog term with a previously constructed Python iterator
*
* @return the Python boolean `True` if all elements of the iterator are `True`,
*    `False`  otherwise.
*/
static PyObject *bip_all(term_t t) {
  PyObject *it, *item, *v;
  PyObject *(*iternext)(PyObject *);
  int cmp;

  if (!PL_get_arg(1, t, t))
    return NULL;
  v = term_to_python(t, true);
  it = PyObject_GetIter(v);
  if (it == NULL)
    return NULL;
  iternext = *Py_TYPE(it)->tp_iternext;

  //  PyObject_Print(v, stderr, 0);
  for (;;) {
    item = iternext(it);
    if (item == NULL)
      break;
    cmp = PyObject_IsTrue(item);
    Py_DECREF(item);
    if (cmp < 0) {
      Py_DECREF(it);
      return NULL;
    }
    if (cmp == 0) {
      Py_DECREF(it);
      return Py_False;
    }
  }
  Py_DECREF(it);
  if (PyErr_Occurred()) {
    if (PyErr_ExceptionMatches(PyExc_StopIteration))
      PyErr_Clear();
    else
      return NULL;
  }
  return Py_True;
}
Beispiel #22
0
static int
get_echars_arg_ex(int i, term_t from, term_t arg, echar **sp, size_t *lenp)
{ const echar *s, *e;

  if ( !PL_get_arg(i, from, arg) )
    return FALSE;

#ifdef __WINDOWS__
  if ( !PL_get_wchars(arg, lenp, sp,
		      CVT_ATOMIC|CVT_EXCEPTION) )
#else
  if ( !PL_get_nchars(arg, lenp, sp,
		      CVT_ATOMIC|CVT_EXCEPTION|REP_FN) )
#endif
    return FALSE;

  for(s = *sp, e = s+*lenp; s<e; s++)
  { if ( !*s )
      return domain_error(arg, "text_non_zero_code");
  }

  return TRUE;
}
Beispiel #23
0
/* General structure of a rule :

[Rule_Label] ComplexEvent <- CEP_Clause [WHERE_Clause] [WITHIN_Clause]

*/
void construct_rule(EtalisBatch* batch,term_t term)
{

    EtalisExecNode* NodeRule = batch->nodes;
    assert(NodeRule != NULL);

    atom_t cep_name;
    int temp_arity;
    int i=0;
    int LUT_Size=2;



#ifdef DEBUG
    printf("--- Constructing rule: \n");
#endif




    /* WITHIN Clause */

    parse_within_op_(NodeRule,term); /*TODO Add a check that a within is explicitely stated in the rule */

    /* WHERE Clause */

    parse_where_op_(NodeRule,term);



    /* CEP Clause */

    term_t cep_term = PL_new_term_refs(2);
    if(NodeRule->has_condition == ETALIS_TRUE)
    {
        term_t first_level_term = PL_new_term_refs(2);
        PL_get_arg(1,term,first_level_term);
        PL_get_arg(1,first_level_term,cep_term);
    }
    else
        PL_get_arg(1,term,cep_term);
    PL_get_name_arity(cep_term, &cep_name, &temp_arity);
    char* aaa = PL_atom_chars(cep_name);

    /* find the right CEP operator */
    while(strcmp(CEP_LUT_[i].CEP_name,PL_atom_chars(cep_name)) != 0 && i<LUT_Size) i++;
    NodeRule->left_exec.exec_1=CEP_LUT_[i].exec1.exec_1;
    NodeRule->right_exec.exec_1=CEP_LUT_[i].exec2.exec_1;

    if(i != LUT_Size) /*The operator is found in the CEP_LUT_*/
    {
        switch (CEP_LUT_[i].CEP_arity)
        {
        case 1:
            NodeRule->op_type=unary;
            strcpy(NodeRule->name,CEP_LUT_[i].CEP_name);
            NodeRule->left_exec.exec_1=CEP_LUT_[i].exec1.exec_1;

            break;
        case 2:
            NodeRule->op_type=binary;
            strcpy(NodeRule->name,CEP_LUT_[i].CEP_name);
            NodeRule->left_exec.exec_1=CEP_LUT_[i].exec1.exec_1;
            NodeRule->right_exec.exec_1=CEP_LUT_[i].exec2.exec_1;
            CEP_LUT_[i].parser_func(NodeRule,cep_term);
            break;
        default:
            printf("error compiling the rules\n");
        }
    }
    else  /*no operator is found : identity operator is assumed*/
    {
        NodeRule->op_type=unary;
        strcpy(NodeRule->name,"identity");
        NodeRule->left_exec.exec_1=_cep_identity;
        default_op_parser(NodeRule,cep_term);
    }


    /* triggering an event should execute the correct function*/ /* deprecated */
    /*
    NodeRule->leftChild->trigger=NodeRule->left_exec.exec_1;
    if(NodeRule->op_type == binary)
        NodeRule->rightChild->trigger=NodeRule->right_exec.exec_1;
    */

    /* setting the tree connections between the events and the CEP operator */
    NodeRule->leftChild->parentNode=NodeRule;
    if(NodeRule->op_type == binary)
        NodeRule->rightChild->parentNode=NodeRule;


    /** Propagate the WHERE Clauses */
    where_binarization(NodeRule);


}
Beispiel #24
0
void parse_seq_op_ (EtalisExecNode* operatorNode,term_t t)
{

    assert(operatorNode != NULL);

    fid_t fid = PL_open_foreign_frame();


    /*get components of the operator*/

    term_t _level_1 = PL_new_term_refs(2);
    term_t _left_event=_level_1;
    term_t _right_event=_level_1+1;
    atom_t _left_event_name,_right_event_name;

    int temp_arity,i=0;

    /* TODO check for embedded operators, if operator -> parse right function ; else get atomic events */
    PL_get_arg(1,t,_left_event);
    PL_get_name_arity(_left_event,&_left_event_name,&temp_arity);

    char * tt = PL_atom_chars(_left_event_name);
    i=0;
    while(strcmp(CEP_LUT_[i].CEP_name,PL_atom_chars(_left_event_name)) != 0 && i<LUT_Size) i++; /* #CONT */

     if(i != LUT_Size) /*The operator is found in the CEP_LUT_*/ /* create a temp event */
    {
        EtalisEventNode* TempEvent = (EtalisEventNode*)calloc(1,sizeof(EtalisEventNode)); /* this temp event is the complex event of the embedded operation */
        TempEvent->event.arity = 0;

        strcpy(TempEvent->event.name,"temp_"); /* TODO Temp Events */ /* Temp Events have no arguments */
        TempEvent->parentNode = operatorNode;
        strcpy(TempEvent->parentNode->name,tt);
        TempEvent->is_temp = ETALIS_TRUE;
        operatorNode->leftChild = TempEvent;

        EtalisExecNode* NewNodeRule = (EtalisExecNode*)calloc(1,sizeof(EtalisExecNode)); /* binarization and allocation of the embedded operator */
        TempEvent->childNode  = NewNodeRule;
        NewNodeRule->parentEvent = TempEvent;
        TempEvent->trigger = _seq_win_cep_l;
        switch (CEP_LUT_[i].CEP_arity)
        {
        case 1:
            break;
        case 2:
            /* found embedded */
            CEP_LUT_[i].parser_func(NewNodeRule,_left_event);
            break;
        default:
            printf("error compiling the rules\n");
        }
    }
    else /* an atomic event has been found */
    {
        operatorNode->leftChild = (EtalisEventNode*) calloc(1,sizeof(EtalisEventNode));
        PL_get_name_arity(_left_event,&_left_event_name,(int *)&((operatorNode->leftChild)->event.arity));
        strcpy(operatorNode->leftChild->event.name,PL_atom_chars(_left_event_name));
        operatorNode->leftChild->childNode = NULL;
        operatorNode->leftChild->parentNode=operatorNode;
        operatorNode->leftChild->is_temp = ETALIS_FALSE;

        if (operatorNode->parentEvent->is_temp)
                strcat(operatorNode->parentEvent->event.name,operatorNode->leftChild->event.name);

        operatorNode->leftChild->trigger = _seq_win_cep_l;

    }

    PL_get_arg(2,t,_right_event);

    operatorNode->rightChild = (EtalisEventNode*) calloc(1,sizeof(EtalisEventNode));
    PL_get_name_arity(_right_event,&_right_event_name,(int *)&(operatorNode->rightChild->event.arity));
    strcpy(operatorNode->rightChild->event.name,PL_atom_chars(_right_event_name));
    operatorNode->rightChild->childNode = NULL;
    operatorNode->rightChild->parentNode = operatorNode;
    operatorNode->rightChild->is_temp = ETALIS_FALSE;
    PL_discard_foreign_frame(fid);

    if (operatorNode->parentEvent->is_temp)
    {
            strcat(operatorNode->parentEvent->event.name,operatorNode->rightChild->event.name);
            operatorNode->rightChild->trigger = _seq_win_cep_l;
    }
    else /* event is latest event in the call list */
    {
        operatorNode->rightChild->trigger = _seq_batch_r;
    }




    ;
}
Beispiel #25
0
/* parse the time window constraints */
void parse_within_op_(EtalisExecNode* operatorNode,term_t t)
{

    assert(operatorNode != NULL);

    fid_t fid = PL_open_foreign_frame();


    EtalisEventNode* opt_t = (EtalisEventNode*)malloc(2*sizeof(EtalisEventNode)); /* memory alignement for L1 cache optimization */
    operatorNode->leftChild=opt_t;
    memset(operatorNode->leftChild,0,sizeof(EtalisEventNode));
    operatorNode->rightChild=opt_t+1;
    operatorNode->condition=NULL;

    /* get window size */

    term_t winsize = PL_new_term_ref();
    PL_get_arg(2,t,winsize);

    WINDOW_SIZE_T i; /*get window size*/ /* depending on the target processor, this might be an int, a double or a structure. */ /* defined in WINDOW_SIZE_T : e_time.h */

#if PROCESSOR_SUPPORTS_DOUBLE ==1
    if (PL_term_type(winsize) == PL_FLOAT)
        PL_get_float(winsize,&i);
        else
        printf("ERROR: window Size must be a floating number ! \n");
#else /* we don't support double accuracy, fall back to int */
        PL_get_integer(winsize, &i);
#endif
    operatorNode->window_size=i;

#ifdef DEBUG
    printf("--- WITHIN Block detected | Window size: %f\n",i);
#endif










/*

    term_t _level_1 = PL_new_term_refs(3);
    term_t _left_event=_level_1+1;
    term_t _right_event=_level_1+2;
    atom_t _left_event_name,_right_event_name;




    PL_get_arg(1,t,_level_1);
    PL_get_arg(1,_level_1,_left_event);
    PL_get_arg(2,_level_1,_right_event);
    PL_get_name_arity(_left_event,&_left_event_name,(int*)&((operatorNode->leftChild)->event.arity));
    PL_get_name_arity(_right_event,&_right_event_name,(int*)&(operatorNode->rightChild->event.arity));

    PL_discard_foreign_frame(fid);
    strcpy(operatorNode->leftChild->event.name,PL_atom_chars(_left_event_name));
    strcpy(operatorNode->rightChild->event.name,PL_atom_chars(_right_event_name));
    }



*/



}
Beispiel #26
0
/*
 * parse a where clause and add the information into the ExecNode.
 * TODO #hafsi#5#
 * TODO implement a non binary, rule wide WHERE clause parser and interpreter.
 *
 */
void parse_where_op_(EtalisExecNode* operatorNode, term_t t)
{
    /* find out whether a where clause is used */
    term_t constraints = PL_new_term_refs(3);
    atom_t wheref;
    int arr;
    ETALIS_BOOL where_available=0;


    PL_get_arg(1,t,constraints);
    PL_get_name_arity(constraints,&wheref,&arr);


    char* gg = (char*)malloc(sizeof(char)*256);
    memset(gg,0,256);
    gg = PL_atom_chars(wheref);

    if(!strcmp(gg,"wheref")) where_available = ETALIS_TRUE;

    if(where_available)
    {


        /* process where clause */

        /*

        A = eventClause(unlabeled, e2(_G321, _G322, _G323, _G324), withinop(wheref(seqf(a(_G321, _G322), d(_G323, _G324)), conditions), 2.0))

        */

        operatorNode->whereNode =(EtalisWhereNode*)malloc(sizeof(EtalisWhereNode));
        memset(operatorNode->whereNode,0,sizeof(EtalisWhereNode));

        term_t _where_level_1 = PL_new_term_refs(2);
        term_t  rule_gut_term = _where_level_1+1;
        term_t  constraints_term = _where_level_1+2;

        PL_get_arg(1,t,_where_level_1);

        PL_get_arg(1,_where_level_1,rule_gut_term);
        PL_get_arg(2,_where_level_1,constraints_term);

#ifdef DEBUG
        char* testing = (char*)malloc(sizeof(char)*256);
        char* args = (char*)malloc(sizeof(char)*256);
        *args="\0";
        memset(testing,0,256);

        int size_contraints,idx=0;

        PL_get_name_arity(constraints_term,NULL,&size_contraints);
        termToStringVerbatim(_where_level_1,testing,args);

        /*
       wheref(seqf(seqf(a(_G1776),b(_G1778)),c(_G1780)),,(>(_G1776,1),<(_G1778,2)))
        */
        int j=strlen(testing);
        int num_=0;
        for (j=strlen(testing)-2;j>0;j--)
        {

            if (testing[j] == ')') num_++;
            if (testing[j] == '(') num_--;
            /*printf("%c : %d : %d\n",testing[j],j,num_);*/
            if(num_ == 0 ) break;

        }

        char* real_constr = testing + j ;


        printf("--- WHERE Block detected | Constraints: %s \n",real_constr);

#endif



        operatorNode->has_condition=ETALIS_TRUE;
        }
    else /* no constraints are detected */
    {
        /*get atomic events of the operator*/

        /*

        A = eventClause(unlabeled, e2(_G321, _G322, _G323, _G324), withinop(seqf(a(_G321, _G322), d(_G323, _G324)), 2.0)).

        */

    operatorNode->has_condition=ETALIS_FALSE;
    }


}
Beispiel #27
0
static PyObject *bip_sum(term_t t) {
  PyObject *seq;
  PyObject *result = NULL;
  PyObject *temp, *item, *iter;

  if (!PL_get_arg(1, t, t))
    return NULL;
  seq = term_to_python(t, true);
  iter = PyObject_GetIter(seq);
  if (iter == NULL)
    return NULL;

  if (result == NULL) {
#if PY_MAJOR_VERSION < 3
    result = PyInt_FromLong(0);
#else
    result = PyLong_FromLong(0);
#endif
    if (result == NULL) {
      Py_DECREF(iter);
      return NULL;
    }
  } else {
#if PY_MAJOR_VERSION < 3
    /* reject string values for 'start' parameter */
    if (PyObject_TypeCheck(result, &PyBaseString_Type)) {
      PyErr_SetString(PyExc_TypeError,
                      "sum() can't sum strings [use ''.join(seq) instead]");
      Py_DECREF(iter);
      return NULL;
    }
    Py_INCREF(result);
#endif
  }

#ifndef SLOW_SUM
/* Fast addition by keeping temporary sums in C instead of new Python objects.
Assumes all inputs are the same type.  If the assumption fails, default
to the more general routine.
*/
#if PY_MAJOR_VERSION < 3
  if (PyInt_CheckExact(result)) {
    long i_result = PyInt_AS_LONG(result);
#else
  if (PyLong_CheckExact(result)) {
    long i_result = PyLong_AS_LONG(result);
#endif
    Py_DECREF(result);
    result = NULL;
    while (result == NULL) {
      item = PyIter_Next(iter);
      if (item == NULL) {
        Py_DECREF(iter);
        if (PyErr_Occurred())
          return NULL;
#if PY_MAJOR_VERSION < 3
        return PyInt_FromLong(i_result);
#else
        return PyLong_FromLong(i_result);
#endif
      }
#if PY_MAJOR_VERSION < 3
      if (PyInt_CheckExact(item)) {
        long b = PyInt_AS_LONG(item);
#else
      if (PyLong_CheckExact(item)) {
        long b = PyLong_AS_LONG(item);
#endif
        long x = i_result + b;
        if ((x ^ i_result) >= 0 || (x ^ b) >= 0) {
          i_result = x;
          Py_DECREF(item);
          continue;
        }
      }
/* Either overflowed or is not an int. Restore real objects and process normally
 */
#if PY_MAJOR_VERSION < 3
      result = PyInt_FromLong(i_result);
#else
      result = PyLong_FromLong(i_result);
#endif
      temp = PyNumber_Add(result, item);
      Py_DECREF(result);
      Py_DECREF(item);
      result = temp;
      if (result == NULL) {
        Py_DECREF(iter);
        return NULL;
      }
    }
  }

  if (PyFloat_CheckExact(result)) {
    double f_result = PyFloat_AS_DOUBLE(result);
    Py_DECREF(result);
    result = NULL;
    while (result == NULL) {
      item = PyIter_Next(iter);
      if (item == NULL) {
        Py_DECREF(iter);
        if (PyErr_Occurred())
          return NULL;
        return PyFloat_FromDouble(f_result);
      }
      if (PyFloat_CheckExact(item)) {
        PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
            f_result += PyFloat_AS_DOUBLE(item);
        PyFPE_END_PROTECT(f_result) Py_DECREF(item);
        continue;
      }
#if PY_MAJOR_VERSION < 3
      if (PyInt_CheckExact(item)) {
        PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
            f_result += (double)PyInt_AS_LONG(item);
        PyFPE_END_PROTECT(f_result) Py_DECREF(item);
        continue;
      }
#else
      if (PyLong_CheckExact(item)) {
        PyFPE_START_PROTECT("add", Py_DECREF(item); Py_DECREF(iter); return 0)
            f_result += PyLong_AsDouble(item);
        PyFPE_END_PROTECT(f_result) Py_DECREF(item);
        continue;
      }
#endif
      result = PyFloat_FromDouble(f_result);
      temp = PyNumber_Add(result, item);
      Py_DECREF(result);
      Py_DECREF(item);
      result = temp;
      if (result == NULL) {
        Py_DECREF(iter);
        return NULL;
      }
    }
#endif
  }

  for (;;) {
    item = PyIter_Next(iter);
    if (item == NULL) {
      /* error, or end-of-sequence */
      if (PyErr_Occurred()) {
        Py_DECREF(result);
        result = NULL;
      }
      break;
    }
    /* It's tempting to use PyNumber_InPlaceAdd instead of
    PyNumber_Add here, to avoid quadratic running time
    when doing 'sum(list_of_lists, [])'.  However, this
    would produce a change in behaviour: a snippet like

    empty = []
    sum([[x] for x in range(10)], empty)

    would change the value of empty. */
    temp = PyNumber_Add(result, item);
    Py_DECREF(result);
    Py_DECREF(item);
    result = temp;
    if (result == NULL)
      break;
  }
  Py_DECREF(iter);
  return result;
}

//@}

static long get_int(term_t arg, bool eval) {
  long low;

  if (!PL_get_long(arg, &low)) {
    PyObject *low = term_to_python(arg, eval);
    if (PyLong_Check(low)) {
      return PyLong_AsLong(low);
#if PY_MAJOR_VERSION < 3
    } else if (PyInt_Check(low)) {
      return PyInt_AsLong(low);
#endif
    } else {
      return 0;
    }
  }
  return low;
}

/* Return number of items in range/xrange (lo, hi, step).  step > 0
* required.  Return a value < 0 if & only if the true value is too
* large to fit in a signed long.
*/
static long get_len_of_range(long lo, long hi, long step) {
  /* -------------------------------------------------------------
  If lo >= hi, the range is empty.
  Else if n values are in the range, the last one is
  lo + (n-1)*step, which must be <= hi-1.  Rearranging,
  n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
  the proper value.  Since lo < hi in this case, hi-lo-1 >= 0, so
  the RHS is non-negative and so truncation is the same as the
  floor.  Letting M be the largest positive long, the worst case
  for the RHS numerator is hi=M, lo=-M-1, and then
  hi-lo-1 = M-(-M-1)-1 = 2*M.  Therefore unsigned long has enough
  precision to compute the RHS exactly.
  ---------------------------------------------------------------*/
  long n = 0;
  if (lo < hi) {
    unsigned long uhi = (unsigned long)hi;
    unsigned long ulo = (unsigned long)lo;
    unsigned long diff = uhi - ulo - 1;
    n = (long)(diff / (unsigned long)step + 1);
  }
  return n;
}
Beispiel #28
0
static foreign_t
pl_new_order_table(term_t name, term_t options)
{ OrdTable t = malloc(sizeof(ordtable));
  term_t tail = PL_copy_term_ref(options);
  term_t head = PL_new_term_ref();

  exact_table(t);

  if ( !PL_get_atom(name, &t->name) )
  { free(t);
    return error(ERR_INSTANTIATION, "new_order_table/2", 1, name);
  }

  while(PL_get_list(tail, head, tail))
  { atom_t name;
    int arity;

    if ( PL_get_name_arity(head, &name, &arity) )
    { if ( name == ATOM_case_insensitive )
      { case_insensitive_table(t);
      } else if ( name == ATOM_iso_latin_1 )
      { iso_latin_1_table(t);
      } else if ( name == ATOM_iso_latin_1_case_insensitive )
      { iso_latin_1_case_table(t);
      } else if ( name == ATOM_copy && arity == 1 )
      { term_t a = PL_new_term_ref();
	OrdTable from;

	_PL_get_arg(1, head, a);
	if ( get_order_table(a, &from) )
	{ copy_table(t, from);
	} else
	{ free(t);
	  return FALSE;
	}
      } else if ( arity == 1 )
      { fid_t fid = PL_open_foreign_frame();
	term_t a = PL_new_term_ref();

	_PL_get_arg(1, head, a);
	if ( !parse_set(t, name, a) )
	  goto err1;

	PL_close_foreign_frame(fid);
      } else if ( name == ATOM_eq && arity == 2 )
      { fid_t fid = PL_open_foreign_frame();
	term_t c = PL_new_term_ref();
	int from, to;

	if ( !PL_get_arg(1, head, c) || !get_char(c, &from) ||
	     !PL_get_arg(2, head, c) || !get_char(c, &to) )
	{ free(t);
	  return FALSE;
	}

	ORD(t, from) = to;

	PL_close_foreign_frame(fid);
      } else
	goto err1;
    } else
    { err1:
      free(t);
      return error(ERR_INSTANTIATION, "new_order_table/2", 2, options);
    }
  }
  if ( !PL_get_nil(tail) )
    goto err1;

  register_table(t);

  PL_succeed;
}
Beispiel #29
0
static int
win_command_line(term_t t, int arity, const wchar_t *exe, wchar_t **cline)
{ if ( arity > 0 )
  { arg_string *av = PL_malloc((arity+1)*sizeof(*av));
    term_t arg = PL_new_term_ref();
    size_t cmdlen;
    wchar_t *cmdline, *o;
    const wchar_t *b;
    int i;

    if ( (b=wcsrchr(exe, '\\')) )
      b++;
    else
      b = exe;
    av[0].text = (wchar_t*)b;
    av[0].len = wcslen(av[0].text);
    set_quote(&av[0]);
    cmdlen = av[0].len+(av[0].quote?2:0)+1;

    for( i=1; i<=arity; i++)
    { PL_get_arg(i, t, arg);

      if ( !PL_get_wchars(arg, &av[i].len, &av[i].text,
			  CVT_ATOMIC|CVT_EXCEPTION|BUF_MALLOC) )
	return FALSE;

      if ( wcslen(av[i].text) != av[i].len )
	return domain_error(arg, "no_zero_code_atom");

      if ( !set_quote(&av[i]) )
	return domain_error(arg, "dos_quotable_atom");

      cmdlen += av[i].len+(av[i].quote?2:0)+1;
    }

    cmdline = PL_malloc(cmdlen*sizeof(wchar_t));
    for( o=cmdline,i=0; i<=arity; )
    { wchar_t *s = av[i].text;

      if ( av[i].quote )
	*o++ = av[i].quote;
      wcsncpy(o, s, av[i].len);
      o += av[i].len;
      if ( i > 0 )
	PL_free(s);			/* do not free shared exename */
      if ( av[i].quote )
	*o++ = av[i].quote;

      if (++i <= arity)
	*o++ = ' ';
    }
    *o = 0;
    PL_free(av);

    *cline = cmdline;
  } else
  { *cline = NULL;
  }

  return TRUE;
}
Beispiel #30
0
static foreign_t
pl_tipc_setopt(term_t Socket, term_t opt)
{ int socket;
  atom_t a;
  int arity;

  if ( !tipc_get_socket(Socket, &socket) )
    return FALSE;

  if ( PL_get_name_arity(opt, &a, &arity) )
  { if ( a == ATOM_importance && arity == 1 )
    { atom_t val;
      term_t a1 = PL_new_term_ref();
      int ival = TIPC_LOW_IMPORTANCE;

      if (PL_get_arg(1, opt, a1))
      { if(!PL_get_atom(a1, &val) )
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "atom");

	if(val == ATOM_low)
	  ival = TIPC_LOW_IMPORTANCE;
	else if(val == ATOM_medium)
	  ival = TIPC_MEDIUM_IMPORTANCE;
	else if(val == ATOM_high)
	  ival = TIPC_HIGH_IMPORTANCE;
	else if(val == ATOM_critical)
	  ival = TIPC_CRITICAL_IMPORTANCE;
	else
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "low, medium, high, or critical");

	return((tipc_setopt(socket, NB_TIPC_IMPORTANCE, ival) == 0) ? TRUE : FALSE);
      }
    }

    if ( ((a == ATOM_dest_droppable) ||
	  (a == ATOM_src_droppable)) && arity == 1 )
    { int val;
      term_t a1 = PL_new_term_ref();
      int option = (a == ATOM_dest_droppable) ? NB_TIPC_DEST_DROPPABLE
					      : NB_TIPC_SRC_DROPPABLE;

      if (PL_get_arg(1, opt, a1))
      { if(!PL_get_bool(a1, &val) )
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "boolean");

	return((tipc_setopt(socket, option, val) == 0) ? TRUE : FALSE);
      }
    }
    if ( a == ATOM_conn_timeout && arity == 1 )
    { double val;
      int ival;
      term_t a1 = PL_new_term_ref();

      if (PL_get_arg(1, opt, a1))
      { if(!PL_get_float(a1, &val) || val < 0)
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a1, "float");

        ival = val * 1000;  // time is in milliseconds

	return((tipc_setopt(socket, NB_TIPC_CONN_TIMEOUT, ival) == 0) ? TRUE : FALSE);
      }
    }

    if ( a == ATOM_nodelay && arity <= 1 )
    { int enable, rc;

      if ( arity == 0 )
      { enable = TRUE;
      } else /*if ( arity == 1 )*/
      { term_t a = PL_new_term_ref();

	_PL_get_arg(1, opt, a);
	if ( !PL_get_bool(a, &enable) )
	  return pl_error(NULL, 0, NULL, ERR_DOMAIN, a, "boolean");
      }

      if ( (rc=nbio_setopt(socket, TCP_NO_DELAY, enable) == 0) )
	return TRUE;
      if ( rc == -2 )
  	return pl_error(NULL, 0, NULL, ERR_DOMAIN, opt, "socket_option");

    }

    if ( a == ATOM_nonblock && arity == 0 )
      return((nbio_setopt(socket, TCP_NONBLOCK) == 0) ? TRUE : FALSE );

    if ( a == ATOM_dispatch && arity == 1 )
    { int val;
      term_t a1 = PL_new_term_ref();

      if ( PL_get_arg(1, opt, a1) && PL_get_bool(a1, &val) )
      { if ( nbio_setopt(socket, TCP_DISPATCH, val) == 0 )
	  return TRUE;
	return FALSE;
      }
    } 
  }

  return pl_error(NULL, 0, NULL, ERR_DOMAIN, opt, "socket_option");
}