* sdcc/sim/ucsim/s51.src/glob.cc: Minor fix.
[fw/sdcc] / sim / ucsim / pobj.cc
1 /*
2  * Simulator of microcontrollers (pobj.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "ddconfig.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32
33 #include "pstr.h"
34 /*#include "pobjt.h"*/
35 #include "pobjcl.h"
36
37
38 /*                                                                          *
39   ==========================================================================*
40                                                                     cl_base *
41   ==========================================================================*
42                                                                             *
43 */
44
45 /* 
46  * Initializing the object
47  */
48
49 cl_base::cl_base(void) {}
50
51
52 /* 
53  * Destructing the object: calling hte virtual Done method
54  */
55
56 cl_base::~cl_base(void) {}
57
58 int cl_base::init(void) {return(0);}
59
60
61 /*                                                                          *
62   ==========================================================================*
63                                                                     cl_list *
64   ==========================================================================*
65                                                                             *
66 */
67
68 /* 
69  * Initializing a collection
70  */
71
72 cl_list::cl_list(t_index alimit, t_index adelta):
73   cl_base()
74 {
75   count= 0;
76   Items= 0;
77   Limit= 0;
78   Delta= adelta;
79   set_limit(alimit);
80 }
81
82
83 /* 
84  * Disposing object's variables
85  */
86
87 cl_list::~cl_list(void)
88 {
89   delete Items;
90 }
91
92
93 /*
94  * Get indexed item from the collection
95  */
96
97 void *
98 cl_list::at(t_index index)
99 {
100   if (index < 0 ||
101       index >= count)
102     error(1, index);
103   return(Items[index]);
104 }
105
106 /*void *
107 cl_list::operator[](t_index index)
108 {
109   if (index < 0 ||
110       index >= count)
111     error(1, 0);
112   return(Items[index]);  
113 }*/
114
115
116 /*
117  * Deleting the indexed item from the collection
118  */
119
120 void
121 cl_list::disconn_at(t_index index)
122 {
123   if (index < 0 ||
124       index >= count)
125     error(1, 0);
126   count--;
127   memmove(&Items[index], &Items[index+1], (count-index)*sizeof(void *));
128 }
129
130
131 /*
132  * Deleting an item from the collection but not disposing it
133  */
134
135 void
136 cl_list::disconn(void *item)
137 {
138   disconn_at(index_of(item));
139 }
140
141
142 /* 
143  * Deleting all the items from the collection but not disposing them
144  */
145
146 void
147 cl_list::disconn_all(void)
148 {
149   count= 0;
150 }
151
152
153 /*
154  * Deleting the indexed item from the collection and disposing it
155  */
156
157 void
158 cl_list::free_at(t_index index)
159 {
160   void *Item= at(index);
161
162   disconn_at(index);
163   free_item(Item);
164 }
165
166
167 /*
168  * Inserting a new item to the exact position
169  */
170
171 void
172 cl_list::add_at(t_index index, void *item)
173 {
174   if (index < 0 )
175     error(1, 0);
176   if (count == Limit)
177     set_limit(count + Delta);
178
179   memmove(&Items[index+1], &Items[index], (count-index)*sizeof(void *));
180   count++;
181
182   Items[index]= item;
183 }
184
185
186 /* 
187  * Put a new item to the collection. This function replaces an existing
188  * item with a new one but it does not delete or dispose the old item!
189  */
190
191 void
192 cl_list::put_at(t_index index, void *item)
193 {
194   if (index >= count)
195     error(1, 0);
196   Items[index]= item;
197 }
198
199
200 /* 
201  * Action taken when an error occure
202  */
203
204 void
205 cl_list::error(t_index code, t_index info)
206 {
207   fprintf(stderr, 
208           "Collection index error. Code= %d, Info= %d.\n",
209           code, info);
210   exit(code);
211 }
212
213
214 /* 
215  * Iterator method. This function calls 'Test' using every items as Test's
216  * argument until Test returns TRUE.
217  */
218
219 void *
220 cl_list::first_that(match_func test, void *arg)
221 {
222   for (t_index i= 0; i < count; i++)
223     {
224       if (test(Items[i], arg)) return(Items[i]);
225     }
226   return(0);
227 }
228
229
230 /* 
231  * Iterator method. This function calls 'Action' using every items as
232  * Action's argument.
233  */
234
235 void
236 cl_list::for_each(iterator_func action, void *arg)
237 {
238   for(t_index i= 0; i < count; i++)
239     action(Items[i], arg);
240 }
241
242
243 /* 
244  * Disposing an item.
245  */
246
247 void
248 cl_list::free_item(void *item)
249 {
250   delete (class cl_base*)item;
251 }
252
253
254 /* 
255  * Get the number of collected items.
256  */
257
258 int
259 cl_list::get_count(void)
260 {
261   return(count);
262 }
263
264 void *
265 cl_list::pop(void)
266 {
267   void *i;
268
269   if (!count)
270     return(0);
271   i= Items[0];
272   disconn_at(0);
273   return(i);
274 }
275
276 void *
277 cl_list::top(void)
278 {
279   if (!count)
280     return(0);
281   return(Items[0]);
282 }
283
284
285 /* 
286  * Returning the index of an item.
287  */
288
289 t_index
290 cl_list::index_of(void *item)
291 {
292   for (t_index i= 0; i < count; i++)
293     if (item == Items[i])
294       return(i);
295   error(1, 0);
296   return(0);    /* Needed by Sun! */
297 }
298
299
300 /* 
301  * Inserting a new item to the collection.
302  */
303
304 t_index
305 cl_list::add(void *item)
306 {
307   t_index loc= count;
308
309   add_at(count, item);
310   return(loc);
311 }
312
313
314 void
315 cl_list::push(void *item)
316 {
317   if (count)
318     add_at(0, item);
319   else
320     add(item);
321 }
322
323
324 /* 
325  * Iterator method. This function calls 'Test' using every items
326  * (in reversed order) as Test's argument until Test returns TRUE.
327  */
328
329 void *
330 cl_list::last_that(match_func test, void *arg)
331 {
332   for(t_index i= count; i > 0; i--)
333     if (test(Items[i-1], arg))
334       return(Items[i-1]);
335   return(0);
336 }
337
338
339 /*
340  * ???
341  */
342
343 /*void
344 cl_list::pack(void)
345 {
346   void **CurDst= Items;
347   void **CurSrc= Items;
348   void **Last  = Items + count;
349
350   while (CurSrc < Last)
351     {
352       if (*CurSrc != 0)
353         *CurDst++= *CurSrc;
354       *CurSrc++;
355     }
356 }*/
357
358
359 /*
360  * Setting up the maximum number of items. This function may expand
361  * the size of the collection.
362  */
363
364 void
365 cl_list::set_limit(t_index alimit)
366 {
367   void **AItems;
368
369   if (alimit < count)
370     alimit= count;
371   if (alimit > (int)max_list_size)
372     alimit= max_list_size;
373   if (alimit != Limit)
374     {
375       if (alimit == 0)
376         AItems= 0;
377       else
378         {
379           AItems = new void *[alimit];
380           //i= ALimit*(sizeof(void *));
381           //AItems= (void **)malloc(i);
382           if (count)
383             memcpy(AItems, Items, count*sizeof(void *));
384         }
385       delete Items;
386       Items= AItems;
387       Limit= alimit;
388     }
389 }
390
391
392 /*                                                                          *
393   ==========================================================================*
394                                                              cl_sorted_list *
395   ==========================================================================*
396                                                                             *
397 */
398
399 /* 
400  * Initilizing the sorted collection
401  */
402
403 cl_sorted_list::cl_sorted_list(t_index alimit, t_index adelta):
404   cl_list(alimit, adelta)
405 {
406   Duplicates= DD_FALSE;
407 }
408
409
410 cl_sorted_list::~cl_sorted_list(void) {}
411
412
413 /* 
414  * Get the address of the key field in an item.
415  */
416
417 void *
418 cl_sorted_list::key_of(void *item)
419 {
420   return(item);
421 }
422
423
424 /* 
425  * Get index of an item.
426  */
427
428 t_index
429 cl_sorted_list::index_of(void *item)
430 {
431   t_index       i;
432
433   if (search(key_of(item), i) == 0)
434     return(ccNotFound);
435   else
436     {
437       if (Duplicates)
438         while (i < count &&
439                item != Items[i])
440           i++;
441       if (i < count)
442         return(i);
443       else
444         return(ccNotFound);
445     }
446 }
447
448
449 /*
450  * Inserting a new item to the collection
451  */
452
453 t_index
454 cl_sorted_list::add(void *item)
455 {
456   t_index i;
457
458   if (search(key_of(item), i) == 0 ||
459       Duplicates)                               // order dependency!
460     add_at(i, item);                            // must do Search
461                                                 // before calling
462                                                 // AtInsert
463   return(i);
464 }
465
466
467 /*
468  * Searching an item using binary search.
469  */
470
471 bool
472 cl_sorted_list::search(void *key, t_index &index)
473 {
474   t_index l  = 0;
475   t_index h  = count - 1;
476   bool    res= DD_FALSE;
477   
478   while (l <= h)
479     {
480       t_index i= (l + h) >> 1;
481       t_index c= compare(key_of(Items[i]), key);
482       if (c < 0) l= i + 1;
483       else
484         {
485           h= i - 1;
486           if (c == 0)
487             {
488               res= DD_TRUE;
489               if (!Duplicates)
490                 l= i;
491             }
492         }
493     }
494   index= l;
495   return(res);
496 }
497
498
499 /*                                                                          *
500   ==========================================================================*
501                                                                  cl_strings *
502   ==========================================================================*
503                                                                             *
504 */
505
506 /* 
507  * Initilizing the string collection
508  */
509
510 cl_strings::cl_strings(t_index alimit, t_index adelta):
511   cl_sorted_list(alimit, adelta)
512 {
513   Duplicates= DD_TRUE;
514 }
515
516
517 cl_strings::~cl_strings(void) {}
518
519
520 /* 
521  * Comapare two string from the collection
522  */
523
524 int
525 cl_strings::compare(void *key1, void *key2)
526 {
527   return(strcmp((char *)key1, (char *)key2));
528 }
529
530
531 /* 
532  * Deallocate string item of the collection
533  */
534
535 void
536 cl_strings::free_item(void* item)
537 {
538   delete (class cl_base*)item;
539 }
540
541
542 /*                                                                          *
543   ==========================================================================*
544                                                                 cl_ustrings *
545   ==========================================================================*
546                                                                             *
547 */
548
549 /*
550  * Initilizing the unsorted string collection
551  */
552
553 cl_ustrings::cl_ustrings(t_index alimit, t_index adelta):
554   cl_strings(alimit, adelta)
555 {}
556
557
558 cl_ustrings::~cl_ustrings(void) {}
559
560
561 /*
562  * Comapare two string from the collection
563  */
564
565 int
566 cl_ustrings::compare(void *key1, void *key2)
567 {
568   return(-1);
569 }
570
571
572 /* 
573  * Searching an item using linear search.
574  */
575
576 bool
577 cl_ustrings::search(void *key, t_index& index)
578 {
579   t_index i    = 0;
580   bool    found= DD_FALSE;
581   void    *Actual;
582
583   if ((count) && key)
584     {
585       while (!found && (i < count))
586         {
587           Actual= key_of(at(i));
588           found = (Actual != 0) &&
589                   (compare(key, Actual) == 0);
590           i++;
591         }
592     }
593   if (found)
594     index= i-1;
595   else
596     index= count;
597
598   return(found);
599 }
600
601 /* End of pobj.cc */