gint xml_parse_next_tag(XMLFile *file) { gchar buf[XMLBUFSIZE]; gchar *bufp = buf; gchar *tag_str; XMLTag *tag; gint len; next: if (file->is_empty_element == TRUE) { file->is_empty_element = FALSE; xml_pop_tag(file); return 0; } if (xml_get_parenthesis(file, buf, sizeof(buf)) < 0) { g_warning("xml_parse_next_tag(): Can't parse next tag in %s", file->path); return -1; } len = strlen(buf); /* end-tag */ if (buf[0] == '/') { if (strcmp(xml_get_current_tag(file)->tag, buf + 1) != 0) { g_warning("xml_parse_next_tag(): Tag name mismatch in %s : %s (%s)", file->path, buf, xml_get_current_tag(file)->tag); return -1; } xml_pop_tag(file); return 0; } if (len >= 7 && !strncmp(buf, "!-- ", 4) && !strncmp(buf+len-3, " --", 3)) { /* skip comment */ goto next; } tag = xml_tag_new(NULL); xml_push_tag(file, tag); if (len > 0 && buf[len - 1] == '/') { file->is_empty_element = TRUE; buf[len - 1] = '\0'; g_strchomp(buf); } if (strlen(buf) == 0) { g_warning("xml_parse_next_tag(): Tag name is empty in %s", file->path); return -1; } while (*bufp != '\0' && !g_ascii_isspace(*bufp)) bufp++; if (*bufp == '\0') { if (file->need_codeconv) { tag_str = conv_codeset_strdup(buf, file->encoding, CS_INTERNAL); if (tag_str) { tag->tag = XML_STRING_ADD(tag_str); g_free(tag_str); } else tag->tag = XML_STRING_ADD(buf); } else tag->tag = XML_STRING_ADD(buf); return 0; } else { *bufp++ = '\0'; if (file->need_codeconv) { tag_str = conv_codeset_strdup(buf, file->encoding, CS_INTERNAL); if (tag_str) { tag->tag = XML_STRING_ADD(tag_str); g_free(tag_str); } else tag->tag = XML_STRING_ADD(buf); } else tag->tag = XML_STRING_ADD(buf); } /* parse attributes ( name=value ) */ while (*bufp) { XMLAttr *attr; gchar *attr_name; gchar *attr_value; gchar *utf8_attr_name; gchar *utf8_attr_value; gchar *p; gchar quote; while (g_ascii_isspace(*bufp)) bufp++; attr_name = bufp; if ((p = strchr(attr_name, '=')) == NULL) { g_warning("xml_parse_next_tag(): Syntax error in %s, tag (a) %s", file->path, attr_name); return -1; } bufp = p; *bufp++ = '\0'; while (g_ascii_isspace(*bufp)) bufp++; if (*bufp != '"' && *bufp != '\'') { g_warning("xml_parse_next_tag(): Syntax error in %s, tag (b) %s", file->path, bufp); return -1; } quote = *bufp; bufp++; attr_value = bufp; if ((p = strchr(attr_value, quote)) == NULL) { g_warning("xml_parse_next_tag(): Syntax error in %s, tag (c) %s", file->path, attr_value); return -1; } bufp = p; *bufp++ = '\0'; g_strchomp(attr_name); xml_unescape_str(attr_value); if (file->need_codeconv) { utf8_attr_name = conv_codeset_strdup (attr_name, file->encoding, CS_INTERNAL); utf8_attr_value = conv_codeset_strdup (attr_value, file->encoding, CS_INTERNAL); if (!utf8_attr_name) utf8_attr_name = g_strdup(attr_name); if (!utf8_attr_value) utf8_attr_value = g_strdup(attr_value); attr = xml_attr_new(utf8_attr_name, utf8_attr_value); g_free(utf8_attr_value); g_free(utf8_attr_name); } else { attr = xml_attr_new(attr_name, attr_value); } xml_tag_add_attr(tag, attr); } tag->attr = g_list_reverse(tag->attr); return 0; }
static XMLAttr *xml_copy_attr(XMLAttr *attr) { return xml_attr_new(attr->name, attr->value); }
/* Save selections in a common xml-file. Called when unloading the plugin. * This is analog to folder.h::folder_write_list. */ void notification_foldercheck_write_array(void) { gchar *path; XMLTag *tag; XMLNode *xmlnode; GNode *rootnode; gint ii; PrefFile *pfile; /* Do nothing if foldercheck is not in use */ if(specific_folder_array_size == 0) return; path = foldercheck_get_array_path(); if((pfile = prefs_write_open(path)) == NULL) { debug_print("Notification Plugin Error: Cannot open " "file " FOLDERCHECK_ARRAY " for writing\n"); return; } /* XML declarations */ xml_file_put_xml_decl(pfile->fp); /* Build up XML tree */ /* root node */ tag = xml_tag_new("foldercheckarray"); xmlnode = xml_node_new(tag, NULL); rootnode = g_node_new(xmlnode); /* branch nodes */ for(ii = 0; ii < specific_folder_array_size; ii++) { GNode *branchnode; GSList *walk; SpecificFolderArrayEntry *entry; entry = foldercheck_get_entry_from_id(ii); tag = xml_tag_new("branch"); xml_tag_add_attr(tag, xml_attr_new("name",entry->name)); xmlnode = xml_node_new(tag, NULL); branchnode = g_node_new(xmlnode); g_node_append(rootnode, branchnode); /* Write out the list as leaf nodes */ for(walk = entry->list; walk != NULL; walk = g_slist_next(walk)) { gchar *identifier; GNode *node; FolderItem *item = (FolderItem*) walk->data; identifier = folder_item_get_identifier(item); tag = xml_tag_new("folderitem"); xml_tag_add_attr(tag, xml_attr_new("identifier", identifier)); g_free(identifier); xmlnode = xml_node_new(tag, NULL); node = g_node_new(xmlnode); g_node_append(branchnode, node); } /* for all list elements in branch node */ } /* for all branch nodes */ /* Actual writing and cleanup */ xml_write_tree(rootnode, pfile->fp); if(prefs_file_close(pfile) < 0) { debug_print("Notification Plugin Error: Failed to write " "file " FOLDERCHECK_ARRAY "\n"); } /* Free XML tree */ xml_free_tree(rootnode); }