I have a more complex example, if you're interested...
static struct qla27xx_fwdt_entry *
qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
{
qla27xx_skip_entry(ent, buf);
return qla27xx_next_entry(ent);
}
static struct {
uint type;
typeof(qla27xx_fwdt_entry_other)(*call);
} qla27xx_fwdt_entry_call[] = {
{ ENTRY_TYPE_TMP_END , qla27xx_fwdt_entry_t255 } ,
{ ENTRY_TYPE_RD_IOB_T1 , qla27xx_fwdt_entry_t256 } ,
{ ENTRY_TYPE_WR_IOB_T1 , qla27xx_fwdt_entry_t257 } ,
{ ENTRY_TYPE_RD_IOB_T2 , qla27xx_fwdt_entry_t258 } ,
{ -1 , qla27xx_fwdt_entry_other }
};
static inline
typeof(*qla27xx_fwdt_entry_call->call)(*qla27xx_find_entry(uint type))
{
typeof(*qla27xx_fwdt_entry_call) *list = qla27xx_fwdt_entry_call;
while (list->type < type)
list++;
if (list->type == type)
return list->call;
return qla27xx_fwdt_entry_other;
}
static void
qla27xx_walk_template(struct scsi_qla_host *vha,
struct qla27xx_fwdt_template *tmp, void *buf, ulong *len)
{
struct qla27xx_fwdt_entry *ent = (void *)tmp + le32_to_cpu(tmp->entry_offset);
ulong count = le32_to_cpu(tmp->entry_count);
while (count--) {
ulong type = le32_to_cpu(ent->hdr.type);
ent = qla27xx_find_entry(type)(vha, ent, buf, len);
if (!ent)
break;
}
}
I chopped out some of the code that was not relevant, but this still compiles ok (using gnu c).
edit: also see 2nd image for minor variation (typeof is already a pointer to function).