diff options
Diffstat (limited to 'src/main/array.c')
-rw-r--r-- | src/main/array.c | 228 |
1 files changed, 225 insertions, 3 deletions
diff --git a/src/main/array.c b/src/main/array.c index c6545bd..a1ef327 100644 --- a/src/main/array.c +++ b/src/main/array.c @@ -17,8 +17,7 @@ * for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program. If not, see <https://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H @@ -31,6 +30,10 @@ #include <string.h> #include <stdlib.h> #include <limits.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <strings.h> struct stp_array @@ -169,6 +172,81 @@ stp_array_get_sequence(const stp_array_t *array) return array->data; } +static stp_array_t * +xml_doc_get_array(stp_mxml_node_t *doc) +{ + stp_mxml_node_t *cur; + stp_mxml_node_t *xmlarray; + stp_array_t *array = NULL; + + if (doc == NULL ) + { + stp_deprintf(STP_DBG_ARRAY_ERRORS, + "xml_doc_get_array: XML file not parsed successfully.\n"); + return NULL; + } + + cur = doc->child; + + if (cur == NULL) + { + stp_deprintf(STP_DBG_ARRAY_ERRORS, + "xml_doc_get_array: empty document\n"); + return NULL; + } + + xmlarray = stp_xml_get_node(cur, "gutenprint", "array", NULL); + + if (xmlarray) + array = stp_array_create_from_xmltree(xmlarray); + + return array; +} + +stp_array_t * +stp_array_create_from_file(const char* file) +{ + stp_array_t *array = NULL; + stp_mxml_node_t *doc; + FILE *fp = NULL; + if (file[0] != '/' && strncmp(file, "./", 2) && strncmp(file, "../", 3)) + { + char *fn = stp_path_find_file(NULL, file); + if (fn) + { + fp = fopen(file, "r"); + free(fn); + } + } + else if (file) + { + fp = fopen(file, "r"); + } + if (!fp) + { + stp_deprintf(STP_DBG_ARRAY_ERRORS, + "stp_array_create_from_file: unable to open %s: %s\n", + file, strerror(errno)); + return NULL; + } + stp_deprintf(STP_DBG_XML, "stp_array_create_from_file: reading `%s'...\n", + file); + + stp_xml_init(); + + doc = stp_mxmlLoadFile(NULL, fp, STP_MXML_NO_CALLBACK); + + array = xml_doc_get_array(doc); + + if (doc) + stp_mxmlDelete(doc); + + stp_xml_exit(); + (void) fclose(fp); + return array; + +} + stp_array_t * stp_array_create_from_xmltree(stp_mxml_node_t *array) /* The array node */ { @@ -179,6 +257,9 @@ stp_array_create_from_xmltree(stp_mxml_node_t *array) /* The array node */ stp_sequence_t *seq = NULL; stp_array_t *ret = NULL; + /* FIXME Need protection against unlimited recursion */ + if ((stmp = stp_mxmlElementGetAttr(array, "src")) != NULL) + return stp_array_create_from_file(stmp); stmp = stp_mxmlElementGetAttr(array, "x-size"); if (stmp) { @@ -203,7 +284,7 @@ stp_array_create_from_xmltree(stp_mxml_node_t *array) /* The array node */ /* Get the sequence data */ - child = stp_mxmlFindElement(array, array, "sequence", NULL, NULL, STP_MXML_DESCEND); + child = stp_xml_get_node(array, "sequence", NULL); if (child) seq = stp_sequence_create_from_xmltree(child); @@ -269,3 +350,144 @@ stp_xmltree_create_from_array(const stp_array_t *array) /* The array */ return arraynode; } + +static stp_mxml_node_t * +xmldoc_create_from_array(const stp_array_t *array) +{ + stp_mxml_node_t *xmldoc; + stp_mxml_node_t *rootnode; + stp_mxml_node_t *arraynode; + + /* Get array details */ + arraynode = stp_xmltree_create_from_array(array); + if (arraynode == NULL) + { + stp_deprintf(STP_DBG_ARRAY_ERRORS, + "xmldoc_create_from_array: error creating array node\n"); + return NULL; + } + /* Create the XML tree */ + xmldoc = stp_xmldoc_create_generic(); + if (xmldoc == NULL) + { + stp_deprintf(STP_DBG_ARRAY_ERRORS, + "xmldoc_create_from_array: error creating XML document\n"); + return NULL; + } + rootnode = xmldoc->child; + if (rootnode == NULL) + { + stp_mxmlDelete(xmldoc); + stp_deprintf(STP_DBG_ARRAY_ERRORS, + "xmldoc_create_from_array: error getting XML document root node\n"); + return NULL; + } + + stp_mxmlAdd(rootnode, STP_MXML_ADD_AFTER, NULL, arraynode); + + return xmldoc; +} + +static int +array_whitespace_callback(stp_mxml_node_t *node, int where) +{ + if (node->type != STP_MXML_ELEMENT) + return 0; + if (strcasecmp(node->value.element.name, "gutenprint") == 0) + { + switch (where) + { + case STP_MXML_WS_AFTER_OPEN: + case STP_MXML_WS_BEFORE_CLOSE: + case STP_MXML_WS_AFTER_CLOSE: + return '\n'; + case STP_MXML_WS_BEFORE_OPEN: + default: + return 0; + } + } + else if (strcasecmp(node->value.element.name, "array") == 0) + { + switch (where) + { + case STP_MXML_WS_AFTER_OPEN: + return '\n'; + case STP_MXML_WS_BEFORE_CLOSE: + case STP_MXML_WS_AFTER_CLOSE: + case STP_MXML_WS_BEFORE_OPEN: + default: + return 0; + } + } + else if (strcasecmp(node->value.element.name, "sequence") == 0) + { + const char *count; + switch (where) + { + case STP_MXML_WS_BEFORE_CLOSE: + count = stp_mxmlElementGetAttr(node, "count"); + if (strcmp(count, "0") == 0) + return 0; + else + return '\n'; + case STP_MXML_WS_AFTER_OPEN: + case STP_MXML_WS_AFTER_CLOSE: + return '\n'; + case STP_MXML_WS_BEFORE_OPEN: + default: + return 0; + } + } + else + return 0; +} + + +int +stp_array_write(FILE *file, const stp_array_t *array) /* The array */ +{ + stp_mxml_node_t *xmldoc = NULL; + + stp_xml_init(); + + xmldoc = xmldoc_create_from_array(array); + if (xmldoc == NULL) + { + stp_xml_exit(); + return 1; + } + + stp_mxmlSaveFile(xmldoc, file, array_whitespace_callback); + + if (xmldoc) + stp_mxmlDelete(xmldoc); + + stp_xml_exit(); + + return 0; +} + +char * +stp_array_write_string(const stp_array_t *array) /* The array */ +{ + stp_mxml_node_t *xmldoc = NULL; + char *retval; + + stp_xml_init(); + + xmldoc = xmldoc_create_from_array(array); + if (xmldoc == NULL) + { + stp_xml_exit(); + return NULL; + } + + retval = stp_mxmlSaveAllocString(xmldoc, array_whitespace_callback); + + if (xmldoc) + stp_mxmlDelete(xmldoc); + + stp_xml_exit(); + + return retval; +} |