2 * Sylpheed -- 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/>.
28 #define ERTFBUFSIZE 8192
31 static ERTFState
ertf_read_line (ERTFParser
*parser
);
32 static void ertf_append_char (ERTFParser
*parser
,
35 static ERTFState
ertf_parse_tag (ERTFParser
*parser
);
36 static void ertf_get_parenthesis (ERTFParser
*parser
,
40 ERTFParser
*ertf_parser_new(FILE *fp
, CodeConverter
*conv
)
44 cm_return_val_if_fail(fp
!= NULL
, NULL
);
45 cm_return_val_if_fail(conv
!= NULL
, NULL
);
47 parser
= g_new0(ERTFParser
, 1);
50 parser
->str
= g_string_new(NULL
);
51 parser
->buf
= g_string_new(NULL
);
52 parser
->bufp
= parser
->buf
->str
;
53 parser
->newline
= TRUE
;
54 parser
->empty_line
= TRUE
;
55 parser
->space
= FALSE
;
61 void ertf_parser_destroy(ERTFParser
*parser
)
63 g_string_free(parser
->str
, TRUE
);
64 g_string_free(parser
->buf
, TRUE
);
68 gchar
*ertf_parse(ERTFParser
*parser
)
70 parser
->state
= ERTF_NORMAL
;
71 g_string_truncate(parser
->str
, 0);
73 if (*parser
->bufp
== '\0') {
74 g_string_truncate(parser
->buf
, 0);
75 parser
->bufp
= parser
->buf
->str
;
76 if (ertf_read_line(parser
) == ERTF_EOF
)
80 while (*parser
->bufp
!= '\0') {
81 switch (*parser
->bufp
) {
83 if (parser
->str
->len
== 0)
84 ertf_parse_tag(parser
);
86 return parser
->str
->str
;
90 if (parser
->bufp
[0] == '\r' && parser
->bufp
[1] == '\n')
94 /* When not pre (not <nofill>), 1 CRLF = SPACE, N>1 CRLF = N-1 CRLF*/
95 if (!parser
->newline
) {
96 parser
->newline
= TRUE
;
104 ertf_append_char(parser
, *parser
->bufp
++);
108 return parser
->str
->str
;
111 static ERTFState
ertf_read_line(ERTFParser
*parser
)
113 gchar buf
[ERTFBUFSIZE
];
114 gchar buf2
[ERTFBUFSIZE
];
117 if (fgets(buf
, sizeof(buf
), parser
->fp
) == NULL
) {
118 parser
->state
= ERTF_EOF
;
122 if (conv_convert(parser
->conv
, buf2
, sizeof(buf2
), buf
) < 0) {
123 g_warning("ertf_read_line(): code conversion failed");
125 index
= parser
->bufp
- parser
->buf
->str
;
127 g_string_append(parser
->buf
, buf
);
129 parser
->bufp
= parser
->buf
->str
+ index
;
134 index
= parser
->bufp
- parser
->buf
->str
;
136 g_string_append(parser
->buf
, buf2
);
138 parser
->bufp
= parser
->buf
->str
+ index
;
143 static void ertf_append_char(ERTFParser
*parser
, gchar ch
)
145 GString
*str
= parser
->str
;
147 if (!parser
->pre
&& parser
->space
) {
149 g_string_append_c(str
, ' ');
150 parser
->space
= FALSE
;
153 g_string_append_c(str
, ch
);
155 parser
->empty_line
= FALSE
;
158 parser
->empty_line
= TRUE
;
160 parser
->newline
= TRUE
;
162 parser
->newline
= FALSE
;
165 static ERTFState
ertf_parse_tag(ERTFParser
*parser
)
167 gchar buf
[ERTFBUFSIZE
];
171 ertf_get_parenthesis (parser
, buf
, sizeof(buf
));
173 for (p
= buf
; *p
!= '\0'; p
++) {
174 if (isspace (*(guchar
*)p
)) {
180 parser
->state
= ERTF_UNKNOWN
;
181 if (buf
[0] == '\0') return parser
->state
;
183 down
= g_utf8_strdown (buf
, -1);
185 if (!strcmp(down
, "nofill")) {
187 parser
->state
= ERTF_NOFILL
;
189 else if (!strcmp(down
, "/nofill")) {
191 parser
->state
= ERTF_NORMAL
;
194 return parser
->state
;
197 static void ertf_get_parenthesis(ERTFParser
*parser
, gchar
*buf
, gint len
)
202 cm_return_if_fail(*parser
->bufp
== '<');
205 if (!g_ascii_strncasecmp(parser
->bufp
, "<param>", 4)) {
207 while ((p
= strstr(parser
->bufp
, "</param>")) == NULL
)
208 if (ertf_read_line(parser
) == ERTF_EOF
) return;
209 parser
->bufp
= p
+ 8;
213 while ((p
= strchr(parser
->bufp
, '>')) == NULL
)
214 if (ertf_read_line(parser
) == ERTF_EOF
) return;
216 strncpy2(buf
, parser
->bufp
, MIN(p
- parser
->bufp
+ 1, len
));
217 parser
->bufp
= p
+ 1;