Statistics
| Revision:

root / src / quote_fmt_parse.y @ 427

History | View | Annotate | Download (7.5 kB)

1 1 hiro
%{
2 1 hiro
3 1 hiro
#include "defs.h"
4 1 hiro
5 1 hiro
#include <glib.h>
6 1 hiro
#include <ctype.h>
7 1 hiro
8 1 hiro
#include "procmsg.h"
9 1 hiro
#include "procmime.h"
10 1 hiro
#include "utils.h"
11 1 hiro
12 1 hiro
#include "quote_fmt.h"
13 1 hiro
#include "quote_fmt_lex.h"
14 1 hiro
15 1 hiro
/* decl */
16 1 hiro
/*
17 1 hiro
flex quote_fmt.l
18 1 hiro
bison -p quote_fmt quote_fmt.y
19 1 hiro
*/
20 1 hiro
21 1 hiro
int yylex(void);
22 1 hiro
23 1 hiro
static MsgInfo *msginfo = NULL;
24 1 hiro
static gboolean *visible = NULL;
25 1 hiro
static gint maxsize = 0;
26 1 hiro
static gint stacksize = 0;
27 1 hiro
28 1 hiro
static gchar *buffer = NULL;
29 1 hiro
static gint bufmax = 0;
30 1 hiro
static gint bufsize = 0;
31 1 hiro
static const gchar *quote_str = NULL;
32 1 hiro
static const gchar *body = NULL;
33 1 hiro
static gint error = 0;
34 1 hiro
35 1 hiro
static void add_visibility(gboolean val)
36 1 hiro
{
37 1 hiro
	stacksize++;
38 1 hiro
	if (maxsize < stacksize) {
39 1 hiro
		maxsize += 128;
40 1 hiro
		visible = g_realloc(visible, maxsize * sizeof(gboolean));
41 1 hiro
		if (visible == NULL)
42 1 hiro
			maxsize = 0;
43 1 hiro
	}
44 1 hiro
45 1 hiro
	visible[stacksize - 1] = val;
46 1 hiro
}
47 1 hiro
48 1 hiro
static void remove_visibility(void)
49 1 hiro
{
50 1 hiro
	stacksize--;
51 1 hiro
}
52 1 hiro
53 1 hiro
static void add_buffer(const gchar *s)
54 1 hiro
{
55 1 hiro
	gint len;
56 1 hiro
57 1 hiro
	len = strlen(s);
58 1 hiro
	if (bufsize + len + 1 > bufmax) {
59 1 hiro
		if (bufmax == 0)
60 1 hiro
			bufmax = 128;
61 1 hiro
		while (bufsize + len + 1 > bufmax)
62 1 hiro
			bufmax *= 2;
63 1 hiro
		buffer = g_realloc(buffer, bufmax);
64 1 hiro
	}
65 1 hiro
	strcpy(buffer + bufsize, s);
66 1 hiro
	bufsize += len;
67 1 hiro
}
68 1 hiro
69 1 hiro
#if 0
70 1 hiro
static void flush_buffer(void)
71 1 hiro
{
72 1 hiro
	if (buffer != NULL)
73 1 hiro
		*buffer = '\0';
74 1 hiro
	bufsize = 0;
75 1 hiro
}
76 1 hiro
#endif
77 1 hiro
78 1 hiro
gchar *quote_fmt_get_buffer(void)
79 1 hiro
{
80 1 hiro
	if (error != 0)
81 1 hiro
		return NULL;
82 1 hiro
	else
83 1 hiro
		return buffer;
84 1 hiro
}
85 1 hiro
86 1 hiro
#define INSERT(buf) \
87 1 hiro
	if (stacksize != 0 && visible[stacksize - 1]) \
88 1 hiro
		add_buffer(buf)
89 1 hiro
90 1 hiro
#define INSERT_CHARACTER(chr) \
91 1 hiro
	if (stacksize != 0 && visible[stacksize - 1]) { \
92 1 hiro
		gchar tmp[2]; \
93 1 hiro
		tmp[0] = (chr); \
94 1 hiro
		tmp[1] = '\0'; \
95 1 hiro
		add_buffer(tmp); \
96 1 hiro
	}
97 1 hiro
98 1 hiro
void quote_fmt_init(MsgInfo *info, const gchar *my_quote_str,
99 1 hiro
		    const gchar *my_body)
100 1 hiro
{
101 1 hiro
	quote_str = my_quote_str;
102 1 hiro
	body = my_body;
103 1 hiro
	msginfo = info;
104 1 hiro
	stacksize = 0;
105 1 hiro
	add_visibility(TRUE);
106 1 hiro
	if (buffer != NULL)
107 1 hiro
		*buffer = 0;
108 1 hiro
	bufsize = 0;
109 1 hiro
	error = 0;
110 1 hiro
}
111 1 hiro
112 1 hiro
void quote_fmterror(char *str)
113 1 hiro
{
114 1 hiro
	g_warning("Error: %s\n", str);
115 1 hiro
	error = 1;
116 1 hiro
}
117 1 hiro
118 1 hiro
int quote_fmtwrap(void)
119 1 hiro
{
120 1 hiro
	return 1;
121 1 hiro
}
122 1 hiro
123 1 hiro
static int isseparator(int ch)
124 1 hiro
{
125 1 hiro
	return isspace(ch) || ch == '.' || ch == '-';
126 1 hiro
}
127 1 hiro
%}
128 1 hiro
129 1 hiro
%union {
130 1 hiro
	char chr;
131 1 hiro
}
132 1 hiro
133 1 hiro
%token SHOW_NEWSGROUPS
134 1 hiro
%token SHOW_DATE SHOW_FROM SHOW_FULLNAME SHOW_FIRST_NAME
135 1 hiro
%token SHOW_SENDER_INITIAL SHOW_SUBJECT SHOW_TO SHOW_MESSAGEID
136 1 hiro
%token SHOW_PERCENT SHOW_CC SHOW_REFERENCES SHOW_MESSAGE
137 1 hiro
%token SHOW_QUOTED_MESSAGE SHOW_BACKSLASH SHOW_TAB
138 1 hiro
%token SHOW_QUOTED_MESSAGE_NO_SIGNATURE SHOW_MESSAGE_NO_SIGNATURE
139 1 hiro
%token SHOW_EOL SHOW_QUESTION_MARK SHOW_OPARENT SHOW_CPARENT
140 1 hiro
%token QUERY_DATE QUERY_FROM
141 1 hiro
%token QUERY_FULLNAME QUERY_SUBJECT QUERY_TO QUERY_NEWSGROUPS
142 1 hiro
%token QUERY_MESSAGEID QUERY_CC QUERY_REFERENCES
143 1 hiro
%token OPARENT CPARENT
144 1 hiro
%token CHARACTER
145 1 hiro
146 1 hiro
%start quote_fmt
147 1 hiro
148 1 hiro
%token <chr> CHARACTER
149 1 hiro
%type <chr> character
150 1 hiro
151 1 hiro
%%
152 1 hiro
153 1 hiro
quote_fmt:
154 1 hiro
	character_or_special_or_query_list;
