]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_setexpr.c
setexpr: simplify code, improve help message
[karo-tx-uboot.git] / common / cmd_setexpr.c
1 /*
2  * Copyright 2008 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 /*
24  * This file provides a shell like 'expr' function to return.
25  */
26
27 #include <common.h>
28 #include <config.h>
29 #include <command.h>
30
31 static ulong get_arg(char *s, int w)
32 {
33         ulong *p;
34
35         /*
36          * if the parameter starts with a '*' then assume
37          * it is a pointer to the value we want
38          */
39
40         if (s[0] == '*') {
41                 p = (ulong *)simple_strtoul(&s[1], NULL, 16);
42                 switch (w) {
43                 case 1: return((ulong)(*(uchar *)p));
44                 case 2: return((ulong)(*(ushort *)p));
45                 case 4:
46                 default: return(*p);
47                 }
48         } else {
49                 return simple_strtoul(s, NULL, 16);
50         }
51 }
52
53 static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
54 {
55         ulong a, b;
56         ulong value;
57         int w;
58
59         if (argc < 3)
60                 return CMD_RET_USAGE;
61
62         w = cmd_get_data_size(argv[0], 4);
63
64         a = get_arg(argv[2], w);
65
66         /* plain assignment: "setexpr name value" */
67         if (argc == 3) {
68                 setenv_hex(argv[1], a);
69                 return 0;
70         }
71
72         /* standard operators: "setexpr name val1 op val2" */
73         if (argc != 5)
74                 return CMD_RET_USAGE;
75
76         if (strlen(argv[3]) != 1)
77                 return CMD_RET_USAGE;
78
79         b = get_arg(argv[4], w);
80
81         switch (argv[3][0]) {
82         case '|':
83                 value = a | b;
84                 break;
85         case '&':
86                 value = a & b;
87                 break;
88         case '+':
89                 value = a + b;
90                 break;
91         case '^':
92                 value = a ^ b;
93                 break;
94         case '-':
95                 value = a - b;
96                 break;
97         case '*':
98                 value = a * b;
99                 break;
100         case '/':
101                 value = a / b;
102                 break;
103         case '%':
104                 value = a % b;
105                 break;
106         default:
107                 printf("invalid op\n");
108                 return 1;
109         }
110
111         setenv_hex(argv[1], value);
112
113         return 0;
114 }
115
116 U_BOOT_CMD(
117         setexpr, 5, 0, do_setexpr,
118         "set environment variable as the result of eval expression",
119         "[.b, .w, .l] name [*]value1 <op> [*]value2\n"
120         "    - set environment variable 'name' to the result of the evaluated\n"
121         "      express specified by <op>.  <op> can be &, |, ^, +, -, *, /, %\n"
122         "      size argument is only meaningful if value1 and/or value2 are\n"
123         "      memory addresses (*)\n"
124         "setexpr[.b, .w, .l] name [*]value\n"
125         "    - load a value into a variable"
126 );