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