/*
 * This file is part of the Poliqarp suite.
 * 
 * Copyright (C) 2004-2009 by Instytut Podstaw Informatyki Polskiej
 * Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 * Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 * 
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file gpl.txt included in the packaging
 * of this file.  (See http://www.gnu.org/licenses/translations.html for
 * unofficial translations.)
 * 
 * A commercial license is available from IPI PAN (contact
 * Michal.Ciesiolka@ipipan.waw.pl or ipi@ipipan.waw.pl for more
 * information).  Licensees holding a valid commercial license from IPI
 * PAN may use this file in accordance with that license.
 * 
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/*
 * regcomp and regexec - front ends to re_ routines
 *
 * The headers remain, but just about everything else is reworked to
 * cope with UTF-8 like Tcl does...
 *
 */

#include <string.h>

#include "regguts.h"
#include <unibits/unibits.h>

/*
 - regcomp - compile regular expression
 */
int
regcomp(re, str, flags)
regex_t *re;
CONST char *str;
int flags;
{
	Tcl_DString buffer;
	size_t len;
	Tcl_UniChar *wchar;

	Tcl_DStringInit(&buffer);
	wchar = Tcl_UtfToUniCharDString(str, strlen(str), &buffer);
	len = Tcl_DStringLength(&buffer) / sizeof(Tcl_UniChar);

	/* FIXME: this should be configurable 
	 * Commented out on demand.
	 * NB. Case sensitivity seems to be turned off by default... */ 
    /* flags &= ~REG_ICASE; */
	
	return poliqarp_re_comp(re, wchar, len, flags);
}

/**
 * Match a null-terminated string against the precompiled pattern buffer.
 */
int regexec(regex_t *preg, const char *string, size_t nmatch,
   regmatch_t pmatch[], int eflags)
{
	Tcl_DString buffer;
	size_t len;
	Tcl_UniChar *wchar;
	rm_detail_t dummy;
	int res;

   Tcl_DStringInit(&buffer);
   wchar = Tcl_UtfToUniCharDString(string, strlen(string), &buffer);
   len = Tcl_DStringLength(&buffer) / sizeof(Tcl_UniChar);
   dummy.rm_extend.rm_so = -1;
   dummy.rm_extend.rm_eo = -1;
   
   res = poliqarp_re_exec(preg, wchar, len, &dummy, nmatch, pmatch, eflags);

   if (res == 0) {
      size_t i = 0;
      for (i = 0; i < nmatch; i++) {
         regoff_t unicode_offset = 0, byte_offset = 0;
         if (pmatch[i].rm_so == -1)
            continue;
         while (unicode_offset < pmatch[i].rm_so) {
            byte_offset += Tcl_Utf8TotalBytes[(unsigned char) string[byte_offset]];
            unicode_offset++;
         }
         pmatch[i].rm_so = byte_offset;
         assert(pmatch[i].rm_eo >= unicode_offset);
         while (unicode_offset <= pmatch[i].rm_eo) {
            byte_offset += Tcl_Utf8TotalBytes[(unsigned char) string[byte_offset]];
            unicode_offset++;
         }
         pmatch[i].rm_eo = byte_offset - 1;
      }
   }

   return res;
}
