2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999,2000 Hiroyuki Yamamoto
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "claws-features.h"
32 #include "file-utils.h"
34 #define ERTFBUFSIZE 8192
37 static ERTFState
ertf_read_line (ERTFParser
*parser
);
38 static void ertf_append_char (ERTFParser
*parser
,
41 static ERTFState
ertf_parse_tag (ERTFParser
*parser
);
42 static void ertf_get_parenthesis (ERTFParser
*parser
,
46 ERTFParser
*ertf_parser_new(FILE *fp
, CodeConverter
*conv
)
50 cm_return_val_if_fail(fp
!= NULL
, NULL
);
51 cm_return_val_if_fail(conv
!= NULL
, NULL
);
53 parser
= g_new0(ERTFParser
, 1);
56 parser
->str
= g_string_new(NULL
);
57 parser
->buf
= g_string_new(NULL
);
58 parser
->bufp
= parser
->buf
->str
;
59 parser
->newline
= TRUE
;
60 parser
->empty_line
= TRUE
;
61 parser
->space
= FALSE
;
67 void ertf_parser_destroy(ERTFParser
*parser
)
69 g_string_free(parser
->str
, TRUE
);
70 g_string_free(parser
->buf
, TRUE
);
74 gchar
*ertf_parse(ERTFParser
*parser
)
76 parser
->state
= ERTF_NORMAL
;
77 g_string_truncate(parser
->str
, 0);
79 if (*parser
->bufp
== '\0') {
80 g_string_truncate(parser
->buf
, 0);
81 parser
->bufp
= parser
->buf
->str
;
82 if (ertf_read_line(parser
) == ERTF_EOF
)
86 while (*parser
->bufp
!= '\0') {
87 switch (*parser
->bufp
) {
89 if (parser
->str
->len
== 0)
90 ertf_parse_tag(parser
);
92 return parser
->str
->str
;
96 if (parser
->bufp
[0] == '\r' && parser
->bufp
[1] == '\n')
100 /* When not pre (not <nofill>), 1 CRLF = SPACE, N>1 CRLF = N-1 CRLF*/
101 if (!parser
->newline
) {
102 parser
->newline
= TRUE
;
103 parser
->space
= TRUE
;
110 ertf_append_char(parser
, *parser
->bufp
++);
114 return parser
->str
->str
;
117 static ERTFState
ertf_read_line(ERTFParser
*parser
)
119 gchar buf
[ERTFBUFSIZE
];
120 gchar buf2
[ERTFBUFSIZE
];
123 if (claws_fgets(buf
, sizeof(buf
), parser
->fp
) == NULL
) {
124 parser
->state
= ERTF_EOF
;
128 if (conv_convert(parser
->conv
, buf2
, sizeof(buf2
), buf
) < 0) {
129 g_warning("ertf_read_line(): code conversion failed");
131 index
= parser
->bufp
- parser
->buf
->str
;
133 g_string_append(parser
->buf
, buf
);
135 parser
->bufp
= parser
->buf
->str
+ index
;
140 index
= parser
->bufp
- parser
->buf
->str
;
142 g_string_append(parser
->buf
, buf2
);
144 parser
->bufp
= parser
->buf
->str
+ index
;
149 static void ertf_append_char(ERTFParser
*parser
, gchar ch
)
151 GString
*str
= parser
->str
;
153 if (!parser
->pre
&& parser
->space
) {
155 g_string_append_c(str
, ' ');
156 parser
->space
= FALSE
;
159 g_string_append_c(str
, ch
);
161 parser
->empty_line
= FALSE
;
164 parser
->empty_line
= TRUE
;
166 parser
->newline
= TRUE
;
168 parser
->newline
= FALSE
;
171 static ERTFState
ertf_parse_tag(ERTFParser
*parser
)
173 gchar buf
[ERTFBUFSIZE
];
177 ertf_get_parenthesis (parser
, buf
, sizeof(buf
));
179 for (p
= buf
; *p
!= '\0'; p
++) {
180 if (isspace (*(guchar
*)p
)) {
186 parser
->state
= ERTF_UNKNOWN
;
187 if (buf
[0] == '\0') return parser
->state
;
189 down
= g_utf8_strdown (buf
, -1);
191 if (!strcmp(down
, "nofill")) {
193 parser
->state
= ERTF_NOFILL
;
195 else if (!strcmp(down
, "/nofill")) {
197 parser
->state
= ERTF_NORMAL
;
200 return parser
->state
;
203 static void ertf_get_parenthesis(ERTFParser
*parser
, gchar
*buf
, gint len
)
208 cm_return_if_fail(*parser
->bufp
== '<');
211 if (!g_ascii_strncasecmp(parser
->bufp
, "<param>", 4)) {
213 while ((p
= strstr(parser
->bufp
, "</param>")) == NULL
)
214 if (ertf_read_line(parser
) == ERTF_EOF
) return;
215 parser
->bufp
= p
+ 8;
219 while ((p
= strchr(parser
->bufp
, '>')) == NULL
)
220 if (ertf_read_line(parser
) == ERTF_EOF
) return;
222 strncpy2(buf
, parser
->bufp
, MIN(p
- parser
->bufp
+ 1, len
));
223 parser
->bufp
= p
+ 1;