sim: add missing values to array initializers
[deliverable/binutils-gdb.git] / sim / common / hw-ports.c
CommitLineData
c906108c 1/* Hardware ports.
dc3cf14f 2 Copyright (C) 1998, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
c906108c
SS
3 Contributed by Andrew Cagney and Cygnus Solutions.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4744ac1b
JB
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
c906108c
SS
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
4744ac1b
JB
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
19
20
21#include "hw-main.h"
22#include "hw-base.h"
23
24#ifdef HAVE_STDLIB_H
25#include <stdlib.h>
26#endif
27
28#ifdef HAVE_STRING_H
29#include <string.h>
30#else
31#ifdef HAVE_STRINGS_H
32#include <strings.h>
33#endif
34#endif
35
36#include <ctype.h>
37
c906108c
SS
38
39struct hw_port_edge {
40 int my_port;
41 struct hw *dest;
42 int dest_port;
43 struct hw_port_edge *next;
44 object_disposition disposition;
45};
46
47struct hw_port_data {
48 hw_port_event_method *to_port_event;
49 const struct hw_port_descriptor *ports;
50 struct hw_port_edge *edges;
51};
52
53const struct hw_port_descriptor empty_hw_ports[] = {
21cf617c 54 { NULL, 0, 0, 0 },
c906108c
SS
55};
56
57static void
58panic_hw_port_event (struct hw *me,
59 int my_port,
60 struct hw *source,
61 int source_port,
62 int level)
63{
64 hw_abort (me, "no port method");
65}
66
67void
68create_hw_port_data (struct hw *me)
69{
70 me->ports_of_hw = HW_ZALLOC (me, struct hw_port_data);
71 set_hw_port_event (me, panic_hw_port_event);
72 set_hw_ports (me, empty_hw_ports);
73}
74
75void
76delete_hw_port_data (struct hw *me)
77{
78 hw_free (me, me->ports_of_hw);
79 me->ports_of_hw = NULL;
80}
81
82void
83set_hw_ports (struct hw *me,
84 const struct hw_port_descriptor ports[])
85{
86 me->ports_of_hw->ports = ports;
87}
88
89void
90set_hw_port_event (struct hw *me,
91 hw_port_event_method *port_event)
92{
93 me->ports_of_hw->to_port_event = port_event;
94}
95
96
97static void
98attach_hw_port_edge (struct hw *me,
99 struct hw_port_edge **list,
100 int my_port,
101 struct hw *dest,
102 int dest_port,
103 object_disposition disposition)
104{
105 struct hw_port_edge *new_edge = HW_ZALLOC (me, struct hw_port_edge);
106 new_edge->my_port = my_port;
107 new_edge->dest = dest;
108 new_edge->dest_port = dest_port;
109 new_edge->next = *list;
110 new_edge->disposition = disposition;
111 *list = new_edge;
112}
113
114
115static void
116detach_hw_port_edge (struct hw *me,
117 struct hw_port_edge **list,
118 int my_port,
119 struct hw *dest,
120 int dest_port)
121{
122 while (*list != NULL)
123 {
124 struct hw_port_edge *old_edge = *list;
125 if (old_edge->dest == dest
126 && old_edge->dest_port == dest_port
127 && old_edge->my_port == my_port)
128 {
129 if (old_edge->disposition == permenant_object)
130 hw_abort (me, "attempt to delete permenant port edge");
131 *list = old_edge->next;
132 hw_free (me, old_edge);
133 return;
134 }
135 }
136 hw_abort (me, "attempt to delete unattached port");
137}
138
139
140#if 0
141static void
142clean_hw_port_edges (struct hw_port_edge **list)
143{
144 while (*list != NULL)
145 {
146 struct hw_port_edge *old_edge = *list;
147 switch (old_edge->disposition)
148 {
149 case permenant_object:
150 list = &old_edge->next;
151 break;
152 case temporary_object:
153 *list = old_edge->next;
154 hw_free (me, old_edge);
155 break;
156 }
157 }
158}
159#endif
160
161
162/* Ports: */
163
164void
165hw_port_event (struct hw *me,
166 int my_port,
167 int level)
168{
169 int found_an_edge = 0;
170 struct hw_port_edge *edge;
171 /* device's lines directly connected */
172 for (edge = me->ports_of_hw->edges;
173 edge != NULL;
174 edge = edge->next)
175 {
176 if (edge->my_port == my_port)
177 {
178 edge->dest->ports_of_hw->to_port_event (edge->dest,
179 edge->dest_port,
180 me,
181 my_port,
182 level);
183 found_an_edge = 1;
184 }
185 }
186 if (!found_an_edge)
187 hw_abort (me, "No edge for port %d", my_port);
188}
189
190
191void
192hw_port_attach (struct hw *me,
193 int my_port,
194 struct hw *dest,
195 int dest_port,
196 object_disposition disposition)
197{
198 attach_hw_port_edge (me,
199 &me->ports_of_hw->edges,
200 my_port,
201 dest,
202 dest_port,
203 disposition);
204}
205
206
207void
208hw_port_detach (struct hw *me,
209 int my_port,
210 struct hw *dest,
211 int dest_port)
212{
213 detach_hw_port_edge (me,
214 &me->ports_of_hw->edges,
215 my_port,
216 dest,
217 dest_port);
218}
219
220
221void
222hw_port_traverse (struct hw *me,
223 hw_port_traverse_function *handler,
224 void *data)
225{
226 struct hw_port_edge *port_edge;
227 for (port_edge = me->ports_of_hw->edges;
228 port_edge != NULL;
229 port_edge = port_edge->next)
230 {
231 handler (me, port_edge->my_port,
232 port_edge->dest, port_edge->dest_port,
233 data);
234 }
235}
236
237
238int
239hw_port_decode (struct hw *me,
240 const char *port_name,
241 port_direction direction)
242{
243 if (port_name == NULL || port_name[0] == '\0')
244 return 0;
245 if (isdigit(port_name[0]))
246 {
247 return strtoul (port_name, NULL, 0);
248 }
249 else
250 {
251 const struct hw_port_descriptor *ports =
252 me->ports_of_hw->ports;
253 if (ports != NULL)
254 {
255 while (ports->name != NULL)
256 {
257 if (ports->direction == bidirect_port
258 || ports->direction == direction)
259 {
260 if (ports->nr_ports > 0)
261 {
262 int len = strlen (ports->name);
263 if (strncmp (port_name, ports->name, len) == 0)
264 {
265 if (port_name[len] == '\0')
266 return ports->number;
267 else if(isdigit (port_name[len]))
268 {
269 int port = (ports->number
270 + strtoul (&port_name[len], NULL, 0));
271 if (port >= ports->number + ports->nr_ports)
272 hw_abort (me,
273 "Port %s out of range",
274 port_name);
275 return port;
276 }
277 }
278 }
279 else if (strcmp (port_name, ports->name) == 0)
280 return ports->number;
281 }
282 ports++;
283 }
284 }
285 }
286 hw_abort (me, "Unreconized port %s", port_name);
287 return 0;
288}
289
290
291int
292hw_port_encode (struct hw *me,
293 int port_number,
294 char *buf,
295 int sizeof_buf,
296 port_direction direction)
297{
298 const struct hw_port_descriptor *ports = NULL;
299 ports = me->ports_of_hw->ports;
300 if (ports != NULL) {
301 while (ports->name != NULL)
302 {
303 if (ports->direction == bidirect_port
304 || ports->direction == direction)
305 {
306 if (ports->nr_ports > 0)
307 {
308 if (port_number >= ports->number
309 && port_number < ports->number + ports->nr_ports)
310 {
311 strcpy (buf, ports->name);
312 sprintf (buf + strlen(buf), "%d", port_number - ports->number);
313 if (strlen (buf) >= sizeof_buf)
314 hw_abort (me, "hw_port_encode: buffer overflow");
315 return strlen (buf);
316 }
317 }
318 else
319 {
320 if (ports->number == port_number)
321 {
322 if (strlen(ports->name) >= sizeof_buf)
323 hw_abort (me, "hw_port_encode: buffer overflow");
324 strcpy(buf, ports->name);
325 return strlen(buf);
326 }
327 }
328 }
329 ports++;
330 }
331 }
332 sprintf (buf, "%d", port_number);
333 if (strlen(buf) >= sizeof_buf)
334 hw_abort (me, "hw_port_encode: buffer overflow");
335 return strlen(buf);
336}
This page took 0.460223 seconds and 4 git commands to generate.