tracefs_filter_string_append(3) — Linux manual page

NAME | SYNOPSIS | DESCRIPTION | RETURN VALUE | EXAMPLE | FILES | SEE ALSO | AUTHOR | REPORTING BUGS | LICENSE | RESOURCES | COPYING | NOTES | COLOPHON

LIBTRACEFS(3)               libtracefs Manual              LIBTRACEFS(3)

NAME         top

       tracefs_filter_string_append, tracefs_filter_string_verify,
       tracefs_event_filter_apply, tracefs_event_filter_clear - Add,
       verify and apply event filters

SYNOPSIS         top

       #include <tracefs.h>

       int tracefs_filter_string_append(struct tep_event *event, char **filter,
                                        struct tracefs_filter type, const char *field,
                                        enum tracefs_synth_compare compare, const char *val);
       int tracefs_filter_string_verify(struct tep_event *event, const char *filter, char **err);
       int tracefs_event_filter_apply(struct tracefs_instance *instance, struct tep_event *event, const char *filter);
       int tracefs_event_filter_clear(struct tracefs_instance *instance, struct tep_event *event);

DESCRIPTION         top

       tracefs_filter_string_append() is a way to create and verify
       event filters for a given event. It will verify that the field
       belongs to the event and that the compare option that is used is
       valid for the type of the field, as well as val. For the type
       that is not of TRACEFS_FILTER_COMPARE, it will build the logical
       string and also make sure that the syntax is correct. For
       example, there are no more close parenthesis than open
       parenthesis. An AND (&&) or OR (||) is not misplaced, etc.

       tracefs_synth_append_start_filter() creates a filter or appends
       to it for the starting event. Depending on type, it will build a
       string of tokens for parenthesis or logic statemens, or it may
       add a comparison of field to val based on compare.

       If type is: TRACEFS_FILTER_COMPARE - See below TRACEFS_FILTER_AND
       - Append "&&" to the filter TRACEFS_FILTER_OR - Append "||" to
       the filter TRACEFS_FILTER_NOT - Append "!" to the filter
       TRACEFS_FILTER_OPEN_PAREN - Append "(" to the filter
       TRACEFS_FILTER_CLOSE_PAREN - Append ")" to the filter

       field, compare, and val are ignored unless type is equal to
       TRACEFS_FILTER_COMPARE, then _compare will be used for the
       following:

       TRACEFS_COMPARE_EQ - field == val

       TRACEFS_COMPARE_NE - field != val

       TRACEFS_COMPARE_GT - field > val

       TRACEFS_COMPARE_GE - field >= val

       TRACEFS_COMPARE_LT - field < val

       TRACEFS_COMPARE_LE - field <= val

       TRACEFS_COMPARE_RE - field ~ "val" : where field is a string.

       TRACEFS_COMPARE_AND - field & val : where field is a flags field.

       tracefs_filter_string_verify() will parse filter to make sure
       that the fields are for the event, and that the syntax is
       correct. If there’s an error in the syntax, and err is not NULL,
       then it will be allocated with an error message stating what was
       found wrong with the filter. err must be freed with free().

       tracefs_event_filter_apply() applies given filter string on event
       in given instance.

       tracefs_event_filter_clear() clear all filters on event in given
       instance.

RETURN VALUE         top

       tracefs_filter_string_append() returns 0 on success and -1 on
       error.

       tracefs_filter_string_verify() returns 0 on success and -1 on
       error. if there is an error, and errno is not ENOMEM, then err is
       allocated and will contain a string describing what was found
       wrong with filter. err must be freed with free().

       tracefs_event_filter_apply() returns 0 on success and -1 on
       error.

       tracefs_event_filter_clear() returns 0 on success and -1 on
       error.

