Use CONFIG_TPLINK_IMAGE_HEADER define to select TP-Link img header, plus minor change...
[oweals/u-boot_mod.git] / u-boot / common / command.c
1 /*
2  * (C) Copyright 2000-2003
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier: GPL-2.0
6  */
7
8 /* Command Processor Table */
9 #include <common.h>
10 #include <command.h>
11
12 int do_version(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
13 {
14         extern char version_string[];
15
16         puts("Version and build date:\n");
17         printf("  %s\n  " __DATE__ ", " __TIME__ "\n\n", version_string);
18
19         puts("Modification by:\n");
20         puts("  Piotr Dymacz <piotr@dymacz.pl>\n");
21         puts("  https://github.com/pepe2k/u-boot_mod\n\n");
22
23         return 0;
24 }
25
26 U_BOOT_CMD(version, 1, 1, do_version,
27                    "print U-Boot version\n",
28                    NULL);
29
30 #if (CONFIG_COMMANDS & CFG_CMD_ECHO)
31 int do_echo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
32 {
33         int i, putnl = 1;
34
35         for (i = 1; i < argc; i++) {
36                 char *p = argv[i], c;
37
38                 if (i > 1)
39                         putc(' ');
40
41                 while ((c = *p++) != '\0') {
42                         if (c == '\\' && *p == 'c') {
43                                 putnl = 0;
44                                 p++;
45                         } else {
46                                 putc(c);
47                         }
48                 }
49         }
50
51         if (putnl)
52                 putc('\n');
53
54         return 0;
55 }
56
57 U_BOOT_CMD(echo, CFG_MAXARGS, 1, do_echo,
58                    "echo args to console\n",
59                    "[args..]\n" "\t- echo args to console; \\c suppresses newline\n");
60 #endif  /*  CFG_CMD_ECHO */
61
62 #ifdef CFG_HUSH_PARSER
63 int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
64 {
65         int left, adv, expr, last_expr, neg, last_cmp;
66         char **ap;
67
68         /* args? */
69         if (argc < 3)
70                 return 1;
71
72         last_expr = 0;
73         left = argc - 1;
74         ap = argv + 1;
75
76         if (left > 0 && strcmp(ap[0], "!") == 0) {
77                 neg = 1;
78                 ap++;
79                 left--;
80         } else {
81                 neg = 0;
82         }
83
84         expr = -1;
85         last_cmp = -1;
86         last_expr = -1;
87
88         while (left > 0) {
89                 if (strcmp(ap[0], "-o") == 0 || strcmp(ap[0], "-a") == 0) {
90                         adv = 1;
91                 } else if (strcmp(ap[0], "-z") == 0 || strcmp(ap[0], "-n") == 0) {
92                         adv = 2;
93                 } else {
94                         adv = 3;
95                 }
96
97                 if (left < adv) {
98                         expr = 1;
99                         break;
100                 }
101
102                 if (adv == 1) {
103                         if (strcmp(ap[0], "-o") == 0) {
104                                 last_expr = expr;
105                                 last_cmp = 0;
106                         } else if (strcmp(ap[0], "-a") == 0) {
107                                 last_expr = expr;
108                                 last_cmp = 1;
109                         } else {
110                                 expr = 1;
111                                 break;
112                         }
113                 }
114
115                 if (adv == 2) {
116                         if (strcmp(ap[0], "-z") == 0) {
117                                 expr = strlen(ap[1]) == 0 ? 1 : 0;
118                         } else if (strcmp(ap[0], "-n") == 0) {
119                                 expr = strlen(ap[1]) == 0 ? 0 : 1;
120                         } else {
121                                 expr = 1;
122                                 break;
123                         }
124
125                         if (last_cmp == 0) {
126                                 expr = last_expr || expr;
127                         } else if (last_cmp == 1) {
128                                 expr = last_expr && expr;
129                         }
130
131                         last_cmp = -1;
132                 }
133
134                 if (adv == 3) {
135                         if (strcmp(ap[1], "=") == 0) {
136                                 expr = strcmp(ap[0], ap[2]) == 0;
137                         } else if (strcmp(ap[1], "!=") == 0) {
138                                 expr = strcmp(ap[0], ap[2]) != 0;
139                         } else if (strcmp(ap[1], ">") == 0) {
140                                 expr = strcmp(ap[0], ap[2]) > 0;
141                         } else if (strcmp(ap[1], "<") == 0) {
142                                 expr = strcmp(ap[0], ap[2]) < 0;
143                         } else if (strcmp(ap[1], "-eq") == 0) {
144                                 expr = simple_strtol(ap[0], NULL, 10) == simple_strtol(ap[2], NULL, 10);
145                         } else if (strcmp(ap[1], "-ne") == 0) {
146                                 expr = simple_strtol(ap[0], NULL, 10) != simple_strtol(ap[2], NULL, 10);
147                         } else if (strcmp(ap[1], "-lt") == 0) {
148                                 expr = simple_strtol(ap[0], NULL, 10) < simple_strtol(ap[2], NULL, 10);
149                         } else if (strcmp(ap[1], "-le") == 0) {
150                                 expr = simple_strtol(ap[0], NULL, 10) <= simple_strtol(ap[2], NULL, 10);
151                         } else if (strcmp(ap[1], "-gt") == 0) {
152                                 expr = simple_strtol(ap[0], NULL, 10) > simple_strtol(ap[2], NULL, 10);
153                         } else if (strcmp(ap[1], "-ge") == 0) {
154                                 expr = simple_strtol(ap[0], NULL, 10) >= simple_strtol(ap[2], NULL, 10);
155                         } else {
156                                 expr = 1;
157                                 break;
158                         }
159
160                         if (last_cmp == 0) {
161                                 expr = last_expr || expr;
162                         } else if (last_cmp == 1) {
163                                 expr = last_expr && expr;
164                         }
165
166                         last_cmp = -1;
167                 }
168
169                 ap += adv; left -= adv;
170         }
171
172         if (neg)
173                 expr = !expr;
174
175         expr = !expr;
176
177         return expr;
178 }
179
180 U_BOOT_CMD(test, CFG_MAXARGS, 1, do_test,
181                    "minimal test like /bin/sh\n",
182                    "[args..]\n\t- test functionality\n");
183
184 int do_exit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
185 {
186         int r = 0;
187
188         if (argc > 1)
189                 r = simple_strtoul(argv[1], NULL, 10);
190
191         return (-r - 2);
192 }
193
194 U_BOOT_CMD(exit, 2, 1, do_exit,
195                    "exit script\n",
196                    "\n\t- exit functionality\n");
197 #endif /* CFG_HUSH_PARSER */
198
199 /*
200  * Use puts() instead of printf() to avoid printf buffer overflow
201  * for long help messages
202  */
203 int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
204 {
205         int i;
206         int rcode = 0;
207
208         /* Show list of commands */
209         if (argc == 1) {
210                 /* Pointer arith! */
211                 int cmd_items = &__u_boot_cmd_end - &__u_boot_cmd_start;
212
213                 cmd_tbl_t *cmd_array[cmd_items];
214                 int i, j, swaps, max_len = 0;
215
216                 /* Make array of commands from .uboot_cmd section */
217                 cmdtp = &__u_boot_cmd_start;
218
219                 for (i = 0; i < cmd_items; i++) {
220                         cmd_array[i] = cmdtp++;
221                 }
222
223                 /* Sort command list (trivial bubble sort) */
224                 for (i = cmd_items - 1; i > 0; --i) {
225                         swaps = 0;
226                         for (j = 0; j < i; ++j) {
227                                 const char *name = cmd_array[j]->name;
228
229                                 if (strlen(name) >= max_len)
230                                         max_len = strlen(name);
231
232                                 if (strcmp(cmd_array[j]->name, cmd_array[j + 1]->name) > 0) {
233                                         cmd_tbl_t *tmp;
234                                         tmp = cmd_array[j];
235                                         cmd_array[j] = cmd_array[j + 1];
236                                         cmd_array[j + 1] = tmp;
237                                         ++swaps;
238                                 }
239                         }
240
241                         if (!swaps)
242                                 break;
243                 }
244
245                 /* Print short help (usage) */
246                 for (i = 0; i < cmd_items; i++) {
247                         const char *usage = cmd_array[i]->usage;
248                         const char *name = cmd_array[i]->name;
249
250                         /* Allow user abort */
251                         if (ctrlc())
252                                 return 1;
253
254                         if (usage == NULL)
255                                 continue;
256
257                         /* Print aligned command name and usage */
258                         printf("%-*s - ", max_len, name);
259                         puts(usage);
260                 }
261
262                 puts("\n");
263                 return 0;
264         }
265
266         /* Command help (long version) */
267         for (i = 1; i < argc; ++i) {
268                 if ((cmdtp = find_cmd(argv[i])) != NULL) {
269 #ifdef  CFG_LONGHELP
270                         /* Found - print (long) help info */
271                         puts(cmdtp->name);
272                         putc(' ');
273
274                         if (cmdtp->help) {
275                                 puts(cmdtp->help);
276                         } else {
277                                 puts("- there is no help for this command\n");
278                                 rcode = 1;
279                         }
280
281                         putc('\n');
282 #else
283                         if (cmdtp->usage)
284                                 puts(cmdtp->usage);
285 #endif  /* CFG_LONGHELP */
286                 } else {
287                         printf("Unknown command '%s' - try 'help' without arguments\n\n", argv[i]);
288                         rcode = 1;
289                 }
290         }
291
292         return rcode;
293 }
294
295 U_BOOT_CMD(help, CFG_MAXARGS, 1, do_help,
296                    "print embedded help\n",
297                    "[command ...]\n"
298                    "\t- show help information (for 'command')\n"
299                         "\twithout arguments, it prints a short usage message for available commands.\n");
300
301 /* This do not ust the U_BOOT_CMD macro as ? can't be used in symbol names */
302 #ifdef CFG_LONGHELP
303 cmd_tbl_t __u_boot_cmd_question_mark Struct_Section = {"?", CFG_MAXARGS, 1, do_help, "alias for 'help'\n", NULL};
304 #else
305 cmd_tbl_t __u_boot_cmd_question_mark Struct_Section = {"?", CFG_MAXARGS, 1, do_help, "alias for 'help'\n"};
306 #endif /* CFG_LONGHELP */
307
308 /*
309  * Find command table entry for a command
310  */
311 cmd_tbl_t *find_cmd(const char *cmd)
312 {
313         cmd_tbl_t *cmdtp;
314         cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start; /*Init value */
315         const char *p;
316         int len;
317         int n_found = 0;
318
319         /*
320          * Some commands allow length modifiers (like "cp.b");
321          * compare command name only until first dot.
322          */
323         len = ((p = strchr(cmd, '.')) == NULL) ? strlen(cmd) : (p - cmd);
324
325         for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
326                 if (strncmp(cmd, cmdtp->name, len) == 0) {
327                         /* Full match? */
328                         if (len == strlen(cmdtp->name))
329                                 return cmdtp;
330
331                         /* Abbreviated command ? */
332                         cmdtp_temp = cmdtp;
333                         n_found++;
334                 }
335         }
336
337         /* Exactly one match */
338         if (n_found == 1)
339                 return(cmdtp_temp);
340
341         /* Not found or ambiguous command */
342         return NULL;
343 }