Home | History | Annotate | Download | only in libop
      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 
     16 char 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
     90 char const * xml_tag_name(tag_t tag)
     91 {
     92 	return xml_tag_map[tag];
     93 }
     94 
     95 
     96 void 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 
    116 void 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 
    138 void 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 
    157 void 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 
    176 static 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 = "&amp;";
    200 			break;
    201 		case '<':
    202 			quote = "&lt;";
    203 			break;
    204 		case '>':
    205                         quote = "&gt;";
    206 			break;
    207 		case '"':
    208 			quote = "&quot;";
    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 
    237 Error:
    238 	fprintf(stderr,"quote_str: buffer overflow\n");
    239 	exit(EXIT_FAILURE);
    240 }
    241 
    242 
    243 void 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;
    265 Error:
    266 	fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
    267 	exit(EXIT_FAILURE);
    268 }
    269