Logo AND Algorithmique Numérique Distribuée

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