Logo AND Algorithmique Numérique Distribuée

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