1 /* 2 * Copyright (c) 2009, 2010 Aggelos Economopoulos. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 3. Neither the name of The DragonFly Project nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific, prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <stdlib.h> 33 #include <stdio.h> 34 #include <string.h> 35 36 #include "xml.h" 37 #include "trivial.h" 38 39 xml_document_t 40 xml_document_create(const char *file) 41 { 42 xml_document_t doc; 43 44 if ((doc = malloc(sizeof(struct xml_document))) == NULL) 45 return (NULL); 46 47 if ((doc->file = fopen(file, "w")) == NULL) { 48 free(doc); 49 return (NULL); 50 } 51 STAILQ_INIT(&doc->open_elems); 52 doc->nr_open = 0; 53 doc->errmsg = NULL; 54 55 fprintf(doc->file, "<?xml version=\"1.0\" encoding=\"UTF-8\" " 56 "standalone=\"no\"?>\n"); 57 fprintf(doc->file, "<!-- Created by evtranalyze -->\n"); 58 59 return doc; 60 } 61 62 int 63 xml_document_close(xml_document_t doc) 64 { 65 fclose(doc->file); 66 return 0; 67 } 68 69 70 static 71 void 72 indent(xml_document_t doc) 73 { 74 int i; 75 76 for (i = 0; i < doc->nr_open; ++i) { 77 fprintf(doc->file, " "); 78 } 79 } 80 81 #if 0 82 int 83 xml_elem_compile(xml_element_t el) 84 { 85 char *buf, *p; 86 int bufsize, c, ret; 87 88 bufsize = 2; 89 if (!(buf = malloc(bufsize))) { 90 return !0; 91 } 92 again_name: 93 p = buf; 94 ret = snprintf(p, sizeof(buf), "<%s ", el->name); 95 if (ret > sizeof(buf)) { 96 bufsize *= 2; 97 buf = realloc(bufsize); 98 if (!buf) { 99 free(p); 100 return !0; 101 } 102 goto again_name; 103 } 104 c += ret; 105 } 106 #endif 107 108 static 109 int 110 xml_elem_print(xml_document_t doc, xml_element_t el, int closed, int nl) 111 { 112 xml_attribute_t at; 113 fprintf(doc->file, "<%s", el->name); 114 STAILQ_FOREACH(at, &el->attributes, next) { 115 fprintf(doc->file, " %s=\"%s\"", at->name, at->value); 116 } 117 fprintf(doc->file, "%s%s", closed ? "/>" : ">", nl ? "\n" : ""); 118 return 0; 119 } 120 121 static 122 int 123 _xml_elem_begin(xml_document_t doc, xml_element_t el, int closed, int nl) 124 { 125 STAILQ_INSERT_HEAD(&doc->open_elems, el, link); 126 indent(doc); 127 ++doc->nr_open; 128 xml_elem_print(doc, el, closed, nl); 129 return 0; 130 } 131 132 static 133 int 134 _xml_elem_close(xml_document_t doc, xml_element_t el, int do_indent) 135 { 136 if (el != STAILQ_FIRST(&doc->open_elems)) { 137 return !0; 138 } 139 140 STAILQ_REMOVE_HEAD(&doc->open_elems, link); 141 --doc->nr_open; 142 if (do_indent) 143 indent(doc); 144 fprintf(doc->file, "</%s>\n", el->name); 145 return 0; 146 } 147 148 int 149 xml_elem_close(xml_document_t doc, xml_element_t el) 150 { 151 return _xml_elem_close(doc, el, !0); 152 } 153 154 int 155 xml_elem_begin(xml_document_t doc, xml_element_t el) 156 { 157 if (el->value) { 158 return !0; 159 } 160 return _xml_elem_begin(doc, el, 0, !0); 161 } 162 163 int 164 xml_elem_closed(xml_document_t doc, xml_element_t el) 165 { 166 if (el->value) { 167 _xml_elem_begin(doc, el, 0, 0); 168 fprintf(doc->file, "%s", el->value); 169 _xml_elem_close(doc, el, 0); 170 return 0; 171 } 172 indent(doc); 173 return xml_elem_print(doc, el, !0, !0); 174 } 175 176