]> git.sur5r.net Git - openocd/blob - src/helper/interpreter.c
- Added support for native MinGW builds (thanks to Spencer Oliver and Michael Fischer...
[openocd] / 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, COMMAND_EXEC);
235         
236         cmd_ctx->echo = echo;
237         
238         fclose(script_file);
239
240         return ERROR_OK;
241 }