200 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*************************************************************************
 | 
						|
*									 *
 | 
						|
*	 YAP Prolog 							 *
 | 
						|
*									 *
 | 
						|
*	Yap Prolog was developed at NCCUP - Universidade do Porto	 *
 | 
						|
*									 *
 | 
						|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 *
 | 
						|
*									 *
 | 
						|
**************************************************************************
 | 
						|
*									 *
 | 
						|
* File:		regexp.c						 *
 | 
						|
* Last rev:								 *
 | 
						|
* mods:									 *
 | 
						|
* comments:	regular expression interpreter                           *
 | 
						|
*									 *
 | 
						|
*************************************************************************/
 | 
						|
 | 
						|
#include "config.h"
 | 
						|
#if HAVE_SYS_TYPES_H
 | 
						|
#include <sys/types.h>
 | 
						|
#endif
 | 
						|
#include "YapInterface.h"
 | 
						|
#if HAVE_REGEXEC
 | 
						|
#include "regex.h"
 | 
						|
#define yap_regcomp(A,B,C) regcomp(A,B,C)
 | 
						|
#define yap_regexec(A,B,C,D,E) regexec(A,B,C,D,E)
 | 
						|
#define yap_regfree(A) regfree(A)
 | 
						|
#define yap_regerror(A,B,C,D) regfree(A,B,C,D)
 | 
						|
#else
 | 
						|
#include "yapregex.h"
 | 
						|
#endif
 | 
						|
/* for the sake of NULL */
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
void init_regexp( void );
 | 
						|
 | 
						|
