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):
This commit is contained in:
Jim Meyering 2008-05-16 09:37:44 +00:00
parent 0dc23afb0c
commit c1ee35af3b
12 changed files with 105 additions and 70 deletions

View File

@ -1,5 +1,42 @@
Fri May 16 11:29:30 CEST 2008 Jim Meyering <meyering@redhat.com>
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):
avoid a double-free bug
* src/qemu_conf.c (qemudParseXML): Ensure that "obj" is either
NULL or a valid malloc'd pointer before we might "goto error"

View File

@ -16,6 +16,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "c-ctype.h"
#define __VIR_BUFFER_C__
@ -349,10 +350,7 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str)
return;
for (p = str; *p; ++p) {
/* This may not work on EBCDIC. */
if ((*p >= 'a' && *p <= 'z') ||
(*p >= 'A' && *p <= 'Z') ||
(*p >= '0' && *p <= '9'))
if (c_isalnum(*p))
grow_size++;
else
grow_size += 3; /* %ab */
@ -362,10 +360,7 @@ virBufferURIEncodeString (virBufferPtr buf, const char *str)
return;
for (p = str; *p; ++p) {
/* This may not work on EBCDIC. */
if ((*p >= 'a' && *p <= 'z') ||
(*p >= 'A' && *p <= 'Z') ||
(*p >= '0' && *p <= '9'))
if (c_isalnum(*p))
buf->content[buf->use++] = *p;
else {
uc = (unsigned char) *p;

View File

@ -22,6 +22,7 @@
#include "buf.h"
#include "conf.h"
#include "util.h"
#include "c-ctype.h"
/************************************************************************
* *
@ -45,17 +46,14 @@ struct _virConfParserCtxt {
#define CUR (*ctxt->cur)
#define NEXT if (ctxt->cur < ctxt->end) ctxt->cur++;
#define IS_EOL(c) (((c) == '\n') || ((c) == '\r'))
#define IS_BLANK(c) (((c) == ' ') || ((c) == '\n') || ((c) == '\r') || \
((c) == '\t'))
#define SKIP_BLANKS {while ((ctxt->cur < ctxt->end) && (IS_BLANK(CUR))){\
if (CUR == '\n') ctxt->line++; \
ctxt->cur++;}}
#define IS_SPACE(c) (((c) == ' ') || ((c) == '\t'))
#define SKIP_SPACES {while ((ctxt->cur < ctxt->end) && (IS_SPACE(CUR))) \
ctxt->cur++;}
#define IS_CHAR(c) ((((c) >= 'a') && ((c) <= 'z')) || \
(((c) >= 'A') && ((c) <= 'Z')))
#define IS_DIGIT(c) (((c) >= '0') && ((c) <= '9'))
#define SKIP_BLANKS_AND_EOL \
do { while ((ctxt->cur < ctxt->end) && (c_isblank(CUR) || IS_EOL(CUR))) { \
if (CUR == '\n') ctxt->line++; \
ctxt->cur++;}} while (0)
#define SKIP_BLANKS \
do { while ((ctxt->cur < ctxt->end) && (c_isblank(CUR))) \
ctxt->cur++; } while (0)
/************************************************************************
* *
@ -338,12 +336,12 @@ virConfParseLong(virConfParserCtxtPtr ctxt, long *val)
} else if (CUR == '+') {
NEXT;
}
if ((ctxt->cur >= ctxt->end) || (!IS_DIGIT(CUR))) {
if ((ctxt->cur >= ctxt->end) || (!c_isdigit(CUR))) {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("unterminated number"),
ctxt->line);
return(-1);
}
while ((ctxt->cur < ctxt->end) && (IS_DIGIT(CUR))) {
while ((ctxt->cur < ctxt->end) && (c_isdigit(CUR))) {
l = l * 10 + (CUR - '0');
NEXT;
}
@ -428,7 +426,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
char *str = NULL;
long l = 0;
SKIP_SPACES;
SKIP_BLANKS;
if (ctxt->cur >= ctxt->end) {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting a value"),
ctxt->line);
@ -442,10 +440,10 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
} else if (CUR == '[') {
type = VIR_CONF_LIST;
NEXT;
SKIP_BLANKS;
SKIP_BLANKS_AND_EOL;
if ((ctxt->cur < ctxt->end) && (CUR != ']')) {
lst = virConfParseValue(ctxt);
SKIP_BLANKS;
SKIP_BLANKS_AND_EOL;
}
while ((ctxt->cur < ctxt->end) && (CUR != ']')) {
if (CUR != ',') {
@ -455,7 +453,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
return(NULL);
}
NEXT;
SKIP_BLANKS;
SKIP_BLANKS_AND_EOL;
if (CUR == ']') {
break;
}
@ -467,7 +465,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
prev = lst;
while (prev->next != NULL) prev = prev->next;
prev->next = tmp;
SKIP_BLANKS;
SKIP_BLANKS_AND_EOL;
}
if (CUR == ']') {
NEXT;
@ -477,7 +475,7 @@ virConfParseValue(virConfParserCtxtPtr ctxt)
virConfFreeList(lst);
return(NULL);
}
} else if (IS_DIGIT(CUR) || (CUR == '-') || (CUR == '+')) {
} else if (c_isdigit(CUR) || (CUR == '-') || (CUR == '+')) {
if (virConfParseLong(ctxt, &l) < 0) {
return(NULL);
}
@ -514,14 +512,14 @@ virConfParseName(virConfParserCtxtPtr ctxt)
const char *base;
char *ret;
SKIP_SPACES;
SKIP_BLANKS;
base = ctxt->cur;
/* TODO: probably need encoding support and UTF-8 parsing ! */
if (!IS_CHAR(CUR)) {
if (!c_isalpha(CUR)) {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting a name"), ctxt->line);
return(NULL);
}
while ((ctxt->cur < ctxt->end) && ((IS_CHAR(CUR)) || (IS_DIGIT(CUR)) || (CUR == '_')))
while ((ctxt->cur < ctxt->end) && (c_isalnum(CUR) || (CUR == '_')))
NEXT;
ret = strndup(base, ctxt->cur - base);
if (ret == NULL) {
@ -572,14 +570,14 @@ virConfParseComment(virConfParserCtxtPtr ctxt)
static int
virConfParseSeparator(virConfParserCtxtPtr ctxt)
{
SKIP_SPACES;
SKIP_BLANKS;
if (ctxt->cur >= ctxt->end)
return(0);
if (IS_EOL(CUR)) {
SKIP_BLANKS
SKIP_BLANKS_AND_EOL;
} else if (CUR == ';') {
NEXT;
SKIP_BLANKS;
SKIP_BLANKS_AND_EOL;
} else {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting a separator"),
ctxt->line);
@ -604,27 +602,27 @@ virConfParseStatement(virConfParserCtxtPtr ctxt)
virConfValuePtr value;
char *comm = NULL;
SKIP_BLANKS;
SKIP_BLANKS_AND_EOL;
if (CUR == '#') {
return(virConfParseComment(ctxt));
}
name = virConfParseName(ctxt);
if (name == NULL)
return(-1);
SKIP_SPACES;
SKIP_BLANKS;
if (CUR != '=') {
virConfError(NULL, VIR_ERR_CONF_SYNTAX, _("expecting an assignment"),
ctxt->line);
return(-1);
}
NEXT;
SKIP_SPACES;
SKIP_BLANKS;
value = virConfParseValue(ctxt);
if (value == NULL) {
free(name);
return(-1);
}
SKIP_SPACES;
SKIP_BLANKS;
if (CUR == '#') {
NEXT;
base = ctxt->cur;

View File

@ -27,7 +27,7 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <c-ctype.h>
#include "c-ctype.h"
#ifdef HAVE_SYS_UTSNAME_H
#include <sys/utsname.h>

View File

@ -49,7 +49,8 @@
#include "buf.h"
#include "conf.h"
#include "util.h"
#include <verify.h>
#include "verify.h"
#include "c-ctype.h"
#define qemudLog(level, msg...) fprintf(stderr, msg)
@ -1007,7 +1008,7 @@ static int qemudParseInterfaceXML(virConnectPtr conn,
* i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio
*/
if (model != NULL) {
int i, len, char_ok;
int i, len;
len = xmlStrlen (model);
if (len >= QEMUD_MODEL_MAX_LEN) {
@ -1016,10 +1017,7 @@ static int qemudParseInterfaceXML(virConnectPtr conn,
goto error;
}
for (i = 0; i < len; ++i) {
char_ok =
(model[i] >= '0' && model[i] <= '9') ||
(model[i] >= 'a' && model[i] <= 'z') ||
(model[i] >= 'A' && model[i] <= 'Z') || model[i] == '_';
int char_ok = c_isalnum(model[i]) || model[i] == '_';
if (!char_ok) {
qemudReportError (conn, NULL, NULL, VIR_ERR_INVALID_ARG, "%s",
_("Model name contains invalid characters"));

View File

@ -41,7 +41,6 @@
#include <fcntl.h>
#include <signal.h>
#include <paths.h>
#include <c-ctype.h>
#include <pwd.h>
#include <stdio.h>
#include <sys/wait.h>
@ -49,6 +48,7 @@
#include "libvirt/virterror.h"
#include "c-ctype.h"
#include "event.h"
#include "buf.h"
#include "util.h"
@ -2650,12 +2650,12 @@ qemudDomainBlockStats (virDomainPtr dom,
* cdrom to ide1-cd0
* fd[a-] to floppy[0-]
*/
if (STRPREFIX (path, "hd") && path[2] >= 'a' && path[2] <= 'z')
if (STRPREFIX (path, "hd") && c_islower(path[2]))
snprintf (qemu_dev_name, sizeof (qemu_dev_name),
"ide0-hd%d", path[2] - 'a');
else if (STREQ (path, "cdrom"))
strcpy (qemu_dev_name, "ide1-cd0");
else if (STRPREFIX (path, "fd") && path[2] >= 'a' && path[2] <= 'z')
else if (STRPREFIX (path, "fd") && c_islower(path[2]))
snprintf (qemu_dev_name, sizeof (qemu_dev_name),
"floppy%d", path[2] - 'a');
else {

View File

@ -15,7 +15,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <c-ctype.h>
#include "c-ctype.h"
#include <errno.h>
#include "internal.h"

View File

@ -18,7 +18,7 @@
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <c-ctype.h>
#include "c-ctype.h"
#ifdef WITH_XEN
#include <xs.h>

View File

@ -37,7 +37,7 @@
#include <sys/wait.h>
#endif
#include <string.h>
#include <c-ctype.h>
#include "c-ctype.h"
#ifdef HAVE_PATHS_H
#include <paths.h>
@ -681,7 +681,7 @@ virParseNumber(const char **str)
if ((*cur < '0') || (*cur > '9'))
return (-1);
while ((*cur >= '0') && (*cur <= '9')) {
while (c_isdigit(*cur)) {
unsigned int c = *cur - '0';
if ((ret > INT_MAX / 10) ||
@ -794,7 +794,7 @@ int virDiskNameToIndex(const char *name) {
while (*ptr) {
idx = idx * 26;
if ('a' > *ptr || 'z' < *ptr)
if (!c_islower(*ptr))
return -1;
idx += *ptr - 'a';

View File

@ -32,6 +32,7 @@
#include <time.h>
#include <unistd.h>
#include "c-ctype.h"
#include "internal.h"
#define qemudLog(level, msg...) fprintf(stderr, msg)
@ -105,6 +106,22 @@ virUUIDGenerate(unsigned char *uuid)
return virUUIDGeneratePseudoRandomBytes(uuid, VIR_UUID_BUFLEN);
}
/* Convert C from hexadecimal character to integer. */
static int
hextobin (unsigned char c)
{
switch (c)
{
default: return c - '0';
case 'a': case 'A': return 10;
case 'b': case 'B': return 11;
case 'c': case 'C': return 12;
case 'd': case 'D': return 13;
case 'e': case 'E': return 14;
case 'f': case 'F': return 15;
}
}
/**
* virUUIDParse:
* @uuidstr: zero terminated string representation of the UUID
@ -136,26 +153,16 @@ virUUIDParse(const char *uuidstr, unsigned char *uuid) {
cur++;
continue;
}
if ((*cur >= '0') && (*cur <= '9'))
uuid[i] = *cur - '0';
else if ((*cur >= 'a') && (*cur <= 'f'))
uuid[i] = *cur - 'a' + 10;
else if ((*cur >= 'A') && (*cur <= 'F'))
uuid[i] = *cur - 'A' + 10;
else
if (!c_isxdigit(*cur))
goto error;
uuid[i] = hextobin(*cur);
uuid[i] *= 16;
cur++;
if (*cur == 0)
goto error;
if ((*cur >= '0') && (*cur <= '9'))
uuid[i] += *cur - '0';
else if ((*cur >= 'a') && (*cur <= 'f'))
uuid[i] += *cur - 'a' + 10;
else if ((*cur >= 'A') && (*cur <= 'F'))
uuid[i] += *cur - 'A' + 10;
else
if (!c_isxdigit(*cur))
goto error;
uuid[i] += hextobin(*cur);
i++;
cur++;
}

View File

@ -26,7 +26,7 @@
#include <getopt.h>
#include <sys/types.h>
#include <sys/time.h>
#include <c-ctype.h>
#include "c-ctype.h"
#include <fcntl.h>
#include <locale.h>
#include <time.h>

View File

@ -76,10 +76,10 @@ parseCpuNumber(const char **str, int maxcpu)
int ret = 0;
const char *cur = *str;
if ((*cur < '0') || (*cur > '9'))
if (!c_isdigit(*cur))
return (-1);
while ((*cur >= '0') && (*cur <= '9')) {
while (c_isdigit(*cur)) {
ret = ret * 10 + (*cur - '0');
if (ret >= maxcpu)
return (-1);
@ -197,7 +197,7 @@ virParseCpuSet(virConnectPtr conn, const char **str, char sep,
neg = 1;
}
if ((*cur < '0') || (*cur > '9'))
if (!c_isdigit(*cur))
goto parse_error;
start = parseCpuNumber(&cur, maxcpu);
if (start < 0)