- prepare OpenOCD for branching, created ./trunk/
[fw/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 #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 }