static YAP_Bool check_regexp(void) 
 | 
						|
{
 | 
						|
  unsigned int buflen = (unsigned int)YAP_IntOfTerm(YAP_ARG2)+1;
 | 
						|
  unsigned int sbuflen = (unsigned int)YAP_IntOfTerm(YAP_ARG4)+1;
 | 
						|
  char *buf, *sbuf;
 | 
						|
  regex_t reg;
 | 
						|
  int out;
 | 
						|
  int yap_flags = YAP_IntOfTerm(YAP_ARG5);
 | 
						|
  int regcomp_flags = REG_NOSUB|REG_EXTENDED;
 | 
						|
  
 | 
						|
  if ((buf = (char *)YAP_AllocSpaceFromYap(buflen)) == NULL) {
 | 
						|
    /* early exit */
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  if (YAP_StringToBuffer(YAP_ARG1,buf,buflen) == FALSE) {
 | 
						|
    /* something went wrong, possibly a type checking error */
 | 
						|
    YAP_FreeSpaceFromYap(buf);
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  if (yap_flags & 1)
 | 
						|
    regcomp_flags |= REG_ICASE;
 | 
						|
  /* cool, now I have my string in the buffer, let's have some fun */
 | 
						|
  if (yap_regcomp(®,buf, regcomp_flags) != 0)
 | 
						|
    return(FALSE);
 | 
						|
  if ((sbuf = (char *)YAP_AllocSpaceFromYap(sbuflen)) == NULL) {
 | 
						|
    /* early exit */
 | 
						|
    yap_regfree(®);
 | 
						|
    YAP_FreeSpaceFromYap(buf);
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  if (YAP_StringToBuffer(YAP_ARG3,sbuf,sbuflen) == FALSE) {
 | 
						|
    /* something went wrong, possibly a type checking error */
 | 
						|
    yap_regfree(®);
 | 
						|
    YAP_FreeSpaceFromYap(buf);
 | 
						|
    YAP_FreeSpaceFromYap(sbuf); 
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  out = yap_regexec(®,sbuf,0,NULL,0);
 | 
						|
  yap_regfree(®);
 | 
						|
  YAP_FreeSpaceFromYap(buf);
 | 
						|
  YAP_FreeSpaceFromYap(sbuf); 
 | 
						|
  if (out != 0 && out != REG_NOMATCH) {
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  return(out == 0);
 | 
						|
}
 | 
						|
 | 
						|
static YAP_Bool regexp(void) 
 | 
						|
{
 | 
						|
  unsigned int buflen = (unsigned int)YAP_IntOfTerm(YAP_ARG2)+1;
 | 
						|
  unsigned int sbuflen = (unsigned int)YAP_IntOfTerm(YAP_ARG4)+1;
 | 
						|
  char *buf, *sbuf;
 | 
						|
  regex_t reg;
 | 
						|
  int out;
 | 
						|
  size_t nmatch;
 | 
						|
  regmatch_t *pmatch;
 | 
						|
  long int tout;
 | 
						|
  int yap_flags = YAP_IntOfTerm(YAP_ARG5);
 | 
						|
  int regcomp_flags = REG_EXTENDED;
 | 
						|
  
 | 
						|
  
 | 
						|
  if ((buf = (char *)YAP_AllocSpaceFromYap(buflen)) == NULL) {
 | 
						|
    /* early exit */
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  if (YAP_StringToBuffer(YAP_ARG1,buf,buflen) == FALSE) {
 | 
						|
    /* something went wrong, possibly a type checking error */
 | 
						|
    YAP_FreeSpaceFromYap(buf);
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  if (yap_flags & 1)
 | 
						|
    regcomp_flags |= REG_ICASE;
 | 
						|
  /* cool, now I have my string in the buffer, let's have some fun */
 | 
						|
  if (yap_regcomp(®,buf, regcomp_flags) != 0) {
 | 
						|
    YAP_FreeSpaceFromYap(buf);
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  if (YAP_IsVarTerm(YAP_ARG7)) {
 | 
						|
    nmatch = reg.re_nsub;
 | 
						|
  } else {
 | 
						|
    nmatch = YAP_IntOfTerm(YAP_ARG7);
 | 
						|
  }
 | 
						|
  if ((sbuf = (char *)YAP_AllocSpaceFromYap(sbuflen)) == NULL) {
 | 
						|
    /* early exit */
 | 
						|
    yap_regfree(®);
 | 
						|
    YAP_FreeSpaceFromYap(buf);
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  if (YAP_StringToBuffer(YAP_ARG3,sbuf,sbuflen) == FALSE) {
 | 
						|
    /* something went wrong, possibly a type checking error */
 | 
						|
    yap_regfree(®);
 | 
						|
    YAP_FreeSpaceFromYap(buf);
 | 
						|
    YAP_FreeSpaceFromYap(sbuf); 
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  pmatch = YAP_AllocSpaceFromYap(sizeof(regmatch_t)*(nmatch));
 | 
						|
  out = yap_regexec(®,sbuf,nmatch,pmatch,0);
 | 
						|
  if (out == 0) {
 | 
						|
    /* match succeed, let's fill the match in */
 | 
						|
    long int i;
 | 
						|
    YAP_Term TNil = YAP_MkAtomTerm(YAP_LookupAtom("[]"));
 | 
						|
    YAP_Functor FDiff = YAP_MkFunctor(YAP_LookupAtom("-"),2);
 | 
						|
 | 
						|
    tout = TNil;
 | 
						|
    for (i = nmatch-1; i >= 0; --i) {
 | 
						|
      int j;
 | 
						|
      YAP_Term t = TNil;
 | 
						|
 | 
						|
      if (pmatch[i].rm_so != -1) {
 | 
						|
	if (yap_flags & 2) {
 | 
						|
	  YAP_Term to[2];
 | 
						|
	  to[0] = YAP_MkIntTerm(pmatch[i].rm_so);
 | 
						|
	  to[1] = YAP_MkIntTerm(pmatch[i].rm_eo);
 | 
						|
	  t = YAP_MkApplTerm(FDiff,2,to);
 | 
						|
	} else {
 | 
						|
	  for (j = pmatch[i].rm_eo-1; j >= pmatch[i].rm_so; j--) {
 | 
						|
	    t = YAP_MkPairTerm(YAP_MkIntTerm(sbuf[j]),t);
 | 
						|
	  }
 | 
						|
	}
 | 
						|
	tout = YAP_MkPairTerm(t,tout);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    out = !YAP_Unify(tout, YAP_ARG6);
 | 
						|
  }
 | 
						|
  else if (out != REG_NOMATCH) {
 | 
						|
    out = 0;
 | 
						|
  }
 | 
						|
  yap_regfree(®);
 | 
						|
  YAP_FreeSpaceFromYap(buf);
 | 
						|
  YAP_FreeSpaceFromYap(sbuf); 
 | 
						|
  YAP_FreeSpaceFromYap(pmatch); 
 | 
						|
  return(out == 0);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
init_regexp(void)
 | 
						|
{
 | 
						|
  YAP_UserCPredicate("check_regexp", check_regexp, 5);
 | 
						|
  YAP_UserCPredicate("check_regexp", regexp, 7);
 | 
						|
}
 | 
						|
 | 
						|
#if __WINDOWS__
 | 
						|
 | 
						|
#include <windows.h>
 | 
						|
 | 
						|
int WINAPI win_regexp(HANDLE, DWORD, LPVOID);
 | 
						|
 | 
						|
int WINAPI win_regexp(HANDLE hinst, DWORD reason, LPVOID reserved)
 | 
						|
{
 | 
						|
  switch (reason) 
 | 
						|
    {
 | 
						|
    case DLL_PROCESS_ATTACH:
 | 
						|
      break;
 | 
						|
    case DLL_PROCESS_DETACH:
 | 
						|
      break;
 | 
						|
    case DLL_THREAD_ATTACH:
 | 
						|
      break;
 | 
						|
    case DLL_THREAD_DETACH:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
#endif
 |