85cd71586dcd9a820c11b58a1681d97490ededa9
[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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "interpreter.h"
25
26 #include "binarybuffer.h"
27 #include <stdlib.h>
28 #include <string.h>
29
30 var_t *variables = NULL;
31
32 int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
33 int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
34 int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
35
36 int interpreter_register_commands(struct command_context_s *cmd_ctx)
37 {
38 register_command(cmd_ctx, NULL, "var", handle_var_command,
39 COMMAND_ANY, "allocate, display or delete variable <name> [num_fields|'del'] [size1] ...");
40 register_command(cmd_ctx, NULL, "field", handle_field_command,
41 COMMAND_ANY, "display/modify variable field <var> <field> [value|'flip']");
42 register_command(cmd_ctx, NULL, "script", handle_script_command,
43 COMMAND_ANY, "execute commands from <file>");
44
45 return ERROR_OK;
46 }
47
48 var_t* get_var_by_num(int num)
49 {
50 int count = 0;
51 var_t *var = variables;
52
53 if (var)
54 {
55 if (num == count)
56 return var;
57 while (var->next)
58 {
59 var = var->next;
60 count++;
61 if (num == count)
62 return var;
63 }
64 }
65 return NULL;
66 }
67
68 var_t* get_var_by_name(char *name)
69 {
70 var_t *var = variables;
71
72 if (var)
73 {
74 if (strcmp(var->name, name) == 0)
75 return var;
76 while (var->next)
77 {
78 var = var->next;
79 if (strcmp(var->name, name) == 0)
80 return var;
81 }
82 }
83 return NULL;
84 }
85
86 var_t* get_var_by_namenum(char *namenum)
87 {
88 if ((namenum[0] >= '0') && (namenum[0] <= '9'))
89 return get_var_by_num(strtol(namenum, NULL, 0));
90 else
91 return get_var_by_name(namenum);
92
93 }
94
95 int field_le_to_host(u8 *buffer, void *priv)
96 {
97 var_field_t *field = priv;
98 field->value = buf_get_u32(buffer, 0, field->num_bits);
99
100 return ERROR_OK;
101 }
102
103 int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
104 {
105 var_t **last_var_p = &variables;
106 int i;
107
108 if (argc >= 2)
109 {
110 while (*last_var_p)
111 {
112 if (strcmp((*last_var_p)->name, args[0]) == 0)
113 {
114 if (strcmp(args[1], "del") == 0)
115 {
116 var_t *next = (*last_var_p)->next;
117 free ((*last_var_p)->fields);
118 free (*last_var_p);
119 *last_var_p = next;
120 command_print(cmd_ctx, "variable %s deleted", args[0]);
121 }
122 else
123 command_print(cmd_ctx, "variable of that name already exists");
124 return ERROR_OK;
125 }
126 last_var_p = &((*last_var_p)->next);
127 }
128
129 if ((args[0][0] >= '0') && (args[0][0] <= '9'))
130 {
131 command_print(cmd_ctx, "invalid name specified (first character may not be a number)");
132 return ERROR_OK;
133 }
134
135 *last_var_p = malloc(sizeof(var_t));
136 (*last_var_p)->name = strdup(args[0]);
137 (*last_var_p)->num_fields = argc - 1;
138 (*last_var_p)->next = NULL;
139
140 (*last_var_p)->fields = malloc(sizeof(var_field_t) * (*last_var_p)->num_fields);
141 for (i = 0; i < (*last_var_p)->num_fields; i++)
142 {
143 (*last_var_p)->fields[i].num_bits = strtol(args[1+i], NULL, 0);
144 (*last_var_p)->fields[i].value = 0x0;
145 }
146 return ERROR_OK;
147 }
148
149 if (argc == 1)
150 {
151 var_t *var = get_var_by_namenum(args[0]);
152 if (var)
153 {
154 int i;
155 command_print(cmd_ctx, "%s (%i fields):", var->name, var->num_fields);
156 for (i = 0; i < (var->num_fields); i++)
157 {
158 command_print(cmd_ctx, "0x%x (/%i)", var->fields[i].value, var->fields[i].num_bits);
159 }
160 }
161 else
162 {
163 command_print(cmd_ctx, "variable %s doesn't exist", args[0]);
164 }
165 }
166
167 if (argc == 0)
168 {
169 var_t *var = variables;
170 int count = 0;
171 while (var)
172 {
173 command_print(cmd_ctx, "%i: %s (%i fields)", count, var->name, var->num_fields);
174 var = var->next;
175 count++;
176 }
177 }
178
179 return ERROR_OK;
180 }
181
182 int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
183 {
184
185 if (argc < 2)
186 command_print(cmd_ctx, "usage: field <var> <field> [value|'flip']");
187
188 if (argc >= 2)
189 {
190 var_t *var = get_var_by_namenum(args[0]);
191 int field_num = strtol(args[1], NULL, 0);
192 if (!var)
193 {
194 command_print(cmd_ctx, "variable %s doesn't exist", args[0]);
195 return ERROR_OK;
196 }
197 if (field_num >= var->num_fields)
198 command_print(cmd_ctx, "variable field %i is out of bounds (max. %i)", field_num, var->num_fields - 1);
199 if ((var) && (field_num < var->num_fields))
200 {
201 if (argc > 2)
202 {
203 if (strcmp(args[2], "flip") == 0)
204 var->fields[field_num].value = flip_u32(var->fields[field_num].value, var->fields[field_num].num_bits);
205 else
206 var->fields[field_num].value = strtoul(args[2], NULL, 0);
207 }
208
209 command_print(cmd_ctx, "%s(%i): 0x%x (/%i)", var->name, field_num, var->fields[field_num].value, var->fields[field_num].num_bits);
210 }
211 }
212
213 return ERROR_OK;
214 }
215
216 int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
217 {
218 FILE *script_file;
219 int echo;
220
221 if (argc != 1)
222 command_print(cmd_ctx, "usage: script <file>");
223
224 script_file = fopen(args[0], "r");
225 if (!script_file)
226 {
227 command_print(cmd_ctx, "couldn't open script file %s", args[0]);
228 return ERROR_OK;
229 }
230
231 echo = cmd_ctx->echo;
232 cmd_ctx->echo = 1;
233
234 command_run_file(cmd_ctx, script_file, cmd_ctx->mode);
235
236 cmd_ctx->echo = echo;
237
238 fclose(script_file);
239
240 return ERROR_OK;
241 }

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)