fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/utils/pri/event.c *
7 * Created: 2015-02-23 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2015 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24
25#include <errno.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <drivers/pri/pri.h>
31
32
33struct pri_event_s {
34 unsigned long type;
35 unsigned long idx1;
36 unsigned long idx2;
37 char all;
38};
39
40
41const char *pri_event_get_name (unsigned long type)
42{
43 switch (type) {
44 case PRI_EVENT_WEAK:
45 return ("WEAK");
46
47 case PRI_EVENT_CLOCK:
48 return ("CLOCK");
49 }
50
51 return ("UNK");
52}
53
54int pri_event_get_type (const char *name, unsigned long *type)
55{
56 if (name == NULL) {
57 return (1);
58 }
59
60 if (strcasecmp (name, "FUZZY") == 0) {
61 *type = PRI_EVENT_WEAK;
62 }
63 else if (strcasecmp (name, "WEAK") == 0) {
64 *type = PRI_EVENT_WEAK;
65 }
66 else if (strcasecmp (name, "CLOCK") == 0) {
67 *type = PRI_EVENT_CLOCK;
68 }
69 else if (strcasecmp (name, "ALL") == 0) {
70 *type = PRI_EVENT_ALL;
71 }
72 else {
73 errno = 0;
74
75 *type = strtoul (name, NULL, 0);
76
77 if (errno) {
78 return (1);
79 }
80 }
81
82 return (0);
83}
84
85
86static
87int pri_event_clear_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque)
88{
89 pri_trk_evt_del_all (trk, PRI_EVENT_ALL);
90
91 return (0);
92}
93
94int pri_event_clear (pri_img_t *img)
95{
96 return (pri_for_all_tracks (img, pri_event_clear_cb, NULL));
97}
98
99
100static
101int pri_event_add_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque)
102{
103 struct pri_event_s *par;
104
105 par = opaque;
106
107 if (pri_trk_evt_add (trk, par->type, par->idx1, par->idx2) == NULL) {
108 return (1);
109 }
110
111 return (0);
112}
113
114int pri_event_add (pri_img_t *img, const char *type, const char *pos, const char *val)
115{
116 struct pri_event_s par;
117
118 if (pri_event_get_type (type, &par.type)) {
119 return (1);
120 }
121
122 errno = 0;
123
124 par.idx1 = strtoul (pos, NULL, 0);
125 par.idx2 = strtoul (val, NULL, 0);
126
127 if (errno) {
128 return (1);
129 }
130
131 return (pri_for_all_tracks (img, pri_event_add_cb, &par));
132}
133
134
135static
136int pri_event_del_idx_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque)
137{
138 unsigned long i;
139 struct pri_event_s *par;
140 pri_evt_t *evt;
141
142 par = opaque;
143
144 if (par->all) {
145 pri_trk_evt_del_all (trk, par->type);
146 }
147 else {
148 for (i = par->idx1; i <= par->idx2; i++) {
149 evt = pri_trk_evt_get_idx (trk, par->type, par->idx1);
150
151 if (evt != NULL) {
152 pri_trk_evt_del (trk, evt);
153 }
154 }
155 }
156
157 return (0);
158}
159
160static
161int pri_event_del_pos_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque)
162{
163 int del;
164 struct pri_event_s *par;
165 pri_evt_t *evt, *tmp, *dst;
166
167 par = opaque;
168
169 evt = trk->evt;
170 dst = NULL;
171 trk->evt = NULL;
172
173 while (evt != NULL) {
174 tmp = evt;
175 evt = evt->next;
176 tmp->next = NULL;
177
178 if ((par->type != PRI_EVENT_ALL) && (tmp->type != par->type)) {
179 del = 0;
180 }
181 else if (par->all) {
182 del = 1;
183 }
184 else if ((tmp->pos >= par->idx1) && (tmp->pos <= par->idx2)) {
185 del = 1;
186 }
187 else {
188 del = 0;
189 }
190
191 if (del) {
192 pri_evt_del (tmp);
193 }
194 else {
195 if (dst == NULL) {
196 trk->evt = tmp;
197 }
198 else {
199 dst->next = tmp;
200 }
201
202 dst = tmp;
203 }
204 }
205
206 return (0);
207}
208
209int pri_event_del (pri_img_t *img, const char *type, const char *range)
210{
211 int byidx;
212 struct pri_event_s par;
213
214 if (pri_event_get_type (type, &par.type)) {
215 return (1);
216 }
217
218 byidx = 0;
219
220 if (*range == '@') {
221 byidx = 1;
222 range += 1;
223 }
224
225 if (pri_parse_range (range, &par.idx1, &par.idx2, &par.all)) {
226 return (1);
227 }
228
229 if (byidx) {
230 return (pri_for_all_tracks (img, pri_event_del_idx_cb, &par));
231 }
232 else {
233 return (pri_for_all_tracks (img, pri_event_del_pos_cb, &par));
234 }
235}
236
237
238static
239void pri_print_event (const pri_evt_t *evt, unsigned long c, unsigned long h, unsigned long i)
240{
241 const char *str;
242
243 str = pri_event_get_name (evt->type);
244
245 printf ("%2lu/%lu %3lu: %08lX %08lX %08lX (%s %lu)\n",
246 c, h, i, evt->type, evt->pos, evt->val,
247 str, evt->pos
248 );
249}
250
251static
252int pri_event_list_idx_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque)
253{
254 unsigned long i;
255 struct pri_event_s *par;
256 pri_evt_t *evt1, *evt2;
257
258 par = opaque;
259
260 evt2 = trk->evt;
261
262 i = 0;
263
264 while (evt2 != NULL) {
265 evt1 = evt2;
266 evt2 = evt2->next;
267
268 if (par->type != PRI_EVENT_ALL) {
269 if (par->type != evt1->type) {
270 continue;
271 }
272 }
273
274 if (par->all == 0) {
275 if ((i < par->idx1) || (i > par->idx2)) {
276 i += 1;
277 continue;
278 }
279 }
280
281 pri_print_event (evt1, c, h, i);
282
283 i += 1;
284 }
285
286 return (0);
287}
288
289static
290int pri_event_list_pos_cb (pri_img_t *img, pri_trk_t *trk, unsigned long c, unsigned long h, void *opaque)
291{
292 unsigned long i;
293 struct pri_event_s *par;
294 pri_evt_t *evt1, *evt2;
295
296 par = opaque;
297
298 i = 0;
299
300 evt2 = trk->evt;
301
302 while (evt2 != NULL) {
303 evt1 = evt2;
304 evt2 = evt2->next;
305
306 if (par->type != PRI_EVENT_ALL) {
307 if (par->type != evt1->type) {
308 continue;
309 }
310 }
311
312 i += 1;
313
314 if (par->all == 0) {
315 if ((evt1->pos < par->idx1) || (evt1->pos > par->idx2)) {
316 continue;
317 }
318 }
319
320 pri_print_event (evt1, c, h, i - 1);
321 }
322
323 return (0);
324}
325
326int pri_event_list (pri_img_t *img, const char *type, const char *range)
327{
328 int byidx;
329 struct pri_event_s par;
330
331 if (pri_event_get_type (type, &par.type)) {
332 return (1);
333 }
334
335 byidx = 0;
336
337 if (*range == '@') {
338 byidx = 1;
339 range += 1;
340 }
341
342 if (pri_parse_range (range, &par.idx1, &par.idx2, &par.all)) {
343 return (1);
344 }
345
346 if (byidx) {
347 return (pri_for_all_tracks (img, pri_event_list_idx_cb, &par));
348 }
349 else {
350 return (pri_for_all_tracks (img, pri_event_list_pos_cb, &par));
351 }
352}