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
->bufp
[1]=='<') {
90 ertf_append_char(parser
,'<');
93 else if (parser
->str
->len
== 0)
94 ertf_parse_tag(parser
);
96 return parser
->str
->str
;
100 if (parser
->bufp
[0] == '\r' && parser
->bufp
[1] == '\n')
104 /* When not pre (not <nofill>), 1 CRLF = SPACE, N>1 CRLF = N-1 CRLF*/
105 if (!parser
->newline
) {
106 parser
->newline
= TRUE
;
107 parser
->space
= TRUE
;
114 ertf_append_char(parser
, *parser
->bufp
++);
118 return parser
->str
->str
;
121 static ERTFState
ertf_read_line(ERTFParser
*parser
)
123 gchar buf
[ERTFBUFSIZE
];
124 gchar buf2
[ERTFBUFSIZE
];
127 if (claws_fgets(buf
, sizeof(buf
), parser
->fp
) == NULL
) {
128 parser
->state
= ERTF_EOF
;
132 if (conv_convert(parser
->conv
, buf2
, sizeof(buf2
), buf
) < 0) {
133 g_warning("ertf_read_line(): code conversion failed");
135 index
= parser
->bufp
- parser
->buf
->str
;
137 g_string_append(parser
->buf
, buf
);
139 parser
->bufp
= parser
->buf
->str
+ index
;
144 index
= parser
->bufp
- parser
->buf
->str
;
146 g_string_append(parser
->buf
, buf2
);
148 parser
->bufp
= parser
->buf
->str
+ index
;
153 static void ertf_append_char(ERTFParser
*parser
, gchar ch
)
155 GString
*str
= parser
->str
;
157 if (!parser
->pre
&& parser
->space
) {
159 g_string_append_c(str
, ' ');
160 parser
->space
= FALSE
;
163 g_string_append_c(str
, ch
);
165 parser
->empty_line
= FALSE
;
168 parser
->empty_line
= TRUE
;
170 parser
->newline
= TRUE
;
172 parser
->newline
= FALSE
;
175 static ERTFState
ertf_parse_tag(ERTFParser
*parser
)
177 gchar buf
[ERTFBUFSIZE
];
181 ertf_get_parenthesis (parser
, buf
, sizeof(buf
));
183 for (p
= buf
; *p
!= '\0'; p
++) {
184 if (isspace (*(guchar
*)p
)) {
190 parser
->state
= ERTF_UNKNOWN
;
191 if (buf
[0] == '\0') return parser
->state
;
193 down
= g_utf8_strdown (buf
, -1);
195 if (!strcmp(down
, "nofill")) {
197 parser
->state
= ERTF_NOFILL
;
199 else if (!strcmp(down
, "/nofill")) {
201 parser
->state
= ERTF_NORMAL
;
204 return parser
->state
;
207 static void ertf_get_parenthesis(ERTFParser
*parser
, gchar
*buf
, gint len
)
212 cm_return_if_fail(*parser
->bufp
== '<');
215 if (!g_ascii_strncasecmp(parser
->bufp
, "<param>", 4)) {
217 while ((p
= strstr(parser
->bufp
, "</param>")) == NULL
)
218 if (ertf_read_line(parser
) == ERTF_EOF
) return;
219 parser
->bufp
= p
+ 8;
223 while ((p
= strchr(parser
->bufp
, '>')) == NULL
)
224 if (ertf_read_line(parser
) == ERTF_EOF
) return;
226 strncpy2(buf
, parser
->bufp
, MIN(p
- parser
->bufp
+ 1, len
));
227 parser
->bufp
= p
+ 1;