#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:
    printf("test1\n");
    return;
l2:
    printf("test2\n");
    return;
l3:
    printf("test3\n");
    return;
}
 
int main(void)
{
	test(0);
	test(test_l1);
	test(test_l2);
	test(test_l3);
}