1 /*  gtksourcetag.c
2  *
3  *  Copyright (C) 2001
4  *  Mikael Hermansson<tyan@linux.se>
5  *  Chris Phelps <chicane@reninet.com>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU Library General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Library General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Library General Public License*  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #include <string.h>
22 #include <gtk/gtk.h>
23 #include <vdk/gtksourcetag.h>
24 
25 static GObjectClass *parent_syntax_class = NULL;
26 static GObjectClass *parent_pattern_class = NULL;
27 static GObjectClass *parent_embedded_class = NULL;
28 
29 static void gtk_syntax_tag_init (GtkSyntaxTag *text_tag);
30 static void gtk_syntax_tag_class_init (GtkSyntaxTagClass *text_tag);
31 static void gtk_syntax_tag_finalize (GObject *object);
32 
33 static void gtk_pattern_tag_init (GtkPatternTag *text_tag);
34 static void gtk_pattern_tag_class_init (GtkPatternTagClass *text_tag);
35 static void gtk_pattern_tag_finalize (GObject *object);
36 
37 static void gtk_embedded_tag_init (GtkEmbeddedTag *text_tag);
38 static void gtk_embedded_tag_class_init (GtkEmbeddedTagClass *text_tag);
39 static void gtk_embedded_tag_finalize (GObject *object);
40 
41 
42 GType
gtk_syntax_tag_get_type(void)43 gtk_syntax_tag_get_type (void)
44 {
45 	static GType our_type = 0;
46 
47 	if (our_type == 0) {
48 		static const GTypeInfo our_info = {
49 			sizeof (GtkSyntaxTagClass),
50 			(GBaseInitFunc) NULL,
51 			(GBaseFinalizeFunc) NULL,
52 			(GClassInitFunc) gtk_syntax_tag_class_init,
53 			NULL,	/* class_finalize */
54 			NULL,	/* class_data */
55 			sizeof (GtkSyntaxTag),
56 			0,	/* n_preallocs */
57 			(GInstanceInitFunc) gtk_syntax_tag_init
58 		};
59 
60 		our_type = g_type_register_static (GTK_TYPE_TEXT_TAG, "GtkSyntaxTag", &our_info, 0);
61 	}
62 	return our_type;
63 }
64 
65 static void
gtk_syntax_tag_class_init(GtkSyntaxTagClass * klass)66 gtk_syntax_tag_class_init (GtkSyntaxTagClass *klass)
67 {
68 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
69 
70 	parent_syntax_class = g_type_class_peek_parent (klass);
71 	object_class->finalize = gtk_syntax_tag_finalize;
72 }
73 
74 static void
gtk_syntax_tag_init(GtkSyntaxTag * text_tag)75 gtk_syntax_tag_init (GtkSyntaxTag *text_tag)
76 {
77 	GTK_TEXT_TAG (text_tag)->table = NULL;
78 }
79 
80 GtkTextTag *
gtk_syntax_tag_new(const gchar * name,const gchar * patternstart,const gchar * patternend)81 gtk_syntax_tag_new (const gchar *name, const gchar *patternstart, const gchar *patternend)
82 {
83 	GtkSyntaxTag *tag;
84 
85 	tag = GTK_SYNTAX_TAG (g_object_new (gtk_syntax_tag_get_type (), "name", name, NULL));
86 	tag->start = g_strdup (patternstart);
87 	if (!gtk_source_compile_regex (patternstart, &tag->reg_start))
88 		g_print ("Regex syntax start pattern failed [%s]\n", patternstart);
89 	if (!gtk_source_compile_regex (patternend, &tag->reg_end))
90 		g_print ("Regex syntax end pattern failed [%s]\n", patternend);
91 	return GTK_TEXT_TAG (tag);
92 }
93 
94 static void
gtk_syntax_tag_finalize(GObject * object)95 gtk_syntax_tag_finalize (GObject *object)
96 {
97 	GtkSyntaxTag *tag;
98 
99 	tag = GTK_SYNTAX_TAG (object);
100 	if (tag->start)
101 		g_free (tag->start);
102 	g_free (tag->reg_start.buf.fastmap);
103 	tag->reg_start.buf.fastmap = NULL;
104 	regfree (&tag->reg_start.buf);
105 	g_free (tag->reg_end.buf.fastmap);
106 	tag->reg_end.buf.fastmap = NULL;
107 	regfree (&tag->reg_end.buf);
108 	(*G_OBJECT_CLASS (parent_syntax_class)->finalize) (object);
109 }
110 
111 /* Pattern Tag */
112 
113 GType
gtk_pattern_tag_get_type(void)114 gtk_pattern_tag_get_type (void)
115 {
116 	static GType our_type = 0;
117 
118 	if (our_type == 0) {
119 		static const GTypeInfo our_info = {
120 			sizeof (GtkPatternTagClass),
121 			(GBaseInitFunc) NULL,
122 			(GBaseFinalizeFunc) NULL,
123 			(GClassInitFunc) gtk_pattern_tag_class_init,
124 			NULL,	/* class_finalize */
125 			NULL,	/* class_data */
126 			sizeof (GtkPatternTag),
127 			0,	/* n_preallocs */
128 			(GInstanceInitFunc) gtk_pattern_tag_init
129 		};
130 
131 		our_type =
132 			g_type_register_static (GTK_TYPE_TEXT_TAG, "GtkPatternTag", &our_info, 0);
133 	}
134 	return (our_type);
135 }
136 
137 static void
gtk_pattern_tag_init(GtkPatternTag * text_tag)138 gtk_pattern_tag_init (GtkPatternTag *text_tag)
139 {
140 
141 }
142 
143 static void
gtk_pattern_tag_class_init(GtkPatternTagClass * klass)144 gtk_pattern_tag_class_init (GtkPatternTagClass *klass)
145 {
146 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
147 
148 	parent_pattern_class = g_type_class_peek_parent (klass);
149 	object_class->finalize = gtk_pattern_tag_finalize;
150 }
151 
152 GtkTextTag *
gtk_pattern_tag_new(const gchar * name,const gchar * pattern)153 gtk_pattern_tag_new (const gchar *name, const gchar *pattern)
154 {
155 	GtkPatternTag *tag;
156 
157 	tag = GTK_PATTERN_TAG (g_object_new (gtk_pattern_tag_get_type (), "name", name, NULL));
158 	if (!gtk_source_compile_regex (pattern, &tag->reg_pattern))
159 		g_print ("Regex pattern failed [%s]\n", pattern);
160 	return GTK_TEXT_TAG (tag);
161 }
162 
163 void
gtk_pattern_tag_finalize(GObject * object)164 gtk_pattern_tag_finalize (GObject *object)
165 {
166 	GtkPatternTag *tag;
167 
168 	tag = GTK_PATTERN_TAG (object);
169 	g_free (tag->reg_pattern.buf.fastmap);
170 	tag->reg_pattern.buf.fastmap = NULL;
171 	regfree (&tag->reg_pattern.buf);
172 	(*G_OBJECT_CLASS (parent_pattern_class)->finalize) (object);
173 }
174 
175 /* Embedded Tags */
176 
177 GType
gtk_embedded_tag_get_type(void)178 gtk_embedded_tag_get_type (void)
179 {
180 	static GType our_type = 0;
181 
182 	if (our_type == 0) {
183 		static const GTypeInfo our_info = {
184 			sizeof (GtkEmbeddedTagClass),
185 			(GBaseInitFunc) NULL,
186 			(GBaseFinalizeFunc) NULL,
187 			(GClassInitFunc) gtk_embedded_tag_class_init,
188 			NULL,	/* class_finalize */
189 			NULL,	/* class_data */
190 			sizeof (GtkEmbeddedTag),
191 			0,	/* n_preallocs */
192 			(GInstanceInitFunc) gtk_embedded_tag_init
193 		};
194 
195 		our_type =
196 			g_type_register_static (GTK_TYPE_TEXT_TAG, "GtkEmbeddedTag", &our_info, 0);
197 	}
198 	return our_type;
199 }
200 
201 static void
gtk_embedded_tag_class_init(GtkEmbeddedTagClass * klass)202 gtk_embedded_tag_class_init (GtkEmbeddedTagClass *klass)
203 {
204 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
205 
206 	parent_embedded_class = g_type_class_peek_parent (klass);
207 	object_class->finalize = gtk_embedded_tag_finalize;
208 }
209 
210 static void
gtk_embedded_tag_init(GtkEmbeddedTag * text_tag)211 gtk_embedded_tag_init (GtkEmbeddedTag *text_tag)
212 {
213 
214 }
215 
216 GtkTextTag *
gtk_embedded_tag_new(const gchar * name,const gchar * outside,const gchar * inside)217 gtk_embedded_tag_new (const gchar *name, const gchar *outside, const gchar *inside)
218 {
219 	GtkEmbeddedTag *tag;
220 
221 	tag = GTK_EMBEDDED_TAG (g_object_new (GTK_TYPE_EMBEDDED_TAG, "name", name, NULL));
222 	if (!gtk_source_compile_regex (outside, &tag->reg_outside))
223 		g_print ("Regex embedded outside pattern failed [%s]\n", outside);
224 	if (!gtk_source_compile_regex (inside, &tag->reg_inside))
225 		g_print ("Regex embedded inside pattern failed [%s]\n", inside);
226 	return GTK_TEXT_TAG (tag);
227 }
228 
229 static void
gtk_embedded_tag_finalize(GObject * object)230 gtk_embedded_tag_finalize (GObject *object)
231 {
232 	GtkEmbeddedTag *tag;
233 
234 	tag = GTK_EMBEDDED_TAG (object);
235 	g_free (tag->reg_outside.buf.fastmap);
236 	tag->reg_outside.buf.fastmap = NULL;
237 	regfree (&tag->reg_outside.buf);
238 	g_free (tag->reg_inside.buf.fastmap);
239 	tag->reg_inside.buf.fastmap = NULL;
240 	regfree (&tag->reg_inside.buf);
241 	(*G_OBJECT_CLASS (parent_embedded_class)->finalize) (object);
242 }
243 
244 /* Generic Functions */
245 
246 gboolean
gtk_source_compile_regex(const gchar * pattern,Regex * regex)247 gtk_source_compile_regex (const gchar *pattern, Regex *regex)
248 {
249 	if (!pattern)
250 		return (FALSE);
251 	memset (&regex->buf, 0, sizeof (regex->buf));
252 	regex->len = strlen (pattern);
253 	regex->buf.translate = NULL;
254 	regex->buf.fastmap = g_malloc (256);
255 	regex->buf.allocated = 0;
256 	regex->buf.buffer = NULL;
257 	regex->buf.can_be_null = 0;	/* so we wont allow that in patterns! */
258 	regex->buf.no_sub = 0;
259 	if (re_compile_pattern (pattern, strlen (pattern), &regex->buf) == 0) {
260 		/* success...now try to compile a fastmap */
261 		if (re_compile_fastmap (&regex->buf) != 0) {
262 			g_warning ("IMPORTANT REGEX FAILED TO CREASTE FASTMAP\n");
263 			/* error...no fastmap */
264 			g_free (regex->buf.fastmap);
265 			regex->buf.fastmap = NULL;
266 		}
267 		return (TRUE);
268 	} else {
269 		g_warning ("IMPORTANT REGEX FAILED TO COMPILE\n");
270 		return (FALSE);
271 	}
272 }
273