Refactor the code a little bit to reduce duplicated code.

Reviewed by:	mjg
MFC after:	2 weeks
This commit is contained in:
Xin LI 2014-09-26 05:05:34 +00:00
parent 663222b9f6
commit e267e00eef

View File

@ -57,6 +57,7 @@ static const char rcsid[] =
#include <machine/pc/bios.h>
#endif
#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
@ -80,7 +81,31 @@ static int show_var(int *, int);
static int sysctl_all(int *oid, int len);
static int name2oid(const char *, int *);
static int set_IK(const char *, int *);
static int strIKtoi(const char *, char **);
static int ctl_sign[CTLTYPE+1] = {
[CTLTYPE_INT] = 1,
[CTLTYPE_LONG] = 1,
[CTLTYPE_S64] = 1,
};
static int ctl_size[CTLTYPE+1] = {
[CTLTYPE_INT] = sizeof(int),
[CTLTYPE_UINT] = sizeof(u_int),
[CTLTYPE_LONG] = sizeof(long),
[CTLTYPE_ULONG] = sizeof(u_long),
[CTLTYPE_S64] = sizeof(int64_t),
[CTLTYPE_U64] = sizeof(uint64_t),
};
static const char *ctl_typename[CTLTYPE+1] = {
[CTLTYPE_INT] = "integer",
[CTLTYPE_UINT] = "unsigned integer",
[CTLTYPE_LONG] = "long integer",
[CTLTYPE_ULONG] = "unsigned long",
[CTLTYPE_S64] = "int64_t",
[CTLTYPE_U64] = "uint64_t",
};
static void
usage(void)
@ -191,7 +216,8 @@ static int
parse(const char *string, int lineno)
{
int len, i, j;
void *newval = 0;
const void *newval;
const char *newvalstr = NULL;
int intval;
unsigned int uintval;
long longval;
@ -200,7 +226,7 @@ parse(const char *string, int lineno)
int64_t i64val;
uint64_t u64val;
int mib[CTL_MAXNAME];
char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ], line[BUFSIZ];
char *cp, *bufp, buf[BUFSIZ], *endptr = NULL, fmt[BUFSIZ], line[BUFSIZ];
u_int kind;
if (lineno)
@ -230,7 +256,7 @@ parse(const char *string, int lineno)
cp[strlen(cp) - 1] = '\0';
cp++;
}
newval = cp;
newvalstr = cp;
newsize = strlen(cp);
}
len = name2oid(bufp, mib);
@ -254,7 +280,7 @@ parse(const char *string, int lineno)
exit(1);
}
if (newval == NULL || dflag) {
if (newvalstr == NULL || dflag) {
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
if (dflag) {
i = show_var(mib, len);
@ -282,105 +308,77 @@ parse(const char *string, int lineno)
return (1);
}
if ((kind & CTLTYPE) == CTLTYPE_INT ||
(kind & CTLTYPE) == CTLTYPE_UINT ||
(kind & CTLTYPE) == CTLTYPE_LONG ||
(kind & CTLTYPE) == CTLTYPE_ULONG ||
(kind & CTLTYPE) == CTLTYPE_S64 ||
(kind & CTLTYPE) == CTLTYPE_U64) {
if (strlen(newval) == 0) {
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
case CTLTYPE_UINT:
case CTLTYPE_LONG:
case CTLTYPE_ULONG:
case CTLTYPE_S64:
case CTLTYPE_U64:
if (strlen(newvalstr) == 0) {
warnx("empty numeric value");
return (1);
}
/* FALLTHROUGH */
case CTLTYPE_STRING:
break;
default:
warnx("oid '%s' is type %d,"
" cannot set that%s", bufp,
kind & CTLTYPE, line);
return (1);
}
errno = 0;
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
if (strcmp(fmt, "IK") == 0) {
if (!set_IK(newval, &intval)) {
warnx("invalid value '%s'%s",
(char *)newval, line);
return (1);
}
} else {
intval = (int)strtol(newval, &endptr,
if (strcmp(fmt, "IK") == 0)
intval = strIKtoi(newvalstr, &endptr);
else
intval = (int)strtol(newvalstr, &endptr,
0);
if (errno != 0 || endptr == newval ||
*endptr != '\0') {
warnx("invalid integer '%s'%s",
(char *)newval, line);
return (1);
}
}
newval = &intval;
newsize = sizeof(intval);
break;
case CTLTYPE_UINT:
uintval = (int) strtoul(newval, &endptr, 0);
if (errno != 0 || endptr == newval ||
*endptr != '\0') {
warnx("invalid unsigned integer '%s'%s",
(char *)newval, line);
return (1);
}
uintval = (int) strtoul(newvalstr, &endptr, 0);
newval = &uintval;
newsize = sizeof(uintval);
break;
case CTLTYPE_LONG:
longval = strtol(newval, &endptr, 0);
if (errno != 0 || endptr == newval ||
*endptr != '\0') {
warnx("invalid long integer '%s'%s",
(char *)newval, line);
return (1);
}
longval = strtol(newvalstr, &endptr, 0);
newval = &longval;
newsize = sizeof(longval);
break;
case CTLTYPE_ULONG:
ulongval = strtoul(newval, &endptr, 0);
if (errno != 0 || endptr == newval ||
*endptr != '\0') {
warnx("invalid unsigned long integer"
" '%s'%s", (char *)newval, line);
return (1);
}
ulongval = strtoul(newvalstr, &endptr, 0);
newval = &ulongval;
newsize = sizeof(ulongval);
break;
case CTLTYPE_STRING:
newval = newvalstr;
break;
case CTLTYPE_S64:
i64val = strtoimax(newval, &endptr, 0);
if (errno != 0 || endptr == newval ||
*endptr != '\0') {
warnx("invalid int64_t '%s'%s",
(char *)newval, line);
return (1);
}
i64val = strtoimax(newvalstr, &endptr, 0);
newval = &i64val;
newsize = sizeof(i64val);
break;
case CTLTYPE_U64:
u64val = strtoumax(newval, &endptr, 0);
if (errno != 0 || endptr == newval ||
*endptr != '\0') {
warnx("invalid uint64_t '%s'%s",
(char *)newval, line);
return (1);
}
u64val = strtoumax(newvalstr, &endptr, 0);
newval = &u64val;
newsize = sizeof(u64val);
break;
case CTLTYPE_OPAQUE:
/* FALLTHROUGH */
default:
warnx("oid '%s' is type %d,"
" cannot set that%s", bufp,
kind & CTLTYPE, line);
return (1);
/* NOTREACHED */
abort();
}
if (errno != 0 || endptr == newvalstr ||
(endptr != NULL && *endptr != '\0')) {
warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE],
newvalstr, line);
return (1);
}
i = show_var(mib, len);
@ -665,33 +663,35 @@ S_bios_smap_xattr(size_t l2, void *p)
#endif
static int
set_IK(const char *str, int *val)
strIKtoi(const char *str, char **endptrp)
{
int kelv;
float temp;
int len, kelv;
size_t len;
const char *p;
char *endptr;
if ((len = strlen(str)) == 0)
return (0);
assert(errno == 0);
len = strlen(str);
/* caller already checked this */
assert(len > 0);
p = &str[len - 1];
errno = 0;
if (*p == 'C' || *p == 'F') {
temp = strtof(str, &endptr);
if (errno != 0 || endptr == str ||
endptr != p)
return (0);
if (*p == 'F')
temp = (temp - 32) * 5 / 9;
kelv = temp * 10 + 2732;
temp = strtof(str, endptrp);
if (*endptrp != str && *endptrp == p && errno != 0) {
if (*p == 'F')
temp = (temp - 32) * 5 / 9;
return (temp * 10 + 2732);
}
} else {
kelv = (int)strtol(str, &endptr, 10);
if (errno != 0 || endptr == str ||
*endptr != '\0')
return (0);
kelv = (int)strtol(str, endptrp, 10);
if (*endptrp != str && *endptrp == p && errno != 0)
return (kelv);
}
*val = kelv;
return (1);
errno = ERANGE;
return (0);
}
/*
@ -746,21 +746,6 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
return (0);
}
static int ctl_sign[CTLTYPE+1] = {
[CTLTYPE_INT] = 1,
[CTLTYPE_LONG] = 1,
[CTLTYPE_S64] = 1,
};
static int ctl_size[CTLTYPE+1] = {
[CTLTYPE_INT] = sizeof(int),
[CTLTYPE_UINT] = sizeof(u_int),
[CTLTYPE_LONG] = sizeof(long),
[CTLTYPE_ULONG] = sizeof(u_long),
[CTLTYPE_S64] = sizeof(int64_t),
[CTLTYPE_U64] = sizeof(int64_t),
};
/*
* This formats and outputs the value of one variable
*