Пример #1
0
/* file_stat(+FileName, +FuncNumber, -Result)	     	   */
xsbBool file_stat(CTXTdeclc int callno, char *file)
{
  struct stat stat_buff;
  int retcode;
#ifdef WIN_NT
  size_t filenamelen; // windows doesn't allow trailing slash, others do
  filenamelen = strlen(file);
  if (file[filenamelen-1] == '/' || file[filenamelen-1] == '\\') {
    char ss = file[filenamelen-1];
    file[filenamelen-1] = '\0';
    retcode = stat(file, &stat_buff);
    file[filenamelen-1] = ss;  // reset
  } else 
#endif
  retcode = stat(file, &stat_buff);

  switch (callno) {
  case IS_PLAIN_FILE: {
    if (retcode == 0 && S_ISREG(stat_buff.st_mode)) 
      return TRUE;
    else return FALSE;
  }
  case IS_DIRECTORY: {
    if (retcode == 0 && S_ISDIR(stat_buff.st_mode)) 
      return TRUE;
    else return FALSE;
  }
  case STAT_FILE_TIME: {
    /* This is DSW's hack to get 32 bit time values.
       The idea is to call this builtin as file_time(File,time(T1,T2))
       where T1 represents the most significant 8 bits and T2 represents
       the least significant 24.
       ***This probably breaks 64 bit systems, so David will look into it!
       */
    int functor_arg3 = isconstr(reg_term(CTXTc 3));
    if (!retcode && functor_arg3) {
      /* file exists & arg3 is a term, return 2 words*/
      c2p_int(CTXTc (prolog_int)(stat_buff.st_mtime >> 24),p2p_arg(reg_term(CTXTc 3),1));
      c2p_int(CTXTc 0xFFFFFF & stat_buff.st_mtime,p2p_arg(reg_term(CTXTc 3),2));
    } else if (!retcode) {
      /* file exists, arg3 non-functor:  issue an error */
      ctop_int(CTXTc 3, (prolog_int)stat_buff.st_mtime);
    } else if (functor_arg3) {
      /* no file, and arg3 is functor: return two 0's */
      c2p_int(CTXTc 0, p2p_arg(reg_term(CTXTc 3),2));
      c2p_int(CTXTc 0, p2p_arg(reg_term(CTXTc 3),1));
    } else {
      /* no file, no functor: return 0 */
      ctop_int(CTXTc 3, 0);
    }
    return TRUE;
  }
Пример #2
0
DllExport int call_conv fibr(CTXTdecl) {
  int inarg, f1, f2;

  inarg = p2c_int(reg_term(CTXTc 1));  // get the input argument

  if (inarg <= 1) { // if small, return answer directly 
    c2p_int(CTXTc 1,reg_term(CTXTc 2));
    return TRUE;
  }

  xsb_query_save(CTXTc 2);  // prepare for calling XSB
  c2p_functor(CTXTc "fibp",2,reg_term(CTXTc 1));  // setup call
  c2p_int(CTXTc inarg-1,p2p_arg(reg_term(CTXTc 1),1)); // and inp arg
  if (xsb_query(CTXT)) {  // call XSB
    printf("Error calling fibp 1.\n");
    fflush(stdout);
    return FALSE;
 }
  f1 = p2c_int(p2p_arg(reg_term(CTXTc 1),2));  // get answer
  if (xsb_close_query(CTXT)) {  // throw away other (nonexistent) answers
    printf("Error closing fibp 1.\n");
    fflush(stdout);
    return FALSE;
  }

  c2p_functor(CTXTc "fibp",2,reg_term(CTXTc 1)); // prepare for 2nd call to XSB
  c2p_int(CTXTc inarg-2,p2p_arg(reg_term(CTXTc 1),1)); // and its inp arg
  if (xsb_query(CTXT)) { // and call query
    printf("Error calling fibp 2.\n");
    fflush(stdout);
    return FALSE;
  }
  f2 = p2c_int(p2p_arg(reg_term(CTXTc 1),2)); // and get its answer
  if (xsb_next(CTXT) != XSB_FAILURE) { // get next answer, which must NOT exist
    printf("Error getting next fibp 2.\n");
    fflush(stdout);
    return FALSE;
  }

  if (xsb_query_restore(CTXT)) {  // restore regs to prepare for exit
    printf("Error finishing.\n");
    fflush(stdout);
    return FALSE;
  }
  c2p_int(CTXTc f1+f2,reg_term(CTXTc 2));  // set our answer
  return TRUE;  // and return successfully
}
Пример #3
0
int return_to_prolog(PyObject *pValue)
{
	if(pValue == Py_None){
		return 1;
	}
	if(PyInt_Check(pValue))
	{
		int result = PyInt_AS_LONG(pValue);
		extern_ctop_int(3, result);
		return 1;
	}
	else if(PyFloat_Check(pValue))
	{
		float result = PyFloat_AS_DOUBLE(pValue);
		extern_ctop_float(3, result);
		return 1;
	}else if(PyString_Check(pValue))
	{
		char *result = PyString_AS_STRING(pValue);
		extern_ctop_string(3, result);
		return 1;
	}else if(PyList_Check(pValue))
	{
		size_t size = PyList_Size(pValue);
		size_t i = 0;
		prolog_term head, tail;
		prolog_term P = p2p_new();
		tail = P;
		
		for(i = 0; i < size; i++)
		{
			c2p_list(CTXTc tail);
			head = p2p_car(CTXTc tail);
			PyObject *pyObj = PyList_GetItem(pValue, i);
			int temp = PyInt_AS_LONG(pyObj);
			c2p_int(temp, head);
			//convert_pyObj_prObj(pyObj, &head);				
			tail = p2p_cdr(tail);
		}
		c2p_nil(CTXTc tail);
		p2p_unify(P, reg_term(CTXTc 3));
		return 1;
	}else
	{
		//returns an object refernce to prolog side.
		pyobj_ref_node *node = 	add_pyobj_ref_list(pValue);
		//printf("node : %p", node);	
	char str[30];
		sprintf(str, "%p", node);
		//extern_ctop_string(3,str);
	  prolog_term ref = p2p_new();
		c2p_functor("pyObject", 1, ref);
		prolog_term ref_inner = p2p_arg(ref, 1);
    c2p_string(str, ref_inner);		
		p2p_unify(ref, reg_term(CTXTc 3));	
		return 1;
	}
	return 0;
}
Пример #4
0
/* file_stat(+FileName, +FuncNumber, -Result)	     	   */
xsbBool file_stat(CTXTdeclc int callno, char *file)
{
  struct stat stat_buff;
  int retcode = stat(file, &stat_buff);

  switch (callno) {
  case IS_PLAIN_FILE: {
    if (retcode == 0 && S_ISREG(stat_buff.st_mode)) 
      return TRUE;
    else return FALSE;
  }
  case IS_DIRECTORY: {
    if (retcode == 0 && S_ISDIR(stat_buff.st_mode)) 
      return TRUE;
    else return FALSE;
  }
  case STAT_FILE_TIME: {
    /* This is DSW's hack to get 32 bit time values.
       The idea is to call this builtin as file_time(File,time(T1,T2))
       where T1 represents the most significant 8 bits and T2 represents
       the least significant 24.
       ***This probably breaks 64 bit systems, so David will look into it!
       */
    int functor_arg3 = isconstr(reg_term(CTXTc 3));
    if (!retcode && functor_arg3) {
      /* file exists & arg3 is a term, return 2 words*/
      c2p_int(CTXTc stat_buff.st_mtime >> 24,p2p_arg(reg_term(CTXTc 3),1));
      c2p_int(CTXTc 0xFFFFFF & stat_buff.st_mtime,p2p_arg(reg_term(CTXTc 3),2));
    } else if (!retcode) {
      /* file exists, arg3 non-functor:  issue an error */
      xsb_warn("Arg 3 (the time argument) must be of the form time(X,Y)");
      ctop_int(CTXTc 3, (0x7FFFFFF & stat_buff.st_mtime));
    } else if (functor_arg3) {
      /* no file, and arg3 is functor: return two 0's */
      c2p_int(CTXTc 0, p2p_arg(reg_term(CTXTc 3),2));
      c2p_int(CTXTc 0, p2p_arg(reg_term(CTXTc 3),1));
    } else {
      /* no file, no functor: return 0 */
      xsb_warn("Arg 3 (the time argument) must be of the form time(X,Y)");
      ctop_int(CTXTc 3, 0);
    }
    return TRUE;
  }
Пример #5
0
/* call as: current_datime(-D)
    Returns the predicate datime(D) where D is the current time in ms*/
int current_datime(CTXTdecl)
{
    time_t now;
    time(&now);
   
    prolog_term t = reg_term(CTXTc 1);
    if (is_functor(t))
    {
        char *func = p2c_functor(t);
        if(strcmp(func,"datime")==0)
        {
            c2p_int(CTXTc now, p2p_arg(reg_term(CTXTc 1),1));
            return TRUE;
        }
        return FALSE;
    }
    c2p_functor(CTXTc "datime",1,reg_term(CTXTc 1));
    c2p_int(CTXTc now, p2p_arg(reg_term(CTXTc 1),1));
    return TRUE;
}
Пример #6
0
/*
 * call as: next_valid_timestamp(Ts1,Ts2,Interval,NTs)
 * Returns NTs as the next valid timestamp after Ts2 taking into account the
 * interval. This is useful for the periodics events  
 */
int next_valid_timestamp(CTXTdecl)
{
    int ts = p2c_int(reg_term(CTXTc 1));
    int interval = p2c_int(reg_term(CTXTc 3));
    int ts_now = p2c_int(reg_term(CTXTc 2));
    int next_ts = 0;

    if (ts_now <= ts)
    {    
        next_ts = ts + interval;
        c2p_int(CTXTc next_ts, reg_term(CTXTc 4));
        return TRUE;
    }

    int diff = (ts_now - ts);
    int left_time = diff % interval;
    next_ts = ts_now + (interval - left_time);
    c2p_int(CTXTc next_ts, reg_term(CTXTc 4));

    return TRUE;
}
Пример #7
0
/*
 * call as: datime_plus_sec(T1,Sec,T2)
 *  Returns T2 as the result of date T1 plus Sec seconds
 */
int datime_plus_sec(CTXTdecl)
{
    prolog_term t1 = reg_term(CTXTc 1);
    if(!is_functor(t1))
        return FALSE;

    int t1_ts = p2c_int(p2p_arg(t1,1));
    int sec = p2c_int(reg_term(CTXTc 2));
    if (p2c_arity(t1) > 1)
    {
        int counter = p2p_arg(t1,2);
        c2p_functor(CTXTc "datime",2,reg_term(CTXTc 3));
        c2p_int(CTXTc t1_ts+sec,p2p_arg(reg_term(CTXTc 3),1));
        c2p_int(CTXTc counter,p2p_arg(reg_term(CTXTc 3),2));
    }
    else
    {
        c2p_functor(CTXTc "datime",1,reg_term(CTXTc 3));
        c2p_int(CTXTc t1_ts+sec,p2p_arg(reg_term(CTXTc 3),1));
    }
    return TRUE;
}
Пример #8
0
static xsbBool set_error_code(CTXTdeclc int ErrCode, int ErrCodeArgNumber, char *Where)
{
  prolog_term ecode_value_term, ecode_arg_term = p2p_new(CTXT);
  
  ecode_value_term = reg_term(CTXTc ErrCodeArgNumber);
  if (!isref(ecode_value_term) && 
      !(isointeger(ecode_value_term)))
    xsb_abort("[%s] Arg %d (the error code) must be a variable or an integer!",
	      Where, ErrCodeArgNumber);

  c2p_int(CTXTc ErrCode, ecode_arg_term);
  return p2p_unify(CTXTc ecode_arg_term, ecode_value_term);
}
Пример #9
0
/*
 * call as: epoch(+Y,+M,+D,+H,+M,+S,-Sec)
 *  Returns the seconds until the date Y-M-D-H-M-S
 */
int epoch(CTXTdecl)
{
    int time_sec;
    struct tm time;
    time.tm_year = p2c_int(reg_term(CTXTc 1)) - 1900;
    time.tm_mon = p2c_int(reg_term(CTXTc 2)) - 1 ;
    time.tm_mday = p2c_int(reg_term(CTXTc 3));
    time.tm_hour = p2c_int(reg_term(CTXTc 4));
    time.tm_min = p2c_int(reg_term(CTXTc 5));
    time.tm_sec = p2c_int(reg_term(CTXTc 6));
    time.tm_isdst = -1;

    time_sec = mktime(&time);
    c2p_int(CTXTc time_sec, reg_term(CTXTc 7));
    return TRUE;
}
Пример #10
0
/* utility function to return the available socket descriptors after testing */
static void test_ready(CTXTdeclc prolog_term *avail_sockfds, fd_set *fdset,
		       int *fds, int size) 
{
  prolog_term head;
  int i=0;

  for (i=0;i<size;i++) {
    c2p_list(CTXTc *avail_sockfds);
    if (FD_ISSET(fds[i], fdset)) {
      head = p2p_car(*avail_sockfds);
      c2p_int(CTXTc fds[i], head);
      *avail_sockfds = p2p_cdr(*avail_sockfds);
    } 
  }
  c2p_nil(CTXTc *avail_sockfds);
  return;
}
Пример #11
0
int epoch2date(CTXTdecl)
{
    time_t epoch = p2c_int(reg_term(CTXTc 7));
    struct tm date = *localtime(&epoch);
    c2p_int(CTXTc 1900 + date.tm_year, reg_term(CTXTc 1));
    c2p_int(CTXTc 1 + date.tm_mon, reg_term(CTXTc 2));
    c2p_int(CTXTc date.tm_mday, reg_term(CTXTc 3));
    c2p_int(CTXTc date.tm_hour, reg_term(CTXTc 4));
    c2p_int(CTXTc date.tm_min, reg_term(CTXTc 5));
    c2p_int(CTXTc date.tm_sec, reg_term(CTXTc 6));
    return TRUE;
}
Пример #12
0
/*
 * call as: datime_minus_datime(T1,T2,Sec)
 * Returns Sec as the diff in seconds between T1 and T2
 */
int datime_minus_datime(CTXTdecl)
{
    prolog_term t1 = reg_term(CTXTc 1);
    prolog_term t2 = reg_term(CTXTc 2);

    if(!is_functor(t1) && !is_functor(t2))
        return FALSE;
    
    int t1_ts = p2c_int(p2p_arg(t1,1));
    int t2_ts = p2c_int(p2p_arg(t2,1));
    int diff = 0;
    
    if(t1_ts < t2_ts)
        diff = t2_ts - t1_ts;
    else
        diff = t1_ts - t2_ts;

    c2p_int(CTXTc diff,reg_term(CTXTc 3));
    return TRUE;
}
Пример #13
0
/* TLS: making a conservative guess at which system calls need to be
   mutexed.  I'm doing it whenever I see the process table altered or
   affected, so this is the data structure that its protecting.

   At some point, the SET_FILEPTRs should be protected against other
   threads closing that stream.  Perhaps for such things a
   thread-specific stream table should be used.
*/
xsbBool sys_system(CTXTdeclc int callno)
{
  //  int pid;
  Integer pid;

  switch (callno) {
  case PLAIN_SYSTEM_CALL: /* dumb system call: no communication with XSB */
    /* this call is superseded by shell and isn't used */
    ctop_int(CTXTc 3, system(ptoc_string(CTXTc 2)));
    return TRUE;
  case SLEEP_FOR_SECS:
#ifdef WIN_NT
    Sleep((int)iso_ptoc_int_arg(CTXTc 2,"sleep/1",1) * 1000);
#else
    sleep(iso_ptoc_int_arg(CTXTc 2,"sleep/1",1));
#endif
    return TRUE;
  case GET_TMP_FILENAME:
    ctop_string(CTXTc 2,tempnam(NULL,NULL));
    return TRUE;
  case IS_PLAIN_FILE:
  case IS_DIRECTORY:
  case STAT_FILE_TIME:
  case STAT_FILE_SIZE:
    return file_stat(CTXTc callno, ptoc_longstring(CTXTc 2));
  case EXEC: {
#ifdef HAVE_EXECVP
    /* execs a new process in place of XSB */
    char *params[MAX_SUBPROC_PARAMS+2];
    prolog_term cmdspec_term;
    int index = 0;
    
    cmdspec_term = reg_term(CTXTc 2);
    if (islist(cmdspec_term)) {
      prolog_term temp, head;
      char *string_head=NULL;

      if (isnil(cmdspec_term))
	xsb_abort("[exec] Arg 1 must not be an empty list.");
      
      temp = cmdspec_term;
      do {
	head = p2p_car(temp);
	temp = p2p_cdr(temp);
	if (isstring(head)) 
	  string_head = string_val(head);
	else
	  xsb_abort("[exec] non-string argument passed in list.");
	
	params[index++] = string_head;
	if (index > MAX_SUBPROC_PARAMS)
	  xsb_abort("[exec] Too many arguments.");
      } while (!isnil(temp));
      params[index] = NULL;
    } else if (isstring(cmdspec_term)) {
      char *string = string_val(cmdspec_term);
      split_command_arguments(string, params, "exec");
    } else
      xsb_abort("[exec] 1st argument should be term or list of strings.");

    if (execvp(params[0], params)) 
      xsb_abort("[exec] Exec call failed.");
#else
    xsb_abort("[exec] builtin not supported in this architecture.");
#endif
  }
    
  case SHELL: /* smart system call: like SPAWN_PROCESS, but returns error code
		 instead of PID. Uses system() rather than execvp.
		 Advantage: can pass arbitrary shell command. */
  case SPAWN_PROCESS: { /* spawn new process, reroute stdin/out/err to XSB */
    /* +CallNo=2, +ProcAndArgsList,
       -StreamToProc, -StreamFromProc, -StreamFromProcStderr,
       -Pid */
    static int pipe_to_proc[2], pipe_from_proc[2], pipe_from_stderr[2];
    int toproc_stream=-1, fromproc_stream=-1, fromproc_stderr_stream=-1;
    int pid_or_status;
    FILE *toprocess_fptr=NULL,
      *fromprocess_fptr=NULL, *fromproc_stderr_fptr=NULL;
    char *params[MAX_SUBPROC_PARAMS+2]; /* one for progname--0th member,
				       one for NULL termination*/
    prolog_term cmdspec_term, cmdlist_temp_term;
    prolog_term cmd_or_arg_term;
    xsbBool toproc_needed=FALSE, fromproc_needed=FALSE, fromstderr_needed=FALSE;
    char *cmd_or_arg=NULL, *shell_cmd=NULL;
    int idx = 0, tbl_pos;
    char *callname=NULL;
    xsbBool params_are_in_a_list=FALSE;

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );

    init_process_table();

    if (callno == SPAWN_PROCESS)
      callname = "spawn_process/5";
    else
      callname = "shell/[1,2,5]";

    cmdspec_term = reg_term(CTXTc 2);
    if (islist(cmdspec_term))
      params_are_in_a_list = TRUE;
    else if (isstring(cmdspec_term))
      shell_cmd = string_val(cmdspec_term);
    else if (isref(cmdspec_term))
      xsb_instantiation_error(CTXTc callname,1);
    else    
      xsb_type_error(CTXTc "atom or list e.g. [command, arg, ...]",cmdspec_term,callname,1);
    
    // xsb_abort("[%s] Arg 1 must be an atom or a list [command, arg, ...]",
    // callname);

    /* the user can indicate that he doesn't want either of the streams created
       by putting an atom in the corresponding argument position */
    if (isref(reg_term(CTXTc 3)))
      toproc_needed = TRUE;
    if (isref(reg_term(CTXTc 4)))
      fromproc_needed = TRUE;
    if (isref(reg_term(CTXTc 5)))
      fromstderr_needed = TRUE;

    /* if any of the arg streams is already used by XSB, then don't create
       pipes --- use these streams instead. */
    if (isointeger(reg_term(CTXTc 3))) {
      SET_FILEPTR(toprocess_fptr, oint_val(reg_term(CTXTc 3)));
    }
    if (isointeger(reg_term(CTXTc 4))) {
      SET_FILEPTR(fromprocess_fptr, oint_val(reg_term(CTXTc 4)));
    }
    if (isointeger(reg_term(CTXTc 5))) {
      SET_FILEPTR(fromproc_stderr_fptr, oint_val(reg_term(CTXTc 5)));
    }

    if (!isref(reg_term(CTXTc 6)))
      xsb_type_error(CTXTc "variable (to return process id)",reg_term(CTXTc 6),callname,5);
    //      xsb_abort("[%s] Arg 5 (process id) must be a variable", callname);

    if (params_are_in_a_list) {
      /* fill in the params[] array */
      if (isnil(cmdspec_term))
	xsb_abort("[%s] Arg 1 must not be an empty list", callname);
      
      cmdlist_temp_term = cmdspec_term;
      do {
	cmd_or_arg_term = p2p_car(cmdlist_temp_term);
	cmdlist_temp_term = p2p_cdr(cmdlist_temp_term);
	if (isstring(cmd_or_arg_term)) {
	  cmd_or_arg = string_val(cmd_or_arg_term);
	}
	else 
	  xsb_abort("[%s] Non string list member in the Arg",
		    callname);
	
	params[idx++] = cmd_or_arg;
	if (idx > MAX_SUBPROC_PARAMS)
	  xsb_abort("[%s] Too many arguments passed to subprocess",
		    callname);
	
      } while (!isnil(cmdlist_temp_term));

      params[idx] = NULL; /* null termination */

    } else { /* params are in a string */
      if (callno == SPAWN_PROCESS)
	split_command_arguments(shell_cmd, params, callname);
      else {
	/* if callno==SHELL => call system() => don't split shell_cmd */
	params[0] = shell_cmd;
	params[1] = NULL;
      }
    }
    
    /* -1 means: no space left */
    if ((tbl_pos = get_free_process_cell()) < 0) {
      xsb_warn(CTXTc "Can't create subprocess because XSB process table is full");
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return FALSE;
    }

      /* params[0] is the progname */
    pid_or_status = xsb_spawn(CTXTc params[0], params, callno,
			      (toproc_needed ? pipe_to_proc : NULL),
			      (fromproc_needed ? pipe_from_proc : NULL),
			      (fromstderr_needed ? pipe_from_stderr : NULL),
			      toprocess_fptr, fromprocess_fptr,
			      fromproc_stderr_fptr);
      
    if (pid_or_status < 0) {
      xsb_warn(CTXTc "[%s] Subprocess creation failed, Error: %d, errno: %d, Cmd: %s", callname,pid_or_status,errno,params[0]);
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return FALSE;
    }

    if (toproc_needed) {
      toprocess_fptr = fdopen(pipe_to_proc[1], "w");
      toproc_stream =  xsb_intern_fileptr(CTXTc toprocess_fptr,callname,"pipe","w",CURRENT_CHARSET); 
      ctop_int(CTXTc 3, toproc_stream);
    }
    if (fromproc_needed) {
      fromprocess_fptr = fdopen(pipe_from_proc[0], "r");
      fromproc_stream =  xsb_intern_fileptr(CTXTc fromprocess_fptr,callname,"pipe","r",CURRENT_CHARSET); 
      ctop_int(CTXTc 4, fromproc_stream);
    }
    if (fromstderr_needed) {
      fromproc_stderr_fptr = fdopen(pipe_from_stderr[0], "r");
      fromproc_stderr_stream
	= xsb_intern_fileptr(CTXTc fromproc_stderr_fptr,callname,"pipe","r",CURRENT_CHARSET); 
      ctop_int(CTXTc 5, fromproc_stderr_stream);
    }
    ctop_int(CTXTc 6, pid_or_status);

    xsb_process_table.process[tbl_pos].pid = pid_or_status;
    xsb_process_table.process[tbl_pos].to_stream = toproc_stream;
    xsb_process_table.process[tbl_pos].from_stream = fromproc_stream;
    xsb_process_table.process[tbl_pos].stderr_stream = fromproc_stderr_stream;
    concat_array(CTXTc params, " ",
		 xsb_process_table.process[tbl_pos].cmdline,MAX_CMD_LEN);
    
    SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
    return TRUE;
  }

  case GET_PROCESS_TABLE: { /* sys_system(3, X). X is bound to the list
	       of the form [process(Pid,To,From,Stderr,Cmdline), ...] */
    int i;
    prolog_term table_term_tail, listHead;
    prolog_term table_term=reg_term(CTXTc 2);

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );
    init_process_table();

    if (!isref(table_term))
      xsb_abort("[GET_PROCESS_TABLE] Arg 1 must be a variable");

    table_term_tail = table_term;
    for (i=0; i<MAX_SUBPROC_NUMBER; i++) {
      if (!FREE_PROC_TABLE_CELL(xsb_process_table.process[i].pid)) {
	c2p_list(CTXTc table_term_tail); /* make it into a list */
	listHead = p2p_car(table_term_tail);

	c2p_functor(CTXTc "process", 5, listHead);
	c2p_int(CTXTc xsb_process_table.process[i].pid, p2p_arg(listHead,1));
	c2p_int(CTXTc xsb_process_table.process[i].to_stream, p2p_arg(listHead,2));
	c2p_int(CTXTc xsb_process_table.process[i].from_stream, p2p_arg(listHead,3));
	c2p_int(CTXTc xsb_process_table.process[i].stderr_stream,
		p2p_arg(listHead,4));
	c2p_string(CTXTc xsb_process_table.process[i].cmdline, p2p_arg(listHead,5));

	table_term_tail = p2p_cdr(table_term_tail);
      }
    }
    c2p_nil(CTXTc table_term_tail); /* bind tail to nil */
    SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
    return p2p_unify(CTXTc table_term, reg_term(CTXTc 2));
  }

  case PROCESS_STATUS: {
    prolog_term pid_term=reg_term(CTXTc 2), status_term=reg_term(CTXTc 3);

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );

    init_process_table();

    if (!(isointeger(pid_term)))
      xsb_abort("[PROCESS_STATUS] Arg 1 (process id) must be an integer");
    pid = (int)oint_val(pid_term);

    if (!isref(status_term))
      xsb_abort("[PROCESS_STATUS] Arg 2 (process status) must be a variable");
    
    switch (process_status(pid)) {
    case RUNNING:
      c2p_string(CTXTc "running", status_term);
      break;
    case STOPPED:
      c2p_string(CTXTc "stopped", status_term);
      break;
    case EXITED_NORMALLY:
      c2p_string(CTXTc "exited_normally", status_term);
      break;
    case EXITED_ABNORMALLY:
      c2p_string(CTXTc "exited_abnormally", status_term);
      break;
    case ABORTED:
      c2p_string(CTXTc "aborted", status_term);
      break;
    case INVALID:
      c2p_string(CTXTc "invalid", status_term);
      break;
    default:
      c2p_string(CTXTc "unknown", status_term);
    }
    SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
    return TRUE;
  }

  case PROCESS_CONTROL: {
    /* sys_system(PROCESS_CONTROL, +Pid, +Signal). Signal: wait, kill */
    int status;
    prolog_term pid_term=reg_term(CTXTc 2), signal_term=reg_term(CTXTc 3);

    SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM );
    init_process_table();

    if (!(isointeger(pid_term)))
      xsb_abort("[PROCESS_CONTROL] Arg 1 (process id) must be an integer");
    pid = (int)oint_val(pid_term);

    if (isstring(signal_term) && strcmp(string_val(signal_term), "kill")==0) {
      if (KILL_FAILED(pid)) {
	SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
	return FALSE;
      }
#ifdef WIN_NT
      CloseHandle((HANDLE) pid);
#endif
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return TRUE;
    }
    if (isconstr(signal_term)
	&& strcmp(p2c_functor(signal_term),"wait") == 0
	&& p2c_arity(signal_term)==1) {
      int exit_status;

      if (WAIT(pid, status) < 0) {
	SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
	return FALSE;
      }

#ifdef WIN_NT
      exit_status = status;
#else
      if (WIFEXITED(status))
	exit_status = WEXITSTATUS(status);
      else
	exit_status = -1;
#endif

      p2p_unify(CTXTc p2p_arg(signal_term,1), makeint(exit_status));
      SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM );
      return TRUE;
    }

    xsb_warn(CTXTc "[PROCESS_CONTROL] Arg 2: Invalid signal specification. Must be `kill' or `wait(Var)'");
    return FALSE;
  }
   
  case LIST_DIRECTORY: {
    /* assume all type- and mode-checking is done in Prolog */
    prolog_term handle = reg_term(CTXTc 2); /* ref for handle */
    char *dir_name = ptoc_longstring(CTXTc 3); /* +directory name */
    prolog_term filename = reg_term(CTXTc 4); /* reference for name of file */
    
    if (is_var(handle)) 
      return xsb_find_first_file(CTXTc handle,dir_name,filename);
    else
      return xsb_find_next_file(CTXTc handle,dir_name,filename);
  }

  default:
    xsb_abort("[SYS_SYSTEM] Wrong call number (an XSB bug)");
  } /* end case */
  return TRUE;
}
Пример #14
0
int convert_pyObj_prObj(PyObject *pyObj, prolog_term *prTerm)
{
	if(pyObj == Py_None){
		return 1;// todo: check this case for a list with a none in the list. how does prolog side react 
	}
	if(PyInt_Check(pyObj))
	{
		int result = PyInt_AS_LONG(pyObj);
		//extern_ctop_int(3, result);
		c2p_int(result, *prTerm);
		return 1;
	}
	else if(PyFloat_Check(pyObj))
	{
		float result = PyFloat_AS_DOUBLE(pyObj);
		//extern_ctop_float(3, result);
		c2p_float(result, *prTerm);
		return 1;
	}else if(PyString_Check(pyObj))
	{
		char *result = PyString_AS_STRING(pyObj);
		//extern_ctop_string(3, result);
		c2p_string(result, *prTerm);
		return 1;
	}else if(PyList_Check(pyObj))
	{
		size_t size = PyList_Size(pyObj);
		size_t i = 0;
		prolog_term head, tail;
		prolog_term P = p2p_new();
		tail = P;
		
		for(i = 0; i < size; i++)
		{
			c2p_list(CTXTc tail);
			head = p2p_car(CTXTc tail);
			PyObject *pyObjInner = PyList_GetItem(pyObj, i);
			//int temp = PyInt_AS_LONG(pyObj);
			//c2p_int(temp, head);
			convert_pyObj_prObj(pyObjInner, &head);				
			tail = p2p_cdr(tail);
		}
		c2p_nil(CTXTc tail);
		//p2p_unify(P, reg_term(CTXTc 3));
		return 1;
	}else
	{
		//returns an object refernce to prolog side.
		pyobj_ref_node *node = 	add_pyobj_ref_list(pyObj);
		//printf("node : %p", node);	
		char str[30];
		sprintf(str, "%p", node);
		//extern_ctop_string(3,str);
	  	prolog_term ref = p2p_new();
		c2p_functor("pyObject", 1, ref);
		prolog_term ref_inner = p2p_arg(ref, 1);
    	c2p_string(str, ref_inner);		
		p2p_unify(ref, *prTerm);	
		return 1;
	}
}
static int bindReturnList(prolog_term returnList, struct xsb_data** result, struct xsb_queryHandle* qHandle)
{
  prolog_term element;
  char* temp;
  char c;
  int i, j;
  int rFlag;
  
  if (is_nil(returnList) && result == NULL) {
    rFlag = RESULT_NONEMPTY_OR_NOT_REQUESTED;
  }

  if (!is_nil(returnList) && result == NULL && qHandle->state == QUERY_BEGIN) {
    errorMesg = "XSB_DBI_ERROR: Invalid return list in query";
    errorNumber = "XSB_DBI_013";
    rFlag = INVALID_RETURN_LIST;
  }  
  else if (!is_nil(returnList) && result == NULL) {
    while (!is_nil(returnList)) {
      element = p2p_car(returnList);
      c2p_nil(CTXTc element);
      returnList = p2p_cdr(returnList);
    }
    rFlag = RESULT_EMPTY_BUT_REQUESTED;
  }

  i = 0;
  if (result != NULL) {
    while (!is_nil(returnList)) {
      if (qHandle->numResultCols <= i) {
	errorMesg = "XSB_DBI ERROR: Number of requested columns exceeds the number of columns in the query";
	errorNumber = "XSB_DBI_011";
	rFlag = TOO_MANY_RETURN_COLS;
	return rFlag;
      }
      element = p2p_car(returnList);
      if (result == NULL) {
	c2p_nil(CTXTc element);
      }
      else if (is_var(element) && result[i]->type == STRING_TYPE) {
	if (result[i]->val == NULL)
	  c2p_nil(CTXTc element);
	else {
	  c = result[i]->val->str_val[0];
	  if (c == DB_INTERFACE_TERM_SYMBOL) {
	    temp = (char *)malloc(strlen(result[i]->val->str_val) * sizeof(char));
	    for (j = 1 ; j < (int)strlen(result[i]->val->str_val) ; j++) {
	      temp[j-1] = result[i]->val->str_val[j];
	    }
	    temp[strlen(result[i]->val->str_val) - 1] = '\0';
	    c2p_functor(CTXTc "term", 1, element);
	    c2p_string(CTXTc temp, p2p_arg(element, 1));    
	    if (temp != NULL) {
	      free(temp);
	      temp = NULL;
	    }
	  }
	  else {
	    c2p_string(CTXTc result[i]->val->str_val, element);
	  }
	}
      }
      else if (is_var(element) && result[i]->type == INT_TYPE)
	c2p_int(CTXTc result[i]->val->i_val, element);
      else if (is_var(element) && result[i]->type == FLOAT_TYPE)
	c2p_float(CTXTc result[i]->val->f_val, element);
      returnList = p2p_cdr(returnList);
      i++;
    }
    rFlag = RESULT_NONEMPTY_OR_NOT_REQUESTED;
  }

  if (result != NULL && qHandle->numResultCols > i) {
    errorMesg = "XSB_DBI ERROR: Number of requested columns is less than the number of returned columns";
    errorNumber = "XSB_DBI_012";
    rFlag = TOO_FEW_RETURN_COLS;
    return rFlag;
  }
  return rFlag;
}
Пример #16
0
int main(int argc, char *argv[])
{ 
  int rcode;
  int myargc = 3;
  char *myargv[3];

  /* xsb_init relies on the calling program to pass the absolute or relative
     path name of the XSB installation directory. We assume that the current
     program is sitting in the directory .../examples/c_calling_xsb/
     To get installation directory, we strip 3 file names from the path. */
  myargv[0] = strip_names_from_path(xsb_executable_full_path(argv[0]), 3);
  myargv[1] = "-n";
  myargv[2] = "-e writeln(hello). writeln(kkk).";

  /* Initialize xsb */
  xsb_init(myargc,myargv);  /* depend on user to put in right options (-n) */

  /* Create command to consult a file: ctest.P, and send it. */
  c2p_functor("consult",1,reg_term(1));
  c2p_string("ctest",p2p_arg(reg_term(1),1));
  if (xsb_command()) {
    printf("Error consulting ctest.P.\n");
    fflush(stdout);
  }

  if (xsb_command_string("consult(basics).")) {
    printf("Error (string) consulting basics.\n");
    fflush(stdout);
  }

  /* Create the query p(300,X,Y) and send it. */
  c2p_functor("p",3,reg_term(1));
  c2p_int(300,p2p_arg(reg_term(1),1));

  rcode = xsb_query();

  /* Print out answer and retrieve next one. */
  while (!rcode) {
    if (!(is_string(p2p_arg(reg_term(2),1)) & 
	  is_string(p2p_arg(reg_term(2),2))))
       printf("2nd and 3rd subfields must be atoms\n");
    else
      printf("Answer: %d, %s(%s), %s(%s)\n",
	     p2c_int(p2p_arg(reg_term(1),1)),
	     p2c_string(p2p_arg(reg_term(1),2)),
	     xsb_var_string(1),
	     p2c_string(p2p_arg(reg_term(1),3)),
	     xsb_var_string(2)
	     );
    fflush(stdout);
    rcode = xsb_next();
  }

  /* Create the string query p(300,X,Y) and send it, use higher-level
     routines. */

  xsb_make_vars(3);
  xsb_set_var_int(300,1);
  rcode = xsb_query_string("p(X,Y,Z).");

  /* Print out answer and retrieve next one. */
  while (!rcode) {
    if (!(is_string(p2p_arg(reg_term(2),2)) & 
	  is_string(p2p_arg(reg_term(2),3))))
       printf("2nd and 3rd subfields must be atoms\n");
    else
      printf("Answer: %d, %s, %s\n",
	     xsb_var_int(1),
	     xsb_var_string(2),
	     xsb_var_string(3)
	     );
    fflush(stdout);
    rcode = xsb_next();
  }



  /* Close connection */
  xsb_close();
  printf("cmain exit\n");
  return(0);
}
DllExport int call_conv pl_load_page()
{

  prolog_term head, tail, result = 0;

  char *functor, *url = NULL, *data = NULL;
  char *username = NULL, *password = NULL;

  curl_opt options = init_options();
  curl_ret ret_vals;

	
  check_thread_context
  tail = reg_term(CTXTc 1);
  
  if(!is_list(tail))
    return curl2pl_error(ERR_DOMAIN, "source", tail);

  while(is_list(tail)){
    
    head = p2p_car(tail); 
    tail = p2p_cdr(tail);

    if(is_functor(head)){
      
      functor = p2c_functor(head);
   
      if(!strcmp(functor,"source")){

	prolog_term term_url_func, term_url = 0;

	term_url_func = p2p_arg(head, 1);
     
	if(is_functor(term_url_func)){
		
	  if(!strcmp(p2c_functor(term_url_func), "url")){
	    
	    term_url = p2p_arg(term_url_func, 1);
	    url = p2c_string(term_url);
	    data = load_page(url, options, &ret_vals);
	  }
	  else{
	    return curl2pl_error(ERR_MISC, "source", term_url);
	  }
	}
	else{
	  return curl2pl_error(ERR_MISC, "source", "Improper input format");
	}
      }
      else if(!strcmp(functor,"options")){

	prolog_term term_options = p2p_arg(head, 1);
	prolog_term term_option;

	while(is_list(term_options)){

		term_option = p2p_car(term_options);
		if(!strcmp(p2c_functor(term_option), "redirect")) {
			if(!strcmp(p2c_string(p2p_arg(term_option, 1)), "true"))
				options.redir_flag = 1;
			else
				options.redir_flag = 0;
		}
		else if(!strcmp(p2c_functor(term_option), "secure")){
			if(!strcmp(p2c_string(p2p_arg(term_option, 1)), "false"))
				options.secure.flag = 0;
			else
				options.secure.crt_name = p2c_string(p2p_arg(term_option, 1));
		}
		else if(!strcmp(p2c_functor(term_option), "auth")){
			username = p2c_string(p2p_arg(term_option, 1));
			password = p2c_string(p2p_arg(term_option, 2));
			options.auth.usr_pwd = (char *) malloc ((strlen(username) + strlen(password) + 2) * sizeof(char));
			strcpy(options.auth.usr_pwd, username);
			strcat(options.auth.usr_pwd, ":");
			strcat(options.auth.usr_pwd, password);			
		}
		else if(!strcmp(p2c_functor(term_option), "timeout")){
		  options.timeout = (int)p2c_int(p2p_arg(term_option, 1));
		}
		else if(!strcmp(p2c_functor(term_option), "url_prop")){
			options.url_prop = options.redir_flag;
		}
		else if(!strcmp(p2c_functor(term_option), "user_agent")){
			options.user_agent = p2c_string(p2p_arg(term_option, 1));
		}
		else if(!strcmp(p2c_functor(term_option), "post")){
			options.post_data = p2c_string(p2p_arg(term_option, 1));
		}
		term_options = p2p_cdr(term_options);
	}

      }
      else if(!strcmp(functor,"document")){

	result = p2p_arg(head, 1);
      }
      else if(!strcmp(functor,"properties")){

	c2p_int(CTXTc (int) ret_vals.size, p2p_arg(head, 1));
	/* the following code can be used to convert to local/UTC time, if
	    necessary. Note: XSB uses local time, and ret_vals.modify_time
	    is local, too.

	    struct tm * timeinfo;
	    timeinfo = gmtime(&(ret_vals.modify_time)); // UTC time
	    timeinfo = localtime(&(ret_vals.modify_time)); // local time
	    c2p_int(CTXTc (int) mktime(timeinfo), p2p_arg(head,2));
	*/
	/* return modification time as an integer */
	c2p_int(CTXTc (int) ret_vals.modify_time, p2p_arg(head,2));
	/*
	  The following converts time to string - not useful

	  if (ctime(&ret_vals.modify_time) == NULL)
	      c2p_string("", p2p_arg(head, 2));
	  else
	      c2p_string(CTXTc (char *) ctime(&ret_vals.modify_time),
		         p2p_arg(head, 2));
	*/
      }
    }
    else{
      return curl2pl_error(ERR_DOMAIN, "source", head);
    }
  }

  c2p_string(CTXTc data, result);

return TRUE;
}
/* XSB regular expression matcher entry point
   In:
       Arg1: regexp
       Arg2: string
       Arg3: offset
       Arg4: match_flags: Var means case-sensitive/extended;
       	       	          number: ignorecase/extended
			  List: [{extended|ignorecase},...]
   Out:
       Arg5: list of the form [match(bo0,eo0), match(bo1,eo1),...]
       	     where bo*,eo* specify the beginning and ending offsets of the
	     matched substrings.
	     All matched substrings are returned. Parenthesized expressions are
	     ignored.
*/
int do_bulkmatch__(void)
{
#ifdef MULTI_THREAD
  if( NULL == th)
	th = xsb_get_main_thread();
#endif

  prolog_term listHead, listTail;
  /* Prolog args are first assigned to these, so we could examine the types
     of these objects to determine if we got strings or atoms. */
  prolog_term regexp_term, input_term, offset_term;
  prolog_term output_term = p2p_new(CTXT);
  char *regexp_ptr=NULL;      /* regular expression ptr	       	      */
  char *input_string=NULL;    /* string where matches are to be found */
  int match_flags=FALSE;
  int return_code, paren_number, offset;
  regmatch_t *match_array;
  int last_pos=0, input_len;
  
  if (first_call)
    initialize_regexp_tbl();

  regexp_term = reg_term(CTXTc 1);  /* Arg1: regexp */
  if (is_string(regexp_term)) /* check it */
    regexp_ptr = string_val(regexp_term);
  else if (is_list(regexp_term))
    regexp_ptr = p_charlist_to_c_string(CTXTc regexp_term, &regexp_buffer,
					"RE_BULKMATCH", "regular expression");
  else
    xsb_abort("[RE_BULKMATCH] Arg 1 (the regular expression) must be an atom or a character list");

  input_term = reg_term(CTXTc 2);  /* Arg2: string to find matches in */
  if (is_string(input_term)) /* check it */
    input_string = string_val(input_term);
  else if (is_list(input_term)) {
    input_string = p_charlist_to_c_string(CTXTc input_term, &input_buffer,
					  "RE_BULKMATCH", "input string");
  } else
    xsb_abort("[RE_BULKMATCH] Arg 2 (the input string) must be an atom or a character list");

  input_len = strlen(input_string);
  
  offset_term = reg_term(CTXTc 3); /* arg3: offset within the string */
  if (! is_int(offset_term))
    xsb_abort("[RE_BULKMATCH] Arg 3 (the offset) must be an integer");
  offset = int_val(offset_term);
  if (offset < 0 || offset > input_len)
    xsb_abort("[RE_BULKMATCH] Arg 3 (=%d) must be between 0 and %d", input_len);

   /* arg 4 specifies flags: _, number, list [extended,ignorecase] */
  match_flags = make_flags(reg_term(CTXTc 4), "RE_BULKMATCH");

  last_pos = offset;
  /* returned result */
  listTail = output_term;
  while (last_pos < input_len) {
    return_code = xsb_re_match(regexp_ptr, input_string+last_pos, match_flags,
			       &match_array, &paren_number, "RE_BULKMATCH");
    /* exit on no match */
    if (! return_code) break;

    c2p_list(CTXTc listTail); /* make it into a list */
    listHead = p2p_car(listTail); /* get head of the list */

    /* bind i-th match to listHead as match(beg,end) */
    c2p_functor(CTXTc "match", 2, listHead);
    c2p_int(CTXTc match_array[0].rm_so+last_pos, p2p_arg(listHead,1));
    c2p_int(CTXTc match_array[0].rm_eo+last_pos, p2p_arg(listHead,2));

    listTail = p2p_cdr(listTail);
    if (match_array[0].rm_eo > 0)
      last_pos = match_array[0].rm_eo+last_pos;
    else
      last_pos++;
  }

  c2p_nil(CTXTc listTail); /* bind tail to nil */
  return p2p_unify(CTXTc output_term, reg_term(CTXTc 5));
}
Пример #19
0
/**
 * Function to handle the errors. It creates an appropriate error term 
 * for the prolog side to throw.
 * Input : type of error
 * Output : TRUE on success, FALSE on failure
 **/
