Index: gtksourceview/gtksourcebuffer.c
===================================================================
RCS file: /cvs/gnome/gtksourceview/gtksourceview/gtksourcebuffer.c,v
retrieving revision 1.23
diff -u -p -r1.23 gtksourcebuffer.c
--- gtksourceview/gtksourcebuffer.c	2 May 2003 17:27:49 -0000	1.23
+++ gtksourceview/gtksourcebuffer.c	8 May 2003 12:36:21 -0000
@@ -118,7 +118,7 @@ struct _GtkSourceBufferPrivate 
 
 	GList                 *syntax_items;
 	GList                 *pattern_items;
-	GtkSourceRegex         reg_syntax_all;
+	GtkSourceRegex        *reg_syntax_all;
 	gunichar               escape_char;
 
 	/* Region covering the unhighlighted text */
@@ -528,8 +528,10 @@ gtk_source_buffer_finalize (GObject *obj
 	if (buffer->priv->old_syntax_regions)
 		g_array_free (buffer->priv->old_syntax_regions, TRUE);
 	
-	if (buffer->priv->reg_syntax_all.len > 0)
-		gtk_source_regex_destroy (&buffer->priv->reg_syntax_all);
+	if (buffer->priv->reg_syntax_all) {
+		gtk_source_regex_destroy (buffer->priv->reg_syntax_all);
+		buffer->priv->reg_syntax_all = NULL;
+	}
 	
 	g_list_free (buffer->priv->syntax_items);
 	g_list_free (buffer->priv->pattern_items);
@@ -930,11 +932,12 @@ sync_with_tag_table (GtkSourceBuffer *bu
 	}
 	else
 	{
-		if (buffer->priv->reg_syntax_all.len > 0)
-			gtk_source_regex_destroy (&buffer->priv->reg_syntax_all);
+		if (buffer->priv->reg_syntax_all) {
+			gtk_source_regex_destroy (buffer->priv->reg_syntax_all);
+			buffer->priv->reg_syntax_all = NULL;
+		}
 	}
 
-
 	if (buffer->priv->highlight)
 		invalidate_syntax_regions (buffer, NULL, 0);
 }
@@ -961,10 +964,10 @@ sync_syntax_regex (GtkSourceBuffer *buff
 			g_string_append (str, "\\|");
 	}
 
-	if (buffer->priv->reg_syntax_all.len > 0)
-		gtk_source_regex_destroy (&buffer->priv->reg_syntax_all);
+	if (buffer->priv->reg_syntax_all)
+		gtk_source_regex_destroy (buffer->priv->reg_syntax_all);
 	
-	gtk_source_regex_compile (&buffer->priv->reg_syntax_all, str->str);
+	buffer->priv->reg_syntax_all = gtk_source_regex_compile (str->str);
 
 	g_string_free (str, TRUE);
 }
