|
Packit |
fd8b60 |
#!perl -w
|
|
Packit |
fd8b60 |
use ktemplate;
|
|
Packit |
fd8b60 |
# List of parameters accepted for substitution.
|
|
Packit |
fd8b60 |
@parms = qw(NAME KEY VALUE COMPARE COPYKEY FREEKEY FREEVALUE);
|
|
Packit |
fd8b60 |
# Defaults, if any.
|
|
Packit |
fd8b60 |
$parm{"COPYKEY"} = "0";
|
|
Packit |
fd8b60 |
$parm{"FREEKEY"} = "0";
|
|
Packit |
fd8b60 |
$parm{"FREEVALUE"} = "0";
|
|
Packit |
fd8b60 |
#
|
|
Packit |
fd8b60 |
&run;
|
|
Packit |
fd8b60 |
#
|
|
Packit |
fd8b60 |
__DATA__
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
* map, generated from template
|
|
Packit |
fd8b60 |
* map name: <NAME>
|
|
Packit |
fd8b60 |
* key: <KEY>
|
|
Packit |
fd8b60 |
* value: <VALUE>
|
|
Packit |
fd8b60 |
* compare: <COMPARE>
|
|
Packit |
fd8b60 |
* copy_key: <COPYKEY>
|
|
Packit |
fd8b60 |
* free_key: <FREEKEY>
|
|
Packit |
fd8b60 |
* free_value: <FREEVALUE>
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
struct <NAME>__element {
|
|
Packit |
fd8b60 |
<KEY> key;
|
|
Packit |
fd8b60 |
<VALUE> value;
|
|
Packit |
fd8b60 |
struct <NAME>__element *next;
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
struct <NAME>__head {
|
|
Packit |
fd8b60 |
struct <NAME>__element *first;
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
typedef struct <NAME>__head <NAME>;
|
|
Packit |
fd8b60 |
static inline int <NAME>_init (struct <NAME>__head *head)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
head->first = NULL;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
static inline void <NAME>_destroy (struct <NAME>__head *head)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
struct <NAME>__element *e, *e_next;
|
|
Packit |
fd8b60 |
void (*free_key)(<KEY>) = <FREEKEY>;
|
|
Packit |
fd8b60 |
void (*free_value)(<VALUE>) = <FREEVALUE>;
|
|
Packit |
fd8b60 |
for (e = head->first; e; e = e_next) {
|
|
Packit |
fd8b60 |
e_next = e->next;
|
|
Packit |
fd8b60 |
if (free_key)
|
|
Packit |
fd8b60 |
(*free_key)(e->key);
|
|
Packit |
fd8b60 |
if (free_value)
|
|
Packit |
fd8b60 |
(*free_value)(e->value);
|
|
Packit |
fd8b60 |
free(e);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
head->first = NULL;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Returns pointer to linked-list entry, or null if key not found. */
|
|
Packit |
fd8b60 |
static inline struct <NAME>__element *
|
|
Packit |
fd8b60 |
<NAME>__find_node (struct <NAME>__head *head, <KEY> key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
struct <NAME>__element *e;
|
|
Packit |
fd8b60 |
for (e = head->first; e; e = e->next)
|
|
Packit |
fd8b60 |
if (<COMPARE> (key, e->key) == 0)
|
|
Packit |
fd8b60 |
return e;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Returns pointer to value, or null if key not found. */
|
|
Packit |
fd8b60 |
static inline <VALUE> *
|
|
Packit |
fd8b60 |
<NAME>_find (struct <NAME>__head *head, <KEY> key)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
struct <NAME>__element *e = <NAME>__find_node(head, key);
|
|
Packit |
fd8b60 |
if (e)
|
|
Packit |
fd8b60 |
return &e->value;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Returns 0 or error code. */
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>__copy_key (<KEY> *out, <KEY> in)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int (*copykey)(<KEY> *, <KEY>) = <COPYKEY>;
|
|
Packit |
fd8b60 |
if (copykey == 0) {
|
|
Packit |
fd8b60 |
*out = in;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
} else
|
|
Packit |
fd8b60 |
return (*copykey)(out, in);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
/* Returns 0 or error code. */
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>_replace_or_insert (struct <NAME>__head *head,
|
|
Packit |
fd8b60 |
<KEY> key, <VALUE> new_value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
struct <NAME>__element *e = <NAME>__find_node(head, key);
|
|
Packit |
fd8b60 |
int ret;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (e) {
|
|
Packit |
fd8b60 |
/* replace */
|
|
Packit |
fd8b60 |
void (*free_value)(<VALUE>) = <FREEVALUE>;
|
|
Packit |
fd8b60 |
if (free_value)
|
|
Packit |
fd8b60 |
(*free_value)(e->value);
|
|
Packit |
fd8b60 |
e->value = new_value;
|
|
Packit |
fd8b60 |
} else {
|
|
Packit |
fd8b60 |
/* insert */
|
|
Packit |
fd8b60 |
e = malloc(sizeof(*e));
|
|
Packit |
fd8b60 |
if (e == NULL)
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
ret = <NAME>__copy_key (&e->key, key);
|
|
Packit |
fd8b60 |
if (ret) {
|
|
Packit |
fd8b60 |
free(e);
|
|
Packit |
fd8b60 |
return ret;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
e->value = new_value;
|
|
Packit |
fd8b60 |
e->next = head->first;
|
|
Packit |
fd8b60 |
head->first = e;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|