1#!perl -w 2use ktemplate; 3# List of parameters accepted for substitution. 4@parms = qw(NAME KEY VALUE COMPARE COPYKEY FREEKEY FREEVALUE); 5# Defaults, if any. 6$parm{"COPYKEY"} = "0"; 7$parm{"FREEKEY"} = "0"; 8$parm{"FREEVALUE"} = "0"; 9# 10&run; 11# 12__DATA__ 13/* 14 * map, generated from template 15 * map name: <NAME> 16 * key: <KEY> 17 * value: <VALUE> 18 * compare: <COMPARE> 19 * copy_key: <COPYKEY> 20 * free_key: <FREEKEY> 21 * free_value: <FREEVALUE> 22 */ 23struct <NAME>__element { 24 <KEY> key; 25 <VALUE> value; 26 struct <NAME>__element *next; 27}; 28struct <NAME>__head { 29 struct <NAME>__element *first; 30}; 31typedef struct <NAME>__head <NAME>; 32static inline int <NAME>_init (struct <NAME>__head *head) 33{ 34 head->first = NULL; 35 return 0; 36} 37static inline void <NAME>_destroy (struct <NAME>__head *head) 38{ 39 struct <NAME>__element *e, *e_next; 40 void (*free_key)(<KEY>) = <FREEKEY>; 41 void (*free_value)(<VALUE>) = <FREEVALUE>; 42 for (e = head->first; e; e = e_next) { 43 e_next = e->next; 44 if (free_key) 45 (*free_key)(e->key); 46 if (free_value) 47 (*free_value)(e->value); 48 free(e); 49 } 50 head->first = NULL; 51} 52/* Returns pointer to linked-list entry, or null if key not found. */ 53static inline struct <NAME>__element * 54<NAME>__find_node (struct <NAME>__head *head, <KEY> key) 55{ 56 struct <NAME>__element *e; 57 for (e = head->first; e; e = e->next) 58 if (<COMPARE> (key, e->key) == 0) 59 return e; 60 return 0; 61} 62/* Returns pointer to value, or null if key not found. */ 63static inline <VALUE> * 64<NAME>_find (struct <NAME>__head *head, <KEY> key) 65{ 66 struct <NAME>__element *e = <NAME>__find_node(head, key); 67 if (e) 68 return &e->value; 69 return 0; 70} 71/* Returns 0 or error code. */ 72static inline int 73<NAME>__copy_key (<KEY> *out, <KEY> in) 74{ 75 int (*copykey)(<KEY> *, <KEY>) = <COPYKEY>; 76 if (copykey == 0) { 77 *out = in; 78 return 0; 79 } else 80 return (*copykey)(out, in); 81} 82/* Returns 0 or error code. */ 83static inline int 84<NAME>_replace_or_insert (struct <NAME>__head *head, 85 <KEY> key, <VALUE> new_value) 86{ 87 struct <NAME>__element *e = <NAME>__find_node(head, key); 88 int ret; 89 90 if (e) { 91 /* replace */ 92 void (*free_value)(<VALUE>) = <FREEVALUE>; 93 if (free_value) 94 (*free_value)(e->value); 95 e->value = new_value; 96 } else { 97 /* insert */ 98 e = malloc(sizeof(*e)); 99 if (e == NULL) 100 return ENOMEM; 101 ret = <NAME>__copy_key (&e->key, key); 102 if (ret) { 103 free(e); 104 return ret; 105 } 106 e->value = new_value; 107 e->next = head->first; 108 head->first = e; 109 } 110 return 0; 111} 112