@@ -1412,7 +1415,7 @@ get_syntax_start (GtkSourceBuffer      *
 	do {
 		/* check for any of the syntax highlights */
 		pos = gtk_source_regex_search (
-			&source_buffer->priv->reg_syntax_all,
+			source_buffer->priv->reg_syntax_all,
 			text,
 			pos,
 			length,
@@ -1426,14 +1429,10 @@ get_syntax_start (GtkSourceBuffer      *
 		return NULL;
 
 	while (list != NULL) {
-		gint l;
-		
 		tag = list->data;
 		
-		l = gtk_source_regex_match (&tag->reg_start, text,
-					    length, pos);
-
-		if (l >= 0)
+		if (gtk_source_regex_match (tag->reg_start, text,
+					    pos, match->endpos))
 			return tag;
 
 		list = g_list_next (list);
@@ -1461,7 +1460,7 @@ get_syntax_end (GtkSourceBuffer      *so
 	
 	pos = 0;
 	do {
-		pos = gtk_source_regex_search (&tag->reg_end, text, pos,
+		pos = gtk_source_regex_search (tag->reg_end, text, pos,
 					       length, match);
 		if (pos < 0 || !is_escaped (source_buffer, text, match->startindex))
 			break;
@@ -2137,7 +2136,7 @@ search_patterns (GList       *matches,
 		}
 		
 		/* do the regex search on @text */
-		i = gtk_source_regex_search (&tag->reg_pattern,
+		i = gtk_source_regex_search (tag->reg_pattern,
 					     text,
 					     0,
 					     length,
Index: gtksourceview/gtksourceregex.c
===================================================================
RCS file: /cvs/gnome/gtksourceview/gtksourceview/gtksourceregex.c,v
retrieving revision 1.2
diff -u -p -r1.2 gtksourceregex.c
--- gtksourceview/gtksourceregex.c	2 May 2003 17:27:52 -0000	1.2
+++ gtksourceview/gtksourceregex.c	8 May 2003 12:36:21 -0000
@@ -22,6 +22,8 @@
 #include <config.h>
 #endif
 
+#include <sys/types.h>
+#include <regex.h>
 #include <string.h>
 #include <stdlib.h>
 #include <glib.h>
@@ -29,17 +31,26 @@
 #include "gtksourceview-i18n.h"
 #include "gtksourceregex.h"
 
+/* #define USE_GNU_REGEX */
 
-gboolean
-gtk_source_regex_compile (GtkSourceRegex *regex, const gchar *pattern)
+#ifdef USE_GNU_REGEX
+
+/* Implementation using GNU Regular Expressions */
+
+struct _GtkSourceRegex 
 {
-	g_return_val_if_fail (pattern != NULL, FALSE);
-	g_return_val_if_fail (regex != NULL, FALSE);
+	struct re_pattern_buffer buf;
+	struct re_registers 	 reg;
+};
 
-	memset (&regex->buf, 0, sizeof (regex->buf));
-	memset (&regex->reg, 0, sizeof (regex->reg));
+GtkSourceRegex *
+gtk_source_regex_compile (const gchar *pattern)
+{
+	GtkSourceRegex *regex;
 	
-	regex->len = strlen (pattern);
+	g_return_val_if_fail (pattern != NULL, FALSE);
+
+	regex = g_new0 (GtkSourceRegex, 1);
 
 	regex->buf.translate = NULL;
 	regex->buf.fastmap = g_malloc (256);
@@ -57,22 +68,24 @@ gtk_source_regex_compile (GtkSourceRegex
 			regex->buf.fastmap = NULL;
 		}
 
-		return TRUE;
+		return regex;
 	} else {
+		g_free (regex->buf.fastmap);
+		g_free (regex);
 		g_warning ("Regex failed to compile.");
-		return FALSE;
+		return NULL;
 	}
 }
 
 void
 gtk_source_regex_destroy (GtkSourceRegex *regex)
 {
-	g_return_if_fail (regex != NULL);
+	if (regex == NULL)
+		return;
 
 	g_free (regex->buf.fastmap);
 	regex->buf.fastmap = NULL;
 	regfree (&regex->buf);
-	regex->len = 0;
 	if (regex->reg.num_regs > 0) {
 		
 		/* FIXME: maybe we should pre-allocate the registers
@@ -82,6 +95,7 @@ gtk_source_regex_destroy (GtkSourceRegex
 		free (regex->reg.end);
 		regex->reg.num_regs = 0;
 	}
+	g_free (regex);
 }
 
 /**
@@ -144,13 +158,13 @@ gtk_source_regex_search (GtkSourceRegex 
 /*
  * pos: offset
  * 
- * Returns: number of bytes matched
+ * Returns: if @regex matched @text 
  */
-gint
+gboolean 
 gtk_source_regex_match (GtkSourceRegex *regex,
-			const gchar    *text, 
-			gint            length, 
-			gint            pos)
+			const gchar    *text,
+			gint            pos,
+			gint            length)
 {
 	g_return_val_if_fail (regex != NULL, -1);
 	g_return_val_if_fail (pos >= 0, -1);
@@ -160,8 +174,139 @@ gtk_source_regex_match (GtkSourceRegex *
 	
 	pos = g_utf8_offset_to_pointer (text, pos) - text;
 
-	return re_match (&regex->buf, text, length, pos,
-			 &regex->reg);
+	return (re_match (&regex->buf, text, length, pos,
+			  &regex->reg) > 0);
+}
+
+#else /* USE_GNU_REGEX */
+
+/* Implementation using POSIX regular expressions */
+
+struct _GtkSourceRegex 
+{
+	regex_t     preg;
+	regmatch_t  pmatch;
+};
+
+GtkSourceRegex *
+gtk_source_regex_compile (const gchar *pattern)
+{
+	GtkSourceRegex *regex;
+	
+	g_return_val_if_fail (pattern != NULL, FALSE);
+
+	regex = g_new0 (GtkSourceRegex, 1);
+
+	regex->preg.translate = NULL;
+	regex->preg.fastmap = NULL;
+	regex->preg.allocated = 0;
+	regex->preg.buffer = NULL;
+	regex->preg.can_be_null = 0;	/* so we wont allow that in patterns! */
+	regex->preg.no_sub = 0;
+	
+	if (regcomp (&regex->preg, pattern, REG_NEWLINE) == 0) {
+		return regex;
+	} else {
+		g_free (regex);
+		g_warning ("Regex failed to compile.");
+		return NULL;
+	}
 }
 
+void
+gtk_source_regex_destroy (GtkSourceRegex *regex)
+{
+	if (regex == NULL)
+		return;
+
+	regfree (&regex->preg);
+	g_free (regex);
+}
+
+/**
+ * gtk_source_regex_search:
+ * @regex: Regular expression object (GtkSourceRegex)
+ * @text: Buffer to search
+ * @pos: Offset position (i.e. character offset, not byte offset)
+ * @length: Length in bytes; -1 for the full text length
+ * @match: (optional) Where to return match information
+ * 
+ * Return value: the offset where a match occurred, or less than 0 for
+ * errors or no match.
+ **/
+gint 
+gtk_source_regex_search (GtkSourceRegex       *regex,
+			 const gchar          *text,
+			 gint                  pos,
+			 gint                  length,
+			 GtkSourceBufferMatch *match)
+{
+	gint res;
+	gchar *ptr = NULL;
+	
+	g_return_val_if_fail (regex != NULL, -2);
+	g_return_val_if_fail (text != NULL, -2);
+	g_return_val_if_fail (pos >= 0, -2);
+
+	if (length < 0)
+	{
+		length = strlen (text);
+	}
+	else if (length < strlen (text))
+	{
+		ptr = g_strndup (text, length);
+		text = ptr;
+	}
+
+	/* convert pos from offset to byte index */
+	if (pos > 0)
+	{
+		pos = g_utf8_offset_to_pointer (text, pos) - text;
+		g_assert (pos < length);
+	}
+	
+	res = regexec (&regex->preg, text + pos, 1, &regex->pmatch, 0);
+	
+	if (res == REG_NOMATCH)
+	{
+		res = -1;
+	}
+	else
+	{
+		res = g_utf8_pointer_to_offset (text, text + pos + regex->pmatch.rm_so);
+		if (match != NULL) {
+			match->startindex = regex->pmatch.rm_so + pos;
+			match->endindex = regex->pmatch.rm_eo + pos;
+			
+			match->startpos = res;
+			match->endpos = match->startpos +
+				g_utf8_pointer_to_offset (text + pos + regex->pmatch.rm_so,
+							  text + pos + regex->pmatch.rm_eo);
+		}
+	}
+	
+	g_free (ptr);
+	
+	return res;
+}
+
+/* regex_match -- tries to match regex at the 'pos' position in the text. It 
+ * returns the number of chars matched, or -1 if no match. 
+ * Warning: The number matched can be 0, if the regex matches the empty string.
+ */
+
+/*
+ * pos: offset
+ * 
+ * Returns: if @regex matched @text 
+ */
+gboolean 
+gtk_source_regex_match (GtkSourceRegex *regex,
+			const gchar    *text,
+			gint            pos,
+			gint            length)
+{
+	return (gtk_source_regex_search (regex, text, pos, length, NULL) == pos);
+}
 
+#endif /* USE_GNU_REGEX */
Index: gtksourceview/gtksourceregex.h
===================================================================
RCS file: /cvs/gnome/gtksourceview/gtksourceview/gtksourceregex.h,v
retrieving revision 1.2
diff -u -p -r1.2 gtksourceregex.h
--- gtksourceview/gtksourceregex.h	2 May 2003 17:27:52 -0000	1.2
+++ gtksourceview/gtksourceregex.h	8 May 2003 12:36:22 -0000
@@ -20,7 +20,6 @@
 #ifndef __GTK_SOURCE_REGEX_H__
 #define __GTK_SOURCE_REGEX_H__
 
-#include <regex.h>
 #include <glib/gtypes.h>
 
 G_BEGIN_DECLS
@@ -37,15 +36,7 @@ struct _GtkSourceBufferMatch
 	gint			 endindex;
 };
 
-struct _GtkSourceRegex 
-{
-	struct re_pattern_buffer buf;
-	struct re_registers 	 reg;
-	gint			 len;
-};
-
-gboolean 	gtk_source_regex_compile 	(GtkSourceRegex       *regex,
-						 const gchar          *pattern);
+GtkSourceRegex *gtk_source_regex_compile 	(const gchar          *pattern);
 
 void		gtk_source_regex_destroy	(GtkSourceRegex       *regex);
 
@@ -55,10 +46,10 @@ gint		gtk_source_regex_search 	(GtkSourc
 						 gint                  length,
 			 			 GtkSourceBufferMatch *match);
 
-gint		gtk_source_regex_match 		(GtkSourceRegex       *regex,
-						 const gchar          *text, 
-						 gint                  len, 
-						 gint                  pos);
+gboolean        gtk_source_regex_match          (GtkSourceRegex       *regex,
+						 const gchar          *text,
+						 gint                  pos,
+						 gint                  len);
 
 G_END_DECLS
 
Index: gtksourceview/gtksourcetag-private.h
===================================================================
RCS file: /cvs/gnome/gtksourceview/gtksourceview/gtksourcetag-private.h,v
retrieving revision 1.3
diff -u -p -r1.3 gtksourcetag-private.h
--- gtksourceview/gtksourcetag-private.h	4 May 2003 22:43:57 -0000	1.3
+++ gtksourceview/gtksourcetag-private.h	8 May 2003 12:36:22 -0000
@@ -48,8 +48,8 @@ struct _GtkSyntaxTag 
 	GtkSourceTag		 parent_instance;
 
 	gchar			*start;  
-	GtkSourceRegex		 reg_start;
-	GtkSourceRegex		 reg_end;
+	GtkSourceRegex		*reg_start;
+	GtkSourceRegex          *reg_end;
 };
 
 struct _GtkSyntaxTagClass 
@@ -61,7 +61,7 @@ struct _GtkPatternTag 
 {
 	GtkSourceTag		 parent_instance;
 
-	GtkSourceRegex		 reg_pattern;
+	GtkSourceRegex		*reg_pattern;
 };
 
 struct _GtkPatternTagClass 
Index: gtksourceview/gtksourcetag.c
===================================================================
RCS file: /cvs/gnome/gtksourceview/gtksourceview/gtksourcetag.c,v
retrieving revision 1.6
diff -u -p -r1.6 gtksourcetag.c
--- gtksourceview/gtksourcetag.c	2 May 2003 17:27:53 -0000	1.6
+++ gtksourceview/gtksourcetag.c	8 May 2003 12:36:22 -0000
@@ -214,14 +214,18 @@ gtk_syntax_tag_new (const gchar *name, 
 					    NULL));
 	
 	tag->start = g_strdup (pattern_start);
-	
-	if (!gtk_source_regex_compile (&tag->reg_start, pattern_start)) {
+
+	tag->reg_start = gtk_source_regex_compile (pattern_start);
+	if (tag->reg_start == NULL) {
 		g_warning ("Regex syntax start pattern failed [%s]", pattern_start);
+		g_object_unref (tag);
 		return NULL;
 	}
 	
-	if (!gtk_source_regex_compile (&tag->reg_end, pattern_end)) {
+	tag->reg_end = gtk_source_regex_compile (pattern_end);
+	if (tag->reg_end == NULL) {
 		g_warning ("Regex syntax end pattern failed [%s]\n", pattern_end);
+		g_object_unref (tag);
 		return NULL;
 	}
 
@@ -237,8 +241,8 @@ gtk_syntax_tag_finalize (GObject *object
 	
 	g_free (tag->start);
 	
-	gtk_source_regex_destroy (&tag->reg_start);
-	gtk_source_regex_destroy (&tag->reg_end);
+	gtk_source_regex_destroy (tag->reg_start);
+	gtk_source_regex_destroy (tag->reg_end);
 
 	G_OBJECT_CLASS (parent_syntax_class)->finalize (object);
 }
@@ -296,8 +300,10 @@ gtk_pattern_tag_new (const gchar *name, 
 					     "name", name,
 					     NULL));
 	
-	if (!gtk_source_regex_compile (&tag->reg_pattern, pattern)) {
+	tag->reg_pattern = gtk_source_regex_compile (pattern);
+	if (tag->reg_pattern == NULL) {
 		g_warning ("Regex pattern failed [%s]\n", pattern);
+		g_object_unref (tag);
 		return NULL;
 	}
 
@@ -311,7 +317,7 @@ gtk_pattern_tag_finalize (GObject *objec
 
 	tag = GTK_PATTERN_TAG (object);
 	
-	gtk_source_regex_destroy (&tag->reg_pattern);
+	gtk_source_regex_destroy (tag->reg_pattern);
 	
 	G_OBJECT_CLASS (parent_pattern_class)->finalize (object);
 }
