Mercurial > audlegacy
comparison audacious/util.c @ 2184:7d40f0a290b9 trunk
[svn] - break out string-related functions from util.c
author | nenolod |
---|---|
date | Wed, 20 Dec 2006 06:45:56 -0800 |
parents | 299651a8f107 |
children | 165a62fdb49e |
comparison
equal
deleted
inserted
replaced
2183:76b4dfc5f4e7 | 2184:7d40f0a290b9 |
---|---|
61 #include <libudet_c.h> | 61 #include <libudet_c.h> |
62 #endif | 62 #endif |
63 #endif | 63 #endif |
64 | 64 |
65 static GQuark quark_popup_data; | 65 static GQuark quark_popup_data; |
66 | |
67 | |
68 /* | |
69 * escape_shell_chars() | |
70 * | |
71 * Escapes characters that are special to the shell inside double quotes. | |
72 */ | |
73 | |
74 gchar * | |
75 escape_shell_chars(const gchar * string) | |
76 { | |
77 const gchar *special = "$`\"\\"; /* Characters to escape */ | |
78 const gchar *in = string; | |
79 gchar *out, *escaped; | |
80 gint num = 0; | |
81 | |
82 while (*in != '\0') | |
83 if (strchr(special, *in++)) | |
84 num++; | |
85 | |
86 escaped = g_malloc(strlen(string) + num + 1); | |
87 | |
88 in = string; | |
89 out = escaped; | |
90 | |
91 while (*in != '\0') { | |
92 if (strchr(special, *in)) | |
93 *out++ = '\\'; | |
94 *out++ = *in++; | |
95 } | |
96 *out = '\0'; | |
97 | |
98 return escaped; | |
99 } | |
100 | 66 |
101 | 67 |
102 /* | 68 /* |
103 * find <file> in directory <dirname> or subdirectories. return | 69 * find <file> in directory <dirname> or subdirectories. return |
104 * pointer to complete filename which has to be freed by calling | 70 * pointer to complete filename which has to be freed by calling |
1409 } while (n > 0); | 1375 } while (n > 0); |
1410 | 1376 |
1411 return count; | 1377 return count; |
1412 } | 1378 } |
1413 | 1379 |
1414 static gchar * | |
1415 str_twenty_to_space(gchar * str) | |
1416 { | |
1417 gchar *match, *match_end; | |
1418 | |
1419 g_return_val_if_fail(str != NULL, NULL); | |
1420 | |
1421 while ((match = strstr(str, "%20"))) { | |
1422 match_end = match + 3; | |
1423 *match++ = ' '; | |
1424 while (*match_end) | |
1425 *match++ = *match_end++; | |
1426 *match = 0; | |
1427 } | |
1428 | |
1429 return str; | |
1430 } | |
1431 | |
1432 static gchar * | |
1433 str_replace_char(gchar * str, gchar old, gchar new) | |
1434 { | |
1435 gchar *match; | |
1436 | |
1437 g_return_val_if_fail(str != NULL, NULL); | |
1438 | |
1439 match = str; | |
1440 while ((match = strchr(match, old))) | |
1441 *match = new; | |
1442 | |
1443 return str; | |
1444 } | |
1445 | |
1446 gchar * | |
1447 str_append(gchar * str, const gchar * add_str) | |
1448 { | |
1449 return str_replace(str, g_strconcat(str, add_str, NULL)); | |
1450 } | |
1451 | |
1452 gchar * | |
1453 str_replace(gchar * str, gchar * new_str) | |
1454 { | |
1455 g_free(str); | |
1456 return new_str; | |
1457 } | |
1458 | |
1459 void | |
1460 str_replace_in(gchar ** str, gchar * new_str) | |
1461 { | |
1462 *str = str_replace(*str, new_str); | |
1463 } | |
1464 | |
1465 | |
1466 gboolean | |
1467 str_has_prefix_nocase(const gchar * str, const gchar * prefix) | |
1468 { | |
1469 return (strncasecmp(str, prefix, strlen(prefix)) == 0); | |
1470 } | |
1471 | |
1472 gboolean | |
1473 str_has_suffix_nocase(const gchar * str, const gchar * suffix) | |
1474 { | |
1475 return (strcasecmp(str + strlen(str) - strlen(suffix), suffix) == 0); | |
1476 } | |
1477 | |
1478 gboolean | |
1479 str_has_suffixes_nocase(const gchar * str, gchar * const *suffixes) | |
1480 { | |
1481 gchar *const *suffix; | |
1482 | |
1483 g_return_val_if_fail(str != NULL, FALSE); | |
1484 g_return_val_if_fail(suffixes != NULL, FALSE); | |
1485 | |
1486 for (suffix = suffixes; *suffix; suffix++) | |
1487 if (str_has_suffix_nocase(str, *suffix)) | |
1488 return TRUE; | |
1489 | |
1490 return FALSE; | |
1491 } | |
1492 | |
1493 gchar * | |
1494 str_to_utf8_fallback(const gchar * str) | |
1495 { | |
1496 gchar *out_str, *convert_str, *chr; | |
1497 | |
1498 /* NULL in NULL out */ | |
1499 if (!str) | |
1500 return NULL; | |
1501 | |
1502 convert_str = g_strdup(str); | |
1503 for (chr = convert_str; *chr; chr++) { | |
1504 if (*chr & 0x80) | |
1505 *chr = '?'; | |
1506 } | |
1507 | |
1508 out_str = g_strconcat(convert_str, _(" (invalid UTF-8)"), NULL); | |
1509 g_free(convert_str); | |
1510 | |
1511 return out_str; | |
1512 } | |
1513 | |
1514 gchar * | |
1515 filename_to_utf8(const gchar * filename) | |
1516 { | |
1517 gchar *out_str; | |
1518 | |
1519 /* NULL in NULL out */ | |
1520 if (!filename) | |
1521 return NULL; | |
1522 | |
1523 if ((out_str = g_filename_to_utf8(filename, -1, NULL, NULL, NULL))) | |
1524 return out_str; | |
1525 | |
1526 return str_to_utf8_fallback(filename); | |
1527 } | |
1528 | |
1529 gchar * | |
1530 str_to_utf8(const gchar * str) | |
1531 { | |
1532 gchar *out_str; | |
1533 | |
1534 /* NULL in NULL out */ | |
1535 if (!str) | |
1536 return NULL; | |
1537 | |
1538 /* Note: Currently, playlist calls this function repeatedly, even | |
1539 * if the string is already converted into utf-8. | |
1540 * chardet_to_utf8() would convert a valid utf-8 string into a | |
1541 * different utf-8 string, if fallback encodings were supplied and | |
1542 * the given string could be treated as a string in one of fallback | |
1543 * encodings. To avoid this, the order of evaluation has been | |
1544 * changed. (It might cause a drawback?) | |
1545 */ | |
1546 /* chardet encoding detector */ | |
1547 if ((out_str = chardet_to_utf8(str, strlen(str), NULL, NULL, NULL))) | |
1548 return out_str; | |
1549 | |
1550 /* already UTF-8? */ | |
1551 if (g_utf8_validate(str, -1, NULL)) | |
1552 return g_strdup(str); | |
1553 | |
1554 /* assume encoding associated with locale */ | |
1555 if ((out_str = g_locale_to_utf8(str, -1, NULL, NULL, NULL))) | |
1556 return out_str; | |
1557 | |
1558 /* all else fails, we mask off character codes >= 128, | |
1559 replace with '?' */ | |
1560 return str_to_utf8_fallback(str); | |
1561 } | |
1562 | |
1563 | |
1564 const gchar * | |
1565 str_skip_chars(const gchar * str, const gchar * chars) | |
1566 { | |
1567 while (strchr(chars, *str)) | |
1568 str++; | |
1569 return str; | |
1570 } | |
1571 | |
1572 gchar * | |
1573 convert_title_text(gchar * title) | |
1574 { | |
1575 g_return_val_if_fail(title != NULL, NULL); | |
1576 | |
1577 if (cfg.convert_slash) | |
1578 str_replace_char(title, '\\', '/'); | |
1579 | |
1580 if (cfg.convert_underscore) | |
1581 str_replace_char(title, '_', ' '); | |
1582 | |
1583 if (cfg.convert_twenty) | |
1584 str_twenty_to_space(title); | |
1585 | |
1586 return title; | |
1587 } | |
1588 | |
1589 | |
1590 gboolean | 1380 gboolean |
1591 dir_foreach(const gchar * path, DirForeachFunc function, | 1381 dir_foreach(const gchar * path, DirForeachFunc function, |
1592 gpointer user_data, GError ** error) | 1382 gpointer user_data, GError ** error) |
1593 { | 1383 { |
1594 GError *error_out = NULL; | 1384 GError *error_out = NULL; |
1683 GtkWidget *item, *menu_; | 1473 GtkWidget *item, *menu_; |
1684 | 1474 |
1685 item = gtk_item_factory_get_widget(menu, item_path); | 1475 item = gtk_item_factory_get_widget(menu, item_path); |
1686 menu_ = gtk_item_factory_get_widget(submenu, ""); | 1476 menu_ = gtk_item_factory_get_widget(submenu, ""); |
1687 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu_); | 1477 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu_); |
1688 } | |
1689 | |
1690 | |
1691 gchar *chardet_to_utf8(const gchar *str, gssize len, | |
1692 gsize *arg_bytes_read, gsize *arg_bytes_write, GError **arg_error) | |
1693 { | |
1694 #ifdef USE_CHARDET | |
1695 char *det = NULL, *encoding = NULL; | |
1696 #endif | |
1697 gchar *ret = NULL; | |
1698 gsize *bytes_read, *bytes_write; | |
1699 GError **error; | |
1700 gsize my_bytes_read, my_bytes_write; | |
1701 | |
1702 bytes_read = arg_bytes_read ? arg_bytes_read : &my_bytes_read; | |
1703 bytes_write = arg_bytes_write ? arg_bytes_write : &my_bytes_write; | |
1704 error = arg_error ? arg_error : NULL; | |
1705 | |
1706 #ifdef USE_CHARDET | |
1707 if(cfg.chardet_detector) | |
1708 det = cfg.chardet_detector; | |
1709 | |
1710 if(det){ | |
1711 if(!strncasecmp("japanese", det, sizeof("japanese"))) { | |
1712 encoding = (char *)guess_jp(str, strlen(str)); | |
1713 if (!encoding) | |
1714 goto fallback; | |
1715 } else if(!strncasecmp("taiwanese", det, sizeof("taiwanese"))) { | |
1716 encoding = (char *)guess_tw(str, strlen(str)); | |
1717 if (!encoding) | |
1718 goto fallback; | |
1719 } else if(!strncasecmp("chinese", det, sizeof("chinese"))) { | |
1720 encoding = (char *)guess_cn(str, strlen(str)); | |
1721 if (!encoding) | |
1722 goto fallback; | |
1723 } else if(!strncasecmp("korean", det, sizeof("korean"))) { | |
1724 encoding = (char *)guess_kr(str, strlen(str)); | |
1725 if (!encoding) | |
1726 goto fallback; | |
1727 } else if(!strncasecmp("russian", det, sizeof("russian"))) { | |
1728 rcd_russian_charset res = rcdGetRussianCharset(str, strlen(str)); | |
1729 switch(res) { | |
1730 case RUSSIAN_CHARSET_WIN: | |
1731 encoding = "CP1251"; | |
1732 break; | |
1733 case RUSSIAN_CHARSET_ALT: | |
1734 encoding = "CP866"; | |
1735 break; | |
1736 case RUSSIAN_CHARSET_KOI: | |
1737 encoding = "KOI8-R"; | |
1738 break; | |
1739 case RUSSIAN_CHARSET_UTF8: | |
1740 encoding = "UTF-8"; | |
1741 break; | |
1742 } | |
1743 if (!encoding) | |
1744 goto fallback; | |
1745 #ifdef HAVE_UDET | |
1746 } else if (!strncasecmp("universal", det, sizeof("universal"))) { | |
1747 encoding = (char *)detectCharset((char *)str, strlen(str)); | |
1748 if (!encoding) | |
1749 goto fallback; | |
1750 #endif | |
1751 } else /* none, invalid */ | |
1752 goto fallback; | |
1753 | |
1754 ret = g_convert(str, len, "UTF-8", encoding, bytes_read, bytes_write, error); | |
1755 } | |
1756 | |
1757 fallback: | |
1758 #endif | |
1759 if(!ret && cfg.chardet_fallback){ | |
1760 gchar **encs=NULL, **enc=NULL; | |
1761 encs = g_strsplit_set(cfg.chardet_fallback, " ,:;|/", 0); | |
1762 | |
1763 if(encs){ | |
1764 enc = encs; | |
1765 for(enc=encs; *enc ; enc++){ | |
1766 ret = g_convert(str, len, "UTF-8", *enc, bytes_read, bytes_write, error); | |
1767 if(len == *bytes_read){ | |
1768 break; | |
1769 } | |
1770 } | |
1771 g_strfreev(encs); | |
1772 } | |
1773 } | |
1774 | |
1775 #ifdef USE_CHARDET | |
1776 /* many tag libraries return 2byte latin1 utf8 character as | |
1777 converted 8bit iso-8859-1 character, if they are asked to return | |
1778 latin1 string. | |
1779 */ | |
1780 if(!ret){ | |
1781 ret = g_convert(str, len, "UTF-8", "ISO-8859-1", bytes_read, bytes_write, error); | |
1782 } | |
1783 #endif | |
1784 | |
1785 if(ret){ | |
1786 if(g_utf8_validate(ret, -1, NULL)) | |
1787 return ret; | |
1788 else { | |
1789 g_free(ret); | |
1790 ret = NULL; | |
1791 } | |
1792 } | |
1793 | |
1794 return NULL; /* if I have no idea, return NULL. */ | |
1795 } | 1478 } |
1796 | 1479 |
1797 /* | 1480 /* |
1798 * Resizes a GDK pixmap. | 1481 * Resizes a GDK pixmap. |
1799 */ | 1482 */ |