#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef int abstract_func_type ();
typedef struct htentry {
struct htentry *next;
abstract_func_type *k;
abstract_func_type **fpp;
} htentry;
static htentry *hashtable[101];
static void insert (abstract_func_type *k, abstract_func_type **p) {
htentry
*e
= malloc(sizeof(htentry
)); int i = ((char *)k - (char *)0) % 101;
e->k = k;
e->fpp = p;
e->next = hashtable[i];
hashtable[i] = e;
}
static abstract_func_type ** lookup (abstract_func_type *k) {
int i = ((char *)k - (char *)0) % 101;
htentry *e = hashtable[i];
while (e) {
if (e->k == k) return e->fpp;
e = e->next;
}
return 0;
}
abstract_func_type * abstract_func_get (abstract_func_type *k) {
abstract_func_type **f = lookup(k);
if (f) return *f;
return 0;
}
int abstract_func_set (abstract_func_type *k, abstract_func_type *p) {
abstract_func_type **f = lookup(k);
if (f) {
*f = p;
return 0;
}
return -ENOENT;
}
#define DEFINE_ABSTRACT_FUNC(func) \
static int static_##func (); \
static abstract_func_type *func##_ptr = static_##func; \
int func () { return func##_ptr(); } \
static int static_##func ()
DEFINE_ABSTRACT_FUNC
(foo
) { return puts("foo"); } DEFINE_ABSTRACT_FUNC
(bar
) { return puts("bar"); }
void abstract_func_init () {
insert(foo, &foo_ptr);
insert(bar, &bar_ptr);
}
void swap(abstract_func_type *a, abstract_func_type *b) {
abstract_func_type *ap = abstract_func_get(a);
abstract_func_type *bp = abstract_func_get(b);
abstract_func_set(a, bp);
abstract_func_set(b, ap);
}
int
main ()
{
abstract_func_init();
foo();
bar();
swap(foo, bar);
foo();
bar();
return 0;
}
ICAgICNpbmNsdWRlIDxzdGRpby5oPgogICAgI2luY2x1ZGUgPHN0ZGxpYi5oPgogICAgI2luY2x1ZGUgPGVycm5vLmg+CgogICAgdHlwZWRlZiBpbnQgYWJzdHJhY3RfZnVuY190eXBlICgpOwoKICAgIHR5cGVkZWYgc3RydWN0IGh0ZW50cnkgewogICAgICAgIHN0cnVjdCBodGVudHJ5ICpuZXh0OwogICAgICAgIGFic3RyYWN0X2Z1bmNfdHlwZSAqazsKICAgICAgICBhYnN0cmFjdF9mdW5jX3R5cGUgKipmcHA7CiAgICB9IGh0ZW50cnk7CiAgICBzdGF0aWMgaHRlbnRyeSAqaGFzaHRhYmxlWzEwMV07CgogICAgc3RhdGljIHZvaWQgaW5zZXJ0IChhYnN0cmFjdF9mdW5jX3R5cGUgKmssIGFic3RyYWN0X2Z1bmNfdHlwZSAqKnApIHsKICAgICAgICBodGVudHJ5ICplID0gbWFsbG9jKHNpemVvZihodGVudHJ5KSk7CiAgICAgICAgaW50IGkgPSAoKGNoYXIgKilrIC0gKGNoYXIgKikwKSAlIDEwMTsKICAgICAgICBlLT5rID0gazsKICAgICAgICBlLT5mcHAgPSBwOwogICAgICAgIGUtPm5leHQgPSBoYXNodGFibGVbaV07CiAgICAgICAgaGFzaHRhYmxlW2ldID0gZTsKICAgIH0KCiAgICBzdGF0aWMgYWJzdHJhY3RfZnVuY190eXBlICoqIGxvb2t1cCAoYWJzdHJhY3RfZnVuY190eXBlICprKSB7CiAgICAgICAgaW50IGkgPSAoKGNoYXIgKilrIC0gKGNoYXIgKikwKSAlIDEwMTsKICAgICAgICBodGVudHJ5ICplID0gaGFzaHRhYmxlW2ldOwogICAgICAgIHdoaWxlIChlKSB7CiAgICAgICAgICAgIGlmIChlLT5rID09IGspIHJldHVybiBlLT5mcHA7CiAgICAgICAgICAgIGUgPSBlLT5uZXh0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBhYnN0cmFjdF9mdW5jX3R5cGUgKiBhYnN0cmFjdF9mdW5jX2dldCAoYWJzdHJhY3RfZnVuY190eXBlICprKSB7CiAgICAgICAgYWJzdHJhY3RfZnVuY190eXBlICoqZiA9IGxvb2t1cChrKTsKICAgICAgICBpZiAoZikgcmV0dXJuICpmOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGludCBhYnN0cmFjdF9mdW5jX3NldCAoYWJzdHJhY3RfZnVuY190eXBlICprLCBhYnN0cmFjdF9mdW5jX3R5cGUgKnApIHsKICAgICAgICBhYnN0cmFjdF9mdW5jX3R5cGUgKipmID0gbG9va3VwKGspOwogICAgICAgIGlmIChmKSB7CiAgICAgICAgICAgICpmID0gcDsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHJldHVybiAtRU5PRU5UOwogICAgfQoKICAgICNkZWZpbmUgREVGSU5FX0FCU1RSQUNUX0ZVTkMoZnVuYykgXAogICAgICAgIHN0YXRpYyBpbnQgc3RhdGljXyMjZnVuYyAoKTsgXAogICAgICAgIHN0YXRpYyBhYnN0cmFjdF9mdW5jX3R5cGUgKmZ1bmMjI19wdHIgPSBzdGF0aWNfIyNmdW5jOyBcCiAgICAgICAgaW50IGZ1bmMgKCkgeyByZXR1cm4gZnVuYyMjX3B0cigpOyB9IFwKICAgICAgICBzdGF0aWMgaW50IHN0YXRpY18jI2Z1bmMgKCkKCiAgICBERUZJTkVfQUJTVFJBQ1RfRlVOQyhmb28pIHsgcmV0dXJuIHB1dHMoImZvbyIpOyB9CiAgICBERUZJTkVfQUJTVFJBQ1RfRlVOQyhiYXIpIHsgcmV0dXJuIHB1dHMoImJhciIpOyB9CgogICAgdm9pZCBhYnN0cmFjdF9mdW5jX2luaXQgKCkgewogICAgICAgIGluc2VydChmb28sICZmb29fcHRyKTsKICAgICAgICBpbnNlcnQoYmFyLCAmYmFyX3B0cik7CiAgICB9CgogICAgdm9pZCBzd2FwKGFic3RyYWN0X2Z1bmNfdHlwZSAqYSwgYWJzdHJhY3RfZnVuY190eXBlICpiKSB7CiAgICAgICAgYWJzdHJhY3RfZnVuY190eXBlICphcCA9IGFic3RyYWN0X2Z1bmNfZ2V0KGEpOwogICAgICAgIGFic3RyYWN0X2Z1bmNfdHlwZSAqYnAgPSBhYnN0cmFjdF9mdW5jX2dldChiKTsKICAgICAgICBhYnN0cmFjdF9mdW5jX3NldChhLCBicCk7CiAgICAgICAgYWJzdHJhY3RfZnVuY19zZXQoYiwgYXApOwogICAgfQoKICAgIGludAogICAgbWFpbiAoKQogICAgewogICAgICAgIGFic3RyYWN0X2Z1bmNfaW5pdCgpOwogICAgICAgIHB1dHMoImJlZm9yZSBzd2FwIik7CiAgICAgICAgZm9vKCk7CiAgICAgICAgYmFyKCk7CiAgICAgICAgc3dhcChmb28sIGJhcik7CiAgICAgICAgcHV0cygiYWZ0ZXIgc3dhcCIpOwogICAgICAgIGZvbygpOwogICAgICAgIGJhcigpOwogICAgICAgIHJldHVybiAwOwogICAgfQo=