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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)