/* $Id: matchlist.c 295 2005-12-16 19:44:24Z tsaviran $
* -------------------------------------------------------
* Copyright (C) 2004-2005 Tommi Saviranta <wnd@iki.fi>
* -------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* ifdef HAVE_CONFIG_H */
#include "matchlist.h"
#include "match.h"
#include "common.h"
#include "list.h"
#include <stdio.h>
#include <string.h>
typedef struct _match_type match_type;
union ptr_int {
void *ptr;
int i;
};
struct _match_type {
char *rule;
union ptr_int state;
};
/*
* Add entry to matchlist.
* @list: list where to add
* @rule: rule to match stuff against
* @state: data for this match
*
* Returns: Pointer to new matchlist.
*
* Rule is duplicated in the struct, state is not. This means state must be
* freed somehow when flushing the list. Fortunately, there's an easy way
* to do this. :-)
*/
list_type *
matchlist_add(list_type *list, char *rule, void *state)
{
match_type *match;
match = (match_type *) xmalloc(sizeof(match_type));
match->rule = xstrdup(rule);
match->state.ptr = state;
return list_add_tail(list, match);
} /* list_type *matchlist_add(list_type *list, char *rule, void *state) */
/*
* Clear matchlist.
* @list: list to clear
*
* Returns: pointer to list
*/
list_type *
matchlist_flush(list_type *list, void (free_cb)(void *))
{
match_type *data;
list_type *ptr;
/* First free data inside the list. */
for (ptr = list; ptr != NULL; ptr = ptr->next) {
data = (match_type *) ptr->data;
xfree((void *) data->rule);
if (free_cb != NULL) {
(*free_cb)(data->state.ptr);
}
xfree(ptr->data);
}
LIST_CLEAR(list);
return list;
} /* llist_t *matchlist_flush(llist_t *list, void (free_cb)(void *)) */
/*
* Get match from matchlist.
* @list: list
* @cand: stuff to match
*
* Returns: pointer to data, (void *) -1 if nothing found.
*/
void *
matchlist_get(list_type *list, const char *cand)
{
match_type *data;
list_type *ptr;
for (ptr = list; ptr != NULL; ptr = ptr->next) {
data = (match_type *) ptr->data;
if (match(cand, data->rule) == 1) {
return data->state.ptr;
}
}
return (void *) -1;
} /* void *matchlist_get(list_type *list, const char *cand) */
#ifdef DUMPSTATUS
#define BUFSIZE 65536
const char *
matchlist_dump(list_type *list)
{
static char buf[BUFSIZE];
match_type *data;
list_type *ptr;
int len, t;
buf[0] = buf[BUFSIZE - 1] = '\0';
len = (int) strlen(buf);
for (ptr = list; ptr != NULL; ptr = ptr->next) {
data = (match_type *) ptr->data;
/* This is dangerous, but no-one has to call this function! */
if ((int) data->state.i == 0 || (int) data->state.i == 1) {
t = snprintf(buf + len, BUFSIZE - len,
" '%s' = %d\n",
data->rule, (int) data->state.i);
} else {
t = snprintf(buf + len, BUFSIZE - len,
" '%s' = '%s'\n",
data->rule, (char *) data->state.ptr);
}
buf[BUFSIZE - 1] = '\0';
if (t < 0) {
return buf;
}
len += t;
}
return buf;
} /* const char *matchlist_dump(list_type *list) */
#endif /* ifdef DUMPSTATUS */
syntax highlighted by Code2HTML, v. 0.9.1