Trivial map, integer-indexed:
static const int mon_lengths[2][MONSPERYEAR] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
The following map is used to dispatch functions based on the
name of the command:
#define F_NEEDARG 0x01 /* needs an argument */
#define F_OFFOK 0x02 /* can turn off */
static struct key {
char *name; /* name */
void (*f) __P((struct info *)); /* function */
int flags;
} keys[] = {
{ "all", f_all, 0 },
{ "cbreak", f_cbreak, F_OFFOK },
{ "cols", f_columns, F_NEEDARG },
{ "columns", f_columns, F_NEEDARG },
{ "cooked", f_sane, 0 },
{ "dec", f_dec, 0 },
{ "everything", f_everything, 0 },
{ "extproc", f_extproc, F_OFFOK },
/* [...] */
{ "size", f_size, 0 },
{ "speed", f_speed, 0 },
{ "tty", f_tty, 0 },
};
static int c_key __P((const void *, const void *));
static int
c_key(a, b)
const void *a, *b;
{
return (strcmp(((struct key *)a)->name, ((struct key *)b)->name));
}
int
ksearch(argvp, ip)
char ***argvp;
struct info *ip;
{
char *name;
struct key *kp, tmp;
name = **argvp;
if (*name == '-') {
ip->off = 1;
++name;
} else
ip->off = 0;
tmp.name = name;
if (!(kp = (struct key *)bsearch(&tmp, keys,
sizeof(keys)/sizeof(struct key), sizeof(struct key), c_key)))
return (0);
if (!(kp->flags & F_OFFOK) && ip->off) {
warnx("illegal option -- %s", name);
usage();
}
if (kp->flags & F_NEEDARG && !(ip->arg = *++*argvp)) {
warnx("option requires an argument -- %s", name);
usage();
}
kp->f(ip);
return (1);
}
void
f_all(ip)
struct info *ip;
{
print(&ip->t, &ip->win, ip->ldisc, BSD);
}