Commit 9fbadfad authored by Matt Colyer's avatar Matt Colyer

Cleaned up plist.c, added doxygen docs.

parent bb74e8fd
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <libxml/parser.h> #include <libxml/parser.h>
#include <libxml/tree.h> #include <libxml/tree.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include "plist.h" #include "plist.h"
const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
...@@ -29,15 +30,29 @@ const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ ...@@ -29,15 +30,29 @@ const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<plist version=\"1.0\">\n\ <plist version=\"1.0\">\n\
</plist>\0"; </plist>\0";
/** Formats a block of text to be a given indentation and width.
*
* The total width of the return string will be depth + cols.
*
* @param buf The string to format.
* @param cols The number of text columns for returned block of text.
* @param depth The number of tabs to indent the returned block of text.
*
* @return The formatted string.
*/
char* format_string(const char* buf, int cols, int depth) char* format_string(const char* buf, int cols, int depth)
{ {
int colw = depth + cols + 1; //new buf cols width int colw = depth + cols + 1;
int len = strlen(buf); int len = strlen(buf);
//int nlines = ceil((float)len / (float)cols);
int nlines = len / cols + 1; int nlines = len / cols + 1;
char* new_buf = (char*)malloc(nlines * colw + depth + 1); char* new_buf = (char*)malloc(nlines * colw + depth + 1);
int i = 0; int i = 0;
int j = 0; int j = 0;
assert(cols > 0);
assert(depth > 0);
// Inserts new lines and tabs at appropriate locations
for (i = 0; i < nlines; i++){ for (i = 0; i < nlines; i++){
new_buf[i * colw] = '\n'; new_buf[i * colw] = '\n';
for (j = 0; j < depth; j++) for (j = 0; j < depth; j++)
...@@ -45,62 +60,137 @@ char* format_string(const char* buf, int cols, int depth) ...@@ -45,62 +60,137 @@ char* format_string(const char* buf, int cols, int depth)
memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, cols); memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, cols);
} }
new_buf[len+(1+depth)*nlines] = '\n'; new_buf[len+(1+depth)*nlines] = '\n';
// Inserts final row of indentation and termination character
for (j = 0; j < depth; j++) for (j = 0; j < depth; j++)
new_buf[len+(1+depth)*nlines + 1 + j] = '\t'; new_buf[len+(1+depth)*nlines + 1 + j] = '\t';
new_buf[len+(1+depth)*nlines+depth+1] = '\0'; new_buf[len+(1+depth)*nlines+depth+1] = '\0';
return new_buf; return new_buf;
} }
/** Creates a new plist XML document.
*
* @return The plist XML document.
*/
xmlDocPtr new_plist() { xmlDocPtr new_plist() {
char *plist = strdup(plist_base); char *plist = strdup(plist_base);
xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0); xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0);
if (!plist_xml) return NULL; if (!plist_xml) return NULL;
free(plist); free(plist);
return plist_xml; return plist_xml;
} }
/** Destroys a previously created XML document.
*
* @param plist The XML document to destroy.
*/
void free_plist(xmlDocPtr plist) { void free_plist(xmlDocPtr plist) {
if (!plist) return; if (!plist) return;
xmlFreeDoc(plist); xmlFreeDoc(plist);
} }
/** Adds a new node as a child to a given node.
*
* This is a lower level function so you probably want to use
* add_key_str_dict_element, add_key_dict_node or add_key_data_dict_element
* instead.
*
* @param plist The plist XML document to which the to_node belongs.
* @param name The name of the new node.
* @param content The string containing the text node of the new node.
* @param to_node The node to attach the child node to. If none is given, the
* root node of the given document is used.
* @param depth The number of tabs to indent the new node.
*
* @return The newly created node.
*/
xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth) { xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth) {
if (!plist) return NULL;
int i = 0; int i = 0;
xmlNode *child; xmlNode *child;
if (!plist) return NULL;
assert(depth > 0);
if (!to_node) to_node = xmlDocGetRootElement(plist); if (!to_node) to_node = xmlDocGetRootElement(plist);
for (i = 0; i < depth; i++) { for (i = 0; i < depth; i++) {
xmlNodeAddContent(to_node, "\t"); xmlNodeAddContent(to_node, "\t");
} }
child = xmlNewChild(to_node, NULL, name, content); child = xmlNewChild(to_node, NULL, name, content);
xmlNodeAddContent(to_node, "\n"); xmlNodeAddContent(to_node, "\n");
return child; return child;
} }
/** Adds a string key-pair to a plist XML document.
*
* @param plist The plist XML document to add the new node to.
* @param dict The dictionary node within the plist XML document to add the new node to.
* @param key The string containing the key value.
* @param value The string containing the value.
* @param depth The number of tabs to indent the new node.
*
* @return The newly created key node.
*/
xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
xmlNode *keyPtr; xmlNode *keyPtr;
keyPtr = add_child_to_plist(plist, "key", key, dict, depth); keyPtr = add_child_to_plist(plist, "key", key, dict, depth);
add_child_to_plist(plist, "string", value, dict, depth); add_child_to_plist(plist, "string", value, dict, depth);
return keyPtr; return keyPtr;
} }
/** Adds a new dictionary key-pair to a plist XML document.
*
* @param plist The plist XML document to add the new node to.
* @param dict The dictionary node within the plist XML document to add the new node to.
* @param key The string containing the key value.
* @param value The string containing the value.
* @param depth The number of tabs to indent the new node.
*
* @return The newly created dict node.
*/
xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
xmlNode *child; xmlNode *child;
add_child_to_plist(plist, "key", key, dict, depth); add_child_to_plist(plist, "key", key, dict, depth);
child = add_child_to_plist(plist, "dict", value, dict, depth); child = add_child_to_plist(plist, "dict", value, dict, depth);
return child; return child;
} }
/** Adds a new data dictionary key-pair to a plist XML document.
*
* @param plist The plist XML document to add the new node to.
* @param dict The dictionary node within the plist XML document to add the new node to.
* @param key The string containing the key value.
* @param value The string containing the value.
* @param depth The number of tabs to indent the new node.
*
* @return The newly created key node.
*/
xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
xmlNode *keyPtr; xmlNode *keyPtr;
keyPtr = add_child_to_plist(plist, "key", key, dict, depth); keyPtr = add_child_to_plist(plist, "key", key, dict, depth);
add_child_to_plist(plist, "data", format_string(value, 60, depth), dict, depth); add_child_to_plist(plist, "data", format_string(value, 60, depth), dict, depth);
return keyPtr; return keyPtr;
} }
/** Reads a set of keys and strings into an array from a plist XML document.
*
* @param dict The root XMLNode of a plist XML document to be read.
*
* @return An array where each even number is a key and the odd numbers are
* values. If the odd number is \0, that's the end of the list.
*/
char **read_dict_element_strings(xmlNode *dict) { char **read_dict_element_strings(xmlNode *dict) {
// reads a set of keys and strings into an array where each even number is a key and odd numbers are values.
// if the odd number is \0, that's the end of the list.
char **return_me = NULL, **old = NULL; char **return_me = NULL, **old = NULL;
int current_length = 0; int current_length = 0;
int current_pos = 0; int current_pos = 0;
...@@ -120,7 +210,6 @@ char **read_dict_element_strings(xmlNode *dict) { ...@@ -120,7 +210,6 @@ char **read_dict_element_strings(xmlNode *dict) {
} }
} }
// one last thing...
old = return_me; old = return_me;
return_me = realloc(return_me, sizeof(char*) * (current_length+1)); return_me = realloc(return_me, sizeof(char*) * (current_length+1));
return_me[current_pos] = strdup(""); return_me[current_pos] = strdup("");
...@@ -128,10 +217,13 @@ char **read_dict_element_strings(xmlNode *dict) { ...@@ -128,10 +217,13 @@ char **read_dict_element_strings(xmlNode *dict) {
return return_me; return return_me;
} }
/** Destroys a dictionary as returned by read_dict_element_strings
*/
void free_dictionary(char **dictionary) { void free_dictionary(char **dictionary) {
if (!dictionary) return;
int i = 0; int i = 0;
if (!dictionary) return;
for (i = 0; strcmp(dictionary[i], ""); i++) { for (i = 0; strcmp(dictionary[i], ""); i++) {
free(dictionary[i]); free(dictionary[i]);
} }
......
...@@ -29,9 +29,10 @@ xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, cons ...@@ -29,9 +29,10 @@ xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, cons
xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth); xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth);
xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth); xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth);
xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth); xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth);
void free_plist(xmlDocPtr plist); void free_plist(xmlDocPtr plist);
xmlDocPtr new_plist(); xmlDocPtr new_plist();
char **read_dict_element_strings(xmlNode *dict); char **read_dict_element_strings(xmlNode *dict);
void free_dictionary(char **dictionary); void free_dictionary(char **dictionary);
char **read_dict_element_strings(xmlNode *dict);
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment