1/** 2 * @file op_xml_out.c 3 * C utility routines for writing XML 4 * 5 * @remark Copyright 2008 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author Dave Nomura 9 */ 10 11#include <stdio.h> 12#include <string.h> 13#include <stdlib.h> 14#include "op_xml_out.h" 15 16char const * xml_tag_map[] = { 17 "NONE", 18 "id", 19 "profile", 20 "processor", 21 "cputype", 22 "title", 23 "schemaversion", 24 "mhz", 25 "setup", 26 "timersetup", 27 "rtcinterrupts", 28 "eventsetup", 29 "eventname", 30 "unitmask", 31 "setupcount", 32 "separatedcpus", 33 "options", 34 "session", "debuginfo", "details", "excludedependent", 35 "excludesymbols", "imagepath", "includesymbols", "merge", 36 "classes", 37 "class", 38 "cpu", 39 "event", 40 "mask", 41 "process", 42 "pid", 43 "thread", 44 "tid", 45 "binary", 46 "module", 47 "name", 48 "callers", 49 "callees", 50 "symbol", 51 "idref", 52 "self", 53 "detaillo", 54 "detailhi", 55 "symboltable", 56 "symboldata", 57 "startingaddr", 58 "file", 59 "line", 60 "codelength", 61 "summarydata", 62 "sampledata", 63 "count", 64 "detailtable", 65 "symboldetails", 66 "detaildata", 67 "vmaoffset", 68 "bytestable", 69 "bytes", 70 "help_events", 71 "header", 72 "title", 73 "doc", 74 "event", 75 "event_name", 76 "group", 77 "desc", 78 "counter_mask", 79 "min_count", 80 "ext", 81 "unit_masks", 82 "default", 83 "category", 84 "unit_mask", 85 "mask", 86 "desc" 87}; 88 89#define MAX_BUF_LEN 2048 90char const * xml_tag_name(tag_t tag) 91{ 92 return xml_tag_map[tag]; 93} 94 95 96void open_xml_element(tag_t tag, int with_attrs, char *buffer, size_t max) 97{ 98 char *buf; 99 int size, ret; 100 101 buffer[max - 1] = '\0'; 102 size = strlen(buffer); 103 buf = &buffer[size]; 104 size = max - 1 - size; 105 106 ret = snprintf(buf, size, "<%s%s", xml_tag_name(tag), 107 (with_attrs ? " " : ">\n")); 108 109 if (ret < 0 || ret >= size) { 110 fprintf(stderr,"open_xml_element: snprintf failed\n"); 111 exit(EXIT_FAILURE); 112 } 113} 114 115 116void close_xml_element(tag_t tag, int has_nested, char *buffer, size_t max) 117{ 118 char *buf; 119 int size, ret; 120 121 buffer[max - 1] = '\0'; 122 size = strlen(buffer); 123 buf = &buffer[size]; 124 size = max - 1 - size; 125 126 if (tag == NONE) 127 ret = snprintf(buf, size, "%s\n", (has_nested ? ">" : "/>")); 128 else 129 ret = snprintf(buf, size, "</%s>\n", xml_tag_name(tag)); 130 131 if (ret < 0 || ret >= size) { 132 fprintf(stderr, "close_xml_element: snprintf failed\n"); 133 exit(EXIT_FAILURE); 134 } 135} 136 137 138void init_xml_int_attr(tag_t attr, int value, char *buffer, size_t max) 139{ 140 char *buf; 141 int size, ret; 142 143 buffer[max - 1] = '\0'; 144 size = strlen(buffer); 145 buf = &buffer[size]; 146 size = max - 1 - size; 147 148 ret = snprintf(buf, size, " %s=\"%d\"", xml_tag_name(attr), value); 149 150 if (ret < 0 || ret >= size) { 151 fprintf(stderr,"init_xml_int_attr: snprintf failed\n"); 152 exit(EXIT_FAILURE); 153 } 154} 155 156 157void init_xml_dbl_attr(tag_t attr, double value, char *buffer, size_t max) 158{ 159 char *buf; 160 int size, ret; 161 162 buffer[max - 1] = '\0'; 163 size = strlen(buffer); 164 buf = &buffer[size]; 165 size = max - 1 - size; 166 167 ret = snprintf(buf, size, " %s=\"%.2f\"", xml_tag_name(attr), value); 168 169 if (ret < 0 || ret >= size) { 170 fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n"); 171 exit(EXIT_FAILURE); 172 } 173} 174 175 176static void xml_quote(char const *str, char *buffer, size_t max) 177{ 178 char *buf; 179 char *quote; 180 char *pos = (char*)str; 181 size_t size; 182 int ret; 183 184 buffer[max - 1] = '\0'; 185 size = strlen(buffer); 186 buf = &buffer[size]; 187 size = max - 1 - size; 188 189 if (size < strlen(pos) + 2) 190 goto Error; 191 192 *buf = '"'; 193 buf++; 194 size--; 195 196 while (*pos) { 197 switch(*pos) { 198 case '&': 199 quote = "&"; 200 break; 201 case '<': 202 quote = "<"; 203 break; 204 case '>': 205 quote = ">"; 206 break; 207 case '"': 208 quote = """; 209 break; 210 default: 211 *buf = *pos; 212 pos++; 213 buf++; 214 size--; 215 continue; 216 } 217 218 pos++; 219 ret = snprintf(buf, size, "%s", quote); 220 if (ret < 0 || ret >= (int)size) 221 goto Error; 222 buf += ret; 223 size -= ret; 224 if (size < strlen(pos)) 225 goto Error; 226 } 227 228 if (!size) 229 goto Error; 230 231 *buf = '"'; 232 buf++; 233 *buf = '\0'; 234 235 return; 236 237Error: 238 fprintf(stderr,"quote_str: buffer overflow\n"); 239 exit(EXIT_FAILURE); 240} 241 242 243void init_xml_str_attr(tag_t attr, char const *str, char *buffer, size_t max) 244{ 245 char *buf; 246 int size, ret; 247 248 buffer[max - 1] = '\0'; 249 size = strlen(buffer); 250 buf = &buffer[size]; 251 size = max - 1 - size; 252 253 ret = snprintf(buf, size, " %s=", xml_tag_name(attr)); 254 if (ret < 0 || ret >= size) 255 goto Error; 256 257 buf += ret; 258 size -= ret; 259 260 if (!size) 261 goto Error; 262 263 xml_quote(str, buf, size); 264 return; 265Error: 266 fprintf(stderr,"init_xml_str_attr: snprintf failed\n"); 267 exit(EXIT_FAILURE); 268} 269