- "flash write_binary" is now "flash write_bank" to clarify the focus of the
[fw/openocd] / src / helper / interpreter.c
1 /***************************************************************************\r
2  *   Copyright (C) 2005 by Dominic Rath                                    *\r
3  *   Dominic.Rath@gmx.de                                                   *\r
4  *                                                                         *\r
5  *   This program is free software; you can redistribute it and/or modify  *\r
6  *   it under the terms of the GNU General Public License as published by  *\r
7  *   the Free Software Foundation; either version 2 of the License, or     *\r
8  *   (at your option) any later version.                                   *\r
9  *                                                                         *\r
10  *   This program is distributed in the hope that it will be useful,       *\r
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
13  *   GNU General Public License for more details.                          *\r
14  *                                                                         *\r
15  *   You should have received a copy of the GNU General Public License     *\r
16  *   along with this program; if not, write to the                         *\r
17  *   Free Software Foundation, Inc.,                                       *\r
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
19  ***************************************************************************/\r
20 #ifdef HAVE_CONFIG_H\r
21 #include "config.h"\r
22 #endif\r
23 \r
24 #include "interpreter.h"\r
25 #include "configuration.h"\r
26 \r
27 #include "binarybuffer.h"\r
28 #include <stdlib.h>\r
29 #include <string.h>\r
30 \r
31 var_t *variables = NULL;\r
32 \r
33 int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
34 int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
35 int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
36 \r
37 int interpreter_register_commands(struct command_context_s *cmd_ctx)\r
38 {\r
39         register_command(cmd_ctx, NULL, "var", handle_var_command,\r
40                 COMMAND_ANY, "allocate, display or delete variable <name> [num_fields|'del'] [size1] ...");\r
41         register_command(cmd_ctx, NULL, "field", handle_field_command,\r
42                 COMMAND_ANY, "display/modify variable field <var> <field> [value|'flip']");\r
43         register_command(cmd_ctx, NULL, "script", handle_script_command,\r
44                 COMMAND_ANY, "execute commands from <file>");\r
45 \r
46         return ERROR_OK;\r
47 }\r
48 \r
49 var_t* get_var_by_num(int num)\r
50 {\r
51         int count = 0;\r
52         var_t *var = variables;\r
53 \r
54         if (var)        \r
55         {\r
56                 if (num == count)\r
57                         return var;\r
58                 while (var->next)\r
59                 {\r
60                         var = var->next;\r
61                         count++;\r
62                         if (num == count)\r
63                                 return var;\r
64                 }\r
65         }\r
66         return NULL;\r
67 }\r
68 \r
69 var_t* get_var_by_name(char *name)\r
70 {\r
71         var_t *var = variables;\r
72 \r
73         if (var)        \r
74         {\r
75                 if (strcmp(var->name, name) == 0)\r
76                         return var;\r
77                 while (var->next)\r
78                 {\r
79                         var = var->next;\r
80                         if (strcmp(var->name, name) == 0)\r
81                                 return var;\r
82                 }\r
83         }\r
84         return NULL;\r
85 }\r
86 \r
87 var_t* get_var_by_namenum(char *namenum)\r
88 {\r
89         if ((namenum[0] >= '0') && (namenum[0] <= '9'))\r
90                 return get_var_by_num(strtol(namenum, NULL, 0));\r
91         else\r
92                 return get_var_by_name(namenum);\r
93         \r
94 }\r
95 \r
96 int field_le_to_host(u8 *buffer, void *priv, struct scan_field_s *dummy)\r
97 {\r
98         var_field_t *field = priv;\r
99         field->value = buf_get_u32(buffer, 0, field->num_bits);\r
100 \r
101         return ERROR_OK;\r
102 }\r
103 \r
104 int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
105 {\r
106         var_t **last_var_p = &variables;\r
107         int i;\r
108 \r
109         if (argc >= 2)\r
110         {\r
111                 while (*last_var_p)\r
112                 {\r
113                         if (strcmp((*last_var_p)->name, args[0]) == 0)\r
114                         {\r
115                                 if (strcmp(args[1], "del") == 0)\r
116                                 {\r
117                                         var_t *next = (*last_var_p)->next;\r
118                                         free ((*last_var_p)->fields);\r
119                                         free (*last_var_p);\r
120                                         *last_var_p = next;\r
121                                         command_print(cmd_ctx, "variable %s deleted", args[0]);\r
122                                 }\r
123                                 else\r
124                                         command_print(cmd_ctx, "variable of that name already exists");\r
125                                 return ERROR_OK;\r
126                         }\r
127                         last_var_p = &((*last_var_p)->next);\r
128                 }\r
129 \r
130                 if ((args[0][0] >= '0') && (args[0][0] <= '9'))\r
131                 {\r
132                         command_print(cmd_ctx, "invalid name specified (first character may not be a number)");\r
133                         return ERROR_OK;\r
134                 }\r
135 \r
136                 *last_var_p = malloc(sizeof(var_t));\r
137                 (*last_var_p)->name = strdup(args[0]);\r
138                 (*last_var_p)->num_fields = argc - 1;\r
139                 (*last_var_p)->next = NULL;\r
140 \r
141                 (*last_var_p)->fields = malloc(sizeof(var_field_t) * (*last_var_p)->num_fields);\r
142                 for (i = 0; i < (*last_var_p)->num_fields; i++)\r
143                 {\r
144                         (*last_var_p)->fields[i].num_bits = strtol(args[1+i], NULL, 0);\r
145                         (*last_var_p)->fields[i].value = 0x0;\r
146                 }\r
147                 return ERROR_OK;\r
148         }\r
149 \r
150         if (argc == 1)\r
151         {\r
152                 var_t *var = get_var_by_namenum(args[0]);\r
153                 if (var)\r
154                 {\r
155                         int i;\r
156                         command_print(cmd_ctx, "%s (%i fields):", var->name, var->num_fields);\r
157                         for (i = 0; i < (var->num_fields); i++)\r
158                         {\r
159                                 command_print(cmd_ctx, "0x%x (/%i)", var->fields[i].value, var->fields[i].num_bits);\r
160                         }\r
161                 }\r
162                 else\r
163                 {\r
164                         command_print(cmd_ctx, "variable %s doesn't exist", args[0]);\r
165                 }\r
166         }\r
167 \r
168         if (argc == 0)\r
169         {\r
170                 var_t *var = variables;\r
171                 int count = 0;\r
172                 while (var)\r
173                 {\r
174                         command_print(cmd_ctx, "%i: %s (%i fields)", count, var->name, var->num_fields);\r
175                         var = var->next;\r
176                         count++;\r
177                 }\r
178         }\r
179 \r
180         return ERROR_OK;\r
181 }\r
182 \r
183 int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
184 {\r
185 \r
186         if (argc < 2)\r
187                 return ERROR_COMMAND_SYNTAX_ERROR;\r
188 \r
189         if (argc >= 2)\r
190         {\r
191                 var_t *var = get_var_by_namenum(args[0]);\r
192                 int field_num = strtol(args[1], NULL, 0);\r
193                 if (!var)\r
194                 {\r
195                         command_print(cmd_ctx, "variable %s doesn't exist", args[0]);\r
196                         return ERROR_OK;\r
197                 }\r
198                 if (field_num >= var->num_fields)\r
199                         command_print(cmd_ctx, "variable field %i is out of bounds (max. %i)", field_num, var->num_fields - 1);\r
200                 if ((var) && (field_num < var->num_fields))\r
201                 {\r
202                         if (argc > 2)\r
203                         {\r
204                                 if (strcmp(args[2], "flip") == 0)\r
205                                         var->fields[field_num].value = flip_u32(var->fields[field_num].value, var->fields[field_num].num_bits);\r
206                                 else\r
207                                         var->fields[field_num].value = strtoul(args[2], NULL, 0);\r
208                         }\r
209 \r
210                         command_print(cmd_ctx, "%s(%i): 0x%x (/%i)", var->name, field_num, var->fields[field_num].value, var->fields[field_num].num_bits);\r
211                 }\r
212         }\r
213 \r
214         return ERROR_OK;\r
215 }\r
216 \r
217 int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
218 {\r
219         FILE *script_file;\r
220         int echo;\r
221 \r
222         if (argc != 1)\r
223                 return ERROR_COMMAND_SYNTAX_ERROR;\r
224 \r
225         script_file = open_file_from_path(cmd_ctx, args[0], "r");\r
226 \r
227         if (!script_file)\r
228         {\r
229                 command_print(cmd_ctx, "couldn't open script file %s", args[0]);\r
230                 return ERROR_OK;\r
231         }\r
232 \r
233         echo = cmd_ctx->echo;\r
234         cmd_ctx->echo = 1;\r
235         \r
236         command_run_file(cmd_ctx, script_file, cmd_ctx->mode);\r
237         \r
238         cmd_ctx->echo = echo;\r
239         \r
240         fclose(script_file);\r
241 \r
242         return ERROR_OK;\r
243 }\r