📄 xml.c
字号:
intdump_data_element( int depth, char **buffer, crm_data_t *data, gboolean formatted) { int printed = 0; int child_result = 0; int has_children = 0; const char *name = crm_element_name(data); crm_insane("Dumping %s...", name); crm_validate_data(data); if(buffer == NULL || *buffer == NULL) { crm_err("No buffer supplied to dump XML into"); return -1; } else if(data == NULL) { crm_warn("No data to dump as XML"); (*buffer)[0] = EOS; return 0; } else if(name == NULL && depth == 0) { xml_child_iter( data, a_child, NULL, child_result = dump_data_element( depth, buffer, a_child, formatted); if(child_result < 0) { return child_result; } ); return 0; } else if(name == NULL) { crm_err("Cannot dump NULL element at depth %d", depth); return -1; } if(formatted) { printed = print_spaces(*buffer, depth); update_buffer_head(*buffer, printed); } printed = sprintf(*buffer, "<%s", name); update_buffer_head(*buffer, printed); xml_prop_iter(data, prop_name, prop_value, if(safe_str_eq(XML_ATTR_TAGNAME, prop_name)) { continue; } else if(safe_str_eq(XML_ATTR_PARENT, prop_name)) { continue; } crm_insane("Dumping <%s %s=\"%s\"...", name, prop_name, prop_value); printed = sprintf(*buffer, " %s=\"%s\"", prop_name, prop_value); update_buffer_head(*buffer, printed); ); xml_child_iter( data, child, NULL, if(child != NULL) { has_children++; break; } ); printed = sprintf(*buffer, "%s>%s", has_children==0?"/":"", formatted?"\n":""); update_buffer_head(*buffer, printed); if(has_children == 0) { return 0; } xml_child_iter( data, child, NULL, child_result = dump_data_element( depth+1, buffer, child, formatted); if(child_result < 0) { return -1; } ); if(formatted) { printed = print_spaces(*buffer, depth); update_buffer_head(*buffer, printed); } printed = sprintf(*buffer, "</%s>%s", name, formatted?"\n":""); update_buffer_head(*buffer, printed); crm_insane("Dumped %s...", name); return has_children;}gbooleanxml_has_children(crm_data_t *xml_root){ crm_validate_data(xml_root);#ifdef USE_LIBXML if(xml_root != NULL && xml_root->children != NULL) { return TRUE; }#else xml_child_iter( xml_root, a_child, NULL, return TRUE; );#endif return FALSE;}voidcrm_validate_data(const crm_data_t *xml_root){#ifdef USE_LIBXML CRM_DEV_ASSERT(xml_root != NULL);#else# ifndef XML_PARANOIA_CHECKS CRM_DEV_ASSERT(xml_root != NULL);# else int lpc = 0; CRM_ASSERT(xml_root != NULL); CRM_ASSERT(cl_is_allocated(xml_root) == 1); CRM_ASSERT(xml_root->nfields < 500); for (lpc = 0; lpc < xml_root->nfields; lpc++) { void *child = xml_root->values[lpc]; CRM_ASSERT(cl_is_allocated(xml_root->names[lpc]) == 1); if(child == NULL) { } else if(xml_root->types[lpc] == FT_STRUCT) { crm_validate_data(child); } else if(xml_root->types[lpc] == FT_STRING) { CRM_ASSERT(cl_is_allocated(child) == 1);/* } else { *//* CRM_DEV_ASSERT(FALSE); */ } }# endif#endif}/* FIXME!! This whole function is evil!! */voidcrm_set_element_parent(crm_data_t *data, crm_data_t *parent){#ifdef USE_LIBXML CRM_DEV_ASSERT(FALSE/* not implemented*/); #else crm_validate_data(data); if(parent != NULL) { ha_msg_mod_int(data, XML_ATTR_PARENT, 1); } else if(cl_get_string(data, XML_ATTR_PARENT) != NULL) { ha_msg_mod_int(data, XML_ATTR_PARENT, 0); }#endif}const char *crm_element_value(crm_data_t *data, const char *name){#ifdef USE_LIBXML return xmlGetProp(data, name);#else const char *value = NULL; crm_validate_data(data); value = cl_get_string(data, name); if(value != NULL) { cl_is_allocated(value); } return value;#endif}char *crm_element_value_copy(crm_data_t *data, const char *name){ const char *value = NULL; char *value_copy = NULL;#ifdef USE_LIBXML value = xmlGetProp(data, name);#else crm_validate_data(data); value = cl_get_string(data, name); if(value != NULL) { cl_is_allocated(value); }#endif CRM_DEV_ASSERT(value != NULL); if(value != NULL) { value_copy = crm_strdup(value); } return value_copy;}const char *crm_element_name(crm_data_t *data){#ifdef USE_LIBXML return (data ? data->name : NULL);#else crm_validate_data(data); return cl_get_string(data, XML_ATTR_TAGNAME);#endif}voidxml_remove_prop(crm_data_t *obj, const char *name){#ifdef USE_LIBXML xmlUnsetProp(obj, name);#else if(crm_element_value(obj, name) != NULL) { cl_msg_remove(obj, name); }#endif}voidcrm_update_parents(crm_data_t *xml_root){#ifndef USE_LIBXML crm_validate_data(xml_root); xml_child_iter( xml_root, a_child, NULL, crm_set_element_parent(a_child, xml_root); crm_update_parents(a_child); );#endif}#ifndef USE_LIBXMLintget_tag_name(const char *input) { int lpc = 0; char ch = 0; const char *error = NULL; gboolean do_special = FALSE; for(lpc = 0; error == NULL && lpc < strlen(input); lpc++) { ch = input[lpc]; crm_insane("Processing char %c [%d]", ch, lpc); switch(ch) { case EOF: case 0: error = "unexpected EOS"; break; case '?': if(lpc == 0) { /* weird xml tag that we dont care about */ do_special = TRUE; } else { return lpc; } break; case '/': case '>': case '\t': case '\n': case ' ': if(!do_special) { return lpc; } break; default: if(do_special) { } else if('a' <= ch && ch <= 'z') { } else if('A' <= ch && ch <= 'Z') { } else if(ch == '_') { } else { error = "bad character, not in [a-zA-Z_]"; } break; } } crm_err("Error parsing token near %.15s: %s", input, crm_str(error)); return -1;}intget_attr_name(const char *input) { int lpc = 0; char ch = 0; const char *error = NULL; for(lpc = 0; error == NULL && lpc < strlen(input); lpc++) { ch = input[lpc]; crm_insane("Processing char %c[%d]", ch, lpc); switch(ch) { case EOF: case 0: error = "unexpected EOS"; break; case '\t': case '\n': case ' ': error = "unexpected whitespace"; break; case '=': return lpc; default: if('a' <= ch && ch <= 'z') { } else if('A' <= ch && ch <= 'Z') { } else if(ch == '_') { } else { error = "bad character, not in [a-zA-Z_]"; } break; } } crm_err("Error parsing token near %.15s: %s", input, crm_str(error)); return -1;}intget_attr_value(const char *input) { int lpc = 0; char ch = 0; const char *error = NULL; for(lpc = 0; error == NULL && lpc < strlen(input); lpc++) { ch = input[lpc]; crm_insane("Processing char %c [%d]", ch, lpc); switch(ch) { case EOF: case 0: error = "unexpected EOS"; break; case '\\': if(input[lpc+1] == '"') { /* skip over the next char */ lpc++; break; } /*fall through*/ case '"': return lpc; default: break; } } crm_err("Error parsing token near %.15s: %s", input, crm_str(error)); return -1;}crm_data_t*parse_xml(const char *input, int *offset){ int len = 0, lpc = 0; char ch = 0; char *tag_name = NULL; char *attr_name = NULL; char *attr_value = NULL; gboolean more = TRUE; const char *error = NULL; const char *our_input = input; crm_data_t *new_obj = NULL; if(offset != NULL) { our_input = input + (*offset); } len = strlen(our_input); while(lpc < len) { if(our_input[lpc] != '<') { } else if(our_input[lpc+1] == '!') { crm_err("XML Comments are not supported"); crm_insane("Skipping char %c", our_input[lpc]); lpc++; } else if(our_input[lpc+1] == '?') { crm_insane("Skipping char %c", our_input[lpc]); lpc++; } else { lpc++; our_input += lpc; break; } crm_insane("Skipping char %c", our_input[lpc]); lpc++; } len = get_tag_name(our_input); if(len < 0) { return NULL; } crm_malloc(tag_name, len+1); strncpy(tag_name, our_input, len+1); tag_name[len] = EOS; crm_devel("Processing tag %s", tag_name); new_obj = ha_msg_new(1); CRM_DEV_ASSERT(cl_is_allocated(new_obj) == 1); ha_msg_add(new_obj, XML_ATTR_TAGNAME, tag_name); lpc = len; for(; more && error == NULL && lpc < strlen(input); lpc++) { ch = our_input[lpc]; crm_insane("Processing char %c[%d]", ch, lpc); switch(ch) { case EOF: case 0: error = "unexpected EOS"; break; case '/': if(our_input[lpc+1] == '>') { more = FALSE; } break; case '<': if(our_input[lpc+1] != '/') { crm_data_t *child = NULL; crm_devel("Start parsing child..."); child = parse_xml(our_input, &lpc); if(child == NULL) { error = "error parsing child"; } else { CRM_DEV_ASSERT(cl_is_allocated(child) == 1); ha_msg_addstruct( new_obj, crm_element_name(child), child); crm_devel("Finished parsing child: %s", crm_element_name(child));/* lpc++; /\* > *\/ */ } } else { lpc += 2; /* </ */ len = get_tag_name(our_input+lpc); if(len < 0) { error = "couldnt find tag"; } else if(strncmp(our_input+lpc, tag_name, len) == 0) { more = FALSE; lpc += len;/* lpc++; /\* > *\/ */ if(our_input[lpc] != '>') { error = "clase tag cannot contain attrs"; } crm_devel("Finished parsing ourselves: %s", crm_element_name(new_obj)); } else { error = "Mismatching close tag"; crm_err("Expected: %s", tag_name); } } break; case '=': lpc++; /* = */ /*fall through*/ case '"': lpc++; /* " */ len = get_attr_value(our_input+lpc); if(len < 0) { error = "couldnt find attr_value"; } else { crm_malloc(attr_value, len+1); strncpy(attr_value, our_input+lpc, len+1); attr_value[len] = EOS; lpc += len;/* lpc++; /\* " *\/ */ crm_devel("creating nvpair: <%s %s=\"%s\"...", tag_name, crm_str(attr_name), crm_str(attr_value)); ha_msg_add(new_obj, attr_name, attr_value); crm_free(attr_name); crm_free(attr_value); } break; case '>': case ' ': case '\t': case '\n': break; default: len = get_attr_name(our_input+lpc); if(len < 0) { error = "couldnt find attr_name"; } else { crm_malloc(attr_name, len+1); strncpy(attr_name, our_input+lpc, len+1); attr_name[len] = EOS; lpc += len; crm_trace("found attr name: %s", attr_name); lpc--; /* make sure the '=' is seen next time around */ } break; } } if(error) { crm_err("Error parsing token: %s", error); crm_err("Error at or before: %s", our_input+lpc-3); return NULL; } crm_devel("Finished processing %s tag", tag_name); crm_free(tag_name); if(offset != NULL) { (*offset) += lpc; } CRM_DEV_ASSERT(cl_is_allocated(new_obj) == 1); return new_obj;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -