//=-- Regex.cpp - Regular Expressions for C++ --------------------------------=
//
// Regular expressions are a cool toy used for filter matching.  This class
// interfaces to the C implementation of a regexp package named "pcre".
// pcre is a so called "perl compatible regular expression" library, that is
// free for all uses.  This library is statically linked in, source is in the
// pcregex directory.
//
// After a regex is created, the error should be checked to see if it was 
// successful or not.
//
//=---------------------------------------------------------------------------=
//  This file is copyright (c) 1997-2000 Chris Lattner
//=---------------------------------------------------------------------------=

#include <malloc.h>
#include <string.h>

#include "Regex.h"
#include "PCRE/pcre.h"

regex::regex(const char *pattern) {
  int ErrorOffset;
  int Flags = PCRE_DOTALL;

  Compiled = pcre_compile(pattern, Flags, &ErrorMessage, &ErrorOffset, 0);
  
  if (ErrorMessage == 0)
    ExtraInfo = pcre_study(Compiled, 0, &ErrorMessage);
}

int regex::CompileNew(const char *pattern) {
  int ErrorOffset;
  free(Compiled);    // Free previously used memory...

  Compiled = pcre_compile(pattern, PCRE_DOTALL, &ErrorMessage, &ErrorOffset, 0);

  if (ErrorMessage == 0)
    ExtraInfo = pcre_study(Compiled, 0, &ErrorMessage);

  return ErrorMessage != 0;
}


regex::~regex() {
  free(Compiled);
}

int regex::Execute(const char *string) {
  int Captured[21];
  int Error;

  LastString = string;

  Error = pcre_exec(Compiled, ExtraInfo, string, strlen(string), 
                    0, Captured, 21);

  if (Error == PCRE_ERROR_NOMATCH)
    return 0;

  if (Error < 1) return -1;  // Error of some sort.
  return 1;
}

int regex::FindMatch(const char *string, int *From, int *To) {
  int Captured[21];
  int Error;

  *From = *To = -1;
  LastString = string;

  Error = pcre_exec(Compiled, ExtraInfo, string, strlen(string), 
                    0, Captured, 21);

  if (Error == PCRE_ERROR_NOMATCH)
    return 0;

  if (Error < 1) return -1;  // Error of some other sort.

  *From = Captured[0];
  *To = Captured[1];
  return 1;
}


const char *regex::GetErrorMessage() {
  return ErrorMessage;
}
