2007-03-15 17:30:04 +00:00
|
|
|
/*
|
2007-06-26 22:21:22 +00:00
|
|
|
* buf.c: buffers for libvirt
|
2007-03-15 17:30:04 +00:00
|
|
|
*
|
2008-05-09 13:50:14 +00:00
|
|
|
* Copyright (C) 2005-2008 Red Hat, Inc.
|
2007-03-15 17:30:04 +00:00
|
|
|
*
|
|
|
|
* See COPYING.LIB for the License of this software
|
|
|
|
*
|
|
|
|
* Daniel Veillard <veillard@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-12-05 21:40:15 +00:00
|
|
|
|
2007-03-15 17:30:04 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
#include "c-ctype.h"
|
2007-12-17 10:05:35 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
#define __VIR_BUFFER_C__
|
|
|
|
|
2007-03-15 17:30:04 +00:00
|
|
|
#include "buf.h"
|
2008-05-29 18:45:36 +00:00
|
|
|
#include "memory.h"
|
2007-03-15 17:30:04 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
|
|
|
|
/* If adding more fields, ensure to edit buf.h to match
|
|
|
|
the number of fields */
|
|
|
|
struct _virBuffer {
|
|
|
|
unsigned int size;
|
|
|
|
unsigned int use;
|
|
|
|
unsigned int error;
|
|
|
|
char *content;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virBufferFail
|
|
|
|
* @buf: the buffer
|
|
|
|
*
|
|
|
|
* Mark the buffer has having failed a memory allocation,
|
|
|
|
* freeing the content and setting the error flag.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
virBufferNoMemory(const virBufferPtr buf)
|
|
|
|
{
|
2008-05-29 18:45:36 +00:00
|
|
|
VIR_FREE(buf->content);
|
2008-04-28 15:14:59 +00:00
|
|
|
buf->size = 0;
|
|
|
|
buf->use = 0;
|
|
|
|
buf->error = 1;
|
|
|
|
}
|
|
|
|
|
2007-03-15 17:30:04 +00:00
|
|
|
/**
|
2007-06-26 22:21:22 +00:00
|
|
|
* virBufferGrow:
|
2007-03-15 17:30:04 +00:00
|
|
|
* @buf: the buffer
|
2007-03-21 15:24:56 +00:00
|
|
|
* @len: the minimum free size to allocate on top of existing used space
|
2007-03-15 17:30:04 +00:00
|
|
|
*
|
2007-03-21 15:24:56 +00:00
|
|
|
* Grow the available space of a buffer to at least @len bytes.
|
2007-03-15 17:30:04 +00:00
|
|
|
*
|
2008-04-28 15:14:59 +00:00
|
|
|
* Returns zero on success or -1 on error
|
2007-03-15 17:30:04 +00:00
|
|
|
*/
|
|
|
|
static int
|
2007-06-26 22:21:22 +00:00
|
|
|
virBufferGrow(virBufferPtr buf, unsigned int len)
|
2007-03-15 17:30:04 +00:00
|
|
|
{
|
|
|
|
int size;
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (buf->error)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ((len + buf->use) < buf->size)
|
|
|
|
return 0;
|
2007-03-15 17:30:04 +00:00
|
|
|
|
|
|
|
size = buf->use + len + 1000;
|
|
|
|
|
2008-05-29 18:45:36 +00:00
|
|
|
if (VIR_REALLOC_N(buf->content, size) < 0) {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferNoMemory(buf);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-03-15 17:30:04 +00:00
|
|
|
buf->size = size;
|
2008-04-28 15:14:59 +00:00
|
|
|
return 0;
|
2007-03-15 17:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2007-06-26 22:21:22 +00:00
|
|
|
* virBufferAdd:
|
2007-12-17 10:05:35 +00:00
|
|
|
* @buf: the buffer to add to
|
2007-03-15 17:30:04 +00:00
|
|
|
* @str: the string
|
|
|
|
* @len: the number of bytes to add
|
|
|
|
*
|
|
|
|
* Add a string range to an XML buffer. if len == -1, the length of
|
|
|
|
* str is recomputed to the full string.
|
|
|
|
*
|
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
void
|
2008-11-17 11:03:25 +00:00
|
|
|
virBufferAdd(const virBufferPtr buf, const char *str, int len)
|
2007-03-15 17:30:04 +00:00
|
|
|
{
|
|
|
|
unsigned int needSize;
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if ((str == NULL) || (buf == NULL) || (len == 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (buf->error)
|
|
|
|
return;
|
2007-03-15 17:30:04 +00:00
|
|
|
|
|
|
|
if (len < 0)
|
|
|
|
len = strlen(str);
|
|
|
|
|
|
|
|
needSize = buf->use + len + 2;
|
2008-04-28 15:14:59 +00:00
|
|
|
if (needSize > buf->size &&
|
|
|
|
virBufferGrow(buf, needSize - buf->use) < 0)
|
|
|
|
return;
|
2007-12-17 10:05:35 +00:00
|
|
|
|
|
|
|
memcpy (&buf->content[buf->use], str, len);
|
2007-03-15 17:30:04 +00:00
|
|
|
buf->use += len;
|
2008-04-28 15:14:59 +00:00
|
|
|
buf->content[buf->use] = '\0';
|
2007-03-15 17:30:04 +00:00
|
|
|
}
|
|
|
|
|
2007-12-17 10:05:35 +00:00
|
|
|
/**
|
|
|
|
* virBufferAddChar:
|
|
|
|
* @buf: the buffer to add to
|
|
|
|
* @c: the character to add
|
|
|
|
*
|
|
|
|
* Add a single character 'c' to a buffer.
|
|
|
|
*
|
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
void
|
2008-11-17 11:03:25 +00:00
|
|
|
virBufferAddChar (virBufferPtr buf, char c)
|
2007-12-17 10:05:35 +00:00
|
|
|
{
|
|
|
|
unsigned int needSize;
|
|
|
|
|
|
|
|
if (buf == NULL)
|
2008-04-28 15:14:59 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (buf->error)
|
|
|
|
return;
|
2007-12-17 10:05:35 +00:00
|
|
|
|
|
|
|
needSize = buf->use + 2;
|
2008-04-28 15:14:59 +00:00
|
|
|
if (needSize > buf->size &&
|
|
|
|
virBufferGrow (buf, needSize - buf->use) < 0)
|
|
|
|
return;
|
2007-12-17 10:05:35 +00:00
|
|
|
|
|
|
|
buf->content[buf->use++] = c;
|
2008-04-28 15:14:59 +00:00
|
|
|
buf->content[buf->use] = '\0';
|
2007-12-17 10:05:35 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
2008-04-28 15:14:59 +00:00
|
|
|
* virBufferContentAndReset:
|
|
|
|
* @buf: Buffer
|
2007-06-29 13:23:13 +00:00
|
|
|
*
|
2008-04-28 15:14:59 +00:00
|
|
|
* Get the content from the buffer and free (only) the buffer structure.
|
|
|
|
* The caller owns the returned string & should free it when no longer
|
|
|
|
* required. The buffer object is reset to its initial state.
|
2007-06-29 13:23:13 +00:00
|
|
|
*
|
2008-04-28 15:14:59 +00:00
|
|
|
* Returns the buffer content or NULL in case of error.
|
2007-06-29 13:23:13 +00:00
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
char *
|
2008-11-17 11:03:25 +00:00
|
|
|
virBufferContentAndReset(const virBufferPtr buf)
|
2007-03-15 17:30:04 +00:00
|
|
|
{
|
2008-04-28 15:14:59 +00:00
|
|
|
char *str;
|
|
|
|
if (buf == NULL)
|
|
|
|
return NULL;
|
2007-03-15 17:30:04 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (buf->error) {
|
|
|
|
memset(buf, 0, sizeof(*buf));
|
2007-03-15 17:30:04 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
str = buf->content;
|
|
|
|
memset(buf, 0, sizeof(*buf));
|
|
|
|
return str;
|
2007-03-15 17:30:04 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 13:23:13 +00:00
|
|
|
/**
|
2008-04-28 15:14:59 +00:00
|
|
|
* virBufferError:
|
|
|
|
* @buf: the buffer
|
2007-06-29 13:23:13 +00:00
|
|
|
*
|
2008-04-28 15:14:59 +00:00
|
|
|
* Check to see if the buffer is in an error state due
|
|
|
|
* to failed memory allocation
|
|
|
|
*
|
|
|
|
* Return true if in error, 0 if normal
|
2007-06-29 13:23:13 +00:00
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
int
|
2008-11-17 11:03:25 +00:00
|
|
|
virBufferError(const virBufferPtr buf)
|
2007-03-15 17:30:04 +00:00
|
|
|
{
|
2008-04-28 15:14:59 +00:00
|
|
|
if (buf == NULL)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return buf->error;
|
2007-03-15 17:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-04-28 15:14:59 +00:00
|
|
|
* virBufferUse:
|
|
|
|
* @buf: the usage of the string in the buffer
|
2007-03-15 17:30:04 +00:00
|
|
|
*
|
2008-04-28 15:14:59 +00:00
|
|
|
* Return the string usage in bytes
|
2007-03-15 17:30:04 +00:00
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
unsigned int
|
|
|
|
virBufferUse(const virBufferPtr buf)
|
2007-03-15 17:30:04 +00:00
|
|
|
{
|
2007-06-29 13:23:13 +00:00
|
|
|
if (buf == NULL)
|
2008-04-28 15:14:59 +00:00
|
|
|
return 0;
|
2007-03-15 17:30:04 +00:00
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
return buf->use;
|
2007-03-15 17:30:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2007-06-26 22:21:22 +00:00
|
|
|
* virBufferVSprintf:
|
2007-03-15 17:30:04 +00:00
|
|
|
* @buf: the buffer to dump
|
|
|
|
* @format: the format
|
2007-06-29 13:23:13 +00:00
|
|
|
* @...: the variable list of arguments
|
2007-03-15 17:30:04 +00:00
|
|
|
*
|
|
|
|
* Do a formatted print to an XML buffer.
|
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
void
|
2008-11-17 11:03:25 +00:00
|
|
|
virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
|
2007-03-15 17:30:04 +00:00
|
|
|
{
|
2007-08-30 13:12:44 +00:00
|
|
|
int size, count, grow_size;
|
2007-03-15 17:30:04 +00:00
|
|
|
va_list locarg, argptr;
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if ((format == NULL) || (buf == NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (buf->error)
|
|
|
|
return;
|
2008-02-20 15:29:13 +00:00
|
|
|
|
|
|
|
if (buf->size == 0 &&
|
|
|
|
virBufferGrow(buf, 100) < 0)
|
2008-04-28 15:14:59 +00:00
|
|
|
return;
|
2008-02-20 15:29:13 +00:00
|
|
|
|
2007-03-15 17:30:04 +00:00
|
|
|
size = buf->size - buf->use - 1;
|
|
|
|
va_start(argptr, format);
|
|
|
|
va_copy(locarg, argptr);
|
|
|
|
while (((count = vsnprintf(&buf->content[buf->use], size, format,
|
|
|
|
locarg)) < 0) || (count >= size - 1)) {
|
|
|
|
buf->content[buf->use] = 0;
|
|
|
|
va_end(locarg);
|
2008-04-28 15:14:59 +00:00
|
|
|
|
2007-08-30 13:12:44 +00:00
|
|
|
grow_size = (count > 1000) ? count : 1000;
|
2008-04-28 15:14:59 +00:00
|
|
|
if (virBufferGrow(buf, grow_size) < 0)
|
|
|
|
return;
|
|
|
|
|
2007-03-15 17:30:04 +00:00
|
|
|
size = buf->size - buf->use - 1;
|
|
|
|
va_copy(locarg, argptr);
|
|
|
|
}
|
|
|
|
va_end(locarg);
|
|
|
|
buf->use += count;
|
2008-04-28 15:14:59 +00:00
|
|
|
buf->content[buf->use] = '\0';
|
2007-03-15 17:30:04 +00:00
|
|
|
}
|
|
|
|
|
2007-07-09 11:24:52 +00:00
|
|
|
/**
|
|
|
|
* virBufferEscapeString:
|
|
|
|
* @buf: the buffer to dump
|
|
|
|
* @format: a printf like format string but with only one %s parameter
|
|
|
|
* @str: the string argument which need to be escaped
|
|
|
|
*
|
|
|
|
* Do a formatted print with a single string to an XML buffer. The string
|
|
|
|
* is escaped to avoid generating a not well-formed XML instance.
|
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
void
|
|
|
|
virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str)
|
2007-07-09 11:24:52 +00:00
|
|
|
{
|
2007-08-30 13:12:44 +00:00
|
|
|
int size, count, len, grow_size;
|
2007-07-09 11:24:52 +00:00
|
|
|
char *escaped, *out;
|
|
|
|
const char *cur;
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if ((format == NULL) || (buf == NULL) || (str == NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (buf->error)
|
|
|
|
return;
|
2007-07-09 11:24:52 +00:00
|
|
|
|
|
|
|
len = strlen(str);
|
2009-05-13 16:19:59 +00:00
|
|
|
if (VIR_ALLOC_N(escaped, 6 * len + 1) < 0) {
|
2008-04-28 15:14:59 +00:00
|
|
|
virBufferNoMemory(buf);
|
|
|
|
return;
|
2007-07-09 11:24:52 +00:00
|
|
|
}
|
2008-04-28 15:14:59 +00:00
|
|
|
|
2007-07-09 11:24:52 +00:00
|
|
|
cur = str;
|
|
|
|
out = escaped;
|
|
|
|
while (*cur != 0) {
|
|
|
|
if (*cur == '<') {
|
2008-04-10 16:54:54 +00:00
|
|
|
*out++ = '&';
|
|
|
|
*out++ = 'l';
|
|
|
|
*out++ = 't';
|
|
|
|
*out++ = ';';
|
|
|
|
} else if (*cur == '>') {
|
|
|
|
*out++ = '&';
|
|
|
|
*out++ = 'g';
|
|
|
|
*out++ = 't';
|
|
|
|
*out++ = ';';
|
|
|
|
} else if (*cur == '&') {
|
|
|
|
*out++ = '&';
|
|
|
|
*out++ = 'a';
|
|
|
|
*out++ = 'm';
|
|
|
|
*out++ = 'p';
|
|
|
|
*out++ = ';';
|
2009-05-13 16:19:59 +00:00
|
|
|
} else if (*cur == '"') {
|
|
|
|
*out++ = '&';
|
|
|
|
*out++ = 'q';
|
|
|
|
*out++ = 'u';
|
|
|
|
*out++ = 'o';
|
|
|
|
*out++ = 't';
|
|
|
|
*out++ = ';';
|
|
|
|
} else if (*cur == '\'') {
|
|
|
|
*out++ = '&';
|
|
|
|
*out++ = 'a';
|
|
|
|
*out++ = 'p';
|
|
|
|
*out++ = 'o';
|
|
|
|
*out++ = 's';
|
|
|
|
*out++ = ';';
|
2009-08-04 17:13:09 +00:00
|
|
|
} else if (((unsigned char)*cur >= 0x20) || (*cur == '\n') || (*cur == '\t') ||
|
2008-04-10 16:54:54 +00:00
|
|
|
(*cur == '\r')) {
|
|
|
|
/*
|
|
|
|
* default case, just copy !
|
|
|
|
* Note that character over 0x80 are likely to give problem
|
|
|
|
* with UTF-8 XML, but since our string don't have an encoding
|
|
|
|
* it's hard to handle properly we have to assume it's UTF-8 too
|
|
|
|
*/
|
|
|
|
*out++ = *cur;
|
|
|
|
}
|
|
|
|
cur++;
|
2007-07-09 11:24:52 +00:00
|
|
|
}
|
|
|
|
*out = 0;
|
|
|
|
|
|
|
|
size = buf->size - buf->use - 1;
|
|
|
|
while (((count = snprintf(&buf->content[buf->use], size, format,
|
|
|
|
(char *)escaped)) < 0) || (count >= size - 1)) {
|
|
|
|
buf->content[buf->use] = 0;
|
2007-08-30 13:12:44 +00:00
|
|
|
grow_size = (count > 1000) ? count : 1000;
|
|
|
|
if (virBufferGrow(buf, grow_size) < 0) {
|
2008-05-29 18:45:36 +00:00
|
|
|
VIR_FREE(escaped);
|
2008-04-28 15:14:59 +00:00
|
|
|
return;
|
2007-07-09 11:24:52 +00:00
|
|
|
}
|
|
|
|
size = buf->size - buf->use - 1;
|
|
|
|
}
|
|
|
|
buf->use += count;
|
2008-04-28 15:14:59 +00:00
|
|
|
buf->content[buf->use] = '\0';
|
2008-05-29 18:45:36 +00:00
|
|
|
VIR_FREE(escaped);
|
2007-07-09 11:24:52 +00:00
|
|
|
}
|
|
|
|
|
2007-12-17 10:05:35 +00:00
|
|
|
/**
|
|
|
|
* virBufferURIEncodeString:
|
|
|
|
* @buf: the buffer to append to
|
|
|
|
* @str: the string argument which will be URI-encoded
|
|
|
|
*
|
|
|
|
* Append the string to the buffer. The string will be URI-encoded
|
|
|
|
* during the append (ie any non alpha-numeric characters are replaced
|
|
|
|
* with '%xx' hex sequences).
|
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
void
|
2007-12-17 10:05:35 +00:00
|
|
|
virBufferURIEncodeString (virBufferPtr buf, const char *str)
|
|
|
|
{
|
|
|
|
int grow_size = 0;
|
|
|
|
const char *p;
|
|
|
|
unsigned char uc;
|
|
|
|
const char *hex = "0123456789abcdef";
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if ((buf == NULL) || (str == NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (buf->error)
|
|
|
|
return;
|
|
|
|
|
2007-12-17 10:05:35 +00:00
|
|
|
for (p = str; *p; ++p) {
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
if (c_isalnum(*p))
|
2007-12-17 10:05:35 +00:00
|
|
|
grow_size++;
|
|
|
|
else
|
|
|
|
grow_size += 3; /* %ab */
|
|
|
|
}
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (virBufferGrow (buf, grow_size) < 0)
|
|
|
|
return;
|
2007-12-17 10:05:35 +00:00
|
|
|
|
|
|
|
for (p = str; *p; ++p) {
|
start using c-ctype functions
Up to now, we've been avoiding ctype functions like isspace, isdigit,
etc. because they are locale-dependent. Now that we have the c-ctype
functions, we can start using *them*, to make the code more readable
with changes like these:
- /* This may not work on EBCDIC. */
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9'))
+ if (c_isalnum(*p))
- while ((*cur >= '0') && (*cur <= '9')) {
+ while (c_isdigit(*cur)) {
Also, some macros in conf.c used names that conflicted with
standard meaning of "BLANK" and "SPACE", so I've adjusted them
to be in line with the definition of e.g., isblank.
In addition, I've wrapped those statement macros with do {...} while (0),
so that we can't forget the ";" after a use. There was one like that
already (fixed below). The missing semicolon would mess up automatic
indenting.
* src/buf.c (virBufferURIEncodeString):
* src/conf.c (IS_EOL, SKIP_BLANKS_AND_EOL, SKIP_BLANKS)
(virConfParseLong, virConfParseValue, virConfParseName)
(virConfParseSeparator, virConfParseStatement, IS_BLANK, IS_CHAR)
(IS_DIGIT, IS_SPACE, SKIP_SPACES):
* src/nodeinfo.c:
* src/qemu_conf.c (qemudParseInterfaceXML):
* src/qemu_driver.c (qemudDomainBlockStats):
* src/sexpr.c:
* src/stats_linux.c:
* src/util.c (virParseNumber, virDiskNameToIndex):
* src/uuid.c (hextobin, virUUIDParse):
* src/virsh.c:
* src/xml.c (parseCpuNumber, virParseCpuSet):
2008-05-16 09:37:44 +00:00
|
|
|
if (c_isalnum(*p))
|
2007-12-17 10:05:35 +00:00
|
|
|
buf->content[buf->use++] = *p;
|
|
|
|
else {
|
|
|
|
uc = (unsigned char) *p;
|
|
|
|
buf->content[buf->use++] = '%';
|
|
|
|
buf->content[buf->use++] = hex[uc >> 4];
|
|
|
|
buf->content[buf->use++] = hex[uc & 0xf];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
buf->content[buf->use] = '\0';
|
|
|
|
}
|
|
|
|
|
2007-03-15 17:30:04 +00:00
|
|
|
/**
|
2007-06-26 22:21:22 +00:00
|
|
|
* virBufferStrcat:
|
2007-03-15 17:30:04 +00:00
|
|
|
* @buf: the buffer to dump
|
2007-06-29 13:23:13 +00:00
|
|
|
* @...: the variable list of strings, the last argument must be NULL
|
2007-03-15 17:30:04 +00:00
|
|
|
*
|
|
|
|
* Concatenate strings to an XML buffer.
|
|
|
|
*/
|
2008-04-28 15:14:59 +00:00
|
|
|
void
|
2007-06-26 22:21:22 +00:00
|
|
|
virBufferStrcat(virBufferPtr buf, ...)
|
2007-03-15 17:30:04 +00:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
char *str;
|
|
|
|
|
2008-04-28 15:14:59 +00:00
|
|
|
if (buf->error)
|
|
|
|
return;
|
|
|
|
|
2007-03-15 17:30:04 +00:00
|
|
|
va_start(ap, buf);
|
|
|
|
|
|
|
|
while ((str = va_arg(ap, char *)) != NULL) {
|
|
|
|
unsigned int len = strlen(str);
|
|
|
|
unsigned int needSize = buf->use + len + 2;
|
|
|
|
|
|
|
|
if (needSize > buf->size) {
|
2008-04-28 15:14:59 +00:00
|
|
|
if (virBufferGrow(buf, needSize - buf->use) < 0)
|
|
|
|
return;
|
2007-03-15 17:30:04 +00:00
|
|
|
}
|
|
|
|
memcpy(&buf->content[buf->use], str, len);
|
|
|
|
buf->use += len;
|
|
|
|
buf->content[buf->use] = 0;
|
|
|
|
}
|
|
|
|
va_end(ap);
|
|
|
|
}
|