Merge branch ucsim-034-pre3 to main trunk; new version 0.4
[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   free(Items);
91 }
92
93
94 /*
95  * Get indexed item from the collection
96  */
97
98 void *
99 cl_list::at(t_index index)
100 {
101   if (index < 0 ||
102       index >= count)
103     error(1, index);
104   return(Items[index]);
105 }
106
107 /*void *
108 cl_list::operator[](t_index index)
109 {
110   if (index < 0 ||
111       index >= count)
112     error(1, 0);
113   return(Items[index]);  
114 }*/
115
116
117 /*
118  * Deleting the indexed item from the collection
119  */
120
121 void
122 cl_list::disconn_at(t_index index)
123 {
124   if (index < 0 ||
125       index >= count)
126     error(1, 0);
127   count--;
128   memmove(&Items[index], &Items[index+1], (count-index)*sizeof(void *));
129 }
130
131
132 /*
133  * Deleting an item from the collection but not disposing it
134  */
135
136 void
137 cl_list::disconn(void *item)
138 {
139   t_index i;
140
141   if (index_of(item, &i))
142     disconn_at(i);
143 }
144
145
146 /* 
147  * Deleting all the items from the collection but not disposing them
148  */
149
150 void
151 cl_list::disconn_all(void)
152 {
153   count= 0;
154 }
155
156
157 /*
158  * Deleting the indexed item from the collection and disposing it
159  */
160
161 void
162 cl_list::free_at(t_index index)
163 {
164   void *Item= at(index);
165
166   disconn_at(index);
167   free_item(Item);
168 }
169
170 void
171 cl_list::free_all(void)
172 {
173   t_index i;
174
175   if (count)
176     {
177       for (i= count-1; i; i--)
178         free_at(i);
179       free_at(0);
180     }
181 }
182
183
184 /*
185  * Inserting a new item to the exact position
186  */
187
188 void
189 cl_list::add_at(t_index index, void *item)
190 {
191   if (index < 0 )
192     error(1, 0);
193   if (count == Limit)
194     set_limit(count + Delta);
195
196   memmove(&Items[index+1], &Items[index], (count-index)*sizeof(void *));
197   count++;
198
199   Items[index]= item;
200 }
201
202
203 /* 
204  * Put a new item to the collection. This function replaces an existing
205  * item with a new one but it does not delete or dispose the old item!
206  */
207
208 void
209 cl_list::put_at(t_index index, void *item)
210 {
211   if (index >= count)
212     error(1, 0);
213   Items[index]= item;
214 }
215
216
217 /* 
218  * Action taken when an error occure
219  */
220
221 void
222 cl_list::error(t_index code, t_index info)
223 {
224   fprintf(stderr, 
225           "Collection index error. Code= %d, Info= %d.\n",
226           code, info);
227   exit(code);
228 }
229
230
231 /* 
232  * Iterator method. This function calls 'Test' using every items as Test's
233  * argument until Test returns TRUE.
234  */
235
236 void *
237 cl_list::first_that(match_func test, void *arg)
238 {
239   for (t_index i= 0; i < count; i++)
240     {
241       if (test(Items[i], arg)) return(Items[i]);
242     }
243   return(0);
244 }
245
246
247 /* 
248  * Iterator method. This function calls 'Action' using every items as
249  * Action's argument.
250  */
251
252 void
253 cl_list::for_each(iterator_func action, void *arg)
254 {
255   for(t_index i= 0; i < count; i++)
256     action(Items[i], arg);
257 }
258
259
260 /* 
261  * Disposing an item.
262  */
263
264 void
265 cl_list::free_item(void *item)
266 {
267   delete (class cl_base*)item;
268 }
269
270
271 /* 
272  * Get the number of collected items.
273  */
274
275 int
276 cl_list::get_count(void)
277 {
278   return(count);
279 }
280
281 void *
282 cl_list::pop(void)
283 {
284   void *i;
285
286   if (!count)
287     return(0);
288   i= Items[0];
289   disconn_at(0);
290   return(i);
291 }
292
293 void *
294 cl_list::top(void)
295 {
296   if (!count)
297     return(0);
298   return(Items[0]);
299 }
300
301
302 /* 
303  * Returning the index of an item.
304  */
305
306 t_index
307 cl_list::index_of(void *item)
308 {
309   for (t_index i= 0; i < count; i++)
310     if (item == Items[i])
311       return(i);
312   error(1, 0);
313   return(0);    /* Needed by Sun! */
314 }
315
316 bool
317 cl_list::index_of(void *item, t_index *idx)
318 {
319   for (t_index i= 0; i < count; i++)
320     if (item == Items[i])
321       {
322         if (idx)
323           *idx= i;
324         return(DD_TRUE);
325       }
326   return(DD_FALSE);
327 }
328
329
330 /* 
331  * Inserting a new item to the collection.
332  */
333
334 t_index
335 cl_list::add(void *item)
336 {
337   t_index loc= count;
338
339   add_at(count, item);
340   return(loc);
341 }
342
343
344 void
345 cl_list::push(void *item)
346 {
347   if (count)
348     add_at(0, item);
349   else
350     add(item);
351 }
352
353
354 /* 
355  * Iterator method. This function calls 'Test' using every items
356  * (in reversed order) as Test's argument until Test returns TRUE.
357  */
358
359 void *
360 cl_list::last_that(match_func test, void *arg)
361 {
362   for(t_index i= count; i > 0; i--)
363     if (test(Items[i-1], arg))
364       return(Items[i-1]);
365   return(0);
366 }
367
368
369 /*
370  * ???
371  */
372
373 /*void
374 cl_list::pack(void)
375 {
376   void **CurDst= Items;
377   void **CurSrc= Items;
378   void **Last  = Items + count;
379
380   while (CurSrc < Last)
381     {
382       if (*CurSrc != 0)
383         *CurDst++= *CurSrc;
384       *CurSrc++;
385     }
386 }*/
387
388
389 /*
390  * Setting up the maximum number of items. This function may expand
391  * the size of the collection.
392  */
393
394 void
395 cl_list::set_limit(t_index alimit)
396 {
397   void **AItems;
398
399   if (alimit < count)
400     alimit= count;
401   if (alimit > (int)max_list_size)
402     alimit= max_list_size;
403   if (alimit != Limit)
404     {
405       if (alimit == 0)
406         AItems= 0;
407       else
408         {
409           //AItems = new void *[alimit];
410           int i= alimit*(sizeof(void *));
411           AItems= (void **)malloc(i);
412           if (count)
413             memcpy(AItems, Items, count*sizeof(void *));
414         }
415       //delete Items;
416       free(Items);
417       Items= AItems;
418       Limit= alimit;
419     }
420 }
421
422
423 /*                                                                          *
424   ==========================================================================*
425                                                              cl_sorted_list *
426   ==========================================================================*
427                                                                             *
428 */
429
430 /* 
431  * Initilizing the sorted collection
432  */
433
434 cl_sorted_list::cl_sorted_list(t_index alimit, t_index adelta):
435   cl_list(alimit, adelta)
436 {
437   Duplicates= DD_FALSE;
438 }
439
440
441 cl_sorted_list::~cl_sorted_list(void) {}
442
443
444 /* 
445  * Get the address of the key field in an item.
446  */
447
448 void *
449 cl_sorted_list::key_of(void *item)
450 {
451   return(item);
452 }
453
454
455 /* 
456  * Get index of an item.
457  */
458
459 t_index
460 cl_sorted_list::index_of(void *item)
461 {
462   t_index       i;
463
464   if (search(key_of(item), i) == 0)
465     return(ccNotFound);
466   else
467     {
468       if (Duplicates)
469         while (i < count &&
470                item != Items[i])
471           i++;
472       if (i < count)
473         return(i);
474       else
475         return(ccNotFound);
476     }
477 }
478
479
480 /*
481  * Inserting a new item to the collection
482  */
483
484 t_index
485 cl_sorted_list::add(void *item)
486 {
487   t_index i;
488
489   if (search(key_of(item), i) == 0 ||
490       Duplicates)                               // order dependency!
491     add_at(i, item);                            // must do Search
492                                                 // before calling
493                                                 // AtInsert
494   return(i);
495 }
496
497
498 /*
499  * Searching an item using binary search.
500  */
501
502 bool
503 cl_sorted_list::search(void *key, t_index &index)
504 {
505   t_index l  = 0;
506   t_index h  = count - 1;
507   bool    res= DD_FALSE;
508   
509   while (l <= h)
510     {
511       t_index i= (l + h) >> 1;
512       t_index c= compare(key_of(Items[i]), key);
513       if (c < 0) l= i + 1;
514       else
515         {
516           h= i - 1;
517           if (c == 0)
518             {
519               res= DD_TRUE;
520               if (!Duplicates)
521                 l= i;
522             }
523         }
524     }
525   index= l;
526   return(res);
527 }
528
529
530 /*                                                                          *
531   ==========================================================================*
532                                                                  cl_strings *
533   ==========================================================================*
534                                                                             *
535 */
536
537 /* 
538  * Initilizing the string collection
539  */
540
541 cl_strings::cl_strings(t_index alimit, t_index adelta):
542   cl_sorted_list(alimit, adelta)
543 {
544   Duplicates= DD_TRUE;
545 }
546
547
548 cl_strings::~cl_strings(void) {}
549
550
551 /* 
552  * Comapare two string from the collection
553  */
554
555 int
556 cl_strings::compare(void *key1, void *key2)
557 {
558   return(strcmp((char *)key1, (char *)key2));
559 }
560
561
562 /* 
563  * Deallocate string item of the collection
564  */
565
566 void
567 cl_strings::free_item(void* item)
568 {
569   delete (class cl_base*)item;
570 }
571
572
573 /*                                                                          *
574   ==========================================================================*
575                                                                 cl_ustrings *
576   ==========================================================================*
577                                                                             *
578 */
579
580 /*
581  * Initilizing the unsorted string collection
582  */
583
584 cl_ustrings::cl_ustrings(t_index alimit, t_index adelta):
585   cl_strings(alimit, adelta)
586 {}
587
588
589 cl_ustrings::~cl_ustrings(void) {}
590
591
592 /*
593  * Comapare two string from the collection
594  */
595
596 int
597 cl_ustrings::compare(void *key1, void *key2)
598 {
599   return(-1);
600 }
601
602
603 /* 
604  * Searching an item using linear search.
605  */
606
607 bool
608 cl_ustrings::search(void *key, t_index& index)
609 {
610   t_index i    = 0;
611   bool    found= DD_FALSE;
612   void    *Actual;
613
614   if ((count) && key)
615     {
616       while (!found && (i < count))
617         {
618           Actual= key_of(at(i));
619           found = (Actual != 0) &&
620                   (compare(key, Actual) == 0);
621           i++;
622         }
623     }
624   if (found)
625     index= i-1;
626   else
627     index= count;
628
629   return(found);
630 }
631
632 /* End of pobj.cc */