/*  filo -- manipulate a `rolodex'-like database
 *  Copyright (C) 1994 David Deaven, Jennifer Corkill
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: regular.c,v 1.3 1996/05/09 22:03:25 deaven Exp $
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "dmd/memory.h"
#include "filo.h"

#if defined(SUN_REGEXP)		/* SunOS 4.3 (very old) */

#include <string.h>
char *re_comp(char *s);
int re_exec(char *s);
static int icase = 0;

#elif defined(OLD_REGEXP)	/* old BSD */

#include <regexp.h>
static regexp *exp;
static int icase = 0;

#else				/* POSIX 1003.2 compliant */

#include <sys/types.h>
#include <regex.h>
static regex_t TheExp;

static void Error(int code)
{
	char buf[256];
	regerror(code, &TheExp, buf, 256);
	fprintf(stderr, "error: %s\n", buf);
	exit(1);
}

#endif

/* Compile a regular expression so that RegExpCompare() can evaluate
 * it against strings.
 */
void RegExpCompile(char *pattern, int ignore_case)
{
#if defined(SUN_REGEXP)
      int i;
      char *error;
      if(ignore_case)
      {
	for(i=0; pattern[i] != '\0'; ++i) pattern[i] = tolower(pattern[i]);
	icase = 1;
      }
      else
	icase = 0;
      if((error = re_comp(pattern)) != NULL)
      {
	fprintf(stderr, "error: re_comp() error `%s' on `%s'\n", error, pattern);
	exit(1);
      }

#elif defined(OLD_REGEXP)
      int i;
      if(ignore_case)
      {
	for(i=0; pattern[i] != '\0'; ++i) pattern[i] = tolower(pattern[i]);
	icase = 1;
      }
      else
	icase = 0;
      if((exp = regcomp(pattern))==NULL)
      {
	fprintf(stderr, "error: regcomp() error on `%s'\n", pattern);
	exit(1);
      }

#else
      int r, cflags = REG_EXTENDED | REG_NOSUB;
      if(ignore_case) cflags |= REG_ICASE;
      if((r = regcomp(&TheExp, pattern, cflags))) Error(r);
#endif
}

/* Return zero if the given string is not matched by the regular
 * expression, and 1 if it is.
 */
int RegExpCompare(char *s)
{
#if defined(SUN_REGEXP) || defined(OLD_REGEXP)
    int i;
    static char *sp;
    static int lp = 0;
    if(icase)
    {
      if(lp == 0)
	sp = mymalloc((lp = strlen(s)) * sizeof(char));
      else if( strlen(s) > lp ) 
	sp = myrealloc(sp, ((lp = strlen(s)) + 1) * sizeof(char));

      for(i=0; s[i] != '\0'; ++i) 
	sp[i] = tolower(s[i]);
      
      sp[i] = '\0';

    } 
    else
    {
      if(lp > 0) { free(sp); lp = 0; }
      sp = s;
    }

#if defined(SUN_REGEXP)
    return re_exec(sp);
#elif defined(OLD_REGEXP)
    return regexec(exp, sp);
#endif

#else
    int r, eflags = 0;
    r = regexec(&TheExp, s, (int) 0, (regmatch_t *) NULL, eflags);
    switch(r) {
      case REG_NOMATCH: return 0;
      case 0:		return 1;
      default:		Error(r);
    }
#endif
    return 0;
}
