Mercurial > pidgin
annotate src/protocols/yahoo/util.c @ 9164:76125b842b23
[gaim-migrate @ 9949]
This is proper yahoo japan support. Technically it worked before, but
you had to know the yahoo japan server, and typing in nonascii didn't work.
The account options are kind of ugly. Eventually Chip is going to replace
the check box with something more like a dropdown thingy, that automaticly
hides the settings that aren't used (Pager Host vs. Japan Pager Host, etc)
But it's not too bad now. And I think I orignally wrote this patch for
0.64 or something, so I got tired of waiting.
committer: Tailor Script <tailor@pidgin.im>
author | Tim Ringenbach <marv@pidgin.im> |
---|---|
date | Wed, 02 Jun 2004 03:02:50 +0000 |
parents | eb3c59b0a16c |
children | 34bce9529cf4 |
rev | line source |
---|---|
6513 | 1 /* |
2 * gaim | |
3 * | |
4 * Some code copyright 2003 Tim Ringenbach <omarvo@hotmail.com> | |
5 * (marv on irc.freenode.net) | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include "config.h" | |
25 #endif | |
26 | |
27 #include "prpl.h" | |
28 #include "debug.h" | |
7827 | 29 #include "yahoo.h" |
6513 | 30 |
6546 | 31 #include <string.h> |
32 | |
7827 | 33 /** |
34 * Encode some text to send to the yahoo server. | |
35 * | |
36 * @param gc The connection handle. | |
37 * @param str The null terminated utf8 string to encode. | |
38 * @param utf8 If not @c NULL, whether utf8 is okay or not. | |
39 * Even if it is okay, we may not use it. If we | |
40 * used it, we set this to @c TRUE, else to | |
41 * @c FALSE. If @c NULL, false is assumed, and | |
42 * it is not dereferenced. | |
43 * @return The g_malloced string in the appropriate encoding. | |
44 */ | |
45 char *yahoo_string_encode(GaimConnection *gc, const char *str, gboolean *utf8) | |
46 { | |
9164 | 47 struct yahoo_data *yd = gc->proto_data; |
7827 | 48 char *ret; |
49 char *to_codeset; | |
50 | |
9164 | 51 if (yd->jp && utf8 && *utf8) |
52 *utf8 = FALSE; | |
53 | |
7827 | 54 if (utf8 && *utf8) /* FIXME: maybe don't use utf8 if it'll fit in latin1 */ |
55 return g_strdup(str); | |
56 | |
9164 | 57 if (yd->jp) |
58 to_codeset = "SHIFT_JIS"; | |
59 else | |
60 to_codeset = "ISO-8859-1"; | |
7827 | 61 |
8955 | 62 ret = g_convert_with_fallback(str, strlen(str), to_codeset, "UTF-8", "?", NULL, NULL, NULL); |
7827 | 63 if (ret) |
64 return ret; | |
65 else | |
66 return g_strdup(""); | |
67 } | |
68 | |
69 /** | |
70 * Decode some text received from the server. | |
71 * | |
72 * @param gc The gc handle. | |
73 * @param str The null terminated string to decode. | |
74 * @param utf8 Did the server tell us it was supposed to be utf8? | |
75 * @return The decoded, utf-8 string, which must be g_free()'d. | |
76 */ | |
77 char *yahoo_string_decode(GaimConnection *gc, const char *str, gboolean utf8) | |
78 { | |
9164 | 79 struct yahoo_data *yd = gc->proto_data; |
7827 | 80 char *ret; |
81 char *from_codeset; | |
82 | |
83 if (utf8) { | |
84 if (g_utf8_validate(str, -1, NULL)) | |
85 return g_strdup(str); | |
86 } | |
87 | |
9164 | 88 if (yd->jp) |
89 from_codeset = "SHIFT_JIS"; | |
90 else | |
91 from_codeset = "ISO-8859-1"; | |
7827 | 92 |
93 ret = g_convert_with_fallback(str, strlen(str), "UTF-8", from_codeset, NULL, NULL, NULL, NULL); | |
94 | |
95 if (ret) | |
96 return ret; | |
97 else | |
98 return g_strdup(""); | |
99 } | |
100 | |
101 | |
6513 | 102 |
103 /* | |
104 * I found these on some website but i don't know that they actually | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8533
diff
changeset
|
105 * work (or are supposed to work). I didn't implement them yet. |
6513 | 106 * |
107 * [0;30m ---black | |
108 * [1;37m ---white | |
109 * [0;37m ---tan | |
110 * [0;38m ---light black | |
111 * [1;39m ---dark blue | |
112 * [0;32m ---green | |
113 * [0;33m ---yellow | |
114 * [0;35m ---pink | |
115 * [1;35m ---purple | |
116 * [1;30m ---light blue | |
117 * [0;31m ---red | |
118 * [0;34m ---blue | |
119 * [0;36m ---aqua | |
120 * (shift+comma)lyellow(shift+period) ---light yellow | |
121 * (shift+comma)lgreen(shift+period) ---light green | |
122 [2;30m <--white out | |
123 | |
124 */ | |
125 | |
126 | |
127 static GHashTable *ht = NULL; | |
128 | |
129 void yahoo_init_colorht() | |
130 { | |
131 ht = g_hash_table_new(g_str_hash, g_str_equal); | |
6629 | 132 /* the numbers in comments are what gyach uses, but i think they're incorrect */ |
6513 | 133 g_hash_table_insert(ht, "30", "<FONT COLOR=\"#000000\">"); /* black */ |
134 g_hash_table_insert(ht, "31", "<FONT COLOR=\"#0000FF\">"); /* blue */ | |
135 g_hash_table_insert(ht, "32", "<FONT COLOR=\"#008080\">"); /* cyan */ /* 00b2b2 */ | |
136 g_hash_table_insert(ht, "33", "<FONT COLOR=\"#808080\">"); /* gray */ /* 808080 */ | |
137 g_hash_table_insert(ht, "34", "<FONT COLOR=\"#008000\">"); /* green */ /* 00c200 */ | |
138 g_hash_table_insert(ht, "35", "<FONT COLOR=\"#FF0080\">"); /* pink */ /* ffafaf */ | |
139 g_hash_table_insert(ht, "36", "<FONT COLOR=\"#800080\">"); /* purple */ /* b200b2 */ | |
140 g_hash_table_insert(ht, "37", "<FONT COLOR=\"#FF8000\">"); /* orange */ /* ffff00 */ | |
141 g_hash_table_insert(ht, "38", "<FONT COLOR=\"#FF0000\">"); /* red */ | |
142 g_hash_table_insert(ht, "39", "<FONT COLOR=\"#808000\">"); /* olive */ /* 546b50 */ | |
143 | |
144 g_hash_table_insert(ht, "1", "<B>"); | |
145 g_hash_table_insert(ht, "x1", "</B>"); | |
146 g_hash_table_insert(ht, "2", "<I>"); | |
147 g_hash_table_insert(ht, "x2", "</I>"); | |
148 g_hash_table_insert(ht, "4", "<U>"); | |
149 g_hash_table_insert(ht, "x4", "</U>"); | |
150 | |
6629 | 151 /* these just tell us the text they surround is supposed |
152 * to be a link. gaim figures that out on its own so we | |
153 * just ignore it. | |
154 */ | |
155 g_hash_table_insert(ht, "l", ""); /* link start */ | |
156 g_hash_table_insert(ht, "xl", ""); /* link end */ | |
157 | |
158 | |
6513 | 159 g_hash_table_insert(ht, "<black>", "<FONT COLOR=\"#000000\">"); |
160 g_hash_table_insert(ht, "<blue>", "<FONT COLOR=\"#0000FF\">"); | |
161 g_hash_table_insert(ht, "<cyan>", "<FONT COLOR=\"#008284\">"); | |
162 g_hash_table_insert(ht, "<gray>", "<FONT COLOR=\"#848284\">"); | |
163 g_hash_table_insert(ht, "<green>", "<FONT COLOR=\"#008200\">"); | |
164 g_hash_table_insert(ht, "<pink>", "<FONT COLOR=\"#FF0084\">"); | |
165 g_hash_table_insert(ht, "<purple>", "<FONT COLOR=\"#840084\">"); | |
166 g_hash_table_insert(ht, "<orange>", "<FONT COLOR=\"#FF8000\">"); | |
167 g_hash_table_insert(ht, "<red>", "<FONT COLOR=\"#FF0000\">"); | |
168 g_hash_table_insert(ht, "<yellow>", "<FONT COLOR=\"#848200\">"); | |
169 | |
170 g_hash_table_insert(ht, "</black>", "</FONT>"); | |
171 g_hash_table_insert(ht, "</blue>", "</FONT>"); | |
172 g_hash_table_insert(ht, "</cyan>", "</FONT>"); | |
173 g_hash_table_insert(ht, "</gray>", "</FONT>"); | |
174 g_hash_table_insert(ht, "</green>", "</FONT>"); | |
175 g_hash_table_insert(ht, "</pink>", "</FONT>"); | |
176 g_hash_table_insert(ht, "</purple>", "</FONT>"); | |
177 g_hash_table_insert(ht, "</orange>", "</FONT>"); | |
178 g_hash_table_insert(ht, "</red>", "</FONT>"); | |
179 g_hash_table_insert(ht, "</yellow>", "</FONT>"); | |
180 | |
181 /* remove these once we have proper support for <FADE> and <ALT> */ | |
182 g_hash_table_insert(ht, "</fade>", ""); | |
183 g_hash_table_insert(ht, "</alt>", ""); | |
8375 | 184 |
185 /* these are the normal html yahoo sends (besides <font>). | |
186 * anything else will get turned into <tag>, so if I forgot | |
187 * about something, please add it. Why Yahoo! has to send unescaped | |
188 * <'s and >'s that aren't supposed to be html is beyond me. | |
189 */ | |
190 g_hash_table_insert(ht, "<b>", "<b>"); | |
191 g_hash_table_insert(ht, "<i>", "<i>"); | |
192 g_hash_table_insert(ht, "<u>", "<u>"); | |
193 | |
194 g_hash_table_insert(ht, "</b>", "</b>"); | |
195 g_hash_table_insert(ht, "</i>", "</i>"); | |
196 g_hash_table_insert(ht, "</u>", "</u>"); | |
8440 | 197 g_hash_table_insert(ht, "</font>", "</font>"); |
6513 | 198 } |
199 | |
200 void yahoo_dest_colorht() | |
201 { | |
202 g_hash_table_destroy(ht); | |
203 } | |
204 | |
6629 | 205 static int point_to_html(int x) |
206 { | |
207 if (x < 9) | |
208 return 1; | |
209 if (x < 11) | |
210 return 2; | |
211 if (x < 13) | |
212 return 3; | |
213 if (x < 17) | |
214 return 4; | |
215 if (x < 25) | |
216 return 5; | |
217 if (x < 35) | |
218 return 6; | |
219 return 7; | |
220 } | |
221 static void _font_tags_fix_size(GString *tag, GString *dest) | |
222 { | |
223 char *x, *end; | |
224 int size; | |
225 | |
226 if (((x = strstr(tag->str, "size"))) && ((x = strchr(tag->str, '=')))) { | |
227 while (*x && !g_ascii_isdigit(*x)) | |
228 x++; | |
229 if (*x) { | |
230 size = strtol(x, &end, 10); | |
231 size = point_to_html(size); | |
232 g_string_append_len(dest, tag->str, x - tag->str); | |
233 g_string_append_printf(dest, "%d", size); | |
234 g_string_append(dest, end); | |
235 } else { | |
236 g_string_append(dest, tag->str); | |
237 return; | |
238 } | |
239 } else { | |
240 g_string_append(dest, tag->str); | |
241 return; | |
242 } | |
243 } | |
244 | |
245 char *yahoo_codes_to_html(const char *x) | |
6513 | 246 { |
247 GString *s, *tmp; | |
6629 | 248 int i, j, xs, nomoreendtags = 0; /* s/endtags/closinganglebrackets */ |
6513 | 249 char *match, *ret; |
250 | |
251 | |
252 s = g_string_sized_new(strlen(x)); | |
253 | |
254 for (i = 0, xs = strlen(x); i < xs; i++) { | |
255 if ((x[i] == 0x1b) && (x[i+1] == '[')) { | |
256 j = i + 1; | |
257 | |
258 while (j++ < xs) { | |
259 if (x[j] != 'm') | |
260 continue; | |
261 else { | |
262 tmp = g_string_new_len(x + i + 2, j - i - 2); | |
6621 | 263 if (tmp->str[0] == '#') |
6513 | 264 g_string_append_printf(s, "<FONT COLOR=\"%s\">", tmp->str); |
6546 | 265 else if ((match = (char *) g_hash_table_lookup(ht, tmp->str))) |
6513 | 266 g_string_append(s, match); |
267 else { | |
268 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", | |
269 "Unknown ansi code 'ESC[%sm'.\n", tmp->str); | |
270 g_string_free(tmp, TRUE); | |
271 break; | |
272 } | |
273 | |
274 i = j; | |
275 g_string_free(tmp, TRUE); | |
276 break; | |
277 } | |
278 } | |
279 | |
280 | |
281 } else if (!nomoreendtags && (x[i] == '<')) { | |
6629 | 282 j = i; |
6513 | 283 |
284 while (j++ < xs) { | |
285 if (x[j] != '>') | |
286 if (j == xs) { | |
8375 | 287 g_string_append(s, "<"); |
6513 | 288 nomoreendtags = 1; |
289 } | |
290 else | |
291 continue; | |
292 else { | |
293 tmp = g_string_new_len(x + i, j - i + 1); | |
294 g_string_ascii_down(tmp); | |
295 | |
6546 | 296 if ((match = (char *) g_hash_table_lookup(ht, tmp->str))) |
6513 | 297 g_string_append(s, match); |
6629 | 298 else if (!strncmp(tmp->str, "<fade ", 6) || |
299 !strncmp(tmp->str, "<alt ", 5) || | |
300 !strncmp(tmp->str, "<snd ", 5)) { | |
6513 | 301 |
6629 | 302 /* remove this if gtkimhtml ever supports any of these */ |
6513 | 303 i = j; |
304 g_string_free(tmp, TRUE); | |
305 break; | |
306 | |
6629 | 307 } else if (!strncmp(tmp->str, "<font ", 6)) { |
308 _font_tags_fix_size(tmp, s); | |
6513 | 309 } else { |
8375 | 310 g_string_append(s, "<"); |
6513 | 311 g_string_free(tmp, TRUE); |
312 break; | |
313 } | |
314 | |
315 i = j; | |
316 g_string_free(tmp, TRUE); | |
317 break; | |
318 } | |
319 | |
320 } | |
321 | |
322 | |
323 | |
324 } else { | |
8375 | 325 if (x[i] == '<') |
326 g_string_append(s, "<"); | |
327 else if (x[i] == '>') | |
328 g_string_append(s, ">"); | |
8440 | 329 else if (x[i] == '&') |
330 g_string_append(s, "&"); | |
331 else if (x[i] == '"') | |
332 g_string_append(s, """); | |
8375 | 333 else |
334 g_string_append_c(s, x[i]); | |
6513 | 335 } |
336 } | |
337 | |
338 ret = s->str; | |
339 g_string_free(s, FALSE); | |
6629 | 340 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "yahoo_codes_to_html: Returning string: '%s'.\n", ret); |
6513 | 341 return ret; |
342 } | |
6629 | 343 |
344 /* borrowed from gtkimhtml */ | |
345 #define MAX_FONT_SIZE 7 | |
346 #define POINT_SIZE(x) (_point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) | |
347 static gint _point_sizes [] = { 8, 10, 12, 14, 20, 30, 40 }; | |
348 | |
349 enum fatype { size, color, face, junk }; | |
350 typedef struct { | |
351 enum fatype type; | |
352 union { | |
353 int size; | |
354 char *color; | |
355 char *face; | |
356 char *junk; | |
357 } u; | |
358 } fontattr; | |
359 | |
360 static void fontattr_free(fontattr *f) | |
361 { | |
362 if (f->type == color) | |
363 g_free(f->u.color); | |
364 else if (f->type == face) | |
365 g_free(f->u.face); | |
366 g_free(f); | |
367 } | |
368 | |
369 static void yahoo_htc_queue_cleanup(GQueue *q) | |
370 { | |
371 char *tmp; | |
372 | |
373 while ((tmp = g_queue_pop_tail(q))) | |
374 g_free(tmp); | |
375 g_queue_free(q); | |
376 } | |
377 | |
378 static void _parse_font_tag(const char *src, GString *dest, int *i, int *j, | |
379 int len, GQueue *colors, GQueue *tags, GQueue *ftattr) | |
380 { | |
381 | |
382 int m, n, vstart; | |
383 gboolean quote = 0, done = 0; | |
384 | |
385 m = *j; | |
386 | |
387 while (1) { | |
388 m++; | |
389 | |
390 if (m >= len) { | |
391 g_string_append(dest, &src[*i]); | |
392 *i = len; | |
393 break; | |
394 } | |
395 | |
396 if (src[m] == '=') { | |
397 n = vstart = m; | |
398 while (1) { | |
399 n++; | |
400 | |
401 if (n >= len) { | |
402 m = n; | |
403 break; | |
404 } | |
405 | |
6631 | 406 if (src[n] == '"') { |
6629 | 407 if (!quote) { |
408 quote = 1; | |
409 vstart = n; | |
410 continue; | |
411 } else { | |
412 done = 1; | |
413 } | |
6631 | 414 } |
6629 | 415 |
416 if (!quote && ((src[n] == ' ') || (src[n] == '>'))) | |
417 done = 1; | |
418 | |
419 if (done) { | |
420 if (!g_ascii_strncasecmp(&src[*j+1], "FACE", m - *j - 1)) { | |
421 fontattr *f; | |
422 | |
423 f = g_new(fontattr, 1); | |
424 f->type = face; | |
425 f->u.face = g_strndup(&src[vstart+1], n-vstart-1); | |
426 if (!ftattr) | |
427 ftattr = g_queue_new(); | |
428 g_queue_push_tail(ftattr, f); | |
429 m = n; | |
430 break; | |
431 } else if (!g_ascii_strncasecmp(&src[*j+1], "SIZE", m - *j - 1)) { | |
432 fontattr *f; | |
433 | |
434 f = g_new(fontattr, 1); | |
435 f->type = size; | |
436 f->u.size = POINT_SIZE(strtol(&src[vstart+1], NULL, 10)); | |
437 if (!ftattr) | |
438 ftattr = g_queue_new(); | |
439 g_queue_push_tail(ftattr, f); | |
440 m = n; | |
441 break; | |
442 } else if (!g_ascii_strncasecmp(&src[*j+1], "COLOR", m - *j - 1)) { | |
443 fontattr *f; | |
444 | |
445 f = g_new(fontattr, 1); | |
446 f->type = color; | |
447 f->u.color = g_strndup(&src[vstart+1], n-vstart-1); | |
448 if (!ftattr) | |
449 ftattr = g_queue_new(); | |
450 g_queue_push_head(ftattr, f); | |
451 m = n; | |
452 break; | |
453 } else { | |
454 fontattr *f; | |
455 | |
456 f = g_new(fontattr, 1); | |
457 f->type = junk; | |
458 f->u.junk = g_strndup(&src[*j+1], n-*j); | |
459 if (!ftattr) | |
460 ftattr = g_queue_new(); | |
461 g_queue_push_tail(ftattr, f); | |
462 m = n; | |
463 break; | |
464 } | |
465 | |
466 } | |
467 } | |
468 } | |
469 | |
470 if (src[m] == ' ') | |
471 *j = m; | |
472 | |
473 | |
474 | |
475 if (src[m] == '>') { | |
476 gboolean needendtag = 0; | |
477 fontattr *f; | |
478 GString *tmp = g_string_new(NULL); | |
479 char *colorstr; | |
480 | |
481 if (!g_queue_is_empty(ftattr)) { | |
482 while ((f = g_queue_pop_tail(ftattr))) { | |
483 switch (f->type) { | |
484 case size: | |
485 if (!needendtag) { | |
486 needendtag = 1; | |
487 g_string_append(dest, "<font "); | |
488 } | |
489 | |
490 g_string_append_printf(dest, "size=\"%d\" ", f->u.size); | |
491 fontattr_free(f); | |
492 break; | |
493 case face: | |
494 if (!needendtag) { | |
495 needendtag = 1; | |
496 g_string_append(dest, "<font "); | |
497 } | |
498 | |
499 g_string_append_printf(dest, "face=\"%s\" ", f->u.face); | |
500 fontattr_free(f); | |
501 break; | |
502 case junk: | |
503 if (!needendtag) { | |
504 needendtag = 1; | |
505 g_string_append(dest, "<font "); | |
506 } | |
507 | |
508 g_string_append(dest, f->u.junk); | |
509 fontattr_free(f); | |
510 break; | |
511 | |
512 case color: | |
513 if (needendtag) { | |
514 g_string_append(tmp, "</font>"); | |
515 dest->str[dest->len-1] = '>'; | |
516 needendtag = 0; | |
517 } | |
518 | |
519 colorstr = g_queue_peek_tail(colors); | |
520 g_string_append(tmp, colorstr ? colorstr : "\033[#000000m"); | |
521 g_string_append_printf(dest, "\033[%sm", f->u.color); | |
522 g_queue_push_tail(colors, g_strdup_printf("\033[%sm", f->u.color)); | |
523 fontattr_free(f); | |
524 break; | |
525 } | |
526 } | |
527 | |
528 g_queue_free(ftattr); | |
529 ftattr = NULL; | |
530 | |
531 if (needendtag) { | |
532 dest->str[dest->len-1] = '>'; | |
533 g_queue_push_tail(tags, g_strdup("</font>")); | |
534 g_string_free(tmp, TRUE); | |
535 } else { | |
536 g_queue_push_tail(tags, tmp->str); | |
537 g_string_free(tmp, FALSE); | |
538 } | |
539 } | |
540 | |
541 *i = *j = m; | |
542 break; | |
543 } | |
544 } | |
545 | |
546 } | |
547 | |
548 char *yahoo_html_to_codes(const char *src) | |
549 { | |
6631 | 550 int i, j, len; |
6629 | 551 GString *dest; |
552 char *ret, *esc; | |
553 GQueue *colors, *tags; | |
554 GQueue *ftattr = NULL; | |
8440 | 555 gboolean no_more_specials = FALSE; |
6629 | 556 |
557 | |
558 colors = g_queue_new(); | |
559 tags = g_queue_new(); | |
560 | |
561 dest = g_string_sized_new(strlen(src)); | |
562 | |
563 for (i = 0, len = strlen(src); i < len; i++) { | |
564 | |
8440 | 565 if (!no_more_specials && src[i] == '<') { |
6629 | 566 j = i; |
567 | |
568 while (1) { | |
569 j++; | |
570 | |
571 if (j >= len) { /* no '>' */ | |
8440 | 572 g_string_append_c(dest, src[i]); |
573 no_more_specials = TRUE; | |
6629 | 574 break; |
575 } | |
576 | |
577 if (src[j] == '<') { | |
8440 | 578 /* FIXME: This doesn't convert outgoing entities. |
579 * However, I suspect this case may never | |
580 * happen anymore because of the entities. | |
581 */ | |
6629 | 582 g_string_append_len(dest, &src[i], j - i); |
583 i = j - 1; | |
584 if (ftattr) { | |
585 fontattr *f; | |
586 | |
587 while ((f = g_queue_pop_head(ftattr))) | |
588 fontattr_free(f); | |
589 g_queue_free(ftattr); | |
590 ftattr = NULL; | |
591 } | |
592 break; | |
593 } | |
594 | |
595 if (src[j] == ' ') { | |
596 if (!g_ascii_strncasecmp(&src[i+1], "BODY", j - i - 1)) { | |
597 char *t = strchr(&src[j], '>'); | |
598 if (!t) { | |
599 g_string_append(dest, &src[i]); | |
600 i = len; | |
601 break; | |
602 } else { | |
603 i = t - src; | |
604 break; | |
605 } | |
8533 | 606 } else if (!g_ascii_strncasecmp(&src[i+1], "A HREF=\"", j - i - 1)) { |
607 j += 7; | |
608 g_string_append(dest, "\033[lm"); | |
609 while (1) { | |
610 g_string_append_c(dest, src[j]); | |
611 if (++j >= len) { | |
8480 | 612 i = len; |
613 break; | |
614 } | |
8533 | 615 if (src[j] == '"') { |
616 g_string_append(dest, "\033[xlm"); | |
617 while (1) { | |
618 if (++j >= len) { | |
619 i = len; | |
620 break; | |
621 } | |
622 if (!g_ascii_strncasecmp(&src[j], "</A>", 4)) { | |
623 j += 3; | |
624 break; | |
625 } | |
626 } | |
627 i = j; | |
8480 | 628 break; |
629 } | |
630 } | |
6629 | 631 } else if (g_ascii_strncasecmp(&src[i+1], "FONT", j - i - 1)) { /* not interested! */ |
632 while (1) { | |
633 if (++j >= len) { | |
634 g_string_append(dest, &src[i]); | |
635 i = len; | |
636 break; | |
637 } | |
638 if (src[j] == '>') { | |
639 g_string_append_len(dest, &src[i], j - i + 1); | |
640 i = j; | |
641 break; | |
642 } | |
643 } | |
644 } else { /* yay we have a font tag */ | |
645 _parse_font_tag(src, dest, &i, &j, len, colors, tags, ftattr); | |
646 } | |
647 | |
648 break; | |
649 } | |
650 | |
651 if (src[j] == '>') { | |
8440 | 652 /* This has some problems like the FIXME for the |
653 * '<' case. and like that case, I suspect the case | |
654 * that this has problems is won't happen anymore anyway. | |
655 */ | |
6629 | 656 int sublen = j - i - 1; |
657 | |
658 if (sublen) { | |
659 if (!g_ascii_strncasecmp(&src[i+1], "B", sublen)) { | |
660 g_string_append(dest, "\033[1m"); | |
661 } else if (!g_ascii_strncasecmp(&src[i+1], "/B", sublen)) { | |
662 g_string_append(dest, "\033[x1m"); | |
663 } else if (!g_ascii_strncasecmp(&src[i+1], "I", sublen)) { | |
664 g_string_append(dest, "\033[2m"); | |
665 } else if (!g_ascii_strncasecmp(&src[i+1], "/I", sublen)) { | |
666 g_string_append(dest, "\033[x2m"); | |
667 } else if (!g_ascii_strncasecmp(&src[i+1], "U", sublen)) { | |
668 g_string_append(dest, "\033[4m"); | |
669 } else if (!g_ascii_strncasecmp(&src[i+1], "/U", sublen)) { | |
670 g_string_append(dest, "\033[x4m"); | |
8480 | 671 } else if (!g_ascii_strncasecmp(&src[i+1], "/A", sublen)) { |
672 g_string_append(dest, "\033[xlm"); | |
8455 | 673 } else if (!g_ascii_strncasecmp(&src[i+1], "BR", sublen)) { |
674 g_string_append_c(dest, '\n'); | |
6629 | 675 } else if (!g_ascii_strncasecmp(&src[i+1], "/BODY", sublen)) { |
676 /* mmm, </body> tags. *BURP* */ | |
677 } else if (!g_ascii_strncasecmp(&src[i+1], "/FONT", sublen) && g_queue_peek_tail(tags)) { | |
678 char *etag, *cl; | |
679 | |
680 etag = g_queue_pop_tail(tags); | |
681 if (etag) { | |
682 g_string_append(dest, etag); | |
683 if (!strcmp(etag, "</font>")) { | |
684 cl = g_queue_pop_tail(colors); | |
685 if (cl) | |
686 g_free(cl); | |
687 } | |
688 g_free(etag); | |
689 } | |
690 } else { | |
691 g_string_append_len(dest, &src[i], j - i + 1); | |
692 } | |
693 } else { | |
694 g_string_append_len(dest, &src[i], j - i + 1); | |
695 } | |
696 | |
697 i = j; | |
698 break; | |
699 } | |
700 | |
701 } | |
702 | |
703 } else { | |
8440 | 704 if (((len - i) >= 4) && !strncmp(&src[i], "<", 4)) { |
705 g_string_append_c(dest, '<'); | |
706 i += 3; | |
707 } else if (((len - i) >= 4) && !strncmp(&src[i], ">", 4)) { | |
708 g_string_append_c(dest, '>'); | |
709 i += 3; | |
710 } else if (((len - i) >= 5) && !strncmp(&src[i], "&", 4)) { | |
711 g_string_append_c(dest, '&'); | |
712 i += 4; | |
713 } else if (((len - i) >= 6) && !strncmp(&src[i], """, 4)) { | |
714 g_string_append_c(dest, '"'); | |
715 i += 5; | |
716 } else { | |
717 g_string_append_c(dest, src[i]); | |
718 } | |
6629 | 719 } |
720 } | |
721 | |
722 ret = dest->str; | |
723 g_string_free(dest, FALSE); | |
724 | |
725 esc = g_strescape(ret, NULL); | |
726 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "yahoo_html_to_codes: Returning string: '%s'.\n", esc); | |
727 g_free(esc); | |
728 | |
729 yahoo_htc_queue_cleanup(colors); | |
730 yahoo_htc_queue_cleanup(tags); | |
731 | |
732 return ret; | |
733 } |