Exemple #1
0
/*
  Input:
      Arg1: +Substr
      Arg2: + String
      Arg3: +forward/reverse (checks only f/r)
        f means the first match from the start of String
	r means the first match from the end of String
  Output:
      Arg4: Beg
        Beg is the offset where Substr matches. Must be a variable or an
	integer
      Arg5: End
	End is the offset of the next character after the end of Substr
	Must be a variable or an integer.

      Both Beg and End can be negative, in which case they represent the offset
      from the 2nd character past the end of String.
      For instance, -1 means the next character past the end of String,
      so End = -1 means that Substr must be a suffix of String..

      The meaning of End and of negative offsets is consistent with substring
      and string_substitute predicates.
*/
xsbBool str_match(CTXTdecl)
{
    static char *subptr, *stringptr, *direction, *matchptr;
    static size_t substr_beg, substr_end;
    int reverse=TRUE; /* search in reverse */
    int beg_bos_offset=TRUE; /* measure beg offset from the beg of string */
    int end_bos_offset=TRUE; /* measure end offset from the beg of string */
    Integer str_len, sub_len; /* length of string and substring */
    Cell beg_offset_term, end_offset_term;

    term = ptoc_tag(CTXTc 1);
    term2 = ptoc_tag(CTXTc 2);
    term3 = ptoc_tag(CTXTc 3);
    beg_offset_term = ptoc_tag(CTXTc 4);
    end_offset_term = ptoc_tag(CTXTc 5);
    if (!isatom(term) || !isatom(term2) || !isatom(term3)) {
        xsb_abort("STR_MATCH: Arguments 1,2,3 must be bound to strings");
    }
    subptr = string_val(term);
    stringptr = string_val(term2);
    direction = string_val(term3);

    if (*direction == 'f')
        reverse=FALSE;
    else if (*direction != 'r')
        xsb_abort("STR_MATCH: Argument 3 must be bound to forward/reverse");

    str_len=strlen(stringptr);
    sub_len=strlen(subptr);

    if (isointeger(beg_offset_term)) {
        if (oint_val(beg_offset_term) < 0) {
            beg_bos_offset = FALSE;
        }
    }
    if (isointeger(end_offset_term)) {
        if (oint_val(end_offset_term) < 0) {
            end_bos_offset = FALSE;
        }
    }

    if (reverse)
        matchptr = xsb_strrstr(stringptr, subptr);
    else
        matchptr = strstr(stringptr, subptr);

    if (matchptr == NULL) return FALSE;

    substr_beg = (beg_bos_offset?
                  matchptr - stringptr : -(str_len - (matchptr - stringptr))
                 );
    substr_end = (end_bos_offset?
                  (matchptr - stringptr) + sub_len
                  : -(str_len + 1 - (matchptr - stringptr) - sub_len)
                 );

    return
        (p2p_unify(CTXTc beg_offset_term, makeint(substr_beg))
         && p2p_unify(CTXTc end_offset_term, makeint(substr_end)));
}
Exemple #2
0
xsbBool str_cat(CTXTdecl)
{
    char *str1, *str2, *tmpstr;
    size_t tmpstr_len;

    term = ptoc_tag(CTXTc 1);
    term2 = ptoc_tag(CTXTc 2);
    if (isatom(term) && isatom(term2)) {
        str1 = string_val(term);
        str2 = string_val(term2);
        tmpstr_len = strlen(str1) + strlen(str2) + 1;

        tmpstr = (char *)mem_alloc(tmpstr_len,LEAK_SPACE);
        strcpy(tmpstr, str1);
        strcat(tmpstr, str2);
        str1 = string_find(tmpstr, 1);
        mem_dealloc(tmpstr,tmpstr_len,LEAK_SPACE);
        return atom_unify(CTXTc makestring(str1), ptoc_tag(CTXTc 3));
    } else return FALSE;
}
Exemple #3
0
/*-----------------------------------------------------------------------------*/
void SetBindVal()
{
  RETCODE rc;
  struct Cursor *cur = (struct Cursor *)ptoc_int(2);
  int j = ptoc_int(3);
  Cell BindVal = ptoc_tag(4);

  if (!((j >= 0) && (j < cur->NumBindVars)))
    xsb_exit("Abnormal argument in SetBindVal!");
    
  /* if we're reusing an opened cursor w/ the statement number*/
  /* reallocate BindVar if type has changed (May not be such a good idea?)*/
  if (cur->Status == 2) {
    if (isinteger(BindVal)) {
      if (cur->BindTypes[j] != 0) {
	if (cur->BindTypes[j] != 2) free((void *)cur->BindList[j]);
	cur->BindList[j] = (UCHAR *)malloc(sizeof(int));
	cur->BindTypes[j] = 0;
	rc = SQLBindParameter(cur->hstmt, (short)(j+1), SQL_PARAM_INPUT, 
			      SQL_C_SLONG, SQL_INTEGER,
			      0, 0, (int *)(cur->BindList[j]), 0, NULL);
	if (rc != SQL_SUCCESS) {
	  ctop_int(5,PrintErrorMsg(cur));
	  SetCursorClose(cur);
	  return;
	}
      }
      *((int *)cur->BindList[j]) = oint_val(BindVal);
    } else if (isfloat(BindVal)) {
      if (cur->BindTypes[j] != 1) { 
	/*printf("ODBC: Changing Type: flt to %d\n",cur->BindTypes[j]);*/
	if (cur->BindTypes[j] != 2) free((void *)cur->BindList[j]);
	cur->BindList[j] = (UCHAR *)malloc(sizeof(float));
	cur->BindTypes[j] = 1;
	rc = SQLBindParameter(cur->hstmt, (short)(j+1), SQL_PARAM_INPUT, 
			      SQL_C_FLOAT, SQL_FLOAT,
			      0, 0, (float *)(cur->BindList[j]), 0, NULL);
	if (rc != SQL_SUCCESS) {
	  ctop_int(5,PrintErrorMsg(cur));
	  SetCursorClose(cur);
	  return;
	}
      }
      *((float *)cur->BindList[j]) = (float)float_val(BindVal);
    } else if (isstring(BindVal)) {
      if (cur->BindTypes[j] != 2) { 
	/*printf("ODBC: Changing Type: str to %d\n",cur->BindTypes[j]);*/
	free((void *)cur->BindList[j]);
	cur->BindTypes[j] = 2;
	/* SQLBindParameter will be done anyway*/
      }
      cur->BindList[j] = string_val(BindVal);
    } else if (isconstr(BindVal) && get_arity(get_str_psc(BindVal))==1) {
      letter_flag = 1;
      wcan_disp = 0;
      write_canonical_term(p2p_arg(BindVal,1));
      if (term_string[j]) free(term_string[j]);
      term_string[j] = malloc(wcan_disp+1);
      strncpy(term_string[j],wcan_string,wcan_disp);
      term_string[j][wcan_disp] = '\0';
      cur->BindTypes[j] = 2;
      cur->BindList[j] = term_string[j];
    } else {
      xsb_exit("Unknown bind variable type, %d", cur->BindTypes[j]);
    }
    ctop_int(5,0);
    return;
  }
    
  /* otherwise, memory needs to be allocated in this case*/
  if (isinteger(BindVal)) {
    cur->BindTypes[j] = 0;
    cur->BindList[j] = (UCHAR *)malloc(sizeof(int));
    if (!cur->BindList[j])
      xsb_exit("Not enough memory for an int in SetBindVal!");
    *((int *)cur->BindList[j]) = oint_val(BindVal);
  } else if (isfloat(BindVal)) {
    cur->BindTypes[j] = 1;
    cur->BindList[j] = (UCHAR *)malloc(sizeof(float));
    if (!cur->BindList[j])
      xsb_exit("Not enough memory for a float in SetBindVal!");
    *((float *)cur->BindList[j]) = (float)float_val(BindVal);
  } else if (isstring(BindVal)) {
    cur->BindTypes[j] = 2;
    cur->BindList[j] = string_val(BindVal);
  } else if (isconstr(BindVal) && get_arity(get_str_psc(BindVal))==1) {
      letter_flag = 1;
      wcan_disp = 0;
      write_canonical_term(p2p_arg(BindVal,1));
      if (term_string[j]) free(term_string[j]);
      term_string[j] = malloc(wcan_disp+1);
      strncpy(term_string[j],wcan_string,wcan_disp);
      term_string[j][wcan_disp] = '\0';
      cur->BindTypes[j] = 2;
      cur->BindList[j] = term_string[j];
  } else {
    xsb_exit("Unknown bind variable type, %d", cur->BindTypes[j]);
  }
  ctop_int(5,0);
  return;
}
Exemple #4
0
/*-----------------------------------------------------------------------------*/
void ODBCDataSources()
{
  static SQLCHAR DSN[SQL_MAX_DSN_LENGTH+1];
  static SQLCHAR Description[SQL_MAX_DSN_LENGTH+1];
  RETCODE rc;
  int seq;
  SWORD dsn_size, descr_size;
  Cell op2 = ptoc_tag(3);
  Cell op3 = ptoc_tag(4);

  if (!henv) {
    /* allocate environment handler*/
    rc = SQLAllocEnv(&henv);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
      xsb_error("Environment allocation failed");   
      ctop_int(5,1);
      return;
    }
    LCursor = FCursor = NULL;
    FCurNum = NULL;
    nullStrAtom = makestring(string_find("NULL",1));
  }

  seq = ptoc_int(2);
  
  if (seq == 1) {
    rc = SQLDataSources(henv,SQL_FETCH_FIRST,DSN,
			SQL_MAX_DSN_LENGTH,&dsn_size,
			Description,SQL_MAX_DSN_LENGTH,
			&descr_size);
    if (rc == SQL_NO_DATA_FOUND) {
      ctop_int(5,2);
      return;
    }
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
      xsb_error("Environment allocation failed");   
      ctop_int(5,1);
      return;
    }
  } else {
    rc = SQLDataSources(henv,SQL_FETCH_NEXT,DSN,
			SQL_MAX_DSN_LENGTH,&dsn_size,
			Description,SQL_MAX_DSN_LENGTH,
			&descr_size);
    if (rc == SQL_NO_DATA_FOUND) {
      ctop_int(5,2);
      return;
    }
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
      xsb_error("Environment allocation failed");   
      ctop_int(5,1);
      return;
    }
  }
  XSB_Deref(op2);
  if (isref(op2))
    unify(op2, makestring(string_find(DSN,1)));
  else {
    xsb_error("[ODBCDataSources] Param 2 should be a free variable.");
    ctop_int(5,1);
    return;
  }
  XSB_Deref(op3);
  if (isref(op3))
    unify(op3, makestring(string_find(Description,1)));
  else {
    xsb_error("[ODBCDataSources] Param 3 should be a free variable.");
    ctop_int(5,1);
    return;
  }
  ctop_int(5,0);
  return;
}
Exemple #5
0
/*-----------------------------------------------------------------------------*/
int GetColumn()
{
  struct Cursor *cur = (struct Cursor *)ptoc_int(2);
  int ColCurNum = ptoc_int(3);
  Cell op1;
  Cell op = ptoc_tag(4);
  UDWORD len;

  if (ColCurNum < 0 || ColCurNum >= cur->NumCols) {
    /* no more columns in the result row*/
    ctop_int(5,1);   
    return TRUE;
  }

  ctop_int(5,0);

  /* get the data*/
  if (cur->OutLen[ColCurNum] == SQL_NULL_DATA) {
    /* column value is NULL*/
    return unify(op,nullStrAtom);
  }

  /* convert the string to either integer, float or string*/
  /* according to the column type and pass it back to XSB*/
  switch (ODBCToXSBType(cur->ColTypes[ColCurNum])) {
  case SQL_C_CHAR:
    /* convert the column string to a C string */
    len = ((cur->ColLen[ColCurNum] < cur->OutLen[ColCurNum])?
	   cur->ColLen[ColCurNum]:cur->OutLen[ColCurNum]);
    *(cur->Data[ColCurNum]+len) = '\0';

    /* compare strings here, so don't intern strings unnecessarily*/
    XSB_Deref(op);
    if (isref(op)) 
      return unify(op, makestring(string_find(cur->Data[ColCurNum],1))); 
    if (isconstr(op) && get_arity(get_str_psc(op)) == 1) {
      STRFILE strfile;
      
      op1 = cell(clref_val(op)+1);
      XSB_Deref(op1);
      
      strfile.strcnt = strlen(cur->Data[ColCurNum]);
      strfile.strptr = strfile.strbase = cur->Data[ColCurNum];
      read_canonical_term(NULL,&strfile,op1); /* terminating '.'? */
      return TRUE;
    }
    if (!isstring(op)) return FALSE;
    if (strcmp(string_val(op),cur->Data[ColCurNum])) return FALSE;
    return TRUE;
  case SQL_C_BINARY:
    /* convert the column string to a C string */
    len = ((cur->ColLen[ColCurNum] < cur->OutLen[ColCurNum])?
	   cur->ColLen[ColCurNum]:cur->OutLen[ColCurNum]);
    *(cur->Data[ColCurNum]+len) = '\0';

    /* compare strings here, so don't intern strings unnecessarily*/
    XSB_Deref(op);
    if (isref(op)) 
      return unify(op, makestring(string_find(cur->Data[ColCurNum],1))); 
    if (isconstr(op) && get_arity(get_str_psc(op)) == 1) {
      STRFILE strfile;
      
      op1 = cell(clref_val(op)+1);
      XSB_Deref(op1);
      
      strfile.strcnt = strlen(cur->Data[ColCurNum]);
      strfile.strptr = strfile.strbase = cur->Data[ColCurNum];
      read_canonical_term(NULL,&strfile,op1); /* terminating '.'? */
      return TRUE;
    }
    if (!isstring(op)) return FALSE;
    if (strcmp(string_val(op),cur->Data[ColCurNum])) return FALSE;
    return TRUE;
  case SQL_C_SLONG:
    return unify(op,makeint(*(long *)(cur->Data[ColCurNum])));
  case SQL_C_FLOAT:
    return unify(op,makefloat(*(float *)(cur->Data[ColCurNum])));
  }

  return FALSE;
}