#include <eggdrop/eggdrop.h>
Go to the source code of this file.
Functions | |
const char * | xml_last_error (void) |
void | xml_set_error (const char *err) |
xml_node_t * | xml_node_new () |
Get a new, blank node. | |
xml_node_t * | xml_node_new_named (const char *name) |
Get a new, named node. | |
void | xml_node_free (xml_node_t *node) |
Free all memory associated with a node. | |
void | xml_node_unlink (xml_node_t *node) |
Unlinks a XML node from a tree. | |
void | xml_node_delete (xml_node_t *node) |
Deletes a node. | |
void | xml_node_delete_callbacked (xml_node_t *node, void(*callback)(void *)) |
Deletes a node and executes a callback function. | |
void | xml_doc_delete (xml_node_t *root) |
Deletes an entire tree. | |
xml_node_t * | xml_node_vlookup (xml_node_t *root, va_list args, int create) |
xml_node_t * | xml_node_lookup (xml_node_t *root, int create,...) |
xml_node_t * | xml_node_path_lookup (xml_node_t *root, const char *path, int index, int create) |
Get a child of a node by its name. | |
char * | xml_node_fullname (xml_node_t *thenode) |
int | xml_node_get_int (int *value, xml_node_t *node,...) |
int | xml_node_int (xml_node_t *node, int def) |
Get an int or the default value from a node. | |
int | xml_node_get_str (char **str, xml_node_t *node,...) |
char * | xml_node_str (xml_node_t *node, char *def) |
Get a string or the default value from a node. | |
int | xml_node_set_int (int value, xml_node_t *node,...) |
int | xml_node_set_str (const char *str, xml_node_t *node,...) |
int | xml_node_get_vars (xml_node_t *node, const char *fmt,...) |
int | xml_node_set_vars (xml_node_t *node, const char *fmt,...) |
xml_node_t * | xml_root_element (xml_node_t *node) |
void | xml_node_append (xml_node_t *parent, xml_node_t *child) |
Attaches a node to a parent. | |
xml_attr_t * | xml_attr_new (char *name, char *value) |
Create a new attribute. | |
void | xml_attr_free (xml_attr_t *attr) |
Frees a node's attribute. | |
int | xml_node_append_attr (xml_node_t *node, xml_attr_t *attr) |
Append an attribute to a node. | |
xml_attr_t * | xml_attr_lookup (xml_node_t *node, const char *name) |
Searches for an attribute with a given name. | |
int | xml_attr_int (xml_node_t *node, const char *name, int def) |
Get an int or the default value from an attribute of a node. | |
char * | xml_attr_str (xml_node_t *node, const char *name, char *def) |
Get a string or the default value from an attribute of a node. | |
Variables | |
static const char | rcsid [] = "$Id: xml.c,v 1.27 2007-08-19 19:49:17 sven Exp $" |
static char * | last_error = NULL |
void xml_attr_free | ( | xml_attr_t * | attr | ) |
Frees a node's attribute.
This will delete an attribute and free all it's memory.
attr | The attribute to free. |
Definition at line 557 of file xml.c.
References xml_attr_t::name, and xml_attr_t::value.
Referenced by xml_node_free().
00558 { 00559 if (attr->name) free(attr->name); 00560 if (attr->value) free(attr->value); 00561 free(attr); 00562 }
int xml_attr_int | ( | xml_node_t * | node, | |
const char * | name, | |||
int | def | |||
) |
Get an int or the default value from an attribute of a node.
Will return the int value of the text of a given attribute of a node. If the node does not have an attribute of the given name or the attribute does not contain text, a default value will be returned.
node | The node to return the int from. | |
name | The name of the attribute. | |
def | The default value to return in case no text is available. |
Definition at line 616 of file xml.c.
References xml_attr_t::value, and xml_attr_lookup().
00617 { 00618 xml_attr_t *attr = xml_attr_lookup(node, name); 00619 if (attr && attr->value) return atoi(attr->value); 00620 else return(def); 00621 }
xml_attr_t* xml_attr_lookup | ( | xml_node_t * | node, | |
const char * | name | |||
) |
Searches for an attribute with a given name.
Searches all attributes of a node for a given name. If an attribute with that name is found, it's returned.
node | The node to search. | |
name | The name of the attribute to search for. |
Definition at line 592 of file xml.c.
References xml_node::attributes, xml_attr_t::name, xml_node::nattributes, and NULL.
Referenced by xml_attr_int(), and xml_attr_str().
00593 { 00594 int i; 00595 00596 for (i = 0; i < node->nattributes; i++) { 00597 if (!strcasecmp(node->attributes[i]->name, name)) return(node->attributes[i]); 00598 } 00599 return(NULL); 00600 }
xml_attr_t* xml_attr_new | ( | char * | name, | |
char * | value | |||
) |
Create a new attribute.
Creates a new attribute and fills its fields. The strings used as parameters to this function will not be dup'd but used as is. The parameters must not be NULL.
name | The name of the attribute. | |
value | The value of the attribute. An empty string is fine, NULL is not. |
Definition at line 538 of file xml.c.
References xml_attr_t::len, xml_attr_t::name, and xml_attr_t::value.
Referenced by read_attributes().
00539 { 00540 xml_attr_t *attr; 00541 00542 attr = malloc(sizeof(*attr)); 00543 attr->name = name; 00544 attr->value = value; 00545 attr->len = strlen(value); 00546 return(attr); 00547 }
char* xml_attr_str | ( | xml_node_t * | node, | |
const char * | name, | |||
char * | def | |||
) |
Get a string or the default value from an attribute of a node.
Will return the text of a given attribute of a node as a string. If the node does not have an attribute of the given name or the attribute does not contain text, a default value will be returned.
node | The node to return the string from. | |
name | The name of the attribute. | |
def | The default value to return in case no text is available. |
Definition at line 637 of file xml.c.
References xml_attr_t::value, and xml_attr_lookup().
00638 { 00639 xml_attr_t *attr = xml_attr_lookup(node, name); 00640 if (attr && attr->value) return(attr->value); 00641 else return(def); 00642 }
void xml_doc_delete | ( | xml_node_t * | root | ) |
Deletes an entire tree.
This function will delete the entire tree a node is in. The node does not have to be the root of that tree, any node of the tree will do.
root | Any node in the tree that will be deleted. Does not really have to be the root node. |
Definition at line 174 of file xml.c.
References xml_node::parent, and xml_node_delete().
Referenced by user_load().
00175 { 00176 while (root->parent) root = root->parent; 00177 xml_node_delete(root); 00178 }
const char* xml_last_error | ( | void | ) |
Definition at line 28 of file xml.c.
References last_error.
Referenced by channel_load(), config_load(), config_save(), and user_load().
00029 { 00030 return last_error; 00031 }
void xml_node_append | ( | xml_node_t * | parent, | |
xml_node_t * | child | |||
) |
Attaches a node to a parent.
Sets a node as a child of a parent node. This node must not have a parent! If it does, use xml_node_unlink() first!
parent | The node that will be the parent. | |
child | The node that will be attached to the parent. |
Definition at line 498 of file xml.c.
References xml_node::children, xml_node::last_child, xml_node::name, xml_node::nchildren, xml_node::next, xml_node::next_sibling, xml_node::parent, xml_node::prev, and xml_node::prev_sibling.
Referenced by channel_save(), save_walker(), xml_node_path_lookup(), and xml_parse_node().
00499 { 00500 xml_node_t *node; 00501 00502 child->parent = parent; 00503 parent->nchildren++; 00504 00505 if (!parent->children) { 00506 parent->children = child; 00507 } 00508 else { 00509 parent->last_child->next = child; 00510 child->prev = parent->last_child; 00511 } 00512 00513 parent->last_child = child; 00514 00515 if (!child->name) return; 00516 for (node = child->prev; node; node = node->prev) { 00517 if (node->name && !strcasecmp(node->name, child->name)) { 00518 node->next_sibling = child; 00519 child->prev_sibling = node; 00520 break; 00521 } 00522 } 00523 }
int xml_node_append_attr | ( | xml_node_t * | node, | |
xml_attr_t * | attr | |||
) |
Append an attribute to a node.
node | The node to appand the attribute to. | |
attr | The attribute to append. |
Definition at line 573 of file xml.c.
References xml_node::attributes, and xml_node::nattributes.
Referenced by read_attributes().
00574 { 00575 node->attributes = realloc(node->attributes, sizeof(*node->attributes) * (node->nattributes+1)); 00576 node->attributes[node->nattributes++] = attr; 00577 return(0); 00578 }
void xml_node_delete | ( | xml_node_t * | node | ) |
Deletes a node.
This function is a wrapper for xml_node_delete_callbacked() without a callback.
node | The node to delete. |
Definition at line 131 of file xml.c.
References NULL, and xml_node_delete_callbacked().
Referenced by botnet_really_delete(), channel_free(), channel_load(), channel_save(), got_newbot(), got_nlinked(), got_version(), help_parse_file(), party_help(), user_really_delete(), user_save(), and xml_doc_delete().
00132 { 00133 xml_node_delete_callbacked(node, NULL); 00134 }
void xml_node_delete_callbacked | ( | xml_node_t * | node, | |
void(*)(void *) | callback | |||
) |
Deletes a node and executes a callback function.
This function deletes a node and all of its children and attributes. For every deleted node the callback function is executed.
node | The node to delete. | |
callback | The callback function to execute. May be NULL. |
Definition at line 146 of file xml.c.
References xml_node::children, xml_node::client_data, xml_node::next, NULL, xml_node::parent, xml_node_delete_callbacked(), xml_node_free(), and xml_node_unlink().
Referenced by config_delete_root(), config_destroy(), config_unlink_table(), xml_node_delete(), and xml_node_delete_callbacked().
00147 { 00148 xml_node_t *child, *child_next; 00149 00150 if (node->client_data && callback) callback(node->client_data); 00151 00152 xml_node_unlink(node); 00153 00154 /* Delete children. */ 00155 for (child = node->children; child; child = child_next) { 00156 child_next = child->next; 00157 child->parent = NULL; 00158 xml_node_delete_callbacked(child, callback); 00159 } 00160 00161 /* Free memory taken by node. */ 00162 xml_node_free(node); 00163 }
void xml_node_free | ( | xml_node_t * | node | ) |
Free all memory associated with a node.
node | The node to be free'd. |
Definition at line 74 of file xml.c.
References xml_node::attributes, xml_node::name, xml_node::nattributes, xml_node::text, and xml_attr_free().
Referenced by xml_node_delete_callbacked(), and xml_parse_node().
00075 { 00076 xml_attr_t *attr; 00077 int i; 00078 00079 if (node->name) free(node->name); 00080 if (node->text) free(node->text); 00081 for (i = 0; i < node->nattributes; i++) { 00082 attr = node->attributes[i]; 00083 xml_attr_free(attr); 00084 } 00085 if (node->attributes) free(node->attributes); 00086 free(node); 00087 }
char* xml_node_fullname | ( | xml_node_t * | thenode | ) |
Definition at line 291 of file xml.c.
References xml_node::name, and xml_node::parent.
Referenced by channel_set(), config_set_int(), and config_set_str().
00292 { 00293 xml_node_t *node; 00294 char *name, *name2; 00295 int len, total_len; 00296 00297 len = total_len = 0; 00298 name = calloc(1, 1); 00299 for (node = thenode; node; node = node->parent) { 00300 if (!node->name) continue; 00301 00302 /* Length of name plus the dot. */ 00303 len = strlen(node->name) + 1; 00304 00305 /* Name plus the null. */ 00306 name2 = malloc(len + total_len + 1); 00307 00308 /* Create new name. */ 00309 sprintf(name2, "%s.%s", node->name, name); 00310 free(name); 00311 name = name2; 00312 total_len += len; 00313 } 00314 if (total_len > 0) name[total_len-1] = 0; 00315 return(name); 00316 }
int xml_node_get_int | ( | int * | value, | |
xml_node_t * | node, | |||
... | ||||
) |
Definition at line 318 of file xml.c.
References NULL, xml_node::text, and xml_node_vlookup().
Referenced by channel_get_int(), config_get_int(), and xml_node_get_vars().
00319 { 00320 va_list args; 00321 00322 va_start(args, node); 00323 node = xml_node_vlookup(node, args, 0); 00324 va_end(args); 00325 if (node && node->text) { 00326 *value = strtol(node->text, NULL, 0); 00327 return(0); 00328 } 00329 *value = 0; 00330 return(-1); 00331 }
int xml_node_get_str | ( | char ** | str, | |
xml_node_t * | node, | |||
... | ||||
) |
Definition at line 357 of file xml.c.
References NULL, xml_node::text, and xml_node_vlookup().
Referenced by botnet_get_info(), channel_get(), channel_set(), config_get_str(), help_lookup_entry(), user_get_setting(), and xml_node_get_vars().
00358 { 00359 va_list args; 00360 00361 va_start(args, node); 00362 node = xml_node_vlookup(node, args, 0); 00363 va_end(args); 00364 if (node) { 00365 *str = node->text; 00366 return(0); 00367 } 00368 *str = NULL; 00369 return(-1); 00370 }
int xml_node_get_vars | ( | xml_node_t * | node, | |
const char * | fmt, | |||
... | ||||
) |
Definition at line 420 of file xml.c.
References xml_node_get_int(), xml_node_get_str(), and xml_node_path_lookup().
Referenced by channel_load(), help_parse_file(), help_parse_syntax(), help_summarize_entry(), party_help(), and user_load().
00421 { 00422 va_list args; 00423 char *name, **strptr; 00424 int *intptr; 00425 xml_node_t **nodeptr; 00426 00427 va_start(args, fmt); 00428 while (*fmt) { 00429 name = va_arg(args, char *); 00430 switch (*fmt) { 00431 case 's': 00432 strptr = va_arg(args, char **); 00433 xml_node_get_str(strptr, node, name, 0, 0); 00434 break; 00435 case 'i': 00436 intptr = va_arg(args, int *); 00437 xml_node_get_int(intptr, node, name, 0, 0); 00438 break; 00439 case 'n': 00440 nodeptr = va_arg(args, xml_node_t **); 00441 *nodeptr = xml_node_path_lookup(node, name, 0, 0); 00442 break; 00443 } 00444 fmt++; 00445 } 00446 va_end(args); 00447 return(0); 00448 }
int xml_node_int | ( | xml_node_t * | node, | |
int | def | |||
) |
Get an int or the default value from a node.
Will convert the text of a given node to an int and return the value. If no node was given or the node does not contain text, a default value will be returned.
node | The node to extract the int from. | |
def | The default value to return in case the node does not contain text. |
Definition at line 346 of file xml.c.
References xml_node::text.
00347 { 00348 int value; 00349 char *ptr; 00350 00351 if (!node || !node->text) return(def); 00352 value = strtol(node->text, &ptr, 0); 00353 if (!ptr || *ptr) return(def); 00354 else return(value); 00355 }
xml_node_t* xml_node_lookup | ( | xml_node_t * | root, | |
int | create, | |||
... | ||||
) |
Definition at line 194 of file xml.c.
References xml_node_vlookup().
Referenced by channel_load(), config_link_table(), config_unlink_table(), config_update_table(), find_setting(), help_lookup_entry(), and user_load().
00195 { 00196 va_list args; 00197 xml_node_t *node; 00198 00199 va_start(args, create); 00200 node = xml_node_vlookup(root, args, create); 00201 va_end(args); 00202 return(node); 00203 }
xml_node_t* xml_node_new | ( | void | ) |
Get a new, blank node.
Definition at line 44 of file xml.c.
Referenced by append_setting(), botnet_new(), channel_probe(), channel_save(), got_newbot(), got_nlinked(), got_version(), recving_login(), save_walker(), sending_login(), user_new(), user_save(), xml_node_new_named(), xml_node_path_lookup(), xml_parse_file(), and xml_parse_node().
00045 { 00046 xml_node_t *node; 00047 00048 node = calloc(sizeof(*node), 1); 00049 00050 return node; 00051 }
xml_node_t* xml_node_new_named | ( | const char * | name | ) |
Get a new, named node.
name | The name of the node. |
Definition at line 61 of file xml.c.
References xml_node::name, and xml_node_new().
00062 { 00063 xml_node_t *node = xml_node_new(); 00064 node->name = strdup(name); 00065 return(node); 00066 }
xml_node_t* xml_node_path_lookup | ( | xml_node_t * | root, | |
const char * | path, | |||
int | index, | |||
int | create | |||
) |
Get a child of a node by its name.
This function searches a tree beginning with a given node and its children for a child by a given name.
This name can be very complex with serveral layers of the tree seperated by '.' and an index with "[x]. Example: "layer1.layer2[3].layer3".
root | The node to start searching from. | |
path | The name or path of the child to search for. | |
index | Added to the index of every layer. Best used for a simple query without multiple layers. | |
create | If this is non-zero and the node was not found it will be created. |
Definition at line 222 of file xml.c.
References xml_node::children, xml_node::name, xml_node::next, xml_node::next_sibling, NULL, xml_node::type, XML_ELEMENT, xml_node_append(), and xml_node_new().
Referenced by xml_node_get_vars(), and xml_node_vlookup().
00223 { 00224 int thisindex, len; 00225 xml_node_t *child; 00226 const char *next; 00227 char *name, *sep, buf[512]; 00228 00229 for (; root && path; path = next) { 00230 /* Get the next path element. */ 00231 sep = strchr(path, '.'); 00232 if (sep) { 00233 next = sep+1; 00234 len = sep - path; 00235 } 00236 else { 00237 next = NULL; 00238 len = strlen(path); 00239 } 00240 00241 /* If it's empty, skip it, otherwise copy it. */ 00242 if (!len) continue; 00243 else if (len > sizeof(buf) - 10) { 00244 name = malloc(len+1); 00245 } 00246 else { 00247 name = buf; 00248 } 00249 memcpy(name, path, len); 00250 name[len] = 0; 00251 00252 /* Ok, now see if there's an [index] at the end. The length 00253 * has to be at least 4, because it's like "a[x]" at least. */ 00254 thisindex = 0; 00255 if (len > 3 && name[len-1] == ']') { 00256 sep = strrchr(name, '['); 00257 if (sep) { 00258 *sep = 0; 00259 name[len-1] = 0; 00260 thisindex = atoi(sep+1); 00261 } 00262 } 00263 00264 /* If it's the last path element, add the index param. */ 00265 if (!next) thisindex += index; 00266 00267 for (child = root->children; child; child = child->next) { 00268 if (child->name && !strcasecmp(child->name, name)) break; 00269 } 00270 00271 while (child && thisindex > 0) { 00272 thisindex--; 00273 child = child->next_sibling; 00274 } 00275 00276 if (!child && create) { 00277 do { 00278 child = xml_node_new(); 00279 child->type = XML_ELEMENT; 00280 child->name = strdup(name); 00281 xml_node_append(root, child); 00282 } while (thisindex-- > 0); 00283 } 00284 if (name != buf) free(name); 00285 00286 root = child; 00287 } 00288 return(root); 00289 }
int xml_node_set_int | ( | int | value, | |
xml_node_t * | node, | |||
... | ||||
) |
Definition at line 390 of file xml.c.
References str_redup(), xml_node::text, and xml_node_vlookup().
Referenced by botnet_set_info_int(), channel_save(), config_set_int(), got_newbot(), got_nlinked(), got_version(), recving_login(), save_walker(), sending_login(), user_save(), and xml_node_set_vars().
00391 { 00392 char buf[32]; 00393 va_list args; 00394 00395 va_start(args, node); 00396 node = xml_node_vlookup(node, args, 1); 00397 va_end(args); 00398 if (!node) return(-1); 00399 00400 snprintf(buf, sizeof(buf), "%d", value); 00401 str_redup(&node->text, buf); 00402 00403 return(0); 00404 }
int xml_node_set_str | ( | const char * | str, | |
xml_node_t * | node, | |||
... | ||||
) |
Definition at line 406 of file xml.c.
References str_redup(), xml_node::text, and xml_node_vlookup().
Referenced by botnet_set_info(), channel_save(), channel_set(), config_set_str(), got_newbot(), got_nlinked(), got_version(), recving_login(), save_walker(), sending_login(), user_set_setting(), and xml_node_set_vars().
00407 { 00408 va_list args; 00409 00410 va_start(args, node); 00411 node = xml_node_vlookup(node, args, 1); 00412 va_end(args); 00413 if (!node) return(-1); 00414 00415 str_redup(&node->text, str); 00416 00417 return(0); 00418 }
int xml_node_set_vars | ( | xml_node_t * | node, | |
const char * | fmt, | |||
... | ||||
) |
Definition at line 450 of file xml.c.
References xml_node_set_int(), and xml_node_set_str().
00451 { 00452 va_list args; 00453 char *name, *strval; 00454 int intval; 00455 00456 va_start(args, fmt); 00457 while (*fmt) { 00458 name = va_arg(args, char *); 00459 switch (*fmt) { 00460 case 's': 00461 strval = va_arg(args, char *); 00462 xml_node_set_str(strval, node, name, 0, 0); 00463 break; 00464 case 'i': 00465 intval = va_arg(args, int); 00466 xml_node_set_int(intval, node, name, 0, 0); 00467 break; 00468 } 00469 fmt++; 00470 } 00471 va_end(args); 00472 return(0); 00473 }
char* xml_node_str | ( | xml_node_t * | node, | |
char * | def | |||
) |
Get a string or the default value from a node.
Will return the text of a given node as a string. If no node was given or the node does not contain text, a default value will be returned.
node | The node to return the string from. | |
def | The default value to return in case the node does not contain text. |
Definition at line 384 of file xml.c.
References xml_node::text.
Referenced by party_help(), and user_load().
void xml_node_unlink | ( | xml_node_t * | node | ) |
Unlinks a XML node from a tree.
Removes a node from a tree. Unlinks the node from its parent and siblings, but all nodes descending from this one will still be attached.
node | The node to unlink. |
Definition at line 98 of file xml.c.
References xml_node::children, xml_node::last_child, xml_node::nchildren, xml_node::next, xml_node::next_sibling, NULL, xml_node::parent, xml_node::prev, and xml_node::prev_sibling.
Referenced by append_setting(), channel_load(), channel_save(), help_lookup_entry(), unlink_walker(), and xml_node_delete_callbacked().
00099 { 00100 xml_node_t *parent = node->parent; 00101 00102 /* Unlink from parent. */ 00103 if (parent) { 00104 parent->nchildren--; 00105 if (parent->children == node) parent->children = node->next; 00106 if (parent->last_child == node) parent->last_child = node->prev; 00107 00108 node->parent = NULL; 00109 } 00110 00111 /* Unlink from node list. */ 00112 if (node->prev) node->prev->next = node->next; 00113 if (node->next) node->next->prev = node->prev; 00114 00115 /* Unlink from sibling list. */ 00116 if (node->prev_sibling) node->prev_sibling->next_sibling = node->next_sibling; 00117 if (node->next_sibling) node->next_sibling->prev_sibling = node->prev_sibling; 00118 }
xml_node_t* xml_node_vlookup | ( | xml_node_t * | root, | |
va_list | args, | |||
int | create | |||
) |
Definition at line 180 of file xml.c.
References xml_node_path_lookup().
Referenced by channel_get(), channel_get_int(), channel_get_node(), channel_set(), config_exists(), config_get_int(), config_get_str(), config_link_table(), config_lookup_section(), config_set_int(), config_set_str(), config_unlink_table(), config_update_table(), xml_node_get_int(), xml_node_get_str(), xml_node_lookup(), xml_node_set_int(), and xml_node_set_str().
00181 { 00182 char *path; 00183 int index; 00184 00185 for (; root;) { 00186 path = va_arg(args, char *); 00187 if (!path) break; 00188 index = va_arg(args, int); 00189 root = xml_node_path_lookup(root, path, index, create); 00190 } 00191 return(root); 00192 }
xml_node_t* xml_root_element | ( | xml_node_t * | node | ) |
Definition at line 475 of file xml.c.
References xml_node::children, xml_node::next, NULL, xml_node::parent, xml_node::type, and XML_ELEMENT.
Referenced by xml_parse_file().
00476 { 00477 if (node == NULL) return NULL; 00478 00479 /* Zoom up to the document. */ 00480 while (node && node->parent) node = node->parent; 00481 00482 /* Find first element. */ 00483 node = node->children; 00484 while (node && node->type != XML_ELEMENT) node = node->next; 00485 return node; 00486 }
void xml_set_error | ( | const char * | err | ) |
Definition at line 33 of file xml.c.
References last_error, and str_redup().
Referenced by xml_parse_file(), xml_parse_node(), xml_save_file(), and xml_write_node().
00034 { 00035 str_redup(&last_error, err); 00036 }
char* last_error = NULL [static] |
const char rcsid[] = "$Id: xml.c,v 1.27 2007-08-19 19:49:17 sven Exp $" [static] |