Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
last version of tesh
[simgrid.git] / tools / tesh2 / src / vector.c
1
2 #include <vector.h>
3
4 #include <errno.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include <stdio.h>
9
10 #ifdef _MSC_VER
11 #define inline _inline
12 #endif
13
14 static inline int 
15 resize(vector_t vector)
16 {           
17         return vector_reserve(vector, !(vector->capacity) ? 1 : (vector->size) << 1);
18 }
19
20 static inline int
21 move(vector_t vector, int dst,int src, int size)
22 {
23         return (NULL != memmove(vector->items + dst, vector->items + src,size * sizeof(void*)));
24 }
25
26 vector_t
27 vector_new(int capacity, fn_finalize_t fn_finalize)
28 {
29         vector_t vector;
30         
31         if(capacity < 0)
32         {
33                 errno = EINVAL;
34                 return NULL;
35         }
36         
37         if(!(vector = (vector_t)calloc(1,sizeof(s_vector_t))))
38                 return NULL;
39         
40         if(capacity)
41         {
42                 if(!(vector->items = (void**)calloc(capacity,sizeof(void*))))
43                 {
44                         free(vector);
45                         return NULL;
46                 }
47                 
48                 vector->capacity = capacity;
49         }
50                                 
51         vector->fn_finalize = fn_finalize;
52         vector->pos = -1;
53         return vector;
54 }
55
56 int 
57 vector_clear(vector_t vector)
58 {
59         int rv;
60         
61         if(!vector)
62             return EINVAL;
63             
64         if(!vector->size)
65                 return 0;
66         
67         if(vector->fn_finalize)
68         {
69                 int size = vector->size;
70                 fn_finalize_t fn_finalize = vector->fn_finalize;
71                 void** items = vector->items;
72                 register int pos;
73                 
74                 for(pos = 0; pos < size; pos++)
75                 {
76                         if((rv = (*(fn_finalize))(&(items[pos]))))
77                                 return rv;
78                         else
79                                 vector->size--;
80                 }
81         }
82         else
83         {
84                 vector->size = 0;       
85         }
86         
87         vector->pos = -1;
88         
89         return 0;
90 }
91
92 int 
93 vector_free(vector_t* vector_ptr)
94 {
95         int rv;
96         
97     if(!(*vector_ptr))
98         return EINVAL;
99        
100         if((rv = vector_clear(*vector_ptr)))
101                 return rv;
102
103         free(*vector_ptr);
104         *vector_ptr = NULL;
105         
106         return 0;
107 }
108
109 int 
110 vector_is_empty(vector_t vector)
111 {       
112         if(!vector)
113         {
114             errno = EINVAL;
115             return 0;
116         }
117         
118         return !vector->size;
119 }
120
121 int 
122 vector_get_size(vector_t vector)
123 {
124     if(!vector)
125     {
126         errno = EINVAL;
127         return -1;
128     }
129     
130         return vector->size;
131 }
132
133 void* 
134 vector_get_front(vector_t vector)
135 {
136         if(!vector)
137     {
138         errno = EINVAL;
139         return NULL;
140     }
141     
142     if(!vector->size)
143     {
144         errno = EAGAIN;
145         return NULL;
146     }
147     
148         return vector->items[0];
149 }
150
151 void*
152 vector_get_back(vector_t vector)
153 {
154         if(!vector)
155     {
156         errno = EINVAL;
157         return NULL;
158     }
159     
160     if(!vector->size)
161     {
162         errno = EAGAIN;
163         return NULL;
164     }
165     
166         return vector->items[vector->size - 1];
167 }
168
169 int
170 vector_get_capacity_available(vector_t vector)
171 {
172     if(!vector)
173     {
174         errno = EINVAL;
175         return -1;
176     }
177     
178         return (vector->capacity - vector->size);
179 }
180
181 int
182 vector_push_back(vector_t vector, void* item)
183 {
184         int rv;
185         
186         if(!vector || !item)
187         return EINVAL;
188     
189         /* if all capacity is used, resize the vector */
190         if(vector->capacity <= vector->size)
191         {
192                 if((rv = resize(vector)))
193                         return rv;
194         }
195         
196         /* increment the item count and push the new item at the end of the vector */
197         vector->items[++(vector->size) - 1] = item;
198         
199         vector->pos = -1;
200         
201         
202         return 0;       
203 }
204
205 void* 
206 vector_pop_back(vector_t vector)
207 {
208     if(!vector)
209     {
210         errno = EINVAL;
211         return NULL;
212     }
213     
214     if(!vector->size)
215     {
216         errno = EAGAIN;
217         return NULL;
218     }
219         
220         vector->pos = -1;
221         
222         return vector->items[(vector->size)-- - 1];
223 }
224
225 int
226 vector_get_upper_bound(vector_t vector)
227 {
228         if(!vector)
229     {
230         errno = EINVAL;
231         return -1;
232     }
233     
234     if(!vector->size)
235     {
236         errno = EAGAIN;
237         return -1;
238     }
239     
240         return (vector->size - 1);
241 }
242
243 void* 
244 vector_set_at(vector_t vector, int pos, void* item)
245 {
246         void* prev_item;
247
248         if(!vector)
249     {
250         errno = EINVAL;
251         return NULL;
252     }
253    
254         if(!vector->size)
255         {
256                 errno = EAGAIN;
257                 return NULL;
258         }
259         
260         if((pos < 0) || (pos >= vector->size))
261         {
262                 errno = ERANGE;
263                 return NULL;
264         }
265         
266         prev_item = vector->items[pos];
267         vector->items[pos] = item;
268         return prev_item;
269 }
270
271 int 
272 vector_insert(vector_t vector, int pos, void* item)
273 {
274         int rv;
275         
276         if(!vector)
277         return EINVAL;
278    
279         if(!vector->size)
280         {
281                 errno = EAGAIN;
282                 return 0;
283         }
284         
285         if((pos < 0) || (pos >= vector->size))
286         {
287                 errno = ERANGE;
288                 return 0;
289         }
290     
291         if(vector->size >= vector->capacity)
292         {
293                 if((rv = resize(vector)))
294                         return rv;
295         }               
296         
297         if(vector->size)
298         {
299                 if(!move(vector, pos + 1, pos, vector->size - pos))
300                     return errno;
301     }
302         
303         vector->size++;
304         vector->items[pos] = item;
305         vector->pos = -1;
306         
307         return 0;
308 }
309
310 int 
311 vector_erase_at(vector_t vector, int pos)
312 {
313         int rv;
314         
315         if(!vector)
316         return EINVAL;
317     
318     if(!vector->size)
319         {
320                 errno = EAGAIN;
321                 return 0;
322         }
323         
324         if((pos < 0) || (pos >= vector->size))
325         {
326                 errno = ERANGE;
327                 return 0;
328         }
329
330         if(vector->fn_finalize)
331         {
332                 if((rv = (*(vector->fn_finalize))(&(vector->items[pos]))))
333                         return rv;
334         }
335
336         if(pos != (vector->size - 1))
337         {
338                 if(!move(vector, pos, pos + 1, (vector->size - (pos + 1))))
339                     return errno;
340         }
341         
342         vector->size--;
343         vector->pos = -1;
344         
345         return 0;
346 }
347
348 int 
349 vector_erase(vector_t vector, void* item)
350 {
351         int pos, rv;
352         
353         if(!vector || !item)
354                 return EINVAL;
355         
356         if(!vector->size)
357                 return EAGAIN;
358                 
359         if(-1 == (pos = vector_search(vector,item)))
360                 return errno;
361                 
362         if(vector->fn_finalize)
363         {
364                 if((rv = (*(vector->fn_finalize))(&item)))
365                         return rv;      
366         }
367         
368         if(pos != (vector->size - 1))
369                 if(!move(vector, pos, pos + 1, (vector->size - (pos + 1))))
370                         return errno;
371         
372         vector->size--;
373         
374         vector->pos = -1;
375         
376         return 0;
377 }
378
379 int 
380 vector_erase_range(vector_t vector, int first, int last)
381 {
382         register int width;
383         int rv;
384         
385         if(!vector || first >= last)
386                 return EINVAL;
387         
388         if(vector->size < 2)
389                 return EAGAIN;
390                 
391         if((first < 0) || (last < 0) || (last >= vector->size))
392                 return ERANGE;
393         
394         width = (last - first) + 1;
395
396         while(width--)
397         {
398                 if((rv = vector_erase_at(vector,first)))
399                         return rv;
400         }
401                 
402         return 0;
403 }
404
405 int
406 vector_search(vector_t vector, void* item)
407 {
408         register int pos;
409         void** items;
410         int size;
411
412         if(!vector || !item)
413         {
414                 errno = EINVAL;
415                 return -1;
416         }
417         
418         if(!vector->size)
419         {
420                 errno = EAGAIN;
421                 return -1;
422         }
423         
424         vector = (vector_t)vector;
425         
426         items = vector->items;
427         size = vector->size;
428         
429         for(pos = 0 ; pos < size; pos++)
430         {
431                 if(items[pos] == item)
432                         return pos;
433         }
434         
435         errno = ESRCH;
436         return -1;      
437 }
438
439 int 
440 vector_remove(vector_t vector, void* item)
441 {
442         int pos;
443         
444         if(!vector || !item)
445                 return EINVAL;
446         
447         if(!vector->size)
448                 return EAGAIN;
449                 
450         if(-1 == (pos = vector_search(vector,item)))
451                 return errno;
452         
453         if(pos != (vector->size - 1))
454                 if(!move(vector, pos, pos + 1, (vector->size - (pos + 1))))
455                         return errno;
456         
457         vector->size--;
458         
459         vector->pos = -1;
460         
461         return 0;
462 }
463
464 int
465 vector_assign(vector_t dst,vector_t src)
466 {
467         register int pos;
468         int size;
469         void** items;
470         int rv;
471
472         
473         if(!dst || !src ||(dst == src))
474                 return EINVAL;
475         
476         if(!src->size)
477                 return EAGAIN;
478         
479         size = src->size;
480         
481         /* if the destination vector has not enough capacity resize it */
482         if(size > dst->capacity)
483         {
484                 if((rv = vector_reserve(dst, size - dst->capacity)))
485                         return rv;
486         }
487
488         /* clear the destination vector */
489         if((rv = vector_clear(dst)))
490                 return rv;
491
492         dst->fn_finalize = NULL;
493                 
494         items = src->items;
495         
496         /* file the destination vector */
497         for(pos = 0; pos < size; pos++)
498                  if((rv = vector_push_back(dst,items[pos])))
499                         return rv;
500                         
501         dst->pos = -1;
502                  
503         return 0;
504 }
505
506 int
507 vector_get_capacity(vector_t vector)
508 {
509         if(!vector)
510         {
511                 errno = EINVAL;
512                 return -1;
513         }
514                 
515         return vector->capacity;
516 }
517
518 int
519 vector_equals(vector_t first, vector_t second)
520 {
521         register int pos;
522         int size;
523         void** __first, ** __second;
524
525         
526         if(!first || !second || (first == second))
527         {
528                 errno = EINVAL;
529                 return 0;
530         }
531         
532         if(first->size != second->size)
533                 return 0;
534         
535         size = first->size;
536         __first = first->items;
537         __second = second->items;
538         
539         for(pos = 0; pos < size; pos++)
540         {
541                 if(__first[pos] != __second[pos])
542                         return 0;
543         }
544         
545         return 1;
546 }
547
548 vector_t 
549 vector_clone(vector_t vector)
550 {
551         int size;
552         register int pos;
553         void** dst,** src;
554         vector_t clone;
555         
556         if(!vector)
557         {
558                 errno = EINVAL;
559                 return NULL;
560         }
561         
562         clone = vector_new(vector->capacity,NULL);
563
564         if(!clone)
565             return NULL;
566         
567         size = vector->size;
568         src = vector->items;
569         dst = clone->items;
570         
571         for(pos = 0; pos < size; pos++)
572                 dst[pos] = src[pos];
573         
574         clone->size = size;
575                 
576         return clone;
577 }
578
579 int
580 vector_contains(vector_t vector,void* item)
581 {
582         if(!vector || !item)
583         {
584                 errno = EINVAL;
585                 return 0;
586         }
587         
588         return (-1 != vector_search(vector,item));
589 }
590
591 int
592 vector_swap(vector_t first,vector_t second)
593 {
594         s_vector_t tmp;
595         
596         if(!first || !second)
597                 return EINVAL;
598         
599         /* save the content or first */
600         tmp = *first;
601         
602         /* copy second in first */
603         if(!memcpy(first, second, sizeof(s_vector_t)))
604             return 0;
605         
606         /* copy tmp in first */
607         if(!memcpy(second, &tmp, sizeof(s_vector_t)))
608         {
609                 *first = tmp;
610             return 0;
611         }
612
613         return 1;
614 }
615
616 int
617 vector_reserve(vector_t vector, int size)
618 {
619         void** items;
620
621         if(!vector || (size < 0))
622                 return EINVAL;
623                 
624         if(vector->capacity >= size)
625                 return EAGAIN;
626         
627         if(!(items = (void**)realloc(vector->items, size * sizeof(void*))))
628                 return errno;
629         
630         
631         vector->capacity = size;
632         vector->items = items;
633         
634         return 0;
635 }
636
637 int
638 vector_is_autodelete(vector_t vector)
639 {
640         if(!vector)
641         {
642                 errno = EINVAL;
643                 return 0;
644         }
645
646         return NULL != vector->fn_finalize;
647 }
648
649 int
650 vector_has_capacity_available(vector_t vector)
651 {
652         if(!vector)
653         {
654                 errno = EINVAL;
655                 return 0;
656         }
657         
658         return (vector->capacity > vector->size);
659 }
660
661 int
662 vector_is_full(vector_t vector)
663 {
664         if(!vector)
665     {
666         errno = EINVAL;
667         return 0;
668     }
669     
670
671         return (vector->capacity == vector->size);
672 }
673
674 int
675 vector_get_max_index(vector_t vector)
676 {
677         
678         if(!vector)
679         {
680                 errno = EINVAL;
681                 return -1;
682         }
683         
684         
685         return vector->size - 1;
686 }
687
688 void*
689 vector_get(vector_t vector)
690 {
691         if(!vector)
692         {
693                 errno = EINVAL;
694                 return NULL;
695         }
696         
697         if(!vector->size || (-1 == vector->pos))
698         {
699                 errno = EAGAIN;
700                 return NULL;
701         }
702         return vector->items[vector->pos];      
703 }
704
705 void*
706 vector_get_at(vector_t vector, int pos)
707 {
708         if(!vector)
709         {
710                 errno = EINVAL;
711                 return NULL;
712         }
713         
714         if(pos < 0 || pos >= vector->size)
715         {
716                 errno = ERANGE;
717                 return NULL;
718         }
719         
720         if(!vector->size)
721         {
722                 errno = EAGAIN;
723                 return NULL;
724         }
725                 
726         
727         return vector->items[pos];      
728 }
729
730 int
731 vector_getpos(vector_t vector, int* pos)
732 {
733         
734         if(!vector || !pos)
735         {
736                 errno = EINVAL;
737                 return 0;
738         }
739         
740         if(!vector->size || (-1 == vector->pos))
741         {
742                 errno = EAGAIN;
743                 return 0;
744         }
745         
746         *pos = vector->pos;
747         return 1;
748 }
749
750 int
751 vector_move_next(vector_t vector)
752 {
753         if(!vector)
754         {
755                 errno = EINVAL;
756                 return 0;
757         }
758         
759         if(!vector->size || (-1 == vector->pos))
760         {
761                 errno = EAGAIN;
762                 return 0;
763         }
764         
765         if(vector->pos < (vector->size - 1))
766         {
767                 vector->pos++;
768                 return 1;
769         }
770         
771         vector->pos = -1;
772         errno = ERANGE;
773         return 0;
774 }
775
776 int
777 vector_move_prev(vector_t vector)
778 {
779         if(!vector)
780         {
781                 errno = EINVAL;
782                 return 0;
783         }
784         
785         if(!vector->size  || (-1 == vector->pos))
786         {
787                 errno = EAGAIN;
788                 return 0;
789         }
790         
791         if(vector->pos > 0)
792         {
793                 vector->pos--;
794                 return 1;
795         }
796         
797         vector->pos = -1;
798         errno = ERANGE;
799         return 0;
800         
801 }
802
803 int
804 vector_rewind(vector_t vector)
805 {
806         if(!vector)
807         {
808                 errno = EINVAL;
809                 return 0;
810         }
811         
812         if(!vector->size)
813         {
814                 errno = EAGAIN;
815                 return 0;
816         }
817         
818         vector->pos = 0;
819         
820         return 1;
821 }
822
823 static int
824 seek_set(vector_t vector, int offset)
825 {
826         if(offset > vector->size)
827                 return EINVAL;
828         
829         vector_rewind(vector);
830         
831         while(offset--)
832                 vector_move_next(vector);
833                 
834         return 0;
835 }
836
837 static int
838 seek_end(vector_t vector, int offset)
839 {
840         if(offset > vector->size)
841                 return EINVAL;
842         
843         vector_unwind(vector);
844         
845         while(offset--)
846                 vector_move_prev(vector);
847                 
848         return 0;
849 }
850
851
852 static int
853 seek_cur(vector_t vector, int offset)
854 {
855         if(vector->pos == 0)
856         {
857                 /* we are at the begin of the vector */
858                 seek_set(vector, offset);
859         }
860         else if(vector->pos == vector->size - 1)
861         {
862                 /* we are at the end of the vector */
863                 seek_end(vector, offset);
864         }
865         else
866         {
867                 if(offset > (vector->size - vector->pos + 1))   
868                         return EINVAL;
869                         
870                 while(offset--)
871                         vector_move_next(vector);
872                         
873         }
874                 
875         return 0;
876 }
877
878 int
879 vector_seek(vector_t vector, int offset, int whence)
880 {
881         if(!vector)
882                 return EINVAL;
883                 
884         if(!vector->size)
885                 return EAGAIN;
886         
887         switch(whence)
888         {
889                 case SEEK_SET :
890                 return seek_set(vector, offset);
891                 
892                 case SEEK_CUR :
893                 return seek_cur(vector, offset);
894                 
895                 case SEEK_END :
896                 return seek_end(vector, offset);
897                 
898         }
899         
900         return EINVAL;
901 }
902
903 void*
904 vector_set(vector_t vector, void* item)
905 {
906         void* prev_item;
907         
908         if(!vector || !item)
909         {
910                 errno = EINVAL;
911                 return NULL;
912         }
913         
914         if(!vector->size  || (-1 == vector->pos))
915         {
916                 errno = EAGAIN;
917                 return NULL;
918         }
919         
920         prev_item = vector->items[vector->pos];
921         vector->items[vector->pos] = item;
922         
923         return prev_item;
924 }
925
926 int
927 vector_setpos(vector_t vector, int pos)
928 {
929         if(!vector)
930         {
931                 errno = EINVAL;
932                 return 0;
933         }
934         
935         if(pos < 0 || pos >= vector->size)
936         {
937                 errno = ERANGE;
938                 return 0;
939         }
940         
941         if(!vector->size)
942         {
943                 errno = EAGAIN;
944                 return 0;
945         }
946         
947         vector->pos = pos;
948         return 1;
949 }
950
951 int
952 vector_tell(vector_t vector)
953 {
954         if(!vector)
955         {
956                 errno = EINVAL;
957                 return -1;
958         }
959         
960         if(!vector->size || (-1 == vector->pos))
961         {
962                 errno = EAGAIN;
963                 return -1;
964         }
965         
966         return vector->pos;
967 }
968
969 int
970 vector_unwind(vector_t vector)
971 {
972         if(!vector)
973         {
974                 errno = EINVAL;
975                 return 0;
976         }
977         
978         if(!vector->size)
979         {
980                 errno = EAGAIN;
981                 return 0;
982         }
983         
984         vector->pos = vector->size - 1;
985         return 1;
986 }