/*
* Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/types.h>
#include "event-parse.h"
#include "event-utils.h"
#define COMM "COMM"
static struct format_field comm = {
.name = "COMM",
};
struct event_list {
struct event_list *next;
struct event_format *event;
};
#define MAX_ERR_STR_SIZE 256
static void show_error(char **error_str, const char *fmt, ...)
{
unsigned long long index;
const char *input;
char *error;
va_list ap;
int len;
int i;
if (!error_str)
return;
input = pevent_get_input_buf();
index = pevent_get_input_buf_ptr();
len = input ? strlen(input) : 0;
error = malloc_or_die(MAX_ERR_STR_SIZE + (len*2) + 3);
if (len) {
strcpy(error, input);
error[len] = '\n';
for (i = 1; i < len && i < index; i++)
error[len+i] = ' ';
error[len + i] = '^';
error[len + i + 1] = '\n';
len += i+2;
}
va_start(ap, fmt);
vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap);
va_end(ap);
*error_str = error;
}
static void free_token(char *token)
{
pevent_free_token(token);
}
static enum event_type read_token(char **tok)
{
enum event_type type;
char *token = NULL;
do {
free_token(token);
type = pevent_read_token(&token);
} while (type == EVENT_NEWLINE || type == EVENT_SPACE);
/* If token is = or ! check to see if the next char is ~ */
if (token &&
(strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
pevent_peek_char() == '~') {
/* append it */
*tok = malloc_or_die(3);
sprintf(*tok, "%c%c", *token, '~');
free_token(token);
/* Now remove the '~' from the buffer */
pevent_read_token(&token);
free_token(token);
} else
*tok = token;
return type;
}
static int filter_cmp(const void *a, const void *b)
{
const struct filter_type *ea = a;
const struct filter_type *eb = b;
if (ea->event_id < eb->event_id)
return -1;
if (ea->event_id > eb->event_id)
return 1;
return 0;
}
static struct filter_type *
find_filter_type(struct event_filter *filter, int id)
{
struct filter_type *filter_type;
struct filter_type key;
key.event_id = id;
filter_type = bsearch(&key, filter->event_filters,
filter->filters,
sizeof(*filter->event_filters),
filter_cmp);
return filter_type;
}
static struct filter_type *
add_filter_type(struct event_filter *filter, int id)
{
struct filter_type *filter_type;
int i;
filter_type = find_filter_type(filter, id);
if (filter_type)
return filter_type;
filter->event_filters = realloc(filter->event_filters,
sizeof(*filter->event_filters) *
(filter->filters + 1));
if (!filter->event_filters)
die("Could not allocate filter");
for (i = 0; i < filter->filters; i++) {
if (filter->event_filters[i].event_id > id)
break;
}
if (i < filter->filters)
memmove(&filter->event_filters[i+1],
&filter->event_filters[i],
sizeof(*filter->event_filters) *
(filter->filters - i));
filter_type = &filter->event_filters[i];
filter_type->event_id = id;
filter_type->event = pevent_find_event(filter->pevent, id);
filter_type->filter = NULL;
filter->filters++;
return filter_type;
}
/**
* pevent_filter_alloc - create a new event filter
* @pevent: The pevent that this filter is associated with
*/
struct event_filter *pevent_filter_alloc(struct pevent *pevent)
{
struct event_filter *filter;
filter = malloc_or_die(sizeof(*filter));
memset(filter, 0, sizeof(*filter));
filter->pevent = pevent;
pevent_ref(pevent);
return filter;
}
static struct filter_arg *allocate_arg(void)
{
struct filter_arg *arg;
arg = malloc_or_die(sizeof(*arg));
memset(arg, 0, sizeof(*arg));
return arg;
}
static void free_arg(struct filter_arg *arg)
{
if (!arg)
return;
switch (arg->type) {
case FILTER_ARG_NONE:
case FILTER_ARG_BOOLEAN:
break;
case FILTER_ARG_NUM:
free_arg(arg->num.left);
free_arg(arg->num.right);
break;
case FILTER_ARG_EXP:
free_arg(arg->exp.left);
free_arg(arg->exp.right);
break;
case FILTER_ARG_STR:
free(arg->str.val);
regfree(&arg->str.reg);
free(arg->str.buffer);
break;
case FILTER_ARG_VALUE:
if (arg->value.type == FILTER_STRING ||
arg->value.type == FILTER_CHAR)
free(arg->value.str);
break;
case FILTER_ARG_OP:
free_arg(arg->op.left);
free_arg(arg->op.right);
default:
break;
}
free(arg);
}
static void add_event(struct event_list **events,
struct event_format *event)
{
struct event_list *list;
list = malloc_or_die(sizeof(*list));
list->next = *events;
*events = list;
list->event = event;
}
static int event_match(struct event_format *event,
regex_t *sreg, regex_t *ereg)
{
if (sreg) {
return !regexec(sreg, event->system, 0, NULL, 0) &&
!regexec(ereg, event->name, 0, NULL, 0);
}
return !regexec(ereg, event->system, 0, NULL, 0) ||
!regexec(ereg, event->name, 0, NULL, 0);
}
static int
find_event(struct pevent *pevent, struct event_list **events,
char *sys_name, char *event_name)
{
struct event_format *event;
regex_t ereg;
regex_t sreg;
int match = 0;
char *reg;
int ret;
int i;
if (!event_name) {
/* if no name is given, then swap sys and name */
event_name = sys_name;
sys_name = NULL;
}
reg = malloc_or_die(strlen(event_name) + 3);
sprintf(reg, "^%s$", event_name);
ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
free(reg);
if (ret)
return -1;
if (sys_name) {
reg = malloc_or_die(strlen(sys_name) + 3);
sprintf(reg, "^%s$", sys_name);
ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
free(reg);
if (ret) {
regfree(&ereg);
return -1;
}
}
for (i = 0; i < pevent->nr_events; i++) {
event = pevent->events[i];
if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
match = 1;
add_event(events, event);
}
}
regfree(&ereg);
if (sys_name)
regfree(&sreg);
if (!match)
return -1;
return 0;
}
static void free_events(struct event_list *events)
{
struct event_list *event;
while (events) {
event = events;
events = events->next;
free(event);
}
}
static struct filter_arg *
create_arg_item(struct event_format *event, const char *token,
enum event_type type, char **error_str)
{
struct format_field *field;
struct filter_arg *arg;
arg = allocate_arg();
switch (type) {
case EVENT_SQUOTE:
case EVENT_DQUOTE:
arg->type = FILTER_ARG_VALUE;
arg->value.type =
type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
arg->value.str = strdup(token);
if (!arg->value.str)
die("malloc string");
break;
case EVENT_ITEM:
/* if it is a number, then convert it */
if (isdigit(token[0])) {
arg->type = FILTER_ARG_VALUE;
arg->value.type = FILTER_NUMBER;
arg->value.val = strtoull(token, NULL, 0);
break;
}
/* Consider this a field */
field = pevent_find_any_field(event, token);
if (!field) {
if (strcmp(token, COMM) != 0) {
/* not a field, Make it false */
arg->type = FILTER_ARG_BOOLEAN;
arg->boolean.value = FILTER_FALSE;
break;
}
/* If token is 'COMM' then it is special */
field = &comm;
}
arg->type = FILTER_ARG_FIELD;
arg->field.field = field;
break;
default:
free_arg(arg);
show
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
parse-filter.rar (1个子文件)
parse-filter.c 48KB
共 1 条
- 1
资源评论
局外狗
- 粉丝: 78
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 9a0f3e58cbb2b13855df377b794dc336.jpg
- (源码)基于SpringBoot和Vue的停车场管理系统.zip
- 中国地质大学(武汉)地理信息系统(GIS)考试试题整理.doc
- (源码)基于Redis的内存数据库管理系统.zip
- rv1126-rv1109-add-camera-gc2053-gc4653-②
- C#.NET酒店宾馆客房管理系统源码数据库 SQL2008源码类型 WinForm
- visual-modflow-4.X使用教程.pdf
- 水仙花数的四种实现方式(C/Java/Python/JavaScript)
- (源码)基于TensorflowLite的AI狗识别系统.zip
- (源码)基于Qt框架的3D点云与模型可视化系统.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功