23ad275a6b0aa67d2b11f1db8a3fa097d461c287
[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_QUOTED_MESSAGE_NO_SIGNATURE SHOW_MESSAGE_NO_SIGNATURE
134 %token SHOW_EOL SHOW_QUESTION_MARK SHOW_OPARENT SHOW_CPARENT
135 %token QUERY_DATE QUERY_FROM
136 %token QUERY_FULLNAME QUERY_SUBJECT QUERY_TO QUERY_NEWSGROUPS
137 %token QUERY_MESSAGEID QUERY_CC QUERY_REFERENCES
138 %token OPARENT CPARENT
139 %token CHARACTER
140
141 %start quote_fmt
142
143 %token <chr> CHARACTER
144 %type <chr> character
145
146 %%
147
148 quote_fmt:
149         character_or_special_or_query_list;
150
151 character_or_special_or_query_list:
152         character_or_special_or_query character_or_special_or_query_list
153         | character_or_special_or_query ;
154
155 character_or_special_or_query:
156         special ;
157         | character
158         {
159                 INSERT_CHARACTER($1);
160         }
161         | query ;
162
163
164 character:
165         CHARACTER
166         ;
167
168 special:
169         SHOW_NEWSGROUPS
170         {
171                 if (msginfo->newsgroups)
172                         INSERT(msginfo->newsgroups);
173         }
174         | SHOW_DATE
175         {
176                 if (msginfo->date)
177                         INSERT(msginfo->date);
178         }
179         | SHOW_FROM
180         {
181                 if (msginfo->from)
182                         INSERT(msginfo->from);
183         }
184         | SHOW_FULLNAME
185         {
186                 if (msginfo->fromname)
187                         INSERT(msginfo->fromname);
188         }
189         | SHOW_FIRST_NAME
190         {
191                 if (msginfo->fromname) {
192                         gchar * p;
193                         gchar * str;
194
195                         str = alloca(strlen(msginfo->fromname) + 1);
196                         if (str != NULL) {
197                                 strcpy(str, msginfo->fromname);
198                                 p = str;
199                                 while (*p && !isspace(*p)) p++;
200                                 *p = '\0';
201                                 INSERT(str);
202                         }
203                 }
204         }
205         | SHOW_SENDER_INITIAL
206         {
207 #define MAX_SENDER_INITIAL 20
208                 if (msginfo->fromname) {
209                         gchar tmp[MAX_SENDER_INITIAL];
210                         gchar * p;      
211                         gchar * cur;
212                         gint len = 0;
213
214                         p = msginfo->fromname;
215                         cur = tmp;
216                         while (*p) {
217                                 if (*p && isalnum(*p)) {
218                                         *cur = toupper(*p);
219                                                 cur ++;
220                                         len ++;
221                                         if (len >= MAX_SENDER_INITIAL - 1)
222                                                 break;
223                                 }
224                                 else
225                                         break;
226                                 while (*p && !isseparator(*p)) p++;
227                                 while (*p && isseparator(*p)) p++;
228                         }
229                         *cur = '\0';
230                         INSERT(tmp);
231                 }
232         }
233         | SHOW_SUBJECT
234         {
235                 if (msginfo->subject)
236                         INSERT(msginfo->subject);
237         }
238         | SHOW_TO
239         {
240                 if (msginfo->to)
241                         INSERT(msginfo->to);
242         }
243         | SHOW_MESSAGEID
244         {
245                 if (msginfo->msgid)
246                         INSERT(msginfo->msgid);
247         }
248         | SHOW_PERCENT
249         {
250                 INSERT("%");
251         }
252         | SHOW_CC
253         {
254                 if (msginfo->cc)
255                         INSERT(msginfo->cc);
256         }
257         | SHOW_REFERENCES
258         {
259                 if (msginfo->references)
260                         INSERT(msginfo->references);
261         }
262         | SHOW_MESSAGE
263         {
264                 gchar buf[BUFFSIZE];
265                 FILE * fp;
266
267                 if ((fp = procmime_get_first_text_content(msginfo)) == NULL)
268                         g_warning(_("Can't get text part\n"));
269                 while (fgets(buf, sizeof(buf), fp) != NULL) {
270                         INSERT(buf);
271                 }
272                 fclose(fp);
273         }
274         | SHOW_QUOTED_MESSAGE
275         {
276                 gchar buf[BUFFSIZE];
277                 FILE * fp;
278
279                 if ((fp = procmime_get_first_text_content(msginfo)) == NULL)
280                         g_warning(_("Can't get text part\n"));
281                 while (fgets(buf, sizeof(buf), fp) != NULL) {
282                         if (quote_str)
283                                 INSERT(quote_str);
284                         INSERT(buf);
285                 }
286                 fclose(fp);
287         }
288         | SHOW_MESSAGE_NO_SIGNATURE
289         {
290                 gchar buf[BUFFSIZE];
291                 FILE * fp;
292
293                 if ((fp = procmime_get_first_text_content(msginfo)) == NULL)
294                         g_warning(_("Can't get text part\n"));
295                 while (fgets(buf, sizeof(buf), fp) != NULL) {
296                         if (strncmp(buf, "-- ", 3) == 0)
297                                 break;
298                         INSERT(buf);
299                 }
300                 fclose(fp);
301         }
302         | SHOW_QUOTED_MESSAGE_NO_SIGNATURE
303         {
304                 gchar buf[BUFFSIZE];
305                 FILE * fp;
306
307                 if ((fp = procmime_get_first_text_content(msginfo)) == NULL)
308                         g_warning(_("Can't get text part\n"));
309                 while (fgets(buf, sizeof(buf), fp) != NULL) {
310                         if (strncmp(buf, "-- ", 3) == 0)
311                                 break;
312                         if (quote_str)
313                                 INSERT(quote_str);
314                         INSERT(buf);
315                 }
316                 fclose(fp);
317         }
318         | SHOW_BACKSLASH
319         {
320                 INSERT("\\");
321         }
322         | SHOW_TAB
323         {
324                 INSERT("\t");
325         }
326         | SHOW_EOL
327         {
328                 INSERT("\n");
329         }
330         | SHOW_QUESTION_MARK
331         {
332                 INSERT("?");
333         }
334         | SHOW_OPARENT
335         {
336                 INSERT("(");
337         }
338         | SHOW_CPARENT
339         {
340                 INSERT(")");
341         };
342
343 query:
344         QUERY_DATE
345         {
346                 add_visibility(msginfo->date != NULL);
347         }
348         OPARENT quote_fmt CPARENT
349         {
350                 remove_visibility();
351         }
352         | QUERY_FROM
353         {
354                 add_visibility(msginfo->from != NULL);
355         }
356         OPARENT quote_fmt CPARENT
357         {
358                 remove_visibility();
359         }
360         | QUERY_FULLNAME
361         {
362                 add_visibility(msginfo->fromname != NULL);
363         }
364         OPARENT quote_fmt CPARENT
365         {
366                 remove_visibility();
367         }
368         | QUERY_SUBJECT
369         {
370                 add_visibility(msginfo->subject != NULL);
371         }
372         OPARENT quote_fmt CPARENT
373         {
374                 remove_visibility();
375         }
376         | QUERY_TO
377         {
378                 add_visibility(msginfo->to != NULL);
379         }
380         OPARENT quote_fmt CPARENT
381         {
382                 remove_visibility();
383         }
384         | QUERY_NEWSGROUPS
385         {
386                 add_visibility(msginfo->newsgroups != NULL);
387         }
388         OPARENT quote_fmt CPARENT
389         {
390                 remove_visibility();
391         }
392         | QUERY_MESSAGEID
393         {
394                 add_visibility(msginfo->msgid != NULL);
395         }
396         OPARENT quote_fmt CPARENT
397         {
398                 remove_visibility();
399         }
400         | QUERY_CC
401         {
402                 add_visibility(msginfo->cc != NULL);
403         }
404         OPARENT quote_fmt CPARENT
405         {
406                 remove_visibility();
407         }
408         | QUERY_REFERENCES
409         {
410                 add_visibility(msginfo->references != NULL);
411         }
412         OPARENT quote_fmt CPARENT
413         {
414                 remove_visibility();
415         };