155 1 hiro
156 1 hiro
character_or_special_or_query_list:
157 1 hiro
	character_or_special_or_query character_or_special_or_query_list
158 1 hiro
	| character_or_special_or_query ;
159 1 hiro
160 1 hiro
character_or_special_or_query:
161 1 hiro
	special
162 1 hiro
	| character
163 1 hiro
	{
164 1 hiro
		INSERT_CHARACTER($1);
165 1 hiro
	}
166 1 hiro
	| query ;
167 1 hiro
168 1 hiro
169 1 hiro
character:
170 1 hiro
	CHARACTER
171 1 hiro
	;
172 1 hiro
173 1 hiro
special:
174 1 hiro
	SHOW_NEWSGROUPS
175 1 hiro
	{
176 1 hiro
		if (msginfo->newsgroups)
177 1 hiro
			INSERT(msginfo->newsgroups);
178 1 hiro
	}
179 1 hiro
	| SHOW_DATE
180 1 hiro
	{
181 1 hiro
		if (msginfo->date)
182 1 hiro
			INSERT(msginfo->date);
183 1 hiro
	}
184 1 hiro
	| SHOW_FROM
185 1 hiro
	{
186 1 hiro
		if (msginfo->from)
187 1 hiro
			INSERT(msginfo->from);
188 1 hiro
	}
