/src/barebox/commands/magicvar.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-only |
2 | | |
3 | | #include <common.h> |
4 | | #include <command.h> |
5 | | #include <getopt.h> |
6 | | #include <environment.h> |
7 | | #include <magicvar.h> |
8 | | #include <malloc.h> |
9 | | |
10 | | static LIST_HEAD(magicvars); |
11 | | |
12 | | struct magicvar_dyn { |
13 | | const char *name; |
14 | | const char *description; |
15 | | struct list_head list; |
16 | | }; |
17 | | |
18 | | static void magicvar_print_one(struct magicvar_dyn *md, int verbose) |
19 | 0 | { |
20 | 0 | printf("%-32s %s\n", md->name, md->description); |
21 | |
|
22 | 0 | if (verbose) { |
23 | 0 | const char *val = getenv(md->name); |
24 | 0 | if (val && strlen(val)) |
25 | 0 | printf(" %s\n", val); |
26 | 0 | } |
27 | 0 | } |
28 | | |
29 | | static struct magicvar_dyn *magicvar_find(const char *name) |
30 | 0 | { |
31 | 0 | struct magicvar_dyn *md; |
32 | |
|
33 | 0 | list_for_each_entry(md, &magicvars, list) |
34 | 0 | if (!strcmp(md->name, name)) |
35 | 0 | return md; |
36 | | |
37 | 0 | return NULL; |
38 | 0 | } |
39 | | |
40 | | static void magicvar_remove(struct magicvar_dyn *md) |
41 | 0 | { |
42 | 0 | free_const(md->name); |
43 | 0 | free_const(md->description); |
44 | 0 | list_del(&md->list); |
45 | 0 | free(md); |
46 | 0 | } |
47 | | |
48 | | static int compare(struct list_head *a, struct list_head *b) |
49 | 0 | { |
50 | 0 | char *na = (char*)list_entry(a, struct magicvar_dyn, list)->name; |
51 | 0 | char *nb = (char*)list_entry(b, struct magicvar_dyn, list)->name; |
52 | |
|
53 | 0 | return strcmp(na, nb); |
54 | 0 | } |
55 | | |
56 | | static int magicvar_add(const char *name, const char *description) |
57 | 0 | { |
58 | 0 | struct magicvar_dyn *md; |
59 | |
|
60 | 0 | md = magicvar_find(name); |
61 | 0 | if (md) |
62 | 0 | magicvar_remove(md); |
63 | |
|
64 | 0 | md = xzalloc(sizeof(*md)); |
65 | 0 | md->name = xstrdup_const(name); |
66 | 0 | md->description = xstrdup_const(description); |
67 | |
|
68 | 0 | list_add_sort(&md->list, &magicvars, compare); |
69 | |
|
70 | 0 | return 0; |
71 | 0 | } |
72 | | |
73 | | static void magicvar_build(void) |
74 | 0 | { |
75 | 0 | static int first = 1; |
76 | 0 | struct magicvar *m; |
77 | |
|
78 | 0 | if (!first) |
79 | 0 | return; |
80 | | |
81 | 0 | for (m = &__barebox_magicvar_start; |
82 | 0 | m != &__barebox_magicvar_end; |
83 | 0 | m++) |
84 | 0 | magicvar_add(m->name, m->description); |
85 | |
|
86 | 0 | first = 0; |
87 | 0 | } |
88 | | |
89 | | static int do_magicvar(int argc, char *argv[]) |
90 | 0 | { |
91 | 0 | struct magicvar_dyn *md; |
92 | 0 | int opt; |
93 | 0 | int verbose = 0, add = 0; |
94 | |
|
95 | 0 | magicvar_build(); |
96 | |
|
97 | 0 | while ((opt = getopt(argc, argv, "va")) > 0) { |
98 | 0 | switch (opt) { |
99 | 0 | case 'v': |
100 | 0 | verbose = 1; |
101 | 0 | break; |
102 | 0 | case 'a': |
103 | 0 | add = 1; |
104 | 0 | break; |
105 | 0 | default: |
106 | 0 | return COMMAND_ERROR_USAGE; |
107 | 0 | } |
108 | 0 | } |
109 | | |
110 | 0 | if (add) { |
111 | 0 | if (optind + 2 != argc) |
112 | 0 | return COMMAND_ERROR_USAGE; |
113 | | |
114 | 0 | return magicvar_add(argv[optind], argv[optind + 1]); |
115 | 0 | } |
116 | | |
117 | 0 | list_for_each_entry(md, &magicvars, list) |
118 | 0 | magicvar_print_one(md, verbose); |
119 | |
|
120 | 0 | return 0; |
121 | 0 | } |
122 | | |
123 | | |
124 | | BAREBOX_CMD_HELP_START(magicvar) |
125 | | BAREBOX_CMD_HELP_TEXT("Options:") |
126 | | BAREBOX_CMD_HELP_OPT ("-v", "verbose (list all value if there is one)") |
127 | | BAREBOX_CMD_HELP_OPT ("-a <NAME> <DESC>", "Add a new magicvar") |
128 | | BAREBOX_CMD_HELP_END |
129 | | |
130 | | BAREBOX_CMD_START(magicvar) |
131 | | .cmd = do_magicvar, |
132 | | BAREBOX_CMD_DESC("list information about magic variables") |
133 | | BAREBOX_CMD_OPTS("[-va]") |
134 | | BAREBOX_CMD_HELP(cmd_magicvar_help) |
135 | | BAREBOX_CMD_GROUP(CMD_GRP_ENV) |
136 | | BAREBOX_CMD_END |