1  /*****************************************************************************
2  **  This is part of the SpaceZero program
3  **  Copyright(C) 2006-2013  MRevenga
4  **
5  **  This program is free software; you can redistribute it and/or modify
6  **  it under the terms of the GNU General Public License (version 3), or
7  **  (at your option) any later version, as published by the Free Software
8  **  Foundation.
9  **
10  **  This program is distributed in the hope that it will be useful,
11  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  **  GNU General Public License for more details.
14  **
15  **  You should have received a copy of the GNU General Public License
16  **  along with this program; if not, write to the Free Software
17  **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ******************************************************************************/
19 
20 /*************  SpaceZero  M.R.H. 2006-2013 ******************
21 		Author: MRevenga
22 		E-mail: mrevenga at users.sourceforge.net
23 		version 0.86 December 2013
24 **************************************************************/
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include "data.h"
29 #include "general.h"
30 #include "objects.h"
31 #include "functions.h"
32 
33 
34 /*
35  *   data structures and functions
36  *
37  */
38 
39 
40 
41 /*
42    Unordered list
43 */
44 
Add2IntList(struct IntList * list,int id)45 struct IntList* Add2IntList(struct IntList *list,int id){
46   /*
47      version 01
48      add the integer id to the end of the list
49      if is not already added.
50      returns:
51      a pointer to the beginning of the list.
52    */
53 
54   struct IntList *kps;
55 
56   if(list==NULL){ /* first item */
57     list=malloc(sizeof(struct IntList));
58     MemUsed(MADD,+sizeof(struct IntList));
59     if(list==NULL){
60       fprintf(stderr,"ERROR in malloc (Add2IntList)\n");
61       exit(-1);
62     }
63     list->id=id;
64     list->next=NULL;
65     return(list);
66   }
67 
68   /* look if it its already added */
69   kps=list;
70 
71   if(kps->id==id)
72     return(list); /* first item is known */
73 
74   while(kps->next!=NULL){
75     if(kps->next->id==id)
76       return(list); /* item was known */
77     kps=kps->next;
78   }
79   /*
80      item is not in the list
81      adding to the end
82   */
83 
84   kps->next=malloc(sizeof(struct IntList));
85   if(kps->next==NULL){
86     fprintf(stderr,"ERROR in malloc (Add2IntList)\n");
87     exit(-1);
88   }
89   MemUsed(MADD,+sizeof(struct IntList));
90   kps->next->id=id;
91   kps->next->next=NULL;
92   return(list);
93 }
94 
95 
IsInIntList(struct IntList * list,int id)96 int IsInIntList(struct IntList *list,int id){
97   /*
98      Secuential search (must be improve)
99      return:
100      TRUE if id is in the list
101      FALSE if not.
102   */
103 
104   /* look if it its already added */
105 
106   while(list!=NULL){
107     if(list->id==id){
108       return(TRUE); /* item is known */
109     }
110     list=list->next;
111   }
112 
113   /* item is not in the list */
114   return(FALSE);
115 }
116 
CountIntList(struct IntList * list)117 int CountIntList(struct IntList *list){
118   /* return the number of item of the list */
119 
120   int n=0;
121 
122   while(list!=NULL){
123     n++;
124     list=list->next;
125   }
126   return(n);
127 }
128 
DelFirstIntList(struct IntList * list)129 int DelFirstIntList(struct IntList *list){
130   /* Delete the first item of the list */
131   struct IntList *item0;
132 
133   if(list!=NULL){
134     item0=list;
135     list=list->next;
136     free(item0);
137     MemUsed(MADD,-sizeof(struct IntList));
138     item0=NULL;
139     return(1);
140   }
141   return(0);
142 }
143 
144 
DelIntList(struct IntList * list)145 int DelIntList(struct IntList *list){
146   /*
147      version 01
148      Delete all the list
149      returns the number of items deleted
150   */
151 
152   struct IntList *item0;
153   int n=0;
154 
155   if(list==NULL)return(0);
156 
157   while(list->next!=NULL){
158     item0=list->next;
159     list->next=list->next->next;
160     free(item0);
161     MemUsed(MADD,-sizeof(struct IntList));
162     item0=NULL;
163     n++;
164   }
165 
166   free(list);
167   MemUsed(MADD,-sizeof(struct IntList));
168   list=NULL;
169   n++;
170   return (n);
171 }
172 
173 
FPrintIntList(FILE * fp,struct IntList * list)174 int FPrintIntList(FILE *fp,struct IntList *list){
175   /* return the number of item of the list */
176 
177   int n=0;
178 
179   while(list!=NULL){
180     fprintf(fp,"%d ",list->id);
181     n++;
182     list=list->next;
183   }
184   return(n);
185 }
186 
187 
188 /*
189    Ordered list
190 */
191 
IsInIntOList(struct IntList * list,int id)192 int IsInIntOList(struct IntList *list,int id){
193   /* return:
194      TRUE if id is in the list
195      FALSE if not.
196   */
197 
198   while(list!=NULL){
199     if(list->id==id)
200       return(TRUE); /* item is known */
201     if(list->id>id)
202       return(FALSE);
203     list=list->next;
204   }
205 
206   /* item is not in the list */
207   return(FALSE);
208 }
209 
210 
211 /*
212    Indexed list
213 */
214 
Add2IntIList(struct HeadIntIList * head,int id)215 int Add2IntIList(struct HeadIntIList *head,int id){
216   /* add the integer id to the list head
217      if is not already added.
218      returns:
219      0 if item is added
220      1 if is not added, the item exists
221    */
222   struct IntList *item;
223   struct IntList *last=NULL;
224   int i;
225 
226   /* is the first */
227   if(head->list==NULL){
228     head->list=malloc(sizeof(struct IntList));
229     MemUsed(MADD,+sizeof(struct IntList));
230     if(head->list==NULL){
231       fprintf(stderr,"ERROR in malloc (Add2IntIList)\n");
232       exit(-1);
233     }
234     head->n++;
235     head->n0++;
236     head->list->id=id;
237     head->list->next=NULL;
238     for(i=0;i<NINDEXILIST;i++){
239       head->index[i]=head->list;
240     }
241     return(0);
242   }
243 
244   if(head->n0 > NINDEXCALC){
245     int i=0;
246     int n=0;
247     int m;
248 
249     item=head->list;
250     head->n0=0;
251     m=head->n/NINDEXILIST;
252     head->index[i++]=head->list;
253     while(item!=NULL){
254       n++;
255       if(n>m){
256 	head->index[i++]=item;
257 	n=0;
258       }
259       item=item->next;
260     }
261   }
262 
263   item=head->list;
264   for(i=0;i<NINDEXILIST-1;i++){
265     if( head->index[i]->id > id)break;
266     item=head->index[i];
267   }
268 
269   /* look if it its already added */
270   while(item!=NULL){
271 
272     if(item->id==id){
273       return(1); /* item is in the list */
274     }
275     if(item->id>id){ /*item is not in the list, adding in the middle */
276       struct IntList *itemn;
277       itemn=malloc(sizeof(struct IntList));
278       MemUsed(MADD,+sizeof(struct IntList));
279       if(itemn==NULL){
280 	fprintf(stderr,"ERROR in malloc (Add2IntIList)\n");
281 	exit(-1);
282       }
283       head->n++;
284       head->n0++;
285 
286       if(last==NULL){ /* first item */
287 	itemn->id=id;
288 	itemn->next=head->list;
289 	head->list=itemn;
290 	head->index[0]=head->list;
291 
292       }
293       else{
294 	itemn->id=id;
295 	last->next=itemn;
296 	itemn->next=item;
297       }
298       return(0);
299     }
300     last=item;
301     item=item->next;
302   }
303 
304   /* item is not in the list, adding to the end */
305   head->n++;
306   head->n0++;
307 
308   item=malloc(sizeof(struct IntList));
309   MemUsed(MADD,+sizeof(struct IntList));
310   if(item==NULL){
311     fprintf(stderr,"ERROR in malloc (Add2IntIList)\n");
312     exit(-1);
313   }
314 
315   last->next=item;
316   item->next=NULL;
317   item->id=id;
318 
319   return(0);
320 }
321 
IsInIntIList(struct HeadIntIList * head,int id)322 int IsInIntIList(struct HeadIntIList *head,int id){
323   /* return:
324      TRUE if id is in the list
325      FALSE if not.
326   */
327 
328   /* look if it its already added */
329 
330   int i;
331   struct IntList *list;
332 
333 
334   list=head->index[0];
335 
336   if(list==NULL){
337     return(FALSE);
338   }
339   for(i=0;i<NINDEXILIST-1;i++){
340     if( head->index[i]->id > id)break;
341     list=head->index[i];
342   }
343 
344   while(list!=NULL){
345     if(list->id==id)
346       return(TRUE); /* item is known */
347     if(list->id>id)
348       return(FALSE);
349     list=list->next;
350   }
351 
352   /* item is not in the list */
353   return(FALSE);
354 }
355 
DelIntIList(struct HeadIntIList * head)356 int DelIntIList(struct HeadIntIList *head){
357   /* Delete all the list */
358 
359   int n=0;
360   int i;
361 
362   DelIntList(head->list);
363 
364   head->n=head->n0=0;
365 
366   head->list=NULL;
367   for(i=0;i<NINDEXILIST;i++){
368     head->index[i]=NULL;
369   }
370   return (n);
371 }
372 
PrintIntIList(struct HeadIntIList head)373 int PrintIntIList(struct HeadIntIList head){
374   /* print the list */
375   int n=0;
376   int i;
377   struct IntList *list;
378 
379   list=head.list;
380 
381   while(list!=NULL){
382     printf("%d ",list->id);
383     n++;
384     list=list->next;
385   }
386   printf("\n");
387   for(i=0;i<NINDEXILIST;i++){
388     if(head.index[i]!=NULL)
389       printf("%p %d\n",(void *)head.index[i],head.index[i]->id);
390     else
391       printf("%p\n",(void *)head.index[i]);
392   }
393   return(n);
394 }
395 
396 
397 /* char list with scroll  */
398 
Add2CharList(struct CharListHead * hlist,char * cad,int mode)399 int Add2CharList(struct CharListHead *hlist,char *cad,int mode){
400   /*
401      version 00
402      add the char cad to the end of the list
403      returns:
404      0 if success, item added.
405      1 success,list full, item added and first item deleted.
406      2 if there are some error.
407      3 if is already added.
408    */
409 
410   struct CharList *list;
411   int swfull=0;
412   int m=0;
413   int n;
414 
415 
416   if(hlist==NULL){
417     fprintf(stderr,"ERROR in Add2CharList(): NULL\n");
418     exit(-1);
419   }
420   if(cad==NULL){
421     fprintf(stderr,"ERROR in Add2CharList(): cad NULL\n");
422     return(2);
423   }
424   n=strlen(cad);
425   if(n>MAXTEXTLEN)n=MAXTEXTLEN; /* max of log messages */
426 
427   if(mode==1){ /* check if is recently added => don't add*/
428     m=0;
429     list=hlist->next;
430     while(list!=NULL){
431       if(strncmp(cad,list->cad,MAXTEXTLEN)==0){
432 	if(m > hlist->n-20){
433 	  return(2);
434 	}
435       }
436       m++;
437       list=list->next;
438     }
439   }
440 
441   list=hlist->next;
442 
443   if(list==NULL){ /* first item */
444     list=malloc(sizeof(struct CharList));
445     MemUsed(MADD,+sizeof(struct CharList));
446     if(list==NULL){
447       fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
448       exit(-1);
449     }
450 
451     list->cad=malloc((n+1)*sizeof(char));
452     MemUsed(MADD,+sizeof((n+1)*sizeof(char)));
453     if(list->cad==NULL){
454       fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
455       exit(-1);
456     }
457 
458     snprintf(list->cad,n+1,"%s",cad);
459     /* strncpy(list->cad,cad,n+1); */
460     list->next=NULL;
461     hlist->next=list;
462     hlist->n++;
463     return(0);
464   }
465 
466   /* checking max number of elements */
467   /* if reach its limit delete the first item */
468 
469   if(hlist->n==hlist->max){
470     struct CharList *freeitem;
471     int n;
472     freeitem=hlist->next;
473     if(freeitem!=NULL){
474       hlist->next=hlist->next->next;
475       n=strlen(freeitem->cad);
476       free(freeitem->cad);
477       free(freeitem);
478       MemUsed(MADD,-(sizeof((n+1)*sizeof(char))+sizeof(struct CharList)));
479       hlist->n--;
480       swfull++;
481     }
482     else{
483       fprintf(stderr,"ERROR in List (Add2Charlist) not added.\n");
484       return(2);
485     }
486   }
487 
488 
489   /* adding to the end of the list if there are room */
490 
491   while(list->next!=NULL)list=list->next;
492 
493     list->next=malloc(sizeof(struct CharList));
494     MemUsed(MADD,+sizeof(struct CharList));
495     if(list->next==NULL){
496       fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
497       exit(-1);
498     }
499 
500     list->next->cad=malloc((n+1)*sizeof(char));
501     MemUsed(MADD,+sizeof((n+1)*sizeof(char)));
502     if(list->next->cad==NULL){
503       fprintf(stderr,"ERROR in malloc (Add2Charlist)\n");
504       exit(-1);
505     }
506     snprintf(list->next->cad,n+1,"%s",cad);
507     /* strncpy(list->next->cad,cad,n+1); */
508     list->next->next=NULL;
509     hlist->n++;
510 
511     if(swfull)return(1);
512     return(0);
513 }
514 
Add2CharListWindow(struct CharListHead * hlist,char * cad,int mode,struct Window * w)515 int Add2CharListWindow(struct CharListHead *hlist,char *cad,int mode,struct Window *w){
516   /*
517      version 00
518      change the scroll bar if a new item is added to hlist.
519      returns:
520      0 if success
521      1 if there are some error
522      2 if is already added
523    */
524 
525   int status;
526 
527   if(hlist==NULL){
528     fprintf(stderr,"ERROR in Add2CharListWindow(): NULL\n");
529     exit(-1);
530   }
531   if(cad==NULL){
532     fprintf(stderr,"ERROR in Add2CharListwindow(): cad NULL\n");
533     return(1);
534   }
535 
536   if(w==NULL)return(1);
537 
538   status= Add2CharList(hlist,cad,mode);
539 
540   switch(status){
541   case 0:
542   case 1:
543     if(w->scrollbar.n!=0){
544       w->scrollbar.n++;
545     }
546     break;
547   case 2:
548     break;
549   default:
550     break;
551   }
552 
553   return(status);
554 }
555 
556 
557 
PrintCharList(struct CharListHead * hlist)558 int PrintCharList(struct CharListHead *hlist){
559   /*
560      version 00
561      print the list
562      returns:
563      the number of item printed.
564    */
565 
566   struct CharList *list;
567   int n=0;
568 
569 
570   if(hlist==NULL){
571     fprintf(stderr,"ERROR in Add2CharList(): NULL\n");
572     exit(-1);
573   }
574 
575   list=hlist->next;
576 
577   while(list!=NULL){
578     printf("%d:  %s\n",n,list->cad);
579     list=list->next;
580     n++;
581   }
582   if(n!=hlist->n){
583     printf("ERROR in list n: %d  hlist.n:%d\n",n,hlist->n);
584   }
585   return(n);
586 }
587 
588 
DestroyCharList(struct CharListHead * hlist)589 int DestroyCharList(struct CharListHead *hlist){
590   /*
591      version 00
592      delete all the list
593      returns:
594      the number of item deleted.
595    */
596 
597   struct CharList *freeitem;
598   int n=0;
599   int cont=0;
600 
601   if(hlist==NULL){
602     fprintf(stderr,"ERROR in Add2CharList(): NULL\n");
603     exit(-1);
604   }
605 
606   while(hlist->next!=NULL){
607     freeitem=hlist->next;
608     hlist->next=hlist->next->next;
609     n=strlen(freeitem->cad);
610     free(freeitem->cad);
611     free(freeitem);
612     MemUsed(MADD,-(sizeof(n*sizeof(char))+sizeof(struct CharList)));
613     hlist->n--;
614     cont++;
615   }
616   return(cont);
617 }
618 
619 
620 
621 /********
622    Tree
623 ********/
624 
Add2IntTree(struct IntTree * head,int id)625 struct IntTree *Add2IntTree(struct IntTree *head,int id){
626   /* add the integer id to the tree head
627      if is not already added.
628      returns:
629      a pointer to the head of the list.
630    */
631 
632   if(!head){
633     head=malloc(sizeof(struct IntTree));
634     MemUsed(MADD,+sizeof(struct IntTree));
635     if(head==NULL){
636       fprintf(stderr,"ERROR in malloc (Add2IntTree)\n");
637       exit(-1);
638     }
639     head->id=id;
640     head->l=NULL;
641     head->r=NULL;
642     printf("added: %d\n",head->id);
643     return(head);
644   }
645 
646   if(id<head->id){
647     head->l=Add2IntTree(head->l,id);
648   }
649   else{
650     if(id>head->id){
651       head->r=Add2IntTree(head->r,id);
652     }
653   }
654   return(head);
655 }
656 
PrintTree(struct IntTree * head)657 void PrintTree (struct IntTree *head){
658   static int level=0;
659   level++;
660   if(head!=NULL){
661     PrintTree(head->l);
662     printf("l %d:  %d\n",level,head->id);
663     PrintTree(head->r);
664   }
665   level--;
666 }
667 
SizeIntTree(struct IntTree * head,int reset)668 int SizeIntTree (struct IntTree *head,int reset){
669   /*
670     Return:
671     the size of the tree.
672    */
673 
674 
675   static int level=0;
676   static int max=0;
677   if(reset){
678     max=0;
679     return(0);
680   }
681   if(level>max)max=level;
682   level++;
683 
684   if(head!=NULL){
685     SizeIntTree(head->l,0);
686     SizeIntTree(head->r,0);
687   }
688   level--;
689   return(max);
690 }
691 
692 
IsInIntTree(struct IntTree * head,int id)693 int IsInIntTree(struct IntTree *head,int id){
694   /*
695     returns:
696     1 if the element id is in the tree
697     0 if not.
698    */
699   if(head!=NULL){
700     if(id==head->id){
701       return(1);
702     }
703     if(id < head->id){
704       return(IsInIntTree(head->l,id));
705     }
706     else{
707       return(IsInIntTree(head->r,id));
708     }
709   }
710   return(0);
711 }
712 
DelIntTree(struct IntTree * head)713 void DelIntTree(struct IntTree *head){
714   /*
715     Delete the tree freeing the memory.
716   */
717 
718   if(head!=NULL){
719     DelIntTree(head->l);
720     DelIntTree(head->r);
721     head->l=NULL;
722     head->r=NULL;
723     free(head);
724     MemUsed(MADD,-sizeof(struct IntTree));
725     head=NULL;
726   }
727 }
728 
729 
CountIntTree(struct IntTree * head)730 int CountIntTree (struct IntTree *head){
731   /*
732     Returns:
733     the number of elemnets of the tree.
734   */
735  int cont=0;
736 
737   if(head!=NULL){
738     cont+=CountIntTree(head->l);
739     cont++;
740     cont+=CountIntTree(head->r);
741   }
742   return(cont);
743 }
744 
745 /************
746 Text Lists
747 ***********/
748 
Add2TextList(struct HeadTextList * listhead,char * cad,int color)749 int Add2TextList(struct HeadTextList *listhead,char *cad,int color){
750   /*
751      add the cad to the list
752   */
753   struct TextList *lh,*new;
754 
755   new=malloc(sizeof(struct TextList));
756   if(new==NULL){
757     fprintf(stderr,"ERROR in malloc Add2TextList()\n");
758     exit(-1);
759   }
760   MemUsed(MADD,+sizeof(struct TextList));
761 
762   strncpy(new->text,cad,MAXTEXTLEN);
763   new->color=color;
764   new->next=NULL;
765 
766   /* first item*/
767   if(listhead->next==NULL){
768     listhead->next=new;
769   }
770   else{
771     /* Add text at the end of the list */
772     lh=listhead->next;
773     while(lh->next!=NULL){
774       lh=lh->next;
775     }
776     lh->next=new;
777   }
778   listhead->n++;
779   return (0);
780 }
781 
DestroyTextList(struct HeadTextList * head)782 int DestroyTextList(struct HeadTextList *head){
783   /*
784      delete all the list
785      return:
786      the number of items deleted
787   */
788   struct TextList *lh0;
789   struct TextList *lh;
790   int n=0;
791   long memused=0;
792 
793   lh=head->next;
794   while(lh!=NULL){
795     lh0=lh;
796     lh=lh->next;
797     free(lh0);
798     lh0=NULL;
799     memused-=sizeof(struct TextList);
800     n++;
801   }
802   head->next=NULL;
803   head->n=0;
804   MemUsed(MADD,memused);
805   return (n);
806 }
807 
PrintTextList(struct HeadTextList * head)808 int PrintTextList(struct HeadTextList *head){
809   struct TextList *lh;
810 
811   lh=head->next;
812   while(lh!=NULL){
813     printf("%s\n",lh->text);
814     lh=lh->next;
815   }
816   return(0);
817 }
CountTextList(struct HeadTextList * head)818 int CountTextList(struct HeadTextList *head){
819   /*
820     returns:
821     the number of items of the the list head.
822    */
823   struct TextList *lh;
824   int n=0;
825   lh=head->next;
826   while(lh!=NULL){
827     n++;
828     lh=lh->next;
829   }
830   return(n);
831 }
PosFirstTextList(struct HeadTextList * head,int m)832 int PosFirstTextList(struct HeadTextList *head,int m){
833   /*
834     returns:
835     the position of the first text with color m
836    */
837 
838   struct TextList *lh;
839   int n=0;
840   lh=head->next;
841   while(lh!=NULL){
842     if(lh->color==m)return(n);
843     n++;
844     lh=lh->next;
845   }
846   return(-1);
847 }
848 
849 
PosLastTextList(struct HeadTextList * head,int m)850 int PosLastTextList(struct HeadTextList *head,int m){
851   /*
852     returns:
853     the position of the last text item with color m
854    */
855 
856   struct TextList *lh;
857   int n=0;
858   int ret=0;
859 
860   lh=head->next;
861   while(lh!=NULL){
862     if(lh->color==m)ret=n;
863     n++;
864     lh=lh->next;
865   }
866   return(ret);
867 }
868 
CountColorTextList(struct HeadTextList * head,int m)869 int CountColorTextList(struct HeadTextList *head,int m){
870   /*
871     returns:
872     the number of texts of color m
873    */
874 
875   struct TextList *lh;
876   int n=0;
877   lh=head->next;
878   while(lh!=NULL){
879     if(lh->color==m)n++;
880     lh=lh->next;
881   }
882   return(n);
883 }
884