aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-02-17 09:52:56 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-02-17 09:52:56 -0500
commita5f716419f133132dfc6e1813aff7eb87344f526 (patch)
tree0046c5654a8fd52087232164b2764339532f7a32
parent03c370ca8b2f45fde8e8e56a59f481981b901780 (diff)
parse-events: Add pevent_filter_make_string()
Add the function pevent_filter_make_string() that will return an allocated string that translates a filter of an event. This can be used to display the defined filters back to the user. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--parse-events.h2
-rw-r--r--parse-filter.c260
2 files changed, 262 insertions, 0 deletions
diff --git a/parse-events.h b/parse-events.h
index 1573869..641aaf2 100644
--- a/parse-events.h
+++ b/parse-events.h
@@ -597,4 +597,6 @@ void pevent_filter_reset(struct event_filter *filter);
597 597
598void pevent_filter_free(struct event_filter *filter); 598void pevent_filter_free(struct event_filter *filter);
599 599
600char *pevent_filter_make_string(struct event_filter *filter, int event_id);
601
600#endif /* _PARSE_EVENTS_H */ 602#endif /* _PARSE_EVENTS_H */
diff --git a/parse-filter.c b/parse-filter.c
index 8944644..c047560 100644
--- a/parse-filter.c
+++ b/parse-filter.c
@@ -1071,3 +1071,263 @@ int pevent_filter_match(struct event_filter *filter,
1071 FILTER_MATCH : FILTER_MISS; 1071 FILTER_MATCH : FILTER_MISS;
1072} 1072}
1073 1073
1074static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg);
1075
1076static char *op_to_str(struct event_filter *filter, struct filter_arg *arg)
1077{
1078 char *str = NULL;
1079 char *left = NULL;
1080 char *right = NULL;
1081 char *op = NULL;
1082 int left_val = -1;
1083 int right_val = -1;
1084 int val;
1085 int len;
1086
1087 switch (arg->op.type) {
1088 case FILTER_OP_AND:
1089 op = "&&";
1090 /* fall through */
1091 case FILTER_OP_OR:
1092 if (!op)
1093 op = "||";
1094
1095 left = arg_to_str(filter, arg->op.left);
1096 right = arg_to_str(filter, arg->op.right);
1097 if (!left || !right)
1098 break;
1099
1100 /* Try to consolidate boolean values */
1101 if (strcmp(left, "TRUE") == 0)
1102 left_val = 1;
1103 else if (strcmp(left, "FALSE") == 0)
1104 left_val = 0;
1105
1106 if (strcmp(right, "TRUE") == 0)
1107 right_val = 1;
1108 else if (strcmp(right, "FALSE") == 0)
1109 right_val = 0;
1110
1111 if (left_val >= 0) {
1112 if ((arg->op.type == FILTER_OP_AND && !left_val) ||
1113 (arg->op.type == FILTER_OP_OR && left_val)) {
1114 /* Just return left value */
1115 str = left;
1116 left = NULL;
1117 break;
1118 }
1119 if (right_val >= 0) {
1120 /* just evaluate this. */
1121 val = 0;
1122 switch (arg->op.type) {
1123 case FILTER_OP_AND:
1124 val = left_val && right_val;
1125 break;
1126 case FILTER_OP_OR:
1127 val = left_val || right_val;
1128 break;
1129 default:
1130 break;
1131 }
1132 str = malloc_or_die(6);
1133 if (val)
1134 strcpy(str, "TRUE");
1135 else
1136 strcpy(str, "FALSE");
1137 break;
1138 }
1139 }
1140 if (right_val >= 0) {
1141 if ((arg->op.type == FILTER_OP_AND && !right_val) ||
1142 (arg->op.type == FILTER_OP_OR && right_val)) {
1143 /* Just return right value */
1144 str = right;
1145 right = NULL;
1146 break;
1147 }
1148 /* The right value is meaningless */
1149 str = left;
1150 left = NULL;
1151 break;
1152 }
1153
1154 len = strlen(left) + strlen(right) + strlen(op) + 10;
1155 str = malloc_or_die(len);
1156 snprintf(str, len, "(%s) %s (%s)",
1157 left, op, right);
1158 break;
1159
1160 case FILTER_OP_NOT:
1161 op = "!";
1162 right = arg_to_str(filter, arg->op.right);
1163 if (!right)
1164 break;
1165
1166 /* See if we can consolidate */
1167 if (strcmp(right, "TRUE") == 0)
1168 right_val = 1;
1169 else if (strcmp(right, "FALSE") == 0)
1170 right_val = 0;
1171 if (right_val >= 0) {
1172 /* just return the opposite */
1173 str = malloc_or_die(6);
1174 if (right_val)
1175 strcpy(str, "FALSE");
1176 else
1177 strcpy(str, "TRUE");
1178 break;
1179 }
1180 len = strlen(right) + strlen(op) + 3;
1181 str = malloc_or_die(len);
1182 snprintf(str, len, "%s(%s)", op, right);
1183 break;
1184
1185 default:
1186 /* ?? */
1187 break;
1188 }
1189 free(left);
1190 free(right);
1191 return str;
1192}
1193
1194static char *num_to_str(struct event_filter *filter, struct filter_arg *arg)
1195{
1196 char *str = NULL;
1197 char *op = NULL;
1198 int len;
1199
1200 switch (arg->num.type) {
1201 case FILTER_CMP_EQ:
1202 op = "==";
1203 /* fall through */
1204 case FILTER_CMP_NE:
1205 if (!op)
1206 op = "!=";
1207 /* fall through */
1208 case FILTER_CMP_GT:
1209 if (!op)
1210 op = ">";
1211 /* fall through */
1212 case FILTER_CMP_LT:
1213 if (!op)
1214 op = "<";
1215 /* fall through */
1216 case FILTER_CMP_GE:
1217 if (!op)
1218 op = ">=";
1219 /* fall through */
1220 case FILTER_CMP_LE:
1221 if (!op)
1222 op = "<=";
1223
1224 len = strlen(arg->num.field->name) + strlen(op) + 30;
1225 str = malloc_or_die(len);
1226 if (arg->num.field->flags & FIELD_IS_SIGNED)
1227 snprintf(str, len, "%s %s %lld",
1228 arg->num.field->name,
1229 op, arg->num.val);
1230 else
1231 snprintf(str, len, "%s %s %llu",
1232 arg->num.field->name,
1233 op, arg->num.val);
1234 break;
1235
1236 default:
1237 /* ?? */
1238 break;
1239 }
1240 return str;
1241}
1242
1243static char *str_to_str(struct event_filter *filter, struct filter_arg *arg)
1244{
1245 char *str = NULL;
1246 char *op = NULL;
1247 int len;
1248
1249 switch (arg->str.type) {
1250 case FILTER_CMP_MATCH:
1251 op = "==";
1252 /* fall through */
1253 case FILTER_CMP_NOT_MATCH:
1254 if (!op)
1255 op = "!=";
1256 /* fall through */
1257 case FILTER_CMP_REGEX:
1258 if (!op)
1259 op = "=~";
1260 /* fall through */
1261 case FILTER_CMP_NOT_REGEX:
1262 if (!op)
1263 op = "!~";
1264
1265 len = strlen(arg->str.field->name) + strlen(op) +
1266 strlen(arg->str.val) + 6;
1267 str = malloc_or_die(len);
1268 snprintf(str, len, "%s %s \"%s\"",
1269 arg->str.field->name,
1270 op, arg->str.val);
1271 break;
1272
1273 default:
1274 /* ?? */
1275 break;
1276 }
1277 return str;
1278}
1279
1280static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg)
1281{
1282 char *str;
1283
1284 switch (arg->type) {
1285 case FILTER_ARG_BOOLEAN:
1286 str = malloc_or_die(6);
1287 if (arg->bool.value)
1288 strcpy(str, "TRUE");
1289 else
1290 strcpy(str, "FALSE");
1291 return str;
1292
1293 case FILTER_ARG_OP:
1294 return op_to_str(filter, arg);
1295
1296 case FILTER_ARG_NUM:
1297 return num_to_str(filter, arg);
1298
1299 case FILTER_ARG_STR:
1300 return str_to_str(filter, arg);
1301
1302 default:
1303 /* ?? */
1304 return NULL;
1305 }
1306
1307}
1308
1309/**
1310 * pevent_filter_make_string - return a string showing the filter
1311 * @filter: filter struct with filter information
1312 * @event_id: the event id to return the filter string with
1313 *
1314 * Returns a string that displays the filter contents.
1315 * This string must be freed with free(str).
1316 * NULL is returned if no filter is found.
1317 */
1318char *
1319pevent_filter_make_string(struct event_filter *filter, int event_id)
1320{
1321 struct filter_type *filter_type;
1322
1323 if (!filter->filters)
1324 return NULL;
1325
1326 filter_type = find_filter_type(filter, event_id);
1327
1328 if (!filter_type)
1329 return NULL;
1330
1331 return arg_to_str(filter, filter_type->filter);
1332}
1333