#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char *name;
void *ptr;
} label;
#define LABELED(rtype, xname, xlcount) label xname##__labels[xlcount];\
int xname##__lcount = xlcount;\
rtype xname
#define LABELS(xname) label *__labels = xname##__labels;\
int __li = 0;
#define LABEL(lname) __labels[__li].name = #lname;\
__labels[__li++].ptr = &&lname;
#define LABELPTR(xname, lname) getlptr(xname##__labels, xname##__lcount, #lname)
void *getlptr(label *labels, int lcount, char *name) {
for (int i
= 0; i
< lcount
; i
++) if (!strcmp(name
, labels
[i
].
name)) return labels
[i
].
ptr; return NULL;
}
LABELED(void, test, 3) (void *ptr)
{
LABELS(test) {
LABEL(l1);
#define test_l1 LABELPTR(test, l1)
LABEL(l2);
#define test_l2 LABELPTR(test, l2)
LABEL(l3);
#define test_l3 LABELPTR(test, l3)
}
if (ptr)
goto *ptr;
return;
l1:
return;
l2:
return;
l3:
return;
}
int main(void)
{
test(0);
test(test_l1);
test(test_l2);
test(test_l3);
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKdHlwZWRlZiBzdHJ1Y3QgewoJY2hhciAqbmFtZTsKCXZvaWQgKnB0cjsKfSBsYWJlbDsKCiNkZWZpbmUgTEFCRUxFRChydHlwZSwgeG5hbWUsIHhsY291bnQpIGxhYmVsIHhuYW1lIyNfX2xhYmVsc1t4bGNvdW50XTtcCmludCB4bmFtZSMjX19sY291bnQgPSB4bGNvdW50O1wKcnR5cGUgeG5hbWUKCiNkZWZpbmUgTEFCRUxTKHhuYW1lKSBsYWJlbCAqX19sYWJlbHMgPSB4bmFtZSMjX19sYWJlbHM7XAppbnQgX19saSA9IDA7CgojZGVmaW5lIExBQkVMKGxuYW1lKSBfX2xhYmVsc1tfX2xpXS5uYW1lID0gI2xuYW1lO1wKX19sYWJlbHNbX19saSsrXS5wdHIgPSAmJmxuYW1lOwoKI2RlZmluZSBMQUJFTFBUUih4bmFtZSwgbG5hbWUpIGdldGxwdHIoeG5hbWUjI19fbGFiZWxzLCB4bmFtZSMjX19sY291bnQsICNsbmFtZSkKCnZvaWQgKmdldGxwdHIobGFiZWwgKmxhYmVscywgaW50IGxjb3VudCwgY2hhciAqbmFtZSkgewoJZm9yIChpbnQgaSA9IDA7IGkgPCBsY291bnQ7IGkrKykgaWYgKCFzdHJjbXAobmFtZSwgbGFiZWxzW2ldLm5hbWUpKSByZXR1cm4gbGFiZWxzW2ldLnB0cjsKCXJldHVybiBOVUxMOwp9CgpMQUJFTEVEKHZvaWQsIHRlc3QsIDMpICh2b2lkICpwdHIpCnsKCUxBQkVMUyh0ZXN0KSB7CgkJTEFCRUwobDEpOwoJCSNkZWZpbmUgdGVzdF9sMSBMQUJFTFBUUih0ZXN0LCBsMSkKCQlMQUJFTChsMik7CgkJI2RlZmluZSB0ZXN0X2wyIExBQkVMUFRSKHRlc3QsIGwyKQoJCUxBQkVMKGwzKTsKCQkjZGVmaW5lIHRlc3RfbDMgTEFCRUxQVFIodGVzdCwgbDMpCgl9CgkKCWlmIChwdHIpCiAgICAJZ290byAqcHRyOwogICAgcmV0dXJuOwpsMToKICAgIHByaW50ZigidGVzdDFcbiIpOwogICAgcmV0dXJuOwpsMjoKICAgIHByaW50ZigidGVzdDJcbiIpOwogICAgcmV0dXJuOwpsMzoKICAgIHByaW50ZigidGVzdDNcbiIpOwogICAgcmV0dXJuOwp9CiAKaW50IG1haW4odm9pZCkKewoJdGVzdCgwKTsKCXRlc3QodGVzdF9sMSk7Cgl0ZXN0KHRlc3RfbDIpOwoJdGVzdCh0ZXN0X2wzKTsKfQ==