189 1 hiro
	| SHOW_FULLNAME
190 1 hiro
	{
191 1 hiro
		if (msginfo->fromname)
192 1 hiro
			INSERT(msginfo->fromname);
193 1 hiro
	}
194 1 hiro
	| SHOW_FIRST_NAME
195 1 hiro
	{
196 1 hiro
		if (msginfo->fromname) {
197 1 hiro
			guchar *p;
198 1 hiro
			gchar *str;
199 1 hiro
200 1 hiro
			str = alloca(strlen(msginfo->fromname) + 1);
201 1 hiro
			if (str != NULL) {
202 1 hiro
				strcpy(str, msginfo->fromname);
203 1 hiro
				p = str;
204 1 hiro
				while (*p && !isspace(*p)) p++;
205 1 hiro
				*p = '\0';
206 1 hiro
				INSERT(str);
207 1 hiro
			}
208 1 hiro
		}
209 1 hiro
	}
210 1 hiro
	| SHOW_SENDER_INITIAL
211 1 hiro
	{
212 1 hiro
#define MAX_SENDER_INITIAL 20
213 1 hiro
		if (msginfo->fromname) {
214 1 hiro
			gchar tmp[MAX_SENDER_INITIAL];
215 1 hiro
			guchar *p;
216 1 hiro
			gchar *cur;
217 1 hiro
			gint len = 0;
218 1 hiro
219 1 hiro
			p = msginfo->fromname;
220 1 hiro
			cur = tmp;
221 1 hiro
			while (*p) {
222 1 hiro
				if (*p && isalnum(*p)) {
223 1 hiro
					*cur = toupper(*p);
224 1 hiro
						cur++;
225 1 hiro
					len++;
226 1 hiro
					if (len >= MAX_SENDER_INITIAL - 1)
227 1 hiro
						break;
228 1 hiro
				} else
229 1 hiro
					break;
230 1 hiro
				while (*p && !isseparator(*p)) p++;
231 1 hiro
				while (*p && isseparator(*p)) p++;
232 1 hiro
			}
233 1 hiro
			*cur = '\0';
234 1 hiro
			INSERT(tmp);
235 1 hiro
		}
236 1 hiro
	}
237 1 hiro
	| SHOW_SUBJECT
238 1 hiro
	{
239 1 hiro
		if (msginfo->subject)
240 1 hiro
			INSERT(msginfo->subject);
241 1 hiro
	}
242 1 hiro
	| SHOW_TO
243 1 hiro
	{
244 1 hiro
		if (msginfo->to)
245 1 hiro
			INSERT(msginfo->to);
246 1 hiro
	}
247 1 hiro
	| SHOW_MESSAGEID
248 1 hiro
	{
249 1 hiro
		if (msginfo->msgid)
250 1 hiro
			INSERT(msginfo->msgid);
251 1 hiro
	}
252 1 hiro
	| SHOW_PERCENT
253 1 hiro
	{
254 1 hiro
		INSERT("%");
255 1 hiro
	}
256 1 hiro
	| SHOW_CC
257 1 hiro
	{
258 1 hiro
		if (msginfo->cc)
259 1 hiro
			INSERT(msginfo->cc);
260 1 hiro
	}
261 1 hiro
	| SHOW_REFERENCES
262 1 hiro
	{
263 1 hiro
		/* if (msginfo->references)
264 1 hiro
			INSERT(msginfo->references); */
265 1 hiro
	}
266 1 hiro
	| SHOW_MESSAGE
