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",
805bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		"ext",
815a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"unit_masks",
825a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"default",
837a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown		"category",
845a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	"unit_mask",
855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"mask",
865a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		"desc"
875a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng};
885a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
895a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#define MAX_BUF_LEN 2048
905a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengchar const * xml_tag_name(tag_t tag)
915a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
925a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	return xml_tag_map[tag];
935a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
945a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
955a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
965bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengvoid open_xml_element(tag_t tag, int with_attrs, char *buffer, size_t max)
975a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
985bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *buf;
995bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	int size, ret;
1005a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1015bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buffer[max - 1] = '\0';
1025bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = strlen(buffer);
1035bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf = &buffer[size];
1045bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = max - 1 - size;
1055a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1065bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	ret = snprintf(buf, size, "<%s%s", xml_tag_name(tag),
1075bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		       (with_attrs ? " " : ">\n"));
1085bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
1095bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (ret < 0 || ret >= size) {
1105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,"open_xml_element: snprintf failed\n");
1115a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		exit(EXIT_FAILURE);
1125a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1135a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1145a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1155a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1165bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengvoid close_xml_element(tag_t tag, int has_nested, char *buffer, size_t max)
1175a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1185bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *buf;
1195bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	int size, ret;
1205a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1215bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buffer[max - 1] = '\0';
1225bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = strlen(buffer);
1235bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf = &buffer[size];
1245bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = max - 1 - size;
1255a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1265bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (tag == NONE)
1275bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		ret = snprintf(buf, size, "%s\n", (has_nested ? ">" : "/>"));
1285bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	else
1295bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		ret = snprintf(buf, size, "</%s>\n", xml_tag_name(tag));
1305bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
1315bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (ret < 0 || ret >= size) {
1325bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		fprintf(stderr, "close_xml_element: snprintf failed\n");
1335bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		exit(EXIT_FAILURE);
1345a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1355a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1365a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1375a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1385bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengvoid init_xml_int_attr(tag_t attr, int value, char *buffer, size_t max)
1395a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1405bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *buf;
1415bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	int size, ret;
1425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1435bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buffer[max - 1] = '\0';
1445bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = strlen(buffer);
1455bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf = &buffer[size];
1465bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = max - 1 - size;
1475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1485bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	ret = snprintf(buf, size, " %s=\"%d\"", xml_tag_name(attr), value);
1495a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1505bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (ret < 0 || ret >= size) {
1515a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr,"init_xml_int_attr: snprintf failed\n");
1525a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		exit(EXIT_FAILURE);
1535a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1545a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1555a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1565a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1575bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengvoid init_xml_dbl_attr(tag_t attr, double value, char *buffer, size_t max)
1585a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1595bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *buf;
1605bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	int size, ret;
1615bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
1625bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buffer[max - 1] = '\0';
1635bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = strlen(buffer);
1645bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf = &buffer[size];
1655bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = max - 1 - size;
1665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1675bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	ret = snprintf(buf, size, " %s=\"%.2f\"", xml_tag_name(attr), value);
1685a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1695bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (ret < 0 || ret >= size) {
1705a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		fprintf(stderr, "init_xml_dbl_attr: snprintf failed\n");
1715a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		exit(EXIT_FAILURE);
1725a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
1735a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
1745a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1755a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1765bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengstatic void xml_quote(char const *str, char *buffer, size_t max)
1775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
1785bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *buf;
1795bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *quote;
1805bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *pos = (char*)str;
1815bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size_t size;
1825bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	int ret;
1835a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1845bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buffer[max - 1] = '\0';
1855bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = strlen(buffer);
1865bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf = &buffer[size];
1875bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = max - 1 - size;
1885a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1895bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (size < strlen(pos) + 2)
1905bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		goto Error;
1915a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
1925bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	*buf = '"';
1935bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf++;
1945bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size--;
1955bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
1965bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	while (*pos) {
1975bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		switch(*pos) {
1985a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '&':
1995bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			quote = "&amp;";
2005a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
2015a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '<':
2025bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			quote = "&lt;";
2035a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
2045a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '>':
2055bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng                        quote = "&gt;";
2065a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
2075a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		case '"':
2085bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			quote = "&quot;";
2095a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			break;
2105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		default:
2115bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			*buf = *pos;
2125bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			pos++;
2135bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			buf++;
2145bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			size--;
2155bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			continue;
2165a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng		}
2175bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
2185bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		pos++;
2195bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		ret = snprintf(buf, size, "%s", quote);
2205bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		if (ret < 0 || ret >= (int)size)
2215bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			goto Error;
2225bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		buf += ret;
2235bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		size -= ret;
2245bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		if (size < strlen(pos))
2255bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng			goto Error;
2265a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng	}
2275a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2285bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (!size)
2295bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		goto Error;
2305bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
2315bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	*buf = '"';
2325bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf++;
2335bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	*buf = '\0';
2345bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
2355bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	return;
2365bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
2375bbbe460405564a1aed8a67a13c43e9356ffc656Ben ChengError:
2385bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	fprintf(stderr,"quote_str: buffer overflow\n");
2395bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	exit(EXIT_FAILURE);
2405a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
2415a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2435bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengvoid init_xml_str_attr(tag_t attr, char const *str, char *buffer, size_t max)
2445a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng{
2455bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	char *buf;
2465bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	int size, ret;
2475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2485bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buffer[max - 1] = '\0';
2495bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = strlen(buffer);
2505bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf = &buffer[size];
2515bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size = max - 1 - size;
2525a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
2535bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	ret = snprintf(buf, size, " %s=", xml_tag_name(attr));
2545bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (ret < 0 || ret >= size)
2555bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		goto Error;
2565bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
2575bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	buf += ret;
2585bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	size -= ret;
2595bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
2605bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	if (!size)
2615bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng		goto Error;
2625bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng
2635bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	xml_quote(str, buf, size);
2645bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	return;
2655bbbe460405564a1aed8a67a13c43e9356ffc656Ben ChengError:
2665bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	fprintf(stderr,"init_xml_str_attr: snprintf failed\n");
2675bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng	exit(EXIT_FAILURE);
2685a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng}
269