Logo Search packages:      
Sourcecode: jmp version File versions  Download package

filter.c

#include <stdlib.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <jmp-config.h>
#include <cls.h>
#include <filter.h>

struct class_filter {
    int   filter_type;   /** FILTER_MATCH_CLASS, ... */
    char* filter_name;   /** java.lang */    
    int   inc_or_exc;    /** include or exclude filter */
};

/** double linked list for easy handling. */
00017 struct filter_list {
    class_filter* filter;
    filter_list*  next;
    filter_list*  prev;
};

static filter_list* current_filters = NULL;

/** Get the filter type
 * @return one of the FILTER_MATCH_*
 */
int get_filter_type (class_filter* cf) {
    return cf->filter_type;
}

/** Get the filter name
 * @return the name that is matched for the given filter.
 */
char* get_filter_name (class_filter* cf) {
    return cf->filter_name;
}

/** 
 * @return FILTER_INCLUDE or FILTER_EXCLUDE
 */ 
int get_inc_or_exc (class_filter* cf) {
    return cf->inc_or_exc;
}

filter_list* get_current_filters () {
    return current_filters;
}

filter_list* get_next_filter (filter_list* fl) {
    return fl->next;
}

class_filter* get_class_filter (filter_list* fl) {
    return fl->filter;
}

int filter_class_name (const char *name)
{
    filter_list* fl = current_filters;
    
    if (current_filters == NULL)
      return 1;
    
    while (fl) {
      class_filter* filter = fl->filter;
      if (filter->filter_type == FILTER_MATCH_ALL) {
          return filter->inc_or_exc;
      } else if (filter->filter_type == FILTER_MATCH_CLASS) {
          if (!strcmp (name, filter->filter_name))
            return filter->inc_or_exc;
      } else if (filter->filter_type == FILTER_MATCH_RECURSIVE) {
          if (!strncmp(name, filter->filter_name, strlen (filter->filter_name)))
            return filter->inc_or_exc;
      }else if (filter->filter_type == FILTER_MATCH_PACKAGE) {
          size_t len = strlen (filter->filter_name);
          if (!strncmp (name, filter->filter_name, len))
            if (!strchr (name + len, '.'))
                return filter->inc_or_exc;
      }
      fl = fl->next;
    }
    return 0;
}

void set_filtered (cls* c) {
    cls_set_filtered (c, filter_class_name (cls_get_name (c)));
}

/** Update each class filtered variable. */
static void update_classes () {
    hashtab* classes = get_classes ();
    jmphash_lock (classes);
    jmphash_for_each ((jmphash_iter_f)set_filtered, classes);
    jmphash_unlock (classes);
}

static void filter_add_filter_internal (class_filter* filter) {
    filter_list* fl;
    fl = malloc (sizeof (*current_filters));
    if (fl == NULL)
      return;
    fl->next = current_filters;
    fl->prev = NULL;
    fl->filter = filter;
    if (current_filters)
      current_filters->prev = fl;
    current_filters = fl;
    update_classes ();
}

void filter_add_filter (int mode, const char* text, int type) {
    class_filter* cfilter;
    if (text == NULL)
      return;
    cfilter = malloc (sizeof (*cfilter));
    if (cfilter == NULL)
      return;
    cfilter->filter_type = type;
    cfilter->filter_name = strdup (text);
    cfilter->inc_or_exc = mode;    
    filter_add_filter_internal (cfilter);
}

static void free_filter_list_elem (filter_list* fl) {
    free (fl->filter->filter_name);
    free (fl->filter);
    free (fl);
}

void remove_filter (class_filter* filter) {
    filter_list* fl = current_filters;
    while (fl) {
      if (fl->filter == filter) {
          if (fl->next)
            fl->next->prev = fl->prev;
          if (fl->prev)
            fl->prev->next = fl->next;
          else /* first in list */ 
            current_filters = fl->next;
          free_filter_list_elem (fl);
          break;
      } else {
          fl = fl->next;
      }
    }
    update_classes ();
}

void filter_clear_filters_internal (int do_update_classes) {
    while (current_filters) {
      filter_list* next_filter = current_filters->next;
      free_filter_list_elem (current_filters);
      current_filters = next_filter;
    }
    if (do_update_classes)
      update_classes ();
}

/** Removes all current filters. */
void filter_clear_filters () {
    filter_clear_filters_internal (1);
}

/* Set the filter. 
 * @param filtertype one of FILTER_MATCH_*
 * @param filter the string to filter on ("rabbit.proxy").
 */
void filter_set_filter (int filter_type, const char* filter) {
    if (filter == NULL)
      return;
    filter_clear_filters (0);
    filter_add_filter (FILTER_INCLUDE, filter, filter_type);
}

/* Emacs Local Variables: */
/* Emacs mode:C */
/* Emacs c-indentation-style:"gnu" */
/* Emacs c-hanging-braces-alist:((brace-list-open)(brace-entry-open)(defun-open after)(substatement-open after)(block-close . c-snug-do-while)(extern-lang-open after)) */
/* Emacs c-cleanup-list:(brace-else-brace brace-elseif-brace space-before-funcall) */
/* Emacs c-basic-offset:4 */
/* Emacs End: */

Generated by  Doxygen 1.6.0   Back to index