+static gchar *rssyl_replace_chrefs(gchar *string)
+{
+ char *new = g_malloc0(strlen(string)), *ret;
+ char buf[16], tmp[6];
+ int i, ii, j, n, len;
+ gunichar c;
+ gboolean valid, replaced;
+
+ /* &xx; */
+ ii = 0;
+ for (i = 0; i < strlen(string); ++i) {
+ if (string[i] == '&') {
+ j = i+1;
+ n = 0;
+ valid = FALSE;
+ while (string[j] != '\0' && j < 16) {
+ if (string[j] != ';') {
+ buf[n++] = string[j];
+ } else {
+ /* End of entity */
+ valid = TRUE;
+ buf[n] = '\0';
+ break;
+ }
+ j++;
+ }
+ if (strlen(buf) > 0 && valid) {
+ replaced = FALSE;
+
+ if (buf[0] == '#' && (c = atoi(buf+1)) > 0) {
+ len = g_unichar_to_utf8(c, tmp);
+ tmp[len] = '\0';
+ g_strlcat(new, tmp, strlen(string));
+ ii += len;
+ replaced = TRUE;
+ } else {
+ for (c = 0; symbol_list[c].key != NULL; c++) {
+ if (!strcmp(buf, symbol_list[c].key)) {
+ g_strlcat(new, symbol_list[c].val, strlen(string));
+ ii += strlen(symbol_list[c].val);
+ replaced = TRUE;
+ break;
+ }
+ }
+ }
+ if (!replaced) {
+ new[ii++] = '&'; /* & */
+ g_strlcat(new, buf, strlen(string));
+ ii += strlen(buf);
+ new[ii++] = ';';
+ }
+ i = j;
+ } else {
+ new[ii++] = string[i];
+ }
+ } else {
+ new[ii++] = string[i];
+ }
+ }
+
+ ret = g_strdup(new);
+ g_free(new);
+ return ret;
+}
+