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