Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
1d5c6d95b06ce93cdd32645be49f146076c5a5e8
[simgrid.git] / tools / tesh2 / src / lstrings.c
1
2 #include <lstrings.h>
3
4 #include <errno.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include <allocator.h>
9
10 #define __DEFAULT_BLOCK_CAPACITY 128
11
12 static allocator_t
13 allocator = NULL;
14
15 static int
16 ref = 0;
17
18 static link_t
19 link_new(void* item)
20 {
21         link_t link;
22         
23         if(!item)
24         {
25                 errno = EINVAL;
26                 return NULL;
27         }
28         
29         if(!(link = (link_t)allocator_alloc(allocator)))
30                 return NULL;
31         
32         link->next = link->prev = NULL;
33         link->item = item;
34         
35         return link;
36 }
37
38 static int
39 link_free(link_t* ref)
40 {
41         if(!(*ref))
42                 return  EINVAL;
43                 
44         allocator_dealloc(allocator, *ref);
45         *ref = NULL;
46         
47         return 0;
48 }
49
50 static link_t
51 search(lstrings_t lstrings, const char* string)
52 {
53         register link_t cur = lstrings->next;
54         
55         while(cur != ((link_t)&(lstrings->item)))
56         {
57                 if(!strcmp((const char*)(cur->item),string))
58                         return cur;
59                         
60                 cur = cur->next;
61         }
62         
63         errno = ESRCH;
64         return NULL;
65 }
66
67
68
69 lstrings_t
70 lstrings_new(void)
71 {
72         lstrings_t lstrings;
73         
74         if(!(lstrings = (lstrings_t)calloc(1,sizeof(s_lstrings_t))))
75                 return NULL;
76                 
77         if(!allocator)
78         {
79                 if(!(allocator = allocator_new(__DEFAULT_BLOCK_CAPACITY, sizeof(s_link_t), NULL)))
80                 {
81                         free(lstrings);
82                         return NULL;
83                 }
84         }
85         
86         lstrings->next = lstrings->prev = lstrings->cur = (link_t)(&(lstrings->item));
87         lstrings->pos = -1;
88         lstrings->size = 0;
89         
90         ref++;
91         return lstrings;
92 }
93
94 int
95 lstrings_rewind(lstrings_t lstrings)
96 {
97         if(!lstrings)
98         {
99                 errno = EINVAL;
100                 return 0;
101         }
102         
103         if(!lstrings->size)
104         {
105                 errno = EAGAIN;
106                 return 0;
107         }
108         
109         lstrings->cur = lstrings->next;
110         lstrings->pos = 0;
111         
112         return 1;
113 }
114
115 int
116 lstrings_unwind(lstrings_t lstrings)
117 {
118         if(!lstrings)
119         {
120                 errno = EINVAL;
121                 return 0;
122         }
123         
124         if(!lstrings->size)
125         {
126                 errno = EAGAIN;
127                 return 0;
128         }
129         
130         lstrings->cur = lstrings->prev;
131         lstrings->pos = lstrings->size - 1;
132         
133         return 1;
134 }
135
136 int
137 lstrings_clear(lstrings_t lstrings)
138 {
139         if(!lstrings)
140                 return EINVAL;
141         
142         if(!lstrings->size)
143                 return 0;
144         
145         while(lstrings->size)
146                 lstrings_pop_back(lstrings);
147         
148         return 0;
149 }
150
151 int
152 lstrings_free(lstrings_t* lstrings_ptr)
153 {
154         if(!(*lstrings_ptr))
155                 return EINVAL;
156         
157         if((*lstrings_ptr)->size)
158                 lstrings_clear(*lstrings_ptr);
159         
160         if(--ref)
161                 allocator_free(&allocator);
162                 
163         free(*lstrings_ptr);
164         *lstrings_ptr = NULL;
165         
166         return 0;
167 }
168
169 int
170 lstrings_push_front(lstrings_t lstrings, const char* string)
171 {
172         link_t what, where, next;
173         
174     if(!lstrings || !string)
175         return EINVAL;
176     
177     if(!(what = (link_t)link_new((void*)string)))
178         return errno;
179         
180     where = (link_t)(&(lstrings->item));
181     next = where->next;
182
183     what->prev = where;
184     what->next = next;
185     next->prev = what;
186     where->next = what;
187         
188     lstrings->size++;
189     
190     /* the iteration functions are now not permited */
191     lstrings->pos = -1;
192     lstrings->cur = (link_t)(&(lstrings->item));        
193     
194     return 0;
195 }
196
197 int
198 lstrings_push_back(lstrings_t lstrings, const char* string)
199 {
200         link_t what, where, prev;
201         
202         if(!lstrings || !string)
203         return EINVAL;
204     
205     if(!(what = (link_t)link_new((void*)string)))
206         return errno;
207         
208     where = (link_t)(&(lstrings->item));
209     prev = where->prev;
210         what->next = where;
211         what->prev = prev;
212     prev->next = what;
213     where->prev = what;
214     
215     lstrings->size++;
216     
217     /* the iteration functions are now not permited */
218     lstrings->pos = -1;
219     lstrings->cur = (link_t)(&(lstrings->item));
220     
221     return 0;   
222 }
223
224 int 
225 lstrings_insert_after(lstrings_t lstrings, const char* what, const char* where)
226 {
227     link_t __what, __where, __next;
228     
229     if(!lstrings || !what || !where)
230         return EINVAL;
231     
232     if(!(__what = link_new((void*)what)))
233         return errno;
234         
235     if((__where = search(lstrings, where)))
236         return errno;
237         
238     __next = __where->next;
239
240     __what->prev = __where;
241     __what->next = __next;
242     __next->prev = __what;
243     __where->next = __what;
244     
245     lstrings->size++;
246     
247     return 0;
248 }
249
250 int 
251 lstrings_insert_before(lstrings_t lstrings, const char* what, const char* where)
252 {
253     link_t __what, __where, __prev;
254     
255      if(!lstrings || !what || !where)
256         return EINVAL;
257     
258     if(!(__what = link_new((void*)what)))
259         return errno;
260         
261     if((__where = search(lstrings, where)))
262         return errno;
263         
264     __prev = __where->prev;
265         
266         __what->next = __where;
267     __what->prev = __prev;
268     __prev->next = __what;
269     __where->prev = __what;
270    
271     lstrings->size++;
272     
273     return 0;
274 }
275
276 const char*
277 lstrings_pop_back(lstrings_t lstrings)
278 {
279         link_t link, next, prev;
280         const char* string;
281         
282         if(!lstrings)
283         {
284                 errno = EINVAL;
285                 return NULL;
286         }
287         
288         if(!lstrings->size)
289         {
290                 errno = EAGAIN;
291                 return NULL;
292         }
293         
294         link = lstrings->prev;
295         
296         next = link->next;
297     prev = link->prev;
298
299     prev->next = next;
300     next->prev = prev;
301     
302     lstrings->size--;
303
304     string = (const char*)link->item;
305     
306     link_free((link_t*)&link);
307     
308     /* the iteration functions are now not permited */
309     lstrings->pos = -1;
310     lstrings->cur = (link_t)(&(lstrings->item));
311     
312     return string;
313 }
314
315 const char*
316 lstrings_pop_front(lstrings_t lstrings)
317 {
318         
319         link_t link, next, prev;
320         const char* string;
321         
322         if(!lstrings)
323         {
324                 errno = EINVAL;
325                 return NULL;
326         }
327         
328         if(!lstrings->size)
329         {
330                 errno = EAGAIN;
331                 return NULL;
332         }
333         
334         link = lstrings->next;
335         
336         next = link->next;
337     prev = link->prev;
338     prev->next = next;
339     next->prev = prev;
340     
341     lstrings->size--;
342
343     string = (const char*)link->item;
344     
345     link_free((link_t*)&link);
346     
347     /* the iteration functions are now not permited */
348     lstrings->pos = -1;
349     lstrings->cur = (link_t)(&(lstrings->item));
350
351     return string;
352 }
353
354 int
355 lstrings_remove(lstrings_t lstrings, const char* string)
356 {
357         link_t link, next, prev;
358         
359         if(!lstrings || !string)
360                 return EINVAL;
361         
362         if(!lstrings->size)
363                 return EAGAIN;
364         
365         if(!(link = search(lstrings, string)))
366                 return errno;
367         
368         next = link->next;
369     prev = link->prev;
370     prev->next = next;
371     next->prev = prev;
372     
373     lstrings->size--;
374     
375     /* the iteration functions are now not permited */
376     lstrings->pos = -1;
377     lstrings->cur = (link_t)(&(lstrings->item));
378
379     return link_free((link_t*)&link);
380 }
381
382 int
383 lstrings_get_size(lstrings_t lstrings)
384 {
385         if(!lstrings)
386         {
387                 errno = EINVAL;
388                 return -1;
389         }
390         
391         return lstrings->size;
392 }
393
394 int
395 lstrings_contains(lstrings_t lstrings, const char* string)
396 {
397         register link_t cur;
398         
399         if(!lstrings || !string)
400         {
401                 errno = EINVAL;
402                 return 0;
403         }
404         
405         if(!lstrings->size)
406         {
407                 errno = EAGAIN;
408                 return 0;
409         }
410         
411         cur = lstrings->next;
412         
413         while(cur != ((link_t)&(lstrings->item)))
414         {
415                 if(!strcmp((const char*)(cur->item), string))
416                         return 1;
417                         
418                 cur = cur->next;
419         }
420         
421         return 0;
422 }
423
424 int
425 lstrings_is_empty(lstrings_t lstrings)
426 {
427         if(!lstrings)
428         {
429                 errno = EINVAL;
430                 return 0;
431         }
432         
433         return !lstrings->size;
434 }
435
436 int
437 lstrings_move_next(lstrings_t lstrings)
438 {
439         if(!lstrings)
440         {
441                 errno = EINVAL;
442                 return 0;
443         }
444         
445         if(!lstrings->size || (-1 == lstrings->pos))
446         {
447                 errno = EAGAIN;
448                 return 0;
449         }
450         
451         if(lstrings->cur != (link_t)(&(lstrings->item)))
452         {
453                 lstrings->cur = lstrings->cur->next;
454                 lstrings->pos++;
455                 return 1;
456         }
457         
458         lstrings->pos = -1;
459         errno = ERANGE;
460         return 0;
461 }
462
463 const char*
464 lstrings_get(lstrings_t lstrings)
465 {
466         if(!lstrings)
467         {
468                 errno = EINVAL;
469                 return NULL;
470         }
471         
472         if(!lstrings->size || (-1 == lstrings->pos))
473         {
474                 errno = EAGAIN;
475                 return NULL;
476         }
477         
478         return (const char*)(lstrings->cur->item);
479 }
480
481 const char*
482 lstrings_set(lstrings_t lstrings, const char* string)
483 {
484         const char* prev_string;
485         
486         if(!lstrings || !string)
487         {
488                 errno = EINVAL;
489                 return NULL;
490         }
491         
492         if(!lstrings->size || (-1 == lstrings->pos))
493         {
494                 errno = EAGAIN;
495                 return NULL;
496         }
497         
498         prev_string = (const char*)(lstrings->cur->item);
499         lstrings->cur->item = (void*)string;
500         
501         return prev_string;
502 }
503
504 const char*
505 lstrings_get_at(lstrings_t lstrings, int pos)
506 {
507         register link_t cur;
508         
509         if(!lstrings || pos < 0 || pos >= lstrings->size)
510         {
511                 errno = EINVAL;
512                 return NULL;
513         }
514         
515         if(!lstrings->size)
516         {
517                 errno = EAGAIN;
518                 return NULL;
519         }
520         
521         cur = lstrings->next;
522         
523         while(pos--)
524                 cur = cur->next;
525                 
526         
527         return (const char*)(cur->item);        
528 }
529
530 const char*
531 lstrings_set_at(lstrings_t lstrings, int pos, const char* string)
532 {
533         register link_t cur;
534         const char* prev_string;
535         
536         if(!lstrings || !string)
537         {
538                 errno = EINVAL;
539                 return NULL;
540         }
541         
542         if(pos < 0 || pos >= lstrings->size)
543         {
544                 errno = ERANGE;
545                 return NULL;
546         }
547         
548         if(!lstrings->size)
549         {
550                 errno = EAGAIN;
551                 return NULL;
552         }
553         
554         cur = lstrings->next;
555         
556         while(pos--)
557                 cur = cur->next;
558                 
559         prev_string = (const char*)cur->item;   
560         cur->item = (void*)string;
561         
562         return prev_string;
563         
564 }
565
566 int
567 lstrings_move_prev(lstrings_t lstrings)
568 {
569         if(!lstrings)
570         {
571                 errno = EINVAL;
572                 return 0;
573         }
574         
575         if(!lstrings->size || (-1 == lstrings->pos))
576         {
577                 errno = EAGAIN;
578                 return 0;
579         }
580         
581         if(lstrings->cur != (link_t)(&(lstrings->item)))
582         {
583                 lstrings->cur = lstrings->cur->prev;
584                 lstrings->pos--;
585                 return 1;
586         }
587         
588         lstrings->pos = -1;
589         errno = ERANGE;
590         return 0;
591 }
592
593 static int
594 seek_set(lstrings_t lstrings, int offset)
595 {
596         if(offset > lstrings->size)
597                 return EINVAL;
598         
599         lstrings_rewind(lstrings);
600         
601         while(offset--)
602                 lstrings_move_next(lstrings);
603                 
604         return 0;
605 }
606
607 static int
608 seek_end(lstrings_t lstrings, int offset)
609 {
610         if(offset > lstrings->size)
611                 return EINVAL;
612         
613         lstrings_unwind(lstrings);
614         
615         while(offset--)
616                 lstrings_move_prev(lstrings);
617                 
618         return 0;
619 }
620
621
622 static int
623 seek_cur(lstrings_t lstrings, int offset)
624 {
625         if(lstrings->cur == lstrings->next)
626         {
627                 /* we are at the begin of the lstrings */
628                 seek_set(lstrings, offset);
629         }
630         else if(lstrings->cur == lstrings->prev)
631         {
632                 /* we are at the end of the lstrings */
633                 seek_end(lstrings, offset);
634         }
635         else
636         {
637                 if(offset > (lstrings->size - lstrings->pos + 1))       
638                         return EINVAL;
639                         
640                 while(offset--)
641                         lstrings_move_next(lstrings);
642                         
643         }
644                 
645         return 0;
646 }
647
648 int
649 lstrings_seek(lstrings_t lstrings, int offset, int whence)
650 {
651         if(!lstrings)
652                 return EINVAL;
653                 
654         if(!lstrings->size)
655                 return EAGAIN;
656         
657         switch(whence)
658         {
659                 case SEEK_SET :
660                 return seek_set(lstrings, offset);
661                 
662                 case SEEK_CUR :
663                 return seek_cur(lstrings, offset);
664                 
665                 case SEEK_END :
666                 return seek_end(lstrings, offset);
667                 
668         }
669         
670         return EINVAL;
671 }
672
673 int
674 lstrings_tell(lstrings_t lstrings)
675 {
676         if(!lstrings)
677         {
678                 errno = EINVAL;
679                 return -1;
680         }
681         
682         if(!lstrings->size || (-1 == lstrings->pos))
683         {
684                 errno = EAGAIN;
685                 return -1;
686         }
687         
688         return lstrings->pos;
689 }
690
691 int
692 lstrings_getpos(lstrings_t lstrings, int* pos)
693 {
694         if(!lstrings || !pos)
695         {
696                 errno = EINVAL;
697                 return 0;
698         }
699         
700         if(!lstrings->size || (-1 == lstrings->pos))
701         {
702                 errno = EAGAIN;
703                 return 0;
704         }
705         
706         *pos = lstrings->pos;
707         return 1;
708 }
709
710 int
711 lstrings_setpos(lstrings_t lstrings, int pos)
712 {
713         if(!lstrings)
714         {
715                 errno = EINVAL;
716                 return 0;
717         }
718         
719         if(pos < 0 || pos >= lstrings->size)
720         {
721                 errno = ERANGE;
722                 return 0;
723         }
724         
725         if(!lstrings->size)
726         {
727                 errno = EAGAIN;
728                 return 0;
729         }
730         
731         lstrings->cur = lstrings->next;
732         lstrings->pos = pos;
733         
734         while(pos--)
735                 lstrings->cur = lstrings->cur->next;
736                 
737         return 1;
738 }
739
740
741 const char*
742 lstrings_get_front(lstrings_t lstrings)
743 {
744         if(!lstrings)
745         {
746                 errno = EINVAL;
747                 return NULL;
748         }
749         
750         if(!lstrings->size)
751         {
752                 errno = EAGAIN;
753                 return NULL;
754         }
755         
756         return (const char*)(lstrings->next->item);     
757 }
758
759
760 const char*
761 lstrings_get_back(lstrings_t lstrings)
762 {
763         if(!lstrings)
764         {
765                 errno = EINVAL;
766                 return NULL;
767         }
768         
769         if(!lstrings->size)
770         {
771                 errno = EAGAIN;
772                 return NULL;
773         }
774         
775         return (const char*)(lstrings->prev->item);
776 }
777
778 char**
779 lstrings_to_cstr(lstrings_t lstrings)
780 {
781         register int i;
782         link_t cur;
783         int size;
784         char** cstr;
785         
786         if(!lstrings || !lstrings->size)
787         {
788                 errno = EINVAL;
789                 return NULL;
790         }
791         
792         if(!(cstr = (char**)calloc(lstrings->size, sizeof(char*))))
793                 return NULL;
794         
795         /* get the first link of the list */
796         cur = lstrings->next;   
797         
798         for(i = 0; i < size; i++)
799         {
800                 if(!(cstr[i] = strdup(cur->item)))
801                 {
802                         register int j;
803                         
804                         for(j = 0; j <i; j++)
805                                 free(cstr[j]);
806                                 
807                         free(cstr);
808                         
809                         return NULL;
810                 }
811                 
812                 cur = cur->next;
813         }
814         
815         
816         return cstr;
817 }