add ptql error messages
This commit is contained in:
parent
b3d43367ef
commit
c2f6979c7e
|
@ -1226,23 +1226,16 @@ JNIEXPORT void SIGAR_JNI(ptql_SigarProcessQuery_create)
|
|||
jboolean is_copy;
|
||||
const char *ptql;
|
||||
sigar_ptql_query_t *query;
|
||||
sigar_ptql_error_t error;
|
||||
|
||||
ptql = JENV->GetStringUTFChars(env, jptql, &is_copy);
|
||||
status = sigar_ptql_query_create(&query, (char *)ptql);
|
||||
status = sigar_ptql_query_create(&query, (char *)ptql, &error);
|
||||
if (is_copy) {
|
||||
JENV->ReleaseStringUTFChars(env, jptql, ptql);
|
||||
}
|
||||
|
||||
if (status != SIGAR_OK) {
|
||||
char buf[1024], *msg=buf;
|
||||
if (status == SIGAR_PTQL_MALFORMED_QUERY) {
|
||||
msg = "Malformed query";
|
||||
}
|
||||
else {
|
||||
sigar_strerror_get(status, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
sigar_throw_ptql_malformed(env, msg);
|
||||
sigar_throw_ptql_malformed(env, error.message);
|
||||
}
|
||||
else {
|
||||
sigar_set_pointer(env, obj, query);
|
||||
|
|
|
@ -94,7 +94,8 @@ public class TestPTQL extends SigarTestCase {
|
|||
"Statex.Name.eq=foo",
|
||||
"State.Name.eqx=foo",
|
||||
"State.Name.Xeq=foo",
|
||||
"State.Name.eq=$2",
|
||||
"State.Name.eq=foo,Args.*.eq=$3",
|
||||
"State.Name.eq=$1",
|
||||
"State.State.eq=read",
|
||||
"Args.x.eq=foo",
|
||||
"Time.Sys.gt=x",
|
||||
|
@ -102,6 +103,7 @@ public class TestPTQL extends SigarTestCase {
|
|||
"Cpu.Percent.ge=x",
|
||||
"Port.foo.eq=8080",
|
||||
"Port.tcp.gt=8080",
|
||||
"Port.tcp.eq=http",
|
||||
"Cpu.Sys.ew=lots",
|
||||
"",
|
||||
null,
|
||||
|
|
|
@ -23,13 +23,20 @@
|
|||
|
||||
typedef struct sigar_ptql_query_t sigar_ptql_query_t;
|
||||
|
||||
#define SIGAR_PTQL_ERRMSG_SIZE 1024
|
||||
|
||||
typedef struct {
|
||||
char message[SIGAR_PTQL_ERRMSG_SIZE];
|
||||
} sigar_ptql_error_t;
|
||||
|
||||
typedef int (*sigar_ptql_re_impl_t)(void *, char *, char *);
|
||||
|
||||
SIGAR_DECLARE(void) sigar_ptql_re_impl_set(sigar_t *sigar, void *data,
|
||||
sigar_ptql_re_impl_t impl);
|
||||
|
||||
SIGAR_DECLARE(int) sigar_ptql_query_create(sigar_ptql_query_t **query,
|
||||
char *ptql);
|
||||
char *ptql,
|
||||
sigar_ptql_error_t *error);
|
||||
|
||||
SIGAR_DECLARE(int) sigar_ptql_query_match(sigar_t *sigar,
|
||||
sigar_ptql_query_t *query,
|
||||
|
|
118
src/sigar_ptql.c
118
src/sigar_ptql.c
|
@ -22,6 +22,8 @@
|
|||
#include "sigar_ptql.h"
|
||||
#include "sigar_os.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SIGAR_HAS_PCRE
|
||||
#include "pcre.h"
|
||||
#endif
|
||||
|
@ -49,7 +51,8 @@ typedef struct ptql_branch_t ptql_branch_t;
|
|||
#endif
|
||||
|
||||
typedef int (SIGAPI *ptql_get_t)(sigar_t *sigar, sigar_pid_t pid, void *data);
|
||||
typedef int (*ptql_branch_init_t)(ptql_parse_branch_t *parsed, ptql_branch_t *branch);
|
||||
typedef int (*ptql_branch_init_t)(ptql_parse_branch_t *parsed, ptql_branch_t *branch,
|
||||
sigar_ptql_error_t *error);
|
||||
|
||||
typedef int (*ptql_op_ui64_t)(ptql_branch_t *branch,
|
||||
sigar_uint64_t haystack,
|
||||
|
@ -535,8 +538,29 @@ static int ptql_branch_list_destroy(ptql_branch_list_t *branches)
|
|||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
#define PTQL_ERRNAN \
|
||||
ptql_error(error, "Query value '%s' is not a number", parsed->value)
|
||||
|
||||
static int ptql_error(sigar_ptql_error_t *error, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (error != NULL) {
|
||||
va_start(args, format);
|
||||
vsnprintf(error->message, sizeof(error->message), format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
}
|
||||
|
||||
static int ptql_branch_init_any(ptql_parse_branch_t *parsed,
|
||||
ptql_branch_t *branch)
|
||||
ptql_branch_t *branch,
|
||||
sigar_ptql_error_t *error)
|
||||
{
|
||||
branch->data.str = sigar_strdup(parsed->attr);
|
||||
branch->data_size = strlen(parsed->attr);
|
||||
|
@ -641,7 +665,8 @@ enum {
|
|||
#endif
|
||||
|
||||
static int ptql_branch_init_pid(ptql_parse_branch_t *parsed,
|
||||
ptql_branch_t *branch)
|
||||
ptql_branch_t *branch,
|
||||
sigar_ptql_error_t *error)
|
||||
{
|
||||
branch->op_flags |= PTQL_OP_FLAG_PID;
|
||||
|
||||
|
@ -654,7 +679,7 @@ static int ptql_branch_init_pid(ptql_parse_branch_t *parsed,
|
|||
char *ptr;
|
||||
branch->data.pid = str2pid(parsed->value, ptr);
|
||||
if (strtonum_failed(parsed->value, ptr)) {
|
||||
return EINVAL;
|
||||
return PTQL_ERRNAN;
|
||||
}
|
||||
}
|
||||
return SIGAR_OK;
|
||||
|
@ -672,10 +697,10 @@ static int ptql_branch_init_pid(ptql_parse_branch_t *parsed,
|
|||
branch->data_size = strlen(parsed->value);
|
||||
#endif
|
||||
return SIGAR_OK;
|
||||
|
||||
}
|
||||
else {
|
||||
return EINVAL;
|
||||
return ptql_error(error, "Unsupported %s attribute: %s",
|
||||
parsed->name, parsed->attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -738,7 +763,8 @@ static int SIGAPI ptql_pid_match(sigar_t *sigar,
|
|||
}
|
||||
|
||||
static int ptql_args_branch_init(ptql_parse_branch_t *parsed,
|
||||
ptql_branch_t *branch)
|
||||
ptql_branch_t *branch,
|
||||
sigar_ptql_error_t *error)
|
||||
{
|
||||
if (strEQ(parsed->attr, "*")) {
|
||||
branch->op_flags |= PTQL_OP_FLAG_GLOB;
|
||||
|
@ -751,7 +777,7 @@ static int ptql_args_branch_init(ptql_parse_branch_t *parsed,
|
|||
|
||||
if (strtonum_failed(parsed->attr, end)) {
|
||||
/* conversion failed */
|
||||
return errno;
|
||||
return ptql_error(error, "%s is not a number", parsed->attr);
|
||||
}
|
||||
}
|
||||
return SIGAR_OK;
|
||||
|
@ -861,11 +887,15 @@ static int SIGAPI ptql_env_match(sigar_t *sigar,
|
|||
}
|
||||
|
||||
static int ptql_branch_init_port(ptql_parse_branch_t *parsed,
|
||||
ptql_branch_t *branch)
|
||||
ptql_branch_t *branch,
|
||||
sigar_ptql_error_t *error)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
/* only 'eq' is supported here */
|
||||
if (branch->op_name != PTQL_OP_EQ) {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "%s requires 'eq' operator",
|
||||
parsed->name);
|
||||
}
|
||||
|
||||
if (strEQ(parsed->attr, "tcp")) {
|
||||
|
@ -875,10 +905,14 @@ static int ptql_branch_init_port(ptql_parse_branch_t *parsed,
|
|||
branch->flags = SIGAR_NETCONN_UDP;
|
||||
}
|
||||
else {
|
||||
return EINVAL;
|
||||
return ptql_error(error, "Unsupported %s protocol: %s",
|
||||
parsed->name, parsed->attr);
|
||||
}
|
||||
|
||||
branch->data.ui32 = atoi(parsed->value); /*XXX*/
|
||||
branch->data.ui32 = strtoul(parsed->value, &ptr, 10);
|
||||
if (strtonum_failed(parsed->value, ptr)) {
|
||||
return PTQL_ERRNAN;
|
||||
}
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
@ -1011,11 +1045,12 @@ static ptql_entry_t ptql_map[] = {
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
static int ptql_branch_parse(char *query, ptql_parse_branch_t *branch)
|
||||
static int ptql_branch_parse(char *query, ptql_parse_branch_t *branch,
|
||||
sigar_ptql_error_t *error)
|
||||
{
|
||||
char *ptr = strchr(query, '=');
|
||||
if (!ptr) {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Missing '='");
|
||||
}
|
||||
|
||||
branch->op_flags = 0;
|
||||
|
@ -1029,7 +1064,7 @@ static int ptql_branch_parse(char *query, ptql_parse_branch_t *branch)
|
|||
query = ++ptr;
|
||||
}
|
||||
else {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Missing '.'");
|
||||
}
|
||||
|
||||
if ((ptr = strchr(query, '.'))) {
|
||||
|
@ -1038,7 +1073,7 @@ static int ptql_branch_parse(char *query, ptql_parse_branch_t *branch)
|
|||
query = ++ptr;
|
||||
}
|
||||
else {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Missing '.'");
|
||||
}
|
||||
|
||||
if (*query) {
|
||||
|
@ -1050,7 +1085,7 @@ static int ptql_branch_parse(char *query, ptql_parse_branch_t *branch)
|
|||
branch->op_flags |= PTQL_OP_FLAG_PARENT;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
return ptql_error(error, "Unsupported modifier: %c", flag);
|
||||
}
|
||||
|
||||
++query;
|
||||
|
@ -1059,14 +1094,15 @@ static int ptql_branch_parse(char *query, ptql_parse_branch_t *branch)
|
|||
branch->op = query;
|
||||
}
|
||||
else {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Missing query");
|
||||
}
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
||||
ptql_branch_list_t *branches)
|
||||
ptql_branch_list_t *branches,
|
||||
sigar_ptql_error_t *error)
|
||||
{
|
||||
ptql_branch_t *branch;
|
||||
ptql_entry_t *entry = NULL;
|
||||
|
@ -1084,7 +1120,7 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
|
||||
branch->op_name = ptql_op_code_get(parsed->op);
|
||||
if (branch->op_name == PTQL_OP_MAX) {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Unsupported operator: %s", parsed->op);
|
||||
}
|
||||
|
||||
for (i=0; ptql_map[i].name; i++) {
|
||||
|
@ -1095,7 +1131,7 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
}
|
||||
|
||||
if (!entry) {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Unsupported method: %s", parsed->name);
|
||||
}
|
||||
|
||||
for (i=0; entry->members[i].name; i++) {
|
||||
|
@ -1111,12 +1147,13 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
lookup = &entry->members[0];
|
||||
}
|
||||
else {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Unsupported %s attribute: %s",
|
||||
parsed->name, parsed->attr);
|
||||
}
|
||||
}
|
||||
|
||||
if (lookup->init) {
|
||||
int status = lookup->init(parsed, branch);
|
||||
int status = lookup->init(parsed, branch, error);
|
||||
if (status != SIGAR_OK) {
|
||||
return status;
|
||||
}
|
||||
|
@ -1127,7 +1164,8 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
if ((lookup->type < PTQL_VALUE_TYPE_STR) &&
|
||||
(branch->op_name > PTQL_OP_MAX_NSTR))
|
||||
{
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Unsupported operator '%s' for %s.%s",
|
||||
parsed->op, parsed->name, parsed->attr);
|
||||
}
|
||||
|
||||
if (*parsed->value == '$') {
|
||||
|
@ -1135,7 +1173,8 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
|
||||
if (branch->op_name == PTQL_OP_RE) {
|
||||
/* not for use with .re */
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Unsupported operator '%s' with variable %s",
|
||||
parsed->op, parsed->value);
|
||||
}
|
||||
|
||||
if (sigar_isdigit(*(parsed->value+1))) {
|
||||
|
@ -1145,11 +1184,13 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
|
||||
if (branch->value.ui32 >= branches->number) {
|
||||
/* out-of-range */
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Variable %s out of range (%d)",
|
||||
parsed->value, branches->number);
|
||||
}
|
||||
else if (branch->value.ui32 == branches->number-1) {
|
||||
/* self reference */
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "Variable %s self reference",
|
||||
parsed->value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1169,7 +1210,8 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
pcre_compile(parsed->value, 0,
|
||||
&error, &offset, NULL);
|
||||
if (!re) {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
/* XXX pcre_error ? */
|
||||
return ptql_error(error, "Invalid regex");
|
||||
}
|
||||
is_set = 1;
|
||||
branch->value.ptr = re;
|
||||
|
@ -1183,7 +1225,7 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
if (!is_set) {
|
||||
branch->value.ui64 = strtoull(parsed->value, &ptr, 10);
|
||||
if (strtonum_failed(parsed->value, ptr)) {
|
||||
return errno;
|
||||
return PTQL_ERRNAN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1192,7 +1234,7 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
if (!is_set) {
|
||||
branch->value.ui32 = strtoul(parsed->value, &ptr, 10);
|
||||
if (strtonum_failed(parsed->value, ptr)) {
|
||||
return errno;
|
||||
return PTQL_ERRNAN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1201,7 +1243,7 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
if (!is_set) {
|
||||
branch->value.dbl = strtod(parsed->value, &ptr);
|
||||
if (strtonum_failed(parsed->value, ptr)) {
|
||||
return errno;
|
||||
return PTQL_ERRNAN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1209,7 +1251,7 @@ static int ptql_branch_add(ptql_parse_branch_t *parsed,
|
|||
branch->match.chr = ptql_op_chr[branch->op_name];
|
||||
if (!is_set) {
|
||||
if (strlen(parsed->value) != 1) {
|
||||
return SIGAR_PTQL_MALFORMED_QUERY;
|
||||
return ptql_error(error, "%s is not a char", parsed->value);
|
||||
}
|
||||
branch->value.chr[0] = parsed->value[0];
|
||||
}
|
||||
|
@ -1237,7 +1279,8 @@ static int ptql_branch_compare(const void *b1, const void *b2)
|
|||
}
|
||||
|
||||
SIGAR_DECLARE(int) sigar_ptql_query_create(sigar_ptql_query_t **queryp,
|
||||
char *ptql)
|
||||
char *ptql,
|
||||
sigar_ptql_error_t *error)
|
||||
{
|
||||
char *ptr, *ptql_copy = sigar_strdup(ptql);
|
||||
int status = SIGAR_OK;
|
||||
|
@ -1245,6 +1288,8 @@ SIGAR_DECLARE(int) sigar_ptql_query_create(sigar_ptql_query_t **queryp,
|
|||
sigar_ptql_query_t *query =
|
||||
*queryp = malloc(sizeof(*query));
|
||||
|
||||
(void)ptql_error(error, "Malformed query");
|
||||
|
||||
#ifdef PTQL_DEBUG
|
||||
query->ptql = sigar_strdup(ptql);
|
||||
#endif
|
||||
|
@ -1260,10 +1305,10 @@ SIGAR_DECLARE(int) sigar_ptql_query_create(sigar_ptql_query_t **queryp,
|
|||
*ptr = '\0';
|
||||
}
|
||||
|
||||
status = ptql_branch_parse(ptql, &parsed);
|
||||
status = ptql_branch_parse(ptql, &parsed, error);
|
||||
if (status == SIGAR_OK) {
|
||||
status =
|
||||
ptql_branch_add(&parsed, &query->branches);
|
||||
ptql_branch_add(&parsed, &query->branches, error);
|
||||
|
||||
if (status != SIGAR_OK) {
|
||||
break;
|
||||
|
@ -1297,6 +1342,9 @@ SIGAR_DECLARE(int) sigar_ptql_query_create(sigar_ptql_query_t **queryp,
|
|||
ptql_branch_compare);
|
||||
}
|
||||
|
||||
if (status == SIGAR_OK) {
|
||||
(void)ptql_error(error, "OK");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue