00001
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <stdlib.h>
00014 #include "op_xml_out.h"
00015
00016 char const * xml_tag_map[] = {
00017 "NONE",
00018 "id",
00019 "profile",
00020 "processor",
00021 "cputype",
00022 "title",
00023 "schemaversion",
00024 "mhz",
00025 "setup",
00026 "timersetup",
00027 "rtcinterrupts",
00028 "eventsetup",
00029 "eventname",
00030 "unitmask",
00031 "setupcount",
00032 "separatedcpus",
00033 "options",
00034 "session", "debuginfo", "details", "excludedependent",
00035 "excludesymbols", "imagepath", "includesymbols", "merge",
00036 "classes",
00037 "class",
00038 "cpu",
00039 "event",
00040 "mask",
00041 "process",
00042 "pid",
00043 "thread",
00044 "tid",
00045 "binary",
00046 "module",
00047 "name",
00048 "callers",
00049 "callees",
00050 "symbol",
00051 "idref",
00052 "self",
00053 "detaillo",
00054 "detailhi",
00055 "symboltable",
00056 "symboldata",
00057 "startingaddr",
00058 "file",
00059 "line",
00060 "codelength",
00061 "summarydata",
00062 "sampledata",
00063 "count",
00064 "detailtable",
00065 "symboldetails",
00066 "detaildata",
00067 "vmaoffset",
00068 "bytestable",
00069 "bytes",
00070 "help_events",
00071 "header",
00072 "title",
00073 "doc",
00074 "event",
00075 "event_name",
00076 "group",
00077 "desc",
00078 "counter_mask",
00079 "min_count",
00080 "ext",
00081 "unit_masks",
00082 "default",
00083 "category",
00084 "unit_mask",
00085 "mask",
00086 "desc",
00087 "extra"
00088 };
00089
00090 #define MAX_BUF_LEN 2048
00091 char const * xml_tag_name(tag_t tag)
00092 {
00093 return xml_tag_map[tag];
00094 }
00095
00096
00097 void open_xml_element(tag_t tag, int with_attrs, char *buffer, size_t max)
00098 {
00099 char *buf;
00100 int size, ret;
00101
00102 buffer[max - 1] = '\0';
00103 size = strlen(buffer);
00104 buf = &buffer[size];
00105 size = max - 1 - size;
00106
00107 ret = snprintf(buf, size, "<%s%s", xml_tag_name(tag),
00108 (with_attrs ? " " : ">\n"));
00109
00110 if (ret < 0 || ret >= size) {
00111 fprintf(stderr,"open_xml_element: snprintf failed\n");
00112 exit(EXIT_FAILURE);
00113 }
00114 }
00115
00116
00117 void close_xml_element(tag_t tag, int has_nested, char *buffer, size_t max)
00118 {
00119 char *buf;
00120 int size, ret;
00121
00122 buffer[max - 1] = '\0';
00123 size = strlen(buffer);
00124 buf = &buffer[size];
00125 size = max - 1 - size;
00126
00127 if (tag == NONE)
00128 ret = snprintf(buf, size, "%s\n", (has_nested ? ">" : "/>"));
00129 else
00130 ret = snprintf(buf, size, "</%s>\n", xml_tag_name(tag));
00131
00132 if (ret < 0 || ret >= size) {
00133 fprintf(stderr, "close_xml_element: snprintf failed\n");
00134 exit(EXIT_FAILURE);
00135 }
00136 }
00137
00138
00139 void init_xml_int_attr(tag_t attr, int value, char *buffer, size_t max)
00140 {
00141 char *buf;
00142 int size, ret;
00143
00144 buffer[max - 1] = '\0';
00145 size = strlen(buffer);
00146 buf = &buffer[size];
00147 size = max - 1 - size;
00148
00149 ret = snprintf(buf, size, " %s=\"%d\"", xml_tag_name(attr), value);
00150
00151 if (ret < 0 || ret >= size) {
00152 fprintf(stderr,"init_xml_int_attr: snprintf failed\n");
00153 exit(EXIT_FAILURE);
00154 }
00155 }
00156
00157
00158 void init_xml_dbl_attr(tag_t attr, double value, char *buffer, size_t max)
00159 {
00160 char *buf;
00161 int size, ret;
00162
00163 buffer[max - 1] = '\0';
00164 size = strlen(buffer);
00165 buf = &buffer[size];
00166 size = max - 1 - size;
00167
00168 ret = snprintf(buf, size, " %s=\"%.2f\"", xml_tag_name(attr), value);
00169
00170 if (ret < 0 || ret >= size) {
00171 fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n");
00172 exit(EXIT_FAILURE);
00173 }
00174 }
00175
00176
00177 static void xml_quote(char const *str, char *buffer, size_t max)
00178 {
00179 char *buf;
00180 char *quote;
00181 char *pos = (char*)str;
00182 size_t size;
00183 int ret;
00184
00185 buffer[max - 1] = '\0';
00186 size = strlen(buffer);
00187 buf = &buffer[size];
00188 size = max - 1 - size;
00189
00190 if (size < strlen(pos) + 2)
00191 goto Error;
00192
00193 *buf = '"';
00194 buf++;
00195 size--;
00196
00197 while (*pos) {
00198 switch(*pos) {
00199 case '&':
00200 quote = "&";
00201 break;
00202 case '<':
00203 quote = "<";
00204 break;
00205 case '>':
00206 quote = ">";
00207 break;
00208 case '"':
00209 quote = """;
00210 break;
00211 default:
00212 *buf = *pos;
00213 pos++;
00214 buf++;
00215 size--;
00216 continue;
00217 }
00218
00219 pos++;
00220 ret = snprintf(buf, size, "%s", quote);
00221 if (ret < 0 || ret >= (int)size)
00222 goto Error;
00223 buf += ret;
00224 size -= ret;
00225 if (size < strlen(pos))
00226 goto Error;
00227 }
00228
00229 if (!size)
00230 goto Error;
00231
00232 *buf = '"';
00233 buf++;
00234 *buf = '\0';
00235
00236 return;
00237
00238 Error:
00239 fprintf(stderr,"quote_str: buffer overflow\n");
00240 exit(EXIT_FAILURE);
00241 }
00242
00243
00244 void init_xml_str_attr(tag_t attr, char const *str, char *buffer, size_t max)
00245 {
00246 char *buf;
00247 int size, ret;
00248
00249 buffer[max - 1] = '\0';
00250 size = strlen(buffer);
00251 buf = &buffer[size];
00252 size = max - 1 - size;
00253
00254 ret = snprintf(buf, size, " %s=", xml_tag_name(attr));
00255 if (ret < 0 || ret >= size)
00256 goto Error;
00257
00258 buf += ret;
00259 size -= ret;
00260
00261 if (!size)
00262 goto Error;
00263
00264 xml_quote(str, buf, size);
00265 return;
00266 Error:
00267 fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
00268 exit(EXIT_FAILURE);
00269 }