op_xml_out.c revision 5a4eb4eb367eccd4b976d1feae96cea96d2c50f2
15a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng/**
25a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @file op_xml_out.c
35a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * C utility routines for writing XML
45a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng *
55a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @remark Copyright 2008 OProfile authors
65a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @remark Read the file COPYING
75a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng *
85a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng * @author Dave Nomura
95a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng */
105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
115a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include <stdio.h>
125a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include <string.h>
135a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include <stdlib.h>
145a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#include "op_xml_out.h"
155a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
165a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengchar const * xml_tag_map[] = {
175a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"NONE",
185a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"id",
195a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"profile",
205a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"processor",
215a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"cputype",
225a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"title",
235a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"schemaversion",
245a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"mhz",
255a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"setup",
265a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"timersetup",
275a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"rtcinterrupts",
285a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"eventsetup",
295a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"eventname",
305a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"unitmask",
315a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"setupcount",
325a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"separatedcpus",
335a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"options",
345a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"session", "debuginfo", "details", "excludedependent",
355a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"excludesymbols", "imagepath", "includesymbols", "merge",
365a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"classes",
375a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"class",
385a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"cpu",
395a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"event",
405a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"mask",
415a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"process",
425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"pid",
435a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"thread",
445a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"tid",
455a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"binary",
465a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"module",
475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"name",
485a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"callers",
495a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"callees",
505a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"symbol",
515a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"idref",
525a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"self",
535a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"detaillo",
545a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"detailhi",
555a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"symboltable",
565a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"symboldata",
575a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"startingaddr",
585a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"file",
595a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"line",
605a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"codelength",
615a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"summarydata",
625a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"sampledata",
635a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"count",
645a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"detailtable",
655a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"symboldetails",
665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"detaildata",
675a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"vmaoffset",
685a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"bytestable",
695a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"bytes",
705a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"help_events",
715a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"header",
725a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"title",
735a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"doc",
745a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"event",
755a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"event_name",
765a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"group",
775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"desc",
785a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"counter_mask",
795a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"min_count",
805a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"unit_masks",
815a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"default",
825a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"unit_mask",
835a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"mask",
845a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"desc"
855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng};
865a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
875a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#define MAX_BUF_LEN 2048
885a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengchar const * xml_tag_name(tag_t tag)
895a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
905a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return xml_tag_map[tag];
915a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
925a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
935a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
945a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid open_xml_element(tag_t tag, int with_attrs, char * buffer)
955a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
965a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char const * tag_name = xml_tag_name(tag);
975a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	unsigned int const max_len = strlen(tag_name) + 3;
985a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char tmp_buf[MAX_BUF_LEN];
995a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1005a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (max_len >= sizeof(tmp_buf))
1015a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,"Warning: open_xml_element: buffer overflow %d\n", max_len);
1025a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1035a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (snprintf(tmp_buf, sizeof(tmp_buf), "<%s%s", tag_name,
1045a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		(with_attrs ? " " : ">\n")) < 0) {
1055a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,"open_xml_element: snprintf failed\n");
1065a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		exit(EXIT_FAILURE);
1075a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1085a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	strncat(buffer, tmp_buf, sizeof(tmp_buf));
1095a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1115a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1125a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid close_xml_element(tag_t tag, int has_nested, char * buffer)
1135a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1145a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char const * tag_name = xml_tag_name(tag);
1155a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	unsigned int const max_len = strlen(tag_name) + 3;
1165a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char tmp_buf[MAX_BUF_LEN];
1175a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1185a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (max_len >= sizeof(tmp_buf))
1195a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,"Warning: close_xml_element: buffer overflow %d\n", max_len);
1205a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1215a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (tag == NONE) {
1225a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		if (snprintf(tmp_buf, sizeof(tmp_buf), "%s\n", (has_nested ? ">" : "/>")) < 0) {
1235a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			fprintf(stderr, "close_xml_element: snprintf failed\n");
1245a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			exit(EXIT_FAILURE);
1255a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		}
1265a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	} else {
1275a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		if (snprintf(tmp_buf, sizeof(tmp_buf), "</%s>\n", tag_name) < 0) {
1285a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			fprintf(stderr, "close_xml_element: snprintf failed\n");
1295a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			exit(EXIT_FAILURE);
1305a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		}
1315a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1325a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	strncat(buffer, tmp_buf, sizeof(tmp_buf));
1335a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1345a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1355a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1365a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid init_xml_int_attr(tag_t attr, int value, char * buffer)
1375a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1385a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char const * attr_name = xml_tag_name(attr);
1395a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char tmp_buf[MAX_BUF_LEN];
1405a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	unsigned int const max_len = strlen(attr_name) + 50;
1415a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (max_len >= sizeof(tmp_buf)) {
1435a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,
1445a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			"Warning: init_xml_int_attr: buffer overflow %d\n", max_len);
1455a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1465a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1485a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (snprintf(tmp_buf, sizeof(tmp_buf), " %s=\"%d\"", attr_name, value) < 0) {
1495a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,"init_xml_int_attr: snprintf failed\n");
1505a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		exit(EXIT_FAILURE);
1515a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1525a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	strncat(buffer, tmp_buf, sizeof(tmp_buf));
1535a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1545a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1555a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1565a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid init_xml_dbl_attr(tag_t attr, double value, char * buffer)
1575a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1585a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char const * attr_name = xml_tag_name(attr);
1595a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	unsigned int const max_len = strlen(attr_name) + 50;
1605a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char tmp_buf[MAX_BUF_LEN];
1615a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1625a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (max_len >= sizeof(tmp_buf))
1635a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr, "Warning: init_xml_dbl_attr: buffer overflow %d\n", max_len);
1645a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1655a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (snprintf(tmp_buf, sizeof(tmp_buf), " %s=\"%.2f\"", attr_name, value) < 0) {
1665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n");
1675a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		exit(EXIT_FAILURE);
1685a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1695a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	strncat(buffer, tmp_buf, sizeof(tmp_buf));
1705a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1715a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1725a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1735a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengstatic char * xml_quote(char const * str, char * quote_buf)
1745a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1755a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	int i;
1765a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	int pos = 0;
1775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	int len = strlen(str);
1785a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1795a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1805a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	quote_buf[pos++] = '"';
1815a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1825a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	for (i = 0; i < len; i++) {
1835a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		if (pos >= MAX_BUF_LEN - 10) {
1845a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			fprintf(stderr,"quote_str: buffer overflow %d\n", pos);
1855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			exit(EXIT_FAILURE);
1865a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		}
1875a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1885a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		switch(str[i]) {
1895a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '&':
1905a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			strncpy(quote_buf + pos, "&amp;", 5);
1915a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			pos += 5;
1925a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
1935a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '<':
1945a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			strncpy(quote_buf + pos, "&lt;", 4);
1955a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			pos += 4;
1965a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
1975a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '>':
1985a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			strncpy(quote_buf + pos, "&gt;", 4);
1995a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			pos += 4;
2005a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
2015a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '"':
2025a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			strncpy(quote_buf + pos, "&quot;", 6);
2035a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			pos += 6;
2045a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
2055a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		default:
2065a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			quote_buf[pos++] = str[i];
2075a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
2085a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		}
2095a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
2105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2115a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	quote_buf[pos++] = '"';
2125a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	quote_buf[pos++] = '\0';
2135a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return quote_buf;
2145a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
2155a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2165a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2175a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengvoid init_xml_str_attr(tag_t attr, char const * str, char * buffer)
2185a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
2195a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char tmp_buf[MAX_BUF_LEN];
2205a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char quote_buf[MAX_BUF_LEN];
2215a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char const * attr_name = xml_tag_name(attr);
2225a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	char const * quote_str = xml_quote(str, quote_buf);
2235a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	const unsigned int max_len = strlen(attr_name) + strlen(quote_str) + 10;
2245a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2255a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (max_len >= sizeof(tmp_buf))
2265a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr, "Warning: init_xml_str_attr: buffer overflow %d\n", max_len);
2275a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2285a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	if (snprintf(tmp_buf, sizeof(tmp_buf), " %s=""%s""", attr_name, quote_str) < 0) {
2295a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
2305a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		exit(EXIT_FAILURE);
2315a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
2325a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	strncat(buffer, tmp_buf, sizeof(tmp_buf));
2335a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
234