267 1 hiro
	{
268 1 hiro
		if (msginfo->folder || body) {
269 1 hiro
			gchar buf[BUFFSIZE];
270 1 hiro
			FILE *fp;
271 1 hiro
272 1 hiro
			if (body)
273 1 hiro
				fp = str_open_as_stream(body);
274 1 hiro
			else
275 129 hiro
				fp = procmime_get_first_text_content
276 129 hiro
					(msginfo, NULL);
277 1 hiro
278 1 hiro
			if (fp == NULL)
279 1 hiro
				g_warning("Can't get text part\n");
280 1 hiro
			else {
281 1 hiro
				while (fgets(buf, sizeof(buf), fp) != NULL) {
282 1 hiro
					strcrchomp(buf);
283 1 hiro
					INSERT(buf);
284 1 hiro
				}
285 1 hiro
				fclose(fp);
286 1 hiro
			}
287 1 hiro
		}
288 1 hiro
	}
289 1 hiro
	| SHOW_QUOTED_MESSAGE
290 1 hiro
	{
291 1 hiro
		if (msginfo->folder || body) {
292 1 hiro
			gchar buf[BUFFSIZE];
293 1 hiro
			FILE *fp;
294 1 hiro
295 1 hiro
			if (body)
296 1 hiro
				fp = str_open_as_stream(body);
297 1 hiro
			else
298 129 hiro
				fp = procmime_get_first_text_content
299 129 hiro
					(msginfo, NULL);
300 1 hiro
301 1 hiro
			if (fp == NULL)
302 1 hiro
				g_warning("Can't get text part\n");
303 1 hiro
			else {
304 1 hiro
				while (fgets(buf, sizeof(buf), fp) != NULL) {
305 1 hiro
					strcrchomp(buf);
306 1 hiro
					if (quote_str)
307 1 hiro
						INSERT(quote_str);
308 1 hiro
					INSERT(buf);
309 1 hiro
				}
310 1 hiro
				fclose(fp);
311 1 hiro
			}
312 1 hiro
		}
313 1 hiro
	}
314 1 hiro
	| SHOW_MESSAGE_NO_SIGNATURE
315 1 hiro
	{
316 1 hiro
		if (msginfo->folder || body) {
317 1 hiro
			gchar buf[BUFFSIZE];
318 1 hiro
			FILE *fp;
319 1 hiro
320 1 hiro
			if (body)
321 1 hiro
				fp = str_open_as_stream(body);
322 1 hiro
			else
323 129 hiro
				fp = procmime_get_first_text_content
324 129 hiro
					(msginfo, NULL);
325 1 hiro
326 1 hiro
			if (fp == NULL)
327 1 hiro
				g_warning("Can't get text part\n");
328 1 hiro
			else {
329 1 hiro
				while (fgets(buf, sizeof(buf), fp) != NULL) {
330 1 hiro
					strcrchomp(buf);
331 1 hiro
					if (strncmp(buf, "-- \n", 4) == 0)
332 1 hiro
						break;
333 1 hiro
					INSERT(buf);
334 1 hiro
				}
335 1 hiro
				fclose(fp);
336 1 hiro
			}
337 1 hiro
		}
338 1 hiro
	}
339 1 hiro
	| SHOW_QUOTED_MESSAGE_NO_SIGNATURE
340 1 hiro
	{
341 1 hiro
		if (msginfo->folder || body) {
342 1 hiro
			gchar buf[BUFFSIZE];
343 1 hiro
			FILE *fp;
344 1 hiro
345 1 hiro
			if (body)
346 1 hiro
				fp = str_open_as_stream(body);
347 1 hiro
			else
348 129 hiro
				fp = procmime_get_first_text_content
349 129 hiro
					(msginfo, NULL);
350 1 hiro
351 1 hiro
			if (fp == NULL)
352 1 hiro
				g_warning("Can't get text part\n");
353 1 hiro
			else {
354 1 hiro
				while (fgets(buf, sizeof(buf), fp) != NULL) {
355 1 hiro
					strcrchomp(buf);
356 1 hiro
					if (strncmp(buf, "-- \n", 4) == 0)
357 1 hiro
						break;
358 1 hiro
					if (quote_str)
359 1 hiro
						INSERT(quote_str);
360 1 hiro
					INSERT(buf);
361 1 hiro
				}
362 1 hiro
				fclose(fp);
363 1 hiro
			}
364 1 hiro
		}
365 1 hiro
	}
