aboutsummaryrefslogtreecommitdiff
path: root/cli/cli-example.c
blob: 941ddd6e79e75fb9312caa9ad2ae4bd3e3dec026 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
 * silly simple example program
 */
#include "cli.h"

CLI_OPT_LONG(distance, 'd', "distance", "the distance (km/miles)");
CLI_OPT_LONG(speed, 's', "speed", "the speed ((km/miles)ph)");
CLI_OPT_LONG(time, 't', "time", "the time (seconds)");
CLI_OPT_FLAG(murica, 'M', "murica", "Use American™ measurements");

int calc_speed(const struct cli_cmd *, const struct cli_ctx *)
{
	if (time.value == 0) {
		fprintf(stderr, "time cannot be zero\n");
		return CLI_RC_BAD_ARGS;
	}
	double speed = (double)distance.value / ((double)time.value / 3600);
	printf("%lf%s\n", speed, murica.value ? "mph" : "km/h");

	return CLI_RC_OK;
}

int calc_distance(const struct cli_cmd *, const struct cli_ctx *)
{
	double distance = speed.value * ((double)time.value / 3600);
	printf("%lf%s\n", distance, murica.value ? "miles" : "km");

	return CLI_RC_OK;
}

struct cli_opt *speed_opts[]	= {&distance.opt, &time.opt, NULL};
struct cli_opt *distance_opts[] = {&speed.opt, &time.opt, NULL};

const struct cli_cmd my_cmds[] = {
	{
		.name = "speed",
		.desc = "calculate speed",
		.help =
			"Tell me the distance and the time, and I'll tell you your speed",
		.opts = speed_opts,
		.run  = calc_speed,
	},
	{
		.name = "distance",
		.desc = "calculate distance",
		.help =
			"Tell me the speed and the time, and I'll tell you your distance",
		.opts = distance_opts,
		.run  = calc_distance,
	},
	{0},
};

struct cli_opt *global_opts[] = {&murica.opt, NULL};

struct cli my_cli = {
	.header = "This is an example CLI program",
	.footer = "\nCopyright (c) 2025 Yaroslav de la Peña Smirnov "
			  "<yps@yaroslavps.com>",
	.cmds	= my_cmds,
	.opts	= global_opts,
};

int main(int argc, char *argv[])
{
	return cli_run(&my_cli, argc, argv);
}