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