op_xml_out.c revision 5bbbe460405564a1aed8a67a13c43e9356ffc656
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 "unit_mask", 84 "mask", 85 "desc" 86}; 87 88#define MAX_BUF_LEN 2048 89char const * xml_tag_name(tag_t tag) 90{ 91 return xml_tag_map[tag]; 92} 93 94 95void open_xml_element(tag_t tag, int with_attrs, char *buffer, size_t max) 96{ 97 char *buf; 98 int size, ret; 99 100 buffer[max - 1] = '\0'; 101 size = strlen(buffer); 102 buf = &buffer[size]; 103 size = max - 1 - size; 104 105 ret = snprintf(buf, size, "<%s%s", xml_tag_name(tag), 106 (with_attrs ? " " : ">\n")); 107 108 if (ret < 0 || ret >= size) { 109 fprintf(stderr,"open_xml_element: snprintf failed\n"); 110 exit(EXIT_FAILURE); 111 } 112} 113 114 115void close_xml_element(tag_t tag, int has_nested, char *buffer, size_t max) 116{ 117 char *buf; 118 int size, ret; 119 120 buffer[max - 1] = '\0'; 121 size = strlen(buffer); 122 buf = &buffer[size]; 123 size = max - 1 - size; 124 125 if (tag == NONE) 126 ret = snprintf(buf, size, "%s\n", (has_nested ? ">" : "/>")); 127 else 128 ret = snprintf(buf, size, "</%s>\n", xml_tag_name(tag)); 129 130 if (ret < 0 || ret >= size) { 131 fprintf(stderr, "close_xml_element: snprintf failed\n"); 132 exit(EXIT_FAILURE); 133 } 134} 135 136 137void init_xml_int_attr(tag_t attr, int value, char *buffer, size_t max) 138{ 139 char *buf; 140 int size, ret; 141 142 buffer[max - 1] = '\0'; 143 size = strlen(buffer); 144 buf = &buffer[size]; 145 size = max - 1 - size; 146 147 ret = snprintf(buf, size, " %s=\"%d\"", xml_tag_name(attr), value); 148 149 if (ret < 0 || ret >= size) { 150 fprintf(stderr,"init_xml_int_attr: snprintf failed\n"); 151 exit(EXIT_FAILURE); 152 } 153} 154 155 156void init_xml_dbl_attr(tag_t attr, double value, char *buffer, size_t max) 157{ 158 char *buf; 159 int size, ret; 160 161 buffer[max - 1] = '\0'; 162 size = strlen(buffer); 163 buf = &buffer[size]; 164 size = max - 1 - size; 165 166 ret = snprintf(buf, size, " %s=\"%.2f\"", xml_tag_name(attr), value); 167 168 if (ret < 0 || ret >= size) { 169 fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n"); 170 exit(EXIT_FAILURE); 171 } 172} 173 174 175static void xml_quote(char const *str, char *buffer, size_t max) 176{ 177 char *buf; 178 char *quote; 179 char *pos = (char*)str; 180 size_t size; 181 int ret; 182 183 buffer[max - 1] = '\0'; 184 size = strlen(buffer); 185 buf = &buffer[size]; 186 size = max - 1 - size; 187 188 if (size < strlen(pos) + 2) 189 goto Error; 190 191 *buf = '"'; 192 buf++; 193 size--; 194 195 while (*pos) { 196 switch(*pos) { 197 case '&': 198 quote = "&"; 199 break; 200 case '<': 201 quote = "<"; 202 break; 203 case '>': 204 quote = ">"; 205 break; 206 case '"': 207 quote = """; 208 break; 209 default: 210 *buf = *pos; 211 pos++; 212 buf++; 213 size--; 214 continue; 215 } 216 217 pos++; 218 ret = snprintf(buf, size, "%s", quote); 219 if (ret < 0 || ret >= (int)size) 220 goto Error; 221 buf += ret; 222 size -= ret; 223 if (size < strlen(pos)) 224 goto Error; 225 } 226 227 if (!size) 228 goto Error; 229 230 *buf = '"'; 231 buf++; 232 *buf = '\0'; 233 234 return; 235 236Error: 237 fprintf(stderr,"quote_str: buffer overflow\n"); 238 exit(EXIT_FAILURE); 239} 240 241 242void init_xml_str_attr(tag_t attr, char const *str, char *buffer, size_t max) 243{ 244 char *buf; 245 int size, ret; 246 247 buffer[max - 1] = '\0'; 248 size = strlen(buffer); 249 buf = &buffer[size]; 250 size = max - 1 - size; 251 252 ret = snprintf(buf, size, " %s=", xml_tag_name(attr)); 253 if (ret < 0 || ret >= size) 254 goto Error; 255 256 buf += ret; 257 size -= ret; 258 259 if (!size) 260 goto Error; 261 262 xml_quote(str, buf, size); 263 return; 264Error: 265 fprintf(stderr,"init_xml_str_attr: snprintf failed\n"); 266 exit(EXIT_FAILURE); 267} 268