366 1 hiro
	| SHOW_BACKSLASH
367 1 hiro
	{
368 1 hiro
		INSERT("\\");
369 1 hiro
	}
370 1 hiro
	| SHOW_TAB
371 1 hiro
	{
372 1 hiro
		INSERT("\t");
373 1 hiro
	}
374 1 hiro
	| SHOW_EOL
375 1 hiro
	{
376 1 hiro
		INSERT("\n");
377 1 hiro
	}
378 1 hiro
	| SHOW_QUESTION_MARK
379 1 hiro
	{
380 1 hiro
		INSERT("?");
381 1 hiro
	}
382 1 hiro
	| SHOW_OPARENT
383 1 hiro
	{
384 1 hiro
		INSERT("{");
385 1 hiro
	}
386 1 hiro
	| SHOW_CPARENT
387 1 hiro
	{
388 1 hiro
		INSERT("}");
389 1 hiro
	};
390 1 hiro
391 1 hiro
query:
392 1 hiro
	QUERY_DATE
393 1 hiro
	{
394 1 hiro
		add_visibility(msginfo->date != NULL);
395 1 hiro
	}
396 1 hiro
	OPARENT quote_fmt CPARENT
397 1 hiro
	{
398 1 hiro
		remove_visibility();
399 1 hiro
	}
400 1 hiro
	| QUERY_FROM
401 1 hiro
	{
402 1 hiro
		add_visibility(msginfo->from != NULL);
403 1 hiro
	}
404 1 hiro
	OPARENT quote_fmt CPARENT
405 1 hiro
	{
406 1 hiro
		remove_visibility();
407 1 hiro
	}
408 1 hiro
	| QUERY_FULLNAME
409 1 hiro
	{
410 1 hiro
		add_visibility(msginfo->fromname != NULL);
411 1 hiro
	}
412 1 hiro
	OPARENT quote_fmt CPARENT
413 1 hiro
	{
414 1 hiro
		remove_visibility();
415 1 hiro
	}
416 1 hiro
	| QUERY_SUBJECT
417 1 hiro
	{
418 1 hiro
		add_visibility(msginfo->subject != NULL);
419 1 hiro
	}
420 1 hiro
	OPARENT quote_fmt CPARENT
421 1 hiro
	{
422 1 hiro
		remove_visibility();
423 1 hiro
	}
424 1 hiro
	| QUERY_TO
425 1 hiro
	{
426 1 hiro
		add_visibility(msginfo->to != NULL);
427 1 hiro
	}
428 1 hiro
	OPARENT quote_fmt CPARENT
429 1 hiro
	{
430 1 hiro
		remove_visibility();
431 1 hiro
	}
432 1 hiro
	| QUERY_NEWSGROUPS
433 1 hiro
	{
434 1 hiro
		add_visibility(msginfo->newsgroups != NULL);
435 1 hiro
	}
436 1 hiro
	OPARENT quote_fmt CPARENT
437 1 hiro
	{
438 1 hiro
		remove_visibility();
439 1 hiro
	}
440 1 hiro
	| QUERY_MESSAGEID
441 1 hiro
	{
442 1 hiro
		add_visibility(msginfo->msgid != NULL);
443 1 hiro
	}
444 1 hiro
	OPARENT quote_fmt CPARENT
445 1 hiro
	{
446 1 hiro
		remove_visibility();
447 1 hiro
	}
448 1 hiro
	| QUERY_CC
449 1 hiro
	{
450 1 hiro
		add_visibility(msginfo->cc != NULL);
451 1 hiro
	}
452 1 hiro
	OPARENT quote_fmt CPARENT
453 1 hiro
	{
454 1 hiro
		remove_visibility();
455 1 hiro
	}
456 1 hiro
	| QUERY_REFERENCES
457 1 hiro
	{
458 1 hiro
		/* add_visibility(msginfo->references != NULL); */
459 1 hiro
	}
460 1 hiro
	OPARENT quote_fmt CPARENT
461 1 hiro
	{
462 1 hiro
		remove_visibility();
463 1 hiro
	};