int
sgml2pl_error(plerrorid id, ...)
{ 
  prolog_term except = p2p_new();
  prolog_term formal = p2p_new();
  prolog_term swi = p2p_new();
  prolog_term tmp1 = p2p_new();
  prolog_term tmp;

  va_list args;
  char msgbuf[1024];
  char *msg = NULL;

  va_start(args, id);
  /*Create the appropriate error term based on the type of error*/
  switch(id)
    { 
    case ERR_ERRNO:					/*Standard unix errors*/
      { 
	int err = va_arg(args, int);
	msg = strerror(err);

	  switch(err)
	    { 
	      /*Not enough memory error*/
	    case ENOMEM:
	  
	      c2p_functor("sgml", 1, tmp1); 	
	      tmp = p2p_arg( tmp1, 1);
	      c2p_functor( "resource_error", 1, tmp);
	  
	      c2p_string( "no_memory", p2p_arg( tmp, 1));
	      p2p_unify( tmp1, formal); 
	      break;
	      /*No access error*/
	    case EACCES:
	      { 
		const char *file = va_arg(args,   const char *);
		const char *action = va_arg(args, const char *);

		c2p_functor("sgml", 1, tmp1);
		tmp = p2p_arg( tmp1, 1);

		c2p_functor( "permission_error", 3, tmp);
		c2p_string( (char*)action, p2p_arg(tmp, 1));
		c2p_string( "file", p2p_arg(tmp, 2));
		c2p_string ( (char*)file, p2p_arg(tmp, 3));

		p2p_unify( tmp1, formal);
		break;
	      }
	      /*Entity not found error*/
	    case ENOENT:
	      { 
		const char *file = va_arg(args, const char *);
	 

		c2p_functor("sgml", 1, tmp1);
		tmp = p2p_arg( tmp1, 1);

		c2p_functor( "permission_error", 2, tmp);
	  		  
		c2p_string( "file", p2p_arg(tmp, 1));
		c2p_string ( (char*)file, p2p_arg(tmp, 2));

		p2p_unify( tmp1, formal); 

		break;
	      }
	      /*Defaults to system error*/
	    default:
	      {
	        c2p_functor("sgml", 1, tmp1);
	        tmp = p2p_arg( tmp1, 1);

		c2p_string("system_error", tmp);
		p2p_unify( tmp1, formal);
		break;
	      }
	    }
	  break;
	}
    case ERR_TYPE:
      { 
	const char *expected = va_arg(args, const char*);
	prolog_term actual        = va_arg(args, prolog_term);


	/*Type error*/
	c2p_functor("sgml", 1, tmp1);
        tmp = p2p_arg( tmp1, 1);

	if( is_attv( actual) && strcmp(expected, "variable") != 0 )
	  {
	    c2p_string( "instantiation_error", tmp);
	    p2p_unify( tmp1, formal);
	  }
	else
	  {
	    c2p_functor( "type_error", 2, tmp);
	    c2p_string( (char*)expected, p2p_arg(tmp, 1));
	    p2p_unify ( actual, p2p_arg(tmp, 2));
	    p2p_unify( tmp1, formal);
	  }
	break;
      }	
    case ERR_DOMAIN:				/*Domain error*/
      { 
	const char *expected = va_arg(args, const char*);
	prolog_term actual        = va_arg(args, prolog_term);

	/*Improper domain of functor*/
        c2p_functor("sgml", 1, tmp1);
        tmp = p2p_arg( tmp1, 1);
	
        if( is_attv( actual) && strcmp(expected, "variable") != 0 )
	  {
	    c2p_string( "instantiation_error", tmp);
	    p2p_unify( tmp1, formal);
	  }
        else
	  {
	    c2p_functor( "domain_error", 2, tmp);
	    c2p_string( (char*)expected, p2p_arg(tmp, 1));
	    p2p_unify( actual, p2p_arg(tmp, 2));
	    p2p_unify( tmp1, formal);
	  }
	break;
      }
    case ERR_EXISTENCE:			/*Existence error*/
      { 
	const char *type = va_arg(args, const char *);
	prolog_term obj  = va_arg(args, prolog_term);

	/*Resource not found*/
	c2p_functor("sgml", 1, tmp1);
        tmp = p2p_arg( tmp1, 1);

	c2p_functor( "existence_error", 2, tmp);
                                                                              
        c2p_string( (char*)type, p2p_arg(tmp, 1));
        p2p_unify ( obj, p2p_arg(tmp, 2));
                                                                                
       	p2p_unify( tmp1, formal);
	break;
      }
    case ERR_FAIL:
      { 
	/*Goal failed error*/
	prolog_term goal  = va_arg(args, prolog_term);

	c2p_functor("sgml", 1, tmp1);
	tmp = p2p_arg( tmp1, 1);

        c2p_functor( "goal_failed", 1, tmp);

	p2p_unify( p2p_arg( tmp,1), goal);	
      
       	p2p_unify( tmp1, formal);
	break;
      }
    case ERR_LIMIT:
      { 
	/*Limit exceeded error*/
	const char *limit = va_arg(args, const char *);
	long maxval  = va_arg(args, long);

        c2p_functor("sgml", 1, tmp1);
	tmp = p2p_arg( tmp1, 1);
	
	c2p_functor( "limit_exceeded", 2, tmp);
	c2p_string( (char*)limit, p2p_arg( tmp,1));
	c2p_int( maxval, p2p_arg( tmp, 2));
       	p2p_unify( tmp1, formal);
	break;
      }
    case ERR_MISC:
      { 
	/*Miscellaneous error*/
	const char *id = va_arg(args, const char *);
      
	const char *fmt = va_arg(args, const char *);

	vsprintf(msgbuf, fmt, args);
	msg = msgbuf;

	c2p_functor("sgml", 1, tmp1);
	tmp = p2p_arg( tmp1, 1);

	c2p_functor( "miscellaneous", 1, tmp);
	c2p_string( (char*)id, p2p_arg( tmp, 1));
	p2p_unify( tmp1, formal);
	break; 
      }
    default:
      assert(0);
    }

  va_end(args);

  if ( msg )
    { 
      prolog_term msgterm  = p2p_new();

      if ( msg )
	{ 
	  c2p_string( msg, msgterm);
	}

      tmp = p2p_new();

      c2p_functor( "context", 1, tmp);
      p2p_unify( p2p_arg( tmp, 1), msgterm);	
      p2p_unify( tmp, swi);
    }

  /*Create the error term to throw*/
  tmp = p2p_new();
  c2p_functor( "error", 2, tmp);
  p2p_unify( p2p_arg( tmp, 1), formal);
  p2p_unify( p2p_arg( tmp, 2), swi);
  p2p_unify( tmp, except);
  
  return p2p_unify( global_error_term, except);
}