EXAMPLE         top

           #include <stdlib.h>
           #include <stdio.h>
           #include <ctype.h>
           #include <tracefs.h>

           static void usage(char **argv)
           {
                   fprintf(stderr, "usage: %s [system] event filter\n", argv[0]);
                   exit(-1);
           }

           int main (int argc, char **argv)
           {
                   struct tep_handle *tep;
                   struct tep_event *event;
                   const char *system = NULL;
                   const char *event_name;
                   const char *filter;
                   char *new_filter = NULL;
                   char *err = NULL;
                   int i;

                   if (argc < 3)
                           usage(argv);

                   if (argc < 4) {
                           event_name = argv[1];
                           filter = argv[2];
                   } else {
                           system = argv[1];
                           event_name = argv[2];
                           filter = argv[3];
                   }

                   /* Load all events from the system */
                   tep = tracefs_local_events(NULL);
                   if (!tep) {
                           perror("tep");
                           exit(-1);
                   }

                   event = tep_find_event_by_name(tep, system, event_name);
                   if (!event) {
                           fprintf(stderr, "Event %s%s%s not found\n",
                                   system ? system : "" , system ? " " : "",
                                   event_name);
                           exit(-1);
                   }

                   if (tracefs_filter_string_verify(event, filter, &err) < 0) {
                           perror("tracecfs_event_verify_filter");
                           if (err)
                                   fprintf(stderr, "%s", err);
                           free(err);
                           exit(-1);
                   }

                   for (i = 0; filter[i]; i++) {
                           char buf[strlen(filter)];
                           char *field = NULL;
                           char *val = NULL;
                           enum tracefs_filter type;
                           enum tracefs_compare compare = 0;
                           int start_i, n;
                           int quote;
                           bool backslash;

                           while (isspace(filter[i]))
                                   i++;

                           switch(filter[i]) {
                           case '(':
                                   type = TRACEFS_FILTER_OPEN_PAREN;
                                   break;
                           case ')':
                                   type = TRACEFS_FILTER_CLOSE_PAREN;
                                   break;
                           case '!':
                                   type = TRACEFS_FILTER_NOT;
                                   break;
                           case '&':
                                   type = TRACEFS_FILTER_AND;
                                   i++;
                                   break;
                           case '|':
                                   type = TRACEFS_FILTER_OR;
                                   i++;
                                   break;
                           default:
                                   type = TRACEFS_FILTER_COMPARE;

                                   while (isspace(filter[i]))
                                           i++;

                                   start_i = i;
                                   for (; filter[i]; i++) {
                                           switch(filter[i]) {
                                           case 'a' ... 'z':
                                           case 'A' ... 'Z':
                                           case '0' ... '9':
                                           case '_':
                                                   continue;
                                           }
                                           break;
                                   }

                                   n = i - start_i;
                                   field = buf;
                                   strncpy(field, filter + start_i, n);
                                   field[n++] = '\0';

                                   val = buf + n;

                                   while (isspace(filter[i]))
                                           i++;

                                   start_i = i;
                                   switch(filter[i++]) {
                                   case '>':
                                           compare = TRACEFS_COMPARE_GT;
                                           if (filter[i] == '=') {
                                                   i++;
                                                   compare = TRACEFS_COMPARE_GE;
                                           }
                                           break;
                                   case '<':
                                           compare = TRACEFS_COMPARE_LT;
                                           if (filter[i] == '=') {
                                                   i++;
                                                   compare = TRACEFS_COMPARE_LE;
                                           }
                                           break;
                                   case '=':
                                           compare = TRACEFS_COMPARE_EQ;
                                           i++;
                                           break;
                                   case '!':
                                           compare = TRACEFS_COMPARE_NE;
                                           i++;
                                           break;
                                   case '~':
                                           compare = TRACEFS_COMPARE_RE;
                                           break;
                                   case '&':
                                           compare = TRACEFS_COMPARE_AND;
                                           break;
                                   }

                                   while (isspace(filter[i]))
                                           i++;

                                   quote = 0;
                                   backslash = false;
                                   start_i = i;
                                   for (; filter[i]; i++) {
                                           if (quote) {
                                                   if (backslash)
                                                           backslash = false;
                                                   else if (filter[i] == '\\')
                                                           backslash = true;
                                                   else if (filter[i] == quote)
                                                           quote = 0;
                                                   continue;
                                           }
                                           switch(filter[i]) {
                                           case '"': case '\'':
                                                   quote = filter[i];
                                                   continue;
                                           case 'a' ... 'z':
                                           case 'A' ... 'Z':
                                           case '0' ... '9':
                                           case '_':
                                                   continue;
                                           }
                                           break;
                                   }
                                   n = i - start_i;
                                   strncpy(val, filter + start_i, n);
                                   val[n] = '\0';
                                   break;
                           }
                           n = tracefs_filter_string_append(event, &new_filter, type,
                                                           field, compare, val);
                           if (n < 0) {
                                   fprintf(stderr, "Failed making new filter:\n'%s'\n",
                                           new_filter ? new_filter : "(null)");
                                   exit(-1);
                           }
                   }

                   if (tracefs_event_filter_apply(NULL, event, new_filter))
                           fprintf(stderr, "Failed to apply filter on event");

                   tep_free(tep);

                   printf("Created new filter: '%s'\n", new_filter);
                   free(new_filter);

                   exit(0);
           }

FILES         top

           tracefs.h
                   Header file to include in order to have access to the library APIs.
           -ltracefs
                   Linker switch to add when building a program that uses the library.

SEE ALSO         top

       libtracefs(3), libtraceevent(3), trace-cmd(1),
       tracefs_hist_alloc(3), tracefs_hist_alloc_2d(3),
       tracefs_hist_alloc_nd(3), tracefs_hist_free(3),
       tracefs_hist_add_key(3), tracefs_hist_add_value(3),
       tracefs_hist_add_name(3), tracefs_hist_start(3),
       tracefs_hist_destory(3), tracefs_hist_add_sort_key(3),
       tracefs_hist_sort_key_direction(3)

AUTHOR         top

           Steven Rostedt <[email protected][1]>
           Tzvetomir Stoyanov <[email protected][2]>
           sameeruddin shaik <[email protected][3]>

REPORTING BUGS         top

       Report bugs to <[email protected][4]>

LICENSE         top

       libtracefs is Free Software licensed under the GNU LGPL 2.1

RESOURCES         top

       https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 

COPYING         top

       Copyright (C) 2020 VMware, Inc. Free use of this software is
       granted under the terms of the GNU Public License (GPL).

NOTES         top

        1. [email protected]
           mailto:[email protected]

        2. [email protected]
           mailto:[email protected]

        3. [email protected]
           mailto:[email protected]

        4. [email protected]
           mailto:[email protected]

COLOPHON         top

       This page is part of the libtracefs (Linux kernel trace file
       system library) project.  Information about the project can be
       found at ⟨https://www.trace-cmd.org/⟩.  If you have a bug report
       for this manual page, see ⟨https://www.trace-cmd.org/⟩.  This
       page was obtained from the project's upstream Git repository
       ⟨https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git⟩ on
       2024-06-14.  (At that time, the date of the most recent commit
       that was found in the repository was 2024-05-17.)  If you
       discover any rendering problems in this HTML version of the page,
       or you believe there is a better or more up-to-date source for
       the page, or you have corrections or improvements to the
       information in this COLOPHON (which is not part of the original
       manual page), send a mail to [email protected]

libtracefs 1.7.0               12/22/2023                  LIBTRACEFS(3)